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

Linux Kernel Patch v2.4, patch-2.4.13 (00/53)

55 views
Skip to first unread message

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:30 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part00

lines added deleted
linux/CREDITS : 26 9 3
linux/Documentation/Configure.help : 359 237 31
linux/Documentation/DMA-mapping.txt : 487 273 74
linux/Documentation/README.DAC960 : 113 24 24
linux/Documentation/README.nsp_cs.eng : 46 9 6
linux/Documentation/arm/README : 8 1 1
linux/Documentation/arm/SA1100/ADSBitsy : 43 43 0
linux/Documentation/arm/SA1100/GraphicsMaster : 53 53 0
linux/Documentation/arm/SA1100/Pangolin : 16 5 1
linux/Documentation/cachetlb.txt : 12 6 0
linux/Documentation/cciss.txt : 89 77 1
linux/Documentation/filesystems/devfs/ToDo : 8 1 1
linux/Documentation/filesystems/udf.txt : 28 4 4
linux/Documentation/i2c/dev-interface : 9 3 0
linux/Documentation/i2c/summary : 65 19 7
linux/Documentation/i2c/writing-clients : 100 18 18
linux/Documentation/networking/8139too.txt : 12 6 0
linux/Documentation/s390/CommonIO : 25 15 0
linux/Documentation/s390/chandev.8 : 34 10 5
linux/Documentation/s390/s390dbf.txt : 29 15 1
linux/Documentation/sonypi.txt : 51 19 2
linux/Documentation/usb/error-codes.txt : 18 2 3
linux/Documentation/usb/philips.txt : 50 22 11
linux/Documentation/usb/scanner.txt : 123 63 18
linux/Documentation/video4linux/README.buz : 212 0 212
linux/Documentation/video4linux/bttv/CARDLIST : 90 25 12
linux/Documentation/video4linux/bttv/Cards : 210 210 0
linux/Documentation/video4linux/bttv/Insmod-options : 73 32 13
linux/Documentation/video4linux/bttv/README.quirks : 83 83 0
linux/Documentation/video4linux/bttv/Sound-FAQ : 7 1 0
linux/Documentation/video4linux/bttv/Tuners : 88 88 0
linux/Documentation/video4linux/meye.txt : 11 4 1
linux/MAINTAINERS : 84 37 6
linux/Makefile : 22 3 2
linux/arch/alpha/kernel/alpha_ksyms.c : 16 6 0
linux/arch/alpha/kernel/core_cia.c : 106 35 21
linux/arch/alpha/kernel/core_mcpcia.c : 15 3 3
linux/arch/alpha/kernel/core_titan.c : 71 17 19
linux/arch/alpha/kernel/core_tsunami.c : 79 15 38
linux/arch/alpha/kernel/pci.c : 54 19 24
linux/arch/alpha/kernel/pci_impl.h : 8 2 0
linux/arch/alpha/kernel/pci_iommu.c : 540 175 61
linux/arch/alpha/kernel/srm_env.c : 28 4 3
linux/arch/alpha/kernel/sys_cabriolet.c : 7 1 0
linux/arch/alpha/kernel/sys_dp264.c : 39 5 0
linux/arch/alpha/kernel/sys_eiger.c : 7 1 0
linux/arch/alpha/kernel/sys_miata.c : 7 1 0
linux/arch/alpha/kernel/sys_rawhide.c : 7 1 0
linux/arch/alpha/kernel/sys_ruffian.c : 7 1 0
linux/arch/alpha/kernel/sys_sx164.c : 18 4 1
linux/arch/alpha/kernel/sys_titan.c : 7 1 0
linux/arch/arm/Makefile : 35 3 5
linux/arch/arm/boot/Makefile : 36 17 2
linux/arch/arm/boot/bootp/Makefile : 7 0 1
linux/arch/arm/boot/bootp/init.S : 55 22 3
linux/arch/arm/boot/compressed/Makefile : 17 3 1
linux/arch/arm/boot/compressed/head-sa1100.S : 38 18 2
linux/arch/arm/boot/compressed/setup-sa1100.S : 163 0 163
linux/arch/arm/config.in : 150 45 8
linux/arch/arm/kernel/Makefile : 8 1 1
linux/arch/arm/kernel/armksyms.c : 56 10 12
linux/arch/arm/kernel/bios32.c : 13 5 2
linux/arch/arm/kernel/compat.c : 8 1 1
linux/arch/arm/kernel/dma-isa.c : 27 10 5
linux/arch/arm/kernel/entry-armv.S : 43 11 10
linux/arch/arm/kernel/entry-common.S : 10 1 2
linux/arch/arm/kernel/entry-header.S : 50 24 6
linux/arch/arm/kernel/head-armv.S : 5 0 1
linux/arch/arm/kernel/init_task.c : 7 1 0
linux/arch/arm/kernel/setup.c : 76 49 5
linux/arch/arm/kernel/signal.c : 351 145 104
linux/arch/arm/kernel/time.c : 7 0 1
linux/arch/arm/kernel/traps.c : 49 7 6
linux/arch/arm/lib/Makefile : 21 6 1
linux/arch/arm/lib/ashldi3.c : 61 61 0
linux/arch/arm/lib/ashrdi3.c : 61 61 0
linux/arch/arm/lib/gcclib.h : 25 25 0
linux/arch/arm/lib/getuser.S : 96 96 0
linux/arch/arm/lib/kbd.c : 13 13 0
linux/arch/arm/lib/lib1funcs.S : 320 320 0
linux/arch/arm/lib/longlong.h : 184 184 0
linux/arch/arm/lib/lshrdi3.c : 61 61 0
linux/arch/arm/lib/muldi3.c : 77 77 0
linux/arch/arm/lib/putuser.S : 94 94 0
linux/arch/arm/lib/ucmpdi2.c : 51 51 0
linux/arch/arm/lib/udivdi3.c : 231 231 0
linux/arch/arm/mach-ebsa110/io.c : 19 6 0
linux/arch/arm/mach-integrator/cpu.c : 34 4 3
linux/arch/arm/mach-integrator/dma.c : 8 1 1
linux/arch/arm/mach-integrator/pci_v3.c : 8 1 1
linux/arch/arm/mach-sa1100/Makefile : 50 12 4
linux/arch/arm/mach-sa1100/adsbitsy.c : 180 180 0
linux/arch/arm/mach-sa1100/assabet.c : 46 10 2
linux/arch/arm/mach-sa1100/bitsy.c : 175 0 175
linux/arch/arm/mach-sa1100/cpu-sa1110.c : 24 2 3
linux/arch/arm/mach-sa1100/dma-sa1100.c : 94 25 14
linux/arch/arm/mach-sa1100/dma-sa1111.c : 17 2 2
linux/arch/arm/mach-sa1100/generic.c : 25 3 2
linux/arch/arm/mach-sa1100/graphicsclient.c : 17 3 2
linux/arch/arm/mach-sa1100/graphicsmaster.c : 225 225 0
linux/arch/arm/mach-sa1100/h3600.c : 189 189 0
linux/arch/arm/mach-sa1100/jornada720.c : 9 2 1
linux/arch/arm/mach-sa1100/leds-graphicsmaster.c : 104 104 0
linux/arch/arm/mach-sa1100/leds.c : 8 2 0
linux/arch/arm/mach-sa1100/leds.h : 5 1 1
linux/arch/arm/mach-sa1100/neponset.c : 100 64 27
linux/arch/arm/mach-sa1100/pangolin.c : 8 1 1
linux/arch/arm/mach-sa1100/pfs168.c : 59 45 6
linux/arch/arm/mach-sa1100/sa1111-pcibuf.c : 75 14 20
linux/arch/arm/mach-sa1100/sa1111.c : 338 104 163
linux/arch/arm/mach-sa1100/sa1111.h : 35 28 2
linux/arch/arm/mach-sa1100/xp860.c : 28 18 1
linux/arch/arm/mm/extable.c : 37 12 4
linux/arch/arm/mm/fault-armv.c : 11 1 1
linux/arch/arm/mm/fault-common.c : 35 8 4
linux/arch/arm/mm/init.c : 102 31 15
linux/arch/arm/mm/mm-ftvpci.c : 32 32 0
linux/arch/arm/mm/mm-nexuspci.c : 32 0 32
linux/arch/arm/mm/proc-arm720.S : 121 77 3
linux/arch/arm/tools/Makefile : 20 7 5
linux/arch/arm/tools/getconstants.c : 16 8 2
linux/arch/arm/tools/mach-types : 39 12 3
linux/arch/cris/config.in : 8 1 1
linux/arch/i386/config.in : 16 2 1
linux/arch/i386/defconfig : 99 38 8
linux/arch/i386/kernel/apm.c : 621 274 63
linux/arch/i386/kernel/bluesmoke.c : 88 20 12
linux/arch/i386/kernel/cpuid.c : 4 1 0
linux/arch/i386/kernel/dmi_scan.c : 17 2 2
linux/arch/i386/kernel/entry.S : 7 1 0
linux/arch/i386/kernel/i386_ksyms.c : 8 0 3
linux/arch/i386/kernel/ldt.c : 35 22 0
linux/arch/i386/kernel/microcode.c : 7 1 0
linux/arch/i386/kernel/msr.c : 4 1 0
linux/arch/i386/kernel/mtrr.c : 35 10 5
linux/arch/i386/kernel/pci-irq.c : 8 2 0
linux/arch/i386/kernel/setup.c : 8 1 1
linux/arch/i386/kernel/smp.c : 97 23 35
linux/arch/ia64/config.in : 8 1 1
linux/arch/ia64/sn/io/pci_dma.c : 8 1 1
linux/arch/mips/config.in : 8 1 1
linux/arch/parisc/kernel/ccio-dma.c : 8 1 1
linux/arch/parisc/kernel/ccio-rm-dma.c : 8 1 1
linux/arch/parisc/kernel/pci-dma.c : 8 1 1
linux/arch/parisc/kernel/sba_iommu.c : 8 1 1
linux/arch/ppc/8xx_io/Config.in : 7 0 3
linux/arch/ppc/8xx_io/enet.c : 68 11 17
linux/arch/ppc/8xx_io/fec.c : 30 6 4
linux/arch/ppc/Makefile : 5 1 1
linux/arch/ppc/amiga/config.c : 6 1 1
linux/arch/ppc/boot/prep/misc.c : 52 17 6
linux/arch/ppc/kernel/m8xx_setup.c : 28 5 5
linux/arch/ppc/kernel/prep_pci.c : 376 76 92
linux/arch/ppc/kernel/prep_setup.c : 17 3 3
linux/arch/s390/Makefile : 16 0 10
linux/arch/s390/kernel/Makefile : 8 1 1
linux/arch/s390/kernel/debug.c : 107 80 0
linux/arch/s390/kernel/entry.S : 182 56 20
linux/arch/s390/kernel/gdb-stub.c : 198 38 32
linux/arch/s390/kernel/head.S : 151 59 33
linux/arch/s390/kernel/lowcore.S : 60 0 60
linux/arch/s390/kernel/process.c : 66 14 14
linux/arch/s390/kernel/s390_ksyms.c : 28 6 9
linux/arch/s390/kernel/setup.c : 183 93 29
linux/arch/s390/kernel/signal.c : 310 94 98
linux/arch/s390/kernel/smp.c : 521 150 228
linux/arch/s390/kernel/time.c : 36 7 5
linux/arch/s390/kernel/traps.c : 35 5 3
linux/arch/s390/math-emu/math.c : 272 137 58
linux/arch/s390/mm/extable.c : 51 16 6
linux/arch/s390/mm/fault.c : 201 82 16
linux/arch/s390/mm/init.c : 89 12 51
linux/arch/s390x/Makefile : 16 0 10
linux/arch/s390x/config.in : 7 1 0
linux/arch/s390x/defconfig : 23 3 0
linux/arch/s390x/kernel/Makefile : 19 7 5
linux/arch/s390x/kernel/cpcmd.c : 53 15 10
linux/arch/s390x/kernel/debug.c : 107 80 0
linux/arch/s390x/kernel/entry.S : 203 63 28
linux/arch/s390x/kernel/head.S : 189 72 49
linux/arch/s390x/kernel/ioctl32.c : 16 3 0
linux/arch/s390x/kernel/linux32.c : 120 47 49
linux/arch/s390x/kernel/linux32.h : 9 1 1
linux/arch/s390x/kernel/lowcore.S : 28 0 28
linux/arch/s390x/kernel/mathemu.c : 920 0 920
linux/arch/s390x/kernel/process.c : 66 14 14
linux/arch/s390x/kernel/s390_ksyms.c : 40 7 10
linux/arch/s390x/kernel/setup.c : 184 93 29
linux/arch/s390x/kernel/signal.c : 301 92 97
linux/arch/s390x/kernel/signal32.c : 344 104 103
linux/arch/s390x/kernel/smp.c : 449 127 207
linux/arch/s390x/kernel/time.c : 39 8 6
linux/arch/s390x/kernel/traps.c : 25 3 2
linux/arch/s390x/kernel/wrapper32.S : 23 20 0
linux/arch/s390x/mm/extable.c : 46 13 6
linux/arch/s390x/mm/fault.c : 257 78 42
linux/arch/s390x/mm/init.c : 108 14 54
linux/arch/sh/Makefile : 33 2 11
linux/arch/sh/config.in : 36 21 2
linux/arch/sh/defconfig : 6 0 2
linux/arch/sh/kernel/io_generic.c : 5 1 1
linux/arch/sh/kernel/io_hd64461.c : 6 1 1
linux/arch/sh/kernel/io_se.c : 5 1 1
linux/arch/sh/kernel/process.c : 5 1 1
linux/arch/sh/kernel/ptrace.c : 5 1 1
linux/arch/sh/kernel/signal.c : 7 1 0
linux/arch/sh/kernel/sys_sh.c : 21 6 2
linux/arch/sh/lib/memchr.S : 5 1 1
linux/arch/sh/lib/memcpy.S : 5 1 1
linux/arch/sh/lib/memmove.S : 5 1 1
linux/arch/sh/lib/memset.S : 5 1 1
linux/arch/sh/mm/cache-sh3.c : 35 12 5
linux/arch/sh/mm/cache-sh4.c : 30 16 4
linux/arch/sh/mm/fault.c : 26 8 1
linux/arch/sh/mm/init.c : 5 1 1
linux/arch/sparc/kernel/systbls.S : 14 2 2
linux/arch/sparc64/Makefile : 30 11 2
linux/arch/sparc64/defconfig : 72 8 4
linux/arch/sparc64/kernel/dtlb_base.S : 16 3 3
linux/arch/sparc64/kernel/entry.S : 35 3 8
linux/arch/sparc64/kernel/ioctl32.c : 251 225 2
linux/arch/sparc64/kernel/iommu_common.c : 122 22 20
linux/arch/sparc64/kernel/iommu_common.h : 23 3 6
linux/arch/sparc64/kernel/pci_iommu.c : 178 40 26
linux/arch/sparc64/kernel/pci_psycho.c : 15 3 2
linux/arch/sparc64/kernel/pci_sabre.c : 15 3 2
linux/arch/sparc64/kernel/pci_schizo.c : 15 3 2
linux/arch/sparc64/kernel/process.c : 5 1 1
linux/arch/sparc64/kernel/rtrap.S : 20 3 3
linux/arch/sparc64/kernel/sbus.c : 133 33 21
linux/arch/sparc64/kernel/setup.c : 48 16 1
linux/arch/sparc64/kernel/smp.c : 68 62 0
linux/arch/sparc64/kernel/sparc64_ksyms.c : 14 2 2
linux/arch/sparc64/kernel/sys_sparc32.c : 18 7 1
linux/arch/sparc64/kernel/systbls.S : 23 3 3
linux/arch/sparc64/mm/init.c : 115 74 11
linux/arch/sparc64/mm/ultra.S : 38 27 1
linux/arch/sparc64/prom/p1275.c : 66 6 33
linux/drivers/Makefile : 17 2 2
linux/drivers/acorn/block/mfmhd.c : 8 1 1
linux/drivers/acorn/char/mouse_rpc.c : 8 5 0
linux/drivers/acorn/scsi/acornscsi.c : 7 2 0
linux/drivers/acorn/scsi/arxescsi.c : 7 3 0
linux/drivers/acorn/scsi/cumana_2.c : 23 7 6
linux/drivers/acorn/scsi/ecoscsi.c : 8 3 1
linux/drivers/acorn/scsi/eesox.c : 22 5 6
linux/drivers/acorn/scsi/fas216.c : 27 2 14
linux/drivers/acorn/scsi/msgqueue.c : 27 3 14
linux/drivers/acorn/scsi/oak.c : 7 2 0
linux/drivers/acorn/scsi/powertec.c : 23 7 6
linux/drivers/acorn/scsi/queue.c : 27 3 14
linux/drivers/acpi/include/platform/acgcc.h : 7 0 1
linux/drivers/acpi/ospm/thermal/tz_osl.c : 31 8 5
linux/drivers/block/DAC960.c : 1093 529 123
linux/drivers/block/DAC960.h : 392 126 31
linux/drivers/block/acsi.c : 8 1 1
linux/drivers/block/amiflop.c : 8 1 1
linux/drivers/block/ataflop.c : 8 1 1
linux/drivers/block/blkpg.c : 13 3 3
linux/drivers/block/cciss.c : 8 1 1
linux/drivers/block/cpqarray.c : 8 1 1
linux/drivers/block/floppy.c : 8 1 1
linux/drivers/block/genhd.c : 19 0 6
linux/drivers/block/ll_rw_blk.c : 46 6 6
linux/drivers/block/loop.c : 17 2 2
linux/drivers/block/nbd.c : 15 3 1
linux/drivers/block/paride/aten.c : 4 1 0
linux/drivers/block/paride/bpck.c : 4 1 0
linux/drivers/block/paride/comm.c : 4 1 0
linux/drivers/block/paride/dstr.c : 4 1 0
linux/drivers/block/paride/epat.c : 4 1 0
linux/drivers/block/paride/epia.c : 4 1 0
linux/drivers/block/paride/fit2.c : 4 1 0
linux/drivers/block/paride/fit3.c : 4 1 0
linux/drivers/block/paride/friq.c : 4 1 0
linux/drivers/block/paride/frpw.c : 4 1 0
linux/drivers/block/paride/kbic.c : 4 1 0
linux/drivers/block/paride/ktti.c : 4 1 0
linux/drivers/block/paride/on20.c : 4 1 0
linux/drivers/block/paride/on26.c : 4 1 0
linux/drivers/block/paride/paride.c : 4 1 0
linux/drivers/block/paride/pcd.c : 4 1 0
linux/drivers/block/paride/pd.c : 26 4 4
linux/drivers/block/paride/pf.c : 4 1 0
linux/drivers/block/paride/pg.c : 4 1 0
linux/drivers/block/paride/ppc6lnx.c : 4 1 0
linux/drivers/block/paride/pt.c : 4 1 0
linux/drivers/block/ps2esdi.c : 11 2 2
linux/drivers/block/rd.c : 8 1 1
linux/drivers/block/xd.c : 8 1 1
linux/drivers/cdrom/cdrom.c : 4 1 0
linux/drivers/char/Config.in : 24 5 1
linux/drivers/char/Makefile : 21 6 0
linux/drivers/char/adbmouse.c : 5 1 1
linux/drivers/char/console.c : 33 13 5
linux/drivers/char/drm/drm_drv.h : 33 20 0
linux/drivers/char/drm/drm_proc.h : 8 1 1
linux/drivers/char/drm/drm_vm.h : 36 9 3
linux/drivers/char/drm/ffb_drv.c : 36 7 5
linux/drivers/char/epca.c : 9 2 1
linux/drivers/char/i810_rng.c : 7 1 0
linux/drivers/char/ib700wdt.c : 272 272 0
linux/drivers/char/ip2main.c : 4 1 0
linux/drivers/char/istallion.c : 8 2 0
linux/drivers/char/joystick/analog.c : 19 4 2
linux/drivers/char/mwave/mwavedd.c : 10 4 0
linux/drivers/char/nwflash.c : 58 5 6
linux/drivers/char/random.c : 435 126 79
linux/drivers/char/sh-sci.c : 8 1 1
linux/drivers/char/shwdt.c : 365 365 0
linux/drivers/char/sonypi.c : 363 109 76
linux/drivers/char/sonypi.h : 136 37 22
linux/drivers/char/toshiba.c : 67 19 5
linux/drivers/fc4/soc.c : 4 1 0
linux/drivers/fc4/socal.c : 4 1 0
linux/drivers/i2c/Config.in : 24 13 0
linux/drivers/i2c/Makefile : 19 5 1
linux/drivers/i2c/i2c-adap-ite.c : 8 1 1
linux/drivers/i2c/i2c-algo-bit.c : 8 1 1
linux/drivers/i2c/i2c-algo-ite.c : 8 1 1
linux/drivers/i2c/i2c-algo-pcf.c : 523 146 209
linux/drivers/i2c/i2c-core.c : 96 44 3
linux/drivers/i2c/i2c-dev.c : 70 23 5
linux/drivers/i2c/i2c-elektor.c : 324 123 99
linux/drivers/i2c/i2c-elv.c : 17 2 2
linux/drivers/i2c/i2c-proc.c : 906 906 0
linux/drivers/i2c/i2c-velleman.c : 8 1 1
linux/drivers/i2o/Config.in : 16 0 16
linux/drivers/i2o/Makefile : 20 0 20
linux/drivers/i2o/README : 98 0 98
linux/drivers/i2o/README.ioctl : 394 0 394
linux/drivers/i2o/i2o_block.c : 2051 0 2051
linux/drivers/i2o/i2o_config.c : 965 0 965
linux/drivers/i2o/i2o_core.c : 3564 0 3564
linux/drivers/i2o/i2o_lan.c : 1577 0 1577
linux/drivers/i2o/i2o_lan.h : 159 0 159
linux/drivers/i2o/i2o_pci.c : 377 0 377
linux/drivers/i2o/i2o_proc.c : 3379 0 3379
linux/drivers/i2o/i2o_scsi.c : 912 0 912
linux/drivers/i2o/i2o_scsi.h : 47 0 47
linux/drivers/ide/hd.c : 8 1 1
linux/drivers/ide/hptraid.c : 19 4 2
linux/drivers/ide/hptraid.h : 33 29 1
linux/drivers/ide/ide-cd.c : 13 2 1
linux/drivers/ide/ide-disk.c : 4 1 0
linux/drivers/ide/ide-floppy.c : 4 1 0
linux/drivers/ide/ide-probe.c : 5 1 0
linux/drivers/ide/ide.c : 16 2 1
linux/drivers/ide/pdcraid.c : 10 2 2
linux/drivers/ide/rapide.c : 7 1 0
linux/drivers/ieee1394/Makefile : 13 2 2
linux/drivers/ieee1394/ieee1394.h : 11 4 1
linux/drivers/ieee1394/ieee1394_core.c : 90 71 0
linux/drivers/ieee1394/ieee1394_types.h : 34 21 0
linux/drivers/ieee1394/nodemgr.c : 24 3 8
linux/drivers/ieee1394/sbp2.c : 1098 166 162
linux/drivers/ieee1394/sbp2.h : 35 4 11
linux/drivers/input/keybdev.c : 4 1 0
linux/drivers/macintosh/macserial.c : 8 2 0
linux/drivers/macintosh/nvram.c : 4 1 0
linux/drivers/macintosh/rtc.c : 4 1 0
linux/drivers/md/lvm.c : 8 1 1
linux/drivers/md/md.c : 20 4 2
linux/drivers/md/raid1.c : 9 2 1
linux/drivers/md/raid5.c : 40 18 16
linux/drivers/media/video/bttv-cards.c : 665 278 59
linux/drivers/media/video/bttv-driver.c : 108 35 25
linux/drivers/media/video/bttv-if.c : 35 5 4
linux/drivers/media/video/bttv.h : 64 17 2
linux/drivers/media/video/bttvp.h : 25 7 3
linux/drivers/media/video/bw-qcam.c : 59 16 17
linux/drivers/media/video/id.h : 6 3 0
linux/drivers/media/video/msp3400.c : 233 53 31
linux/drivers/media/video/planb.c : 53 14 15
linux/drivers/media/video/saa7110.c : 8 1 1
linux/drivers/media/video/tda7432.c : 7 0 1
linux/drivers/media/video/tda9875.c : 7 0 1
linux/drivers/media/video/tuner.c : 522 381 20
linux/drivers/media/video/tuner.h : 67 23 12
linux/drivers/media/video/tvaudio.c : 298 205 3
linux/drivers/media/video/tvaudio.h : 7 1 0
linux/drivers/media/video/tvmixer.c : 66 20 22
linux/drivers/media/video/videodev.c : 77 2 37
linux/drivers/message/fusion/isense.c : 7 1 0
linux/drivers/message/i2o/Config.in : 16 16 0
linux/drivers/message/i2o/Makefile : 20 20 0
linux/drivers/message/i2o/README : 98 98 0
linux/drivers/message/i2o/README.ioctl : 394 394 0
linux/drivers/message/i2o/i2o_block.c : 2043 2043 0
linux/drivers/message/i2o/i2o_config.c : 966 966 0
linux/drivers/message/i2o/i2o_core.c : 3591 3591 0
linux/drivers/message/i2o/i2o_lan.c : 1579 1579 0
linux/drivers/message/i2o/i2o_lan.h : 159 159 0
linux/drivers/message/i2o/i2o_pci.c : 391 391 0
linux/drivers/message/i2o/i2o_proc.c : 3377 3377 0
linux/drivers/message/i2o/i2o_scsi.c : 923 923 0
linux/drivers/message/i2o/i2o_scsi.h : 47 47 0
linux/drivers/mtd/Config.in : 14 4 4
linux/drivers/mtd/ftl.c : 8 1 1
linux/drivers/mtd/mtdblock.c : 8 1 1
linux/drivers/mtd/mtdblock_ro.c : 8 1 1
linux/drivers/mtd/nftlcore.c : 8 1 1
linux/drivers/net/8139cp.c : 1325 1325 0
linux/drivers/net/8139too.c : 110 20 7
linux/drivers/net/Config.in : 16 2 1
linux/drivers/net/Makefile : 7 1 0
linux/drivers/net/a2065.c : 4 1 0
linux/drivers/net/acenic.c : 364 72 103
linux/drivers/net/acenic.h : 48 2 22
linux/drivers/net/atari_bionet.c : 7 1 0
linux/drivers/net/atari_pamsnet.c : 7 1 0
linux/drivers/net/atarilance.c : 7 1 0
linux/drivers/net/bagetlance.c : 7 1 0
linux/drivers/net/bmac.c : 7 1 0
linux/drivers/net/fealnx.c : 7 1 0
linux/drivers/net/fmv18x.c : 7 1 0
linux/drivers/net/gmac.c : 7 1 0
linux/drivers/net/gt96100eth.c : 4 1 0
linux/drivers/net/hamradio/scc.c : 33 6 3
linux/drivers/net/hplance.c : 7 1 0
linux/drivers/net/hydra.c : 4 1 0
linux/drivers/net/ibmlana.c : 7 1 0
linux/drivers/net/ioc3-eth.c : 7 1 0
linux/drivers/net/isa-skeleton.c : 7 1 0
linux/drivers/net/lasi_82596.c : 7 1 0
linux/drivers/net/mac89x0.c : 7 1 0
linux/drivers/net/mace.c : 7 1 0
linux/drivers/net/macsonic.c : 7 1 0
linux/drivers/net/mvme147.c : 8 2 0
linux/drivers/net/myri_sbus.c : 4 1 0
linux/drivers/net/ne2.c : 7 1 0
linux/drivers/net/oaknet.c : 4 1 0
linux/drivers/net/pci-skeleton.c : 7 1 0
linux/drivers/net/pcmcia/netwave_cs.c : 17 9 2
linux/drivers/net/pcmcia/ray_cs.c : 15 6 3
linux/drivers/net/pcmcia/wavelan_cs.c : 12 6 0
linux/drivers/net/pcmcia/wavelan_cs.h : 26 13 6
linux/drivers/net/pcmcia/xircom_tulip_cb.c : 102 28 17
linux/drivers/net/pcnet32.c : 13 6 0
linux/drivers/net/ppp_generic.c : 4 1 0
linux/drivers/net/ppp_synctty.c : 18 1 7
linux/drivers/net/saa9730.c : 4 1 0
linux/drivers/net/seeq8005.c : 7 1 0
linux/drivers/net/sk98lin/skge.c : 129 38 29
linux/drivers/net/sk_g16.c : 7 1 0
linux/drivers/net/sk_mca.c : 7 1 0
linux/drivers/net/smc-mca.c : 7 1 0
linux/drivers/net/smc9194.c : 7 1 0
linux/drivers/net/stnic.c : 4 1 0
linux/drivers/net/sun3lance.c : 7 1 0
linux/drivers/net/sunbmac.c : 4 1 0
linux/drivers/net/sundance.c : 310 129 53
linux/drivers/net/sungem.c : 1177 598 218
linux/drivers/net/sungem.h : 106 52 1
linux/drivers/net/sunhme.c : 5 1 1
linux/drivers/net/sunlance.c : 4 1 0
linux/drivers/net/sunqe.c : 10 2 1
linux/drivers/net/tulip/interrupt.c : 28 5 3
linux/drivers/net/tulip/tulip_core.c : 10 2 2
linux/drivers/net/via-rhine.c : 19 1 5
linux/drivers/net/wavelan.c : 10 4 0
linux/drivers/net/wavelan.p.h : 19 6 6
linux/drivers/net/wireless/airo.c : 2145 487 431
linux/drivers/net/wireless/airport.c : 7 1 0
linux/drivers/net/yellowfin.c : 41 7 4
linux/drivers/nubus/nubus_syms.c : 8 2 0
linux/drivers/parport/ieee1284_ops.c : 17 2 2
linux/drivers/parport/parport_amiga.c : 7 1 0
linux/drivers/parport/parport_atari.c : 7 1 0
linux/drivers/parport/parport_pc.c : 8 2 0
linux/drivers/pci/gen-devlist.c : 7 1 0
linux/drivers/pci/pci.c : 67 20 8
linux/drivers/pci/pci.ids : 343 224 49
linux/drivers/pcmcia/Makefile : 33 23 0
linux/drivers/pcmcia/cs.c : 30 8 2
linux/drivers/pcmcia/sa1100.h : 202 202 0
linux/drivers/pcmcia/sa1100_adsbitsy.c : 216 216 0
linux/drivers/pcmcia/sa1100_assabet.c : 149 149 0
linux/drivers/pcmcia/sa1100_cerf.c : 150 150 0
linux/drivers/pcmcia/sa1100_flexanet.c : 84 84 0
linux/drivers/pcmcia/sa1100_freebird.c : 160 160 0
linux/drivers/pcmcia/sa1100_generic.c : 1168 1168 0
linux/drivers/pcmcia/sa1100_graphicsclient.c : 154 154 0
linux/drivers/pcmcia/sa1100_graphicsmaster.c : 215 215 0
linux/drivers/pcmcia/sa1100_h3600.c : 147 147 0
linux/drivers/pcmcia/sa1100_jornada720.c : 215 215 0
linux/drivers/pcmcia/sa1100_neponset.c : 248 248 0
linux/drivers/pcmcia/sa1100_pangolin.c : 157 157 0
linux/drivers/pcmcia/sa1100_pfs168.c : 237 237 0
linux/drivers/pcmcia/sa1100_simpad.c : 136 136 0
linux/drivers/pcmcia/sa1100_stork.c : 202 202 0
linux/drivers/pcmcia/sa1100_xp860.c : 255 255 0
linux/drivers/pcmcia/sa1100_yopy.c : 139 139 0
linux/drivers/pnp/isapnp.c : 68 14 7
linux/drivers/s390/block/dasd.c : 201 52 42
linux/drivers/s390/block/dasd_3990_erp.c : 8 1 1
linux/drivers/s390/block/xpram.c : 17 2 2
linux/drivers/s390/char/Makefile : 7 1 0
linux/drivers/s390/char/hwc_cpi.c : 8 1 1
linux/drivers/s390/char/tape34xx.c : 17 3 1
linux/drivers/s390/char/tapechar.c : 14 1 5
linux/drivers/s390/char/tuball.c : 10 2 2
linux/drivers/s390/char/tubtty.c : 10 2 2
linux/drivers/s390/net/ctcmain.c : 115 14 11
linux/drivers/s390/net/iucv.c : 47 5 8
linux/drivers/s390/net/netiucv.c : 43 6 5
linux/drivers/sbus/audio/amd7930.c : 13 2 1
linux/drivers/sbus/char/aurora.c : 90 14 30
linux/drivers/sbus/char/bpp.c : 4 0 1
linux/drivers/sbus/char/jsflash.c : 8 1 1
linux/drivers/sbus/char/sab82532.c : 268 70 136
linux/drivers/sbus/char/su.c : 66 14 17
linux/drivers/sbus/char/zs.c : 115 23 34
linux/drivers/scsi/53c700.c : 464 145 95
linux/drivers/scsi/53c700.h : 98 42 10
linux/drivers/scsi/Config.in : 12 2 1
linux/drivers/scsi/README.53c700 : 163 146 9
linux/drivers/scsi/aha152x.c : 84 35 24
linux/drivers/scsi/aha1542.c : 22 2 4
linux/drivers/scsi/aic7xxx_old.c : 11 0 5
linux/drivers/scsi/dpt_i2o.c : 56 9 9
linux/drivers/scsi/i60uscsi.h : 20 2 5
linux/drivers/scsi/i91uscsi.h : 20 2 5
linux/drivers/scsi/ini9100u.h : 28 4 7
linux/drivers/scsi/inia100.h : 21 3 5
linux/drivers/scsi/osst.c : 23 0 3
linux/drivers/scsi/pcmcia/nsp_cs.c : 150 17 27
linux/drivers/scsi/pcmcia/nsp_cs.h : 66 18 12
linux/drivers/scsi/pcmcia/nsp_debug.c : 17 2 2
linux/drivers/scsi/pcmcia/nsp_io.h : 13 2 2
linux/drivers/scsi/pcmcia/nsp_message.c : 8 1 1
linux/drivers/scsi/qlogicfc.c : 421 82 111
linux/drivers/scsi/qlogicfc.h : 13 0 5
linux/drivers/scsi/scsi.c : 17 2 2
linux/drivers/scsi/scsi.h : 18 4 1
linux/drivers/scsi/scsi_debug.c : 24 1 10
linux/drivers/scsi/scsi_lib.c : 49 17 10
linux/drivers/scsi/scsi_merge.c : 104 30 12
linux/drivers/scsi/scsi_scan.c : 10 4 0
linux/drivers/scsi/sd.c : 36 7 2
linux/drivers/scsi/sr.c : 68 18 6
linux/drivers/scsi/sr_ioctl.c : 8 1 1
linux/drivers/scsi/st.c : 23 0 3
linux/drivers/scsi/sym53c8xx.c : 205 53 42
linux/drivers/scsi/sym53c8xx_comm.h : 8 1 1
linux/drivers/scsi/sym53c8xx_defs.h : 42 1 21
linux/drivers/sgi/char/graphics.c : 8 2 0
linux/drivers/sound/btaudio.c : 24 18 0
linux/drivers/sound/cmpci.c : 34 4 3
linux/drivers/sound/ite8172.c : 8 1 1
linux/drivers/sound/maestro3.c : 73 9 9
linux/drivers/sound/nec_vrc5477.c : 8 1 1
linux/drivers/sound/opl3sa2.c : 25 6 6
linux/drivers/sound/sb_card.c : 31 11 0
linux/drivers/sound/trident.c : 176 41 28
linux/drivers/sound/vidc.c : 8 5 0
linux/drivers/sound/ymfpci.c : 102 24 28
linux/drivers/tc/tc.c : 7 1 0
linux/drivers/usb/Config.in : 147 65 54
linux/drivers/usb/devices.c : 17 2 2
linux/drivers/usb/hiddev.c : 17 2 2
linux/drivers/usb/inode.c : 52 7 7
linux/drivers/usb/kaweth.c : 25 3 3
linux/drivers/usb/pegasus.h : 38 8 4
linux/drivers/usb/pwc-ctrl.c : 136 40 29
linux/drivers/usb/pwc-if.c : 228 60 40
linux/drivers/usb/pwc-ioctl.h : 27 11 3
linux/drivers/usb/pwc.h : 19 4 2
linux/drivers/usb/scanner.c : 502 167 52
linux/drivers/usb/scanner.h : 176 52 17
linux/drivers/usb/serial/Config.in : 62 26 30
linux/drivers/usb/serial/ftdi_sio.c : 8 1 1
linux/drivers/usb/uhci.c : 508 135 135
linux/drivers/usb/uhci.h : 15 2 0
linux/drivers/usb/ultracam.c : 12 1 5
linux/drivers/usb/usb-ohci.c : 17 2 2
linux/drivers/usb/usb-uhci.c : 8 1 1
linux/drivers/usb/usb.c : 82 10 9
linux/drivers/usb/usbnet.c : 301 71 49
linux/drivers/usb/uss720.c : 8 1 1
linux/drivers/video/Config.in : 23 0 10
linux/drivers/video/acornfb.c : 16 4 1
linux/drivers/video/amifb.c : 8 1 1
linux/drivers/video/aty/atyfb_base.c : 9 1 2
linux/drivers/video/aty128fb.c : 9 1 2
linux/drivers/video/cgsixfb.c : 23 5 3
linux/drivers/video/controlfb.c : 9 1 2
linux/drivers/video/creatorfb.c : 21 5 3
linux/drivers/video/cyber2000fb.c : 827 259 222
linux/drivers/video/cyber2000fb.h : 69 2 40
linux/drivers/video/cyberfb.c : 9 1 2
linux/drivers/video/dn_cfb8.c : 8 1 1
linux/drivers/video/fbcon-afb.c : 11 3 2
linux/drivers/video/fbcon-cfb16.c : 11 3 2
linux/drivers/video/fbcon-cfb2.c : 11 3 2
linux/drivers/video/fbcon-cfb24.c : 11 3 2
linux/drivers/video/fbcon-cfb32.c : 11 3 2
linux/drivers/video/fbcon-cfb4.c : 11 3 2
linux/drivers/video/fbcon-cfb8.c : 11 3 2
linux/drivers/video/fbcon-hga.c : 13 4 3
linux/drivers/video/fbcon-ilbm.c : 11 3 2
linux/drivers/video/fbcon-iplan2p2.c : 11 3 2
linux/drivers/video/fbcon-iplan2p4.c : 11 3 2
linux/drivers/video/fbcon-iplan2p8.c : 11 3 2
linux/drivers/video/fbcon-mfb.c : 13 4 3
linux/drivers/video/fbcon-sti.c : 13 4 3
linux/drivers/video/fbcon-vga-planes.c : 32 7 5
linux/drivers/video/fbcon.c : 40 7 10
linux/drivers/video/fm2fb.c : 9 1 2
linux/drivers/video/hgafb.c : 33 5 5
linux/drivers/video/igafb.c : 9 1 2
linux/drivers/video/imsttfb.c : 9 1 2
linux/drivers/video/leofb.c : 24 5 3
linux/drivers/video/macfb.c : 8 1 1
linux/drivers/video/matrox/matroxfb_accel.c : 69 15 7
linux/drivers/video/matrox/matroxfb_base.c : 8 1 1
linux/drivers/video/newport_con.c : 17 2 2
linux/drivers/video/platinumfb.c : 9 1 2
linux/drivers/video/promcon.c : 118 36 28
linux/drivers/video/pvr2fb.c : 49 7 6
linux/drivers/video/radeonfb.c : 9 1 2
linux/drivers/video/retz3fb.c : 9 1 2
linux/drivers/video/riva/accel.c : 45 11 8
linux/drivers/video/riva/fbdev.c : 9 1 2
linux/drivers/video/sa1100fb.c : 9 1 2
linux/drivers/video/sgivwfb.c : 9 1 2
linux/drivers/video/sis/sis_main.c : 9 1 2
linux/drivers/video/sstfb.c : 9 1 2
linux/drivers/video/sticon-bmode.c : 37 1 15
linux/drivers/video/sticon.c : 37 1 15
linux/drivers/video/tdfxfb.c : 47 10 12
linux/drivers/video/tgafb.c : 8 1 1
linux/drivers/video/valkyriefb.c : 9 1 2
linux/drivers/video/vesafb.c : 8 1 1
linux/drivers/video/vfb.c : 9 1 2
linux/drivers/video/vga16fb.c : 8 1 1
linux/drivers/video/vgacon.c : 17 2 2
linux/drivers/video/virgefb.c : 8 1 1
linux/fs/attr.c : 8 1 1
linux/fs/binfmt_elf.c : 18 3 2
linux/fs/binfmt_misc.c : 1016 550 347
linux/fs/block_dev.c : 29 0 23
linux/fs/buffer.c : 174 60 44
linux/fs/devfs/util.c : 8 1 1
linux/fs/ext2/Makefile : 8 1 1
linux/fs/ext2/acl.c : 17 0 17
linux/fs/ext2/file.c : 84 2 61
linux/fs/ext2/inode.c : 21 7 1
linux/fs/fat/cache.c : 8 0 2
linux/fs/fat/dir.c : 258 60 49
linux/fs/fat/fatfs_syms.c : 26 1 5
linux/fs/fat/inode.c : 185 37 26
linux/fs/fat/misc.c : 342 46 175
linux/fs/fat/msbuffer.h : 14 0 14
linux/fs/fat/tables.c : 76 0 76
linux/fs/fat/tables.h : 35 0 35
linux/fs/freevxfs/vxfs_super.c : 7 1 0
linux/fs/hfs/catalog.c : 8 1 1
linux/fs/isofs/inode.c : 19 8 5
linux/fs/lockd/clntproc.c : 26 13 0
linux/fs/lockd/svc.c : 7 1 0
linux/fs/lockd/svclock.c : 41 12 7
linux/fs/lockd/svcproc.c : 28 11 8
linux/fs/locks.c : 47 11 2
linux/fs/msdos/namei.c : 8 0 2
linux/fs/namei.c : 16 6 2
linux/fs/namespace.c : 17 3 1
linux/fs/nfs/read.c : 8 1 1
linux/fs/nfs/write.c : 17 2 2
linux/fs/nfsd/nfsctl.c : 7 1 0
linux/fs/nfsd/nfsproc.c : 87 17 14
linux/fs/nfsd/nfssvc.c : 8 1 1
linux/fs/nfsd/nfsxdr.c : 15 0 2
linux/fs/ntfs/fs.c : 7 1 0
linux/fs/open.c : 99 27 10
linux/fs/partitions/check.c : 28 7 1
linux/fs/partitions/msdos.c : 58 8 9
linux/fs/proc/array.c : 14 2 1
linux/fs/proc/proc_misc.c : 32 5 2
linux/fs/proc/root.c : 10 4 0
linux/fs/reiserfs/Makefile : 16 10 0
linux/fs/reiserfs/README : 10 4 0
linux/fs/reiserfs/bitmap.c : 88 12 13
linux/fs/reiserfs/dir.c : 50 3 36
linux/fs/reiserfs/do_balan.c : 914 96 316
linux/fs/reiserfs/file.c : 34 2 11
linux/fs/reiserfs/fix_node.c : 160 26 35
linux/fs/reiserfs/hashes.c : 26 3 3
linux/fs/reiserfs/ibalance.c : 270 63 47
linux/fs/reiserfs/inode.c : 508 135 103
linux/fs/reiserfs/item_ops.c : 109 21 18
linux/fs/reiserfs/journal.c : 91 45 5
linux/fs/reiserfs/lbalance.c : 828 191 177
linux/fs/reiserfs/namei.c : 210 60 33
linux/fs/reiserfs/objectid.c : 63 13 13
linux/fs/reiserfs/prints.c : 399 129 116
linux/fs/reiserfs/stree.c : 383 72 69
linux/fs/reiserfs/super.c : 288 55 56
linux/fs/reiserfs/tail_conversion.c : 41 7 7
linux/fs/super.c : 40 12 2
linux/fs/udf/balloc.c : 412 86 124
linux/fs/udf/dir.c : 8 1 1
linux/fs/udf/file.c : 50 9 13
linux/fs/udf/ialloc.c : 20 2 3
linux/fs/udf/inode.c : 245 43 33
linux/fs/udf/lowlevel.c : 8 1 1
linux/fs/udf/namei.c : 89 5 17
linux/fs/udf/super.c : 357 109 103
linux/fs/udf/truncate.c : 53 6 9
linux/fs/udf/udfdecl.h : 50 11 12
linux/fs/ufs/dir.c : 474 447 0
linux/fs/ufs/ialloc.c : 67 8 16
linux/fs/ufs/inode.c : 200 60 109
linux/fs/ufs/namei.c : 1123 184 824
linux/fs/vfat/namei.c : 782 217 332
linux/fs/vfat/vfatfs_syms.c : 8 0 2
linux/include/asm-alpha/bitops.h : 159 35 15
linux/include/asm-alpha/core_cia.h : 9 3 0
linux/include/asm-alpha/core_mcpcia.h : 8 2 0
linux/include/asm-alpha/core_titan.h : 20 6 2
linux/include/asm-alpha/core_tsunami.h : 8 1 1
linux/include/asm-alpha/machvec.h : 7 1 0
linux/include/asm-alpha/pci.h : 99 33 7
linux/include/asm-alpha/scatterlist.h : 34 15 9
linux/include/asm-alpha/types.h : 12 2 4
linux/include/asm-alpha/vga.h : 16 0 3
linux/include/asm-arm/a.out.h : 7 1 0
linux/include/asm-arm/arch-sa1100/SA-1111.h : 75 46 6
linux/include/asm-arm/arch-sa1100/adsbitsy.h : 14 14 0
linux/include/asm-arm/arch-sa1100/assabet.h : 19 5 1
linux/include/asm-arm/arch-sa1100/bitsy.h : 81 0 81
linux/include/asm-arm/arch-sa1100/dma.h : 15 7 2
linux/include/asm-arm/arch-sa1100/graphicsmaster.h : 66 66 0
linux/include/asm-arm/arch-sa1100/h3600.h : 81 81 0
linux/include/asm-arm/arch-sa1100/hardware.h : 25 10 2
linux/include/asm-arm/arch-sa1100/irqs.h : 20 5 1
linux/include/asm-arm/arch-sa1100/keyboard.h : 192 35 127
linux/include/asm-arm/arch-sa1100/pangolin.h : 49 39 0
linux/include/asm-arm/arch-sa1100/uncompress.h : 63 12 25
linux/include/asm-arm/atomic.h : 11 0 4
linux/include/asm-arm/cpu-multi32.h : 22 10 0
linux/include/asm-arm/cpu-single.h : 22 10 0
linux/include/asm-arm/hardirq.h : 7 1 0
linux/include/asm-arm/hardware/pci_v3.h : 10 4 0
linux/include/asm-arm/io.h : 42 14 9
linux/include/asm-arm/mach/arch.h : 22 5 4
linux/include/asm-arm/param.h : 9 3 0
linux/include/asm-arm/pci.h : 57 18 10
linux/include/asm-arm/pgtable.h : 8 2 0
linux/include/asm-arm/processor.h : 13 7 0
linux/include/asm-arm/scatterlist.h : 7 0 1
linux/include/asm-arm/setup.h : 17 2 2
linux/include/asm-arm/signal.h : 42 12 10
linux/include/asm-arm/uaccess.h : 117 74 6
linux/include/asm-i386/page.h : 8 1 1
linux/include/asm-i386/pci.h : 122 78 4
linux/include/asm-i386/scatterlist.h : 15 6 3
linux/include/asm-i386/smp.h : 8 1 1
linux/include/asm-i386/system.h : 27 11 0
linux/include/asm-i386/types.h : 24 8 1
linux/include/asm-i386/unistd.h : 7 1 0
linux/include/asm-ia64/pci.h : 8 1 1
linux/include/asm-ia64/scatterlist.h : 11 0 5
linux/include/asm-m68k/scatterlist.h : 8 0 2
linux/include/asm-mips/pci.h : 8 1 1
linux/include/asm-mips/scatterlist.h : 8 0 2
linux/include/asm-mips64/pci.h : 8 1 1
linux/include/asm-mips64/scatterlist.h : 8 0 2
linux/include/asm-parisc/pci.h : 8 1 1
linux/include/asm-parisc/scatterlist.h : 8 0 2
linux/include/asm-ppc/pci.h : 236 153 12
linux/include/asm-ppc/ppcboot.h : 8 1 1
linux/include/asm-ppc/scatterlist.h : 35 17 5
linux/include/asm-ppc/types.h : 14 2 1
linux/include/asm-s390/chandev.h : 10 4 0
linux/include/asm-s390/current.h : 8 1 1
linux/include/asm-s390/dasd.h : 7 1 0
linux/include/asm-s390/debug.h : 7 1 0
linux/include/asm-s390/gdb-stub.h : 15 6 2
linux/include/asm-s390/lowcore.h : 50 10 6
linux/include/asm-s390/pgalloc.h : 8 2 0
linux/include/asm-s390/pgtable.h : 115 49 16
linux/include/asm-s390/ptrace.h : 7 1 0
linux/include/asm-s390/scatterlist.h : 8 0 2
linux/include/asm-s390/sigp.h : 35 1 26
linux/include/asm-s390/smp.h : 21 2 7
linux/include/asm-s390/softirq.h : 31 9 6
linux/include/asm-s390/spinlock.h : 91 19 20
linux/include/asm-s390/uaccess.h : 96 61 1
linux/include/asm-s390/ucontext.h : 11 1 3
linux/include/asm-s390/unistd.h : 8 2 0
linux/include/asm-s390/vtoc.h : 135 0 129
linux/include/asm-s390x/chandev.h : 10 4 0
linux/include/asm-s390x/current.h : 8 1 1
linux/include/asm-s390x/dasd.h : 7 1 0
linux/include/asm-s390x/debug.h : 7 1 0
linux/include/asm-s390x/lowcore.h : 56 11 7
linux/include/asm-s390x/mathemu.h : 48 0 48
linux/include/asm-s390x/page.h : 11 0 5
linux/include/asm-s390x/param.h : 9 3 0
linux/include/asm-s390x/pgtable.h : 121 50 16
linux/include/asm-s390x/scatterlist.h : 8 0 2
linux/include/asm-s390x/sigp.h : 34 1 24
linux/include/asm-s390x/smp.h : 21 2 7
linux/include/asm-s390x/softirq.h : 31 9 6
linux/include/asm-s390x/spinlock.h : 94 19 24
linux/include/asm-s390x/ucontext.h : 11 1 3
linux/include/asm-s390x/unistd.h : 62 8 6
linux/include/asm-sh/ioctl.h : 5 1 1
linux/include/asm-sh/namei.h : 5 1 1
linux/include/asm-sh/pci.h : 8 1 1
linux/include/asm-sh/scatterlist.h : 8 0 2
linux/include/asm-sh/uaccess.h : 75 50 1
linux/include/asm-sparc/highmem.h : 23 2 4
linux/include/asm-sparc/pci.h : 8 1 1
linux/include/asm-sparc/pgalloc.h : 5 1 1
linux/include/asm-sparc/scatterlist.h : 14 1 3
linux/include/asm-sparc/unistd.h : 14 2 2
linux/include/asm-sparc64/cache.h : 9 2 1
linux/include/asm-sparc64/hardirq.h : 7 1 0
linux/include/asm-sparc64/pci.h : 105 62 4
linux/include/asm-sparc64/pgalloc.h : 43 9 24
linux/include/asm-sparc64/pgtable.h : 35 24 1
linux/include/asm-sparc64/scatterlist.h : 36 15 9
linux/include/asm-sparc64/types.h : 17 3 2
linux/include/asm-sparc64/unistd.h : 14 2 2
linux/include/linux/b1lli.h : 13 4 2
linux/include/linux/b1pcmcia.h : 14 4 2
linux/include/linux/blkdev.h : 36 23 1
linux/include/linux/console_struct.h : 8 1 1
linux/include/linux/ethtool.h : 27 6 1
linux/include/linux/ext2_fs.h : 90 16 27
linux/include/linux/fs.h : 17 3 1
linux/include/linux/genhd.h : 10 2 2
linux/include/linux/i2c-dev.h : 8 1 1
linux/include/linux/i2c-elektor.h : 31 9 5
linux/include/linux/i2c-id.h : 96 39 7
linux/include/linux/i2c-proc.h : 396 396 0
linux/include/linux/i2c.h : 68 17 6
linux/include/linux/i2o-dev.h : 456 171 159
linux/include/linux/i2o.h : 306 69 61
linux/include/linux/locks.h : 8 1 1
linux/include/linux/mm.h : 48 10 7
linux/include/linux/msdos_fs.h : 281 134 103
linux/include/linux/msdos_fs_sb.h : 27 1 6
linux/include/linux/pci.h : 28 5 3
linux/include/linux/pci_ids.h : 17 11 0
linux/include/linux/reiserfs_fs.h : 625 242 98
linux/include/linux/reiserfs_fs_i.h : 12 6 0
linux/include/linux/reiserfs_fs_sb.h : 117 69 22
linux/include/linux/slab.h : 8 1 1
linux/include/linux/sonypi.h : 15 6 3
linux/include/linux/spinlock.h : 10 4 0
linux/include/linux/swap.h : 9 0 2
linux/include/linux/udf_fs.h : 10 2 2
linux/include/linux/udf_fs_sb.h : 19 1 5
linux/include/linux/ufs_fs.h : 23 9 1
linux/include/linux/usb.h : 8 1 1
linux/include/linux/videodev.h : 24 1 11
linux/include/linux/vt_buffer.h : 32 0 19
linux/include/linux/wireless.h : 156 69 9
linux/include/net/route.h : 13 4 1
linux/include/pcmcia/cs_types.h : 14 6 1
linux/include/pcmcia/ss.h : 25 4 1
linux/init/main.c : 14 6 2
linux/ipc/shm.c : 22 5 3
linux/kernel/context.c : 37 8 2
linux/kernel/exit.c : 31 3 10
linux/kernel/ksyms.c : 16 2 1
linux/kernel/sched.c : 7 1 0
linux/lib/vsprintf.c : 106 30 11
linux/mm/filemap.c : 120 61 11
linux/mm/highmem.c : 31 2 2
linux/mm/memory.c : 10 0 2
linux/mm/page_alloc.c : 85 20 19
linux/mm/shmem.c : 101 34 27
linux/mm/swap.c : 38 11 7
linux/mm/swapfile.c : 174 52 27
linux/mm/vmscan.c : 175 39 27
linux/net/ax25/ax25_ip.c : 25 8 3
linux/net/bridge/br.c : 8 1 1
linux/net/core/dev.c : 77 39 4
linux/net/ipv4/ip_output.c : 17 2 2
linux/net/ipv4/ipconfig.c : 15 2 2
linux/net/ipv4/ipip.c : 8 1 1
linux/net/ipv4/route.c : 19 2 4
linux/net/ipv4/syncookies.c : 17 2 2
linux/net/ipv4/tcp_ipv4.c : 136 43 38
linux/net/ipv4/udp.c : 17 2 2
linux/net/ipv6/af_inet6.c : 8 1 1
linux/net/ipv6/netfilter/ip6t_mac.c : 8 1 1
linux/net/ipv6/tcp_ipv6.c : 43 14 9
linux/net/socket.c : 12 2 1
linux/net/sunrpc/sched.c : 26 2 4
linux/net/sunrpc/stats.c : 4 1 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:31 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part01

#!/bin/sh -x
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 01 of a 53 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
if test -r _shar_seq_.tmp; then
echo "Must unpack archives in sequence!"
echo "Please unpack part `cat _shar_seq_.tmp` next"
exit 1
fi
# ============= patch-2.4.13 ==============
if test -f 'patch-2.4.13' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.4.13 (File already exists)'
rm -f _shar_wnt_.tmp;
else
> _shar_wnt_.tmp;
echo 'x - extracting patch-2.4.13 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.4.13' &&
diff -u --recursive --new-file v2.4.12/linux/CREDITS linux/CREDITS
--- v2.4.12/linux/CREDITS Tue Oct 9 17:06:50 2001
+++ linux/CREDITS Sun Oct 21 10:20:57 2001
@@ -999,6 +999,11 @@
X E: phi...@raptor.com
X D: Kernel / timekeeping stuff
X
+N: Jan-Benedict Glaw
+E: jbg...@lug-owl.de
+D: SRM environment driver (for Alpha systems)
+P: 1024D/8399E1BB 250D 3BCF 7127 0D8C A444 A961 1DBD 5E75 8399 E1BB
+
X N: Richard E. Gooch
X E: rgo...@atnf.csiro.au
X D: parent process death signal to children
@@ -2057,10 +2062,11 @@
X S: USA
X
X N: Patrick Mochel
-E: moc...@transmeta.com
+E: p...@osdl.org
+E: moc...@infinity.powertie.org
X D: PCI Power Management, ACPI work
-S: 3940 Freedom Circle
-S: Santa Clara, CA 95054
+S: 15275 SW Koll Parkway, Suite H
+S: Beaverton, OR 97006
X S: USA
X
X N: Eberhard Moenkeberg
diff -u --recursive --new-file v2.4.12/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.12/linux/Documentation/Configure.help Tue Oct 9 17:06:51 2001
+++ linux/Documentation/Configure.help Sat Oct 20 19:17:19 2001
@@ -2568,6 +2568,31 @@
X a module, say M here and read Documentation/modules.txt. If unsure,
X say N.
X
+ACP Modem (Mwave) support
+CONFIG_MWAVE
+ The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
+ kernel driver and a user level application. Together these components
+ support direct attachment to public switched telephone networks (PSTNs)
+ and support selected world wide countries.
+
+ This version of the ACP Modem driver supports the IBM Thinkpad 600E,
+ 600, and 770 that include on board ACP modem hardware.
+
+ The modem also supports the standard communications port interface
+ (ttySx) and is compatible with the Hayes AT Command Set.
+
+ The user level application needed to use this driver can be found at
+ the IBM Linux Technology Center (LTC) web site:
+ http://www.ibm.com/linux/ltc/
+
+ If you own one of the above IBM Thinkpads which has the Mwave chipset
+ in it, say Y.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called mwave.o. If you want to compile it as
+ a module, say M here and read Documentation/modules.txt.
+
X /dev/agpgart (AGP Support) (EXPERIMENTAL)
X CONFIG_AGP
X AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -7675,15 +7700,6 @@
X Support for these adaptors is so far still incomplete and buggy.
X You have been warned.
X
-Hermes PCMCIA card support
-CONFIG_PCMCIA_HERMES
- Enable support for PCMCIA 802.11b cards using the Hermes or Intersil
- HFA384x (Prism 2) chipset. To use your PC-cards, you will need
- supporting software from David Hinds' pcmcia-cs package (see the
- file Documentation/Changes for location). You also want to check out
- the PCMCIA-HOWTO, available from
- http://www.linuxdoc.org/docs.html#howto .
-
X Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)
X CONFIG_PCMCIA_HERMES
X A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
@@ -8850,6 +8866,18 @@
X module, say M here and read Documentation/modules.txt as well as
X Documentation/networking/net-modules.txt.
X
+RealTek RTL-8139C+ 10/100 PCI Fast Ethernet Adapter support
+CONFIG_8139CP
+ This is a driver for the Fast Ethernet PCI network cards based on
+ the RTL8139C+ chips. If you have one of those, say Y and read
+ the Ethernet-HOWTO, available from
+ http://www.linuxdoc.org/docs.html#howto .
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read Documentation/modules.txt. This is recommended.
+ The module will be called 8139cp.o.
+
X RealTek RTL-8139 PCI Fast Ethernet Adapter support
X CONFIG_8139TOO
X This is a driver for the Fast Ethernet PCI network cards based on
@@ -11025,7 +11053,29 @@
X of debug messages to the system log. Select this if you are having a
X problem with USB support and want to see more of what is going on.
X
-UHCI (intel PIIX4, VIA, ...) support?
+USB fetch large config
+CONFIG_USB_LARGE_CONFIG
+ This option changes the initial request for a config descriptor so
+ that some poorly designed devices will still work. Some APC UPSes
+ need it. Basically, the usb subsystem sends a request for a short
+ (8 byte) config, just to find out how large the real config is.
+ Incorrectly implemented devices may choke on this small config
+ request. This option make the initial request for a quite large
+ config (1009 bytes), and things just work.
+
+ If you have an APC UPS, say Y; otherwise say N.
+
+USB long timeout
+CONFIG_USB_LONG_TIMEOUT
+ This option makes the standard time out a bit longer. Basically,
+ some devices are just slow to respond, so this makes usb more
+ patient. There should be no harm in selecting this, but it is
+ needed for some MGE Ellipse UPSes.
+
+ If you have an MGE Ellipse UPS, or you see timeouts in HID
+ transactions, say Y; otherwise say N.
+
+UHCI (intel PIIX4, VIA, ...) support
X CONFIG_USB_UHCI
X The Universal Host Controller Interface is a standard by Intel for
X accessing the USB hardware in the PC (which is also called the USB
@@ -11101,6 +11151,20 @@
X The module will be called hid.o. If you want to compile it as a
X module, say M here and read Documentation/modules.txt.
X
+/dev/usb/hiddev raw HID device support
+CONFIG_USB_HIDDEV
+ Say Y here if you want to support HID devices (from the USB
+ specification standpoint) that aren't strictly user interface
+ devices, like monitor controls and Uninterruptable Power Supplies.
+ It is also used for "consumer keys" on multimedia keyboards and
+ USB speakers.
+
+ This module supports these devices separately using a separate
+ event interface on /dev/usb/hiddevX (char 180:96 to 180:111).
+ This driver requires CONFIG_USB_HID.
+
+ If unsure, say N.
+
X USB HIDBP Keyboard (basic) support
X CONFIG_USB_KBD
X Say Y here if you don't want to use the generic HID driver for your
@@ -11359,8 +11423,7 @@
X and was developed with their support. You must also include
X firmware to support your particular device(s).
X
- See http://www.linuxcare.com.au/hugh/keyspan.html for
- more information.
+ See http://misc.nu/hugh/keyspan.html for more information.
X
X This code is also available as a module ( = code which can be
X inserted in and removed from the running kernel whenever you want).
@@ -11374,6 +11437,20 @@
X USB Keyspan USA-28X Firmware
X CONFIG_USB_SERIAL_KEYSPAN_USA28X
X Say Y here to include firmware for the USA-28X converter.
+ Be sure you have a USA-28X, there are also 28XA and 28XB
+ models, the label underneath has the actual part number.
+
+USB Keyspan USA-28XA Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA
+ Say Y here to include firmware for the USA-28XA converter.
+ Be sure you have a USA-28XA, there are also 28X and 28XB
+ models, the label underneath has the actual part number.
+
+USB Keyspan USA-28XB Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB
+ Say Y here to include firmware for the USA-28XB converter.
+ Be sure you have a USA-28XB, there are also 28X and 28XA
+ models, the label underneath has the actual part number.
X
X USB Keyspan USA-19 Firmware
X CONFIG_USB_SERIAL_KEYSPAN_USA19
@@ -11584,26 +11661,14 @@
X The module will be called se401.o. If you want to compile it as a
X module, say M here and read Documentation/modules.txt.
X
-USB ADMtek Pegasus-based ethernet device support
+Pegasus/Pegasus II based USB-Ethernet device support
X CONFIG_USB_PEGASUS
- Say Y if you want to use your USB ethernet device. Supported
- cards until now are:
- ADMtek AN986 Pegasus (eval. board)
- ADMtek ADM8511 Pegasus II (eval. board)
- Accton 10/100
- Billington USB-100
- Corega FEter USB-TX
- MELCO/BUFFALO LUA-TX
- D-Link DSB-650TX, DSB-650TX-PNA, DSB-650, DU-E10, DU-E100
- Linksys USB100TX, USB10TX
- LANEED Ethernet LD-USB/TX
- SMC 202
- SOHOware NUB Ethernet
-
- Any Pegasus II based board also are supported.
- If you have devices with vendor IDs other than noted above
- you should add them in the driver code and send a message
- to me (pet...@dce.bg) for update.
+ Say Y here if you know you have Pegasus or Pegasus II based adapter.
+ If in doubt then look at linux/drivers/usb/pegasus.h for the complete
+ list of supported devices.
+ If your particular adapter is not in the list and you are _sure_ it
+ is Pegasus or Pegasus II based then send me (pman...@lnxw.com) vendor
+ and device IDs.
X
X This code is also available as a module ( = code which can be
X inserted in and removed from the running kernel whenever you want).
@@ -11685,6 +11750,10 @@
X The module will be called CDCEther.o. If you want to compile it as
X a module, say M here and read <file:Documentation/modules.txt>.
X
+NetChip 1080-based USB Host-to-Host Link
+CONFIG_USB_NET1080
+ The NetChip 1080 is a USB 1.1 host controller. NetChip has a web
+ site with technical information at http://www.netchip.com/ .
X
X USB Kodak DC-2xx Camera support
X CONFIG_USB_DC2XX
@@ -11869,6 +11938,12 @@
X and work. SANE 1.0.4 or newer is needed to make use of your scanner.
X This driver can be compiled as a module.
X
+HP 53xx and Minolta Dual Scanner support
+CONFIG_USB_HPUSBSCSI
+ Say Y here if you want support for the HP 53xx series of scanners
+ and the Minolta Scan Dual. This driver is experimental.
+ The scanner will be accessible as a SCSI device.
+
X USB Bluetooth support
X CONFIG_USB_BLUETOOTH
X Say Y here if you want to connect a USB Bluetooth device to your
@@ -14851,6 +14926,17 @@
X The module is called machzwd.o. If you want to compile it as a module,
X say M here and read Documentation/modules.txt.
X
+SuperH 3/4 Watchdog
+CONFIG_SH_WDT
+ This driver adds watchdog support for the integrated watchdog in the
+ SuperH 3 and 4 processors. If you have one of these processors, say Y,
+ otherwise say N.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module is called shwdt.o. If you want to compile it as a module,
+ say M here and read Documentation/modules.txt.
+
X Toshiba Laptop support
X CONFIG_TOSHIBA
X This adds a driver to safely access the System Management Mode
@@ -16636,6 +16722,121 @@
X found on many Sun machines. Note that many of the newer Ultras
X actually have pc style hardware instead.
X
+# The following options are for Linux when running on the Hitachi
+# SuperH family of RISC microprocessors.
+
+CPU Selection
+CONFIG_CPU_SUBTYPE_SH7707
+ This is the type of your Hitachi SuperH processor. This information is
+ used for optimizing and configuration purposes.
+
+ - "SH7707" for SH7707
+ - "SH7708" for SH7708, SH7708S, SH7708R
+ - "SH7709" for SH7707, SH7709, SH7709A, and SH7729.
+ - "SH7750" for SH7750, SH7750S
+ - "SH7751" for SH7751
+ - "ST40STB1" for ST40STB1
+
+Target machine selection
+CONFIG_SH_GENERIC
+ This is machine type of your target.
+
+ - "Generic" for Generic kernel which might support all of them
+ - "SolutionEngine" for Hitachi SolutionEngine (7709A, 7750, 7750S)
+ - "SolutionEngine7751" for Hitachi SolutionEngine (7751)
+ - "STB1_Harp" for STMicroelectronics HARP
+ - "STB1_Overdrive" for STMicroelectronics Overdrive
+ - "HP620" for HP 'Jornada' 620
+ - "HP680" for HP 'Jornada' 680
+ - "HP690" for HP 'Jornada' 690
+ - "CqREEK" for CQ Publishing CqREEK SH-4
+ - "DMIDA" for DMIDA, industrial data assistant
+ - "EC3104" for Compaq Aero 8000
+ - "Dreamcast" for SEGA Dreamcast
+ - "CAT68701" for CAT 68701 Evaluation Board (SH7708)
+ - "BigSur" for Big Sur Evaluation Board
+ - "SH2000" for SH2000 Evaluation Board (SH7709A)
+ - "ADX" for A&D ADX
+ - "BareCPU" for Bare CPU board such as CqREEK SH-3
+
+ If unsure, select "BareCPU".
+
+Physical memory start address
+CONFIG_MEMORY_START
+ Computers built with Hitachi SuperH processors always
+ map the ROM starting at address zero. But the processor
+ does not specify the range that RAM takes. RAM is usually
+ mapped starting at 0c000000, but it may be elsewhere.
+
+ You should set this value to the address of the lowest
+ RAM location.
+
+ A value of 0c000000 will work for most boards.
+
+Directly Connected Compact Flash support
+CONFIG_CF_ENABLER
+ If your board has "Directly Connected" CompactFlash at area 5 or 6,
+ you may want to enable this option. Then, you can use CF as
+ primary IDE drive (only tested for SanDisk).
+
+ If in doubt, press "n".
+
+SuperH RTC support
+CONFIG_SH_RTC
+ Selecting this option will allow the Linux kernel to emulate
+ PC's RTC.
+
+ If unsure, say N.
+
+SuperH DMAC support
+CONFIG_SH_DMA
+ Selecting this option will provide same API as PC's Direct Memory
+ Access Controller(8237A) for SuperH DMAC.
+
+ If unsure, say N.
+
+SuperH SCI (serial) support
+CONFIG_SH_SCI
+ Selecting this option will allow the Linux kernel to transfer
+ data over SCI (Serial Communication Interface) and/or SCIF
+ which are built into the Hitachi SuperH processor.
+
+ If unsure, say N.
+
+Use LinuxSH standard BIOS
+CONFIG_SH_STANDARD_BIOS
+ Say Y here if your target has the gdb-sh-stub package from
+ www.m17n.org (or any conforming standard LinuxSH BIOS) in FLASH
+ or EPROM. The kernel will use standard BIOS calls during boot
+ for various housekeeping tasks. Note this does not work with
+ WindowsCE machines. If unsure, say N.
+
+Early printk support
+CONFIG_SH_EARLY_PRINTK
+ If you say Y here, the kernel printk routine will begin output to
+ the console much earlier in the boot process, before the serial
+ console is initialised, instead of buffering output. Standard
+ LinuxSH BIOS calls are used for the output. This helps when
+ debugging fatal problems early in the boot sequence. This is only
+ useful for kernel hackers. If unsure, say N.
+
+National Semiconductor DP83902AV 'ST-NIC' support
+CONFIG_STNIC
+ If you have a network adaptor with National Semiconductor DP83902AV,
+ say Y or M (for module).
+
+ If unsure, say N.
+
+CompactFlash Connection Area
+CONFIG_CF_AREA5
+ If your board has "Directly Connected" CompactFlash, You should
+ select the area where your CF is connected to.
+
+ - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
+ - "Area6" if it is connected to Area 6 (0x18000000)
+
+ "Area6" will work for most boards. For ADX, select "Area5".
+
X #
X # m68k-specific kernel options
X # Documented by Chris Lawrence <qua...@themall.net> et al.
@@ -18188,6 +18389,11 @@
X It is also possible to say M here to build it as a module (ds1620.o)
X It is recommended to be used on a NetWinder, but it is not a
X necessity.
+
+Debug high memory support
+CONFIG_DEBUG_HIGHMEM
+ This options enables addition error checking for high memory systems.
+ Disable for production systems.
X
X Verbose kernel error messages
X CONFIG_DEBUG_ERRORS
diff -u --recursive --new-file v2.4.12/linux/Documentation/DMA-mapping.txt linux/Documentation/DMA-mapping.txt
--- v2.4.12/linux/Documentation/DMA-mapping.txt Mon Aug 27 12:41:37 2001
+++ linux/Documentation/DMA-mapping.txt Fri Oct 12 15:35:53 2001
@@ -6,14 +6,15 @@
X Jakub Jelinek <ja...@redhat.com>
X
X Most of the 64bit platforms have special hardware that translates bus
-addresses (DMA addresses) to physical addresses similarly to how page
-tables and/or TLB translate virtual addresses to physical addresses.
-This is needed so that e.g. PCI devices can access with a Single Address
-Cycle (32bit DMA address) any page in the 64bit physical address space.
-Previously in Linux those 64bit platforms had to set artificial limits on
-the maximum RAM size in the system, so that the virt_to_bus() static scheme
-works (the DMA address translation tables were simply filled on bootup
-to map each bus address to the physical page __pa(bus_to_virt())).
+addresses (DMA addresses) into physical addresses. This is similar to
+how page tables and/or a TLB translates virtual addresses to physical
+addresses on a cpu. This is needed so that e.g. PCI devices can
+access with a Single Address Cycle (32bit DMA address) any page in the
+64bit physical address space. Previously in Linux those 64bit
+platforms had to set artificial limits on the maximum RAM size in the
+system, so that the virt_to_bus() static scheme works (the DMA address
+translation tables were simply filled on bootup to map each bus
+address to the physical page __pa(bus_to_virt())).
X
X So that Linux can use the dynamic DMA mapping, it needs some help from the
X drivers, namely it has to take into account that DMA addresses should be
@@ -28,9 +29,10 @@
X
X #include <linux/pci.h>
X
-is in your driver. This file will obtain for you the definition of
-the dma_addr_t type which should be used everywhere you hold a DMA
-(bus) address returned from the DMA mapping functions.
+is in your driver. This file will obtain for you the definition of the
+dma_addr_t (which can hold any valid DMA address for the platform)
+type which should be used everywhere you hold a DMA (bus) address
+returned from the DMA mapping functions.
X
X What memory is DMA'able?
X
@@ -49,7 +51,8 @@
X _underlying_ memory mapped into a vmalloc() area, but this requires
X walking page tables to get the physical addresses, and then
X translating each of those pages back to a kernel address using
-something like __va().
+something like __va(). [ EDIT: Update this when we integrate
+Gerd Knorr's generic code which does this. ]
X
X This rule also means that you may not use kernel image addresses
X (ie. items in the kernel's data/text/bss segment, or your driver's)
@@ -65,60 +68,96 @@
X
X Does your device have any DMA addressing limitations? For example, is
X your device only capable of driving the low order 24-bits of address
-on the PCI bus for DMA transfers? If your device can handle any PCI
-dma address fully, then please skip to the next section, the rest of
-this section does not concern your device.
+on the PCI bus for SAC DMA transfers? If so, you need to inform the
+PCI layer of this fact.
+
+By default, the kernel assumes that your device can address the full
+32-bits in a SAC cycle. For a 64-bit DAC capable device, this needs
+to be increased. And for a device with limitations, as discussed in
+the previous paragraph, it needs to be decreased.
X
X For correct operation, you must interrogate the PCI layer in your
X device probe routine to see if the PCI controller on the machine can
-properly support the DMA addressing limitation your device has. This
-query is performed via a call to pci_dma_supported():
+properly support the DMA addressing limitation your device has. It is
+good style to do this even if your device holds the default setting,
+because this shows that you did think about these issues wrt. your
+device.
+
+The query is performed via a call to pci_set_dma_mask():
X
- int pci_dma_supported(struct pci_dev *pdev, dma_addr_t device_mask)
+ int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
X
X Here, pdev is a pointer to the PCI device struct of your device, and
X device_mask is a bit mask describing which bits of a PCI address your
-device supports. It returns non-zero if your card can perform DMA
-properly on the machine. If it returns zero, your device can not
-perform DMA properly on this platform, and attempting to do so will
-result in undefined behavior.
+device supports. It returns zero if your card can perform DMA
+properly on the machine given the address mask you provided.
X
-In the failure case, you have two options:
-
-1) Use some non-DMA mode for data transfer, if possible.
-2) Ignore this device and do not initialize it.
+If it returns non-zero, your device can not perform DMA properly on
+this platform, and attempting to do so will result in undefined
+behavior. You must either use a different mask, or not use DMA.
+
+This means that in the failure case, you have three options:
+
+1) Use another DMA mask, if possible (see below).
+2) Use some non-DMA mode for data transfer, if possible.
+3) Ignore this device and do not initialize it.
X
X It is recommended that your driver print a kernel KERN_WARNING message
-when you do one of these two things. In this manner, if a user of
-your driver reports that performance is bad or that the device is not
-even detected, you can ask him for the kernel messages to find out
+when you end up performing either #2 or #2. In this manner, if a user
+of your driver reports that performance is bad or that the device is not
+even detected, you can ask them for the kernel messages to find out
X exactly why.
X
-So if, for example, you device can only drive the low 24-bits of
-address during PCI bus mastering you might do something like:
+The standard 32-bit addressing PCI device would do something like
+this:
X
- if (! pci_dma_supported(pdev, 0x00ffffff))
+ if (pci_set_dma_mask(pdev, 0xffffffff)) {
+ printk(KERN_WARNING
+ "mydev: No suitable DMA available.\n");
X goto ignore_this_device;
+ }
X
-When DMA is possible for a given mask, the PCI layer must be informed of the
-mask for later allocation operations on the device. This is achieved by
-setting the dma_mask member of the pci_dev structure, like so:
-
-#define MY_HW_DMA_MASK 0x00ffffff
-
- if (! pci_dma_supported(pdev, MY_HW_DMA_MASK))
+Another common scenario is a 64-bit capable device. The approach
+here is to try for 64-bit DAC addressing, but back down to a
+32-bit mask should that fail. The PCI platform code may fail the
+64-bit mask not because the platform is not capable of 64-bit
+addressing. Rather, it may fail in this case simply because
+32-bit SAC addressing is done more efficiently than DAC addressing.
+Sparc64 is one platform which behaves in this way.
+
+Here is how you would handle a 64-bit capable device which can drive
+all 64-bits during a DAC cycle:
+
+ int using_dac;
+
+ if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
+ using_dac = 1;
+ } else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
+ using_dac = 0;
+ } else {
+ printk(KERN_WARNING
+ "mydev: No suitable DMA available.\n");
X goto ignore_this_device;
+ }
X
- pdev->dma_mask = MY_HW_DMA_MASK;
+If your 64-bit device is going to be an enormous consumer of DMA
+mappings, this can be problematic since the DMA mappings are a
+finite resource on many platforms. Please see the "DAC Addressing
+for Address Space Hungry Devices" setion near the end of this
+document for how to handle this case.
X
-A helper function is provided which performs this common code sequence:
+Finally, if your device can only drive the low 24-bits of
+address during PCI bus mastering you might do something like:
X
- int pci_set_dma_mask(struct pci_dev *pdev, dma_addr_t device_mask)
+ if (pci_set_dma_mask(pdev, 0x00ffffff)) {
+ printk(KERN_WARNING
+ "mydev: 24-bit DMA addressing not available.\n");
+ goto ignore_this_device;
+ }
X
-Unlike pci_dma_supported(), this returns -EIO when the PCI layer will not be
-able to DMA with addresses restricted by that mask, and returns 0 when DMA
-transfers are possible. If the call succeeds, the dma_mask will have been
-updated so that your driver need not worry about it.
+When pci_set_dma_mask() is successful, and returns zero, the PCI layer
+saves away this mask you have provided. The PCI layer will use this
+information later when you make DMA mappings.
X
X There is a case which we are aware of at this time, which is worth
X mentioning in this documentation. If your device supports multiple
@@ -169,6 +208,10 @@
X
X Think of "consistent" as "synchronous" or "coherent".
X
+ Consistent DMA mappings are always SAC addressable. That is
+ to say, consistent DMA addresses given to the driver will always
+ be in the low 32-bits of the PCI bus space.
+
X Good examples of what to use consistent mappings for are:
X
X - Network card DMA ring descriptors.
@@ -230,15 +273,26 @@
X specific (and often is private to the bus which the device is attached
X to).
X
-Size is the length of the region you want to allocate.
+Size is the length of the region you want to allocate, in bytes.
X
X This routine will allocate RAM for that region, so it acts similarly to
X __get_free_pages (but takes size instead of a page order). If your
X driver needs regions sized smaller than a page, you may prefer using
X the pci_pool interface, described below.
X
-It returns two values: the virtual address which you can use to access
-it from the CPU and dma_handle which you pass to the card.
+The consistent DMA mapping interfaces, for non-NULL dev, will always
+return a DMA address which is SAC (Single Address Cycle) addressible.
+Even if the device indicates (via PCI dma mask) that it may address
+the upper 32-bits and thus perform DAC cycles, consistent allocation
+will still only return 32-bit PCI addresses for DMA. This is true
+of the pci_pool interface as well.
+
+In fact, as mentioned above, all consistent memory provided by the
+kernel DMA APIs are always SAC addressable.
+
+pci_alloc_consistent returns two values: the virtual address which you
+can use to access it from the CPU and dma_handle which you pass to the
+card.
X
X The cpu return address and the DMA bus master address are both
X guaranteed to be aligned to the smallest PAGE_SIZE order which
@@ -270,14 +324,15 @@
X
X The "name" is for diagnostics (like a kmem_cache name); dev and size
X are as above. The device's hardware alignment requirement for this
-type of data is "align" (a power of two). The flags are SLAB_ flags
-as you'd pass to kmem_cache_create. Not all flags are understood, but
-SLAB_POISON may help you find driver bugs. If you call this in a non-
-sleeping context (f.e. in_interrupt is true or while holding SMP
-locks), pass SLAB_ATOMIC. If your device has no boundary crossing
-restrictions, pass 0 for alloc; passing 4096 says memory allocated
-from this pool must not cross 4KByte boundaries (but at that time it
-may be better to go for pci_alloc_consistent directly instead).
+type of data is "align" (which is expressed in bytes, and must be a
+power of two). The flags are SLAB_ flags as you'd pass to
+kmem_cache_create. Not all flags are understood, but SLAB_POISON may
+help you find driver bugs. If you call this in a non- sleeping
+context (f.e. in_interrupt is true or while holding SMP locks), pass
+SLAB_ATOMIC. If your device has no boundary crossing restrictions,
+pass 0 for alloc; passing 4096 says memory allocated from this pool
+must not cross 4KByte boundaries (but at that time it may be better to
+go for pci_alloc_consistent directly instead).
X
X Allocate memory from a pci pool like this:
X
@@ -318,6 +373,8 @@
X
X PCI_DMA_TODEVICE means "from main memory to the PCI device"
X PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
+It is the direction in which the data moves during the DMA
+transfer.
X
X You are _strongly_ encouraged to specify this as precisely
X as you possibly can.
@@ -333,13 +390,13 @@
X precise direction, and this will help catch cases where your
X direction tracking logic has failed to set things up properly.
X
-Another advantage of specifying this value precisely (outside
-of potential platform-specific optimizations of such) is for
-debugging. Some platforms actually have a write permission
-boolean which DMA mappings can be marked with, much like page
-protections in a user program can have. Such platforms can
-and do report errors in the kernel logs when the PCI controller
-hardware detects violation of the permission setting.
+Another advantage of specifying this value precisely (outside of
+potential platform-specific optimizations of such) is for debugging.
+Some platforms actually have a write permission boolean which DMA
+mappings can be marked with, much like page protections in the user
+program address space. Such platforms can and do report errors in the
+kernel logs when the PCI controller hardware detects violation of the
+permission setting.
X
X Only streaming mappings specify a direction, consistent mappings
X implicitly have a direction attribute setting of
@@ -362,13 +419,17 @@
X
X Using Streaming DMA mappings
X
-The streaming DMA mapping routines can be called from interrupt context.
-There are two versions of each map/unmap, one which map/unmap a single
-memory region, one which map/unmap a scatterlist.
+The streaming DMA mapping routines can be called from interrupt
+context. There are two versions of each map/unmap, one which will
+map/unmap a single memory region, and one which will map/unmap a
+scatterlist.
X
X To map a single region, you do:
X
+ struct pci_dev *pdev = mydev->pdev;
X dma_addr_t dma_handle;
+ void *addr = buffer->ptr;
+ size_t size = buffer->len;
X
X dma_handle = pci_map_single(dev, addr, size, direction);
X
@@ -377,9 +438,29 @@
X pci_unmap_single(dev, dma_handle, size, direction);
X
X You should call pci_unmap_single when the DMA activity is finished, e.g.
-from interrupt which told you the DMA transfer is done.
+from the interrupt which told you that the DMA transfer is done.
X
-Similarly with scatterlists, you map a region gathered from several regions by:
+Using cpu pointers like this for single mappings has a disadvantage,
+you cannot reference HIGHMEM memory in this way. Thus, there is a
+map/unmap interface pair akin to pci_{map,unmap}_single. These
+interfaces deal with page/offset pairs instead of cpu pointers.
+Specifically:
+
+ struct pci_dev *pdev = mydev->pdev;
+ dma_addr_t dma_handle;
+ struct page *page = buffer->page;
+ unsigned long offset = buffer->offset;
+ size_t size = buffer->len;
+
+ dma_handle = pci_map_page(dev, page, offset, size, direction);
+
+ ...
+
+ pci_unmap_page(dev, dma_handle, size, direction);
+
+Here, "offset" means byte offset within the given page.
+
+With scatterlists, you map a region gathered from several regions by:
X
X int i, count = pci_map_sg(dev, sglist, nents, direction);
X struct scatterlist *sg;
@@ -407,7 +488,7 @@
X
X pci_unmap_sg(dev, sglist, nents, direction);
X
-Again, make sure DMA activity finished.
+Again, make sure DMA activity has already finished.
X
X PLEASE NOTE: The 'nents' argument to the pci_unmap_sg call must be
X the _same_ one you passed into the pci_map_sg call,
@@ -421,8 +502,8 @@
X all bus addresses.
X
X If you need to use the same streaming DMA region multiple times and touch
-the data in between the DMA transfers, just map it
-with pci_map_{single,sg}, after each DMA transfer call either:
+the data in between the DMA transfers, just map it with
+pci_map_{single,sg}, and after each DMA transfer call either:
X
X pci_dma_sync_single(dev, dma_handle, size, direction);
X
@@ -430,9 +511,11 @@
X
X pci_dma_sync_sg(dev, sglist, nents, direction);
X
-and after the last DMA transfer call one of the DMA unmap routines
+as appropriate.
+
+After the last DMA transfer call one of the DMA unmap routines
X pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
-call till pci_unmap_*, then you don't have to call the pci_sync_*
+call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
X routines at all.
X
X Here is pseudo code which shows a situation in which you would need
@@ -492,6 +575,119 @@
X supports dynamic DMA mapping in hardware) in your driver structures and/or
X in the card registers.
X
+All PCI drivers should be using these interfaces with no exceptions.
+It is planned to completely remove virt_to_bus() and bus_to_virt() as
+they are entirely deprecated. Some ports already do not provide these
+as it is impossible to correctly support them.
+
+ 64-bit DMA and DAC cycle support
+
+Do you understand all of the text above? Great, then you already
+know how to use 64-bit DMA addressing under Linux. Simply make
+the appropriate pci_set_dma_mask() calls based upon your cards
+capabilities, then use the mapping APIs above.
+
+It is that simple.
+
+Well, not for some odd devices. See the next section for information
+about that.
+
+ DAC Addressing for Address Space Hungry Devices
+
+There exists a class of devices which do not mesh well with the PCI
+DMA mapping API. By definition these "mappings" are a finite
+resource. The number of total available mappings per bus is platform
+specific, but there will always be a reasonable amount.
+
+What is "reasonable"? Reasonable means that networking and block I/O
+devices need not worry about using too many mappings.
+
+As an example of a problematic device, consider compute cluster cards.
+They can potentially need to access gigabytes of memory at once via
+DMA. Dynamic mappings are unsuitable for this kind of access pattern.
+
+To this end we've provided a small API by which a device driver
+may use DAC cycles to directly address all of physical memory.
+Not all platforms support this, but most do. It is easy to determine
+whether the platform will work properly at probe time.
+
+First, understand that there may be a SEVERE performance penalty for
+using these interfaces on some platforms. Therefore, you MUST only
+use these interfaces if it is absolutely required. %99 of devices can
+use the normal APIs without any problems.
+
+Note that for streaming type mappings you must either use these
+interfaces, or the dynamic mapping interfaces above. You may not mix
+usage of both for the same device. Such an act is illegal and is
+guarenteed to put a banana in your tailpipe.
+
+However, consistent mappings may in fact be used in conjunction with
+these interfaces. Remember that, as defined, consistent mappings are
+always going to be SAC addressable.
+
+The first thing your driver needs to do is query the PCI platform
+layer with your devices DAC addressing capabilities:
+
+ int pci_dac_set_dma_mask(struct pci_dev *pdev, u64 mask);
+
+This routine behaves identically to pci_set_dma_mask. You may not
+use the following interfaces if this routine fails.
+
+Next, DMA addresses using this API are kept track of using the
+dma64_addr_t type. It is guarenteed to be big enough to hold any
+DAC address the platform layer will give to you from the following
+routines. If you have consistent mappings as well, you still
+use plain dma_addr_t to keep track of those.
+
+All mappings obtained here will be direct. The mappings are not
+translated, and this is the purpose of this dialect of the DMA API.
+
+All routines work with page/offset pairs. This is the _ONLY_ way to
+portably refer to any piece of memory. If you have a cpu pointer
+(which may be validly DMA'd too) you may easily obtain the page
+and offset using something like this:
+
+ struct page *page = virt_to_page(ptr);
+ unsigned long offset = ((unsigned long)ptr & ~PAGE_MASK);
+
+Here are the interfaces:
+
+ dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+ struct page *page,
+ unsigned long offset,
+ int direction);
+
+The DAC address for the tuple PAGE/OFFSET are returned. The direction
+argument is the same as for pci_{map,unmap}_single(). The same rules
+for cpu/device access apply here as for the streaming mapping
+interfaces. To reiterate:
+
+ The cpu may touch the buffer before pci_dac_page_to_dma.
+ The device may touch the buffer after pci_dac_page_to_dma
+ is made, but the cpu may NOT.
+
+When the DMA transfer is complete, invoke:
+
+ void pci_dac_dma_sync_single(struct pci_dev *pdev,
+ dma64_addr_t dma_addr,
+ size_t len, int direction);
+
+This must be done before the CPU looks at the buffer again.
+This interface behaves identically to pci_dma_sync_{single,sg}().
+
+If you need to get back to the PAGE/OFFSET tuple from a dma64_addr_t
+the following interfaces are provided:
+
+ struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+ dma64_addr_t dma_addr);
+ unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+ dma64_addr_t dma_addr);
+
+This is possible with the DAC interfaces purely because they are
+not translated in any way.
+
+ Closing
+
X This document, and the API itself, would not be in it's current
X form without the feedback and suggestions from numerous individuals.
X We would like to specifically mention, in no particular order, the
@@ -503,3 +699,6 @@
X Grant Grundler <grun...@cup.hp.com>
X Jay Estabrook <Jay.Es...@compaq.com>
X Thomas Sailer <sai...@ife.ee.ethz.ch>
+ Andrea Arcangeli <and...@suse.de>
+ Jens Axboe <ax...@suse.de>
+ David Mosberger-Tang <dav...@hpl.hp.com>
diff -u --recursive --new-file v2.4.12/linux/Documentation/README.DAC960 linux/Documentation/README.DAC960
--- v2.4.12/linux/Documentation/README.DAC960 Thu Dec 7 17:05:41 2000
+++ linux/Documentation/README.DAC960 Wed Oct 17 14:46:29 2001
@@ -1,17 +1,17 @@
X Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
X
- Version 2.2.9 for Linux 2.2.17
- Version 2.4.9 for Linux 2.4.0
+ Version 2.2.11 for Linux 2.2.19
+ Version 2.4.11 for Linux 2.4.12
X
X PRODUCTION RELEASE
X
- 7 September 2000
+ 11 October 2001
X
X Leonard N. Zubkoff
X Dandelion Digital
X l...@dandelion.com
X
- Copyright 1998-2000 by Leonard N. Zubkoff <l...@dandelion.com>
+ Copyright 1998-2001 by Leonard N. Zubkoff <l...@dandelion.com>
X
X
X INTRODUCTION
@@ -20,7 +20,7 @@
X controllers. Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont,
X California 94555, USA and can be reached at 510.796.6100 or on the World Wide
X Web at http://www.mylex.com. Mylex Technical Support can be reached by
-electronic mail at sup...@mylex.com, by voice at 510.608.2400, or by FAX at
+electronic mail at myle...@us.ibm.com, by voice at 510.608.2400, or by FAX at
X 510.745.7715. Contact information for offices in Europe and Japan is available
X on their Web site.
X
@@ -120,7 +120,7 @@
X 100MHz Intel i960RM RISC Processor
X 16MB/32MB/64MB ECC SDRAM Memory
X
-AcceleRAID 160
+AcceleRAID 160 (AcceleRAID 170LP)
X 1 Wide Ultra-160 LVD SCSI channel
X 100MHz Intel i960RS RISC Processor
X Built in 16M ECC SDRAM Memory
@@ -170,6 +170,10 @@
X Intel i960 RISC Processor
X 2MB/4MB/8MB/16MB/32MB DRAM Memory
X
+DAC960P 1/2/3 Wide Fast SCSI-2 Channels
+ Intel i960 RISC Processor
+ 2MB/4MB/8MB/16MB/32MB DRAM Memory
+
X For the eXtremeRAID 2000/3000 and AcceleRAID 352/170/160, firmware version
X 6.00-01 or above is required.
X
@@ -180,36 +184,29 @@
X
X For the DAC960PJ and DAC960PG, firmware version 4.06-0-00 or above is required.
X
-For the DAC960PU, DAC960PD, and DAC960PL, firmware version 3.51-0-04 or above
-is required.
-
-Note that earlier revisions of the DAC960PU, DAC960PD, and DAC960PL controllers
-were delivered with version 2.xx firmware. Version 2.xx firmware is not
-supported by this driver and no support is envisioned. Contact Mylex RAID
-Technical Support to inquire about upgrading controllers with version 2.xx
-firmware to version 3.51-0-04. Upgrading to version 3.xx firmware requires
-installation of higher capacity Flash ROM chips, and not all DAC960PD and
-DAC960PL controllers can be upgraded.
+For the DAC960PU, DAC960PD, DAC960PL, and DAC960P, either firmware version
+3.51-0-04 or above is required (for dual Flash ROM controllers), or firmware
+version 2.73-0-00 or above is required (for single Flash ROM controllers)
X
X Please note that not all SCSI disk drives are suitable for use with DAC960
X controllers, and only particular firmware versions of any given model may
X actually function correctly. Similarly, not all motherboards have a BIOS that
X properly initializes the AcceleRAID 250, AcceleRAID 200, AcceleRAID 150,
X DAC960PJ, and DAC960PG because the Intel i960RD/RP is a multi-function device.
-If in doubt, contact Mylex RAID Technical Support (sup...@mylex.com) to verify
-compatibility. Mylex makes available a hard disk compatibility list by FTP at
-ftp://ftp.mylex.com/pub/dac960/diskcomp.html.
+If in doubt, contact Mylex RAID Technical Support (myle...@us.ibm.com) to
+verify compatibility. Mylex makes available a hard disk compatibility list at
+http://www.mylex.com/support/hdcomp/hd-lists.html.
X
X
X DRIVER INSTALLATION
X
-This distribution was prepared for Linux kernel version 2.2.17 or 2.4.0.
+This distribution was prepared for Linux kernel version 2.2.19 or 2.4.12.
X
X To install the DAC960 RAID driver, you may use the following commands,
X replacing "/usr/src" with wherever you keep your Linux kernel source tree:
X
X cd /usr/src
- tar -xvzf DAC960-2.2.9.tar.gz (or DAC960-2.4.9.tar.gz)
+ tar -xvzf DAC960-2.2.11.tar.gz (or DAC960-2.4.11.tar.gz)
X mv README.DAC960 linux/Documentation
X mv DAC960.[ch] linux/drivers/block
X patch -p0 < DAC960.patch (if DAC960.patch is included)
@@ -374,11 +371,14 @@
X
X The "make-online" command changes the physical drive <channel>:<target-id>
X from status DEAD to status ONLINE. In cases where multiple physical drives
- have been killed simultaneously, this command may be used to bring them
- back online, after which a consistency check is advisable.
+ have been killed simultaneously, this command may be used to bring all but
+ one of them back online, after which a rebuild to the final drive is
+ necessary.
X
X Warning: make-online should only be used on a dead physical drive that is
- an active part of a drive group, never on a standby drive.
+ an active part of a drive group, never on a standby drive. The command
+ should never be used on a dead drive that is part of a critical logical
+ drive; rebuild should be used if only a single drive is dead.
X
X make-standby <channel>:<target-id>
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/README.nsp_cs.eng linux/Documentation/README.nsp_cs.eng
--- v2.4.12/linux/Documentation/README.nsp_cs.eng Wed Jul 25 17:10:16 2001
+++ linux/Documentation/README.nsp_cs.eng Thu Oct 11 11:17:22 2001
@@ -8,9 +8,9 @@
X for Linux.
X
X 2. My Linux environment
-Linux kernel: 2.4.0 / 2.2.18
-pcmcia-cs: 3.1.24
-gcc: gcc-2.95.2
+Linux kernel: 2.4.7 / 2.2.19
+pcmcia-cs: 3.1.27
+gcc: gcc-2.95.4
X PC card: I-O data PCSC-F (NinjaSCSI-3)
X I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
X SCSI device: I-O data CDPS-PX24 (CD-ROM drive)
@@ -55,6 +55,8 @@
X [4] Extract this driver's archive somewhere, and edit Makefile, then do make.
X $ tar -zxvf nsp_cs-x.x.tar.gz
X $ cd nsp_cs-x.x
+$ emacs Makefile
+...
X $ make
X
X [5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
@@ -95,7 +97,7 @@
X bind "nsp_cs"
X -------------------------------------
X
-[7] Boot (or reboot) pcmcia-cs.
+[7] Start (or restart) pcmcia-cs.
X # /etc/rc.d/rc.pcmcia start (BSD style)
X or
X # /etc/init.d/pcmcia start (SYSV style)
@@ -111,7 +113,8 @@
X your data. Please backup your data when you use this driver.
X
X 6. Known Bugs
- Some write error occurs when you use slow device.
+ In 2.4 kernel, you can't use 640MB Optical disk. This error comes from
+high level SCSI driver.
X
X 7. Testing
X Please send me some reports(bug reports etc..) of this software.
@@ -124,4 +127,4 @@
X See GPL.
X
X
-2001/02/01 yok...@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
+2001/08/08 yok...@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/README linux/Documentation/arm/README
--- v2.4.12/linux/Documentation/arm/README Wed Apr 11 19:02:27 2001
+++ linux/Documentation/arm/README Thu Oct 11 09:04:57 2001
@@ -162,7 +162,7 @@
X <description of your architecture>
X
X Please follow this format - it is an automated system. You should
- receive a reply within one day.
+ receive a reply in short order.
X
X ---
X Russell King (26/01/2001)
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/ADSBitsy linux/Documentation/arm/SA1100/ADSBitsy
--- v2.4.12/linux/Documentation/arm/SA1100/ADSBitsy Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/ADSBitsy Thu Oct 11 09:04:57 2001
@@ -0,0 +1,43 @@
+ADS Bitsy Single Board Computer
+(It is different from Bitsy(iPAQ) of Compaq)
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The Linux support for this product has been provided by
+Woojung Huh <wh...@applieddata.net>
+
+Use 'make adsbitsy_config' before any 'make config'.
+This will set up defaults for ADS Bitsy support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- SA1100 serial port
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- console on LCD screen
+- serial ports (ttyS[0-2])
+ - ttyS0 is default for serial console
+
+To do:
+- everything else! :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions.
+ You should be careful to use flash on board.
+ It's partition is different from GraphicsClient Plus and GraphicsMaster
+
+- 16bpp mode requires a different cable than what ships with the board.
+ Contact ADS or look through the manual to wire your own. Currently,
+ if you compile with 16bit mode support and switch into a lower bpp
+ mode, the timing is off so the image is corrupted. This will be
+ fixed soon.
+
+Any contribution can be sent to ni...@cam.org and will be greatly welcome!
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/GraphicsMaster linux/Documentation/arm/SA1100/GraphicsMaster
--- v2.4.12/linux/Documentation/arm/SA1100/GraphicsMaster Wed Dec 31 16:00:00 1969
+++ linux/Documentation/arm/SA1100/GraphicsMaster Thu Oct 11 09:04:57 2001
@@ -0,0 +1,53 @@
+ADS GraphicsMaster Single Board Computer
+
+For more details, contact Applied Data Systems or see
+http://www.applieddata.net/products.html
+
+The original Linux support for this product has been provided by
+Nicolas Pitre <ni...@cam.org>. Continued development work by
+Woojung Huh <wh...@applieddata.net>
+
+Use 'make graphicsmaster_config' before any 'make config'.
+This will set up defaults for GraphicsMaster support.
+
+The kernel zImage is linked to be loaded and executed at 0xc0400000.
+
+Linux can be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+
+Supported peripherals:
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- SA1111 USB Master
+- on-board SMC 92C96 ethernet NIC
+- SA1100 serial port
+- flash memory access (MTD/JFFS)
+- pcmcia, compact flash
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+ - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+ See http://www.applieddata.com/developers/linux for IOCTL documentation
+ and example user space code. ps/2 keybd is multiplexed through this driver
+
+To do:
+- everything else! :-)
+
+Notes:
+
+- The flash on board is divided into 3 partitions. mtd0 is where
+ the zImage is stored. It's been marked as read-only to keep you
+ from blasting over the bootloader. :) mtd1 is
+ for the ramdisk.gz image. mtd2 is user flash space and can be
+ utilized for either JFFS or if you're feeling crazy, running ext2
+ on top of it. If you're not using the ADS bootloader, you're
+ welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+ Contact ADS or look through the manual to wire your own. Currently,
+ if you compile with 16bit mode support and switch into a lower bpp
+ mode, the timing is off so the image is corrupted. This will be
+ fixed soon.
+
+Any contribution can be sent to ni...@cam.org and will be greatly welcome!
diff -u --recursive --new-file v2.4.12/linux/Documentation/arm/SA1100/Pangolin linux/Documentation/arm/SA1100/Pangolin
--- v2.4.12/linux/Documentation/arm/SA1100/Pangolin Sun Sep 23 11:40:54 2001
+++ linux/Documentation/arm/SA1100/Pangolin Thu Oct 11 09:04:57 2001
@@ -2,7 +2,7 @@
X by Dialogue Technology (http://www.dialogue.com.tw/).
X It has EISA slots for ease of configuration with SDRAM/Flash
X memory card, USB/Serial/Audio card, Compact Flash card,
-and TFT-LCD card.
+PCMCIA/IDE card and TFT-LCD card.
X
X To compile for Pangolin, you must issue the following commands:
X
@@ -18,3 +18,7 @@
X - UDA1341 sound driver
X - SA1100 LCD controller for 800x600 16bpp TFT-LCD
X - MQ-200 driver for 800x600 16bpp TFT-LCD
+- Penmount(touch panel) driver
+- PCMCIA driver
+- SMC91C94 LAN driver
+- IDE driver (experimental)
diff -u --recursive --new-file v2.4.12/linux/Documentation/cachetlb.txt linux/Documentation/cachetlb.txt
--- v2.4.12/linux/Documentation/cachetlb.txt Sun Mar 25 18:14:20 2001
+++ linux/Documentation/cachetlb.txt Sun Oct 21 10:40:36 2001
@@ -326,6 +326,12 @@
X update_mmu_cache(), a check is made of this flag bit, and if
X set the flush is done and the flag bit is cleared.
X
+ IMPORTANT NOTE: It is often important, if you defer the flush,
+ that the actual flush occurs on the same CPU
+ as did the cpu stores into the page to make it
+ dirty. Again, see sparc64 for examples of how
+ to deal with this.
+
X void flush_icache_range(unsigned long start, unsigned long end)
X When the kernel stores into addresses that it will execute
X out of (eg when loading modules), this function is called.
diff -u --recursive --new-file v2.4.12/linux/Documentation/cciss.txt linux/Documentation/cciss.txt
--- v2.4.12/linux/Documentation/cciss.txt Sat Feb 3 12:13:19 2001
+++ linux/Documentation/cciss.txt Thu Oct 11 09:04:57 2001
@@ -8,8 +8,9 @@
X * SA 5300
X * SA 5i
X * SA 532
+ * SA 5312
X
-If notes are not already created in the /dev/cciss directory
+If nodes are not already created in the /dev/cciss directory
X
X # mkdev.cciss [ctlrs]
X
@@ -47,3 +48,78 @@
X /dev/cciss/c1d1p1 Controller 1, disk 1, partition 1
X /dev/cciss/c1d1p2 Controller 1, disk 1, partition 2
X /dev/cciss/c1d1p3 Controller 1, disk 1, partition 3
+
+SCSI tape drive and medium changer support
+------------------------------------------
+
+SCSI sequential access devices and medium changer devices are supported and
+appropriate device nodes are automatically created. (e.g.
+/dev/st0, /dev/st1, etc. See the "st" man page for more details.)
+You must enable "SCSI tape drive support for Smart Array 5xxx" and
+"SCSI support" in your kernel configuration to be able to use SCSI
+tape drives with your Smart Array 5xxx controller.
+
+Additionally, note that the driver will not engage the SCSI core at init
+time. The driver must be directed to dynamically engage the SCSI core via
+the /proc filesystem entry which the "block" side of the driver creates as
+/proc/driver/cciss/cciss* at runtime. This is because at driver init time,
+the SCSI core may not yet be initialized (because the driver is a block
+driver) and attempting to register it with the SCSI core in such a case
+would cause a hang. This is best done via an initialization script
+(typically in /etc/init.d, but could vary depending on distibution).
+For example:
+
+ for x in /proc/driver/cciss/cciss[0-9]*
+ do
+ echo "engage scsi" > $x
+ done
+
+Once the SCSI core is engaged by the driver, it cannot be disengaged
+(except by unloading the driver, if it happens to be linked as a module.)
+
+Note also that if no sequential access devices or medium changers are
+detected, the SCSI core will not be engaged by the action of the above
+script.
+
+Hot plug support for SCSI tape drives
+-------------------------------------
+
+Hot plugging of SCSI tape drives is supported, with some caveats.
+The cciss driver must be informed that changes to the SCSI bus
+have been made, in addition to and prior to informing the the SCSI
+mid layer. This may be done via the /proc filesystem. For example:
+
+ echo "rescan" > /proc/scsi/cciss0/1
+
+This causes the adapter to query the adapter about changes to the
+physical SCSI buses and/or fibre channel arbitrated loop and the
+driver to make note of any new or removed sequential access devices
+or medium changers. The driver will output messages indicating what
+devices have been added or removed and the controller, bus, target and
+lun used to address the device. Once this is done, the SCSI mid layer
+can be informed of changes to the virtual SCSI bus which the driver
+presents to it in the usual way. For example:
+
+ echo add-single-device 3 2 1 0 > /proc/scsi/scsi
+
+to add a device on controller 3, bus 2, target 1, lun 0. Note that
+the driver makes an effort to preserve the devices positions
+in the virtual SCSI bus, so if you are only moving tape drives
+around on the same adapter and not adding or removing tape drives
+from the adapter, informing the SCSI mid layer may not be necessary.
+
+Note that the naming convention of the /proc filesystem entries
+contains a number in addition to the driver name. (E.g. "cciss0"
+instead of just "cciss" which you might expect.) This is because
+of changes to the 2.4 kernel PCI interface related to PCI hot plug
+that imply the driver must register with the SCSI mid layer once per
+adapter instance rather than once per driver.
+
+Note: ONLY sequential access devices and medium changers are presented
+as SCSI devices to the SCSI mid layer by the cciss driver. Specifically,
+physical SCSI disk drives are NOT presented to the SCSI mid layer. The
+physical SCSI disk drives are controlled directly by the array controller
+hardware and it is important to prevent the OS from attempting to directly
+access these devices too, as if the array controller were merely a SCSI
+controller in the same way that we are allowing it to access SCSI tape drives.
+
diff -u --recursive --new-file v2.4.12/linux/Documentation/filesystems/devfs/ToDo linux/Documentation/filesystems/devfs/ToDo
--- v2.4.12/linux/Documentation/filesystems/devfs/ToDo Wed Jul 5 21:36:49 2000
+++ linux/Documentation/filesystems/devfs/ToDo Mon Oct 15 13:42:14 2001
@@ -32,7 +32,7 @@
X
X - MFM hard drive (drivers/acorn/block/mfmhd.c)
X
-- I2O block device (drivers/i2o/i2o_block.c)
+- I2O block device (drivers/message/i2o/i2o_block.c)
X
X - ST-RAM device (arch/m68k/atari/stram.c)
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/filesystems/udf.txt linux/Documentation/filesystems/udf.txt
--- v2.4.12/linux/Documentation/filesystems/udf.txt Tue Jul 3 17:08:18 2001
+++ linux/Documentation/filesystems/udf.txt Fri Oct 12 13:48:42 2001
@@ -1,7 +1,7 @@
X *
X * ./Documentation/filesystems/udf.txt
X *
-UDF Filesystem version 0.9.4
+UDF Filesystem version 0.9.5
X
X If you encounter problems with reading UDF discs using this driver,
X please report them to linu...@hpesjro.fc.hp.com, which is the
@@ -23,7 +23,7 @@
X noadinicb Don't embed data in the inode
X shortad Use short ad's
X longad Use long ad's (default)
- strict Set strict conformance
+ nostrict Unset strict conformance
X iocharset= Set the NLS character set
X
X The remaining are for debugging and disaster recovery:
@@ -42,8 +42,8 @@
X
X fileset= Override the fileset block location. (unused)
X rootdir= Override the root directory location. (unused)
- WARNING: overriding the rootdir to a non-directory may
- yield highly unpredictable results.
+ WARNING: overriding the rootdir to a non-directory may
+ yield highly unpredictable results.
X -------------------------------------------------------------------------------
X
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/dev-interface linux/Documentation/i2c/dev-interface
--- v2.4.12/linux/Documentation/i2c/dev-interface Fri Jul 28 12:50:51 2000
+++ linux/Documentation/i2c/dev-interface Thu Oct 11 08:05:47 2001
@@ -70,6 +70,9 @@
X /* buf[0] contains the read byte */
X }
X
+IMPORTANT: because of the use of inline functions, you *have* to use
+'-O' or some variation when you compile your program!
+
X
X Full interface description
X ==========================
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/summary linux/Documentation/i2c/summary
--- v2.4.12/linux/Documentation/i2c/summary Thu Dec 16 13:59:38 1999
+++ linux/Documentation/i2c/summary Thu Oct 11 08:05:47 2001
@@ -1,9 +1,9 @@
-This is an explanation of what i2c is, and what is supported.
+This is an explanation of what i2c is, and what is supported in this package.
X
X I2C and SMBus
X =============
X
-I2C (pronounce: I square C) is a protocol developed by Philips. It is a
+I2C (pronounce: I squared C) is a protocol developed by Philips. It is a
X slow two-wire protocol (10-100 kHz), but it suffices for many types of
X devices.
X
@@ -25,6 +25,7 @@
X Adapter
X Device -> Driver
X Client
+
X An Algorithm driver contains general code that can be used for a whole class
X of I2C adapters. Each specific adapter driver depends on one algorithm
X driver.
@@ -35,29 +36,40 @@
X
X For a given configuration, you will need a driver for your I2C bus (usually
X a separate Adapter and Algorithm driver), and drivers for your I2C devices
-(usually one driver for each device).
+(usually one driver for each device). There are no I2C device drivers
+in this package. See the lm_sensors project http://www.lm-sensors.nu
+for device drivers.
+
X
+Included Bus Drivers
+====================
+Note that not only stable drivers are patched into the kernel by 'mkpatch'.
X
-Included Drivers
-================
X
X Base modules
X ------------
X
X i2c-core: The basic I2C code, including the /proc interface
X i2c-dev: The /dev interface
+i2c-proc: The /proc interface for device (client) drivers
X
X Algorithm drivers
X -----------------
X
-i2c-algo-bit: A bit-banging algorithm
SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi
echo 'End of part 01'
echo 'File patch-2.4.13 is continued in part 02'
echo "02" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:32 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part02

#!/bin/sh -x
# this is part 02 of a 53 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh

# file patch-2.4.13 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 02; 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.13'
else
echo 'x - continuing with patch-2.4.13'


sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

-i2c-algo-pcf: A PCF 8584 style algorithm
+i2c-algo-8xx: An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
+i2c-algo-bit: A bit-banging algorithm
+i2c-algo-pcf: A PCF 8584 style algorithm
+i2c-algo-ppc405: An algorithm for the I2C device in IBM 405xx processors (NOT BUILT BY DEFAULT)
X
X Adapter drivers
X ---------------
X
X i2c-elektor: Elektor ISA card (uses i2c-algo-pcf)
X i2c-elv: ELV parallel port adapter (uses i2c-algo-bit)
+i2c-pcf-epp: PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (BROKEN - missing i2c-pcf-epp.h)
X i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
+i2c-ppc405: IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT)
+i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit)
+i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
X i2c-velleman: Velleman K9000 parallel port adapter (uses i2c-algo-bit)
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/i2c/writing-clients linux/Documentation/i2c/writing-clients
--- v2.4.12/linux/Documentation/i2c/writing-clients Fri Jul 28 12:50:51 2000
+++ linux/Documentation/i2c/writing-clients Thu Oct 11 08:05:47 2001
@@ -33,7 +33,7 @@
X /* detach_client */ &foo_detach_client,
X /* command */ &foo_command, /* May be NULL */
X /* inc_use */ &foo_inc_use, /* May be NULL */
- /* dec_use */ &foo_dev_use /* May be NULL */
+ /* dec_use */ &foo_dec_use /* May be NULL */
X }
X
X The name can be chosen freely, and may be upto 40 characters long. Please
@@ -190,7 +190,7 @@
X detection algorithm.
X
X You do not have to use this parameter interface; but don't try to use
-function i2c_probe() (or sensors_detect()) if you don't.
+function i2c_probe() (or i2c_detect()) if you don't.
X
X NOTE: If you want to write a `sensors' driver, the interface is slightly
X different! See below.
@@ -344,17 +344,17 @@
X return i2c_probe(adapter,&addr_data,&foo_detect_client);
X }
X
-For `sensors' drivers, use the sensors_detect function instead:
+For `sensors' drivers, use the i2c_detect function instead:
X
X int foo_attach_adapter(struct i2c_adapter *adapter)
X {
- return sensors_detect(adapter,&addr_data,&foo_detect_client);
+ return i2c_detect(adapter,&addr_data,&foo_detect_client);
X }
X
X Remember, structure `addr_data' is defined by the macros explained above,
X so you do not have to define it yourself.
X
-The i2c_probe or sensors_detect function will call the foo_detect_client
+The i2c_probe or i2c_detect function will call the foo_detect_client
X function only for those i2c addresses that actually have a device on
X them (unless a `force' parameter was used). In addition, addresses that
X are already in use (by some other registered client) are skipped.
@@ -363,9 +363,9 @@
X The detect client function
X --------------------------
X
-The detect client function is called by i2c_probe or sensors_detect.
+The detect client function is called by i2c_probe or i2c_detect.
X The `kind' parameter contains 0 if this call is due to a `force'
-parameter, and 0 otherwise (for sensors_detect, it contains 0 if
+parameter, and 0 otherwise (for i2c_detect, it contains 0 if
X this call is due to the generic `force' parameter, and the chip type
X number if it is due to a specific `force' parameter).
X
@@ -530,7 +530,7 @@
X /* SENSORS ONLY BEGIN */
X /* Register a new directory entry with module sensors. See below for
X the `template' structure. */
- if ((i = sensors_register_entry(new_client, type_name,
+ if ((i = i2c_register_entry(new_client, type_name,
X foo_dir_table_template,THIS_MODULE)) < 0) {
X err = i;
X goto ERROR4;
@@ -574,8 +574,8 @@
X int err,i;
X
X /* SENSORS ONLY START */
- /* Deregister with the `sensors' module. */
- sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
+ /* Deregister with the `i2c-proc' module. */
+ i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
X /* SENSORS ONLY END */
X
X /* Try to detach the client from i2c space */
@@ -772,12 +772,12 @@
X
X First, I will give an example definition.
X static ctl_table foo_dir_table_template[] = {
- { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real,NULL,&foo_func },
- { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real,NULL,&foo_func },
- { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real,NULL,&foo_data },
+ { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real,NULL,&foo_func },
+ { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real,NULL,&foo_func },
+ { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real,NULL,&foo_data },
X { 0 }
X };
X
@@ -791,8 +791,8 @@
X fourth should always be 0. The fifth is the mode of the /proc file;
X 0644 is safe, as the file will be owned by root:root.
X
-The seventh and eighth parameters should be &sensors_proc_real and
-&sensors_sysctl_real if you want to export lists of reals (scaled
+The seventh and eighth parameters should be &i2c_proc_real and
+&i2c_sysctl_real if you want to export lists of reals (scaled
X integers). You can also use your own function for them, as usual.
X Finally, the last parameter is the call-back to gather the data
X (see below) if you use the *_proc_real functions.
diff -u --recursive --new-file v2.4.12/linux/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- v2.4.12/linux/Documentation/networking/8139too.txt Tue Oct 9 17:06:51 2001
+++ linux/Documentation/networking/8139too.txt Fri Oct 19 08:32:28 2001
@@ -183,6 +183,12 @@
X Change History
X --------------
X
+Version 0.9.20 - October 18, 2001
+
+* Print out notice when 8139C+ chip is detected
+* Add id for D-Link DFE690TXD pcmcia cardbus card (Gert Dewit)
+
+
X Version 0.9.19 - October 9, 2001
X
X * Eliminate buffer copy for unaligned Tx's (manfred)
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/CommonIO linux/Documentation/s390/CommonIO
--- v2.4.12/linux/Documentation/s390/CommonIO Sun Aug 12 13:27:58 2001
+++ linux/Documentation/s390/CommonIO Thu Oct 11 09:04:57 2001
@@ -101,6 +101,17 @@
X the device driver will be notified if possible, so the device will become
X available to the system.
X
+ You can also add ranges of devices to be ignored by piping to
+ /proc/cio_ignore; "add <devnorange>, <devnorange>, ..." will ignore the
+ specified devices.
+
+ Note: Already known devices cannot be ignored; this also applies to devices
+ which are gone after a machine check.
+
+ For example, if device abcd is already known and all other devices a000-afff
+ are not known, "echo add 0xa000-0xaccc, 0xaf00-0xafff > /proc/cio_ignore"
+ will add af00-afff to the list of ignored devices and skip a000-accc.
+
X
X * /proc/s390dbf/cio_*/ (S/390 debug feature)
X
@@ -122,3 +133,7 @@
X /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
X the S/390 debug feature (Documentation/s390/s390dbf.txt) for details.
X
+* /proc/irq_count
+
+ This entry counts how many times s390_process_IRQ has been called for each
+ CPU. This info is in /proc/interrupts on other architectures.
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/chandev.8 linux/Documentation/s390/chandev.8
--- v2.4.12/linux/Documentation/s390/chandev.8 Sun Aug 12 13:27:58 2001
+++ linux/Documentation/s390/chandev.8 Thu Oct 11 09:04:57 2001
@@ -124,17 +124,16 @@
X .B (ctc|escon|lcs|osad|qeth)<devif_num>,
X read_devno,write_devno,<data_devno,memory_usage_in_k,port_no/protocol_no,checksum_received_ip_pkts,use_hw_stats>
X .It
-devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type.
-The data_devno field is only valid for qeth devices when not forcing a range of devices.
-all parameters after & including memory_usage_in_k can be set optionally if not set they
+devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type, qeth devices can't be forced as a range as it makes no sense for them.
+The data_devno field is only valid for qeth devices, all parameters including & after memory_usage_in_k can be set optionally, if not set they
X go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false
X .It
X e.g. ctc0,0x7c00,0x7c01
X .It
X Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails.
X .It
-qeth,0x7c00,0x7d00,-1,4096
-All devices between 0x7c00 & 7d00 should be detected as gigabit ethernet, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
+lcs,0x7c00,0x7d00,-1,4096
+All devices between 0x7c00 & 7d00 should be detected as lcs, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
X .It
X qeth1,0x7c00,0x7c01,0x7c02
X .It
@@ -368,6 +367,12 @@
X Force drivers modules to stay loaded even if no device is found,
X this is useful for debugging & one wishes to examine debug entries in
X /proc/s390dbf/ to find out why a module failed to load.
+.It
+e.g.
+.It
+persist,-1 forces all devices to persist.
+.It
+persist,0 forces all channel devices to be non persistent.
X .El
X
X .It
diff -u --recursive --new-file v2.4.12/linux/Documentation/s390/s390dbf.txt linux/Documentation/s390/s390dbf.txt
--- v2.4.12/linux/Documentation/s390/s390dbf.txt Wed Apr 11 19:02:27 2001
+++ linux/Documentation/s390/s390dbf.txt Thu Oct 11 09:04:57 2001
@@ -336,7 +336,7 @@
X Example:
X
X > ls /proc/s390dbf/dasd
-hex_ascii level raw
+flush hex_ascii level raw
X > cat /proc/s390dbf/dasd/hex_ascii | sort +1
X 00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | ....
X 00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE
@@ -362,6 +362,20 @@
X > echo "5" > /proc/s390dbf/dasd/level
X > cat /proc/s390dbf/dasd/level
X 5
+
+Flushing debug areas
+--------------------
+Debug areas can be flushed with piping the number of the desired
+area (0...n) to the proc file "flush". When using "-" all debug areas
+are flushed.
+
+Examples:
+
+1. Flush debug area 0:
+> echo "0" > /proc/s390dbf/dasd/flush
+
+2. Flush all debug areas:
+> echo "-" > /proc/s390dbf/dasd/flush
X
X lcrash Interface
X ----------------
diff -u --recursive --new-file v2.4.12/linux/Documentation/sonypi.txt linux/Documentation/sonypi.txt
--- v2.4.12/linux/Documentation/sonypi.txt Mon Aug 27 12:41:37 2001
+++ linux/Documentation/sonypi.txt Mon Oct 15 08:38:31 2001
@@ -15,6 +15,8 @@
X - capture button events (only on Vaio Picturebook series)
X - Fn keys
X - bluetooth button (only on C1VR model)
+ - back button (PCG-GR7/K model)
+ - lid open/close events (Z600NE model)
X
X Those events (see linux/sonypi.h) can be polled using the character device node
X /dev/sonypi (major 10, minor auto allocated or specified as a option).
@@ -36,6 +38,14 @@
X Module options:
X ---------------
X
+Several options can be passed to the sonypi driver, either by adding them
+to /etc/modules.conf file, when the driver is compiled as a module or by
+adding the following to the kernel command line (in your bootloader):
+
+ sonypi=minor[[[[,camera],fnkeyinit],verbose],compat]
+
+where:
+
X minor: minor number of the misc device /dev/sonypi,
X default is -1 (automatic allocation, see /proc/misc
X or kernel logs)
@@ -45,10 +55,17 @@
X in order to let the driver access to the camera
X
X fnkeyinit: on some Vaios (C1VE, C1VR etc), the Fn key events don't
- get enabled unless you set this parameter to 1
+ get enabled unless you set this parameter to 1.
+ Do not use this option unless it's actually necessary,
+ some Vaio models don't deal well with this option.
X
X verbose: print unknown events from the sonypi device
X
+ compat: uses some compatibility code for enabling the sonypi
+ events. If the driver worked for you in the past
+ (prior to version 1.5) and does not work anymore,
+ add this option and report to the author.
+
X Module use:
X -----------
X
@@ -56,7 +73,7 @@
X lines in your /etc/modules.conf file:
X
X alias char-major-10-250 sonypi
- options sonypi minor=250 fnkeyinit=1
+ options sonypi minor=250
X
X This supposes the use of minor 250 for the sonypi device:
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/usb/error-codes.txt linux/Documentation/usb/error-codes.txt
--- v2.4.12/linux/Documentation/usb/error-codes.txt Thu Dec 7 16:13:38 2000
+++ linux/Documentation/usb/error-codes.txt Wed Oct 17 14:34:06 2001
@@ -79,8 +79,7 @@
X -EILSEQ CRC mismatch
X
X USB_ST_STALL
--EPIPE a) babble detect
- b) endpoint stalled
+-EPIPE endpoint stalled
X
X USB_ST_BUFFEROVERRUN
X -ECOMM During an IN transfer, the host controller
@@ -95,7 +94,7 @@
X USB_ST_DATAOVERRUN
X -EOVERFLOW The amount of data returned by the endpoint was
X greater than either the max packet size of the
- endpoint or the remaining buffer size
+ endpoint or the remaining buffer size. "Babble".
X
X USB_ST_DATAUNDERRUN
X -EREMOTEIO The endpoint returned less than max packet size
diff -u --recursive --new-file v2.4.12/linux/Documentation/usb/philips.txt linux/Documentation/usb/philips.txt
--- v2.4.12/linux/Documentation/usb/philips.txt Mon Aug 27 12:41:37 2001
+++ linux/Documentation/usb/philips.txt Wed Oct 17 14:34:06 2001
@@ -22,21 +22,12 @@
X size
X Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
X 'vga', for an image size of resp. 128x96, 160x120, 176x144,
- 320x240, 352x288 and 640x480 (of course, only for those cameras that support these resolutions).
+ 320x240, 352x288 and 640x480 (of course, only for those cameras that
+ support these resolutions).
X
X fps
X Specifies the desired framerate. Is an integer in the range of 4-30.
X
-palette
- Specifies the desired colour order that should be delivered by read() and
- mmap(). The string can be one of yuv420 or yuv420p; however, yuv420 will
- be phased out, leaving only yuv420p, so this option will disappear
- entirely.
-
- Only the native yuv420/yuv420p format is supported by the in kernel driver.
- If you want to use other formats with in-kernel conversion download the
- driver from the URL given. [Alan]
-
X fbufs
X This paramter specifies the number of internal buffers to use for storing
X frames from the cam. This will help if the process that reads images from
@@ -88,6 +79,26 @@
X
X The compression parameter only applies to the Vesta & ToUCam cameras.
X The 645 and 646 have fixed compression parameters.
+
+leds
+ This settings takes 2 integers, that define the on/off time for the LED
+ (in milliseconds). One of the interesting things that you can do with
+ this is let the LED blink while the camera is in use. This:
+
+ leds=500,500
+
+ will blink the LED once every second. But with:
+
+ leds=0,0
+
+ the LED never goes on, making it suitable for silent survaillance.
+
+ By default the camera's LED is on solid while in use, and turned off
+ when the camera is not used anymore.
+
+ This parameter works only with the ToUCam range of cameras (730, 740,
+ 750). For other cameras this command is silently ignored, and the LED
+ cannot be controlled.
X
X trace
X In order to better detect problems, it is now possible to turn on a
diff -u --recursive --new-file v2.4.12/linux/Documentation/usb/scanner.txt linux/Documentation/usb/scanner.txt
--- v2.4.12/linux/Documentation/usb/scanner.txt Fri Jul 28 12:50:52 2000
+++ linux/Documentation/usb/scanner.txt Sat Oct 20 19:13:11 2001
@@ -1,9 +1,11 @@
-Copyright (C) 1999, 2000 David E. Nelson
+Copyright (C) 1999, 2000 David E. Nelson <dne...@jump.net>
X
X April 26, 2000
X
X CHANGES
X
+- Amended for linux-2.4.12
+- Updated devfs support
X - Amended for linux-2.3.99-pre6-3
X - Appended hp_scan.c to end of this README
X - Removed most references to HP
@@ -35,11 +37,9 @@
X (Compaq and others) hardware port should work. At the time of this
X writing, there are two UHCI drivers and one OHCI.
X
-A Linux development kernel (2.3.x) with USB support enabled or a
-backported version to linux-2.2.x. See http://www.linux-usb.org for
-more information on accomplishing this.
-
-A Linux kernel with USB Scanner support enabled.
+A Linux kernel with USB support enabled or a backported version to
+linux-2.2.x. See http://www.linux-usb.org for more information on
+accomplishing this.
X
X 'lspci' which is only needed to determine the type of USB hardware
X available/installed in your machine.
@@ -75,15 +75,15 @@
X YMMV.
X
X Beginning with version 0.4 of the driver, up to 16 scanners can be
-connected/used simultaneously. If you intend to use more than
-one scanner at a time:
+connected/used simultaneously. For devfs support, see next section.
+If you intend to use more than one scanner at a time w/o devfs support:
X
X Add a device for the USB scanner:
X `mknod /dev/usbscanner0 c 180 48`
X `mknod /dev/usbscanner1 c 180 49`
X .
X .
- `mknod /dev/usb/scanner15 180 63`
+ `mknod /dev/usbscanner15 180 63`
X
X
X If you foresee using only one scanner it is best to:
@@ -106,6 +106,32 @@
X modprobe usb-uhci
X modprobe scanner
X
+DEVFS
+
+The later versions of the Linux kernel (2.4.8'ish) included a dynamic
+device filesystem call 'devfs'. With devfs, there is no need to
+create the device files as explained above; instead, they are
+dynamically created for you. For USB Scanner, the device is created
+in /dev/usb/scannerX where X can range from 0 to 15 depending on the
+number of scanners connected to the system.
+
+To see if you have devfs, issue the command `cat /proc/filesytems`.
+If devfs is listed you should be ready to go. You sould also have a
+process running called 'devfsd'. In order to make sure, issue the
+command `ps aux | grep '[d]evfsd'`.
+
+If you would like to maintain /dev/usbscanner0 in order to maintain
+compatibility with applications, then add the following to
+/etc/devfsd.conf:
+
+REGISTER ^usb/scanner0$ CFUNCTION GLOBAL symlink usb/scanner0 usbscanner0
+UNREGISTER ^usb/scanner0$ CFUNCTION GLOBAL unlink usbscanner0
+
+Then reset the scanner (reseat the USB connector or power cycle). This
+will create the necessary symlinks in /dev to /dev/usb.
+
+CONCLUSION
+
X That's it. SANE should now be able to access the device.
X
X There is a small test program (hp_scan.c -- appended below) that can
@@ -121,15 +147,34 @@
X
X MESSAGES
X
-On occasions the message 'usb_control/bulk_msg: timeout' or something
-similar will appear in '/var/adm/messages' or on the console or both,
-depending on how your system is configured. This is a side effect
-that scanners are sometimes very slow at warming up and/or
-initializing. In most cases, however, only several of these messages
-should appear and is generally considered to be normal. If you see
-a message of the type 'excessive NAK's received' then this should
-be considered abnormal and generally indicates that the USB system is
-unable to communicate with the scanner for some particular reason.
+usb_control/bulk_msg: timeout -- On occasions this message will appear
+in '/var/adm/messages', on the console, or both depending on how
+your system is configured. This is a side effect that scanners are
+sometimes very slow at warming up and/or initializing. In most cases,
+however, only several of these messages should appear and is generally
+considered to be normal.
+
+excessive NAK's received -- This message should be considered abnormal
+and generally indicates that the USB system is unable to communicate
+with the scanner for some particular reason.
+
+probe_scanner: Undetected endpoint -- The USB Scanner driver is fairly
+general when it comes to communicating to scanners. Unfortunately,
+some vendors have designed their scanners in one way or another that
+this driver doesn't account for.
+
+probe_scanner: Endpoint determination failed -- This means that the
+driver is unable to detect a supported configuration for means to
+communicate with the scanner. See also 'probe_scanner: Undetected
+endpoint'.
+
+funky result -- Most of the time the data flow between the computer
+and the scanner goes smoothly. However, due to whatever reason,
+whether it be solar flares or stray neutrons, sometimes the
+communications don't work as expected. The driver tries to handle
+most types of errors but not all. When this message is seen,
+something weird happened. Please contact the maintaner listed at the
+top of this file.
X
X SUPPORTED SCANNERS
X
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/README.buz linux/Documentation/video4linux/README.buz
--- v2.4.12/linux/Documentation/video4linux/README.buz Thu Jan 6 14:46:18 2000
+++ linux/Documentation/video4linux/README.buz Wed Dec 31 16:00:00 1969
@@ -1,212 +0,0 @@
-Iomega Buz Driver for Linux
-===========================
-
-by Rainer Johanni <Rai...@Johanni.de>
-
-Compiling and Loading the Driver
-================================
-
-You must run a 2.2.x kernel in order to use this driver.
-
-To compile the driver, just type make.
-
-Besides the files in this directory, the driver needs the
-'videodev' and the 'i2c' module from the Linux kernel.
-In order to get these modules available, enable module support
-for VIDEODEV and BTTV (which implies i2c) in your kernel
-configuration. You find these devices in the menu
-"Character Devices" in your Kernel Configuration.
-
-Before you load the driver you must have a video device
-at major device node 81. If you don't have it yet, do the
-following (as root!):
-
-cd /dev
-mknod video0 c 81 0
-ln -s video0 video
-
-Edit the 'update' script if you want to give the driver
-special options and then type (as root)
-
-./update
-
-to insert all the necessary modules into the kernel.
-
-If you want to make full use of the Video for Linux uncompressed
-grabbing facilities, you must either
-
-- obtain and install the "big_physarea patch" for your kernel and
- set aside the necessary memory during boot time.
- There seem to be several versions of this patch against
- various kernel versions floating around in the net,
- you may obtain one e.g. from:
- http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
- You also have to compile your driver AFTER installing that patch
- in order to get it working
-
- or
-
-- start your kernel with the mem=xxx option, where xxx is your
- real memory minus the memory needed for the buffers.
- For doing this add an entry in lilo.conf (if you use lilo):
- append "mem=xxxM"
- or add a line in your linux.par file (if you use loadlin):
- mem=xxxM
-
-The second method is by far easier, however it is dangerous
-if more than one driver at a time has the idea to use the memory
-leftover by setting the mem=xxx parameter below the actual
-memory size.
-
-Read also below how to use this memory!
-
-
-
-Driver Options
-==============
-
-You are able to customize the behavior of the driver by giving
-it some options at start time.
-
-default_input, default_norm
----------------------------
-
-As soon as the driver is loaded, the Buz samples video signals
-from one of its input ports and displays it on its output.
-The driver uses the Composite Input and the video norm PAL for this.
-If you want to change this default behavior, set default_input=1
-(for S-VHS input) or default_norm=1 for NTSC.
-
-v4l_nbufs, v4l_bufsize
-----------------------
-
-In order to make to make full use of the Video for Linux picture
-grabbing facilities of the driver (which are needed by many
-Video for Linux applications), the driver needs a set of
-physically contiguous buffers for grabbing. These parameters
-determine how many buffers of which size the driver will
-allocate at open (the open will fail if it is unable to do so!).
-
-These values do not affect the MJPEG grabbing facilities of the driver,
-they are needed for uncompressed image grabbing only!!!
-
-v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
-should be sufficient in almost all cases. Only special applications
-(streaming captures) will need more buffers and then mostly the
-MJPEG capturing features of the Buz will be more appropriate.
-So leave this parameter at it's default unless you know what you do.
-
-The things for v4l_bufsize are more complicated:
-v4l_bufsize is set by default to 128 [KB] which is the maximum
-amount of physically contiguous memory Linux is able to allocate
-without kernel changes. This is sufficient for grabbing 24 bit color images
-up to sizes of approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
-
-In order to be able to capture bigger images you have either to
-- obtain and install the "big_physarea patch" and set aside
- the necessary memory during boot time or
-- start your kernel with the mem=xxx option, where xxx is your
- real memory minus the memory needed for the buffers.
-In that case, useful settings for v4l_bufsize are
-- 1296 [Kb] for grabbing 24 bit images of max size 768*576
-- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
-You may reduce these numbers accordingly if you know you are only
-grabbing 720 pixels wide images or NTSC images (max height 480).
-
-In some cases it may happen that Linux isn't even able to obtain
-the default 128 KB buffers. If you don't need uncompressed image
-grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
-in order to be able to open the video device.
-
-vidmem
-------
-
-The video mem address of the video card.
-The driver has a little database for some videocards
-to determine it from there. If your video card is not in there
-you have either to give it to the driver as a parameter
-or set in in a VIDIOCSFBUF ioctl
-
-The videocard database is contained in the file "videocards.h"
-Gernot Ziegler wants to keep an actual version of that file.
-If your card is not contained in that file, look at
-http://www.lysator.liu.se/~gz/buz/ for an actual version of
-"videocards.h".
-
-triton, natoma
---------------
-
-The driver tries to detect if you have a triton or natome chipset
-in order to take special measures for these chipsets.
-If this detection fails but you are sure you have such a chipset,
-set the corresponding variable to 1.
-This is a very special option and may go away in the future.
-
-
-
-Programming interface
-=====================
-
-This driver should be fully compliant to Video for Linux, so all
-tools working with Video for Linux should work with (hopefully)
-no problems.
-
-A description of the Video for Linux programming interface can be found at:
-http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
-
-Besides the Video for Linux interface, the driver has a "proprietary"
-interface for accessing the Buz's MJPEG capture and playback facilities.
-
-The ioctls for that interface are as follows:
-
-BUZIOC_G_PARAMS
-BUZIOC_S_PARAMS
-
-Get and set the parameters of the buz. The user should always
-do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
-settings, change what he likes and then make a BUZIOC_S_PARAMS call.
-A typical application should at least set the members
-input, norm and decimation of the struct buz_params.
-For a full description of all members see "buz.h"
-
-BUZIOC_REQBUFS
-
-Before being able to capture/playback, the user has to request
-the buffers he is wanting to use. Fill the structure
-buz_requestbuffers with the size (recommended: 256*1024) and
-the number (recommended 32 up to 256). There are no such restrictions
-as for the Video for Linux buffers, you should LEAVE SUFFICIENT
-MEMORY for your system however, else strange things will happen ....
-On return, the buz_requestbuffers structure contains number and
-size of the actually allocated buffers.
-You should use these numbers for doing a mmap of the buffers
-into the user space.
-The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
-maps the MJPEG buffer instead of the V4L buffers.
-
-BUZIOC_QBUF_CAPT
-BUZIOC_QBUF_PLAY
-
-Queue a buffer for capture or playback. The first call also starts
-streaming capture. When streaming capture is going on, you may
-only queue further buffers or issue syncs until streaming
-capture is switched off again with a argument of -1 to
-a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
-
-BUZIOC_SYNC
-
-Issue this ioctl when all buffers are queued. This ioctl will
-block until the first buffer becomes free for saving its
-data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
-
-BUZIOC_G_STATUS
-
-Get the status of the input lines (video source connected/norm).
-This ioctl may be subject to change.
-
-
-
-
-
-See the examples directory delivered with this driver
-for actual coding examples!
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/CARDLIST linux/Documentation/video4linux/bttv/CARDLIST
--- v2.4.12/linux/Documentation/video4linux/bttv/CARDLIST Sun Aug 12 13:27:58 2001
+++ linux/Documentation/video4linux/bttv/CARDLIST Wed Oct 17 14:19:20 2001
@@ -1,15 +1,15 @@
X bttv.o
- card=0 - *** UNKNOWN ***
+ card=0 - *** UNKNOWN/GENERIC ***
X card=1 - MIRO PCTV
- card=2 - Hauppauge old
+ card=2 - Hauppauge (bt848)
X card=3 - STB
X card=4 - Intel
X card=5 - Diamond DTV2000
X card=6 - AVerMedia TVPhone
X card=7 - MATRIX-Vision MV-Delta
- card=8 - Fly Video II
+ card=8 - Fly Video II (Bt848)
X card=9 - TurboTV
- card=10 - Hauppauge new (bt878)
+ card=10 - Hauppauge (bt878)
X card=11 - MIRO PCTV pro
X card=12 - ADS Technologies Channel Surfer TV
X card=13 - AVerMedia TVCapture 98
@@ -23,7 +23,7 @@
X card=21 - Lucky Star Image World ConferenceTV
X card=22 - Phoebe Tv Master + FM
X card=23 - Modular Technology MM205 PCTV, bt878
- card=24 - Askey/Typhoon/Anubis Magic TView CPH051/061 (bt878)
+ card=24 - [many vendors] CPH05X/06X (bt878)
X card=25 - Terratec/Vobis TV-Boostar
X card=26 - Newer Hauppauge WinCam (bt878)
X card=27 - MAXI TV Video PCI2
@@ -34,10 +34,10 @@
X card=32 - Intel Create and Share PCI
X card=33 - Terratec TerraTValue
X card=34 - Leadtek WinFast 2000
- card=35 - Chronos Video Shuttle II
- card=36 - Typhoon TView TV/FM Tuner
+ card=35 - Flyvideo 98 (LR50Q) / Chronos Video Shuttle II
+ card=36 - Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner
X card=37 - PixelView PlayTV pro
- card=38 - TView99 CPH063
+ card=38 - TView99 CPH06X
X card=39 - Pinnacle PCTV Studio/Rave
X card=40 - STB2
X card=41 - AVerMedia TVPhone 98
@@ -49,11 +49,11 @@
X card=47 - Terratec TV/Radio+
X card=48 - Dynalink Magic TView
X card=49 - GV-BCTV3
- card=50 - Prolink PV-BT878P+4E (PixelView PlayTV PAK)
+ card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
X card=51 - Eagle Wireless Capricorn2 (bt878A)
X card=52 - Pinnacle PCTV Studio Pro
- card=53 - Typhoon TView RDS / FM Stereo
- card=54 - Lifetec LT 9415 TV
+ card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
+ card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
X card=55 - BESTBUY Easy TV
X card=56 - FlyVideo '98/FM
X card=57 - GrandTec 'Grand Video Capture'
@@ -66,6 +66,12 @@
X card=64 - ATI TV-Wonder VE
X card=65 - FlyVideo 2000S
X card=66 - Terratec TValueRadio
+ card=67 - GV-BCTV4/PCI
+ card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
+ card=69 - Active Imaging AIMMS
+ card=70 - PV-BT878P+
+ card=71 - Flyvideo 98EZ (capture only)
+ card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
X
X tuner.o
X type=0 - Temic PAL (4002 FH5)
@@ -82,7 +88,7 @@
X type=11 - Alps TSBB5
X type=12 - Alps TSBE5
X type=13 - Alps TSBC5
- type=14 - Temic PAL_I (4006FH5)
+ type=14 - Temic PAL_BG (4006FH5)
X type=15 - Alps TSCH6
X type=16 - Temic PAL_DK (4016 FY5)
X type=17 - Philips NTSC_M (MK2)
@@ -99,3 +105,10 @@
X type=28 - LG PAL_BG+FM (TPI8PSB01D)
X type=29 - LG PAL_BG (TPI8PSB11D)
X type=30 - Temic PAL* auto + FM (4009 FN5)
+ type=31 - SHARP NTSC_JP (2U5JF5540)
+ type=32 - Samsung PAL TCPM9091PD27
+ type=33 - MT2032 universal
+ type=34 - Temic PAL_BG (4106 FH5)
+ type=35 - Temic PAL_DK/SECAM_L (4012 FY5)
+ type=36 - Temic NTSC (4136 FY5)
+ type=37 - LG PAL (newer TAPC series)
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/Cards linux/Documentation/video4linux/bttv/Cards
--- v2.4.12/linux/Documentation/video4linux/bttv/Cards Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/bttv/Cards Wed Oct 17 14:19:20 2001
@@ -0,0 +1,210 @@
+Suppported cards:
+
+
+Bt848/Bt848a/Bt849/Bt878/Bt879 cards
+------------------------------------
+
+All cards with Bt848/Bt848a/Bt849/Bt878/Bt879 and normal Composite/S-VHS inputs
+are supported.
+Teletext and Intercast support (PAL only) for ALL cards via VBI sample decoding
+in software.
+
+Some cards with additional multiplexing of inputs are only partially
+supported (unless specifications by the card manufacturer are given).
+
+All other cards only differ by additional components as tuners, sound decoders,
+EEPROMs, teletext decoders ...
+
+
+MATRIX Vision
+-------------
+
+MV-Delta
+- Bt848A
+- 4 Composite inputs, 1 S-VHS input (shared with 4th composite)
+- EEPROM
+
+http://www.matrix-vision.de/
+
+This card has no tuner but supports all 4 composite (1 shared with an
+S-VHS input) of the Bt848A.
+Very nice card if you only have satellite TV but several tuners connected
+to the card via composite.
+
+Many thanks to Matrix-Vision for giving us 2 cards for free which made
+Bt848a/Bt849 single crytal operation support possible!!!
+
+
+
+Miro/Pinnacle PCTV
+------------------
+
+- Bt848
+ some (all??) come with 2 crystals for PAL/SECAM and NTSC
+- PAL, SECAM or NTSC TV tuner (Philips or TEMIC)
+- MSP34xx sound decoder on add on board
+ decoder is supported but AFAIK does not yet work
+ (other sound MUX setting in GPIO port needed??? somebody who fixed this???)
+- 1 tuner, 1 composite and 1 S-VHS input
+- tuner type is autodetected
+
+http://www.miro.de/
+http://www.miro.com/
+
+
+Many thanks for the free card which made first NTSC support possible back
+in 1997!
+
+
+Hauppauge Win/TV pci
+--------------------
+
+There are many different versions of the Hauppauge cards with different
+tuners (TV+Radio ...), teletext decoders.
+Note that even cards with same model numbers have (depending on the revision)
+different chips on it.
+
+- Bt848 (and others but always in 2 crystal operation???)
+ newer cards have a Bt878
+- PAL, SECAM, NTSC or tuner with or without Radio support
+
+e.g.:
+ PAL:
+ TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+ TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
+
+ NTSC:
+ TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+ TSA5518: no datasheet available on Philips site
+- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip
+ with buffer RAM (e.g. Winbond W24257AS-35: 32Kx8 CMOS static RAM)
+ SAA5246 (I2C 0x22) is supported
+- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y
+ with configuration information
+ I2C address 0xa0 (24LC02B also responds to 0xa2-0xaf)
+- 1 tuner, 1 composite and (depending on model) 1 S-VHS input
+- 14052B: mux for selection of sound source
+- sound decoder: TDA9800, MSP34xx (stereo cards)
+
+
+CPH-Series (CPH050, ...)
+------------------------
+Developed by TelSignal(?), OEMed by many vendors (Askey, Typhoon,
+ Anubis, Dynalink)
+
+ Card series:
+ CPH01x: BT848 capture only
+ CPH03x: BT848
+ CPH05x: BT878 with FM
+ CPH06x: BT878 (w/o FM)
+ CPH07x: BT878 capture only
+
+ TV standards:
+ CPH0x0: NTSC-M/M
+ CPH0x1: PAL-B/G
+ CPH0x2: PAL-I/I
+ CPH0x3: PAL-D/K
+ CPH0x4: SECAM-L/L
+ CPH0x5: SECAM-B/G
+ CPH0x6: SECAM-D/K
+ CPH0x7: PAL-N/N
+ CPH0x8: PAL-B/H
+ CPH0x9: PAL-M/M
+
+ CPH03x was often sold as "TV capturer".
+
+ Identifying:
+ 1) 878 cards can be identified by PCI Subsystem-ID:
+ 144f:3000 = CPH06x
+ 144F:3002 = CPH05x w/ FM
+ 144F:3005 = CPH06x_LC (w/o remote control)
+ 1) The cards have a sticker with "CPH"-model on the back.
+ 2) These cards have a number printed on the PCB just above the tuner metal box:
+ "80-CP2000300-x" = CPH03X
+ "80-CP2000500-x" = CPH05X
+ "80-CP2000600-x" = CPH06X / CPH06x_LC
+
+ Askey sells these cards as "Magic TView series", Brand "MagicXpress".
+ Other OEM often call these "Tview", "TView99" or else.
+
+Lifeview Flyvideo Series:
+-------------------------
+ The naming of these series differs in time and space.
+
+ Identifying:
+ 1) Some models can be identified by PCI subsystem ID:
+ 1852:1852 = Flyvideo 98 FM
+ 1851:1850 = Flyvideo 98
+ 1851:1851 = Flyvideo 98 EZ (capture only)
+ 2) There is a print on the PCB:
+ LR25 = Flyvideo (Zoran)
+ LR37 Rev.C = Capture only (ZR36120 + SAA7110)
+ LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
+ LR50 Rev.W = Flyvideo 98 (no eeprom)
+ LR51 Rev.E = Flyvideo 98 EZ (capture only)
+ LR90 = Flyvideo 2000 series
+ LR90 Rev.F = Lifetec/Medion LT 9815
+ LR97 = Flyvideo DVBS
+
+ "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
+ this name is re-used for LR50 Rev.W.
+ The Lifeview website has even more names: Flyvideo III,2100,3000,3100.
+ These cards are sold by many OEMs too.
+
+
+Typhoon TV card series:
+-----------------------
+ These can be CPH, Flyvideo, Pixelview or KNC1 series.
+ Typhoon is the brand of Anubis.
+ Model 50680 got re-used, some model no. had different contents over time.
+
+ Models:
+ 50680 "TV Tuner PCI Pal BG"(old,red package)=can be CPH03x(bt848) or CPH06x(bt878)
+ 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
+ 50681 "TV Tuner PCI Pal I" (variant of 50680)
+ 50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q)
+ Note: The package has a picture of CPH05x (which would be a real TView)
+ 50683 "TV Tuner PCI SECAM" (variant of 50680)
+ 50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D)
+ 50686 "TV Tuner" = KNC1 TV Station
+ 50687 "TV Tuner stereo" = KNC1 TV Station pro
+ 50688 "TV Tuner RDS" (black package) = KNC1 TV Station RDS
+ 50692 "TV/FM Tuner" (small PCB)
+ 50868 "TV/FM Tuner Pal I" (variant of 50682)
+ 50999 "TV/FM Tuner Secam" (variant of 50682)
+
+
+Guillemot
+---------
+ Maxi TV Video 2 = LR50 Rev.Q (FI1216MF, PAL BG+SECAM)
+ Maxi TV Video 3 = CPH064 (PAL BG + SECAM)
+
+Mentor
+------
+ Mentor TV card ("55-878TV-U1") = Pixelview 878TV(Rev.3F) (w/FM w/Remote)
+
+Prolink
+-------
+ Pixelview Play TV Pro:
+ PV-BT878P+rev.9B (Play TV Pro w/FM w/NICAM)
+ PV-BT878P+rev.8X
+ PV-BT878P+rev.4C (Play TV Pro)
+ PV-BT878P+rev.4E (Play TV Pak)
+ PV-BT878P+rev.2F
+ PV-BT878TV
+
+ PixelView Play TV
+ PV-BT848P+
+
+Dynalink
+--------
+ These are CPH series.
+
+Phoebemicro
+-----------
+ TV Master = CPH030 or CPH060
+ TV Master FM = CPH050
+
+Genius/Kye
+----------
+ Video Wonder/Genius Internet Video Kit = LR37 Rev.C
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/Insmod-options linux/Documentation/video4linux/bttv/Insmod-options
--- v2.4.12/linux/Documentation/video4linux/bttv/Insmod-options Sun Aug 12 13:27:58 2001
+++ linux/Documentation/video4linux/bttv/Insmod-options Wed Oct 17 14:19:20 2001
@@ -1,6 +1,6 @@
X
X bttv.o
- the bt848 (grabber chip) driver
+ the bt848/878 (grabber chip) driver
X
X insmod args:
X card=n card type, see CARDLIST for a list.
@@ -10,12 +10,11 @@
X 0: don't use PLL
X 1: 28 MHz crystal installed
X 2: 35 MHz crystal installed
- triton1=0/1 for Triton1 compatibility
- Triton1 is automatically recognized
- but this might also help with other chipsets
- vsfx=0/1 yet another chipset bug compatibility flag
- (bt878 docs mentiones via+sis, but no
- specific chipsets with that problem).
+
+ triton1=0/1 for Triton1 (+others) compatibility
+ vsfx=0/1 yet another chipset bug compatibility bit
+ see README.quirks for details on these two.
+
X bigendian=n Set the endianness of the gfx framebuffer.
X Default is native endian.
X fieldnr=0/1 Count fields. Some TV descrambling software
@@ -23,8 +22,8 @@
X 50 useless IRQs/sec. default is 0 (off).
X autoload=0/1 autoload helper modules (tuner, audio).
X default is 1 (on).
- bttv_verbose=0/1/2 verbose level (at insmod time, while looking
- at the hardware). default is 1.
+ bttv_verbose=0/1/2 verbose level (at insmod time, while
+ looking at the hardware). default is 1.
X bttv_debug=0/1 debug messages (for capture).
X default is 0 (off).
X irq_debug=0/1 irq handler debug messages.
@@ -80,12 +79,32 @@
X tda9850 = 1 The tea6300 can't be autodetected and is
X tda9855 = 1 therefore off by default, if you have
X tda9873 = 1 this one on your card (STB uses these)
- tea6300 = 0 you have to enable it explicitly.
- tea6420 = 1 The two tda985x chips use the same i2c
- pic16c54 = 1 address and can't be disturgished from
- each other, you might have to disable
+ tda9874a = 1 you have to enable it explicitly.
+ tea6300 = 0 The two tda985x chips use the same i2c
+ tea6420 = 1 address and can't be disturgished from
+ pic16c54 = 1 each other, you might have to disable
X the wrong one.
X debug = 1 print debug messages
+
+ insmod args for tda9874a:
+ tda9874a_SIF=1/2 select sound IF input pin (1 or 2)
+ (default is pin 1)
+ tda9874a_STD=n select TV sound standard (0..8):
+ 0 - A2, B/G
+ 1 - A2, M (Korea)
+ 2 - A2, D/K (1)
+ 3 - A2, D/K (2)
+ 4 - A2, D/K (3)
+ 5 - NICAM, I
+ 6 - NICAM, B/G
+ 7 - NICAM, D/K (default)
+ 8 - NICAM, L
+
+ Note: tda9874a is very similar to tda9874 (without 'A'-suffix), but
+ this driver will not work for the latter device (will not load).
+ Note: tda9874a and tda9875 (which is supported separately by
+ tda9875.o) use the same i2c address so both modules should not be
+ used at the same time.
X
X msp3400.o
X The driver for the msp34xx sound processor chips. If you have a
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/README.quirks linux/Documentation/video4linux/bttv/README.quirks
--- v2.4.12/linux/Documentation/video4linux/bttv/README.quirks Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/bttv/README.quirks Wed Oct 17 14:19:20 2001
@@ -0,0 +1,83 @@
+
+Below is what the bt878 data book says about the PCI bug compatibility
+modes of the bt878 chip.
+
+The triton1 insmod option sets the EN_TBFX bit in the control register.
+The vsfx insmod option does the same for EN_VSFX bit. If you have
+stability problems you can try if one of these options makes your box
+work solid.
+
+drivers/pci/quirks.c knows about these issues, this way these bits are
+enabled automagically for known-buggy chipsets (look at the kernel
+messages, bttv tells you).
+
+HTH,
+
+ Gerd
+
+---------------------------- cut here --------------------------
+
+Normal PCI Mode
+---------------
+
+The PCI REQ signal is the logical-or of the incoming function requests.
+The inter-nal GNT[0:1] signals are gated asynchronously with GNT and
+demultiplexed by the audio request signal. Thus the arbiter defaults to
+the video function at power-up and parks there during no requests for
+bus access. This is desirable since the video will request the bus more
+often. However, the audio will have highest bus access priority. Thus
+the audio will have first access to the bus even when issuing a request
+after the video request but before the PCI external arbiter has granted
+access to the Bt879. Neither function can preempt the other once on the
+bus. The duration to empty the entire video PCI FIFO onto the PCI bus is
+very short compared to the bus access latency the audio PCI FIFO can
+tolerate.
+
+
+430FX Compatibility Mode
+------------------------
+
+When using the 430FX PCI, the following rules will ensure
+compatibility:
+
+ (1) Deassert REQ at the same time as asserting FRAME.
+ (2) Do not reassert REQ to request another bus transaction until after
+ finish-ing the previous transaction.
+
+Since the individual bus masters do not have direct control of REQ, a
+simple logical-or of video and audio requests would violate the rules.
+Thus, both the arbiter and the initiator contain 430FX compatibility
+mode logic. To enable 430FX mode, set the EN_TBFX bit as indicated in
+Device Control Register on page 104.
+
+When EN_TBFX is enabled, the arbiter ensures that the two compatibility
+rules are satisfied. Before GNT is asserted by the PCI arbiter, this
+internal arbiter may still logical-or the two requests. However, once
+the GNT is issued, this arbiter must lock in its decision and now route
+only the granted request to the REQ pin. The arbiter decision lock
+happens regardless of the state of FRAME because it does not know when
+FRAME will be asserted (typically - each initiator will assert FRAME on
+the cycle following GNT). When FRAME is asserted, it is the initiator s
+responsibility to remove its request at the same time. It is the
+arbiters responsibility to allow this request to flow through to REQ and
+not allow the other request to hold REQ asserted. The decision lock may
+be removed at the end of the transaction: for example, when the bus is
+idle (FRAME and IRDY). The arbiter decision may then continue
+asynchronously until GNT is again asserted.
+
+
+Interfacing with Non-PCI 2.1 Compliant Core Logic
+-------------------------------------------------
+
+A small percentage of core logic devices may start a bus transaction
+during the same cycle that GNT is de-asserted. This is non PCI 2.1
+compliant. To ensure compatibility when using PCs with these PCI
+controllers, the EN_VSFX bit must be enabled (refer to Device Control
+Register on page 104). When in this mode, the arbiter does not pass GNT
+to the internal functions unless REQ is asserted. This prevents a bus
+transaction from starting the same cycle as GNT is de-asserted. This
+also has the side effect of not being able to take advantage of bus
+parking, thus lowering arbitration performance. The Bt879 drivers must
+query for these non-compliant devices, and set the EN_VSFX bit only if
+required.
+
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/Sound-FAQ linux/Documentation/video4linux/bttv/Sound-FAQ
--- v2.4.12/linux/Documentation/video4linux/bttv/Sound-FAQ Sun Aug 12 13:27:58 2001
+++ linux/Documentation/video4linux/bttv/Sound-FAQ Wed Oct 17 14:19:20 2001
@@ -126,6 +126,7 @@
X tuner_type - same as tuner= insmod option
X *_modulename - hint whenever some card needs this or that audio
X module loaded to work properly.
+has_radio - whenever this TV card has a radio tuner.
X
X If some config item is specified both from the tvcards array and as
X insmod option, the insmod option takes precedence.
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/bttv/Tuners linux/Documentation/video4linux/bttv/Tuners
--- v2.4.12/linux/Documentation/video4linux/bttv/Tuners Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/bttv/Tuners Wed Oct 17 14:19:20 2001
@@ -0,0 +1,88 @@
+
+SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
+ TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
+ [ABCJLMNQ]:
+ A= BG+DK
+ B= BG
+ C= I+DK
+ J= NTSC-Japan
+ L= Secam LL
+ M= BG+I+DK
+ N= NTSC
+ Q= BG+I+DK+LL
+ [125]:
+ 2: No FM
+ 5: With FM
+ [DP]:
+ D= NTSC
+ P= PAL
+ [ACD]:
+ A= F-connector
+ C= Phono connector
+ D= Din Jack
+ [ABCD]:
+ 3-wire/I2C tuning, 2-band/3-band
+
+Philips Tuner identification: (e.g. FM1216MF)
+ F[IRMQ]12[1345]{MF|ME|MP}
+ [IRMQ]:
+ I: Tuner Series
+ R: Tuner + Radio IF
+ M: Tuner + FM
+ Q,MR: specials
+ TD15xx: Digital Tuner ATSC
+ [1345]
+ 1: PAL BG
+ 3: NTSC
+ 4: PAL I
+ 5: Pal DK
+ {MF|ME|MP}
+ MF: w/ Secam
+ ME: BD DK I LL
+ MP: BG DK I
+ MR: BG DK M (?)
+ MG: BG DKI M (?)
+
+Temic Tuner identification: (.e.g 4006FH5)
+ 4[01][0136][269]F[HYNR]5
+ 40x2: Tuner (5V/33V), different I2C programming from Philips !
+ 40x6: Tuner 5V
+ 41xx: Tuner compact
+ 40x9: Tuner+FM compact
+ [0136]
+ 0: PAL BG
+ 1: Pal DK, Secam LL
+ 3: NTSC
+ 6: PAL I
+ F[HYNR]5
+ FH5: Pal BG
+ FY5: others
+ FN5: multistandard
+ FR5: w/ FM radio
+ 3X xxxx: order number with specific connector
+
+LG Innotek Tuner:
+ TPI8NSR11 : NTSC J/M (TPI8NSR01 w/FM) (P,210/497)
+ TPI8PSB11 : PAL B/G (TPI8PSB01 w/FM) (P,170/450)
+ TAPC-I701 : PAL I (TAPC-I001 w/FM) (P,170/450)
+ TPI8PSB12 : PAL D/K+B/G (TPI8PSB02 w/FM) (P,170/450)
+ TAPC-H701P: NTSC_JP (TAPC-H001P w/FM) (L,170/450)
+ TAPC-G701P: PAL B/G (TAPC-G001P w/FM) (L,170/450)
+ TAPC-W701P: PAL I (TAPC-W001P w/FM) (L,170/450)
+ TAPC-Q703P: PAL D/K (TAPC-Q001P w/FM) (L,170/450)
+ TAPC-Q704P: PAL D/K+I (L,170/450)
+ TAPC-G702P: PAL D/K+B/G (L,170/450)
+
+ TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
+ TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8)
+ TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69)
+
+ (API,Lo-Hi-takeover/Hi-UHF-takeover)
+ I2C APIs:
+ L= LG programming (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+ P= Philips progr. (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+ T= Temic progr. (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+ Suffix:
+ P= Standard phono female socket
+ D= IEC female socket
+ F= F-connector
diff -u --recursive --new-file v2.4.12/linux/Documentation/video4linux/meye.txt linux/Documentation/video4linux/meye.txt
--- v2.4.12/linux/Documentation/video4linux/meye.txt Wed Jul 25 17:10:17 2001
+++ linux/Documentation/video4linux/meye.txt Thu Oct 11 09:04:57 2001
@@ -4,7 +4,10 @@
X Copyright (C) 2000 Andrew Tridgell <tri...@samba.org>
X
X This driver enable the use of video4linux compatible applications with the
-Motion Eye camera.
+Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O
+Control Device" driver (which can be found in the "Character drivers"
+section of the kernel configuration utility) to be compiled and installed
+(using its "camera=1" parameter).
X
X It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
X
diff -u --recursive --new-file v2.4.12/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.12/linux/MAINTAINERS Tue Oct 9 17:06:51 2001
+++ linux/MAINTAINERS Mon Oct 22 08:37:17 2001
@@ -1053,6 +1053,12 @@
X L: linu...@vger.kernel.org
X S: Maintained
X
+NINJA SCSI-3 / NINJA SCSI-32Bi PCMCIA SCSI HOST ADAPTER DRIVER
+P: YOKOTA Hiroshi
+M: yok...@netlab.is.tsukuba.ac.jp
+W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
+S: Maintained
+
X NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
X P: Eberhard Moenkeberg
X M: emo...@gwdg.de
@@ -1115,6 +1121,12 @@
X W: http://www.torque.net/linux-pp.html
X S: Maintained
X
+PERSONALITY HANDLING
+P: Christoph Hellwig
+M: h...@caldera.de
+L: linux-a...@lists.sourceforge.net
+S: Supported
+
X PCI ID DATABASE
X P: Jens Maurer
X M: jma...@cck.uni-kl.de
@@ -1286,6 +1298,13 @@
X L: sa...@samba.org
X S: Maintained
X
+SNA NETWORK LAYER
+P: Jay Schulist
+M: jsc...@samba.org
+L: linu...@turbolinux.com
+W: http://www.linux-sna.org
+S: Supported
+
X SOFTWARE RAID (Multiple Disks) SUPPORT
X P: Ingo Molnar
X M: mi...@redhat.com
@@ -1333,12 +1352,11 @@
X L: linu...@vger.kernel.org
X S: Supported
X
-SNA NETWORK LAYER
-P: Jay Schulist
-M: jsc...@samba.org
-L: linu...@turbolinux.com
-W: http://www.linux-sna.org
-S: Supported
+SRM (Alpha) environment access
+P: Jan-Benedict Glaw
+M: jbg...@lug-owl.de
+L: linux-...@vger.kernel.org
+S: Maintained
X
X STALLION TECHNOLOGIES MULTIPORT SERIAL BOARDS
X M: sup...@stallion.oz.au
@@ -1399,6 +1417,13 @@
X W: http://www.linuxtr.net
X S: Maintained
X
+TOSHIBA SMM DRIVER
+P: Jonathan Buzzard
+M: jona...@buzzard.org.uk
+L: tlinux...@tce.toshiba-dme.co.jp
+W: http://www.buzzard.org.uk/toshiba/
+S: Maintained
+
X TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
X P: Ollie Lho
X M: ol...@sis.com.tw
@@ -1666,6 +1691,12 @@
X P: Jean-Paul Roubelat
X M: j...@f6fbb.org
X L: linux...@vger.kernel.org
+S: Maintained
+
+YMFPCI YAMAHA PCI SOUND
+P: Pete Zaitcev
+M: zai...@yahoo.com
+L: linux-...@vger.kernel.org
X S: Maintained
X
X Z85230 SYNCHRONOUS DRIVER
diff -u --recursive --new-file v2.4.12/linux/Makefile linux/Makefile
--- v2.4.12/linux/Makefile Thu Oct 11 08:02:26 2001
+++ linux/Makefile Tue Oct 23 22:21:20 2001
@@ -1,11 +1,12 @@
X VERSION = 2
X PATCHLEVEL = 4
-SUBLEVEL = 12
+SUBLEVEL = 13
X EXTRAVERSION =
X
X KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
X
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//")
X
X CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
X else if [ -x /bin/bash ]; then echo /bin/bash; \
@@ -176,7 +177,7 @@
X DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
X DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
X DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
-DRIVERS-$(CONFIG_I2O) += drivers/i2o/i2o.o
+DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
X DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
X DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
X DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.4.12/linux/arch/alpha/kernel/alpha_ksyms.c Sun Sep 23 11:40:54 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c Fri Oct 12 15:35:53 2001
@@ -127,10 +127,16 @@
X EXPORT_SYMBOL(pci_alloc_consistent);
X EXPORT_SYMBOL(pci_free_consistent);
X EXPORT_SYMBOL(pci_map_single);
+EXPORT_SYMBOL(pci_map_page);
X EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(pci_unmap_page);
X EXPORT_SYMBOL(pci_map_sg);
X EXPORT_SYMBOL(pci_unmap_sg);
X EXPORT_SYMBOL(pci_dma_supported);
+EXPORT_SYMBOL(pci_dac_dma_supported);
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
X #endif
X
X EXPORT_SYMBOL(dump_thread);
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c
--- v2.4.12/linux/arch/alpha/kernel/core_cia.c Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/core_cia.c Sun Oct 21 10:30:58 2001
@@ -321,7 +321,7 @@
X * be purged to make room for the new entries coming in for the garbage page.
X */
X
-#define CIA_BROKEN_TBIA_BASE 0xE0000000
+#define CIA_BROKEN_TBIA_BASE 0x30000000
X #define CIA_BROKEN_TBIA_SIZE 1024
X
X /* Always called with interrupts disabled */
@@ -382,10 +382,10 @@
X for (i = 0; i < CIA_BROKEN_TBIA_SIZE / sizeof(unsigned long); ++i)
X ppte[i] = pte;
X
- *(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBIA_BASE | 3;
- *(vip)CIA_IOC_PCI_W3_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
+ *(vip)CIA_IOC_PCI_W1_BASE = CIA_BROKEN_TBIA_BASE | 3;
+ *(vip)CIA_IOC_PCI_W1_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
X & 0xfff00000;
- *(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2;
+ *(vip)CIA_IOC_PCI_T1_BASE = virt_to_phys(ppte) >> 2;
X }
X
X static void __init
@@ -595,6 +595,8 @@
X failed:
X printk("pci: disabling sg translation window\n");
X *(vip)CIA_IOC_PCI_W0_BASE = 0;
+ *(vip)CIA_IOC_PCI_W1_BASE = 0;
+ pci_isa_hose->sg_isa = NULL;
X alpha_mv.mv_pci_tbi = NULL;
X goto exit;
X }
@@ -635,10 +637,11 @@
X *(vip)CIA_IOC_HAE_IO = 0;
X
X /* For PYXIS, we always use BWX bus and i/o accesses. To that end,
- make sure they're enabled on the controller. */
+ make sure they're enabled on the controller. At the same time,
+ enable the monster window. */
X if (is_pyxis) {
X temp = *(vip)CIA_IOC_CIA_CNFG;
- temp |= CIA_CNFG_IOA_BWEN;
+ temp |= CIA_CNFG_IOA_BWEN | CIA_CNFG_PCI_MWEN;
X *(vip)CIA_IOC_CIA_CNFG = temp;
X }
X
@@ -682,13 +685,9 @@
X * Set up the PCI to main memory translation windows.
X *
X * Window 0 is scatter-gather 8MB at 8MB (for isa)
- * Window 1 is direct access 1GB at 1GB
- * Window 2 is direct access 1GB at 2GB
- *
- * We must actually use 2 windows to direct-map the 2GB space,
- * because of an idiot-syncrasy of the CYPRESS chip used on
- * many PYXIS systems. It may respond to a PCI bus address in
- * the last 1MB of the 4GB address range.
+ * Window 1 is scatter-gather 1MB at 768MB (for tbia)
+ * Window 2 is direct access 2GB at 2GB
+ * Window 3 is DAC access 4GB at 8GB
X *
X * ??? NetBSD hints that page tables must be aligned to 32K,
X * possibly due to a hardware bug. This is over-aligned
@@ -698,20 +697,35 @@
X
X hose->sg_pci = NULL;


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 02'
echo 'File patch-2.4.13 is continued in part 03'
echo "03" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:33 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part03

#!/bin/sh -x
# this is part 03 of a 53 - part archive


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

if test "$Scheck" != 03; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 32768);
- __direct_map_base = 0x40000000;
+ __direct_map_base = 0x80000000;
X __direct_map_size = 0x80000000;
X
X *(vip)CIA_IOC_PCI_W0_BASE = hose->sg_isa->dma_base | 3;
X *(vip)CIA_IOC_PCI_W0_MASK = (hose->sg_isa->size - 1) & 0xfff00000;
X *(vip)CIA_IOC_PCI_T0_BASE = virt_to_phys(hose->sg_isa->ptes) >> 2;
X
- *(vip)CIA_IOC_PCI_W1_BASE = 0x40000000 | 1;
- *(vip)CIA_IOC_PCI_W1_MASK = (0x40000000 - 1) & 0xfff00000;
- *(vip)CIA_IOC_PCI_T1_BASE = 0 >> 2;
-
- *(vip)CIA_IOC_PCI_W2_BASE = 0x80000000 | 1;
- *(vip)CIA_IOC_PCI_W2_MASK = (0x40000000 - 1) & 0xfff00000;
- *(vip)CIA_IOC_PCI_T2_BASE = 0x40000000 >> 2;
+ *(vip)CIA_IOC_PCI_W2_BASE = __direct_map_base | 1;
+ *(vip)CIA_IOC_PCI_W2_MASK = (__direct_map_size - 1) & 0xfff00000;
+ *(vip)CIA_IOC_PCI_T2_BASE = 0 >> 2;
+
+ /* On PYXIS we have the monster window, selected by bit 40, so
+ there is no need for window3 to be enabled.
+
+ On CIA, we don't have true arbitrary addressing -- bits <39:32>
+ are compared against W_DAC. We can, however, directly map 4GB,
+ which is better than before. However, due to assumptions made
+ elsewhere, we should not claim that we support DAC unless that
+ 4GB covers all of physical memory. */
+ if (is_pyxis || max_low_pfn > (0x100000000 >> PAGE_SHIFT)) {
+ *(vip)CIA_IOC_PCI_W3_BASE = 0;
+ } else {
+ *(vip)CIA_IOC_PCI_W3_BASE = 0x00000000 | 1 | 8;
+ *(vip)CIA_IOC_PCI_W3_MASK = 0xfff00000;
+ *(vip)CIA_IOC_PCI_T3_BASE = 0 >> 2;
+
+ alpha_mv.pci_dac_offset = 0x200000000;
+ *(vip)CIA_IOC_PCI_W_DAC = alpha_mv.pci_dac_offset >> 32;
+ }
X
X /* Prepare workaround for apparently broken tbia. */
X cia_prepare_tbia_workaround();
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c
--- v2.4.12/linux/arch/alpha/kernel/core_mcpcia.c Fri Mar 2 11:12:07 2001
+++ linux/arch/alpha/kernel/core_mcpcia.c Fri Oct 12 15:35:53 2001
@@ -406,12 +406,12 @@
X * Set up the PCI->physical memory translation windows.


X *
X * Window 0 is scatter-gather 8MB at 8MB (for isa)

- * Window 1 is scatter-gather 128MB at 1GB
+ * Window 1 is scatter-gather (up to) 1GB at 1GB (for pci)
X * Window 2 is direct access 2GB at 2GB
- * ??? We ought to scale window 1 with memory.
X */
X hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
- hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 0);
+ hose->sg_pci = iommu_arena_new(hose, 0x40000000,
+ size_for_memory(0x40000000), 0);
X
X __direct_map_base = 0x80000000;
X __direct_map_size = 0x80000000;
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/core_titan.c linux/arch/alpha/kernel/core_titan.c
--- v2.4.12/linux/arch/alpha/kernel/core_titan.c Fri Mar 2 11:12:07 2001
+++ linux/arch/alpha/kernel/core_titan.c Sun Oct 21 10:30:58 2001
@@ -20,6 +20,8 @@
X #include <asm/core_titan.h>
X #undef __EXTERN_INLINE
X
+#include <linux/bootmem.h>
+
X #include "proto.h"
X #include "pci_impl.h"
X
@@ -277,6 +279,7 @@
X titan_init_one_pachip_port(titan_pachip_port *port, int index)
X {
X struct pci_controller *hose;
+ unsigned long sg_size;
X
X hose = alloc_pci_controller();
X if (index == 0)
@@ -342,40 +345,35 @@
X * Note: Window 3 on Titan is Scatter-Gather ONLY


X *
X * Window 0 is scatter-gather 8MB at 8MB (for isa)
- * Window 1 is direct access 1GB at 1GB
- * Window 2 is direct access 1GB at 2GB

- * Window 3 is scatter-gather 128MB at 3GB
- * ??? We ought to scale window 3 memory.


- *
- * We must actually use 2 windows to direct-map the 2GB space,

- * because of an idiot-syncrasy of the CYPRESS chip. It may
- * respond to a PCI bus address in the last 1MB of the 4GB
- * address range.
+ * Window 1 is scatter-gather (up to) 1GB at 1GB


+ * Window 2 is direct access 2GB at 2GB

X */
X hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
X hose->sg_isa->align_entry = 8; /* 64KB for ISA */
X
- hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0);
+ hose->sg_pci = iommu_arena_new(hose, 0x40000000,
+ size_for_memory(0x40000000), 0);
X hose->sg_pci->align_entry = 4; /* Titan caches 4 PTEs at a time */
X
- __direct_map_base = 0x40000000;
+ __direct_map_base = 0x80000000;
X __direct_map_size = 0x80000000;
X
X port->wsba[0].csr = hose->sg_isa->dma_base | 3;
X port->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000;
X port->tba[0].csr = virt_to_phys(hose->sg_isa->ptes);
X
- port->wsba[1].csr = 0x40000000 | 1;
- port->wsm[1].csr = (0x40000000 - 1) & 0xfff00000;
- port->tba[1].csr = 0;
+ port->wsba[1].csr = hose->sg_pci->dma_base | 3;
+ port->wsm[1].csr = (hose->sg_pci->size - 1) & 0xfff00000;
+ port->tba[1].csr = virt_to_phys(hose->sg_pci->ptes);
X
X port->wsba[2].csr = 0x80000000 | 1;
- port->wsm[2].csr = (0x40000000 - 1) & 0xfff00000;
- port->tba[2].csr = 0x40000000;
+ port->wsm[2].csr = (0x80000000 - 1) & 0xfff00000;
+ port->tba[2].csr = 0;
+
+ port->wsba[3].csr = 0;
X
- port->wsba[3].csr = hose->sg_pci->dma_base | 3;
- port->wsm[3].csr = (hose->sg_pci->size - 1) & 0xfff00000;
- port->tba[3].csr = virt_to_phys(hose->sg_pci->ptes);
+ /* Enable the Monster Window to make DAC pci64 possible. */
+ port->pctl.csr |= pctl_m_mwin;
X
X titan_pci_tbi(hose, 0, -1);
X }
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c
--- v2.4.12/linux/arch/alpha/kernel/core_tsunami.c Tue Jul 3 17:08:18 2001
+++ linux/arch/alpha/kernel/core_tsunami.c Sun Oct 21 10:30:58 2001
@@ -279,16 +279,6 @@
X #define FN __FUNCTION__


X
X static void __init

-tsunami_monster_window_enable(tsunami_pchip * pchip)
-{
- volatile unsigned long * csr = &pchip->pctl.csr;
-
- *csr |= pctl_m_mwin;
- mb();
- *csr;
-}
-
-static void __init
X tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
X {
X struct pci_controller *hose;
@@ -358,47 +348,34 @@
X * Note: Window 3 is scatter-gather only


X *
X * Window 0 is scatter-gather 8MB at 8MB (for isa)
- * Window 1 is direct access 1GB at 1GB
- * Window 2 is direct access 1GB at 2GB

- * Window 3 is scatter-gather 128MB at 3GB
- * ??? We ought to scale window 3 memory.


- *
- * We must actually use 2 windows to direct-map the 2GB space,

- * because of an idiot-syncrasy of the CYPRESS chip. It may
- * respond to a PCI bus address in the last 1MB of the 4GB
- * address range.
+ * Window 1 is scatter-gather (up to) 1GB at 1GB


+ * Window 2 is direct access 2GB at 2GB

X */
X hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
- {
- unsigned long size = 0x08000000;
- if (max_low_pfn > (0x80000000 >> PAGE_SHIFT))
- size = 0x40000000;
- hose->sg_pci = iommu_arena_new(hose, 0xc0000000, size, 0);
- }
-
- __direct_map_base = 0x40000000;
+ hose->sg_pci = iommu_arena_new(hose, 0x40000000,
+ size_for_memory(0x40000000), 0);
+
+ __direct_map_base = 0x80000000;
X __direct_map_size = 0x80000000;
X
X pchip->wsba[0].csr = hose->sg_isa->dma_base | 3;
X pchip->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000;
X pchip->tba[0].csr = virt_to_phys(hose->sg_isa->ptes);
X
- pchip->wsba[1].csr = 0x40000000 | 1;
- pchip->wsm[1].csr = (0x40000000 - 1) & 0xfff00000;
- pchip->tba[1].csr = 0;
+ pchip->wsba[1].csr = hose->sg_pci->dma_base | 3;
+ pchip->wsm[1].csr = (hose->sg_pci->size - 1) & 0xfff00000;
+ pchip->tba[1].csr = virt_to_phys(hose->sg_pci->ptes);
X
X pchip->wsba[2].csr = 0x80000000 | 1;
- pchip->wsm[2].csr = (0x40000000 - 1) & 0xfff00000;
- pchip->tba[2].csr = 0x40000000;
+ pchip->wsm[2].csr = (0x80000000 - 1) & 0xfff00000;
+ pchip->tba[2].csr = 0;
X
- pchip->wsba[3].csr = hose->sg_pci->dma_base | 3;
- pchip->wsm[3].csr = (hose->sg_pci->size - 1) & 0xfff00000;
- pchip->tba[3].csr = virt_to_phys(hose->sg_pci->ptes);
-
- tsunami_pci_tbi(hose, 0, -1);
+ pchip->wsba[3].csr = 0;
X
X /* Enable the Monster Window to make DAC pci64 possible. */
- tsunami_monster_window_enable(pchip);
+ pchip->pctl.csr |= pctl_m_mwin;
+
+ tsunami_pci_tbi(hose, 0, -1);
X }
X
X void __init
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c
--- v2.4.12/linux/arch/alpha/kernel/pci.c Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/pci.c Sun Oct 21 10:30:58 2001
@@ -79,35 +79,30 @@
X static void __init
X quirk_cypress(struct pci_dev *dev)
X {
-/*
- * Notorious Cy82C693 chip. One of its numerous bugs: although
- * Cypress IDE controller doesn't support native mode, it has
- * programmable addresses of IDE command/control registers.
- * This violates PCI specifications, confuses IDE subsystem
- * and causes resource conflict between primary HD_CMD register
- * and floppy controller. Ugh.
- * Fix that.
- */
+ /* The Notorious Cy82C693 chip. */
+
+ /* The Cypress IDE controller doesn't support native mode, but it
+ has programmable addresses of IDE command/control registers.
+ This violates PCI specifications, confuses the IDE subsystem and
+ causes resource conflicts between the primary HD_CMD register and
+ the floppy controller. Ugh. Fix that. */
X if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
X dev->resource[0].flags = 0;
X dev->resource[1].flags = 0;
- return;
X }
-/*
- * Another "feature": Cypress bridge responds on the PCI bus
- * in the address range 0xffff0000-0xffffffff (conventional
- * x86 BIOS ROM). No way to turn this off, so if we use
- * large SG window, we must avoid these addresses.
- */
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA) {
- struct pci_controller *hose = dev->sysdata;
- long overlap;
X
- if (hose->sg_pci) {
- overlap = hose->sg_pci->dma_base + hose->sg_pci->size;
- overlap -= 0xffff0000;
- if (overlap > 0)
- hose->sg_pci->size -= overlap;
+ /* The Cypress bridge responds on the PCI bus in the address range
+ 0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no
+ way to turn this off, so if we use a large direct-map window, or
+ a large SG window, we must avoid this region. */
+ else if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA) {
+ if (__direct_map_base + __direct_map_size >= 0xffff0000)
+ __direct_map_size = 0xffff0000 - __direct_map_base;
+ else {
+ struct pci_controller *hose = dev->sysdata;
+ struct pci_iommu_arena *pci = hose->sg_pci;
+ if (pci && pci->dma_base + pci->size >= 0xffff0000)
+ pci->size = 0xffff0000 - pci->dma_base;
X }
X }
X }
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/pci_impl.h linux/arch/alpha/kernel/pci_impl.h
--- v2.4.12/linux/arch/alpha/kernel/pci_impl.h Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/pci_impl.h Fri Oct 12 15:35:53 2001
@@ -163,6 +163,8 @@
X extern const char *const pci_mem_names[];
X extern const char pci_hae0_name[];
X
+extern unsigned long size_for_memory(unsigned long max);
+
X extern int iommu_reserve(struct pci_iommu_arena *, long, long);
X extern int iommu_release(struct pci_iommu_arena *, long, long);
X extern int iommu_bind(struct pci_iommu_arena *, long, long, unsigned long *);
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c
--- v2.4.12/linux/arch/alpha/kernel/pci_iommu.c Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/pci_iommu.c Fri Oct 12 15:35:53 2001
@@ -17,17 +17,18 @@
X
X #define DEBUG_ALLOC 0
X #if DEBUG_ALLOC > 0
-# define DBGA(args...) printk(KERN_DEBUG ##args)
+# define DBGA(args...) printk(KERN_DEBUG args)
X #else
X # define DBGA(args...)
X #endif
X #if DEBUG_ALLOC > 1
-# define DBGA2(args...) printk(KERN_DEBUG ##args)
+# define DBGA2(args...) printk(KERN_DEBUG args)
X #else
X # define DBGA2(args...)
X #endif
X
X #define DEBUG_NODIRECT 0
+#define DEBUG_FORCEDAC 0
X
X
X static inline unsigned long
@@ -43,6 +44,18 @@
X }
X
X
+/* Return the minimum of MAX or the first power of two larger
+ than main memory. */
+
+unsigned long
+size_for_memory(unsigned long max)
+{
+ unsigned long mem = max_low_pfn << PAGE_SHIFT;
+ if (mem < max)
+ max = 1UL << ceil_log2(mem);
+ return max;
+}
+
X struct pci_iommu_arena *
X iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
X unsigned long window_size, unsigned long align)
@@ -163,8 +176,9 @@
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
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, long size, int direction)
+static dma_addr_t
+pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
+ int dac_allowed)
X {
X struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
X dma_addr_t max_dma = pdev ? pdev->dma_mask : 0x00ffffff;
@@ -173,10 +187,7 @@
X unsigned long paddr;
X dma_addr_t ret;
X
- if (direction == PCI_DMA_NONE)
- BUG();
-
- paddr = virt_to_phys(cpu_addr);
+ paddr = __pa(cpu_addr);
X
X #if !DEBUG_NODIRECT
X /* First check to see if we can use the direct map window. */
@@ -184,13 +195,23 @@
X && paddr + size <= __direct_map_size) {
X ret = paddr + __direct_map_base;
X
- DBGA2("pci_map_single: [%p,%lx] -> direct %x from %p\n",
+ DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n",
X cpu_addr, size, ret, __builtin_return_address(0));
X
X return ret;
X }
X #endif
X
+ /* Next, use DAC if selected earlier. */
+ if (dac_allowed) {
+ ret = paddr + alpha_mv.pci_dac_offset;
+
+ DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n",
+ cpu_addr, size, ret, __builtin_return_address(0));
+
+ return ret;
+ }
+
X /* If the machine doesn't define a pci_tbi routine, we have to
X assume it doesn't support sg mapping. */
X if (! alpha_mv.mv_pci_tbi) {
@@ -217,12 +238,30 @@
X ret = arena->dma_base + dma_ofs * PAGE_SIZE;
X ret += (unsigned long)cpu_addr & ~PAGE_MASK;
X
- DBGA("pci_map_single: [%p,%lx] np %ld -> sg %x from %p\n",
- cpu_addr, size, npages, ret, __builtin_return_address(0));
+ DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n",
+ cpu_addr, size, npages, ret, __builtin_return_address(0));
X
X return ret;
X }
X
+dma_addr_t
+pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+{
+ if (dir == PCI_DMA_NONE)
+ BUG();
+ return pci_map_single_1(pdev, cpu_addr, size,
+ (pdev->dma_mask >> 32) != 0);
+}
+
+dma_addr_t
+pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
+ size_t size, int dir)
+{
+ if (dir == PCI_DMA_NONE)
+ BUG();
+ return pci_map_single_1(pdev, (char *)page_address(page) + offset,
+ size, (pdev->dma_mask >> 32) != 0);
+}
X
X /* Unmap a single streaming mode DMA translation. The DMA_ADDR and
X SIZE must match what was provided for in a previous pci_map_single
@@ -231,7 +270,7 @@
X wrote there. */
X
X void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size,
+pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
X int direction)
X {
X unsigned long flags;
@@ -242,17 +281,21 @@
X if (direction == PCI_DMA_NONE)
X BUG();
X
-#if !DEBUG_NODIRECT
X if (dma_addr >= __direct_map_base
X && dma_addr < __direct_map_base + __direct_map_size) {
X /* Nothing to do. */
X
- DBGA2("pci_unmap_single: direct [%x,%lx] from %p\n",
+ DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n",
X dma_addr, size, __builtin_return_address(0));
X
X return;
X }
-#endif
+
+ if (dma_addr > 0xffffffff) {
+ DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n",
+ dma_addr, size, __builtin_return_address(0));
+ return;
+ }
X
X arena = hose->sg_pci;
X if (!arena || dma_addr < arena->dma_base)
@@ -260,7 +303,7 @@
X
X dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT;
X if (dma_ofs * PAGE_SIZE >= arena->size) {
- printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %x "
+ printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx "
X " base %x size %x\n", dma_addr, arena->dma_base,
X arena->size);
X return;
@@ -273,21 +316,24 @@
X
X iommu_arena_free(arena, dma_ofs, npages);
X
-
- /*
- If we're freeing ptes above the `next_entry' pointer (they
+ /* If we're freeing ptes above the `next_entry' pointer (they
X may have snuck back into the TLB since the last wrap flush),
- we need to flush the TLB before reallocating the latter.
- */
+ we need to flush the TLB before reallocating the latter. */
X if (dma_ofs >= arena->next_entry)
X alpha_mv.mv_pci_tbi(hose, dma_addr, dma_addr + size - 1);
X
X spin_unlock_irqrestore(&arena->lock, flags);
X
- DBGA("pci_unmap_single: sg [%x,%lx] np %ld from %p\n",
- dma_addr, size, npages, __builtin_return_address(0));
+ DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n",
+ dma_addr, size, npages, __builtin_return_address(0));
X }
X
+void
+pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
+ size_t size, int direction)
+{
+ pci_unmap_single(pdev, dma_addr, size, direction);
+}
X
X /* Allocate and map kernel buffer using consistent mode DMA for PCI
X device. Returns non-NULL cpu-view pointer to the buffer if
@@ -295,7 +341,7 @@
X else DMA_ADDRP is undefined. */
X
X void *
-pci_alloc_consistent(struct pci_dev *pdev, long size, dma_addr_t *dma_addrp)
+pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
X {
X void *cpu_addr;
X long order = get_order(size);
@@ -311,8 +357,7 @@
X }
X memset(cpu_addr, 0, size);
X
- *dma_addrp = pci_map_single(pdev, cpu_addr, size,
- PCI_DMA_BIDIRECTIONAL);
+ *dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
X if (*dma_addrp == 0) {
X free_pages((unsigned long)cpu_addr, order);
X return NULL;
@@ -324,7 +369,6 @@
X return cpu_addr;
X }
X
-
X /* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
X be values that were returned from pci_alloc_consistent. SIZE must
X be the same as what as passed into pci_alloc_consistent.
@@ -332,7 +376,7 @@
X DMA_ADDR past this call are illegal. */
X
X void
-pci_free_consistent(struct pci_dev *pdev, long size, void *cpu_addr,
+pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
X dma_addr_t dma_addr)
X {
X pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
@@ -352,27 +396,35 @@
X Write dma_length of each leader with the combined lengths of
X the mergable followers. */
X
+#define SG_ENT_VIRT_ADDRESS(SG) \
+ ((SG)->address \
+ ? (SG)->address \
+ : page_address((SG)->page) + (SG)->offset)
+
+#define SG_ENT_PHYS_ADDRESS(SG) \
+ __pa(SG_ENT_VIRT_ADDRESS(SG))
+
X static void
X sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok)
X {
- unsigned long next_vaddr;
+ unsigned long next_paddr;
X struct scatterlist *leader;
X long leader_flag, leader_length;
X
X leader = sg;
X leader_flag = 0;
X leader_length = leader->length;
- next_vaddr = (unsigned long)leader->address + leader_length;
+ next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length;
X
X for (++sg; sg < end; ++sg) {
X unsigned long addr, len;
- addr = (unsigned long) sg->address;
+ addr = SG_ENT_PHYS_ADDRESS(sg);
X len = sg->length;
X
- if (next_vaddr == addr) {
+ if (next_paddr == addr) {
X sg->dma_address = -1;
X leader_length += len;
- } else if (((next_vaddr | addr) & ~PAGE_MASK) == 0 && virt_ok) {
+ } else if (((next_paddr | addr) & ~PAGE_MASK) == 0 && virt_ok) {
X sg->dma_address = -2;
X leader_flag = 1;
X leader_length += len;
@@ -384,7 +436,7 @@
X leader_length = len;
X }
X
- next_vaddr = addr + len;
+ next_paddr = addr + len;
X }
X
X leader->dma_address = leader_flag;
@@ -397,9 +449,9 @@
X static inline int
X sg_fill(struct scatterlist *leader, struct scatterlist *end,
X struct scatterlist *out, struct pci_iommu_arena *arena,
- dma_addr_t max_dma)
+ dma_addr_t max_dma, int dac_allowed)
X {
- unsigned long paddr = virt_to_phys(leader->address);
+ unsigned long paddr = SG_ENT_PHYS_ADDRESS(leader);
X long size = leader->dma_length;
X struct scatterlist *sg;
X unsigned long *ptes;
@@ -414,13 +466,24 @@
X out->dma_address = paddr + __direct_map_base;
X out->dma_length = size;
X
- DBGA(" sg_fill: [%p,%lx] -> direct %x\n",
- leader->address, size, out->dma_address);
+ DBGA(" sg_fill: [%p,%lx] -> direct %lx\n",
+ __va(paddr), size, out->dma_address);
X
X return 0;
X }
X #endif
X
+ /* If physically contiguous and DAC is available, use it. */
+ if (leader->dma_address == 0 && dac_allowed) {
+ out->dma_address = paddr + alpha_mv.pci_dac_offset;
+ out->dma_length = size;
+
+ DBGA(" sg_fill: [%p,%lx] -> DAC %lx\n",
+ __va(paddr), size, out->dma_address);
+
+ return 0;
+ }
+
X /* Otherwise, we'll use the iommu to make the pages virtually
X contiguous. */
X
@@ -433,17 +496,16 @@
X return -1;
X
X /* Otherwise, break up the remaining virtually contiguous
- hunks into individual direct maps. */
+ hunks into individual direct maps and retry. */
X sg_classify(leader, end, 0);
- /* Retry. */
- return sg_fill(leader, end, out, arena, max_dma);
+ return sg_fill(leader, end, out, arena, max_dma, dac_allowed);
X }
X
X out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
X out->dma_length = size;
X
- DBGA(" sg_fill: [%p,%lx] -> sg %x np %ld\n",
- leader->address, size, out->dma_address, npages);
+ DBGA(" sg_fill: [%p,%lx] -> sg %lx np %ld\n",
+ __va(paddr), size, out->dma_address, npages);
X
X /* All virtually contiguous. We need to find the length of each
X physically contiguous subsegment to fill in the ptes. */
@@ -455,7 +517,7 @@
X #endif
X
X size = sg->length;
- paddr = virt_to_phys(sg->address);
+ paddr = SG_ENT_PHYS_ADDRESS(sg);
X
X while (sg+1 < end && (int) sg[1].dma_address == -1) {
X size += sg[1].length;
@@ -470,11 +532,11 @@
X
X #if DEBUG_ALLOC > 0
X DBGA(" (%ld) [%p,%x] np %ld\n",
- last_sg - leader, last_sg->address,
+ last_sg - leader, SG_ENT_VIRT_ADDRESS(last_sg),
X last_sg->length, npages);
X while (++last_sg <= sg) {
X DBGA(" (%ld) [%p,%x] cont\n",
- last_sg - leader, last_sg->address,
+ last_sg - leader, SG_ENT_VIRT_ADDRESS(last_sg),
X last_sg->length);
X }
X #endif
@@ -491,15 +553,19 @@
X struct pci_controller *hose;
X struct pci_iommu_arena *arena;
X dma_addr_t max_dma;
+ int dac_allowed;
X
X if (direction == PCI_DMA_NONE)
X BUG();
X
+ dac_allowed = ((pdev->dma_mask >> 32) != 0);
+
X /* Fast path single entry scatterlists. */
X if (nents == 1) {
X sg->dma_length = sg->length;
X sg->dma_address
- = pci_map_single(pdev, sg->address, sg->length, direction);
+ = pci_map_single_1(pdev, SG_ENT_VIRT_ADDRESS(sg),
+ sg->length, dac_allowed);
X return sg->dma_address != 0;
X }
X
@@ -527,7 +593,7 @@
X for (out = sg; sg < end; ++sg) {
X if ((int) sg->dma_address < 0)
X continue;
- if (sg_fill(sg, end, out, arena, max_dma) < 0)
+ if (sg_fill(sg, end, out, arena, max_dma, dac_allowed) < 0)
X goto error;
X out++;
X }
@@ -542,7 +608,7 @@
X
X return out - start;
X
-error:
+ error:
X printk(KERN_WARNING "pci_map_sg failed: "
X "could not allocate dma page tables\n");
X
@@ -553,7 +619,6 @@
X return 0;
X }
X
-
X /* Unmap a set of streaming mode DMA translations. Again, cpu read
X rules concerning calls here are the same as for pci_unmap_single()
X above. */
@@ -586,7 +651,8 @@
X spin_lock_irqsave(&arena->lock, flags);
X
X for (end = sg + nents; sg < end; ++sg) {
- unsigned long addr, size;
+ dma64_addr_t addr;
+ size_t size;
X long npages, ofs;
X dma_addr_t tend;
X
@@ -595,7 +661,13 @@
X if (!size)
X break;
X
-#if !DEBUG_NODIRECT
+ if (addr > 0xffffffff) {
+ /* It's a DAC address -- nothing to do. */
+ DBGA(" (%ld) DAC [%lx,%lx]\n",
+ sg - end + nents, addr, size);
+ continue;
+ }
+
X if (addr >= __direct_map_base
X && addr < __direct_map_base + __direct_map_size) {
X /* Nothing to do. */
@@ -603,7 +675,6 @@
X sg - end + nents, addr, size);
X continue;
X }
-#endif
X
X DBGA(" (%ld) sg [%lx,%lx]\n",
X sg - end + nents, addr, size);
@@ -617,29 +688,27 @@
X if (fend < tend) fend = tend;
X }
X
- /*
- If we're freeing ptes above the `next_entry' pointer (they
+ /* If we're freeing ptes above the `next_entry' pointer (they
X may have snuck back into the TLB since the last wrap flush),
- we need to flush the TLB before reallocating the latter.
- */
+ we need to flush the TLB before reallocating the latter. */
X if ((fend - arena->dma_base) >> PAGE_SHIFT >= arena->next_entry)
X alpha_mv.mv_pci_tbi(hose, fbeg, fend);
X
X spin_unlock_irqrestore(&arena->lock, flags);
X
- DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg));
+ DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
X }
X
+
X /* Return whether the given PCI device DMA address mask can be
X supported properly. */
X
X int
-pci_dma_supported(struct pci_dev *pdev, dma_addr_t mask)
+pci_dma_supported(struct pci_dev *pdev, u64 mask)
X {
X struct pci_controller *hose;
X struct pci_iommu_arena *arena;
X
-#if !DEBUG_NODIRECT
X /* If there exists a direct map, and the mask fits either
X MAX_DMA_ADDRESS defined such that GFP_DMA does something
X useful, or the total system memory as shifted by the
@@ -648,7 +717,6 @@
X && (__direct_map_base + MAX_DMA_ADDRESS-IDENT_ADDR-1 <= mask
X || __direct_map_base + (max_low_pfn<<PAGE_SHIFT)-1 <= mask))
X return 1;
-#endif
X
X /* Check that we have a scatter-gather arena that fits. */
X hose = pdev ? pdev->sysdata : pci_isa_hose;
@@ -758,4 +826,50 @@
X p[i] = IOMMU_RESERVED_PTE;
X
X return 0;
+}
+
+/* True if the machine supports DAC addressing, and DEV can
+ make use of it given MASK. */
+
+int
+pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
+{
+ dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+ int ok = 1;
+
+ /* If this is not set, the machine doesn't support DAC at all. */
+ if (dac_offset == 0)
+ ok = 0;
+
+ /* The device has to be able to address our DAC bit. */
+ if ((dac_offset & dev->dma_mask) != dac_offset)
+ ok = 0;
+
+ /* If both conditions above are met, we are fine. */
+ DBGA("pci_dac_dma_supported %s from %p\n",
+ ok ? "yes" : "no", __builtin_return_address(0));
+
+ return ok;
+}
+
+dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page,
+ unsigned long offset, int direction)
+{
+ return (alpha_mv.pci_dac_offset
+ + __pa(page_address(page))
+ + (dma64_addr_t) offset);
+}
+
+struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ unsigned long paddr = (dma_addr & PAGE_MASK) - alpha_mv.pci_dac_offset;
+ return virt_to_page(__va(paddr));
+}
+
+unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ return (dma_addr & ~PAGE_MASK);
X }
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/srm_env.c linux/arch/alpha/kernel/srm_env.c
--- v2.4.12/linux/arch/alpha/kernel/srm_env.c Mon Aug 27 12:41:38 2001
+++ linux/arch/alpha/kernel/srm_env.c Sun Oct 21 10:20:57 2001
@@ -2,11 +2,11 @@
X * srm_env.c - Access to SRC environment variables through
X * the linux procfs
X *
- * (C)2001, Jan-Benedict Glaw <jb...@lug-owl.de>
+ * (C)2001, Jan-Benedict Glaw <jbg...@lug-owl.de>
X *
X * This driver is at all a modified version of Erik Mouw's
X * ./linux/Documentation/DocBook/procfs_example.c, so: thanky
- * you, erik! He can be reached via email at
+ * you, Erik! He can be reached via email at
X * <J.A.K...@its.tudelft.nl>. It is based on an idea
X * provided by DEC^WCompaq's "Jumpstart" CD. They included
X * a patch like this as well. Thanks for idea!
@@ -45,12 +45,13 @@
X #include <asm/uaccess.h>
X
X #define DIRNAME "srm_environment" /* Subdir in /proc/ */
-#define VERSION "0.0.1" /* Module version */
+#define VERSION "0.0.2" /* Module version */
X #define NAME "srm_env" /* Module name */
X #define DEBUG
X
X MODULE_AUTHOR("Jan-Benedict Glaw <jbg...@lug-owl.de>");
X MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
+MODULE_LICENSE("GPL");
X EXPORT_NO_SYMBOLS;
X
X typedef struct _srm_env {
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c
--- v2.4.12/linux/arch/alpha/kernel/sys_cabriolet.c Tue Oct 9 17:06:51 2001
+++ linux/arch/alpha/kernel/sys_cabriolet.c Fri Oct 12 15:35:53 2001
@@ -407,6 +407,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: PYXIS_DAC_OFFSET,
X
X nr_irqs: 35,
X device_interrupt: cabriolet_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- v2.4.12/linux/arch/alpha/kernel/sys_dp264.c Mon Aug 27 12:41:38 2001
+++ linux/arch/alpha/kernel/sys_dp264.c Fri Oct 12 15:35:53 2001
@@ -574,6 +574,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 64,
X device_interrupt: dp264_device_interrupt,
@@ -598,6 +599,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 64,
X device_interrupt: dp264_device_interrupt,
@@ -621,6 +623,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 64,
X device_interrupt: dp264_device_interrupt,
@@ -644,6 +647,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 64,
X device_interrupt: dp264_device_interrupt,
@@ -672,6 +676,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 64,
X device_interrupt: dp264_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_eiger.c linux/arch/alpha/kernel/sys_eiger.c
--- v2.4.12/linux/arch/alpha/kernel/sys_eiger.c Fri Mar 2 11:12:07 2001
+++ linux/arch/alpha/kernel/sys_eiger.c Fri Oct 12 15:35:53 2001
@@ -233,6 +233,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TSUNAMI_DAC_OFFSET,
X
X nr_irqs: 128,
X device_interrupt: eiger_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c
--- v2.4.12/linux/arch/alpha/kernel/sys_miata.c Sat May 19 17:43:05 2001
+++ linux/arch/alpha/kernel/sys_miata.c Fri Oct 12 15:35:53 2001
@@ -256,6 +256,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: PYXIS_DAC_OFFSET,
X
X nr_irqs: 48,
X device_interrupt: pyxis_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c
--- v2.4.12/linux/arch/alpha/kernel/sys_rawhide.c Tue Jul 3 17:08:18 2001
+++ linux/arch/alpha/kernel/sys_rawhide.c Fri Oct 12 15:35:53 2001
@@ -254,6 +254,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
+ pci_dac_offset: MCPCIA_DAC_OFFSET,
X
X nr_irqs: 128,
X device_interrupt: rawhide_srm_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c
--- v2.4.12/linux/arch/alpha/kernel/sys_ruffian.c Thu Feb 8 12:56:29 2001
+++ linux/arch/alpha/kernel/sys_ruffian.c Fri Oct 12 15:35:53 2001
@@ -220,6 +220,7 @@
X max_dma_address: ALPHA_RUFFIAN_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: PYXIS_DAC_OFFSET,
X
X nr_irqs: 48,
X device_interrupt: pyxis_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c
--- v2.4.12/linux/arch/alpha/kernel/sys_sx164.c Fri Oct 27 10:55:01 2000
+++ linux/arch/alpha/kernel/sys_sx164.c Fri Oct 12 15:35:53 2001
@@ -129,7 +129,9 @@
X struct percpu_struct *cpu = (struct percpu_struct*)
X ((char*)hwrpb + hwrpb->processor_offset);
X
- if (alpha_using_srm && (cpu->pal_revision & 0xffff) == 0x117) {
+ if (amask(AMASK_MAX) != 0
+ && alpha_using_srm
+ && (cpu->pal_revision & 0xffff) == 0x117) {
X __asm__ __volatile__(
X "lda $16,8($31)\n"
X "call_pal 9\n" /* Allow PALRES insns in kernel mode */
@@ -160,6 +162,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: PYXIS_DAC_OFFSET,
X
X nr_irqs: 48,
X device_interrupt: pyxis_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/alpha/kernel/sys_titan.c linux/arch/alpha/kernel/sys_titan.c
--- v2.4.12/linux/arch/alpha/kernel/sys_titan.c Fri Mar 2 11:12:07 2001
+++ linux/arch/alpha/kernel/sys_titan.c Fri Oct 12 15:35:53 2001
@@ -378,6 +378,7 @@
X max_dma_address: ALPHA_MAX_DMA_ADDRESS,
X min_io_address: DEFAULT_IO_BASE,
X min_mem_address: DEFAULT_MEM_BASE,
+ pci_dac_offset: TITAN_DAC_OFFSET,
X
X nr_irqs: 80, /* 64 + 16 */
X device_interrupt: privateer_device_interrupt,
diff -u --recursive --new-file v2.4.12/linux/arch/arm/Makefile linux/arch/arm/Makefile
--- v2.4.12/linux/arch/arm/Makefile Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/Makefile Thu Oct 11 09:04:57 2001
@@ -45,8 +45,6 @@
X CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
X AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu
X
-LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
-
X ifeq ($(CONFIG_CPU_26),y)
X PROCESSOR = armo
X ifeq ($(CONFIG_ROM_KERNEL),y)
@@ -123,7 +121,7 @@
X endif
X
X ifeq ($(CONFIG_ARCH_CLPS711X),y)
-TEXTADDR = 0xc0018000
+TEXTADDR = 0xc0028000
X MACHINE = clps711x
X endif
X
@@ -131,7 +129,7 @@
X MACHINE = anakin
X endif
X
-export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
+export MACHINE PROCESSOR TEXTADDR GZFLAGS
X
X # Only set INCDIR if its not already defined above
X # Grr, ?= doesn't work as all the other assignment operators do. Make bug?
@@ -155,7 +153,7 @@
X SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe \
X arch/arm/fastfpe
X CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS := arch/arm/lib/lib.a $(LIBS) $(LIBGCC)
+LIBS := arch/arm/lib/lib.a $(LIBS)
X
X ifeq ($(CONFIG_FPE_NWFPE),y)
X LIBS := arch/arm/nwfpe/math-emu.o $(LIBS)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
--- v2.4.12/linux/arch/arm/boot/Makefile Tue Jul 3 17:08:18 2001
+++ linux/arch/arm/boot/Makefile Thu Oct 11 09:04:57 2001
@@ -69,12 +69,21 @@
X ZBSSADDR = 0xf03e0000
X endif
X
-ifeq ($(CONFIG_ARCH_P720T),y)
-ZTEXTADDR = 0xc0018000
+# The standard locations for stuff on CLPS711x type processors
+ifeq ($(CONFIG_ARCH_CLPS711X),y)
+ZTEXTADDR = 0xc0028000
X PARAMS_PHYS = 0xc0000100
+endif
+
+# Should probably have some agreement on these...
+ifeq ($(CONFIG_ARCH_P720T),y)
X INITRD_PHYS = 0xc0400000
X INITRD_VIRT = 0xc0400000
X endif
+ifeq ($(CONFIG_ARCH_CDB89712),y)
+INITRD_PHYS = 0x00700000
+INITRD_VIRT = 0xc0300000
+endif
X
X ifeq ($(CONFIG_ARCH_SA1100),y)
X ZTEXTADDR = 0xc0008000
@@ -89,6 +98,12 @@
X endif
X ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
X ZTEXTADDR = 0xC0200000
+endif
+ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y)
+ ZTEXTADDR = 0xC0400000
+endif
+ifeq ($(CONFIG_SA1100_ADSBITSY),y)
+ ZTEXTADDR = 0xC0400000
X endif
X ifeq ($(CONFIG_SA1100_YOPY),y)
X ZTEXTADDR = 0x00080000
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/bootp/Makefile linux/arch/arm/boot/bootp/Makefile
--- v2.4.12/linux/arch/arm/boot/bootp/Makefile Thu Feb 8 16:32:44 2001
+++ linux/arch/arm/boot/bootp/Makefile Thu Oct 11 09:04:57 2001
@@ -3,7 +3,6 @@
X #
X
X ZSYSTEM =$(TOPDIR)/arch/arm/boot/zImage
-INITRD =$(ZSYSTEM)
X ZLDFLAGS =-p -X -T bootp.lds \
X --defsym initrd_addr=$(INITRD_PHYS) \
X --defsym initrd_virt=$(INITRD_VIRT) \
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/bootp/init.S linux/arch/arm/boot/bootp/init.S
--- v2.4.12/linux/arch/arm/boot/bootp/init.S Thu Feb 8 16:32:44 2001
+++ linux/arch/arm/boot/bootp/init.S Thu Oct 11 09:04:57 2001
@@ -39,7 +39,7 @@
X * method by looking at the first word; this should either indicate a page
X * size of 4K, 16K or 32K.
X */
- ldmia r13, {r5-r8} @ get size and addr of initrd
+ ldmia r13, {r4-r8} @ get size and addr of initrd
X @ r5 = ATAG_INITRD
X @ r6 = initrd start
X @ r7 = initrd end
@@ -48,10 +48,25 @@
X teq r9, #0x1000 @ 4K?
X teqne r9, #0x4000 @ 16K?
X teqne r9, #0x8000 @ 32K?
- beq no_taglist
+ beq param_struct
+
+ ldr r9, [r8, #4] @ get first tag
+ teq r9, r4
+ bne taglist @ ok, we have a tag list
+
+/*
+ * We didn't find a valid tag list - create one.
+ */
+ str r4, [r8, #4]
+ mov r4, #8
+ str r4, [r8, #0]
+ mov r4, #0
+ str r4, [r8, #8]
X
X /*
X * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precidence.
X */
X taglist: ldr r9, [r8, #0] @ tag length
X teq r9, #0 @ last tag?
@@ -63,7 +78,10 @@
X stmia r8, {r4, r5, r6, r7, r9}
X mov pc, r12 @ call kernel
X
-no_taglist: add r8, r8, #16*4
+/*
+ * We found a param struct. Modify the param struct for the initrd
+ */
+param_struct: add r8, r8, #16*4
X stmia r8, {r6,r7} @ save in param_struct
X mov pc, r12 @ call kernel
X
@@ -83,6 +101,7 @@
X .word kernel_addr
X .word kernel_len
X
+ .word 0x54410001 @ r4 = ATAG_CORE
X .word 0x54410005 @ r5 = ATAG_INITRD
X .word initrd_virt @ r6
X .word initrd_len @ r7
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
--- v2.4.12/linux/arch/arm/boot/compressed/Makefile Tue Jul 3 17:08:18 2001
+++ linux/arch/arm/boot/compressed/Makefile Thu Oct 11 09:04:57 2001
@@ -51,7 +51,7 @@
X endif
X
X ifeq ($(CONFIG_ARCH_SA1100),y)
-OBJS += head-sa1100.o setup-sa1100.o
+OBJS += head-sa1100.o
X ifeq ($(CONFIG_SA1100_NANOENGINE),y)
X OBJS += hw-bse.o
X endif
@@ -64,6 +64,8 @@
X else
X SEDFLAGS += s/BSS_START/ALIGN(4)/
X endif
+
+LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
X
X all: vmlinux
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/head-sa1100.S linux/arch/arm/boot/compressed/head-sa1100.S
--- v2.4.12/linux/arch/arm/boot/compressed/head-sa1100.S Thu Feb 8 16:32:44 2001
+++ linux/arch/arm/boot/compressed/head-sa1100.S Thu Oct 11 09:04:57 2001
@@ -17,6 +17,24 @@
X
X @ Preserve r8/r7 i.e. kernel entry values
X
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) && !defined(CONFIG_ANGELBOOT)
+ mov r7, #MACH_TYPE_GRAPHICSCLIENT
+ mov r8, #0
+#endif
+#if defined(CONFIG_SA1100_GRAPHICSMASTER) && !defined(CONFIG_ANGELBOOT)
+ mov r7, #MACH_TYPE_GRAPHICSMASTER
+ mov r8, #0
+#endif
+#if defined(CONFIG_SA1100_ADSBITSY) && !defined(CONFIG_ANGELBOOT)
+ mov r7, #MACH_TYPE_ADSBITSY
+ mov r8, #0
+#endif
+
+#ifdef CONFIG_SA1100_PFS168
+ @ REVISIT_PFS168: Temporary until firmware updated to use assigned machine number
+ mov r7, #MACH_TYPE_PFS168
+#endif
+
X #ifdef CONFIG_SA1100_VICTOR
X teq r7, #MACH_TYPE_VICTOR
X bne 10f
@@ -51,7 +69,6 @@
X bic r0, r0, #0x1000 @ clear Icache
X mcr p15, 0, r0, c1, c0, 0
X
-#ifdef CONFIG_ANGELBOOT
X /*
X * Pause for a short time so that we give enough time
X * for the host to start a terminal up.
@@ -59,5 +76,4 @@
X mov r0, #0x00200000
X 1: subs r0, r0, #1
X bne 1b
-#endif
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/boot/compressed/setup-sa1100.S linux/arch/arm/boot/compressed/setup-sa1100.S
--- v2.4.12/linux/arch/arm/boot/compressed/setup-sa1100.S Tue Jul 3 17:08:18 2001
+++ linux/arch/arm/boot/compressed/setup-sa1100.S Wed Dec 31 16:00:00 1969
@@ -1,163 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/setup-sa1100.S
- *
- * Copyright (C) 2000 Nicolas Pitre <ni...@cam.org>
- *
- * SA1100 setup routines, to be used after BSS has been cleared.
- *
- * John G Dorsey <jo...@cs.cmu.edu> 2000/05/25 :
- * Runtime test for Neponset added.
- */
-
-#include <linux/linkage.h>
-#include <linux/config.h>
-#include <asm/mach-types.h>
-
- .text
-
-GPIO_BASE: .long 0x90040000
-#define GPLR 0x00
-#define GPDR 0x04
-#define GPSR 0x08
-#define GAFR 0x1c
-
-PPC_BASE: .long 0x90060000
-#define PPAR 0x08
-
-IC_BASE: .long 0x90050000
-#define ICMR 0x04
-
-UART1_BASE: .long 0x80010000
-UART3_BASE: .long 0x80050000
-#define UTCR0 0x00
-#define UTCR1 0x04
-#define UTCR2 0x08
-#define UTCR3 0x0c
-#define UTSR0 0x1c
-#define UTSR1 0x20
-
-#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE
-#define CONFIG_SA1100_DEFAULT_BAUDRATE 9600
-#endif
-
-#define BAUD_DIV ((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1)
-
-SCR_loc: .long SYMBOL_NAME(SCR_value)
-#define GPIO_2_9 0x3fc
-
-
-/*
- * void sa1100_setup( int arch_id );
- *
- * This is called from decompress_kernel() with the arch_decomp_setup() macro.
- */
-
-ENTRY(sa1100_setup)
- mov r3, r0 @ keep machine type in r3
-
- @ Clear all interrupt sources
- ldr r0, IC_BASE
- mov r1, #0
- str r1, [r0, #ICMR]
-
-@ Read System Configuration "Register" for Assabet.
-@ (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
-@ User's Guide," p.4-9)
-
- teq r3, #MACH_TYPE_ASSABET
- bne skip_SCR
-
- ldr r0, GPIO_BASE
- ldr r1, [r0, #GPDR]
- and r1, r1, #GPIO_2_9
- str r1, [r0, #GPDR]
- mov r1, #GPIO_2_9
- str r1, [r0, #GPSR]
- ldr r1, [r0, #GPDR]
- bic r1, r1, #GPIO_2_9
- str r1, [r0, #GPDR]
-
- mov r2, #100
-1: ldr r1, [r0, #GPLR]
- subs r2, r2, #1
- bne 1b
-
- and r2, r1, #GPIO_2_9
- ldr r1, SCR_loc
- str r2, [r1]
-
- ldr r1, [r0, #GPDR]
- and r1, r1, #GPIO_2_9
- str r1, [r0, #GPDR]
-
-skip_SCR:
-
- @ Initialize UART (if bootloader has not done it yet)...
- teq r3, #MACH_TYPE_BRUTUS
- teqne r3, #MACH_TYPE_ASSABET
- teqne r3, #MACH_TYPE_ITSY
- teqne r3, #MACH_TYPE_OMNIMETER
- teqne r3, #MACH_TYPE_JORNADA720
- teqne r3, #MACH_TYPE_GRAPHICSCLIENT
- teqne r3, #MACH_TYPE_FLEXANET
- bne skip_uart
-
- @ UART3 if Assabet is used with Neponset
- teq r3, #MACH_TYPE_ASSABET @ if Assabet
- tsteq r2, #(1 << 9) @ ... and Neponset present
- ldreq r0, UART3_BASE
- beq uart_init
-
- @ UART3 on GraphicsClient
- teq r3, #MACH_TYPE_GRAPHICSCLIENT
- ldreq r0, UART3_BASE
- beq uart_init
-
- @ At least for Brutus, the UART1 is used through
- @ the alternate GPIO function...
- teq r3, #MACH_TYPE_BRUTUS
- bne uart1
-
-alt_GPIO_uart: ldr r0, GPIO_BASE
- ldr r1, [r0, #GPDR]
- bic r1, r1, #1<<15
- orr r1, r1, #1<<14
- str r1, [r0, #GPDR]
- ldr r1, [r0, #GAFR]
- orr r1, r1, #(1<<15)|(1<<14)
- str r1, [r0, #GAFR]
- ldr r0, PPC_BASE
- ldr r1, [r0, #PPAR]
- orr r1, r1, #1<<12
- str r1, [r0, #PPAR]
-
-uart1: ldr r0, UART1_BASE
-
-uart_init:
-1: ldr r1, [r0, #UTSR1]
- tst r1, #1<<0 @ TBY
- bne 1b
- mov r1, #0
- str r1, [r0, #UTCR3]
- mov r1, #0x08 @ 8N1
- str r1, [r0, #UTCR0]
- mov r1, #BAUD_DIV
- str r1, [r0, #UTCR2]
- mov r1, r1, lsr #8
- str r1, [r0, #UTCR1]
- mov r1, #0x03 @ RXE + TXE
- str r1, [r0, #UTCR3]
- mov r1, #0xff @ flush status reg
- str r1, [r0, #UTSR0]
-skip_uart:
-
- @ Extra specific setup calls
- @ The machine type is passed in r0
- mov r0, r3
-#ifdef CONFIG_SA1100_NANOENGINE
- teq r0, #MACH_TYPE_NANOENGINE
- beq SYMBOL_NAME(bse_setup)
-#endif
-
-out: mov pc, lr
-
diff -u --recursive --new-file v2.4.12/linux/arch/arm/config.in linux/arch/arm/config.in
--- v2.4.12/linux/arch/arm/config.in Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/config.in Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@
X define_bool CONFIG_UID16 y
X define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
X define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
X
X
X mainmenu_option next_comment
@@ -68,12 +69,13 @@
X comment 'SA11x0 Implementations'
X dep_bool ' Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100
X dep_bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET
+dep_bool ' ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100
X dep_bool ' Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100
X dep_bool ' CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100
X if [ "$CONFIG_SA1100_CERF" = "y" ]; then
X bool ' 32MB Cerf support' CONFIG_SA1100_CERF_32MB
X fi
-dep_bool ' Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY $CONFIG_ARCH_SA1100
+dep_bool ' Compaq iPAQ H3600' CONFIG_SA1100_H3600 $CONFIG_ARCH_SA1100
X #dep_bool ' Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
X dep_bool ' Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
X if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -82,6 +84,7 @@
X dep_bool ' FlexaNet' CONFIG_SA1100_FLEXANET $CONFIG_ARCH_SA1100
X dep_bool ' FreeBird-v1.1' CONFIG_SA1100_FREEBIRD $CONFIG_ARCH_SA1100
X dep_bool ' GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
+dep_bool ' GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
X dep_bool ' HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
X dep_bool ' HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
X dep_bool ' Itsy' CONFIG_SA1100_ITSY $CONFIG_ARCH_SA1100
@@ -101,14 +104,38 @@
X if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
X "$CONFIG_SA1100_JORNADA720" = "y" -o \
X "$CONFIG_SA1100_PFS168" = "y" -o \
- "$CONFIG_SA1100_XP860" = "y" ]; then
+ "$CONFIG_SA1100_XP860" = "y" -o \
+ "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
+ "$CONFIG_SA1100_ADSBITSY" = "y" ]; then
X define_bool CONFIG_SA1111 y
+ define_int CONFIG_FORCE_MAX_ZONEORDER 9
X fi
X endmenu
X
X mainmenu_option next_comment
X comment 'CLPS711X/EP721X Implementations'
+dep_bool ' CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
+dep_bool ' CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
+dep_bool ' EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
X dep_bool ' P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+
+# XXX Maybe these should indicate register compatibility
+# instead of being mutually exclusive.
+if [ "$CONFIG_ARCH_EDB7211" = "y" ]; then
+ define_bool CONFIG_ARCH_EP7211 y
+else
+ define_bool CONFIG_ARCH_EP7211 n
+fi
+if [ "$CONFIG_ARCH_P720T" = "y" ]; then
+ define_bool CONFIG_ARCH_EP7212 y
+else
+ define_bool CONFIG_ARCH_EP7212 n
+fi
+
+if [ "$CONFIG_ARCH_EP7211" = "y" -o \
+ "$CONFIG_ARCH_EP7212" = "y" ]; then
+ bool ' EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
+fi
X endmenu
X
X # Definitions to make life easier
@@ -196,7 +223,9 @@
X fi
X
X # ARM720T
-if [ "$CONFIG_ARCH_CLPS711X" = "y" -o "$CONFIG_ARCH_L7200" = "y" ]; then
+if [ "$CONFIG_ARCH_CLPS711X" = "y" -o \
+ "$CONFIG_ARCH_L7200" = "y" -o \
+ "$CONFIG_ARCH_CDB89712" = "y" ]; then
X define_bool CONFIG_CPU_ARM720T y
X else
X if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -255,12 +284,13 @@
X define_bool CONFIG_CPU_SA1100 n
X fi
X
-#if [ "$CONFIG_CPU_32" = "y" ]; then
-# bool 'Support Thumb instructions' CONFIG_ARM_THUMB
-#fi
+if [ "$CONFIG_CPU_32" = "y" ]; then
+ dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+fi
X
X # Select various configuration options depending on the machine type
-if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
+ "$CONFIG_ARCH_SA1100" = "y" ]; then
X define_bool CONFIG_DISCONTIGMEM y
X else
X define_bool CONFIG_DISCONTIGMEM n
@@ -289,6 +319,8 @@
X "$CONFIG_ARCH_SHARK" = "y" -o \
X "$CONFIG_ARCH_CLPS7500" = "y" -o \
X "$CONFIG_ARCH_EBSA110" = "y" -o \
+ "$CONFIG_ARCH_CDB89712" = "y" -o \
+ "$CONFIG_ARCH_EDB7211" = "y" -o \
X "$CONFIG_ARCH_SA1100" = "y" ]; then
X define_bool CONFIG_ISA y
X else
@@ -318,6 +350,7 @@
X bool 'System V IPC' CONFIG_SYSVIPC
X bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
X bool 'Sysctl support' CONFIG_SYSCTL
+comment 'At least one math emulation must be selected'
X tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
X dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
X choice 'Kernel core (/proc/kcore) format' \
@@ -335,6 +368,7 @@
X "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
X "$CONFIG_ARCH_CATS" = "y" -o \
X "$CONFIG_ARCH_P720T" = "y" -o \
+ "$CONFIG_ARCH_CDB89712" = "y" -o \
X "$CONFIG_ARCH_ANAKIN" = "y" ]; then
X string 'Default kernel command string' CONFIG_CMDLINE ""
X fi
@@ -346,6 +380,7 @@
X "$CONFIG_ARCH_CO285" = "y" -o \
X "$CONFIG_ARCH_SA1100" = "y" -o \
X "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+ "$CONFIG_ARCH_CDB89712" = "y" -o \
X "$CONFIG_ARCH_P720T" = "y" ]; then
X bool 'Timer and CPU usage LEDs' CONFIG_LEDS
X if [ "$CONFIG_LEDS" = "y" ]; then
@@ -429,7 +464,7 @@
X
X source drivers/ieee1394/Config.in
X
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
X
X mainmenu_option next_comment
X comment 'ISDN subsystem'
@@ -509,6 +544,8 @@
X fi
X endmenu
X fi
+
+source drivers/misc/Config.in
X
X source drivers/usb/Config.in
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile
--- v2.4.12/linux/arch/arm/kernel/Makefile Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/Makefile Thu Oct 11 09:04:57 2001
@@ -41,7 +41,7 @@
X export-objs := armksyms.o dma.o ecard.o fiq.o io.o oldlatches.o time.o
X
X no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
- $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
+ $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
X $(CONFIG_ARCH_SA1100)
X
X ifneq ($(findstring y,$(no-irq-arch)),y)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c
--- v2.4.12/linux/arch/arm/kernel/armksyms.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/armksyms.c Thu Oct 11 09:04:57 2001
@@ -54,22 +54,16 @@
X * compiler... (prototypes are not correct though, but that
X * doesn't really matter since they're not versioned).
X */
-extern void __gcc_bcmp(void);
X extern void __ashldi3(void);
X extern void __ashrdi3(void);
-extern void __cmpdi2(void);
-extern void __divdi3(void);
X extern void __divsi3(void);
X extern void __lshrdi3(void);
-extern void __moddi3(void);
X extern void __modsi3(void);
X extern void __muldi3(void);
-extern void __negdi2(void);
X extern void __ucmpdi2(void);
X extern void __udivdi3(void);
X extern void __udivmoddi4(void);
X extern void __udivsi3(void);
-extern void __umoddi3(void);
X extern void __umodsi3(void);
X
X extern void ret_from_exception(void);
@@ -213,23 +207,27 @@
X EXPORT_SYMBOL(uaccess_user);
X #endif
X
+EXPORT_SYMBOL_NOVERS(__get_user_1);
+EXPORT_SYMBOL_NOVERS(__get_user_2);
+EXPORT_SYMBOL_NOVERS(__get_user_4);
+EXPORT_SYMBOL_NOVERS(__get_user_8);
+
+EXPORT_SYMBOL_NOVERS(__put_user_1);
+EXPORT_SYMBOL_NOVERS(__put_user_2);
+EXPORT_SYMBOL_NOVERS(__put_user_4);
+EXPORT_SYMBOL_NOVERS(__put_user_8);
+
X /* gcc lib functions */
-EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
X EXPORT_SYMBOL_NOVERS(__ashldi3);
X EXPORT_SYMBOL_NOVERS(__ashrdi3);
-EXPORT_SYMBOL_NOVERS(__cmpdi2);
-EXPORT_SYMBOL_NOVERS(__divdi3);
X EXPORT_SYMBOL_NOVERS(__divsi3);
X EXPORT_SYMBOL_NOVERS(__lshrdi3);
-EXPORT_SYMBOL_NOVERS(__moddi3);
X EXPORT_SYMBOL_NOVERS(__modsi3);
X EXPORT_SYMBOL_NOVERS(__muldi3);
-EXPORT_SYMBOL_NOVERS(__negdi2);
X EXPORT_SYMBOL_NOVERS(__ucmpdi2);
X EXPORT_SYMBOL_NOVERS(__udivdi3);
X EXPORT_SYMBOL_NOVERS(__udivmoddi4);
X EXPORT_SYMBOL_NOVERS(__udivsi3);
-EXPORT_SYMBOL_NOVERS(__umoddi3);
X EXPORT_SYMBOL_NOVERS(__umodsi3);
X
X /* bitops */
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- v2.4.12/linux/arch/arm/kernel/bios32.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/bios32.c Thu Oct 11 09:04:57 2001
@@ -288,8 +288,11 @@
X
X if (dev) {
X for (i = 0; i < 3; i++) {
- bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
- bus->resource[i]->name = bus->name;
+ if(root->resource[i]) {
+ bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+ bus->resource[i]->end = root->resource[i]->end;
+ bus->resource[i]->name = bus->name;
+ }
X }
X bus->resource[0]->flags |= pci_bridge_check_io(dev);
X bus->resource[1]->flags |= IORESOURCE_MEM;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/compat.c linux/arch/arm/kernel/compat.c
--- v2.4.12/linux/arch/arm/kernel/compat.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/compat.c Thu Oct 11 09:04:57 2001
@@ -8,7 +8,7 @@
X * published by the Free Software Foundation.
X *
X * We keep the old params compatibility cruft in one place (here)
- * so we don't end up with lots of
+ * so we don't end up with lots of mess around other places.
X */
X #include <linux/config.h>
X #include <linux/types.h>
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/dma-isa.c linux/arch/arm/kernel/dma-isa.c
--- v2.4.12/linux/arch/arm/kernel/dma-isa.c Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/dma-isa.c Thu Oct 11 09:04:57 2001
@@ -148,17 +148,22 @@
X
X void __init isa_init_dma(dma_t *dma)
X {
- int dmac_found;
-
+ /*
+ * Try to autodetect presence of an ISA DMA controller.
+ * We do some minimal initialisation, and check that
+ * channel 0's DMA address registers are writeable.
+ */
X outb(0xff, 0x0d);
X outb(0xff, 0xda);
X
+ /*
+ * Write high and low address, and then read them back
+ * in the same order.
+ */
X outb(0x55, 0x00);
X outb(0xaa, 0x00);
X
- dmac_found = inb(0x00) == 0x55 && inb(0x00) == 0xaa;
-
- if (dmac_found) {
+ if (inb(0) == 0x55 && inb(0) == 0xaa) {
X int channel, i;
X
X for (channel = 0; channel < 8; channel++) {
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
--- v2.4.12/linux/arch/arm/kernel/entry-armv.S Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-armv.S Thu Oct 11 09:04:57 2001
@@ -404,6 +404,7 @@
X .endm
X
X #elif defined(CONFIG_ARCH_L7200)
+#include <asm/hardware.h>
X
X .equ irq_base_addr, IO_BASE_2
X
@@ -625,8 +626,8 @@
X * This routine must not corrupt r9
X */
X #ifdef MULTI_CPU
- ldr r2, .LCprocfns
- mov lr, pc
+ ldr r2, .LCprocfns @ pass r0, r3 to
+ mov lr, pc @ processor code
X ldr pc, [r2] @ call processor specific code
X #else
X bl cpu_data_abort
@@ -722,16 +723,16 @@
X .align 5
X __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
X stmia sp, {r0 - r12} @ save r0 - r12
- ldr r4, .LCabt
- add r3, sp, #S_PC
- ldmia r4, {r0 - r2} @ Get USR pc, cpsr
- stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0
- stmdb r3, {sp, lr}^
- alignment_trap r4, r7, __temp_abt
+ ldr r7, .LCabt
+ add r5, sp, #S_PC
+ ldmia r7, {r0, r3, r4} @ Get USR pc, cpsr
+ stmia r5, {r0, r3, r4} @ Save USR pc, cpsr, old_r0
+ stmdb r5, {sp, lr}^
+ alignment_trap r7, r7, __temp_abt
X zero_fp
X #ifdef MULTI_CPU
- ldr r2, .LCprocfns
- mov lr, pc
+ ldr r2, .LCprocfns @ pass r0, r3 to
+ mov lr, pc @ processor code
X ldr pc, [r2] @ call processor specific code
X #else
X bl cpu_data_abort
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-common.S linux/arch/arm/kernel/entry-common.S
--- v2.4.12/linux/arch/arm/kernel/entry-common.S Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-common.S Thu Oct 11 09:04:57 2001
@@ -123,9 +123,8 @@
X .align 5
X ENTRY(vector_swi)
X save_user_regs
- mask_pc lr, lr
X zero_fp
- ldr scno, [lr, #-4] @ get SWI instruction
+ get_scno
X arm710_bug_check scno, ip
X
X #ifdef CONFIG_ALIGNMENT_TRAP
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/entry-header.S linux/arch/arm/kernel/entry-header.S
--- v2.4.12/linux/arch/arm/kernel/entry-header.S Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/entry-header.S Thu Oct 11 09:04:57 2001
@@ -75,9 +75,9 @@
X stmia sp, {r0 - r12} @ Calling r0 - r12
X add r8, sp, #S_PC
X stmdb r8, {sp, lr}^ @ Calling sp, lr
- mrs r7, spsr
+ mrs r8, spsr @ called from non-FIQ mode, so ok.
X str lr, [sp, #S_PC] @ Save calling PC
- str r7, [sp, #S_PSR] @ Save CPSR
+ str r8, [sp, #S_PSR] @ Save CPSR
X str r0, [sp, #S_OLD_R0] @ Save OLD_R0
X .endm
X
@@ -186,16 +186,34 @@
X
X #endif
X
+
X /*
X * These are the registers used in the syscall handler, and allow us to
- * have in theory up to 7 arguments to a function. Note that tbl == why
- * is intentional.
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * r7 is reserved for the system call number for thumb mode.
+ *
+ * Note that tbl == why is intentional.
X *
X * We must set at least "tsk" and "why" when calling ret_with_reschedule.
X */
-scno .req r9 @ syscall number
+scno .req r7 @ syscall number
X tbl .req r8 @ syscall table pointer
X why .req r8 @ Linux syscall (!= 0)
-tsk .req r7 @ current task
+tsk .req r9 @ current task
+
+/*
+ * Get the system call number.
+ */
+ .macro get_scno
+#ifdef CONFIG_ARM_THUMB
+ tst r8, #T_BIT @ this is SPSR from save_user_regs
+ addne scno, r7, #OS_NUMBER << 20 @ put OS number in
+ ldreq scno, [lr, #-4]
X
+#else
+ mask_pc lr, lr
+ ldr scno, [lr, #-4] @ get SWI instruction
+#endif
+ .endm
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/head-armv.S linux/arch/arm/kernel/head-armv.S
--- v2.4.12/linux/arch/arm/kernel/head-armv.S Mon Aug 27 12:41:38 2001


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 03'
echo 'File patch-2.4.13 is continued in part 04'
echo "04" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:34 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part04

#!/bin/sh -x
# this is part 04 of a 53 - part archive


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

if test "$Scheck" != 04; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+++ linux/arch/arm/kernel/head-armv.S Thu Oct 11 09:04:57 2001
@@ -418,5 +418,4 @@
X mov r7, #0 @ unknown architecture
X mov pc, lr
X 2: ldmib r4, {r5, r6, r7} @ found, get results
- mov r7, r7, lsr #18 @ pagetable byte offset
X mov pc, lr
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/init_task.c linux/arch/arm/kernel/init_task.c
--- v2.4.12/linux/arch/arm/kernel/init_task.c Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/kernel/init_task.c Thu Oct 11 09:04:57 2001
@@ -9,6 +9,7 @@
X #include <asm/uaccess.h>
X #include <asm/pgtable.h>
X
+static struct vm_area_struct init_mmap = INIT_MMAP;
X static struct fs_struct init_fs = INIT_FS;
X static struct files_struct init_files = INIT_FILES;
X static struct signal_struct init_signals = INIT_SIGNALS;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
--- v2.4.12/linux/arch/arm/kernel/setup.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/setup.c Thu Oct 11 09:04:57 2001
@@ -260,10 +260,10 @@
X struct resource *res;
X int i;
X
- kernel_code.start = __virt_to_bus(init_mm.start_code);
- kernel_code.end = __virt_to_bus(init_mm.end_code - 1);
- kernel_data.start = __virt_to_bus(init_mm.end_code);
- kernel_data.end = __virt_to_bus(init_mm.brk - 1);
+ kernel_code.start = __virt_to_phys(init_mm.start_code);
+ kernel_code.end = __virt_to_phys(init_mm.end_code - 1);
+ kernel_data.start = __virt_to_phys(init_mm.end_code);
+ kernel_data.end = __virt_to_phys(init_mm.brk - 1);
X
X for (i = 0; i < mi->nr_banks; i++) {
X unsigned long virt_start, virt_end;
@@ -520,9 +520,44 @@
X #endif
X }
X
-int get_cpuinfo(char * buffer)
+static const char *hwcap_str[] = {
+ "swp",
+ "half",
+ "thumb",
+ "26bit",
+ "fastmult",
+ "fpa",
+ "vfp",
+ "edsp",
+ NULL
+};
+
+/*
+ * get_cpuinfo - Get information on one CPU for use by the procfs.
+ *
+ * Prints info on the next CPU into buffer. Beware, doesn't check for
+ * buffer overflow. Current implementation of procfs assumes that the
+ * resulting data is <= 1K.
+ *
+ * Args:
+ * buffer -- you guessed it, the data buffer
+ * cpu_np -- Input: next cpu to get (start at 0). Output: Updated.
+ *
+ * Returns number of bytes written to buffer.
+ */
+
+int get_cpuinfo(char *buffer, unsigned *cpu_np)
X {
X char *p = buffer;
+ unsigned n;
+ int i;
+
+ /* No SMP at the moment, so just toggle 0/1 */
+ n = *cpu_np;
+ *cpu_np = 1;
+ if (n != 0) {
+ return (0);
+ }
X
X p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
X proc_info.manufacturer, proc_info.cpu_name,
@@ -531,6 +566,15 @@
X p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
X loops_per_jiffy / (500000/HZ),
X (loops_per_jiffy / (5000/HZ)) % 100);
+
+ /* dump out the processor features */
+ p += sprintf(p, "Features\t: ");
+
+ for (i = 0; hwcap_str[i]; i++)
+ if (elf_hwcap & (1 << i))
+ p += sprintf(p, "%s ", hwcap_str[i]);
+
+ p += sprintf(p, "\n\n");
X
X p += sprintf(p, "Hardware\t: %s\n", machine_name);
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/signal.c linux/arch/arm/kernel/signal.c
--- v2.4.12/linux/arch/arm/kernel/signal.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/kernel/signal.c Thu Oct 11 09:04:57 2001
@@ -1,7 +1,7 @@
X /*
X * linux/arch/arm/kernel/signal.c
X *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995-2001 Russell King
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License version 2 as
@@ -19,7 +19,9 @@
X #include <linux/ptrace.h>
X #include <linux/stddef.h>
X #include <linux/unistd.h>
+#include <linux/personality.h>
X #include <linux/tty.h>
+#include <linux/elf.h>
X
X #include <asm/pgalloc.h>
X #include <asm/ucontext.h>
@@ -29,8 +31,23 @@
X
X #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
X
-#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn))
-#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
+/*
+ * For ARM syscalls, we encode the syscall number into the instruction.
+ */
+#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn))
+#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
+
+/*
+ * For Thumb syscalls, we pass the syscall number via r7. We therefore
+ * need two 16-bit instructions.
+ */
+#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+static const unsigned long retcodes[4] = {
+ SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
+ SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
+};
X
X asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
X
@@ -208,11 +225,11 @@
X sigset_t set;
X
X /*
- * Since we stacked the signal on a word boundary,
+ * Since we stacked the signal on a 64-bit boundary,
X * then 'sp' should be word aligned here. If it's
X * not, then the user is trying to mess with us.
X */
- if (regs->ARM_sp & 3)
+ if (regs->ARM_sp & 7)
X goto badframe;
X
X frame = (struct sigframe *)regs->ARM_sp;
@@ -251,11 +268,11 @@
X sigset_t set;
X
X /*
- * Since we stacked the signal on a word boundary,
+ * Since we stacked the signal on a 64-bit boundary,
X * then 'sp' should be word aligned here. If it's
X * not, then the user is trying to mess with us.
X */
- if (regs->ARM_sp & 3)
+ if (regs->ARM_sp & 7)
X goto badframe;
X
X frame = (struct rt_sigframe *)regs->ARM_sp;
@@ -319,8 +336,8 @@
X return err;
X }
X
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
- unsigned long framesize)
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
X {
X unsigned long sp = regs->ARM_sp;
X
@@ -331,77 +348,103 @@
X sp = current->sas_ss_sp + current->sas_ss_size;
X
X /*
- * No matter what happens, 'sp' must be word
- * aligned otherwise nasty things could happen
+ * ATPCS B01 mandates 8-byte alignment
X */
- /* ATPCS B01 mandates 8-byte alignment */
X return (void *)((sp - framesize) & ~7);
X }
X
-static void setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int
+setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+ unsigned long *rc, void *frame, int usig)
X {
- struct sigframe *frame;
+ unsigned long handler = (unsigned long)ka->sa.sa_handler;
X unsigned long retcode;
- int err = 0;
-
- frame = get_sigframe(ka, regs, sizeof(*frame));
-
- if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto segv_and_exit;
+ int thumb = 0;
+#ifdef CONFIG_CPU_32
+ unsigned long cpsr = regs->ARM_cpsr;
X
- err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+ /*
+ * Maybe we need to deliver a 32-bit signal to a 26-bit task.
+ */
+ if (ka->sa.sa_flags & SA_THIRTYTWO)
+ cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
X
- if (_NSIG_WORDS > 1) {
- err |= __copy_to_user(frame->extramask, &set->sig[1],
- sizeof(frame->extramask));
+#ifdef CONFIG_ARM_THUMB
+ if (elf_hwcap & HWCAP_THUMB) {
+ /*
+ * The LSB of the handler determines if we're going to
+ * be using THUMB or ARM mode for this signal handler.
+ */
+ thumb = handler & 1;
+
+ if (thumb)
+ cpsr |= T_BIT;
+ else
+ cpsr &= ~T_BIT;
X }
+#endif
+#endif
X
- /* Set up to return from userspace. If provided, use a stub
- already in userspace. */
X if (ka->sa.sa_flags & SA_RESTORER) {
X retcode = (unsigned long)ka->sa.sa_restorer;
X } else {
- retcode = (unsigned long)&frame->retcode;
- __put_user_error(SWI_SYS_SIGRETURN, &frame->retcode, err);
- flush_icache_range(retcode, retcode + 4);
- }
+ unsigned int idx = thumb;
X
- if (err)
- goto segv_and_exit;
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ idx += 2;
X
- if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
- regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
- else
- regs->ARM_r0 = sig;
+ if (__put_user(retcodes[idx], rc))
+ return 1;
+
+ flush_icache_range((unsigned long)rc,
+ (unsigned long)(rc + 1));
+
+ retcode = ((unsigned long)rc) + thumb;
+ }
+
+ regs->ARM_r0 = usig;
X regs->ARM_sp = (unsigned long)frame;
X regs->ARM_lr = retcode;
- regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
- /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
- if (ka->sa.sa_flags & SA_THIRTYTWO)
- regs->ARM_cpsr = USR_MODE;
+ regs->ARM_pc = handler & (thumb ? ~1 : ~3);
+
+#ifdef CONFIG_CPU_32
+ regs->ARM_cpsr = cpsr;
X #endif
- if (valid_user_regs(regs))
- return;
X
-segv_and_exit:
- if (sig == SIGSEGV)
- ka->sa.sa_handler = SIG_DFL;
- force_sig(SIGSEGV, current);
+ return 0;
X }
X
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int
+setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs)
X {
- struct rt_sigframe *frame;
- unsigned long retcode;
+ struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
X int err = 0;
X
- frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ return 1;
+
+ err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+
+ if (_NSIG_WORDS > 1) {
+ err |= __copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+ }
+
+ if (err == 0)
+ err = setup_return(regs, ka, &frame->retcode, frame, usig);
+
+ return err;
+}
+
+static int
+setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
+ int err = 0;
X
X if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto segv_and_exit;
+ return 1;
X
X __put_user_error(&frame->info, &frame->pinfo, err);
X __put_user_error(&frame->uc, &frame->puc, err);
@@ -414,47 +457,20 @@
X regs, set->sig[0]);
X err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
X
- /* Set up to return from userspace. If provided, use a stub
- already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- retcode = (unsigned long)ka->sa.sa_restorer;
- } else {
- retcode = (unsigned long)&frame->retcode;
- __put_user_error(SWI_SYS_RT_SIGRETURN, &frame->retcode, err);
- flush_icache_range(retcode, retcode + 4);
- }
-
- if (err)
- goto segv_and_exit;
-
- if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
- regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
- else
- regs->ARM_r0 = sig;
+ if (err == 0)
+ err = setup_return(regs, ka, &frame->retcode, frame, usig);
X
- /*
- * For realtime signals we must also set the second and third
- * arguments for the signal handler.
- * -- Peter Maydell <pmay...@chiark.greenend.org.uk> 2000-12-06
- */
- regs->ARM_r1 = (unsigned long)frame->pinfo;
- regs->ARM_r2 = (unsigned long)frame->puc;
-
- regs->ARM_sp = (unsigned long)frame;
- regs->ARM_lr = retcode;
- regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
-#if defined(CONFIG_CPU_32)
- /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
- if (ka->sa.sa_flags & SA_THIRTYTWO)
- regs->ARM_cpsr = USR_MODE;
-#endif
- if (valid_user_regs(regs))
- return;
+ if (err == 0) {
+ /*
+ * For realtime signals we must also set the second and third
+ * arguments for the signal handler.
+ * -- Peter Maydell <pmay...@chiark.greenend.org.uk> 2000-12-06
+ */
+ regs->ARM_r1 = (unsigned long)frame->pinfo;
+ regs->ARM_r2 = (unsigned long)frame->puc;
+ }
X
-segv_and_exit:
- if (sig == SIGSEGV)
- ka->sa.sa_handler = SIG_DFL;
- force_sig(SIGSEGV, current);
+ return err;
X }
X
X /*
@@ -464,22 +480,47 @@
X handle_signal(unsigned long sig, struct k_sigaction *ka,
X siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
X {
- /* Set up the stack frame */
+ struct task_struct *tsk = current;
+ int usig = sig;
+ int ret;
+
+ /*
+ * translate the signal
+ */
+ if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap)
+ usig = tsk->exec_domain->signal_invmap[usig];
+
+ /*
+ * Set up the stack frame
+ */
X if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = setup_rt_frame(usig, ka, info, oldset, regs);
X else
- setup_frame(sig, ka, oldset, regs);
+ ret = setup_frame(usig, ka, oldset, regs);
X
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
+ /*
+ * Check that the resulting registers are actually sane.
+ */
+ ret |= !valid_user_regs(regs);
X
- if (!(ka->sa.sa_flags & SA_NODEFER)) {
- spin_lock_irq(&current->sigmask_lock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
- sigaddset(&current->blocked,sig);
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
+ if (ret == 0) {
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
+
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
+ spin_lock_irq(&tsk->sigmask_lock);
+ sigorsets(&tsk->blocked, &tsk->blocked,
+ &ka->sa.sa_mask);
+ sigaddset(&tsk->blocked, sig);
+ recalc_sigpending(tsk);
+ spin_unlock_irq(&tsk->sigmask_lock);
+ }
+ return;
X }
+
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, tsk);
X }
X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
--- v2.4.12/linux/arch/arm/kernel/time.c Thu Feb 8 16:32:44 2001
+++ linux/arch/arm/kernel/time.c Thu Oct 11 09:04:57 2001
@@ -33,7 +33,6 @@
X #include <asm/hardware.h>
X
X extern int setup_arm_irq(int, struct irqaction *);
-extern void setup_timer(void);
X extern rwlock_t xtime_lock;
X extern unsigned long wall_jiffies;
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- v2.4.12/linux/arch/arm/kernel/traps.c Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/kernel/traps.c Thu Oct 11 09:04:57 2001
@@ -22,6 +22,7 @@
X #include <linux/personality.h>
X #include <linux/ptrace.h>
X #include <linux/elf.h>
+#include <linux/interrupt.h>
X #include <linux/init.h>
X
X #include <asm/atomic.h>
@@ -176,7 +177,7 @@
X printk("Process %s (pid: %d, stackpage=%08lx)\n",
X current->comm, current->pid, 4096+(unsigned long)tsk);
X
- if (!user_mode(regs)) {
+ if (!user_mode(regs) || in_interrupt()) {
X mm_segment_t fs;
X
X /*
@@ -209,7 +210,7 @@
X
X asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
X {
- unsigned long addr;
+ unsigned long *pc;
X siginfo_t info;
X
X /*
@@ -217,11 +218,11 @@
X * whether we're in Thumb mode or not.
X */
X regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
- addr = instruction_pointer(regs);
+ pc = (unsigned long *)instruction_pointer(regs);
X
X #ifdef CONFIG_DEBUG_USER
- printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
- current->comm, current->pid, addr);
+ printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+ current->comm, current->pid, pc);
X dump_instr(regs);
X #endif
X
@@ -231,7 +232,7 @@
X info.si_signo = SIGILL;
X info.si_errno = 0;
X info.si_code = ILL_ILLOPC;
- info.si_addr = (void *)addr;
+ info.si_addr = pc;
X
X force_sig_info(SIGILL, &info, current);
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile
--- v2.4.12/linux/arch/arm/lib/Makefile Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/lib/Makefile Thu Oct 11 09:04:57 2001
@@ -13,15 +13,20 @@
X copy_page.o delay.o findbit.o memchr.o memcpy.o \
X memset.o memzero.o setbit.o strncpy_from_user.o \
X strnlen_user.o strchr.o strrchr.o testchangebit.o \
- testclearbit.o testsetbit.o uaccess.o
+ testclearbit.o testsetbit.o uaccess.o getuser.o \
+ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+ ucmpdi2.o udivdi3.o lib1funcs.o
X obj-m :=
X obj-n :=
X
+obj-$(CONFIG_VT)+= kbd.o
+
X obj-arc := ecard.o io-acorn.o floppydma.o
X obj-rpc := ecard.o io-acorn.o floppydma.o
X obj-clps7500 := io-acorn.o
X obj-l7200 := io-acorn.o
X obj-shark := io-shark.o
+obj-edb7211 := io-acorn.o
X
X obj-y += $(obj-$(MACHINE))
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ashldi3.c linux/arch/arm/lib/ashldi3.c
--- v2.4.12/linux/arch/arm/lib/ashldi3.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ashldi3.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (USItype)uu.s.low << -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.low >> bm;
+ w.s.low = (USItype)uu.s.low << b;
+ w.s.high = ((USItype)uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ashrdi3.c linux/arch/arm/lib/ashrdi3.c
--- v2.4.12/linux/arch/arm/lib/ashrdi3.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ashrdi3.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/gcclib.h linux/arch/arm/lib/gcclib.h
--- v2.4.12/linux/arch/arm/lib/gcclib.h Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/gcclib.h Thu Oct 11 09:04:57 2001
@@ -0,0 +1,25 @@
+/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#define BITS_PER_UNIT 8
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+
+#if 0 /* FIXME: endian test here!!! */
+ struct DIstruct {SItype high, low;};
+#else
+ struct DIstruct {SItype low, high;};
+#endif
+
+typedef union
+{
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/getuser.S linux/arch/arm/lib/getuser.S
--- v2.4.12/linux/arch/arm/lib/getuser.S Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/getuser.S Thu Oct 11 09:04:57 2001
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/lib/getuser.S
+ *
+ * Copyright (C) 2001 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.
+ *
+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make them more
+ * efficient, especially as they return an error value in addition to
+ * the "real" return value.
+ *
+ * __get_user_X
+ *
+ * Inputs: r0 contains the address
+ * Outputs: r0 is the error code
+ * r1, r2 contains the zero-extended value
+ * lr corrupted
+ *
+ * No other registers must be altered. (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000.
+ * Note also that it is intended that __get_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+ .global __get_user_1
+__get_user_1:
+ bic r1, sp, #0x1f00
+ bic r1, r1, #0x00ff
+ ldr r1, [r1, #TSK_ADDR_LIMIT]
+ sub r1, r1, #1
+ cmp r0, r1
+1: ldrlsbt r1, [r0]
+ movls r0, #0
+ movls pc, lr
+ b __get_user_bad
+
+ .global __get_user_2
+__get_user_2:
+ bic r2, sp, #0x1f00
+ bic r2, r2, #0x00ff
+ ldr r2, [r2, #TSK_ADDR_LIMIT]
+ sub r2, r2, #2
+ cmp r0, r2
+2: ldrlsbt r1, [r0], #1
+3: ldrlsbt r2, [r0]
+ orrls r1, r1, r2, lsl #8
+ movls r0, #0
+ movls pc, lr
+ b __get_user_bad
+
+ .global __get_user_4
+__get_user_4:
+ bic r1, sp, #0x1f00
+ bic r1, r1, #0x00ff
+ ldr r1, [r1, #TSK_ADDR_LIMIT]
+ sub r1, r1, #4
+ cmp r0, r1
+4: ldrlst r1, [r0]
+ movls r0, #0
+ movls pc, lr
+ b __get_user_bad
+
+ .global __get_user_8
+__get_user_8:
+ bic r2, sp, #0x1f00
+ bic r2, r2, #0x00ff
+ ldr r2, [r2, #TSK_ADDR_LIMIT]
+ sub r2, r2, #8
+ cmp r0, r2
+5: ldrlst r1, [r0], #4
+6: ldrlst r2, [r0]
+ movls r0, #0
+ movls pc, lr
+
+ /* fall through */
+
+__get_user_bad:
+ mov r2, #0
+ mov r1, #0
+ mov r0, #-14
+ mov pc, lr
+
+.section __ex_table, "a"
+ .long 1b, __get_user_bad
+ .long 2b, __get_user_bad
+ .long 3b, __get_user_bad
+ .long 4b, __get_user_bad
+ .long 5b, __get_user_bad
+ .long 6b, __get_user_bad
+.previous
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/kbd.c linux/arch/arm/lib/kbd.c
--- v2.4.12/linux/arch/arm/lib/kbd.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/kbd.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,13 @@
+#include <linux/config.h>
+#include <linux/kd.h>
+
+int (*k_setkeycode)(unsigned int, unsigned int);
+int (*k_getkeycode)(unsigned int);
+int (*k_translate)(unsigned char, unsigned char *, char);
+char (*k_unexpected_up)(unsigned char);
+void (*k_leds)(unsigned char);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+int k_sysrq_key;
+unsigned char *k_sysrq_xlate;
+#endif
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/lib1funcs.S linux/arch/arm/lib/lib1funcs.S
--- v2.4.12/linux/arch/arm/lib/lib1funcs.S Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/lib1funcs.S Thu Oct 11 09:04:57 2001
@@ -0,0 +1,320 @@
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rear...@armltd.co.uk)
+
+/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+
+This file 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file. (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file 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; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* This code is derived from gcc 2.95.3 */
+/* I Molton 29/07/01 */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_CPU_26
+#define RET movs
+#define RETc(x) mov##x##s
+#define RETCOND ^
+#else
+#define RET mov
+#define RETc(x) mov##x
+#define RETCOND
+#endif
+
+dividend .req r0
+divisor .req r1
+result .req r2
+overdone .req r2
+curbit .req r3
+ip .req r12
+sp .req r13
+lr .req r14
+pc .req r15
+
+ENTRY(__udivsi3)
+ cmp divisor, #0
+ beq Ldiv0
+ mov curbit, #1
+ mov result, #0
+ cmp dividend, divisor
+ bcc Lgot_result_udivsi3
+1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc 1b
+
+2:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc 2b
+
+3:
+ @ Test for possible subtractions, and note which bits
+ @ are done in the result. On the final pass, this may subtract
+ @ too much from the dividend, but the result will be ok, since the
+ @ "bit" will have been shifted out at the bottom.
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ orrcs result, result, curbit
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs result, result, curbit, lsr #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs result, result, curbit, lsr #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs result, result, curbit, lsr #3
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne 3b
+Lgot_result_udivsi3:
+ mov r0, result
+ RET pc, lr
+
+Ldiv0:
+ str lr, [sp, #-4]!
+ bl __div0
+ mov r0, #0 @ about as wrong as it could be
+ ldmia sp!, {pc}RETCOND
+
+/* __umodsi3 ----------------------- */
+
+ENTRY(__umodsi3)
+ cmp divisor, #0
+ beq Ldiv0
+ mov curbit, #1
+ cmp dividend, divisor
+ RETc(cc) pc, lr
+1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc 1b
+
+2:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc 2b
+
+3:
+ @ Test for possible subtractions. On the final pass, this may
+ @ subtract too much from the dividend, so keep track of which
+ @ subtractions are done, we can fix them up afterwards...
+ mov overdone, #0
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs overdone, overdone, curbit, ror #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs overdone, overdone, curbit, ror #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs overdone, overdone, curbit, ror #3
+ mov ip, curbit
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne 3b
+
+ @ Any subtractions that we should not have done will be recorded in
+ @ the top three bits of "overdone". Exactly which were not needed
+ @ are governed by the position of the bit, stored in ip.
+ @ If we terminated early, because dividend became zero,
+ @ then none of the below will match, since the bit in ip will not be
+ @ in the bottom nibble.
+ ands overdone, overdone, #0xe0000000
+ RETc(eq) pc, lr @ No fixups needed
+ tst overdone, ip, ror #3
+ addne dividend, dividend, divisor, lsr #3
+ tst overdone, ip, ror #2
+ addne dividend, dividend, divisor, lsr #2
+ tst overdone, ip, ror #1
+ addne dividend, dividend, divisor, lsr #1
+ RET pc, lr
+
+ENTRY(__divsi3)
+ eor ip, dividend, divisor @ Save the sign of the result.
+ mov curbit, #1
+ mov result, #0
+ cmp divisor, #0
+ rsbmi divisor, divisor, #0 @ Loops below use unsigned.
+ beq Ldiv0
+ cmp dividend, #0
+ rsbmi dividend, dividend, #0
+ cmp dividend, divisor
+ bcc Lgot_result_divsi3
+
+1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc 1b
+
+2:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc 2b
+
+3:
+ @ Test for possible subtractions, and note which bits
+ @ are done in the result. On the final pass, this may subtract
+ @ too much from the dividend, but the result will be ok, since the
+ @ "bit" will have been shifted out at the bottom.
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ orrcs result, result, curbit
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs result, result, curbit, lsr #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs result, result, curbit, lsr #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs result, result, curbit, lsr #3
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne 3b
+Lgot_result_divsi3:
+ mov r0, result
+ cmp ip, #0
+ rsbmi r0, r0, #0
+ RET pc, lr
+
+ENTRY(__modsi3)
+ mov curbit, #1
+ cmp divisor, #0
+ rsbmi divisor, divisor, #0 @ Loops below use unsigned.
+ beq Ldiv0
+ @ Need to save the sign of the dividend, unfortunately, we need
+ @ ip later on; this is faster than pushing lr and using that.
+ str dividend, [sp, #-4]!
+ cmp dividend, #0
+ rsbmi dividend, dividend, #0
+ cmp dividend, divisor
+ bcc Lgot_result_modsi3
+
+1:
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+ cmp divisor, #0x10000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #4
+ movcc curbit, curbit, lsl #4
+ bcc 1b
+
+2:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+ cmp divisor, #0x80000000
+ cmpcc divisor, dividend
+ movcc divisor, divisor, lsl #1
+ movcc curbit, curbit, lsl #1
+ bcc 2b
+
+3:
+ @ Test for possible subtractions. On the final pass, this may
+ @ subtract too much from the dividend, so keep track of which
+ @ subtractions are done, we can fix them up afterwards...
+ mov overdone, #0
+ cmp dividend, divisor
+ subcs dividend, dividend, divisor
+ cmp dividend, divisor, lsr #1
+ subcs dividend, dividend, divisor, lsr #1
+ orrcs overdone, overdone, curbit, ror #1
+ cmp dividend, divisor, lsr #2
+ subcs dividend, dividend, divisor, lsr #2
+ orrcs overdone, overdone, curbit, ror #2
+ cmp dividend, divisor, lsr #3
+ subcs dividend, dividend, divisor, lsr #3
+ orrcs overdone, overdone, curbit, ror #3
+ mov ip, curbit
+ cmp dividend, #0 @ Early termination?
+ movnes curbit, curbit, lsr #4 @ No, any more bits to do?
+ movne divisor, divisor, lsr #4
+ bne 3b
+
+ @ Any subtractions that we should not have done will be recorded in
+ @ the top three bits of "overdone". Exactly which were not needed
+ @ are governed by the position of the bit, stored in ip.
+ @ If we terminated early, because dividend became zero,
+ @ then none of the below will match, since the bit in ip will not be
+ @ in the bottom nibble.
+ ands overdone, overdone, #0xe0000000
+ beq Lgot_result_modsi3
+ tst overdone, ip, ror #3
+ addne dividend, dividend, divisor, lsr #3
+ tst overdone, ip, ror #2
+ addne dividend, dividend, divisor, lsr #2
+ tst overdone, ip, ror #1
+ addne dividend, dividend, divisor, lsr #1
+Lgot_result_modsi3:
+ ldr ip, [sp], #4
+ cmp ip, #0
+ rsbmi dividend, dividend, #0
+ RET pc, lr
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/longlong.h linux/arch/arm/lib/longlong.h
--- v2.4.12/linux/arch/arm/lib/longlong.h Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/longlong.h Thu Oct 11 09:04:57 2001
@@ -0,0 +1,184 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+ definitions for mixed size 32/64 bit arithmetic.
+ Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+ This definition file 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 definition file 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. */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+ multiplies two USItype integers MULTIPLER and MULTIPLICAND,
+ and generates a two-part USItype product in HIGH_PROD and
+ LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
+ and returns a UDItype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a two-word unsigned integer, composed by the
+ integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+ places the quotient in QUOTIENT and the remainder in REMAINDER.
+ HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+ If, in addition, the most significant bit of DENOMINATOR must be 1,
+ then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The
+ quotient is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from
+ the msb to the first non-zero bit. This is the number of steps X
+ needs to be shifted left to set the msb. Undefined for X == 0.
+
+ 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two two-word unsigned integers,
+ composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+ LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
+ LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
+ lost.
+
+ 7) sub_ddmmss(high_difference, low_difference, high_minuend,
+ low_minuend, high_subtrahend, low_subtrahend) subtracts two
+ two-word unsigned integers, composed by HIGH_MINUEND_1 and
+ LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+ respectively. The result is placed in HIGH_DIFFERENCE and
+ LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5
+ adc %0, %2, %3" \
+ : "=r" ((USItype) (sh)), \
+ "=&r" ((USItype) (sl)) \
+ : "%r" ((USItype) (ah)), \
+ "rI" ((USItype) (bh)), \
+ "%r" ((USItype) (al)), \
+ "rI" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5
+ sbc %0, %2, %3" \
+ : "=r" ((USItype) (sh)), \
+ "=&r" ((USItype) (sl)) \
+ : "r" ((USItype) (ah)), \
+ "rI" ((USItype) (bh)), \
+ "r" ((USItype) (al)), \
+ "rI" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2; \
+ __asm__ ("%@ Inlined umul_ppmm
+ mov %2, %5, lsr #16
+ mov %0, %6, lsr #16
+ bic %3, %5, %2, lsl #16
+ bic %4, %6, %0, lsl #16
+ mul %1, %3, %4
+ mul %4, %2, %4
+ mul %3, %0, %3
+ mul %0, %2, %0
+ adds %3, %4, %3
+ addcs %0, %0, #65536
+ adds %1, %1, %3, lsl #16
+ adc %0, %0, %3, lsr #16" \
+ : "=&r" ((USItype) (xh)), \
+ "=r" ((USItype) (xl)), \
+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
+ : "r" ((USItype) (a)), \
+ "r" ((USItype) (b)));}
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+ ({DIunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ USItype __d1, __d0, __q1, __q0; \
+ USItype __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (USItype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (USItype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (USItype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+extern const UQItype __clz_tab[];
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __xr = (x); \
+ USItype __a; \
+ \
+ if (SI_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((USItype)1<<2*__BITS4) \
+ ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
+ : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
+ } \
+ else \
+ { \
+ for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
+ } while (0)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/lshrdi3.c linux/arch/arm/lib/lshrdi3.c
--- v2.4.12/linux/arch/arm/lib/lshrdi3.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/lshrdi3.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.high = 0;
+ w.s.low = (USItype)uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = (USItype)uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/muldi3.c linux/arch/arm/lib/muldi3.c
--- v2.4.12/linux/arch/arm/lib/muldi3.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/muldi3.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,77 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+#define umul_ppmm(xh, xl, a, b) \
+{register USItype __t0, __t1, __t2; \
+ __asm__ ("%@ Inlined umul_ppmm
+ mov %2, %5, lsr #16
+ mov %0, %6, lsr #16
+ bic %3, %5, %2, lsl #16
+ bic %4, %6, %0, lsl #16
+ mul %1, %3, %4
+ mul %4, %2, %4
+ mul %3, %0, %3
+ mul %0, %2, %0
+ adds %3, %4, %3
+ addcs %0, %0, #65536
+ adds %1, %1, %3, lsl #16
+ adc %0, %0, %3, lsr #16" \
+ : "=&r" ((USItype) (xh)), \
+ "=r" ((USItype) (xl)), \
+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
+ : "r" ((USItype) (a)), \
+ "r" ((USItype) (b)));}
+
+
+#define __umulsidi3(u, v) \
+ ({DIunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; })
+
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+ DIunion w;
+ DIunion uu, vv;
+
+ uu.ll = u,
+ vv.ll = v;
+
+ w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+ w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+ + (USItype) uu.s.high * (USItype) vv.s.low);
+
+ return w.ll;
+}
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/putuser.S linux/arch/arm/lib/putuser.S
--- v2.4.12/linux/arch/arm/lib/putuser.S Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/putuser.S Thu Oct 11 09:04:57 2001
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/lib/putuser.S
+ *
+ * Copyright (C) 2001 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.
+ *
+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make
+ * them more efficient, especially as they return an error
+ * value in addition to the "real" return value.
+ *
+ * __put_user_X
+ *
+ * Inputs: r0 contains the address
+ * r1, r2 contains the value
+ * Outputs: r0 is the error code
+ * lr corrupted
+ *
+ * No other registers must be altered. (see include/asm-arm/uaccess.h
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000
+ * Note also that it is intended that __put_user_bad is not global.
+ */
+#include <asm/constants.h>
+
+ .global __put_user_1
+__put_user_1:
+ bic r2, sp, #0x1f00
+ bic r2, r2, #0x00ff
+ ldr r2, [r2, #TSK_ADDR_LIMIT]
+ sub r2, r2, #1
+ cmp r0, r2
+1: strlsbt r1, [r0]
+ movls r0, #0
+ movls pc, lr
+ b __put_user_bad
+
+ .global __put_user_2
+__put_user_2:
+ bic r2, sp, #0x1f00
+ bic r2, r2, #0x00ff
+ ldr r2, [r2, #TSK_ADDR_LIMIT]
+ sub r2, r2, #2
+ cmp r0, r2
+2: strlsbt r1, [r0], #1
+ movls r1, r1, lsr #8
+3: strlsbt r1, [r0]
+ movls r0, #0
+ movls pc, lr
+ b __put_user_bad
+
+ .global __put_user_4
+__put_user_4:
+ bic r2, sp, #0x1f00
+ bic r2, r2, #0x00ff
+ ldr r2, [r2, #TSK_ADDR_LIMIT]
+ sub r2, r2, #4
+ cmp r0, r2
+4: strlst r1, [r0]
+ movls r0, #0
+ movls pc, lr
+ b __put_user_bad
+
+ .global __put_user_8
+__put_user_8:
+ bic ip, sp, #0x1f00
+ bic ip, ip, #0x00ff
+ ldr ip, [ip, #TSK_ADDR_LIMIT]
+ sub ip, ip, #8
+ cmp r0, ip
+5: strlst r1, [r0], #4
+6: strlst r2, [r0]
+ movls r0, #0
+ movls pc, lr
+
+ /* fall through */
+
+__put_user_bad:
+ mov r0, #-14
+ mov pc, lr
+
+.section __ex_table, "a"
+ .long 1b, __put_user_bad
+ .long 2b, __put_user_bad
+ .long 3b, __put_user_bad
+ .long 4b, __put_user_bad
+ .long 5b, __put_user_bad
+ .long 6b, __put_user_bad
+.previous
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/ucmpdi2.c linux/arch/arm/lib/ucmpdi2.c
--- v2.4.12/linux/arch/arm/lib/ucmpdi2.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/ucmpdi2.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,51 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+word_type
+__ucmpdi2 (DItype a, DItype b)
+{
+ DIunion au, bu;
+
+ au.ll = a, bu.ll = b;
+
+ if ((USItype) au.s.high < (USItype) bu.s.high)
+ return 0;
+ else if ((USItype) au.s.high > (USItype) bu.s.high)
+ return 2;
+ if ((USItype) au.s.low < (USItype) bu.s.low)
+ return 0;
+ else if ((USItype) au.s.low > (USItype) bu.s.low)
+ return 2;
+ return 1;
+}
+
diff -u --recursive --new-file v2.4.12/linux/arch/arm/lib/udivdi3.c linux/arch/arm/lib/udivdi3.c
--- v2.4.12/linux/arch/arm/lib/udivdi3.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/udivdi3.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,231 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+#include "longlong.h"
+
+static const UQItype __clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+
+UDItype
+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
+{
+ DIunion ww;
+ DIunion nn, dd;
+ DIunion rr;
+ USItype d0, d1, n0, n1, n2;
+ USItype q0, q1;
+ USItype b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm != 0)
+ {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm == 0)
+ {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of SI_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ }
+ else
+ {
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ if (d1 > n1)
+ {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ /* 0q = NN / dd */
+
+ count_leading_zeros (bm, d1);
+ if (bm == 0)
+ {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0)
+ {
+ q0 = 1;
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ }
+ else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ USItype m1, m0;
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q0, n1, n2, n1, d1);
+ umul_ppmm (m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0))
+ {
+ q0--;
+ sub_ddmmss (m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0)
+ {
+ sub_ddmmss (n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 04'
echo 'File patch-2.4.13 is continued in part 05'
echo "05" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:35 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part05

#!/bin/sh -x
# this is part 05 of a 53 - part archive


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

if test "$Scheck" != 05; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ rr.s.high = n1 >> bm;


+ *rp = rr.ll;
+ }
+ }
+ }

+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+
+UDItype
+__udivdi3 (UDItype n, UDItype d)
+{
+ return __udivmoddi4 (n, d, (UDItype *) 0);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-ebsa110/io.c linux/arch/arm/mach-ebsa110/io.c
--- v2.4.12/linux/arch/arm/mach-ebsa110/io.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-ebsa110/io.c Thu Oct 11 09:04:57 2001
@@ -279,6 +279,9 @@
X __raw_readsb(ISAIO_BASE + off, from, len);
X }
X
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+
X void outsw(unsigned int port, const void *from, int len)
X {
X u32 off;
@@ -308,6 +311,9 @@
X
X __raw_readsw(ISAIO_BASE + off, from, len);
X }
+
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
X
X void outsl(unsigned int port, const void *from, int len)
X {
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/cpu.c linux/arch/arm/mach-integrator/cpu.c
--- v2.4.12/linux/arch/arm/mach-integrator/cpu.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-integrator/cpu.c Thu Oct 11 09:04:57 2001
@@ -3,7 +3,7 @@
X *
X * Copyright (C) 2001 Deep Blue Solutions Ltd.
X *
- * $Id: cpu.c,v 1.1 2001/06/17 10:12:37 rmk Exp $
+ * $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $


X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License version 2 as

@@ -70,7 +70,7 @@
X * Validate the speed in khz. If it is outside our
X * range, then return the lowest.
X */
-unsigned int cpufreq_validatespeed(unsigned int freq_khz)
+unsigned int integrator_validatespeed(unsigned int freq_khz)
X {
X struct vco vco;
X
@@ -87,7 +87,7 @@
X return vco_to_freq(vco, 1);
X }
X
-void cpufreq_setspeed(unsigned int freq_khz)
+void integrator_setspeed(unsigned int freq_khz)
X {
X struct vco vco = freq_to_vco(freq_khz, 1);
X u_int cm_osc;
@@ -122,6 +122,7 @@
X
X #ifdef CONFIG_CPU_FREQ
X cpufreq_init(cpu_freq_khz);
+ cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
X #endif
X
X cm_stat = __raw_readl(CM_STAT);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/dma.c linux/arch/arm/mach-integrator/dma.c
--- v2.4.12/linux/arch/arm/mach-integrator/dma.c Fri Mar 2 18:38:39 2001
+++ linux/arch/arm/mach-integrator/dma.c Thu Oct 11 09:04:57 2001
@@ -19,7 +19,7 @@
X * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
X */
X #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/mman.h>
X #include <linux/init.h>
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-integrator/pci_v3.c linux/arch/arm/mach-integrator/pci_v3.c
--- v2.4.12/linux/arch/arm/mach-integrator/pci_v3.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-integrator/pci_v3.c Thu Oct 11 09:04:57 2001
@@ -24,7 +24,7 @@
X #include <linux/kernel.h>
X #include <linux/pci.h>
X #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/ioport.h>
X #include <linux/interrupt.h>
X #include <linux/spinlock.h>
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/Makefile linux/arch/arm/mach-sa1100/Makefile
--- v2.4.12/linux/arch/arm/mach-sa1100/Makefile Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/Makefile Thu Oct 11 09:04:57 2001
@@ -14,31 +14,38 @@
X obj-n :=
X obj- :=
X
-export-objs := assabet.o bitsy.o freebird.o huw_webpanel.o yopy.o \
+export-objs := assabet.o h3600.o freebird.o huw_webpanel.o yopy.o \
X generic.o hwtimer.o irq.o usb_ctl.o usb_recv.o usb_send.o \
- dma-sa1100.o dma-sa1111.o pcipool.o
+ dma-sa1100.o dma-sa1111.o pcipool.o sa1111-pcibuf.o
X
X # Common support (must be linked before board specific support)
X obj-y += generic.o irq.o dma-sa1100.o
-obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o sa1111-pcibuf.o pcipool.o
X
X # This needs to be cleaned up. We probably need to have SA1100
X # and SA1110 config symbols.
+#
+# We link the CPU support next, so that RAM timings can be tuned.
X ifeq ($(CONFIG_CPU_FREQ),y)
X obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
X obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
X endif
X
+# Next, the SA1111 stuff.
+obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
+obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
+
X # Specific board support
+obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
X obj-$(CONFIG_SA1100_ASSABET) += assabet.o
X obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
-obj-$(CONFIG_SA1100_BITSY) += bitsy.o
X obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
X obj-$(CONFIG_SA1100_CERF) += cerf.o
X obj-$(CONFIG_SA1100_EMPEG) += empeg.o
X obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
X obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
X obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
+obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
+obj-$(CONFIG_SA1100_H3600) += h3600.o
X obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
X obj-$(CONFIG_SA1100_ITSY) += itsy.o
X obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
@@ -63,6 +70,7 @@
X leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
X leds-$(CONFIG_SA1100_LART) += leds-lart.o
X leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
+leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
X obj-$(CONFIG_LEDS) += $(leds-y)
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/adsbitsy.c linux/arch/arm/mach-sa1100/adsbitsy.c
--- v2.4.12/linux/arch/arm/mach-sa1100/adsbitsy.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/adsbitsy.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsbitsy.c
+ *
+ * Author: Woojung Huh
+ *
+ * Pieces specific to the ADS Bitsy


+ *
+ * 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.

+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init adsbitsy_init(void)
+{
+ int ret;
+
+ if (!machine_is_adsbitsy())
+ return -ENODEV;
+
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state
+ */
+ sa1110_mb_disable();
+
+ /*
+ * Reset SA1111
+ */
+ GPCR |= GPIO_GPIO26;
+ udelay(1000);
+ GPSR |= GPIO_GPIO26;
+
+ /*
+ * Probe for SA1111.
+ */
+ ret = sa1111_probe();
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We found it. Wake the chip up.
+ */
+ sa1111_wake();
+
+ /*
+ * The SDRAM configuration of the SA1110 and the SA1111 must
+ * match. This is very important to ensure that SA1111 accesses
+ * don't corrupt the SDRAM. Note that this ungates the SA1111's
+ * MBGNT signal, so we must have called sa1110_mb_disable()
+ * beforehand.
+ */
+ sa1111_configure_smc(1,
+ FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+ FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+ /*
+ * Enable PWM control for LCD
+ */
+ SKPCR |= SKPCR_PWMCLKEN;
+ SKPWM0 = 0x7F; // VEE
+ SKPEN0 = 1;
+ SKPWM1 = 0x01; // Backlight
+ SKPEN1 = 1;
+
+ /*
+ * We only need to turn on DCLK whenever we want to use the
+ * DMA. It can otherwise be held firmly in the off position.
+ */
+ SKPCR |= SKPCR_DCLKEN;
+
+ /*
+ * Enable the SA1110 memory bus request and grant signals.
+ */
+ sa1110_mb_enable();
+
+ set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+ sa1111_init_irq(SA1100_GPIO_TO_IRQ(0));


+
+ return 0;
+}
+

+__initcall(adsbitsy_init);
+
+static void __init adsbitsy_init_irq(void)
+{
+ /* First the standard SA1100 IRQs */
+ sa1100_init_irq();
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc adsbitsy_io_desc[] __initdata = {
+ /* virtual physical length domain r w c b */
+ { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1111 */
+ LAST_DESC
+};
+
+static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
+{
+ if (port->mapbase == _Ser1UTCR0) {
+ Ser1SDCR0 |= SDCR0_UART;
+ // Set RTS Output and High (should be done in the set_mctrl fn)
+ GPDR |= GPIO_GPIO15;
+ GPCR |= GPIO_GPIO15;
+ // Set CTS Input
+ GPDR &= ~GPIO_GPIO14;
+ } else if (port->mapbase == _Ser2UTCR0) {
+ Ser2UTCR4 = Ser2HSCR0 = 0;
+ // Set RTS Output and High (should be done in the set_mctrl fn)
+ GPDR |= GPIO_GPIO17;
+ GPCR |= GPIO_GPIO17;
+ // Set CTS Input
+ GPDR &= ~GPIO_GPIO16;
+ } else if (port->mapbase == _Ser2UTCR0) {
+ // Set RTS Output and High (should be done in the set_mctrl fn)
+ GPDR |= GPIO_GPIO19;
+ GPCR |= GPIO_GPIO19;
+ // Set CTS Input
+ GPDR &= ~GPIO_GPIO18;


+ }
+ return 0;
+}
+

+static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
+ open: adsbitsy_uart_open,
+};
+
+static void __init adsbitsy_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(adsbitsy_io_desc);
+
+ sa1110_register_uart_fns(&adsbitsy_port_fns);
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+ sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(ADSBITSY, "ADS Bitsy")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_adsbitsy)
+ MAPIO(adsbitsy_map_io)
+ INITIRQ(adsbitsy_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/assabet.c linux/arch/arm/mach-sa1100/assabet.c
--- v2.4.12/linux/arch/arm/mach-sa1100/assabet.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/assabet.c Thu Oct 11 09:04:57 2001
@@ -47,6 +47,7 @@
X * or BCR_clear().
X */
X BCR = BCR_value = BCR_DB1111;
+ NCR_0 = 0;
X
X #ifndef CONFIG_ASSABET_NEPONSET
X printk( "Warning: Neponset detected but full support "
@@ -101,6 +102,8 @@
X SCR_value = scr;
X }
X
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
X static void __init
X fixup_assabet(struct machine_desc *desc, struct param_struct *params,
X char **cmdline, struct meminfo *mi)
@@ -114,6 +117,12 @@
X if (machine_has_neponset())
X printk("Neponset expansion board detected\n");
X
+ /*
+ * Apparantly bootldr uses a param_struct. Groan.
+ */
+ if (t->hdr.tag != ATAG_CORE)
+ convert_to_tag_list(params, 1);
+
X if (t->hdr.tag != ATAG_CORE) {
X t->hdr.tag = ATAG_CORE;
X t->hdr.size = tag_size(tag_core);
@@ -265,7 +274,6 @@
X neponset_map_io();
X #endif
X
- sa1100_register_uart(1, 2);
X if (machine_has_neponset()) {
X /*
X * When Neponset is attached, the first UART should be
@@ -295,7 +303,7 @@
X * excessive power drain. --rmk
X */
X GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
- GPCR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+ GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
X }
X
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/bitsy.c linux/arch/arm/mach-sa1100/bitsy.c
--- v2.4.12/linux/arch/arm/mach-sa1100/bitsy.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/bitsy.c Wed Dec 31 16:00:00 1969
@@ -1,175 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/bitsy.c
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/setup.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
-#include <linux/serial_core.h>
-
-#include "generic.h"
-
-
-/*
- * Bitsy has extended, write-only memory-mapped GPIO's
- */
-
-static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
-
-void clr_bitsy_egpio(unsigned long x)
-{
- bitsy_egpio &= ~x;
- BITSY_EGPIO = bitsy_egpio;
-}
-
-void set_bitsy_egpio(unsigned long x)
-{
- bitsy_egpio |= x;
- BITSY_EGPIO = bitsy_egpio;
-}
-
-EXPORT_SYMBOL(clr_bitsy_egpio);
-EXPORT_SYMBOL(set_bitsy_egpio);
-
-
-/*
- * low-level UART features
- */
-
-static void bitsy_uart_set_mctrl(struct uart_port *port, u_int mctrl)
-{
- if (port->mapbase == _Ser3UTCR0) {
- if (mctrl & TIOCM_RTS)
- GPCR = GPIO_BITSY_COM_RTS;
- else
- GPSR = GPIO_BITSY_COM_RTS;
- }
-}
-
-static int bitsy_uart_get_mctrl(struct uart_port *port)
-{
- int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
- if (port->mapbase == _Ser3UTCR0) {
- int gplr = GPLR;
- if (gplr & GPIO_BITSY_COM_DCD)
- ret &= ~TIOCM_CD;
- if (gplr & GPIO_BITSY_COM_CTS)
- ret &= ~TIOCM_CTS;
- }
-
- return ret;
-}
-
-static void bitsy_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct uart_info *info = dev_id;
- /* Note: should only call this if something has changed */
- uart_handle_dcd_change(info, GPLR & GPIO_BITSY_COM_DCD);
-}
-
-static void bitsy_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct uart_info *info = dev_id;
- /* Note: should only call this if something has changed */
- uart_handle_cts_change(info, GPLR & GPIO_BITSY_COM_CTS);
-}
-
-static void bitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
-{
- if (port->mapbase == _Ser2UTCR0) {
- if (state == 0) {
- set_bitsy_egpio(EGPIO_BITSY_IR_ON);
- } else {
- clr_bitsy_egpio(EGPIO_BITSY_IR_ON);
- }
- } else if (port->mapbase == _Ser3UTCR0) {
- if (state == 0) {
- set_bitsy_egpio(EGPIO_BITSY_RS232_ON);
- } else {
- clr_bitsy_egpio(EGPIO_BITSY_RS232_ON);
- }
- }
-}
-
-static int bitsy_uart_open(struct uart_port *port, struct uart_info *info)
-{
- int ret = 0;
-
- if (port->mapbase == _Ser2UTCR0) {
- Ser2UTCR4 = UTCR4_HSE;
- Ser2HSCR0 = 0;
- Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
- HSSR0_RAB | HSSR0_FRE;
- } else if (port->mapbase == _Ser3UTCR0) {
- GPDR &= ~(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS);
- GPDR |= GPIO_BITSY_COM_RTS;
- set_GPIO_IRQ_edge(GPIO_BITSY_COM_DCD|GPIO_BITSY_COM_CTS,
- GPIO_BOTH_EDGES);
-
- ret = request_irq(IRQ_GPIO_BITSY_COM_DCD, bitsy_dcd_intr,
- 0, "RS232 DCD", info);
- if (ret)
- return ret;
-
- ret = request_irq(IRQ_GPIO_BITSY_COM_CTS, bitsy_cts_intr,
- 0, "RS232 CTS", info);
- if (ret)
- free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
- }
- return ret;
-}
-
-static void bitsy_uart_close(struct uart_port *port, struct uart_info *info)
-{
- if (port->mapbase == _Ser3UTCR0) {
- free_irq(IRQ_GPIO_BITSY_COM_DCD, info);
- free_irq(IRQ_GPIO_BITSY_COM_CTS, info);
- }
-}
-
-static struct sa1100_port_fns bitsy_port_fns __initdata = {
- set_mctrl: bitsy_uart_set_mctrl,
- get_mctrl: bitsy_uart_get_mctrl,
- pm: bitsy_uart_pm,
- open: bitsy_uart_open,
- close: bitsy_uart_close,
-};
-
-static struct map_desc bitsy_io_desc[] __initdata = {
- /* virtual physical length domain r w c b */
- { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
- { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
- { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
- { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
- LAST_DESC
-};
-
-static void __init bitsy_map_io(void)
-{
- sa1100_map_io();
- iotable_init(bitsy_io_desc);
-
- sa1100_register_uart_fns(&bitsy_port_fns);
- sa1100_register_uart(0, 3);
- sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
- sa1100_register_uart(2, 2);
-}
-
-MACHINE_START(BITSY, "Compaq iPAQ")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- BOOT_PARAMS(0xc0000100)
- MAPIO(bitsy_map_io)
- INITIRQ(sa1100_init_irq)
-MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/cpu-sa1110.c linux/arch/arm/mach-sa1100/cpu-sa1110.c
--- v2.4.12/linux/arch/arm/mach-sa1100/cpu-sa1110.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/cpu-sa1110.c Thu Oct 11 09:04:57 2001
@@ -3,7 +3,7 @@
X *
X * Copyright (C) 2001 Russell King
X *
- * $Id: cpu-sa1110.c,v 1.3 2001/08/12 15:41:53 rmk Exp $
+ * $Id: cpu-sa1110.c,v 1.5 2001/09/10 13:25:58 rmk Exp $


X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License version 2 as

@@ -258,14 +258,13 @@
X {
X struct sdram_params *sdram = NULL;
X unsigned int cur_freq = cpufreq_get(smp_processor_id());
- int ret = -ENODEV;
X
X if (machine_is_assabet())
X sdram = &tc59sm716_cl3_params;
X
X if (sdram) {
X printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
- " twr: %d refresh: %d cas_latency: %d",
+ " twr: %d refresh: %d cas_latency: %d\n",
X sdram->tck, sdram->trcd, sdram->trp,
X sdram->twr, sdram->refresh, sdram->cas_latency);
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1100.c linux/arch/arm/mach-sa1100/dma-sa1100.c
--- v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1100.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1100.c Thu Oct 11 09:04:57 2001
@@ -68,26 +68,30 @@
X {
X dma_regs_t *regs = dma->regs;
X int status;
- int use_bufa;
X
X status = regs->RdDCSR;
X
X /* If both DMA buffers are started, there's nothing else we can do. */
- if ((status & DCSR_STRTA) && (status & DCSR_STRTB)) {
+ if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
X DPRINTK("start: st %#x busy\n", status);
X return -EBUSY;
X }
X
- use_bufa = (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
- (!(status & DCSR_BIU) && !(status & DCSR_STRTA)));
- if (use_bufa) {
- regs->ClrDCSR = DCSR_DONEA | DCSR_STRTA;
+ if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
+ (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
+ if (status & DCSR_DONEA) {
+ /* give a chance for the interrupt to be processed */
+ goto irq_pending;
+ }
X regs->DBSA = dma_ptr;
X regs->DBTA = size;
X regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
X DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
X } else {
- regs->ClrDCSR = DCSR_DONEB | DCSR_STRTB;
+ if (status & DCSR_DONEB) {
+ /* give a chance for the interrupt to be processed */
+ goto irq_pending;
+ }
X regs->DBSB = dma_ptr;
X regs->DBTB = size;
X regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
@@ -95,6 +99,9 @@
X }


X
X return 0;
+

+irq_pending:
+ return -EAGAIN;
X }
X
X
@@ -204,11 +211,16 @@
X
X DPRINTK("IRQ: b=%#x st=%#x\n", (int) dma->curr->id, status);
X
- dma->regs->ClrDCSR = DCSR_ERROR | DCSR_DONEA | DCSR_DONEB;
- if (!(status & (DCSR_DONEA | DCSR_DONEB)))
- return;
+ if (status & (DCSR_ERROR)) {
+ printk(KERN_ERR "DMA on \"%s\" caused an error\n", dma->device_id);
+ dma->regs->ClrDCSR = DCSR_ERROR;
+ }
X
- sa1100_dma_done (dma);
+ dma->regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
+ if (status & DCSR_DONEA)
+ sa1100_dma_done (dma);
+ if (status & DCSR_DONEB)
+ sa1100_dma_done (dma);
X }
X
X
@@ -435,7 +447,7 @@
X dma->curr = NULL;
X }
X dma->spin_ref = 0;
- dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB;
+ dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB;
X process_dma(dma);
X local_irq_restore(flags);
X return 0;
@@ -455,7 +467,6 @@
X if (dma->stopped) {
X int flags;
X save_flags_cli(flags);
- dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
X dma->stopped = 0;
X dma->spin_ref = 0;
X process_dma(dma);
@@ -478,7 +489,7 @@
X if (channel_is_sa1111_sac(channel))
X sa1111_reset_sac_dma(channel);
X else
- dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_RUN|DCSR_IE;
+ dma->regs->ClrDCSR = DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB|DCSR_RUN|DCSR_IE;
X buf = dma->curr;
X if (!buf)
X buf = dma->tail;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1111.c linux/arch/arm/mach-sa1100/dma-sa1111.c
--- v2.4.12/linux/arch/arm/mach-sa1100/dma-sa1111.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1111.c Thu Oct 11 09:04:57 2001
@@ -314,7 +314,7 @@
X if(physaddr<(1<<20))
X return 0;
X
- switch(FExtr(SMCR, SMCR_DRAC)){
+ switch(FExtr(SBI_SMCR, SMCR_DRAC)){
X case 01: /* 10 row + bank address bits, A<20> must not be set */
X if(physaddr & (1<<20))
X return -1;
@@ -341,7 +341,7 @@
X break;
X default:
X printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%o\n",
- __FUNCTION__, FExtr(SMCR, SMCR_DRAC));
+ __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));
X return -1;
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/generic.c linux/arch/arm/mach-sa1100/generic.c
--- v2.4.12/linux/arch/arm/mach-sa1100/generic.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/generic.c Thu Oct 11 09:04:57 2001
@@ -69,7 +69,7 @@
X * Validate the speed in khz. If we can't generate the precise
X * frequency requested, round it down (to be on the safe side).
X */
-unsigned int cpufreq_validatespeed(unsigned int khz)
+unsigned int sa1100_validatespeed(unsigned int khz)
X {
X int i;
X
@@ -87,7 +87,7 @@
X * above, we can match for an exact frequency. If we don't find
X * an exact match, we will to set the lowest frequency to be safe.
X */
-void cpufreq_setspeed(unsigned int khz)
+void sa1100_setspeed(unsigned int khz)
X {
X int i;
X
@@ -103,6 +103,7 @@
X static int __init sa1100_init_clock(void)
X {
X cpufreq_init(get_cclk_frequency() * 100);
+ cpufreq_setfunctions(sa1100_validatespeed, sa1100_setspeed);
X return 0;
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/graphicsclient.c linux/arch/arm/mach-sa1100/graphicsclient.c
--- v2.4.12/linux/arch/arm/mach-sa1100/graphicsclient.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/graphicsclient.c Thu Oct 11 09:04:57 2001
@@ -131,14 +131,15 @@
X mi->nr_banks = 2;
X
X ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 4096 );
+ setup_ramdisk( 1, 0, 0, 8192 );
X setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
X }
X
X static struct map_desc graphicsclient_io_desc[] __initdata = {
X /* virtual physical length domain r w c b */
- { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
X { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+ { 0xf1000000, 0x18000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
X LAST_DESC
X };
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/graphicsmaster.c linux/arch/arm/mach-sa1100/graphicsmaster.c
--- v2.4.12/linux/arch/arm/mach-sa1100/graphicsmaster.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/graphicsmaster.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,225 @@
+/*
+ * linux/arch/arm/mach-sa1100/graphicsmaster.c
+ *
+ * Pieces specific to the GraphicsMaster board


+ *
+ * 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.

+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init graphicsmaster_init(void)
+{
+ int ret;
+
+ if (!machine_is_graphicsmaster())
+ return -ENODEV;
+
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state
+ */
+ sa1110_mb_disable();
+
+ /*
+ * Probe for SA1111.
+ */
+ ret = sa1111_probe();
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We found it. Wake the chip up.
+ */
+ sa1111_wake();
+
+ /*
+ * The SDRAM configuration of the SA1110 and the SA1111 must
+ * match. This is very important to ensure that SA1111 accesses
+ * don't corrupt the SDRAM. Note that this ungates the SA1111's
+ * MBGNT signal, so we must have called sa1110_mb_disable()
+ * beforehand.
+ */
+ sa1111_configure_smc(1,
+ FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+ FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+ /*
+ * Enable PWM control for LCD
+ */
+ SKPCR |= SKPCR_PWMCLKEN;
+ SKPWM0 = 0x7F; // VEE
+ SKPEN0 = 1;
+ SKPWM1 = 0x01; // Backlight
+ SKPEN1 = 1;
+
+ /*
+ * We only need to turn on DCLK whenever we want to use the
+ * DMA. It can otherwise be held firmly in the off position.
+ */
+ SKPCR |= SKPCR_DCLKEN;
+
+ /*
+ * Enable the SA1110 memory bus request and grant signals.
+ */
+ sa1110_mb_enable();
+
+ sa1111_init_irq(ADS_EXT_IRQ(0));


+
+ return 0;
+}
+

+__initcall(graphicsmaster_init);
+
+/*
+ * Handlers for GraphicsMaster's external IRQ logic
+ */
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+ int i;
+
+ while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
+ for( i = 0; i < 16; i++ )
+ if( irq & (1<<i) ) {
+ do_IRQ( ADS_EXT_IRQ(i), regs );
+ }
+ }
+}
+
+static struct irqaction ADS_ext_irq = {
+ name: "ADS_ext_IRQ",
+ handler: ADS_IRQ_demux,
+ flags: SA_INTERRUPT
+};
+
+static void ADS_mask_and_ack_irq0(unsigned int irq)
+{
+ int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+ ADS_INT_EN1 &= ~mask;
+ ADS_INT_ST1 = mask;
+}
+
+static void ADS_mask_irq0(unsigned int irq)
+{
+ ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+}
+
+static void ADS_unmask_irq0(unsigned int irq)
+{
+ ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+}
+
+static void ADS_mask_and_ack_irq1(unsigned int irq)
+{
+ int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+ ADS_INT_EN2 &= ~mask;
+ ADS_INT_ST2 = mask;
+}
+
+static void ADS_mask_irq1(unsigned int irq)
+{
+ ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
+static void ADS_unmask_irq1(unsigned int irq)
+{
+ ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+}
+
+static void __init graphicsmaster_init_irq(void)
+{
+ int irq;
+
+ /* First the standard SA1100 IRQs */
+ sa1100_init_irq();
+
+ /* disable all IRQs */
+ ADS_INT_EN1 = 0;
+ ADS_INT_EN2 = 0;
+ /* clear all IRQs */
+ ADS_INT_ST1 = 0xff;
+ ADS_INT_ST2 = 0xff;
+
+ for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = ADS_mask_and_ack_irq0;
+ irq_desc[irq].mask = ADS_mask_irq0;
+ irq_desc[irq].unmask = ADS_unmask_irq0;
+ }
+ for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = ADS_mask_and_ack_irq1;
+ irq_desc[irq].mask = ADS_mask_irq1;
+ irq_desc[irq].unmask = ADS_unmask_irq1;
+ }
+ GPDR &= ~GPIO_GPIO0;
+ set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
+ setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
+}
+
+
+/*
+ * Initialization fixup
+ */
+
+static void __init
+fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+ mi->nr_banks = 1;
+ SET_BANK( 1, 0xc8000000, 16*1024*1024 );
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+}
+
+static struct map_desc graphicsmaster_io_desc[] __initdata = {
+ /* virtual physical length domain r w c b */
+ { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CPLD */
+ { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CAN */
+ { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+ LAST_DESC
+};
+
+static void __init graphicsmaster_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(graphicsmaster_io_desc);
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+ sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_graphicsmaster)
+ MAPIO(graphicsmaster_map_io)
+ INITIRQ(graphicsmaster_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/h3600.c linux/arch/arm/mach-sa1100/h3600.c
--- v2.4.12/linux/arch/arm/mach-sa1100/h3600.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/h3600.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-sa1100/h3600.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <linux/serial_core.h>
+
+#include "generic.h"
+
+
+/*
+ * Bitsy has extended, write-only memory-mapped GPIO's
+ */
+
+static int h3600_egpio = EGPIO_H3600_RS232_ON;
+
+void clr_h3600_egpio(unsigned long x)
+{
+ h3600_egpio &= ~x;
+ H3600_EGPIO = h3600_egpio;
+}
+
+void set_h3600_egpio(unsigned long x)
+{
+ h3600_egpio |= x;
+ H3600_EGPIO = h3600_egpio;
+}
+
+EXPORT_SYMBOL(clr_h3600_egpio);
+EXPORT_SYMBOL(set_h3600_egpio);
+
+
+/*
+ * Low-level UART features.
+ *
+ * Note that RTS, CTS and DCD are all active low.
+ */
+
+static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ if (mctrl & TIOCM_RTS)
+ GPCR = GPIO_H3600_COM_RTS;
+ else
+ GPSR = GPIO_H3600_COM_RTS;
+ }
+}
+
+static int h3600_uart_get_mctrl(struct uart_port *port)
+{
+ int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+ if (port->mapbase == _Ser3UTCR0) {
+ int gplr = GPLR;
+ if (gplr & GPIO_H3600_COM_DCD)
+ ret &= ~TIOCM_CD;
+ if (gplr & GPIO_H3600_COM_CTS)
+ ret &= ~TIOCM_CTS;
+ }


+
+ return ret;
+}
+

+static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct uart_info *info = dev_id;
+ /* Note: should only call this if something has changed */
+ uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD));
+}
+
+static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct uart_info *info = dev_id;
+ /* Note: should only call this if something has changed */
+ uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS));
+}
+
+static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == _Ser2UTCR0) {
+ if (state == 0) {
+ set_h3600_egpio(EGPIO_H3600_IR_ON);
+ } else {
+ clr_h3600_egpio(EGPIO_H3600_IR_ON);
+ }
+ } else if (port->mapbase == _Ser3UTCR0) {
+ if (state == 0) {
+ set_h3600_egpio(EGPIO_H3600_RS232_ON);
+ } else {
+ clr_h3600_egpio(EGPIO_H3600_RS232_ON);
+ }
+ }
+}
+
+static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
+{
+ int ret = 0;
+
+ if (port->mapbase == _Ser2UTCR0) {
+ Ser2UTCR4 = UTCR4_HSE;
+ Ser2HSCR0 = 0;
+ Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
+ HSSR0_RAB | HSSR0_FRE;
+ } else if (port->mapbase == _Ser3UTCR0) {
+ GPDR &= ~(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS);
+ GPDR |= GPIO_H3600_COM_RTS;
+ set_GPIO_IRQ_edge(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS,
+ GPIO_BOTH_EDGES);
+
+ ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr,
+ 0, "RS232 DCD", info);
+ if (ret)
+ return ret;
+
+ ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr,
+ 0, "RS232 CTS", info);
+ if (ret)
+ free_irq(IRQ_GPIO_H3600_COM_DCD, info);


+ }
+ return ret;
+}
+

+static void h3600_uart_close(struct uart_port *port, struct uart_info *info)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+ free_irq(IRQ_GPIO_H3600_COM_CTS, info);
+ }
+}
+
+static struct sa1100_port_fns h3600_port_fns __initdata = {
+ set_mctrl: h3600_uart_set_mctrl,
+ get_mctrl: h3600_uart_get_mctrl,
+ pm: h3600_uart_pm,
+ open: h3600_uart_open,
+ close: h3600_uart_close,
+};
+
+static struct map_desc h3600_io_desc[] __initdata = {
+ /* virtual physical length domain r w c b */
+ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
+ { 0xf1000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
+ { 0xf3000000, 0x40000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
+ LAST_DESC
+};
+
+static void __init h3600_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(h3600_io_desc);
+
+ sa1100_register_uart_fns(&h3600_port_fns);
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
+ sa1100_register_uart(2, 2);
+
+ /*
+ * Default GPIO settings.
+ */
+ GPCR = 0x0fffffff;
+ GPDR = 0x0401f3fc;
+
+ /*
+ * Ensure those pins are outputs and driving low.
+ */
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ BOOT_PARAMS(0xc0000100)
+ MAPIO(h3600_map_io)
+ INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/jornada720.c linux/arch/arm/mach-sa1100/jornada720.c
--- v2.4.12/linux/arch/arm/mach-sa1100/jornada720.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/jornada720.c Thu Oct 11 09:04:57 2001
@@ -46,7 +46,8 @@
X PPDR |= PPC_LDD3 | PPC_LDD4;
X
X /* initialize extra IRQs */
- sa1111_init_irq(1); /* chained on GPIO 1 */
+ set_GPIO_IRQ_edge(GPIO_GPIO(1), GPIO_RISING_EDGE);
+ sa1111_init_irq(SA1100_GPIO_TO_IRQ(1)); /* chained on GPIO 1 */
X
X sa1100_register_uart(0, 3);
X sa1100_register_uart(1, 1);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds-graphicsmaster.c linux/arch/arm/mach-sa1100/leds-graphicsmaster.c
--- v2.4.12/linux/arch/arm/mach-sa1100/leds-graphicsmaster.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-sa1100/leds-graphicsmaster.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-graphicsmaster.c
+ *
+ * GraphicsClient Plus LEDs support
+ * Woojung Huh, Feb 13, 2001
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER ADS_LED0 /* green heartbeat */
+#define LED_USER ADS_LED1 /* amber, boots to on */
+#define LED_IDLE ADS_LED2 /* red has the idle led, if any */
+
+#define LED_MASK (ADS_LED0|ADS_LED1|ADS_LED2)
+
+void graphicsmaster_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ save_flags_cli(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = 0; /* gc leds are positive logic */
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_TIMER;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_IDLE;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_IDLE;
+ break;
+#endif
+
+ case led_green_on:
+ break;
+
+ case led_green_off:
+ break;
+
+ case led_amber_on:
+ hw_led_state |= LED_USER;
+ break;
+
+ case led_amber_off:
+ hw_led_state &= ~LED_USER;
+ break;
+
+ case led_red_on:
+ break;
+
+ case led_red_off:
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ restore_flags(flags);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds.c linux/arch/arm/mach-sa1100/leds.c
--- v2.4.12/linux/arch/arm/mach-sa1100/leds.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/leds.c Thu Oct 11 09:04:57 2001
@@ -30,6 +30,8 @@
X leds_event = lart_leds_event;
X if (machine_is_pfs168())
X leds_event = pfs168_leds_event;
+ if (machine_is_graphicsmaster())
+ leds_event = graphicsmaster_leds_event;
X
X leds_event(led_start);
X return 0;
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/leds.h linux/arch/arm/mach-sa1100/leds.h
--- v2.4.12/linux/arch/arm/mach-sa1100/leds.h Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/leds.h Thu Oct 11 09:04:57 2001
@@ -5,4 +5,4 @@
X extern void graphicsclient_leds_event(led_event_t evt);
X extern void lart_leds_event(led_event_t evt);
X extern void pfs168_leds_event(led_event_t evt);
-
+extern void graphicsmaster_leds_event(led_event_t evt);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/neponset.c linux/arch/arm/mach-sa1100/neponset.c
--- v2.4.12/linux/arch/arm/mach-sa1100/neponset.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/neponset.c Thu Oct 11 09:04:57 2001
@@ -74,36 +74,73 @@
X
X static int __init neponset_init(void)
X {
- /* only on assabet */


+ int ret;
+
+ /*

+ * The Neponset is only present on the Assabet machine type.
+ */
X if (!machine_is_assabet())
- return 0;
+ return -ENODEV;
+
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state, whether or not
+ * we actually have a Neponset attached.
+ */
+ sa1110_mb_disable();
+
+ if (!machine_has_neponset()) {
+ printk(KERN_DEBUG "Neponset expansion board not present\n");
+ return -ENODEV;
+ }
+
+ if (WHOAMI != 0x11) {
+ printk(KERN_WARNING "Neponset board detected, but "
+ "wrong ID: %02x\n", WHOAMI);
+ return -ENODEV;
+ }
+
+ /*
+ * Neponset has SA1111 connected to CS4. We know that after
+ * reset the chip will be configured for variable latency IO.
+ */
+ /* FIXME: setup MSC2 */
+
+ /*
+ * Probe for a SA1111.
+ */
+ ret = sa1111_probe();
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We found it. Wake the chip up.
+ */
+ sa1111_wake();
+
+ /*
+ * The SDRAM configuration of the SA1110 and the SA1111 must
+ * match. This is very important to ensure that SA1111 accesses
+ * don't corrupt the SDRAM. Note that this ungates the SA1111's
+ * MBGNT signal, so we must have called sa1110_mb_disable()
+ * beforehand.
+ */
+ sa1111_configure_smc(1,
+ FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+ FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+ /*
+ * We only need to turn on DCLK whenever we want to use the
+ * DMA. It can otherwise be held firmly in the off position.
+ */
+ SKPCR |= SKPCR_DCLKEN;
X
- if (machine_has_neponset()) {
- LEDS = WHOAMI;
+ /*
+ * Enable the SA1110 memory bus request and grant signals.
+ */
+ sa1110_mb_enable();
X
- if (sa1111_init() < 0)
- return -EINVAL;
- /*
- * Assabet is populated by default with two Samsung
- * KM416S8030T-G8
- * 128Mb SDRAMs, which are organized as 12-bit (row addr) x
- * 9-bit
- * (column addr), according to the data sheet. Apparently, the
- * bank selects factor into the row address, as Angel sets up
- * the
- * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies
- * that when running at 100-125MHz, the CAS latency for -8
- * parts
- * is 3 cycles, which is consistent with Angel.
- */
- SMCR = (SMCR_DTIM | SMCR_MBGE |
- FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
- ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
- SKPCR |= SKPCR_DCLKEN;
-
- neponset_init_irq();
- } else
- printk("Neponset expansion board not present\n");
+ neponset_init_irq();
X
X return 0;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/pangolin.c linux/arch/arm/mach-sa1100/pangolin.c
--- v2.4.12/linux/arch/arm/mach-sa1100/pangolin.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/pangolin.c Thu Oct 11 09:04:57 2001
@@ -20,7 +20,7 @@
X fixup_pangolin(struct machine_desc *desc, struct param_struct *params,
X char **cmdline, struct meminfo *mi)
X {
- SET_BANK( 0, 0xc0000000, 64*1024*1024 );
+ SET_BANK( 0, 0xc0000000, 128*1024*1024 );
X mi->nr_banks = 1;
X
X ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/pfs168.c linux/arch/arm/mach-sa1100/pfs168.c
--- v2.4.12/linux/arch/arm/mach-sa1100/pfs168.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/pfs168.c Thu Oct 11 09:04:57 2001
@@ -20,14 +20,53 @@
X
X static int __init pfs168_init(void)
X {
- if (sa1111_init() < 0)
- return -EINVAL;
- SMCR = (SMCR_DTIM | SMCR_MBGE |
- FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
- ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
+ int ret;
+
+ if (!machine_is_pfs168())
+ return -ENODEV;
+
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state
+ */
+ sa1110_mb_disable();
+
+ /*
+ * Probe for SA1111.
+ */
+ ret = sa1111_probe();
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We found it. Wake the chip up.
+ */
+ sa1111_wake();
+
+ /*
+ * The SDRAM configuration of the SA1110 and the SA1111 must
+ * match. This is very important to ensure that SA1111 accesses
+ * don't corrupt the SDRAM. Note that this ungates the SA1111's
+ * MBGNT signal, so we must have called sa1110_mb_disable()
+ * beforehand.
+ */
+ sa1111_configure_smc(1,
+ FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+ FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+ /*
+ * We only need to turn on DCLK whenever we want to use the
+ * DMA. It can otherwise be held firmly in the off position.
+ */
X SKPCR |= SKPCR_DCLKEN;
X
- sa1111_init_irq(25); /* SA1111 IRQ on GPIO 25 */
+ /*
+ * Enable the SA1110 memory bus request and grant signals.
+ */
+ sa1110_mb_enable();
+
+ set_GPIO_IRQ_edge(GPIO_GPIO(25), GPIO_RISING_EDGE);
+ sa1111_init_irq(SA1100_GPIO_TO_IRQ(25)); /* SA1111 IRQ on GPIO 25 */
X
X return 0;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111-pcibuf.c linux/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111-pcibuf.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111-pcibuf.c Thu Oct 11 09:04:57 2001
@@ -13,7 +13,6 @@
X *
X * 06/13/2001 - created.
X */
-
X #include <linux/config.h>
X #include <linux/module.h>
X #include <linux/init.h>
@@ -64,13 +63,6 @@
X return 0;
X }
X
-static void
-free_safe_buffers(void)
-{
- pci_pool_destroy(small_buffer_cache);
- pci_pool_destroy(large_buffer_cache);
-}
-
X /* allocate a 'safe' buffer and keep track of it */
X static char *
X alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus)
@@ -183,17 +175,11 @@
X * we assume calls to map_single are symmetric with calls to unmap_single...
X */
X dma_addr_t
-pci_map_single(struct pci_dev *hwdev, void *virtptr,
+sa1111_map_single(struct pci_dev *hwdev, void *virtptr,
X size_t size, int direction)
X {
X dma_addr_t busptr;
X
- /* hack; usb-ohci.c never sends hwdev==NULL, all others do */
- if (hwdev == NULL) {
- consistent_sync(virtptr, size, direction);
- return virt_to_bus(virtptr);
- }
-
X mapped_alloc_size += size;
X
X if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
@@ -235,7 +221,7 @@
X * (basically return things back to the way they should be)
X */
X void
-pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
X size_t size, int direction)
X {
X char *safe, *unsafe;
@@ -267,13 +253,21 @@
X }
X }
X
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(sa1111_map_single);
+EXPORT_SYMBOL(sa1111_unmap_single);
X
-static void __init sa1111_init_safe_buffers(void)
+static int __init sa1111_init_safe_buffers(void)
X {
X printk("Initializing SA1111 buffer pool for DMA workaround\n");
X init_safe_buffers(NULL);


+ return 0;
+}
+

+static void free_safe_buffers(void)
+{
+ pci_pool_destroy(small_buffer_cache);
+ pci_pool_destroy(large_buffer_cache);
X }
X
-__initcall(sa1111_init_safe_buffers);
+module_init(sa1111_init_safe_buffers);
+module_exit(free_safe_buffers);
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111.c linux/arch/arm/mach-sa1100/sa1111.c
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111.c Thu Oct 11 09:04:57 2001
@@ -15,7 +15,6 @@
X * All initialization functions provided here are intended to be called
X * from machine specific code with proper arguments when required.
X */
-
X #include <linux/init.h>
X #include <linux/kernel.h>
X #include <linux/delay.h>
@@ -23,8 +22,6 @@
X #include <linux/interrupt.h>
X #include <linux/ptrace.h>
X #include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
X
X #include <asm/hardware.h>
X #include <asm/irq.h>
@@ -33,64 +30,6 @@
X
X #include "sa1111.h"
X
-static int sa1111_ohci_hcd_init(void);
-
-/*
- * SA1111 initialization
- */
-
-int __init sa1111_init(void)
-{
- unsigned long id = SKID;
-
- if((id & SKID_ID_MASK) == SKID_SA1111_ID)
- printk( KERN_INFO "SA-1111 Microprocessor Companion Chip: "
- "silicon revision %lx, metal revision %lx\n",
- (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
- else {
- printk(KERN_ERR "Could not detect SA-1111!\n");
- return -EINVAL;
- }
-
- /*
- * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
- * (SA-1110 Developer's Manual, section 9.1.2.1)
- */
- GAFR |= GPIO_32_768kHz;
- GPDR |= GPIO_32_768kHz;
- TUCR = TUCR_3_6864MHz;
-
- /* Now, set up the PLL and RCLK in the SA-1111: */
- SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
- udelay(100);
- SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
-
- /*
- * SA-1111 Register Access Bus should now be available. Clocks for
- * any other SA-1111 functional blocks must be enabled separately
- * using the SKPCR.
- */
-
- /*
- * If the system is going to use the SA-1111 DMA engines, set up
- * the memory bus request/grant pins. Also configure the shared
- * memory controller on the SA-1111 (SA-1111 Developer's Manual,
- * section 3.2.3) and power up the DMA bus clock:
- */
- GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
- GPDR |= GPIO_MBGNT;
- GPDR &= ~GPIO_MBREQ;
- TUCR |= TUCR_MR;
-
-#ifdef CONFIG_USB_OHCI
- /* setup up sa1111 usb host controller h/w */
- sa1111_ohci_hcd_init();
-#endif
-
- return 0;
-}
-
-
X /*
X * SA1111 Interrupt support
X */
@@ -159,7 +98,7 @@
X INTEN1 |= 1 << ((irq - SA1111_IRQ(32)));
X }
X
-void __init sa1111_init_irq(int gpio_nr)
+void __init sa1111_init_irq(int irq_nr)
X {
X int irq;
X
@@ -181,144 +120,146 @@
X
X for (irq = SA1111_IRQ(0); irq <= SA1111_IRQ(26); irq++) {
X irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].probe_ok = 0;
X irq_desc[irq].mask_ack = sa1111_mask_and_ack_lowirq;
X irq_desc[irq].mask = sa1111_mask_lowirq;
X irq_desc[irq].unmask = sa1111_unmask_lowirq;
X }
X for (irq = SA1111_IRQ(32); irq <= SA1111_IRQ(54); irq++) {
X irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].probe_ok = 0;
X irq_desc[irq].mask_ack = sa1111_mask_and_ack_highirq;
X irq_desc[irq].mask = sa1111_mask_highirq;
X irq_desc[irq].unmask = sa1111_unmask_highirq;
X }
X
- /* Not every machines has the SA1111 interrupt routed to a GPIO */
- if (gpio_nr >= 0) {
- set_GPIO_IRQ_edge (GPIO_GPIO(gpio_nr), GPIO_RISING_EDGE);
- setup_arm_irq (SA1100_GPIO_TO_IRQ(gpio_nr), &sa1111_irq);
- }
+ /* Register SA1111 interrupt */
+ if (irq_nr >= 0)
+ setup_arm_irq(irq_nr, &sa1111_irq);
X }
X
-/* ----------------- */
-
-#ifdef CONFIG_USB_OHCI
-
-#if defined(CONFIG_SA1100_XP860) || defined(CONFIG_ASSABET_NEPONSET) || defined(CONFIG_SA1100_PFS168)
-#define PwrSensePolLow 1
-#define PwrCtrlPolLow 1
-#else
-#define PwrSensePolLow 0
-#define PwrCtrlPolLow 0
-#endif
-
X /*
- * The SA-1111 errata says that the DMA hardware needs to be exercised
- * before the clocks are turned on to work properly. This code does
- * a tiny dma transfer to prime to hardware.
+ * Probe for a SA1111 chip.
X */
-static void __init sa1111_dma_setup(void)
+
+int __init sa1111_probe(void)
X {
- dma_addr_t vbuf;
- void * pbuf;
+ unsigned long id = SBI_SKID;
+ int ret = -ENODEV;
X
- /* DMA init & setup */
+ if ((id & SKID_ID_MASK) == SKID_SA1111_ID) {
+ printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
+ "silicon revision %lx, metal revision %lx\n",
+ (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+ ret = 0;
+ } else {
+ printk(KERN_DEBUG "SA-1111 not detected: ID = %08lx\n", id);
+ }
X
- /* WARNING: The SA-1111 L3 function is used as part of this
- * SA-1111 DMA errata workaround.
- *
- * N.B., When the L3 function is enabled, it uses GPIO_B<4:5>
- * and takes precedence over the PS/2 mouse and GPIO_B
- * functions. Refer to "Intel StrongARM SA-1111 Microprocessor
- * Companion Chip, Sect 10.2" for details. So this "fix" may
- * "break" support of either PS/2 mouse or GPIO_B if
- * precautions are not taken to avoid collisions in
- * configuration and use of these pins. AFAIK, no precautions
- * are taken at this time. So it is likely that the action
- * taken here may cause problems in PS/2 mouse and/or GPIO_B
- * pin use elsewhere.
- *
- * But wait, there's more... What we're doing here is
- * obviously altogether a bad idea. We're indiscrimanately bit
- * flipping config for a few different functions here which
- * are "owned" by other drivers. This needs to be handled
- * better than it is being done here at this time. */
-
- /* prime the dma engine with a tiny dma */
- SKPCR |= SKPCR_I2SCLKEN;
- SKAUD |= SKPCR_L3CLKEN | SKPCR_SCLKEN;
-
- SACR0 |= 0x00003305;
- SACR1 = 0x00000000;
-
- /* we need memory below 1mb */
- pbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &vbuf);
+ return ret;
+}
X
- SADTSA = (unsigned long)pbuf;
- SADTCA = 4;
+/*
+ * Bring the SA1111 out of reset. This requires a set procedure:
+ * 1. nRESET asserted (by hardware)
+ * 2. CLK turned on from SA1110
+ * 3. nRESET deasserted
+ * 4. VCO turned on, PLL_BYPASS turned off
+ * 5. Wait lock time, then assert RCLKEn
+ * 7. PCR set to allow clocking of individual functions
+ *
+ * Until we've done this, the only registers we can access are:
+ * SBI_SKCR
+ * SBI_SMCR
+ * SBI_SKID
+ */
+void sa1111_wake(void)
+{
+ /*
+ * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+ * (SA-1110 Developer's Manual, section 9.1.2.1)
+ */
+ GAFR |= GPIO_32_768kHz;
+ GPDR |= GPIO_32_768kHz;
+ TUCR = TUCR_3_6864MHz;
X
- SADTCS |= 0x00000011;
- SKPCR |= SKPCR_DCLKEN;
+ /*
+ * Turn VCO on, and disable PLL Bypass.
+ */
+ SBI_SKCR &= ~SKCR_VCO_OFF;
+ SBI_SKCR |= SKCR_PLL_BYPASS | SKCR_OE_EN;
X
- /* wait */
+ /*
+ * Wait lock time. SA1111 manual _doesn't_
+ * specify a figure for this! We choose 100us.
+ */
X udelay(100);
X
- SACR0 &= ~(0x00000002);
- SACR0 &= ~(0x00000001);
-
- /* */
- SACR0 |= 0x00000004;
- SACR0 &= ~(0x00000004);
+ /*
+ * Enable RCLK. We also ensure that RDYEN is set.
+ */
+ SBI_SKCR |= SKCR_RCLKEN | SKCR_RDYEN;
X
- SKAUD &= ~(SKPCR_L3CLKEN | SKPCR_SCLKEN);
+ /*
+ * Wait 14 RCLK cycles for the chip to finish coming out
+ * of reset. (RCLK=24MHz). This is 590ns.
+ */
+ udelay(1);
X
- SKPCR &= ~SKPCR_I2SCLKEN;
+ /*
+ * Ensure all clocks are initially off.
+ */
+ SKPCR = 0;
+}
X
- consistent_free(pbuf, 4, vbuf);
+void sa1111_doze(void)
+{
+ if (SKPCR & SKPCR_UCLKEN) {
+ printk("SA1111 doze mode refused\n");
+ return;
+ }
+ SBI_SKCR &= ~SKCR_RCLKEN;
X }
X
-#ifdef CONFIG_USB_OHCI
X /*
- * reset the SA-1111 usb controller and turn on it's clocks
+ * Configure the SA1111 shared memory controller.
X */
-static int __init sa1111_ohci_hcd_init(void)
+void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency)
X {
- volatile unsigned long *Reset = (void *)SA1111_p2v(_SA1111(0x051c));
- volatile unsigned long *Status = (void *)SA1111_p2v(_SA1111(0x0518));
-
- /* turn on clocks */
- SKPCR |= SKPCR_UCLKEN;
- udelay(100);
-
- /* force a reset */
- *Reset = 0x01;
- *Reset |= 0x02;
- udelay(100);
+ unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
X
- *Reset = 0;
+ if (cas_latency == 3)
+ smcr |= SMCR_CLAT;
X
- /* take out of reset */
- /* set power sense and control lines (this from the diags code) */
- *Reset = ( PwrSensePolLow << 6 )
- | ( PwrCtrlPolLow << 7 );
-
- *Status = 0;
+ SBI_SMCR = smcr;
+}
X
- udelay(10);
+/*
+ * Disable the memory bus request/grant signals on the SA1110 to
+ * ensure that we don't receive spurious memory requests. We set
+ * the MBGNT signal false to ensure the SA1111 doesn't own the
+ * SDRAM bus.
+ */
+void __init sa1110_mb_disable(void)
+{
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
X
- /* compensate for dma bug */
- sa1111_dma_setup();
+ GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
X
- return 0;
X }
X
-void sa1111_ohci_hcd_cleanup(void)
+/*
+ * If the system is going to use the SA-1111 DMA engines, set up
+ * the memory bus request/grant pins.
+ */
+void __init sa1110_mb_enable(void)
X {
- /* turn the USB clock off */
- SKPCR &= ~SKPCR_UCLKEN;
-}
-#endif
-
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
X
-#endif /* CONFIG_USB_OHCI */
+ GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+ TUCR |= TUCR_MR;
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/sa1111.h linux/arch/arm/mach-sa1100/sa1111.h
--- v2.4.12/linux/arch/arm/mach-sa1100/sa1111.h Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/sa1111.h Thu Oct 11 09:04:57 2001
@@ -2,7 +2,33 @@
X * linux/arch/arm/mach-sa1100/sa1111.h
X */
X
-extern int __init sa1111_init(void);
-extern void __init sa1111_init_irq(int gpio_nr);
+/*
+ * These two don't really belong in here.
+ */
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+/*
+ * Probe for a SA1111 chip.
+ */
+extern int sa1111_probe(void);
+
+/*
+ * Wake up a SA1111 chip.
+ */
+extern void sa1111_wake(void);
+
+/*
+ * Doze the SA1111 chip.
+ */
+extern void sa1111_doze(void);
+
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+extern void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency);
+
+
+extern void sa1111_init_irq(int irq_nr);
X extern void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mach-sa1100/xp860.c linux/arch/arm/mach-sa1100/xp860.c
--- v2.4.12/linux/arch/arm/mach-sa1100/xp860.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mach-sa1100/xp860.c Thu Oct 11 09:04:57 2001
@@ -28,10 +28,27 @@
X while(1);
X }
X
+/*
+ * Note: I replaced the sa1111_init() without the full SA1111 initialisation
+ * because this machine doesn't appear to use the DMA features. If this is
+ * wrong, please look at neponset.c to fix it properly.
+ */
X static int __init xp860_init(void)
X {
X pm_power_off = xp860_power_off;
- sa1111_init();
+
+ /*
+ * Probe for SA1111.
+ */
+ ret = sa1111_probe();
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We found it. Wake the chip up.
+ */
+ sa1111_wake();
+
X return 0;
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/extable.c linux/arch/arm/mm/extable.c
--- v2.4.12/linux/arch/arm/mm/extable.c Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/extable.c Thu Oct 11 09:04:57 2001
@@ -30,6 +30,8 @@


X return 0;
X }
X

+extern spinlock_t modlist_lock;
+
X unsigned long
X search_exception_table(unsigned long addr)
X {
@@ -38,18 +40,24 @@
X #ifndef CONFIG_MODULES
X /* There is only the kernel to search. */
X ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
- if (ret) return ret;
X #else
X /* The kernel is the last "module" -- no need to treat it special. */
+ unsigned long flags;
X struct module *mp;
+
+ ret = 0;
+ spin_lock_irqsave(&modlist_lock, flags);
X for (mp = module_list; mp != NULL; mp = mp->next) {
- if (mp->ex_table_start == NULL)
+ if (mp->ex_table_start == NULL ||
+ !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
X continue;
X ret = search_one_table(mp->ex_table_start,
X mp->ex_table_end - 1, addr);
- if (ret) return ret;
+ if (ret)
+ break;
X }
+ spin_unlock_irqrestore(&modlist_lock, flags);
X #endif
X
- return 0;
+ return ret;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- v2.4.12/linux/arch/arm/mm/fault-armv.c Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/mm/fault-armv.c Thu Oct 11 09:04:57 2001
@@ -599,10 +599,10 @@
X if (!inf->fn(addr, error_code, regs))
X return;
X bad:
- force_sig(inf->sig, current);
X printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
X inf->name, fsr, addr);
X show_pte(current->mm, addr);
+ force_sig(inf->sig, current);
X die_if_kernel("Oops", regs, 0);
X return;
X
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c
--- v2.4.12/linux/arch/arm/mm/fault-common.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/fault-common.c Thu Oct 11 09:04:57 2001
@@ -301,6 +301,10 @@
X tsk->thread.error_code = error_code;
X tsk->thread.trap_no = 14;
X force_sig(SIGBUS, tsk);
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
+ current->comm, addr, instruction_pointer(regs));
+#endif
X
X /* Kernel mode? Handle exceptions or die */
X if (user_mode(regs))
@@ -339,13 +343,10 @@
X if (addr < TASK_SIZE)
X return do_page_fault(addr, error_code, regs);
X
- tsk = current;
- mm = tsk->active_mm;
-
X offset = __pgd_offset(addr);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 05'
echo 'File patch-2.4.13 is continued in part 06'
echo "06" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:36 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part06

#!/bin/sh -x
# this is part 06 of a 53 - part archive


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

if test "$Scheck" != 06; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X
+ pgd = cpu_get_pgd() + offset;
X pgd_k = init_mm.pgd + offset;
- pgd = mm->pgd + offset;
X
X if (pgd_none(*pgd_k))
X goto bad_area;
@@ -365,6 +366,9 @@
X return 0;
X
X bad_area:
+ tsk = current;
+ mm = tsk->active_mm;
+
X do_bad_area(tsk, mm, addr, error_code, regs);
X return 0;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c
--- v2.4.12/linux/arch/arm/mm/init.c Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/init.c Thu Oct 11 09:04:57 2001
@@ -96,10 +96,22 @@
X }
X #endif
X
+/* This is currently broken
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * #define PG_skip 10
+ * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
+ * if (PageSkip(page)) {
+ * page = page->next_hash;
+ * if (page == NULL)
+ * break;
+ * }
+ */
X void show_mem(void)
X {
X int free = 0, total = 0, reserved = 0;
- int shared = 0, cached = 0, node;
+ int shared = 0, cached = 0, slab = 0, node;
X
X printk("Mem-info:\n");
X show_free_areas();
@@ -112,23 +124,13 @@
X end = page + NODE_DATA(node)->node_size;
X
X do {
-/* This is currently broken
- * PG_skip is used on sparc/sparc64 architectures to "skip" certain
- * parts of the address space.
- *
- * #define PG_skip 10
- * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
- * if (PageSkip(page)) {
- * page = page->next_hash;
- * if (page == NULL)
- * break;
- * }
- */
X total++;
X if (PageReserved(page))
X reserved++;
X else if (PageSwapCache(page))
X cached++;
+ else if (PageSlab(page))
+ slab++;
X else if (!page_count(page))
X free++;
X else
@@ -140,6 +142,7 @@
X printk("%d pages of RAM\n", total);
X printk("%d free pages\n", free);
X printk("%d reserved pages\n", reserved);
+ printk("%d slab pages\n", slab);
X printk("%d pages shared\n", shared);
X printk("%d pages swap cached\n", cached);
X #ifndef CONFIG_NO_PGT_CACHE
@@ -375,6 +378,8 @@
X */
X if (machine_is_archimedes() || machine_is_a5k())
X reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+ if (machine_is_edb7211())
+ reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
X if (machine_is_p720t())
X reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
X #ifdef CONFIG_SA1111
@@ -471,6 +476,7 @@
X
X if (map_pg != bootmap_pfn + bootmap_pages)
X BUG();
+
X }
X
X /*
@@ -528,6 +534,12 @@
X (bdata->node_boot_start >> PAGE_SHIFT);
X
X /*
+ * If this zone has zero size, skip it.
+ */
+ if (!zone_size[0])
+ continue;
+
+ /*
X * For each bank in this node, calculate the size of the
X * holes. holes = node_size - sum(bank_sizes_in_node)
X */
@@ -598,8 +610,12 @@
X create_memmap_holes(&meminfo);
X
X /* this will put all unused low memory onto the freelists */
- for (node = 0; node < numnodes; node++)
- totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+ for (node = 0; node < numnodes; node++) {
+ pg_data_t *pgdat = NODE_DATA(node);
+
+ if (pgdat->node_size != 0)
+ totalram_pages += free_all_bootmem_node(pgdat);
+ }
X
X #ifdef CONFIG_SA1111
X /* now that our DMA memory is actually so designated, we can free it */
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/mm-ftvpci.c linux/arch/arm/mm/mm-ftvpci.c
--- v2.4.12/linux/arch/arm/mm/mm-ftvpci.c Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mm/mm-ftvpci.c Thu Oct 11 09:04:57 2001
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/mm/mm-nexuspci.c
+ * from linux/arch/arm/mm/mm-ebsa110.c
+ *
+ * Copyright (C) 1998-1999 Phil Blundell
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * Extra MM routines for the FTV/PCI architecture
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+
+static struct map_desc nexuspci_io_desc[] __initdata = {
+ { INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
+ { DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
+
+void __init nexuspci_map_io(void)
+{
+ iotable_init(nexuspci_io_desc);
+}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/mm-nexuspci.c linux/arch/arm/mm/mm-nexuspci.c
--- v2.4.12/linux/arch/arm/mm/mm-nexuspci.c Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/mm/mm-nexuspci.c Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- * linux/arch/arm/mm/mm-nexuspci.c
- * from linux/arch/arm/mm/mm-ebsa110.c
- *
- * Copyright (C) 1998-1999 Phil Blundell
- * Copyright (C) 1998-1999 Russell King
- *
- * Extra MM routines for the FTV/PCI architecture
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-
-#include <asm/mach/map.h>
-
-static struct map_desc nexuspci_io_desc[] __initdata = {
- { INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
- { DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- LAST_DESC
-};
-
-void __init nexuspci_map_io(void)
-{
- iotable_init(nexuspci_io_desc);
-}
diff -u --recursive --new-file v2.4.12/linux/arch/arm/mm/proc-arm720.S linux/arch/arm/mm/proc-arm720.S
--- v2.4.12/linux/arch/arm/mm/proc-arm720.S Mon Aug 27 12:41:38 2001
+++ linux/arch/arm/mm/proc-arm720.S Thu Oct 11 09:04:57 2001
@@ -108,6 +108,7 @@
X * Function: arm720_data_abort ()
X *
X * Params : r0 = address of aborted instruction
+ * : r3 = saved SPSR
X *
X * Purpose : obtain information about current aborted instruction
X *
@@ -143,6 +144,8 @@


X mov pc, lr
X

X ENTRY(cpu_arm720_data_abort)
+ tst r3, #T_BIT
+ bne .data_thumb_abort
X ldr r4, [r0] @ read instruction causing problem
X tst r4, r4, lsr #21 @ C = bit 20
X sbc r1, r1, r1 @ r1 = C - 1
@@ -169,7 +172,7 @@
X Ldata_unknown: @ Part of jumptable
X mov r0, r2
X mov r1, r4
- mov r2, r3
+ mov r2, sp
X bl baddataabort
X b ret_from_exception
X
@@ -255,6 +258,77 @@
X addeq r7, r0, r2
X b Ldata_saver7
X
+.data_thumb_abort:
+ ldrh r4, [r0] @ read instruction
+ tst r4, r4, lsr #12 @ C = bit 11
+ sbc r1, r1, r1 @ r1 = C - 1
+ and r2, r4, #15 << 12
+ add pc, pc, r2, lsr #10 @ lookup in table
+ nop
+
+/* 0 */ b Ldata_unknown
+/* 1 */ b Ldata_unknown
+/* 2 */ b Ldata_unknown
+/* 3 */ b Ldata_unknown
+/* 4 */ b Ldata_unknown
+/* 5 */ b .data_thumb_reg
+/* 6 */ b Ldata_simple
+/* 7 */ b Ldata_simple
+/* 8 */ b Ldata_simple
+/* 9 */ b Ldata_simple
+/* A */ b Ldata_unknown
+/* B */ b .data_thumb_pushpop
+/* C */ b .data_thumb_ldmstm
+/* D */ b Ldata_unknown
+/* E */ b Ldata_unknown
+/* F */ b Ldata_unknown
+
+.data_thumb_reg:
+ tst r4, #1 << 9
+ beq Ldata_simple
+ tst r4, #1 << 10 @ If 'S' (signed) bit is set
+ movne r1, #0 @ it must be a load instr
+ b Ldata_simple
+
+.data_thumb_pushpop:
+ tst r4, #1 << 10
+ beq Ldata_unknown
+ mov r7, #0x11
+ and r0, r4, r7
+ and r2, r4, r7, lsl #1
+ add r0, r0, r2, lsr #1
+ and r2, r4, r7, lsl #2
+ add r0, r0, r2, lsr #2
+ and r2, r4, r7, lsl #3
+ add r0, r0, r2, lsr #3
+ add r0, r0, r0, lsr #4
+ and r2, r4, #0x0100 @ catch 'R' bit for push/pop
+ add r0, r0, r2, lsr #8
+ and r0, r0, #15 @ number of regs to transfer
+ ldr r7, [sp, #13 << 2]
+ tst r4, #1 << 11
+ addne r7, r7, r0, lsl #2 @ increment SP if PUSH
+ subeq r7, r7, r0, lsr #2 @ decrement SP if POP
+ str r7, [sp, #13 << 2]
+ b Ldata_simple
+
+.data_thumb_ldmstm:
+ mov r7, #0x11
+ and r0, r4, r7
+ and r2, r4, r7, lsl #1
+ add r0, r0, r2, lsr #1
+ and r2, r4, r7, lsl #2
+ add r0, r0, r2, lsr #2
+ and r2, r4, r7, lsl #3
+ add r0, r0, r2, lsr #3
+ add r0, r0, r0, lsr #4
+ and r0, r0, #15 @ number of regs to transfer
+ and r5, r4, #7 << 8
+ ldr r7, [sp, r5, lsr #6]
+ sub r7, r7, r0, lsr #2 @ always decrement
+ str r7, [sp, r5, lsr #6]
+ b Ldata_simple
+
X /*
X * Function: arm720_check_bugs (void)
X * : arm720_proc_init (void)
@@ -437,7 +511,7 @@
X .align
X
X /*
- * See /include/asm-arm for a definition of this structure.
+ * See linux/include/asm-arm/procinfo.h for a definition of this structure.
X */
X
X .section ".proc.info", #alloc, #execinstr
@@ -450,7 +524,7 @@
X b __arm720_setup @ cpu_flush
X .long cpu_arch_name @ arch_name
X .long cpu_elf_name @ elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT @ elf_hwcap
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT @ elf_hwcap
X .long cpu_arm720_info @ info
X .long arm720_processor_functions
X .size __arm720_proc_info, . - __arm720_proc_info
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/Makefile linux/arch/arm/tools/Makefile
--- v2.4.12/linux/arch/arm/tools/Makefile Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/tools/Makefile Thu Oct 11 09:04:57 2001
@@ -12,13 +12,15 @@
X
X # Generate the constants.h header file using the compiler. We get
X # the compiler to spit out assembly code, and then mundge it into
-# what we want.
+# what we want. We do this in several stages so make picks up on
+# any errors that occur along the way.
X
X $(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
- $(CC) $(CFLAGS) -S -o - getconstants.c | \
- sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' | \
- cat constants-hdr - > $@.tmp
- cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
+ $(CC) $(CFLAGS) -S -o - getconstants.c > $@.tmp.1
+ sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' $@.tmp.1 > $@.tmp.2
+ cat constants-hdr $@.tmp.2 > $@.tmp
+ cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@
+ $(RM) $@.tmp*
X
X # Build our dependencies, and then generate the constants and
X # mach-types header files. If we do it now, mkdep will pick
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/getconstants.c linux/arch/arm/tools/getconstants.c
--- v2.4.12/linux/arch/arm/tools/getconstants.c Tue Jul 3 17:08:18 2001
+++ linux/arch/arm/tools/getconstants.c Thu Oct 11 09:04:57 2001
@@ -14,8 +14,14 @@
X #include <asm/pgtable.h>
X #include <asm/uaccess.h>
X
-#ifndef __APCS_32__
-#error APCS-32 required
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
+#error Your compiler targets APCS-32 but this kernel requires APCS-26
+#endif
+#if defined(__APCS_26__) && defined(CONFIG_CPU_32)
+#error Your compiler targets APCS-26 but this kernel requires APCS-32
X #endif
X
X #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
diff -u --recursive --new-file v2.4.12/linux/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- v2.4.12/linux/arch/arm/tools/mach-types Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/tools/mach-types Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
X # To add an entry into this database, please see Documentation/arm/README,
X # or contact r...@arm.linux.org.uk
X #
-# Last update: Thu Aug 23 12:38:13 2001
+# Last update: Fri Oct 5 18:40:53 2001
X #
X # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
X #
@@ -71,7 +71,7 @@
X jupiter SA1100_JUPITER JUPITER 59
X psionw ARCH_PSIONW PSIONW 60
X aln SA1100_ALN ALN 61
-camelot ARCH_CAMELOT CAMELOT 62
+epxa10db ARCH_CAMELOT CAMELOT 62
X gds2200 SA1100_GDS2200 GDS2200 63
X psion_series7 SA1100_PSION_SERIES7 PSION_SERIES7 64
X xfile SA1100_XFILE XFILE 65
@@ -114,7 +114,7 @@
X gator SA1100_GATOR GATOR 103
X granite ARCH_GRANITE GRANITE 104
X consus SA1100_CONSUS CONSUS 105
-aaec2000_aaed20 ARCH_AAEC2000_AAED2000 AAEC2000_AAED2000 106
+agilent_aaed2000 ARCH_AAEC2000_AAED2000 AAEC2000_AAED2000 106
X cdb89712 ARCH_CDB89712 CDB89712 107
X graphicsmaster SA1100_GRAPHICSMASTER GRAPHICSMASTER 108
X adsbitsy SA1100_ADSBITSY ADSBITSY 109
@@ -122,3 +122,12 @@
X plce ARCH_PLCE PLCE 111
X pt_system3 SA1100_PT_SYSTEM3 PT_SYSTEM3 112
X medalb ARCH_MEDALB MEDALB 113
+eagle ARCH_EAGLE EAGLE 114
+dsc21 ARCH_DSC21 DSC21 115
+dsc24 ARCH_DSC24 DSC24 116
+ti5472 ARCH_TI5472 TI5472 117
+autcpu12 ARCH_AUTCPU12 AUTCPU12 118
+uengine ARCH_UENGINE UENGINE 119
+bluestem SA1100_BLUESTEM BLUESTEM 120
+xingu8 ARCH_XINGU8 XINGU8 121
+bushstb ARCH_BUSHSTB BUSHSTB 122
diff -u --recursive --new-file v2.4.12/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.12/linux/arch/cris/config.in Tue Oct 9 17:06:51 2001
+++ linux/arch/cris/config.in Mon Oct 15 13:42:14 2001
@@ -180,7 +180,7 @@


X
X source drivers/ieee1394/Config.in
X
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
X

X if [ "$CONFIG_NET" = "y" ]; then
X mainmenu_option next_comment
diff -u --recursive --new-file v2.4.12/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.4.12/linux/arch/i386/config.in Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/config.in Sat Oct 20 19:17:19 2001
@@ -315,7 +315,7 @@


X
X source drivers/ieee1394/Config.in
X
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
X

X if [ "$CONFIG_NET" = "y" ]; then
X mainmenu_option next_comment
@@ -398,6 +398,7 @@
X
X bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
X if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+ bool ' Debug high memory support' CONFIG_DEBUG_HIGHMEM
X bool ' Debug memory allocations' CONFIG_DEBUG_SLAB
X bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
X bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
diff -u --recursive --new-file v2.4.12/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.12/linux/arch/i386/defconfig Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/defconfig Sat Oct 20 19:17:37 2001
@@ -411,6 +411,7 @@
X # CONFIG_NE2K_PCI is not set
X # CONFIG_NE3210 is not set
X # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
X # CONFIG_8139TOO is not set
X # CONFIG_8139TOO_PIO is not set
X # CONFIG_8139TOO_TUNE_TWISTER is not set
@@ -579,6 +580,7 @@
X # PCMCIA character devices
X #
X # CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_MWAVE is not set
X
X #
X # Multimedia devices
@@ -703,6 +705,8 @@
X #
X # CONFIG_USB_DEVICEFS is not set
X # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_LARGE_CONFIG is not set
X
X #
X # USB Controllers
@@ -717,9 +721,13 @@
X # CONFIG_USB_BLUETOOTH is not set
X CONFIG_USB_STORAGE=y
X # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
X # CONFIG_USB_STORAGE_FREECOM is not set
X # CONFIG_USB_STORAGE_ISD200 is not set
X # CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
X # CONFIG_USB_ACM is not set
X # CONFIG_USB_PRINTER is not set
X
@@ -743,20 +751,18 @@
X #
X # USB Multimedia devices
X #
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
X
X #
X # USB Network adaptors
X #
X # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
X # CONFIG_USB_CATC is not set
X # CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_KAWETH is not set
X # CONFIG_USB_USBNET is not set
X
X #
@@ -768,9 +774,33 @@
X # USB Serial Converter support
X #
X # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
X
X #
-# USB misc drivers
+# USB Miscellaneous drivers
X #
X # CONFIG_USB_RIO500 is not set
X
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- v2.4.12/linux/arch/i386/kernel/apm.c Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/kernel/apm.c Fri Oct 19 08:32:28 2001
@@ -38,6 +38,7 @@
X * Jan 2000, Version 1.12
X * Feb 2000, Version 1.13
X * Nov 2000, Version 1.14
+ * Oct 2001, Version 1.15
X *
X * History:
X * 0.6b: first version in official kernel, Linux 1.3.46
@@ -157,7 +158,14 @@
X * Work around byte swap bug in one of the Vaio's BIOS's
X * (Marc Boucher <ma...@mbsi.ca>).
X * Exposed the disable flag to dmi so that we can handle known
- * broken APM (Alan Cox <al...@redhat.com>).
+ * broken APM (Alan Cox <al...@redhat.com>).
+ * 1.14ac: If the BIOS says "I slowed the CPU down" then don't spin
+ * calling it - instead idle. (Alan Cox <al...@redhat.com>)
+ * If an APM idle fails log it and idle sensibly
+ * 1.15: Don't queue events to clients who open the device O_WRONLY.
+ * Don't expect replies from clients who open the device O_RDONLY.
+ * (Idea from Thomas Hood <jdthood at yahoo.co.uk>)
+ * Minor waitqueue cleanups.(John Fremlin <ch...@bandits.org>)
X *
X * APM 1.1 Reference:
X *
@@ -222,8 +230,14 @@
X * Various options can be changed at boot time as follows:
X * (We allow underscores for compatibility with the modules code)
X * apm=on/off enable/disable APM
+ * [no-]allow[-_]ints allow interrupts during BIOS calls
+ * [no-]broken[-_]psr BIOS has a broken GetPowerStatus call
+ * [no-]realmode[-_]power[-_]off switch to real mode before
+ * powering off
X * [no-]debug log some debugging messages
X * [no-]power[-_]off power off on shutdown
+ * bounce[-_]interval=<n> number of ticks to ignore suspend
+ * bounces
X */
X
X /* KNOWN PROBLEM MACHINES:
@@ -308,6 +322,8 @@
X int magic;
X struct apm_user * next;
X int suser: 1;
+ int writer: 1;
+ int reader: 1;
X int suspend_wait: 1;
X int suspend_result;
X int suspends_pending;
@@ -372,8 +388,12 @@
X static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
X static struct apm_user * user_list;
X
-static char driver_version[] = "1.14"; /* no spaces */
+static char driver_version[] = "1.15"; /* no spaces */
X
+/*
+ * APM event names taken from the APM 1.2 specification. These are
+ * the message codes that the BIOS uses to tell us about events
+ */
X static char * apm_event_name[] = {
X "system standby",
X "system suspend",
@@ -396,6 +416,11 @@
X char * msg;
X } lookup_t;
X
+/*
+ * The BIOS returns a set of standard error codes in AX when the
+ * carry flag is set.
+ */
+
X static const lookup_t error_table[] = {
X /* N/A { APM_SUCCESS, "Operation succeeded" }, */
X { APM_DISABLED, "Power management disabled" },
@@ -419,7 +444,7 @@
X
X /*
X * These are the actual BIOS calls. Depending on APM_ZERO_SEGS and
- * CONFIG_APM_ALLOW_INTS, we are being really paranoid here! Not only
+ * apm_info.allow_ints, we are being really paranoid here! Not only
X * are interrupts disabled, but all the segment registers (except SS)
X * are saved and zeroed this means that if the BIOS tries to reference
X * any data without explicitly loading the segment registers, the kernel
@@ -465,6 +490,26 @@
X # define APM_DO_RESTORE_SEGS
X #endif
X
+/**
+ * apm_bios_call - Make an APM BIOS 32bit call
+ * @func: APM function to execute
+ * @ebx_in: EBX register for call entry
+ * @ecx_in: ECX register for call entry
+ * @eax: EAX register return
+ * @ebx: EBX register return
+ * @ecx: ECX register return
+ * @edx: EDX register return
+ * @esi: ESI register return
+ *
+ * Make an APM call using the 32bit protected mode interface. The
+ * caller is responsible for knowing if APM BIOS is configured and
+ * enabled. This call can disable interrupts for a long period of
+ * time on some laptops. The return value is in AH and the carry
+ * flag is loaded into AL. If there is an error, then the error
+ * code is returned in AH (bits 8-15 of eax) and this function
+ * returns non-zero.
+ */
+
X static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
X u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
X {
@@ -495,8 +540,18 @@
X return *eax & 0xff;
X }
X
-/*
- * This version only returns one value (usually an error code)
+/**
+ * apm_bios_call_simple - make a simple APM BIOS 32bit call
+ * @func: APM function to invoke
+ * @ebx_in: EBX register value for BIOS call
+ * @ecx_in: ECX register value for BIOS call
+ * @eax: EAX register on return from the BIOS call
+ *
+ * Make a BIOS call that does only returns one value, or just status.
+ * If there is an error, then the error code is returned in AH
+ * (bits 8-15 of eax) and this function returns non-zero. This is
+ * used for simpler BIOS operations. This call may hold interrupts
+ * off for a long time on some laptops.
X */
X
X static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
@@ -533,6 +588,22 @@
X return error;
X }
X
+/**
+ * apm_driver_version - APM driver version
+ * @val: loaded with the APM version on return
+ *
+ * Retrieve the APM version supported by the BIOS. This is only
+ * supported for APM 1.1 or higher. An error indicates APM 1.0 is
+ * probably present.
+ *
+ * On entry val should point to a value indicating the APM driver
+ * version with the high byte being the major and the low byte the
+ * minor number both in BCD
+ *
+ * On return it will hold the BIOS revision supported in the
+ * same format.
+ */
+
X static int __init apm_driver_version(u_short *val)
X {
X u32 eax;
@@ -543,6 +614,23 @@
X return APM_SUCCESS;
X }
X
+/**
+ * apm_get_event - get an APM event from the BIOS
+ * @event: pointer to the event
+ * @info: point to the event information
+ *
+ * The APM BIOS provides a polled information for event
+ * reporting. The BIOS expects to be polled at least every second
+ * when events are pending. When a message is found the caller should
+ * poll until no more messages are present. However, this causes
+ * problems on some laptops where a suspend event notification is
+ * not cleared until it is acknowledged.
+ *
+ * Additional information is returned in the info pointer, providing
+ * that APM 1.2 is in use. If no messges are pending the value 0x80
+ * is returned (No power management events pending).
+ */
+
X static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
X {
X u32 eax;
@@ -561,6 +649,20 @@
X return APM_SUCCESS;
X }
X
+/**
+ * set_power_state - set the power management state
+ * @what: which items to transition
+ * @state: state to transition to
+ *
+ * Request an APM change of state for one or more system devices. The
+ * processor state must be transitioned last of all. what holds the
+ * class of device in the upper byte and the device number (0xFF for
+ * all) for the object to be transitioned.
+ *
+ * The state holds the state to transition to, which may in fact
+ * be an acceptance of a BIOS requested state change.
+ */
+
X static int set_power_state(u_short what, u_short state)
X {
X u32 eax;
@@ -570,27 +672,59 @@
X return APM_SUCCESS;
X }
X
+/**
+ * apm_set_power_state - set system wide power state
+ * @state: which state to enter
+ *
+ * Transition the entire system into a new APM power state.
+ */
+
X static int apm_set_power_state(u_short state)
X {
X return set_power_state(APM_DEVICE_ALL, state);
X }
X
X #ifdef CONFIG_APM_CPU_IDLE
+
+/**
+ * apm_do_idle - perform power saving
+ *
+ * This function notifies the BIOS that the processor is (in the view
+ * of the OS) idle. It returns -1 in the event that the BIOS refuses
+ * to handle the idle request. On a success the function returns 1
+ * if the BIOS did clock slowing or 0 otherwise.
+ */
+
X static int apm_do_idle(void)
X {
- u32 dummy;
+ u32 eax;
+ int slowed;
X
- if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &dummy))
- return 0;
+ if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) {
+ static unsigned long t;
X
+ if (time_after(jiffies, t + 10 * HZ)) {
+ printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
+ (eax >> 8) & 0xff);
+ t = jiffies;
+ }
+ return -1;
+ }
+ slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
X #ifdef ALWAYS_CALL_BUSY
X clock_slowed = 1;
X #else
- clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
+ clock_slowed = slowed;
X #endif
- return 1;
+ return slowed;
X }
X
+/**
+ * apm_do_busy - inform the BIOS the CPU is busy
+ *
+ * Request that the BIOS brings the CPU back to full performance.
+ */
+
X static void apm_do_busy(void)
X {
X u32 dummy;
@@ -615,9 +749,16 @@
X /* This should wake up kapmd and ask it to slow the CPU */
X #define powermanagement_idle() do { } while (0)
X
-/*
- * This is the idle thing.
+/**
+ * apm_cpu_idle - cpu idling for APM capable Linux
+ *
+ * This is the idling function the kernel executes when APM is available. It
+ * tries to save processor time directly by using hlt instructions. A
+ * separate apm thread tries to do the BIOS power management.
+ *
+ * N.B. This is curently not used for kernels 2.4.x.
X */
+
X static void apm_cpu_idle(void)
X {
X unsigned int start_idle;
@@ -660,6 +801,16 @@
X }
X #endif
X
+/**
+ * apm_power_off - ask the BIOS to power off
+ *
+ * Handle the power off sequence. This is the one piece of code we
+ * will execute even on SMP machines. In order to deal with BIOS
+ * bugs we support real mode APM BIOS power off calls. We also make
+ * the SMP call on CPU0 as some systems will only honour this call
+ * on their first cpu.
+ */
+
X static void apm_power_off(void)
X {
X unsigned char po_bios_call[] = {
@@ -689,15 +840,23 @@
X (void) apm_set_power_state(APM_STATE_OFF);
X }
X
-/*
- * Magic sysrq key and handler for the power off function
+/**
+ * handle_poweroff - sysrq callback for power down
+ * @key: key pressed (unused)
+ * @pt_regs: register state (unused)
+ * @kbd: keyboard state (unused)
+ * @tty: tty involved (unused)
+ *
+ * When the user hits Sys-Rq o to power down the machine this is the
+ * callback we use.
X */
X
X void handle_poweroff (int key, struct pt_regs *pt_regs,
- struct kbd_struct *kbd, struct tty_struct *tty) {
- apm_power_off();
+ struct kbd_struct *kbd, struct tty_struct *tty) {
+ apm_power_off();
X }
-struct sysrq_key_op sysrq_poweroff_op = {
+
+struct sysrq_key_op sysrq_poweroff_op = {
X handler: handle_poweroff,
X help_msg: "Off",
X action_msg: "Power Off\n"
@@ -705,6 +864,14 @@
X
X
X #ifdef CONFIG_APM_DO_ENABLE
+
+/**
+ * apm_enable_power_management - enable BIOS APM power management
+ * @enable: enable yes/no
+ *
+ * Enable or disable the APM BIOS power services.
+ */
+
X static int apm_enable_power_management(int enable)
X {
X u32 eax;
@@ -722,6 +889,20 @@
X }
X #endif
X
+/**
+ * apm_get_power_status - get current power state
+ * @status: returned status
+ * @bat: battery info
+ * @life: estimated life
+ *
+ * Obtain the current power status from the APM BIOS. We return a
+ * status which gives the rough battery status, and current power
+ * source. The bat value returned give an estimate as a percentage
+ * of life and a status value for the battery. The estimated life
+ * if reported is a lifetime in secodnds/minutes at current powwer
+ * consumption.
+ */
+
X static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
X {
X u32 eax;
@@ -774,6 +955,15 @@
X }
X #endif
X
+/**
+ * apm_engage_power_management - enable PM on a device
+ * @device: identity of device
+ * @enable: on/off
+ *
+ * Activate or deactive power management on either a specific device
+ * or the entire system (%APM_DEVICE_ALL).
+ */
+
X static int apm_engage_power_management(u_short device, int enable)
X {
X u32 eax;
@@ -792,6 +982,15 @@
X return APM_SUCCESS;
X }
X
+/**
+ * apm_error - display an APM error
+ * @str: information string
+ * @err: APM BIOS return code
+ *
+ * Write a meaningful log entry to the kernel log in the event of
+ * an APM error.
+ */
+
X static void apm_error(char *str, int err)
X {
X int i;
@@ -806,6 +1005,17 @@
X }
X
X #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
+
+/**
+ * apm_console_blank - blank the display
+ * @blank: on/off
+ *
+ * Attempt to blank the console, firstly by blanking just video device
+ * zero, and if that fails (some BIOSes dont support it) then it blanks
+ * all video devices. Typically the BIOS will do laptop backlight and
+ * monitor powerdown for us.
+ */
+
X static int apm_console_blank(int blank)
X {
X int error;
@@ -846,7 +1056,7 @@
X if (user_list == NULL)
X return;
X for (as = user_list; as != NULL; as = as->next) {
- if (as == sender)
+ if ((as == sender) || (!as->reader))
X continue;
X as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
X if (as->event_head == as->event_tail) {
@@ -857,7 +1067,7 @@
X as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
X }
X as->events[as->event_head] = event;
- if (!as->suser)
+ if ((!as->suser) || (!as->writer))
X continue;
X switch (event) {
X case APM_SYS_SUSPEND:
@@ -932,7 +1142,9 @@
X /* map all suspends to ACPI D3 */
X if (pm_send_all(PM_SUSPEND, (void *)3)) {
X if (event == APM_CRITICAL_SUSPEND) {
- printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armageddon\n" );
+ printk(KERN_CRIT
+ "apm: Critical suspend was vetoed, "
+ "expect armageddon\n" );
X return 0;
X }
X if (apm_info.connection_version > 0x100)
@@ -1109,7 +1321,8 @@
X int err;
X
X if ((standbys_pending > 0) || (suspends_pending > 0)) {
- if ((apm_info.connection_version > 0x100) && (pending_count-- <= 0)) {
+ if ((apm_info.connection_version > 0x100) &&
+ (pending_count-- <= 0)) {
X pending_count = 4;
X if (debug)
X printk(KERN_DEBUG "apm: setting state busy\n");
@@ -1140,7 +1353,7 @@
X set_current_state(TASK_INTERRUPTIBLE);
X for (;;) {
X /* Nothing to do, just sleep for the timeout */
- timeout = 2*timeout;
+ timeout = 2 * timeout;
X if (timeout > APM_CHECK_TIMEOUT)
X timeout = APM_CHECK_TIMEOUT;
X schedule_timeout(timeout);
@@ -1156,10 +1369,21 @@
X #ifdef CONFIG_APM_CPU_IDLE
X if (!system_idle())
X continue;
- if (apm_do_idle()) {
+
+ /*
+ * If we can idle...
+ */
+ if (apm_do_idle() != -1) {
X unsigned long start = jiffies;
X while ((!exit_kapmd) && system_idle()) {
- apm_do_idle();
+ if (apm_do_idle()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ /* APM needs us to snooze .. either
+ the BIOS call failed (-1) or it
+ slowed the clock (1). We sleep
+ until it talks to us again */
+ schedule_timeout(1);
+ }
X if ((jiffies - start) > APM_CHECK_TIMEOUT) {
X apm_event_handler();
X start = jiffies;
@@ -1188,26 +1412,15 @@
X struct apm_user * as;
X int i;
X apm_event_t event;
- DECLARE_WAITQUEUE(wait, current);
X
X as = fp->private_data;
X if (check_apm_user(as, "read"))
X return -EIO;
X if (count < sizeof(apm_event_t))
X return -EINVAL;
- if (queue_empty(as)) {
- if (fp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- add_wait_queue(&apm_waitqueue, &wait);
-repeat:
- set_current_state(TASK_INTERRUPTIBLE);
- if (queue_empty(as) && !signal_pending(current)) {
- schedule();
- goto repeat;
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_waitqueue, &wait);
- }
+ if ((queue_empty(as)) && (fp->f_flags & O_NONBLOCK))
+ return -EAGAIN;
+ wait_event_interruptible(apm_waitqueue, !queue_empty(as));
X i = count;
X while ((i >= sizeof(event)) && !queue_empty(as)) {
X event = get_queued_event(as);
@@ -1254,7 +1467,6 @@
X u_int cmd, u_long arg)
X {
X struct apm_user * as;
- DECLARE_WAITQUEUE(wait, current);
X
X as = filp->private_data;
X if (check_apm_user(as, "ioctl"))
@@ -1288,16 +1500,8 @@
X return -EIO;
X } else {
X as->suspend_wait = 1;
- add_wait_queue(&apm_suspend_waitqueue, &wait);
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if ((as->suspend_wait == 0)
- || signal_pending(current))
- break;
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_suspend_waitqueue, &wait);
+ wait_event_interruptible(apm_suspend_waitqueue,
+ as->suspend_wait == 0);
X return as->suspend_result;
X }
X break;
@@ -1367,6 +1571,8 @@
X * privileged operation -- cevans
X */
X as->suser = capable(CAP_SYS_ADMIN);
+ as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
+ as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
X as->next = user_list;
X user_list = as;
X filp->private_data = as;
@@ -1562,7 +1768,7 @@
X /* Install our power off handler.. */
X if (power_off)
X pm_power_off = apm_power_off;
- register_sysrq_key('o',&sysrq_poweroff_op);
+ register_sysrq_key('o', &sysrq_poweroff_op);
X
X if (smp_num_cpus == 1) {
X #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
@@ -1588,15 +1794,9 @@
X apm_disabled = 1;
X if (strncmp(str, "on", 2) == 0)
X apm_disabled = 0;
- if ((strncmp(str, "allow-ints", 10) == 0) ||
- (strncmp(str, "allow_ints", 10) == 0))
- apm_info.allow_ints = 1;
- if ((strncmp(str, "broken-psr", 10) == 0) ||
- (strncmp(str, "broken_psr", 10) == 0))
- apm_info.get_power_status_broken = 1;
- if ((strncmp(str, "realmode-power-off", 18) == 0) ||
- (strncmp(str, "realmode_power_off", 18) == 0))
- apm_info.realmode_power_off = 1;
+ if ((strncmp(str, "bounce-interval=", 16) == 0) ||
+ (strncmp(str, "bounce_interval=", 16) == 0))
+ bounce_interval = simple_strtol(str + 16, NULL, 0);
X invert = (strncmp(str, "no-", 3) == 0);
X if (invert)
X str += 3;
@@ -1605,9 +1805,15 @@
X if ((strncmp(str, "power-off", 9) == 0) ||
X (strncmp(str, "power_off", 9) == 0))
X power_off = !invert;
- if ((strncmp(str, "bounce-interval=", 16) == 0) ||
- (strncmp(str, "bounce_interval=", 16) == 0))
- bounce_interval = simple_strtol(str + 16, NULL, 0);
+ if ((strncmp(str, "allow-ints", 10) == 0) ||
+ (strncmp(str, "allow_ints", 10) == 0))
+ apm_info.allow_ints = !invert;
+ if ((strncmp(str, "broken-psr", 10) == 0) ||
+ (strncmp(str, "broken_psr", 10) == 0))
+ apm_info.get_power_status_broken = !invert;
+ if ((strncmp(str, "realmode-power-off", 18) == 0) ||
+ (strncmp(str, "realmode_power_off", 18) == 0))
+ apm_info.realmode_power_off = !invert;
X str = strchr(str, ',');
X if (str != NULL)
X str += strspn(str, ", \t");
@@ -1791,15 +1997,20 @@
X
X MODULE_AUTHOR("Stephen Rothwell");
X MODULE_DESCRIPTION("Advanced Power Management");
+MODULE_LICENSE("GPL");
X MODULE_PARM(debug, "i");
X MODULE_PARM_DESC(debug, "Enable debug mode");
X MODULE_PARM(power_off, "i");
X MODULE_PARM_DESC(power_off, "Enable power off");
X MODULE_PARM(bounce_interval, "i");
-MODULE_PARM_DESC(bounce_interval, "Set the number of ticks to ignore suspend bounces");
+MODULE_PARM_DESC(bounce_interval,
+ "Set the number of ticks to ignore suspend bounces");
X MODULE_PARM(allow_ints, "i");
X MODULE_PARM_DESC(allow_ints, "Allow interrupts during BIOS calls");
X MODULE_PARM(broken_psr, "i");
X MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
+MODULE_PARM(realmode_power_off, "i");
+MODULE_PARM_DESC(realmode_power_off,
+ "Switch to real mode before powering off");
X
X EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- v2.4.12/linux/arch/i386/kernel/bluesmoke.c Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/bluesmoke.c Thu Oct 11 09:04:57 2001
@@ -6,6 +6,8 @@
X #include <asm/processor.h>
X #include <asm/msr.h>
X
+static int mce_disabled __initdata = 0;
+
X /*
X * Machine Check Handler For PII/PIII
X */
@@ -111,7 +113,7 @@
X * Set up machine check reporting for Intel processors
X */
X
-void __init intel_mcheck_init(struct cpuinfo_x86 *c)
+static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
X {
X u32 l, h;
X int i;
@@ -130,6 +132,9 @@
X
X if(c->x86 == 5)
X {
+ /* Default P5 to off as its often misconnected */
+ if(mce_disabled != -1)
+ return;
X machine_check_vector = pentium_machine_check;
X wmb();
X /* Read registers before enabling */
@@ -137,11 +142,8 @@
X rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
X if(done==0)
X printk(KERN_INFO "Intel old style machine check architecture supported.\n");
- /* Enable MCE */
- __asm__ __volatile__ (
- "movl %%cr4, %%eax\n\t"
- "orl $0x40, %%eax\n\t"
- "movl %%eax, %%cr4\n\t" : : : "eax");
+ /* Enable MCE */
+ set_in_cr4(X86_CR4_MCE);
X printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
X return;
X }
@@ -195,10 +197,7 @@
X lo|= (1<<2); /* Enable EIERRINT (int 18 MCE) */
X lo&= ~(1<<4); /* Enable MCE */
X wrmsr(MSR_IDT_FCR1, lo, hi);
- __asm__ __volatile__ (
- "movl %%cr4, %%eax\n\t"
- "orl $0x40, %%eax\n\t"
- "movl %%eax, %%cr4\n\t" : : : "eax");
+ set_in_cr4(X86_CR4_MCE);
X printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id());
X }
X
@@ -208,11 +207,10 @@
X */
X
X
-static int mce_disabled = 0;
X
X void __init mcheck_init(struct cpuinfo_x86 *c)
X {
- if(mce_disabled)
+ if(mce_disabled==1)
X return;
X
X switch(c->x86_vendor)
@@ -230,6 +228,8 @@
X case X86_VENDOR_CENTAUR:
X winchip_mcheck_init(c);
X break;
+ default:
+ break;
X }
X }
X
@@ -238,4 +238,12 @@
X mce_disabled = 1;
X return 0;
X }
+
+static int __init mcheck_enable(char *str)
+{
+ mce_disabled = -1;


+ return 0;
+}
+

X __setup("nomce", mcheck_disable);
+__setup("mce", mcheck_enable);
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/cpuid.c linux/arch/i386/kernel/cpuid.c
--- v2.4.12/linux/arch/i386/kernel/cpuid.c Sun Aug 12 13:27:58 2001
+++ linux/arch/i386/kernel/cpuid.c Thu Oct 11 09:04:57 2001
@@ -163,3 +163,4 @@
X
X MODULE_AUTHOR("H. Peter Anvin <h...@zytor.com>");
X MODULE_DESCRIPTION("x86 generic CPUID driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- v2.4.12/linux/arch/i386/kernel/dmi_scan.c Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/dmi_scan.c Thu Oct 11 13:47:17 2001
@@ -10,6 +10,8 @@
X #include <linux/keyboard.h>
X #include <asm/keyboard.h>
X
+int is_sony_vaio_laptop;
+
X struct dmi_header
X {
X u8 type;
@@ -322,8 +324,6 @@
X * This one isn't a bug detect for those who asked, we simply want to
X * activate Sony specific goodies like the camera and jogdial..
X */
-int is_sony_vaio_laptop;
-
X static __init int sony_vaio_laptop(struct dmi_blacklist *d)
X {
X if (is_sony_vaio_laptop == 0)
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.4.12/linux/arch/i386/kernel/entry.S Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/kernel/entry.S Wed Oct 17 10:02:39 2001
@@ -621,6 +621,7 @@
X .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
X .long SYMBOL_NAME(sys_ni_syscall) /* Reserved for Security */
X .long SYMBOL_NAME(sys_gettid)
+ .long SYMBOL_NAME(sys_readahead) /* 225 */
X
X .rept NR_syscalls-(.-sys_call_table)/4
X .long SYMBOL_NAME(sys_ni_syscall)
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.4.12/linux/arch/i386/kernel/i386_ksyms.c Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/i386_ksyms.c Thu Oct 11 13:47:50 2001
@@ -170,8 +170,5 @@
X EXPORT_SYMBOL(do_BUG);
X #endif
X
-#if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE)
X extern int is_sony_vaio_laptop;
X EXPORT_SYMBOL(is_sony_vaio_laptop);
-#endif
-
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c
--- v2.4.12/linux/arch/i386/kernel/ldt.c Sun Aug 12 13:27:58 2001
+++ linux/arch/i386/kernel/ldt.c Wed Oct 17 14:46:29 2001
@@ -45,6 +45,25 @@


X return err;
X }
X

+static int read_default_ldt(void * ptr, unsigned long bytecount)
+{
+ int err;
+ unsigned long size;
+ void *address;
+
+ err = 0;
+ address = &default_ldt[0];
+ size = sizeof(struct desc_struct);
+ if (size > bytecount)
+ size = bytecount;
+
+ err = size;
+ if (copy_to_user(ptr, address, size))
+ err = -EFAULT;


+
+ return err;
+}
+

X static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
X {
X struct mm_struct * mm = current->mm;
@@ -139,6 +158,9 @@
X break;
X case 1:
X ret = write_ldt(ptr, bytecount, 1);
+ break;
+ case 2:
+ ret = read_default_ldt(ptr, bytecount);
X break;
X case 0x11:
X ret = write_ldt(ptr, bytecount, 0);
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c
--- v2.4.12/linux/arch/i386/kernel/microcode.c Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/microcode.c Thu Oct 11 09:04:57 2001
@@ -65,6 +65,7 @@
X
X MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
X MODULE_AUTHOR("Tigran Aivazian <tig...@veritas.com>");


+MODULE_LICENSE("GPL");
X EXPORT_NO_SYMBOLS;
X

X #define MICRO_DEBUG 0
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/msr.c linux/arch/i386/kernel/msr.c
--- v2.4.12/linux/arch/i386/kernel/msr.c Sun Aug 12 13:27:58 2001
+++ linux/arch/i386/kernel/msr.c Thu Oct 11 09:04:57 2001
@@ -271,3 +271,4 @@
X
X MODULE_AUTHOR("H. Peter Anvin <h...@zytor.com>");
X MODULE_DESCRIPTION("x86 generic MSR driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.4.12/linux/arch/i386/kernel/mtrr.c Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/mtrr.c Mon Oct 15 13:43:24 2001
@@ -1253,7 +1253,8 @@
X break;
X
X case MTRR_IF_INTEL:
- /* For Intel PPro stepping <= 7, must be 4 MiB aligned */
+ /* For Intel PPro stepping <= 7, must be 4 MiB aligned
+ and not touch 0x70000000->0x7003FFFF */
X if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
X boot_cpu_data.x86 == 6 &&
X boot_cpu_data.x86_model == 1 &&
@@ -1264,6 +1265,12 @@
X printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
X return -EINVAL;
X }
+ if (!(base + size < 0x70000000 || base > 0x7003FFFF) &&
+ (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK))
+ {
+ printk (KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
+ return -EINVAL;
+ }
X }
X /* Fall through */
X
@@ -2119,10 +2126,8 @@
X break;
X
X case X86_VENDOR_CENTAUR:
- /* Cyrix III has Intel style MTRRs, but doesn't support PAE */
- if (boot_cpu_data.x86 == 6 &&
- (boot_cpu_data.x86_model == 6 ||
- boot_cpu_data.x86_model == 7)) {
+ /* VIA Cyrix family have Intel style MTRRs, but don't support PAE */
+ if (boot_cpu_data.x86 == 6) {
X size_or_mask = 0xfff00000; /* 32 bits */
X size_and_mask = 0;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- v2.4.12/linux/arch/i386/kernel/pci-irq.c Wed Jul 25 17:10:17 2001
+++ linux/arch/i386/kernel/pci-irq.c Mon Oct 15 19:30:33 2001
@@ -458,6 +458,8 @@
X { "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
X { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
X pirq_serverworks_get, pirq_serverworks_set },
+ { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5,
+ pirq_serverworks_get, pirq_serverworks_set },
X { "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
X pirq_amd756_get, pirq_amd756_set },
X
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.12/linux/arch/i386/kernel/setup.c Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/kernel/setup.c Mon Oct 15 13:43:24 2001
@@ -1604,7 +1604,7 @@
X
X case 6:
X switch (c->x86_model) {
- case 6 ... 7: /* Cyrix III or C3 */
+ case 6 ... 8: /* Cyrix III family */
X rdmsr (MSR_VIA_FCR, lo, hi);
X lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */
X wrmsr (MSR_VIA_FCR, lo, hi);
diff -u --recursive --new-file v2.4.12/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.4.12/linux/arch/i386/kernel/smp.c Tue Oct 9 17:06:51 2001
+++ linux/arch/i386/kernel/smp.c Tue Oct 23 14:17:10 2001
@@ -507,10 +507,9 @@
X atomic_t started;
X atomic_t finished;
X int wait;
-} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
+};
X
X static struct call_data_struct * call_data;
-static struct call_data_struct call_data_array[NR_CPUS];
X
X /*
X * this function sends a 'generic call function' IPI to all other CPUs
@@ -532,45 +531,33 @@
X * hardware interrupt handler, you may call it from a bottom half handler.
X */
X {
- struct call_data_struct *data;
- int cpus = (cpu_online_map & ~(1 << smp_processor_id()));
+ struct call_data_struct data;
+ int cpus = smp_num_cpus-1;
X
X if (!cpus)
X return 0;
X
- data = &call_data_array[smp_processor_id()];
-
- data->func = func;
- data->info = info;
- data->wait = wait;
+ data.func = func;
+ data.info = info;
+ atomic_set(&data.started, 0);
+ data.wait = wait;
X if (wait)
- atomic_set(&data->finished, 0);
- /* We have do to this one last to make sure that the IPI service
- * code desn't get confused if it gets an unexpected repeat
- * trigger of an old IPI while we're still setting up the new
- * one. */
- atomic_set(&data->started, 0);
-
- local_bh_disable();
- spin_lock(&call_lock);
- call_data = data;
+ atomic_set(&data.finished, 0);
+
+ spin_lock_bh(&call_lock);
+ call_data = &data;
+ wmb();
X /* Send a message to all other CPUs and wait for them to respond */
X send_IPI_allbutself(CALL_FUNCTION_VECTOR);
X
X /* Wait for response */
- while (atomic_read(&data->started) != cpus)
+ while (atomic_read(&data.started) != cpus)
X barrier();
X
- /* It is now safe to reuse the "call_data" global, but we need
- * to keep local bottom-halves disabled until after waiters have
- * been acknowledged to prevent reuse of the per-cpu call data
- * entry. */
- spin_unlock(&call_lock);
-
X if (wait)
- while (atomic_read(&data->finished) != cpus)
+ while (atomic_read(&data.finished) != cpus)
X barrier();
- local_bh_enable();
+ spin_unlock_bh(&call_lock);


X
X return 0;
X }

@@ -620,17 +607,18 @@
X
X ack_APIC_irq();
X /*
- * Notify initiating CPU that I've grabbed the data and am about
- * to execute the function (and avoid servicing any single IPI
- * twice)
+ * Notify initiating CPU that I've grabbed the data and am
+ * about to execute the function
X */
- if (test_and_set_bit(smp_processor_id(), &call_data->started))
- return;
+ mb();
+ atomic_inc(&call_data->started);
X /*
X * At this point the info structure may be out of scope unless wait==1
X */
X (*func)(info);
- if (wait)
- set_bit(smp_processor_id(), &call_data->finished);
+ if (wait) {
+ mb();
+ atomic_inc(&call_data->finished);
+ }
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/ia64/config.in linux/arch/ia64/config.in
--- v2.4.12/linux/arch/ia64/config.in Sun Aug 12 13:27:58 2001
+++ linux/arch/ia64/config.in Mon Oct 15 13:42:14 2001
@@ -149,7 +149,7 @@
X source drivers/mtd/Config.in
X source drivers/pnp/Config.in
X source drivers/block/Config.in
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
X source drivers/md/Config.in
X
X mainmenu_option next_comment
diff -u --recursive --new-file v2.4.12/linux/arch/ia64/sn/io/pci_dma.c linux/arch/ia64/sn/io/pci_dma.c
--- v2.4.12/linux/arch/ia64/sn/io/pci_dma.c Thu Apr 12 12:16:35 2001
+++ linux/arch/ia64/sn/io/pci_dma.c Fri Oct 12 15:35:53 2001
@@ -182,7 +182,7 @@
X }
X
X /*
- * On sn1 we use the alt_address entry of the scatterlist to store
+ * On sn1 we use the orig_address entry of the scatterlist to store
X * the physical address corresponding to the given virtual address
X */
X int
diff -u --recursive --new-file v2.4.12/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.4.12/linux/arch/mips/config.in Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/config.in Mon Oct 15 13:41:34 2001
@@ -377,7 +377,7 @@
X
X if [ "$CONFIG_DECSTATION" != "y" -a \
X "$CONFIG_SGI_IP22" != "y" ]; then
- source drivers/i2o/Config.in
+ source drivers/message/i2o/Config.in
X fi
X
X if [ "$CONFIG_NET" = "y" ]; then
diff -u --recursive --new-file v2.4.12/linux/arch/parisc/kernel/ccio-dma.c linux/arch/parisc/kernel/ccio-dma.c
--- v2.4.12/linux/arch/parisc/kernel/ccio-dma.c Fri Feb 9 11:29:44 2001
+++ linux/arch/parisc/kernel/ccio-dma.c Fri Oct 12 15:35:53 2001
@@ -638,7 +638,7 @@
X }
X
X
-static int ccio_dma_supported( struct pci_dev *dev, dma_addr_t mask)
+static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
X {
X if (dev == NULL) {
X printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
diff -u --recursive --new-file v2.4.12/linux/arch/parisc/kernel/ccio-rm-dma.c linux/arch/parisc/kernel/ccio-rm-dma.c
--- v2.4.12/linux/arch/parisc/kernel/ccio-rm-dma.c Tue Dec 5 12:29:39 2000
+++ linux/arch/parisc/kernel/ccio-rm-dma.c Fri Oct 12 15:35:53 2001
@@ -93,7 +93,7 @@
X }
X
X
-static int ccio_dma_supported( struct pci_dev *dev, dma_addr_t mask)
+static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
X {
X if (dev == NULL) {
X printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
diff -u --recursive --new-file v2.4.12/linux/arch/parisc/kernel/pci-dma.c linux/arch/parisc/kernel/pci-dma.c
--- v2.4.12/linux/arch/parisc/kernel/pci-dma.c Fri Feb 9 11:29:44 2001
+++ linux/arch/parisc/kernel/pci-dma.c Fri Oct 12 15:35:53 2001
@@ -77,7 +77,7 @@
X static inline void dump_resmap(void) {;}
X #endif
X
-static int pa11_dma_supported( struct pci_dev *dev, dma_addr_t mask)
+static int pa11_dma_supported( struct pci_dev *dev, u64 mask)
X {
X return 1;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/parisc/kernel/sba_iommu.c linux/arch/parisc/kernel/sba_iommu.c
--- v2.4.12/linux/arch/parisc/kernel/sba_iommu.c Fri Feb 9 11:29:44 2001
+++ linux/arch/parisc/kernel/sba_iommu.c Fri Oct 12 15:35:53 2001
@@ -779,7 +779,7 @@
X }
X
X static int
-sba_dma_supported( struct pci_dev *dev, dma_addr_t mask)
+sba_dma_supported( struct pci_dev *dev, u64 mask)
X {
X if (dev == NULL) {
X printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/8xx_io/Config.in linux/arch/ppc/8xx_io/Config.in
--- v2.4.12/linux/arch/ppc/8xx_io/Config.in Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/8xx_io/Config.in Mon Oct 15 13:35:26 2001
@@ -33,7 +33,4 @@
X bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
X bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
X
-if [ "$CONFIG_IDE" = "y" ]; then
- bool 'MPC8xx direct IDE support on PCMCIA port' CONFIG_BLK_DEV_MPC8xx_IDE
-fi
X endmenu
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c
--- v2.4.12/linux/arch/ppc/8xx_io/enet.c Tue Oct 9 17:06:51 2001
+++ linux/arch/ppc/8xx_io/enet.c Wed Oct 17 14:37:01 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.enet.c 1.15 09/14/01 18:01:16 trini
+ * BK Id: SCCS/s.enet.c 1.17 10/11/01 11:55:47 trini
X */
X /*
X * Ethernet driver for Motorola MPC8xx.
@@ -147,7 +147,7 @@
X static int scc_enet_open(struct net_device *dev);
X static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
X static int scc_enet_rx(struct net_device *dev);
-static void scc_enet_interrupt(void *dev_id);
+static void scc_enet_interrupt(void *dev_id, struct pt_regs *regs);
X static int scc_enet_close(struct net_device *dev);
X static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
X static void set_multicast_list(struct net_device *dev);
@@ -303,7 +303,7 @@
X * This is called from the CPM handler, not the MPC core interrupt.
X */
X static void
-scc_enet_interrupt(void *dev_id)
+scc_enet_interrupt(void *dev_id, struct pt_regs *regs)
X {
X struct net_device *dev = dev_id;
X volatile struct scc_enet_private *cep;
@@ -805,22 +805,10 @@
X ep->sen_iaddr4 = 0;
X
X /* Set Ethernet station address.
- *
- * If we performed a MBX diskless boot, the Ethernet controller
- * has been initialized and we copy the address out into our
- * own structure.
- *
- * All other types of boards supply the address in the board
- * information structure, so we copy that into the controller.
X */
X eap = (unsigned char *)&(ep->sen_paddrh);
-#ifndef CONFIG_MBX
X for (i=5; i>=0; i--)
X *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
-#else
- for (i=5; i>=0; i--)
- dev->dev_addr[i] = *eap++;
-#endif
X
X ep->sen_pper = 0; /* 'cause the book says so */
X ep->sen_taddrl = 0; /* temp address (LSB) */
@@ -943,6 +931,14 @@
X immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
X #endif
X
+#ifdef CONFIG_FADS
+ cp->cp_pbpar |= PB_ENET_TENA;
+ cp->cp_pbdir |= PB_ENET_TENA;
+
+ /* Enable the EEST PHY.
+ */
+ *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
+#endif
X
X dev->base_addr = (unsigned long)ep;
X dev->priv = cep;
@@ -970,5 +966,3 @@


X
X return 0;
X }

-
-
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c
--- v2.4.12/linux/arch/ppc/8xx_io/fec.c Tue Oct 9 17:06:51 2001
+++ linux/arch/ppc/8xx_io/fec.c Wed Oct 17 14:37:01 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.fec.c 1.18 09/22/01 09:12:32 trini
+ * BK Id: SCCS/s.fec.c 1.20 10/11/01 11:55:47 trini
X */
X /*
X * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
@@ -868,6 +868,8 @@
X *s |= PHY_STAT_FAULT;
X if (mii_reg & 0x0020)
X *s |= PHY_STAT_ANC;
+
+ fep->link = (*s & PHY_STAT_LINK) ? 1 : 0;
X }
X
X static void mii_parse_cr(uint mii_reg, struct net_device *dev)
@@ -1650,11 +1652,11 @@
X #endif
X
X #ifdef PHY_INTERRUPT
- if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
- panic("Could not allocate MII IRQ!");
-
X ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
X (0x80000000 >> PHY_INTERRUPT);
+
+ if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
+ panic("Could not allocate MII IRQ!");
X #endif
X
X dev->base_addr = (unsigned long)fecp;
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.4.12/linux/arch/ppc/Makefile Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/Makefile Thu Oct 11 09:04:57 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.21 08/19/01 20:06:47 paulus
+# BK Id: SCCS/s.Makefile 1.23 09/18/01 11:19:05 paulus
X #
X # This file is included by the global makefile so that you can add your own
X # architecture-specific flags and dependencies. Remember to do have actions
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.4.12/linux/arch/ppc/amiga/config.c Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/amiga/config.c Thu Oct 11 09:04:57 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.config.c 1.7 05/21/01 00:48:24 cort
+ * BK Id: SCCS/s.config.c 1.12 09/18/01 11:19:06 paulus
X */
X #define m68k_debug_device debug_device
X
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/boot/prep/misc.c linux/arch/ppc/boot/prep/misc.c
--- v2.4.12/linux/arch/ppc/boot/prep/misc.c Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/boot/prep/misc.c Mon Oct 15 13:35:26 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.misc.c 1.18 07/30/01 17:19:40 trini
+ * BK Id: SCCS/s.misc.c 1.20 09/24/01 18:42:54 trini
X *
X * arch/ppc/boot/prep/misc.c
X *
@@ -47,6 +47,15 @@
X RESIDUAL hold_resid_buf;
X RESIDUAL *hold_residual = &hold_resid_buf;
X unsigned long initrd_start = 0, initrd_end = 0;
+
+/* These values must be variables. If not, the compiler optimizer
+ * will remove some code, causing the size of the code to vary
+ * when these values are zero. This is bad because we first
+ * compile with these zero to determine the size and offsets
+ * in an image, than compile again with these set to the proper
+ * discovered value.
+ */
+unsigned int initrd_offset, initrd_size;
X char *zimage_start;
X int zimage_size;
X
@@ -302,12 +311,14 @@
X size of the elf header which we strip -- Cort */
X zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
X zimage_size = ZIMAGE_SIZE;
+ initrd_offset = INITRD_OFFSET;
+ initrd_size = INITRD_SIZE;
X
- if ( INITRD_OFFSET )
- initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
+ if ( initrd_offset )
+ initrd_start = load_addr - 0x10000 + initrd_offset;
X else
X initrd_start = 0;
- initrd_end = INITRD_SIZE + initrd_start;
+ initrd_end = initrd_size + initrd_start;
X
X /*
X * Find a place to stick the zimage and initrd and
@@ -332,9 +343,9 @@
X puts(" "); puthex(initrd_end); puts("\n");
X avail_ram = (char *)PAGE_ALIGN(
X (unsigned long)zimage_size+(unsigned long)zimage_start);
- memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
+ memcpy ((void *)avail_ram, (void *)initrd_start, initrd_size );
X initrd_start = (unsigned long)avail_ram;
- initrd_end = initrd_start + INITRD_SIZE;
+ initrd_end = initrd_start + initrd_size;
X puts("relocated to: "); puthex(initrd_start);
X puts(" "); puthex(initrd_end); puts("\n");
X }
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 06'
echo 'File patch-2.4.13 is continued in part 07'
echo "07" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:37 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part07

#!/bin/sh -x
# this is part 07 of a 53 - part archive


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

if test "$Scheck" != 07; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

--- v2.4.12/linux/arch/ppc/kernel/m8xx_setup.c Tue Oct 9 17:06:51 2001
+++ linux/arch/ppc/kernel/m8xx_setup.c Wed Oct 17 14:37:01 2001


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

- * BK Id: SCCS/s.m8xx_setup.c 1.32 09/27/01 09:01:12 trini
+ * BK Id: SCCS/s.m8xx_setup.c 1.35 10/11/01 11:55:47 trini
X *
X * linux/arch/ppc/kernel/setup.c
X *
@@ -52,7 +52,7 @@
X
X unsigned char __res[sizeof(bd_t)];
X
-extern void m8xx_ide_init();
+extern void m8xx_ide_init(void);
X
X #ifdef CONFIG_BLK_DEV_RAM
X extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
@@ -164,9 +164,9 @@
X ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
X ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
X ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
+ ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
+ ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
+ ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
X
X /* Disable the RTC one second and alarm interrupts. */
X ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.4.12/linux/arch/ppc/kernel/prep_pci.c Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/prep_pci.c Mon Oct 15 13:35:26 2001


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

- * BK Id: SCCS/s.prep_pci.c 1.26 09/08/01 15:47:42 paulus
+ * BK Id: SCCS/s.prep_pci.c 1.31 10/05/01 17:48:18 trini
X */
X /*
X * PReP pci functions.
@@ -33,15 +33,15 @@
X
X /* Which PCI interrupt line does a given device [slot] use? */
X /* Note: This really should be two dimensional based in slot/pin used */
-unsigned char *Motherboard_map;
+static unsigned char *Motherboard_map;
X unsigned char *Motherboard_map_name;
X
X /* How is the 82378 PIRQ mapping setup? */
-unsigned char *Motherboard_routes;
+static unsigned char *Motherboard_routes;
X
-void (*Motherboard_non0)(struct pci_dev *);
+static void (*Motherboard_non0)(struct pci_dev *);
X
-void Powerplus_Map_Non0(struct pci_dev *);
+static void Powerplus_Map_Non0(struct pci_dev *);
X
X /* Used for Motorola to store system config register */
X static unsigned long *ProcInfo;
@@ -474,16 +474,17 @@
X 0, /* Slot 21 - */
X 2, /* Slot 22 - */
X };
+
X static char ibm6015_pci_IRQ_routes[] __prepdata = {
X 0, /* Line 0 - unused */
X 13, /* Line 1 */
- 10, /* Line 2 */
+ 15, /* Line 2 */
X 15, /* Line 3 */
X 15, /* Line 4 */
X };
X
X
-/* IBM Nobis and 850 */
+/* IBM Nobis and Thinkpad 850 */
X static char Nobis_pci_IRQ_map[23] __prepdata ={
X 0, /* Slot 0 - unused */
X 0, /* Slot 1 - unused */
@@ -564,7 +565,7 @@
X * are routed to OpenPIC inputs 5-8. These values are offset by
X * 16 in the table to reflect the Linux kernel interrupt value.
X */
-struct powerplus_irq_list Powerplus_pci_IRQ_list =
+struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
X {
X {25, 26, 27, 28},
X {21, 22, 23, 24}
@@ -577,7 +578,7 @@
X * are routed to OpenPIC inputs 12-15. These values are offset by
X * 16 in the table to reflect the Linux kernel interrupt value.
X */
-struct powerplus_irq_list Mesquite_pci_IRQ_list =
+struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
X {
X {24, 25, 26, 27},
X {28, 29, 30, 31}
@@ -587,7 +588,7 @@
X * This table represents the standard PCI swizzle defined in the
X * PCI bus specification.
X */
-static unsigned char prep_pci_intpins[4][4] =
+static unsigned char prep_pci_intpins[4][4] __prepdata =
X {
X { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */
X { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */
@@ -600,8 +601,6 @@
X * other than hard-coded as well... IRQ's are individually mappable
X * to either edge or level.
X */
-#define CAROLINA_IRQ_EDGE_MASK_LO 0x00 /* IRQ's 0-7 */
-#define CAROLINA_IRQ_EDGE_MASK_HI 0xA4 /* IRQ's 8-15 [10,13,15] */
X
X /*
X * 8259 edge/level control definitions
@@ -694,7 +693,8 @@
X int MotMPIC;
X int mot_multi;
X
-int __init raven_init(void)
+int __init
+raven_init(void)
X {
X unsigned int devid;
X unsigned int pci_membase;
@@ -776,7 +776,7 @@
X void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
X struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
X unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
-} mot_info[] = {
+} mot_info[] __prepdata = {
X {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
X {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
X {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
@@ -805,7 +805,8 @@
X {0x000, 0x00, 0x00, "", NULL, NULL, NULL, NULL, 0x00}
X };
X
-void ibm_prep_init(void)
+void __init
+ibm_prep_init(void)
X {
X u32 addr;
X #ifdef CONFIG_PREP_RESIDUAL
@@ -828,13 +829,12 @@
X #ifdef CONFIG_PREP_RESIDUAL
X mpic = residual_find_device(-1, NULL, SystemPeripheral,
X ProgrammableInterruptController, MPIC, 0);
- if (mpic != NULL) {
+ if (mpic != NULL)
X printk("mpic = %p\n", mpic);
- }
X #endif
X }
X
-void
+static void __init
X ibm43p_pci_map_non0(struct pci_dev *dev)
X {
X unsigned char intpin;
@@ -850,7 +850,8 @@
X pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
X }
X
-void __init prep_route_pci_interrupts(void)
+void __init
+prep_route_pci_interrupts(void)
X {
X unsigned char *ibc_pirq = (unsigned char *)0x80800860;
X unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
@@ -913,68 +914,65 @@
X /* AJF adjust level/edge control according to routes */
X irq_mode = 0;
X for (i = 1; i <= 4; i++)
- {
X irq_mode |= ( 1 << Motherboard_routes[i] );
- }
X outb( irq_mode & 0xff, 0x4d0 );
X outb( (irq_mode >> 8) & 0xff, 0x4d1 );
X }
- } else if ( _prep_type == _PREP_IBM )
- {
- unsigned char pl_id;
- /*
- * my carolina is 0xf0
- * 6015 has 0xfc
- * -- Cort
- */
- printk("IBM ID: %08x\n", inb(0x0852));
- switch(inb(0x0852))
- {
+ } else if ( _prep_type == _PREP_IBM ) {
+ unsigned char planar_id = inb(0x0852);
+ unsigned char irq_edge_mask_lo, irq_edge_mask_hi;
+
+ printk("IBM ID: %08x\n", planar_id);
+ switch(planar_id) {
X case 0xff:
- Motherboard_map_name = "IBM 850/860 Portable";
+ Motherboard_map_name = "IBM Thinkpad 850/860";
X Motherboard_map = Nobis_pci_IRQ_map;
X Motherboard_routes = Nobis_pci_IRQ_routes;
+ irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+ irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
X break;
X case 0xfc:
- Motherboard_map_name = "IBM 6015";
+ Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";
X Motherboard_map = ibm6015_pci_IRQ_map;
X Motherboard_routes = ibm6015_pci_IRQ_routes;
+ irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+ irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
X break;
X case 0xd5:
- Motherboard_map_name = "IBM 43p/140";
+ Motherboard_map_name = "IBM 43P-140 (Tiger1)";
X Motherboard_map = ibm43p_pci_IRQ_map;
X Motherboard_routes = ibm43p_pci_IRQ_routes;
X Motherboard_non0 = ibm43p_pci_map_non0;
+ irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+ irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
X break;
X default:
- Motherboard_map_name = "IBM 8xx (Carolina)";
+ printk(KERN_ERR "Unknown IBM motherboard! Defaulting to Carolina.\n");
+ case 0xf0: /* PowerSeries 830/850 */
+ case 0xf1: /* PowerSeries 830/850 */
+ case 0xf2: /* PowerSeries 830/850 */
+ case 0xf4: /* 7248-43P */
+ case 0xf5: /* 7248-43P */
+ case 0xf6: /* 7248-43P */
+ case 0xf7: /* 7248-43P (missing from Carolina Tech Spec) */
+ Motherboard_map_name = "IBM PS830/PS850/7248 (Carolina)";
X Motherboard_map = ibm8xx_pci_IRQ_map;
X Motherboard_routes = ibm8xx_pci_IRQ_routes;
+ irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+ irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */
X break;
X }
X
- /*printk("Changing IRQ mode\n");*/
- pl_id=inb(0x04d0);
- /*printk("Low mask is %#0x\n", pl_id);*/
- outb(pl_id|CAROLINA_IRQ_EDGE_MASK_LO, 0x04d0);
-
- pl_id=inb(0x04d1);
- /*printk("Hi mask is %#0x\n", pl_id);*/
- outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1);
- pl_id=inb(0x04d1);
- /*printk("Hi mask now %#0x\n", pl_id);*/
- }
- else
- {
+ outb(inb(0x04d0)|irq_edge_mask_lo, 0x04d0); /* primary 8259 */
+ outb(inb(0x04d1)|irq_edge_mask_hi, 0x04d1); /* cascaded 8259 */
+ } else {
X printk("No known machine pci routing!\n");
X return;
X }
X
X /* Set up mapping from slots */
X for (i = 1; i <= 4; i++)
- {
X ibc_pirq[i-1] = Motherboard_routes[i];
- }
X /* Enable PCI interrupts */
X *ibc_pcicon |= 0x20;
X }
@@ -1039,14 +1037,14 @@
X pci_write_config_byte(dev,
X PCI_INTERRUPT_LINE,
X dev->irq);
- }else{
+ } else {
X /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */
X pci_write_config_dword(dev, 0x40, 0x10ff08a1);
X }
X }
X }
X
-void
+static void __init
X Powerplus_Map_Non0(struct pci_dev *dev)
X {
X struct pci_bus *pbus; /* Parent bus structure pointer */
@@ -1092,23 +1090,19 @@
X * Otherwise, assume it's a PMC site and get the interrupt line
X * value from the interrupt routing table.
X */
- if (mot_info[mot_entry].secondary_bridge_devfn)
- {
+ if (mot_info[mot_entry].secondary_bridge_devfn) {
X pbus = dev->bus;
X
X while (pbus->primary != 0)
X pbus = pbus->parent;
X
- if ((pbus->self)->devfn != 0xA0)
- {
+ if ((pbus->self)->devfn != 0xA0) {
X if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn)
X intline = mot_info[mot_entry].pci_irq_list->secondary[intpin];
- else
- {
+ else {
X if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map)
X intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16;
- else
- {
+ else {
X int i;
X for (i=0;i<3;i++)
X intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
@@ -1137,13 +1131,10 @@
X if (OpenPIC_Addr) {
X /* PCI interrupts are controlled by the OpenPIC */
X pci_for_each_dev(dev) {
- if (dev->bus->number == 0)
- {
+ if (dev->bus->number == 0) {
X dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
X pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_LINE, dev->irq);
- }
- else
- {
+ } else {
X if (Motherboard_non0 != NULL)
X Motherboard_non0(dev);
X }
@@ -1164,26 +1155,26 @@
X unsigned char d = PCI_SLOT(dev->devfn);
X dev->irq = Motherboard_routes[Motherboard_map[d]];
X
- for ( i = 0 ; i <= 5 ; i++ )
- {
+ for ( i = 0 ; i <= 5 ; i++ ) {
X /*
X * Relocate PCI I/O resources if necessary so the
X * standard 256MB BAT covers them.
X */
X if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) &&
- (dev->resource[i].start > 0x10000000) )
- {
- printk("Relocating PCI address %lx -> %lx\n",
- dev->resource[i].start,
- (dev->resource[i].start & 0x00FFFFFF)
- | 0x01000000);
- dev->resource[i].start =
- (dev->resource[i].start & 0x00FFFFFF) | 0x01000000;
+ (dev->resource[i].start > 0x10000000)) {
+ printk("Relocating PCI address %lx -> %lx\n",
+ dev->resource[i].start,
+ (dev->resource[i].start &
+ 0x00FFFFFF)| 0x01000000);
+ dev->resource[i].start =
+ (dev->resource[i].start & 0x00FFFFFF)
+ | 0x01000000;
X pci_write_config_dword(dev,
- PCI_BASE_ADDRESS_0+(i*0x4),
- dev->resource[i].start );
- dev->resource[i].end =
- (dev->resource[i].end & 0x00FFFFFF) | 0x01000000;
+ PCI_BASE_ADDRESS_0 + (i*0x4),
+ dev->resource[i].start);
+ dev->resource[i].end =
+ (dev->resource[i].end & 0x00FFFFFF)
+ | 0x01000000;
X }
X }
X #if 0
@@ -1223,7 +1214,8 @@
X hose->first_busno = 0;
X hose->last_busno = 0xff;
X hose->pci_mem_offset = PREP_ISA_MEM_BASE;
- hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
+ hose->io_base_phys = PREP_ISA_IO_BASE;
+ hose->io_base_virt = (void *)0x80000000; /* see prep_map_io() */
X prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO);
X prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,
X IORESOURCE_MEM);
@@ -1241,25 +1233,17 @@
X pkt = PnP_find_large_vendor_packet(
X res->DevicePnPHeap+hostbridge->AllocatedOffset,
X 3, 0);
- if(pkt)
- {
+ if(pkt) {
X #define p pkt->L4_Pack.L4_Data.L4_PPCPack
X setup_indirect_pci(hose,
X ld_le32((unsigned *) (p.PPCData)),
X ld_le32((unsigned *) (p.PPCData+8)));
- }
- else
- {
+ } else
X setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);
- }
- }
- else
+ } else
X #endif /* CONFIG_PREP_RESIDUAL */
- {
X hose->ops = &prep_pci_ops;
- }
X }
X
X ppc_md.pcibios_fixup = prep_pcibios_fixup;
X }
-
diff -u --recursive --new-file v2.4.12/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.4.12/linux/arch/ppc/kernel/prep_setup.c Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/prep_setup.c Mon Oct 15 13:35:26 2001


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

- * BK Id: SCCS/s.prep_setup.c 1.36 09/08/01 15:47:42 paulus
+ * BK Id: SCCS/s.prep_setup.c 1.38 09/15/01 09:13:52 trini
X */
X /*
X * linux/arch/ppc/kernel/setup.c
@@ -840,8 +840,8 @@
X */
X void __init prep_map_io(void)
X {
- io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
- io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO);
+ io_block_mapping(0x80000000, PREP_ISA_IO_BASE, 0x10000000, _PAGE_IO);
+ io_block_mapping(0xf0000000, PREP_ISA_MEM_BASE, 0x08000000, _PAGE_IO);


X }
X
X void __init

diff -u --recursive --new-file v2.4.12/linux/arch/s390/Makefile linux/arch/s390/Makefile
--- v2.4.12/linux/arch/s390/Makefile Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/Makefile Thu Oct 11 09:04:57 2001
@@ -55,16 +55,6 @@
X
X MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
X
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:
- @$(MAKESILO) silo
-
-dasdfmt:
- @$(MAKEDASDFMT) dasdfmt
-
X image: vmlinux
X @$(MAKEBOOT) image
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/Makefile linux/arch/s390/kernel/Makefile
--- v2.4.12/linux/arch/s390/kernel/Makefile Wed Apr 11 19:02:27 2001
+++ linux/arch/s390/kernel/Makefile Thu Oct 11 09:04:57 2001
@@ -15,7 +15,7 @@
X O_TARGET := kernel.o
X
X export-objs := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
-obj-y := lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \
+obj-y := entry.o bitmap.o traps.o time.o process.o irq.o \
X setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
X semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/debug.c linux/arch/s390/kernel/debug.c
--- v2.4.12/linux/arch/s390/kernel/debug.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/debug.c Thu Oct 11 09:04:57 2001
@@ -83,6 +83,9 @@
X static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
X struct file *file, const char *user_buf,
X size_t user_buf_size, loff_t * offset);
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+ struct file *file, const char *user_buf,
+ size_t user_buf_size, loff_t * offset);
X static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
X char *out_buf, const char *in_buf);
X static int debug_raw_format_fn(debug_info_t * id,
@@ -123,6 +126,15 @@
X NULL
X };
X
+struct debug_view debug_flush_view = {
+ "flush",
+ NULL,
+ NULL,
+ NULL,
+ &debug_input_flush_fn,
+ NULL
+};
+
X struct debug_view debug_sprintf_view = {
X "sprintf",
X NULL,
@@ -664,6 +676,7 @@
X if(!rc)
X goto out;
X debug_register_view(rc, &debug_level_view);
+ debug_register_view(rc, &debug_flush_view);
X printk(KERN_INFO
X "debug: reserved %d areas of %d pages for debugging %s\n",
X nr_areas, 1 << page_order, rc->name);
@@ -1027,6 +1040,73 @@
X out:
X *offset += in_buf_size;
X return rc; /* number of input characters */
+}
+
+
+/*
+ * flushes debug areas
+ */
+
+void debug_flush(debug_info_t* id, int area)


+{
+ unsigned long flags;

+ int i;
+
+ if(!id)
+ return;
+ spin_lock_irqsave(&id->lock,flags);
+ if(area == DEBUG_FLUSH_ALL){
+ id->active_area = 0;
+ memset(id->active_entry, 0, id->nr_areas * sizeof(int));
+ for (i = 0; i < id->nr_areas; i++)
+ memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+ printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
+ } else if(area >= 0 && area < id->nr_areas) {
+ id->active_entry[area] = 0;
+ memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
+ printk(KERN_INFO
+ "debug: %s: area %i has been flushed\n",
+ id->name, area);
+ } else {
+ printk(KERN_INFO
+ "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+ id->name, area, 0, id->nr_areas-1);
+ }
+ spin_unlock_irqrestore(&id->lock,flags);
+}
+
+/*
+ * view function: flushes debug areas
+ */
+
+static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+ struct file *file, const char *user_buf,
+ size_t in_buf_size, loff_t * offset)
+{
+ char input_buf[1];
+ int rc = in_buf_size;
+
+ if (*offset != 0)
+ goto out;
+ if (copy_from_user(input_buf, user_buf, 1)){
+ rc = -EFAULT;
+ goto out;
+ }
+ if(input_buf[0] == '-') {
+ debug_flush(id, DEBUG_FLUSH_ALL);
+ goto out;
+ }
+ if (isdigit(input_buf[0])) {
+ int area = ((int) input_buf[0] - (int) '0');
+ debug_flush(id, area);
+ goto out;
+ }
+
+ printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
+
+ out:
+ *offset += in_buf_size;
+ return rc; /* number of input characters */
X }
X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- v2.4.12/linux/arch/s390/kernel/entry.S Tue Oct 9 17:06:51 2001
+++ linux/arch/s390/kernel/entry.S Thu Oct 11 09:04:57 2001
@@ -97,17 +97,27 @@
X * R15 - kernel stack pointer
X */
X
- .macro SAVE_ALL psworg # system entry macro
+ .macro SAVE_ALL psworg,sync # system entry macro
X stm %r13,%r15,__LC_SAVE_AREA
- stam %a2,%a4,__LC_SAVE_AREA+12
X basr %r13,0 # temp base pointer
X l %r13,.Lentry_base-.(%r13) # load &entry_base to %r13
X tm \psworg+1,0x01 # test problem state bit
- bz BASED(.+12) # skip stack setup save
- l %r15,__LC_KERNEL_STACK # problem state -> load ksp
- lam %a2,%a4,BASED(.Lc_ac) # set ac.reg. 2 to primary space
- # and access reg. 4 to home space
-0: s %r15,BASED(.Lc_spsize) # make room for registers & psw
+ stam %a2,%a4,__LC_SAVE_AREA+12
+ .if \sync
+ bz BASED(1f) # skip stack setup save
+ .else
+ bnz BASED(0f) # from user -> load kernel stack
+ l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
+ slr %r14,%r15
+ sra %r14,13
+ be BASED(1f)
+ l %r15,__LC_ASYNC_STACK # load async. stack
+ b BASED(1f)
+ .endif
+0: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ lam %a2,%a4,BASED(.Lc_ac) # set ac.reg. 2 to primary space
+ # and ac.reg. 4 to home space
+1: s %r15,BASED(.Lc_spsize) # make room for registers & psw
X n %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
X stm %r0,%r12,SP_R0(%r15) # store gprs 0-12 to kernel stack
X st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
@@ -120,7 +130,7 @@
X xc 0(4,%r15),0(%r15) # clear back chain
X .endm
X
- .macro RESTORE_ALL # system exit macro
+ .macro RESTORE_ALL sync # system exit macro
X mvc __LC_RETURN_PSW(8),SP_PSW(%r15) # move user PSW to lowcore
X lam %a0,%a15,SP_AREGS(%r15) # load the access registers
X lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
@@ -129,8 +139,8 @@
X .endm
X
X .macro GET_CURRENT
- lr %r9,%r15 # load pointer to task_struct to %r9
- n %r9,BASED(.Lc0xffffe000)
+ l %r9,BASED(.Lc0xffffe000) # load pointer to task_struct to %r9
+ al %r9,__LC_KERNEL_STACK
X .endm
X
X
@@ -171,13 +181,35 @@
X br %r14
X
X /*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+ .global do_call_softirq
+do_call_softirq:
+ stm %r12,%r15,24(%r15)
+ lr %r12,%r15
+ basr %r13,0
+do_call_base:
+ l %r0,__LC_ASYNC_STACK
+ slr %r0,%r15
+ sra %r0,13
+ be 0f-do_call_base(%r13)
+ l %r15,__LC_ASYNC_STACK
+0: sl %r15,.Lc_overhead-do_call_base(%r13)
+ st %r12,0(%r15) # store backchain
+ l %r1,.Ldo_softirq-do_call_base(%r13)
+ basr %r14,%r1
+ lm %r12,%r15,24(%r12)
+ br %r14
+
+/*
X * SVC interrupt handler routine. System calls are synchronous events and
X * are executed with interrupts enabled.
X */
X
X .globl system_call
X system_call:
- SAVE_ALL __LC_SVC_OLD_PSW
+ SAVE_ALL __LC_SVC_OLD_PSW,1
X mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid
X pgm_system_call:
X GET_CURRENT # load pointer to task_struct to R9
@@ -207,7 +239,7 @@
X tm SP_PGM_OLD_ILC(%r15),0xff
X bz BASED(pgm_svcret)
X stnsm 24(%r15),0xfc # disable I/O and ext. interrupts
- RESTORE_ALL
+ RESTORE_ALL 1
X
X #
X # call do_signal before return
@@ -557,7 +589,10 @@
X .long sys_madvise
X .long sys_getdents64 /* 220 */
X .long sys_fcntl64
- .rept 255-221
+ .long sys_ni_syscall /* 222 - reserved for posix_acl */
+ .long sys_ni_syscall /* 223 - reserved for posix_acl */
+ .long sys_ni_syscall /* 224 - reserved for posix_acl */
+ .rept 255-224
X .long sys_ni_syscall
X .endr
X
@@ -581,10 +616,10 @@
X * for LPSW?).
X */
X stm %r13,%r15,__LC_SAVE_AREA
- stam %a2,%a4,__LC_SAVE_AREA+12
X basr %r13,0 # temp base pointer
X l %r13,.Lentry_base-.(%r13)# load &entry_base to %r13
X tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
+ stam %a2,%a4,__LC_SAVE_AREA+12
X bz BASED(pgm_sv) # skip if not
X tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
X bnz BASED(pgm_sv) # skip if it is
@@ -677,7 +712,7 @@
X
X .globl io_int_handler
X io_int_handler:
- SAVE_ALL __LC_IO_OLD_PSW
+ SAVE_ALL __LC_IO_OLD_PSW,0
X GET_CURRENT # load pointer to task_struct to R9
X la %r2,SP_PTREGS(%r15) # address of register-save area
X sr %r3,%r3
@@ -710,7 +745,7 @@
X bnz BASED(io_signal_return)
X io_leave:
X stnsm 24(%r15),0xfc # disable I/O and ext. interrupts
- RESTORE_ALL
+ RESTORE_ALL 0
X
X #
X # call do_softirq
@@ -744,7 +779,7 @@
X
X .globl ext_int_handler
X ext_int_handler:
- SAVE_ALL __LC_EXT_OLD_PSW
+ SAVE_ALL __LC_EXT_OLD_PSW,0
X GET_CURRENT # load pointer to task_struct to R9
X la %r2,SP_PTREGS(%r15) # address of register-save area
X lh %r3,__LC_EXT_INT_CODE # error code
@@ -772,11 +807,11 @@
X
X .globl mcck_int_handler
X mcck_int_handler:
- SAVE_ALL __LC_MCK_OLD_PSW
+ SAVE_ALL __LC_MCK_OLD_PSW,0
X l %r1,BASED(.Ls390_mcck)
X basr %r14,%r1 # call machine check handler
X mcck_return:
- RESTORE_ALL
+ RESTORE_ALL 0
X
X #ifdef CONFIG_SMP
X /*
@@ -784,7 +819,7 @@
X */
X .globl restart_int_handler
X restart_int_handler:
- l %r15,__LC_KERNEL_STACK # load ksp
+ l %r15,__LC_SAVE_AREA+60 # load ksp
X lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
X lam %a0,%a15,__LC_AREGS_SAVE_AREA
X stosm 0(%r15),0x04 # now we can turn dat on
@@ -817,6 +852,7 @@
X .Lc0xffffe000: .long -8192 # to round stack pointer to &task_struct
X .Lc8191: .long 8191
X .Lc_spsize: .long SP_SIZE
+.Lc_overhead: .long STACK_FRAME_OVERHEAD
X .Lc_ac: .long 0,0,1
X .Lc_ENOSYS: .long -ENOSYS
X .Lc4: .long 4
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/gdb-stub.c linux/arch/s390/kernel/gdb-stub.c
--- v2.4.12/linux/arch/s390/kernel/gdb-stub.c Fri May 12 11:41:44 2000
+++ linux/arch/s390/kernel/gdb-stub.c Thu Oct 11 09:04:57 2001
@@ -65,7 +65,8 @@
X * $m0,10#2a +$00010203040506070809101112131415#42
X *
X */
-
+#define TRUE 1
+#define FALSE 0
X #include <asm/gdb-stub.h>
X #include <linux/string.h>
X #include <linux/kernel.h>
@@ -74,14 +75,15 @@
X #include <linux/mm.h>
X #include <asm/pgtable.h>
X #include <asm/system.h>
+#include <linux/stddef.h>
X
+#define S390_REGS_COMMON_SIZE offsetof(struct gdb_pt_regs,orig_gpr2)
X
X /*
X * external low-level support routines
X */
X
-extern int putDebugChar(char c); /* write a single character */
-extern char getDebugChar(void); /* read and return a single char */
+
X extern void fltr_set_mem_err(void);
X extern void trap_low(void);
X
@@ -247,8 +249,10 @@
X
X while (count-- > 0) {
X ch = *(mem++);
+#if 0
X if (mem_err)
X return 0;
+#endif
X *buf++ = hexchars[ch >> 4];
X *buf++ = hexchars[ch & 0xf];
X }
@@ -276,8 +280,10 @@
X ch = hex(*buf++) << 4;
X ch |= hex(*buf++);
X *(mem++) = ch;
+#if 0
X if (mem_err)
X return 0;
+#endif
X }
X
X /* set_mem_fault_trap(0); */
@@ -349,7 +355,7 @@
X return (numChars);
X }
X
-void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_get_non_pt_regs(struct gdb_pt_regs *regs)
X {
X s390_fp_regs *fpregs=&regs->fp_regs;
X int has_ieee=save_fp_regs1(fpregs);


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

X }
X
-void gdb_stub_set_non_pt_regs(gdb_pt_regs *regs)
+void gdb_stub_set_non_pt_regs(struct gdb_pt_regs *regs)
X {
X restore_fp_regs1(&regs->fp_regs);
X }
@@ -390,7 +396,7 @@
X * returns 1 if you should skip the instruction at the trap address, 0
X * otherwise.
X */
-void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
+void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval)
X {
X int trap; /* Trap type */
X int addr;
@@ -402,19 +408,23 @@
X /*
X * reply to host that an exception has occurred
X */
+#if 0
X send_signal(sigval);
-
+#endif
X /*
X * Wait for input from remote GDB
X */
- while (1) {
+ while (1)
+ {
X output_buffer[0] = 0;
X getpacket(input_buffer);
X
X switch (input_buffer[0])
X {
X case '?':
+#if 0
X send_signal(sigval);
+#endif
X continue;
X
X case 'd':
@@ -427,9 +437,9 @@
X case 'g':
X gdb_stub_get_non_pt_regs(regs);
X ptr = output_buffer;
- ptr= mem2hex((char *)regs,ptr,sizeof(s390_regs_common),FALSE);
+ ptr= mem2hex((char *)regs,ptr,S390_REGS_COMMON_SIZE,FALSE);
X ptr= mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
- ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs));
+ ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs),FALSE);
X break;
X
X /*
@@ -438,11 +448,11 @@
X */
X case 'G':
X ptr=input_buffer;
- hex2mem (ptr, (char *)regs,sizeof(s390_regs_common), FALSE);
- ptr+=sizeof(s390_regs_common)*2;
+ hex2mem (ptr, (char *)regs,S390_REGS_COMMON_SIZE, FALSE);
+ ptr+=S390_REGS_COMMON_SIZE*2;
X hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
X ptr+=NUM_CRS*CR_SIZE*2;
- hex2mem (ptr, (char *)regs->fp_regs,sizeof(s390_fp_regs), FALSE);
+ hex2mem (ptr, (char *)&regs->fp_regs,sizeof(s390_fp_regs), FALSE);
X gdb_stub_set_non_pt_regs(regs);
X strcpy(output_buffer,"OK");
X break;
@@ -472,7 +482,8 @@
X if (hexToInt(&ptr, &addr)
X && *ptr++ == ','
X && hexToInt(&ptr, &length)
- && *ptr++ == ':') {
+ && *ptr++ == ':')
+ {
X if (hex2mem(ptr, (char *)addr, length, 1))
X strcpy(output_buffer, "OK");
X else
@@ -490,8 +501,7 @@
X
X ptr = &input_buffer[1];
X if (hexToInt(&ptr, &addr))
- regs->cp0_epc = addr;
-
+ regs->psw.addr = addr;
X /*
X * Need to flush the instruction cache here, as we may
X * have deposited a breakpoint, and the icache probably
@@ -529,22 +539,22 @@
X * There is no single step insn in the MIPS ISA, so we
X * use breakpoints and continue, instead.
X */
+#if 0
X single_step(regs);
+#endif
X flush_cache_all();
X return;
X /* NOTREACHED */
+ break;
X
- }
- break;
-
- } /* switch */
-
- /*
- * reply to the request
- */
+ } /* switch */
X
+ /*
+ * reply to the request
+ */
+
X putpacket(output_buffer);
-
+
X } /* while */
X }
X
@@ -558,13 +568,9 @@
X {
X if (!gdb_stub_initialised)
X return;
- __asm__ __volatile__(
- ".globl breakinst\n"
- "breakinst:\t.word %0\n\t"
- :
- : "i" (S390_BREAKPOINT_U16)
- :
- );
+ asm volatile (".globl breakinst\n"
+ "breakinst:\t.word %0"
+ : : "i" (S390_BREAKPOINT_U16) );
X }
X
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/head.S linux/arch/s390/kernel/head.S
--- v2.4.12/linux/arch/s390/kernel/head.S Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/head.S Thu Oct 11 09:04:57 2001
@@ -461,28 +461,52 @@
X .org 0x10000
X startup:basr %r13,0 # get base
X .LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
- la %r12,parmarea-.LPG1(%r13) # pointer to parameter area
+ la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
X # move IPL device to lowcore
X mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
X
X #
-# find out memory size.
+# find memory chunks.
X #
X mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
- lhi %r2,1
- sll %r2,17 # test in increments of 128KB
- lr %r1,%r2
- ahi %r1,-4 # test last word in the segment
-.Lloop:
- l %r0,0(%r1) # test 128KB segment
- st %r0,0(%r1)
- ar %r1,%r2 # add 128KB
- bnm .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
-.Lchkmem:
- n %r1,.L4malign-.LPG1(%r13) # align to multiples of 4M
- l %r2,.Lmemsize-.LPG1(%r13) # address of variable memory_size
- st %r1,0(%r2) # store memory size
-
+ la %r1,1 # test in increments of 128KB
+ sll %r1,17
+ l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
+ slr %r4,%r4 # set start of chunk to zero
+ slr %r5,%r5 # set end of chunk to zero
+ slr %r6,%r6 # set access code to zero
+.Lloop:
+ tprot 0(%r5),0 # test protection of first byte
+ ipm %r7
+ srl %r7,28
+ clr %r6,%r7 # compare cc with last access code
+ be .Lsame-.LPG1(%r13)
+ clr %r4,%r5 # chunk size > 0?
+ be .Lsize0-.LPG1(%r13)
+ st %r4,0(%r3) # store start address of chunk
+ lr %r0,%r5
+ slr %r0,%r4
+ st %r0,4(%r3) # store size of chunk
+ st %r6,8(%r3) # store type of chunk
+ la %r3,12(%r3)
+ lr %r4,%r5 # set start to end
+.Lsize0:
+ lr %r6,%r7 # set access code to last cc
+.Lsame:
+ ar %r5,%r1 # add 128KB to end of chunk
+ bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
+.Lchkmem: # > 2GB or tprot got a program check
+ clr %r4,%r5 # chunk size > 0?
+ be .Ldonemem-.LPG1(%r13)
+ st %r4,0(%r3) # store start address of chunk
+ lr %r0,%r5
+ slr %r0,%r4
+ st %r0,4(%r3) # store size of chunk
+ st %r6,8(%r3) # store type of chunk
+.Ldonemem:
+ l %r1,.Lmemsize-.LPG1(%r13) # address of variable memory_size
+ st %r5,0(%r1) # store last end to memory size
+
X l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
X #
X # find out if we are running under VM
@@ -534,7 +558,7 @@
X .Lentry:.long 0x00080000,0x80000000 + _stext
X .Lctl: .long 0x04b50002 # cr0: various things
X .long 0 # cr1: primary space segment table
- .long 0 # cr2: access register translation
+ .long .Lduct # cr2: dispatchable unit control table
X .long 0 # cr3: instruction authorization
X .long 0 # cr4: instruction authorization
X .long 0 # cr5: various things
@@ -552,47 +576,50 @@
X .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
X .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
X .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.L4malign:.long 0xffc00000
X .Lmemsize:.long memory_size
+.Lmchunk:.long memory_chunk
X .Lmflags:.long machine_flags
X
+ .org PARMAREA-64
+.Lduct: .long 0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0
+
X #
X # params at 10400 (setup.h)
X #
X .org PARMAREA
-parmarea:
+ .global _pstart
+_pstart:
X .long 0,0 # IPL_DEVICE
X .long 0,RAMDISK_ORIGIN # INITRD_START
- .long 0,0x800000 # INITRD_SIZE
+ .long 0,RAMDISK_SIZE # INITRD_SIZE
X
X .org COMMAND_LINE
X .byte "root=/dev/ram0 ro"
X .byte 0
+ .org 0x11000
+ .global _pend
+_pend:
X
-#
-# startup-code, running in virtual mode
-#
X #ifdef CONFIG_SHARED_KERNEL
X .org 0x100000
-#else
- .org 0x10800
X #endif
+
+#
+# startup-code, running in virtual mode
+#
X .globl _stext
X _stext: basr %r13,0 # get base
X .LPG2:
X #
-# Setup lowcore
+# Setup stack
X #
- l %r1,__LC_IPLDEV # load ipl device number
- spx .Lprefix-.LPG2(%r13) # set prefix to linux lowcore
- st %r1,__LC_IPLDEV # store ipl device number
X l %r15,.Linittu-.LPG2(%r13)
- ahi %r15,8192 # init_task_union + 8191
+ ahi %r15,8192 # init_task_union + 8192
X st %r15,__LC_KERNEL_STACK # set end of kernel stack
X ahi %r15,-96
X xc 0(4,%r15),0(%r15) # set backchain to zero
- lhi %r0,-1
- st %r0,__LC_KERNEL_LEVEL # set interrupt count to -1
+
X #
X # clear bss memory
X #
@@ -622,7 +649,6 @@
X #
X .align 8
X .Ldw: .long 0x000a0000,0x00000000
-.Lprefix: .long init_S390_lowcore
X .Linittu: .long init_task_union
X .Lstart: .long start_kernel
X .Lbss_bgn: .long __bss_start
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/lowcore.S linux/arch/s390/kernel/lowcore.S
--- v2.4.12/linux/arch/s390/kernel/lowcore.S Fri May 12 11:41:44 2000
+++ linux/arch/s390/kernel/lowcore.S Wed Dec 31 16:00:00 1969
@@ -1,60 +0,0 @@
-/*
- * arch/s390/kernel/lowcore.S
- * S390 lowcore definition.
- *
- * S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Hartmut Penner (h...@de.ibm.com)
- * Martin Schwidefsky (schwi...@de.ibm.com),
- */
-
-#include <asm/lowcore.h>
- .align 4096
- .globl init_S390_lowcore
-init_S390_lowcore:
- .long _RESTART_PSW_MASK
- .long restart_int_handler + _ADDR_31
- .long 0,0
- .long 0,0
-EXT_OLD: .long 0,0
-SVC_OLD: .long 0,0
-PGM_OLD: .long 0,0
-MCCK_OLD:.long 0,0
-IO_OLD: .long 0,0
- .long 0,0,0,0,0,0
-#
-# new psws need all to be physical
-# because we start with dat off
-#
-EXT_PSW: .long _EXT_PSW_MASK
- .long ext_int_handler + _ADDR_31
-#
-SVC_PSW: .long _SVC_PSW_MASK
- .long system_call + _ADDR_31
-#
-PGM_PSW: .long _PGM_PSW_MASK
- .long pgm_check_handler + _ADDR_31
-#
-MCCK_PSW:.long _MCCK_PSW_MASK
- .long mcck_int_handler + _ADDR_31
-#
-IO_PSW: .long _IO_PSW_MASK
- .long io_int_handler + _ADDR_31
-#
-#
-#
-EXTERNAL_PARAMETER: .long 0
-CPU_ADDRESS: .word 0
-EXT_INTERRUPT_CODE: .word 0
-SVC_ILC: .word 0
-SVC_CODE: .word 0
-PGM_ILC: .word 0
-PGM_CODE: .word 0
-TRANS_EXC_ADDR: .long 0 # 090
- .fill 0xC00-0x094,1,0
-SAVE_AREA: .fill 0x40,1,0 # C00
-KERNEL_STACK: .long 0 # C40
-KERNEL_LEVEL: .long 0 # C44
-CPUID: .long 0,0 # C48
- .fill 0x1000-0xC50,1,0
-
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
--- v2.4.12/linux/arch/s390/kernel/process.c Tue Oct 9 17:06:51 2001
+++ linux/arch/s390/kernel/process.c Thu Oct 11 09:04:57 2001
@@ -44,8 +44,6 @@
X #include <asm/processor.h>
X #include <asm/irq.h>
X
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
X asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
X
X /*
@@ -209,7 +207,7 @@
X void show_regs(struct pt_regs *regs)
X {
X char buff[80];
- int line;
+ int i, line;
X
X printk("CPU: %d\n",smp_processor_id());
X printk("Process %s (pid: %d, stackpage=%08X)\n",
@@ -217,6 +215,17 @@
X
X for (line = 0; sprintf_regs(line, buff, current, regs); line++)
X printk(buff);
+
+ if (regs->psw.mask & PSW_PROBLEM_STATE)
+ {
+ printk("User Code:\n");
+ memset(buff, 0, 20);
+ copy_from_user(buff,
+ (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+ for (i = 0; i < 20; i++)
+ printk("%02x ", buff[i]);
+ printk("\n");
+ }
X }
X
X char *task_show_regs(struct task_struct *task, char *buffer)
@@ -324,28 +333,19 @@
X
X asmlinkage int sys_fork(struct pt_regs regs)
X {
- int ret;
-
- lock_kernel();
- ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
- unlock_kernel();
- return ret;
+ return do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
X }
X
X asmlinkage int sys_clone(struct pt_regs regs)
X {
X unsigned long clone_flags;
X unsigned long newsp;
- int ret;
X
- lock_kernel();
X clone_flags = regs.gprs[3];
X newsp = regs.orig_gpr2;
X if (!newsp)
X newsp = regs.gprs[15];
- ret = do_fork(clone_flags, newsp, &regs, 0);
- unlock_kernel();
- return ret;
+ return do_fork(clone_flags, newsp, &regs, 0);
X }
X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/s390_ksyms.c linux/arch/s390/kernel/s390_ksyms.c
--- v2.4.12/linux/arch/s390/kernel/s390_ksyms.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/s390_ksyms.c Thu Oct 11 09:04:57 2001
@@ -15,11 +15,11 @@
X /*
X * memory management
X */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
X
X /*
X * semaphore ops
@@ -56,10 +56,7 @@
X EXPORT_SYMBOL(csum_fold);
X EXPORT_SYMBOL(console_mode);
X EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
X
-#if CONFIG_IP_MULTICAST
-/* Required for lcs gigabit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
X
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/setup.c linux/arch/s390/kernel/setup.c
--- v2.4.12/linux/arch/s390/kernel/setup.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/setup.c Thu Oct 11 09:04:57 2001
@@ -47,6 +47,9 @@
X unsigned int console_device = -1;
X unsigned long memory_size = 0;
X unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
X __u16 boot_cpu_addr;
X int cpus_initialized = 0;
X unsigned long cpu_initialized = 0;
@@ -258,6 +261,8 @@
X * Setup function called from init/main.c just after the banner
X * was printed.
X */
+extern char _pstart, _pend, _stext;
+
X void __init setup_arch(char **cmdline_p)
X {
X unsigned long bootmap_size;
@@ -267,19 +272,14 @@
X unsigned long start_pfn, end_pfn;
X static unsigned int smptrap=0;
X unsigned long delay = 0;
+ struct _lowcore *lowcore;
+ int i;
X
X if (smptrap)
X return;
X smptrap=1;
X
X /*
- * Setup lowcore information for boot cpu
- */
- cpu_init();
- boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
- __cpu_logical_map[0] = boot_cpu_addr;
-
- /*
X * print what head.S has found out about the machine
X */
X printk((MACHINE_IS_VM) ?
@@ -291,7 +291,7 @@
X
X ROOT_DEV = to_kdev_t(0x0100);
X memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/
- memory_end = memory_size;
+ memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
X /*
X * We need some free virtual space to be able to do vmalloc.
X * On a machine with 2GB memory we make sure that we have at
@@ -373,10 +373,25 @@
X bootmap_size = init_bootmem(start_pfn, end_pfn);
X
X /*
- * Register RAM pages with the bootmem allocator.
+ * Register RAM areas with the bootmem allocator.
X */
- free_bootmem(start_pfn << PAGE_SHIFT,
- (end_pfn - start_pfn) << PAGE_SHIFT);
+ for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+ unsigned long start_chunk, end_chunk;
+
+ if (memory_chunk[i].type != CHUNK_READ_WRITE)
+ continue;
+ start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+ start_chunk >>= PAGE_SHIFT;
+ end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+ end_chunk >>= PAGE_SHIFT;
+ if (start_chunk < start_pfn)
+ start_chunk = start_pfn;
+ if (end_chunk > end_pfn)
+ end_chunk = end_pfn;
+ if (start_chunk < end_chunk)
+ free_bootmem(start_chunk << PAGE_SHIFT,
+ (end_chunk - start_chunk) << PAGE_SHIFT);
+ }
X
X /*
X * Reserve the bootmem bitmap itself as well. We do this in two
@@ -401,6 +416,36 @@


X }
X #endif
X
+ /*

+ * Setup lowcore for boot cpu
+ */
+ lowcore = (struct _lowcore *)
+ __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+ memset(lowcore, 0, PAGE_SIZE);
+ lowcore->restart_psw.mask = _RESTART_PSW_MASK;
+ lowcore->restart_psw.addr = _ADDR_31 + (addr_t) &restart_int_handler;
+ lowcore->external_new_psw.mask = _EXT_PSW_MASK;
+ lowcore->external_new_psw.addr = _ADDR_31 + (addr_t) &ext_int_handler;
+ lowcore->svc_new_psw.mask = _SVC_PSW_MASK;
+ lowcore->svc_new_psw.addr = _ADDR_31 + (addr_t) &system_call;
+ lowcore->program_new_psw.mask = _PGM_PSW_MASK;
+ lowcore->program_new_psw.addr = _ADDR_31 + (addr_t) &pgm_check_handler;
+ lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;
+ lowcore->mcck_new_psw.addr = _ADDR_31 + (addr_t) &mcck_int_handler;
+ lowcore->io_new_psw.mask = _IO_PSW_MASK;
+ lowcore->io_new_psw.addr = _ADDR_31 + (addr_t) &io_int_handler;
+ lowcore->ipl_device = S390_lowcore.ipl_device;
+ lowcore->kernel_stack = ((__u32) &init_task_union) + 8192;
+ lowcore->async_stack = (__u32)
+ __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192;
+ set_prefix((__u32) lowcore);
+ cpu_init();
+ boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+ __cpu_logical_map[0] = boot_cpu_addr;
+
+ /*
+ * Create kernel page tables and switch to virtual addressing.
+ */
X paging_init();
X
X res = alloc_bootmem_low(sizeof(struct resource));
@@ -433,30 +478,49 @@
X }
X
X /*
- * Get CPU information for use by the procfs.
+ * get_cpuinfo - Get information on one CPU for use by procfs.


+ *
+ * Prints info on the next CPU into buffer. Beware, doesn't check for
+ * buffer overflow. Current implementation of procfs assumes that the
+ * resulting data is <= 1K.
+ *
+ * Args:
+ * buffer -- you guessed it, the data buffer
+ * cpu_np -- Input: next cpu to get (start at 0). Output: Updated.
+ *
+ * Returns number of bytes written to buffer.

X */


X
-int get_cpuinfo(char * buffer)

+int get_cpuinfo(char *buffer, unsigned *cpu_np)
X {

X struct cpuinfo_S390 *cpuinfo;


X char *p = buffer;

- int i;
+ unsigned n;
X
- p += sprintf(p,"vendor_id : IBM/S390\n"
- "# processors : %i\n"
- "bogomips per cpu: %lu.%02lu\n",
- smp_num_cpus, loops_per_jiffy/(500000/HZ),
- (loops_per_jiffy/(5000/HZ))%100);
- for (i = 0; i < smp_num_cpus; i++) {
- cpuinfo = &safe_get_cpu_lowcore(i).cpu_data;
- p += sprintf(p,"processor %i: "
- "version = %02X, "
- "identification = %06X, "
- "machine = %04X\n",
- i, cpuinfo->cpu_id.version,
- cpuinfo->cpu_id.ident,
- cpuinfo->cpu_id.machine);
- }
+ n = *cpu_np;
+ while (n < NR_CPUS && (cpu_online_map & (1 << n)) == 0)
+ n++;
+ if (n >= NR_CPUS) {
+ *cpu_np = NR_CPUS;
+ return (0);
+ }
+ *cpu_np = n + 1;
+
+ if (n == 0) {
+ p += sprintf(p,"vendor_id : IBM/S390\n"
+ "# processors : %i\n"
+ "bogomips per cpu: %lu.%02lu\n",
+ smp_num_cpus, loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ))%100);
+ }
+ cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
+ p += sprintf(p,"processor %i: "
+ "version = %02X, "
+ "identification = %06X, "
+ "machine = %04X\n",
+ n, cpuinfo->cpu_id.version,
+ cpuinfo->cpu_id.ident,
+ cpuinfo->cpu_id.machine);
X return p - buffer;
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/signal.c linux/arch/s390/kernel/signal.c
--- v2.4.12/linux/arch/s390/kernel/signal.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/signal.c Thu Oct 11 09:04:57 2001
@@ -12,6 +12,7 @@
X * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
X */
X
+#include <linux/config.h>
X #include <linux/sched.h>
X #include <linux/mm.h>
X #include <linux/smp.h>
@@ -23,31 +24,25 @@
X #include <linux/ptrace.h>
X #include <linux/unistd.h>
X #include <linux/stddef.h>
+#include <linux/personality.h>
X #include <asm/ucontext.h>
X #include <asm/uaccess.h>
X
-#define DEBUG_SIG 0
-


X #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
X

-/* pretcode & sig are used to store the return addr on Intel
- & the signal no as the first parameter we do this differently
- using gpr14 & gpr2. */
-
-#define SIGFRAME_COMMON \
-__u8 callee_used_stack[__SIGNAL_FRAMESIZE]; \
-struct sigcontext sc; \
-_sigregs sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
X
X typedef struct
X {
- SIGFRAME_COMMON
+ __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+ struct sigcontext sc;
+ _sigregs sregs;
+ __u8 retcode[S390_SYSCALL_SIZE];
X } sigframe;
X
X typedef struct
X {
- SIGFRAME_COMMON
+ __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
+ __u8 retcode[S390_SYSCALL_SIZE];
X struct siginfo info;
X struct ucontext uc;
X } rt_sigframe;
@@ -205,7 +200,7 @@
X err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
X if(!err)
X {
- regs->orig_gpr2 = -1; /* disable syscall checks */
+ regs->trap = -1; /* disable syscall checks */
X regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
X (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
X regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
@@ -217,53 +212,51 @@
X return(err);
X }
X
-static int
-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
- _sigregs *sregs,sigset_t *set)
-{
- unsigned int err;
-
- err=restore_sigregs(regs,sregs);
- if(!err)
- err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE);
- return(err);
-}
-
-int sigreturn_common(struct pt_regs *regs,int framesize)
+asmlinkage long sys_sigreturn(struct pt_regs *regs)
X {
X sigframe *frame = (sigframe *)regs->gprs[15];
X sigset_t set;
X
X if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
- return -1;
- if (restore_sigcontext(&frame->sc,regs,&frame->sregs,&set))
- return -1;
+ goto badframe;
+ if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
+ goto badframe;
+
X sigdelsetmask(&set, ~_BLOCKABLE);
X spin_lock_irq(&current->sigmask_lock);
X current->blocked = set;
X recalc_sigpending(current);
X spin_unlock_irq(&current->sigmask_lock);


- return 0;
-}
-

-asmlinkage int sys_sigreturn(struct pt_regs *regs)
-{
X
- if (sigreturn_common(regs,sizeof(sigframe)))
+ if (restore_sigregs(regs, &frame->sregs))
X goto badframe;
+
X return regs->gprs[2];
X
X badframe:
X force_sig(SIGSEGV, current);
X return 0;
-}
+}
X
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
X {
X rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+ sigset_t set;
+
+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
X
- if (sigreturn_common(regs,sizeof(rt_sigframe)))
+ if (restore_sigregs(regs, &frame->uc.uc_mcontext))
X goto badframe;
+
X /* It is more difficult to avoid calling this function than to
X call it and ignore errors. */
X do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
@@ -272,7 +265,7 @@
X badframe:
X force_sig(SIGSEGV, current);
X return 0;
-}
+}
X
X /*
X * Set up a signal frame.
@@ -306,58 +299,48 @@
X return (void *)((sp - frame_size) & -8ul);
X }
X
-static void *setup_frame_common(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs,
- int frame_size,u16 retcode)
+static inline int map_signal(int sig)
X {
- sigframe *frame;
- int err;
+ if (current->exec_domain
+ && current->exec_domain->signal_invmap
+ && sig < 32)
+ return current->exec_domain->signal_invmap[sig];
+ else
+ return sig;
+}
X
- frame = get_sigframe(ka, regs,frame_size);
- if (!access_ok(VERIFY_WRITE, frame,frame_size))
- return 0;
- err = save_sigregs(regs,&frame->sregs);
- if(!err)
- err=__put_user(&frame->sregs,&frame->sc.sregs);
- if(!err)
+static void setup_frame(int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs * regs)
+{
+ sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
+ goto give_sigsegv;
+
+ if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
+ goto give_sigsegv;
+
+ if (save_sigregs(regs, &frame->sregs))
+ goto give_sigsegv;
+ if (__put_user(&frame->sregs, &frame->sc.sregs))
+ goto give_sigsegv;
X
- err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE);
- if(!err)
- {
- regs->gprs[2]=(current->exec_domain
- && current->exec_domain->signal_invmap
- && sig < 32
- ? current->exec_domain->signal_invmap[sig]
- : sig);
- /* Set up registers for signal handler */
- regs->gprs[15] = (addr_t)frame;
- regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
- regs->psw.mask = _USER_PSW_MASK;
- }
X /* Set up to return from userspace. If provided, use a stub
X already in userspace. */


X if (ka->sa.sa_flags & SA_RESTORER) {

X regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
X } else {
X regs->gprs[14] = FIX_PSW(frame->retcode);
- err |= __put_user(retcode, (u16 *)(frame->retcode));
+ if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+ (u16 *)(frame->retcode)))
+ goto give_sigsegv;
X }
- return(err ? 0:frame);
-}


X
-static void setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs)

-{
- sigframe *frame;
+ /* Set up registers for signal handler */
+ regs->gprs[15] = (addr_t)frame;
+ regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+ regs->psw.mask = _USER_PSW_MASK;
X
- if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
- (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
- goto give_sigsegv;
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
- current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
- /* Martin wants this for pthreads */
+ regs->gprs[2] = map_signal(sig);
X regs->gprs[3] = (addr_t)&frame->sc;
X
X /* We forgot to include these in the sigcontext.
@@ -375,34 +358,44 @@
X static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
X sigset_t *set, struct pt_regs * regs)
X {
- rt_sigframe *frame;
- addr_t orig_sp=regs->gprs[15];
- int err;


+ int err = 0;

+ rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
+ goto give_sigsegv;
X
- if((frame=setup_frame_common(sig,ka,set,regs,sizeof(rt_sigframe),
- (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+ if (copy_siginfo_to_user(&frame->info, info))
X goto give_sigsegv;
-
- err = copy_siginfo_to_user(&frame->info, info);
X
X /* Create the ucontext. */
X err |= __put_user(0, &frame->uc.uc_flags);
X err |= __put_user(0, &frame->uc.uc_link);
X err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(orig_sp),
+ err |= __put_user(sas_ss_flags(regs->gprs[15]),
X &frame->uc.uc_stack.ss_flags);
X err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= __put_user(&frame->sc,&frame->uc.sc);
- regs->gprs[3] = (addr_t)&frame->info;
- regs->gprs[4] = (addr_t)&frame->uc;
-
+ err |= save_sigregs(regs, &frame->uc.uc_mcontext);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
X if (err)
X goto give_sigsegv;
X
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
- current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+ } else {
+ regs->gprs[14] = FIX_PSW(frame->retcode);
+ err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+ (u16 *)(frame->retcode));
+ }
+
+ /* Set up registers for signal handler */
+ regs->gprs[15] = (addr_t)frame;
+ regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+ regs->psw.mask = _USER_PSW_MASK;
+
+ regs->gprs[2] = map_signal(sig);
+ regs->gprs[3] = (addr_t)&frame->info;
+ regs->gprs[4] = (addr_t)&frame->uc;
X return;
X
X give_sigsegv:
@@ -551,13 +544,16 @@
X continue;
X /* FALLTHRU */
X
- case SIGSTOP:
+ case SIGSTOP: {
+ struct signal_struct *sig;
X set_current_state(TASK_STOPPED);
X current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+ sig = current->p_pptr->sig;
+ if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
X notify_parent(current, SIGCHLD);
X schedule();
X continue;
+ }
X
X case SIGQUIT: case SIGILL: case SIGTRAP:
X case SIGABRT: case SIGFPE: case SIGSEGV:
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/smp.c linux/arch/s390/kernel/smp.c
--- v2.4.12/linux/arch/s390/kernel/smp.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/smp.c Thu Oct 11 09:04:57 2001
@@ -57,6 +57,8 @@
X
X spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
X
+unsigned long cpu_online_map;
+
X /*
X * Setup routine for controlling SMP activation
X *
@@ -92,6 +94,95 @@
X
X extern void reipl(unsigned long devno);
X
+static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
+static void smp_ext_bitcall_others(ec_bit_sig);
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+struct call_data_struct {
+ void (*func) (void *info);
+ void *info;
+ atomic_t started;
+ atomic_t finished;
+ int wait;
+};
+
+static struct call_data_struct * call_data;
+
+/*
+ * 'Call function' interrupt callback
+ */
+static void do_call_function(void)
+{
+ void (*func) (void *info) = call_data->func;
+ void *info = call_data->info;
+ int wait = call_data->wait;
+
+ atomic_inc(&call_data->started);
+ (*func)(info);
+ if (wait)
+ atomic_inc(&call_data->finished);
+}
+
+/*
+ * 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,


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 07'
echo 'File patch-2.4.13 is continued in part 08'
echo "08" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:38 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part08

#!/bin/sh -x
# this is part 08 of a 53 - part archive


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

if test "$Scheck" != 08; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ 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 cpus = smp_num_cpus-1;

+
+ if (!cpus || !atomic_read(&smp_commenced))
+ 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_ext_bitcall_others(ec_call_function);
+
+ /* Wait for response */


+ while (atomic_read(&data.started) != cpus)

+ barrier();
+
+ if (wait)


+ while (atomic_read(&data.finished) != cpus)

+ barrier();
+ spin_unlock_bh(&call_lock);
+
+ return 0;
+}
+
+
+/*
+ * Various special callbacks
+ */
+
X void do_machine_restart(void)
X {
X smp_send_stop();
@@ -148,7 +239,6 @@
X
X void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
X {
- ec_ext_call *ec, *next;
X int bits;
X
X /*
@@ -169,131 +259,15 @@
X do_machine_halt();
X if (test_bit(ec_power_off, &bits))
X do_machine_power_off();
- if (test_bit(ec_ptlb, &bits))
- local_flush_tlb();
-
- /*
- * Handle external call commands with a parameter area
- */
- do {
- ec = (ec_ext_call *) atomic_read(&S390_lowcore.ext_call_queue);
- } while (atomic_compare_and_swap((int) ec, 0,
- &S390_lowcore.ext_call_queue));
- if (ec == NULL)
- return; /* no command signals */
-
- /* Make a fifo out of the lifo */
- next = ec->next;
- ec->next = NULL;
- while (next != NULL) {
- ec_ext_call *tmp = next->next;
- next->next = ec;
- ec = next;
- next = tmp;
- }
-
- /* Execute every sigp command on the queue */
- while (ec != NULL) {
- switch (ec->cmd) {
- case ec_callback_async: {
- void (*func)(void *info);
- void *info;
-
- func = ec->func;
- info = ec->info;
- atomic_set(&ec->status,ec_executing);
- (func)(info);
- return;
- }
- case ec_callback_sync:
- atomic_set(&ec->status,ec_executing);
- (ec->func)(ec->info);
- atomic_set(&ec->status,ec_done);
- return;
- default:
- }
- ec = ec->next;
- }
-}
-
-/*
- * Send a callback sigp to another cpu.
- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{
- struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
- sigp_ccode ccode;
- ec_ext_call ec;
-
- ec.cmd = wait ? ec_callback_sync : ec_callback_async;
- atomic_set(&ec.status, ec_pending);
- ec.func = func;
- ec.info = info;
- do {
- ec.next = (ec_ext_call*) atomic_read(&lowcore->ext_call_queue);
- } while (atomic_compare_and_swap((int) ec.next, (int)(&ec),
- &lowcore->ext_call_queue));
- /*
- * We try once to deliver the signal. There are four possible
- * return codes:
- * 0) Order code accepted - can't show up on an external call
- * 1) Status stored - fine, wait for completion.
- * 2) Busy - there is another signal pending. Thats fine too, because
- * do_ext_call from the pending signal will execute all signals on
- * the queue. We wait for completion.
- * 3) Not operational - something very bad has happened to the cpu.
- * do not wait for completion.
- */
- ccode = signal_processor(cpu, sigp_external_call);
-
- if (ccode != sigp_not_operational)
- /* wait for completion, FIXME: possible seed of a deadlock */
- while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
- return ccode;
-}
-
-/*
- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{
- struct _lowcore *lowcore;
- ec_ext_call ec[NR_CPUS];
- sigp_ccode ccode;
- int i;
-


- for (i = 0; i < smp_num_cpus; i++) {

- if (smp_processor_id() == i)
- continue;
- lowcore = &get_cpu_lowcore(i);
- ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
- atomic_set(&ec[i].status, ec_pending);
- ec[i].func = func;
- ec[i].info = info;
- do {
- ec[i].next = (ec_ext_call *)
- atomic_read(&lowcore->ext_call_queue);
- } while (atomic_compare_and_swap((int) ec[i].next, (int)(ec+i),
- &lowcore->ext_call_queue));
- ccode = signal_processor(i, sigp_external_call);
- }
-
- /* wait for completion, FIXME: possible seed of a deadlock */


- for (i = 0; i < smp_num_cpus; i++) {

- if (smp_processor_id() == i)
- continue;
- while (atomic_read(&ec[i].status) !=
- (wait ? ec_done:ec_executing));
- }
+ if (test_bit(ec_call_function, &bits))
+ do_call_function();
X }
X
X /*
X * Send an external call sigp to another cpu and return without waiting
X * for its completion.
X */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
X {
X struct _lowcore *lowcore = &get_cpu_lowcore(cpu);
X sigp_ccode ccode;
@@ -310,7 +284,7 @@
X * Send an external call sigp to every other cpu in the system and
X * return without waiting for its completion.
X */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
X {
X struct _lowcore *lowcore;
X sigp_ccode ccode;
@@ -329,51 +303,6 @@
X }
X
X /*
- * cycles through all the cpus,
- * returns early if info is not NULL & the processor has something
- * of intrest to report in the info structure.
- * it returns the next cpu to check if it returns early.
- * i.e. it should be used as follows if you wish to receive info.
- * next_cpu=0;
- * do
- * {
- * info->cpu=next_cpu;
- * next_cpu=smp_signal_others(order_code,parameter,1,info);
- * ... check info here
- * } while(next_cpu<=smp_num_cpus)
- *
- * if you are lazy just use it like
- * smp_signal_others(order_code,parameter,0,1,NULL);
- */
-int smp_signal_others(sigp_order_code order_code, u32 parameter,
- int spin, sigp_info *info)
-{
- sigp_ccode ccode;
- u32 dummy;
- u16 i;
-
- if (info)
- info->intresting = 0;
- for (i = (info ? info->cpu : 0); i < smp_num_cpus; i++) {
- if (smp_processor_id() != i) {
- do {
- ccode = signal_processor_ps(
- (info ? &info->status : &dummy),
- parameter, i, order_code);
- } while(spin && ccode == sigp_busy);
- if (info && ccode != sigp_order_code_accepted) {
- info->intresting = 1;
- info->cpu = i;
- info->ccode = ccode;
- i++;
- break;
- }
- }
- }
- return i;
-}
-
-/*
X * this function sends a 'stop' sigp to all other CPUs in the system.
X * it goes straight through.
X */
@@ -390,7 +319,18 @@
X
X /* stop all processors */
X
- smp_signal_others(sigp_stop, 0, 1, NULL);
+ for (i = 0; i < smp_num_cpus; i++) {
+ if (smp_processor_id() != i) {
+ int ccode;
+ do {
+ ccode = signal_processor_ps(
+ &dummy,
+ 0,
+ i,
+ sigp_stop);
+ } while(ccode == sigp_busy);
+ }
+ }
X
X /* store status of all processors in their lowcores (real 0) */
X
@@ -419,7 +359,7 @@
X
X void smp_ptlb_all(void)
X {
- smp_ext_call_others(smp_ptlb_callback, NULL, 1);
+ smp_call_function(smp_ptlb_callback, NULL, 0, 1);
X local_flush_tlb();
X }
X
@@ -482,7 +422,7 @@
X parms.end_ctl = cr;
X parms.orvals[cr] = 1 << bit;
X parms.andvals[cr] = 0xFFFFFFFF;
- smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+ smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
X }
X __ctl_set_bit(cr, bit);
X }
@@ -498,36 +438,12 @@
X parms.end_ctl = cr;
X parms.orvals[cr] = 0x00000000;
X parms.andvals[cr] = ~(1 << bit);
- smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+ smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
X }
X __ctl_clear_bit(cr, bit);
X }
X
X /*
- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, 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.
- * <retry> 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.
- */
-{
- if (atomic_read(&smp_commenced) != 0)
- smp_ext_call_others(func, info, wait);


- return 0;
-}
-

-/*
X * Lets check how many CPUs we have.
X */
X
@@ -537,6 +453,7 @@
X
X current->processor = 0;
X smp_num_cpus = 1;
+ cpu_online_map = 1;
X for (curr_cpu = 0;
X curr_cpu <= 65535 && smp_num_cpus < max_cpus; curr_cpu++) {
X if ((__u16) curr_cpu == boot_cpu_addr)
@@ -556,6 +473,7 @@
X * Activate a secondary processor.
X */
X extern void init_100hz_timer(void);
+extern int pfault_init(void);
X extern int pfault_token(void);
X
X int __init start_secondary(void *cpuvoid)
@@ -620,15 +538,20 @@
X init_tasks[cpu] = idle;
X
X cpu_lowcore=&get_cpu_lowcore(cpu);
- cpu_lowcore->kernel_stack=idle->thread.ksp;
- __asm__ __volatile__("stctl 0,15,%0\n\t"
- "stam 0,15,%1"
+ cpu_lowcore->save_area[15] = idle->thread.ksp;
+ cpu_lowcore->kernel_stack = (idle->thread.ksp | 8191) + 1;
+ __asm__ __volatile__("la 1,%0\n\t"
+ "stctl 0,15,0(1)\n\t"
+ "la 1,%1\n\t"
+ "stam 0,15,0(1)"
X : "=m" (cpu_lowcore->cregs_save_area[0]),
X "=m" (cpu_lowcore->access_regs_save_area[0])
- : : "memory");
+ : : "1", "memory");
X
X eieio();
X signal_processor(cpu,sigp_restart);
+ /* Mark this cpu as online */
+ set_bit(cpu, &cpu_online_map);
X }
X
X /*
@@ -650,12 +573,12 @@
X }
X
X /*
- * Cycle through the processors sending APIC IPIs to boot each.
+ * Cycle through the processors sending sigp_restart to boot each.
X */
X
X void __init smp_boot_cpus(void)
X {
- struct _lowcore *curr_lowcore;
+ unsigned long async_stack;
X sigp_ccode ccode;
X int i;
X
@@ -680,34 +603,37 @@
X
X for(i = 0; i < smp_num_cpus; i++)
X {
- curr_lowcore = (struct _lowcore *)
- __get_free_page(GFP_KERNEL|GFP_DMA);
- if (curr_lowcore == NULL) {
- printk("smp_boot_cpus failed to allocate prefix memory\n");
- break;
- }
- lowcore_ptr[i] = curr_lowcore;
- memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+ lowcore_ptr[i] = (struct _lowcore *)
+ __get_free_page(GFP_KERNEL|GFP_DMA);
+ if (lowcore_ptr[i] == NULL)
+ panic("smp_boot_cpus failed to "
+ "allocate prefix memory\n");
+ async_stack = __get_free_pages(GFP_KERNEL,1);
+ if (async_stack == 0)
+ panic("smp_boot_cpus failed to allocate "
+ "asyncronous interrupt stack\n");
+
+ memcpy(lowcore_ptr[i], &S390_lowcore, sizeof(struct _lowcore));
+ lowcore_ptr[i]->async_stack = async_stack + (2 * PAGE_SIZE);
X /*
X * Most of the parameters are set up when the cpu is
X * started up.
X */
- if (smp_processor_id() == i)
- set_prefix((u32) curr_lowcore);
- else {
- ccode = signal_processor_p((u32)(curr_lowcore),
- i, sigp_set_prefix);
- if(ccode) {
- /* if this gets troublesome I'll have to do
- * something about it. */
- printk("ccode %d for cpu %d returned when "
- "setting prefix in smp_boot_cpus not good.\n",
- (int) ccode, (int) i);
- }
- else
- do_boot_cpu(i);
- }
- }
+ if (smp_processor_id() == i)
+ set_prefix((u32) lowcore_ptr[i]);
+ else {
+ ccode = signal_processor_p((u32)(lowcore_ptr[i]),
+ i, sigp_set_prefix);
+ if (ccode)
+ /* if this gets troublesome I'll have to do
+ * something about it. */
+ printk("ccode %d for cpu %d returned when "
+ "setting prefix in smp_boot_cpus not good.\n",
+ (int) ccode, (int) i);
+ else
+ do_boot_cpu(i);
+ }


+ }
X }
X
X /*

@@ -746,8 +672,6 @@
X s390_do_profile(regs->psw.addr);
X
X if (!--prof_counter[cpu]) {
- int system = 1-user;
- struct task_struct * p = current;
X
X /*
X * The multiplier may have changed since the last time we got
@@ -771,9 +695,7 @@
X * WrongThing (tm) to do.
X */
X
- irq_enter(cpu, 0);
X update_process_times(user);
- irq_exit(cpu, 0);
X }
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/time.c linux/arch/s390/kernel/time.c
--- v2.4.12/linux/arch/s390/kernel/time.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/time.c Thu Oct 11 09:04:57 2001
@@ -151,15 +151,14 @@
X
X void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
X {
- unsigned long flags;
+ int cpu = smp_processor_id();
+
+ irq_enter(cpu, 0);
X
X /*
X * reset timer to 10ms minus time already elapsed
X * since timer-interrupt pending
X */
-
- save_flags(flags);
- cli();
X #ifdef CONFIG_SMP
X if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
X write_lock(&xtime_lock);
@@ -195,8 +194,8 @@
X write_unlock(&xtime_lock);
X #endif
X }
- restore_flags(flags);
X
+ irq_exit(cpu, 0);
X }
X
X /*
@@ -250,4 +249,7 @@
X init_timer_cc -= 0x8126d60e46000000LL -
X (0x3c26700LL*1000000*4096);
X tod_to_timeval(init_timer_cc, &xtime);
+
+ /* Set do_get_fast_time function pointer. */
+ do_get_fast_time = do_gettimeofday;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/s390/kernel/traps.c linux/arch/s390/kernel/traps.c
--- v2.4.12/linux/arch/s390/kernel/traps.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/kernel/traps.c Thu Oct 11 09:04:57 2001
@@ -60,14 +60,16 @@
X extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
X #endif
X
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
X
X void die(const char * str, struct pt_regs * regs, long err)
X {
X console_verbose();
X spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
X printk("%s: %04lx\n", str, err & 0xffff);
X show_regs(regs);
+ bust_spinlocks(0);
X spin_unlock_irq(&die_lock);
X do_exit(SIGSEGV);
X }
@@ -135,7 +137,7 @@
X #if CONFIG_REMOTE_DEBUG
X if(gdb_stub_initialised)
X {
- gdb_stub_handle_exception((gdb_pt_regs *)regs,signal);
+ gdb_stub_handle_exception((struct gdb_pt_regs *)regs,signal);
X return 0;
X }
X #endif
@@ -211,7 +213,7 @@
X specification_exception(struct pt_regs * regs, long interruption_code)
X {
X __u8 opcode[6];
- __u16 *location;
+ __u16 *location = NULL;
X int signal = 0;
X
X if (regs->psw.mask & PSW_PROBLEM_STATE) {
diff -u --recursive --new-file v2.4.12/linux/arch/s390/math-emu/math.c linux/arch/s390/math-emu/math.c
--- v2.4.12/linux/arch/s390/math-emu/math.c Thu Apr 12 12:16:35 2001
+++ linux/arch/s390/math-emu/math.c Thu Oct 11 09:04:57 2001
@@ -1471,20 +1471,98 @@
X }
X
X /* Test data class long double */
-static int emu_tcxb (int rx, double *val) {
- display_emulation_not_implemented("tcxb");
+static int emu_tcxb (int rx, long val) {
+ FP_DECL_Q(QA);
+ mathemu_ldcv cvt;
+ int bit;
+
+ cvt.w.high = current->thread.fp_regs.fprs[rx].ui;
+ cvt.w.low = current->thread.fp_regs.fprs[rx+2].ui;
+ FP_UNPACK_RAW_QP(QA, &cvt.ld);
+ switch (QA_e) {
+ default:
+ bit = 8; /* normalized number */
+ break;
+ case 0:
+ if (_FP_FRAC_ZEROP_4(QA))
+ bit = 10; /* zero */
+ else
+ bit = 6; /* denormalized number */
+ break;
+ case _FP_EXPMAX_Q:
+ if (_FP_FRAC_ZEROP_4(QA))
+ bit = 4; /* infinity */
+ else if (_FP_FRAC_HIGH_RAW_Q(QA) & _FP_QNANBIT_Q)
+ bit = 2; /* quiet NAN */
+ else
+ bit = 0; /* signaling NAN */
+ break;
+ }
+ if (!QA_s)
+ bit++;
+ emu_set_CC(((__u32) val >> bit) & 1);


X return 0;
X }
X

X /* Test data class double */
-static int emu_tcdb (int rx, double *val) {
- display_emulation_not_implemented("tcdb");
+static int emu_tcdb (int rx, long val) {
+ FP_DECL_D(DA);
+ int bit;
+
+ FP_UNPACK_RAW_DP(DA, &current->thread.fp_regs.fprs[rx].d);
+ switch (DA_e) {
+ default:
+ bit = 8; /* normalized number */
+ break;
+ case 0:
+ if (_FP_FRAC_ZEROP_2(DA))
+ bit = 10; /* zero */
+ else
+ bit = 6; /* denormalized number */
+ break;
+ case _FP_EXPMAX_D:
+ if (_FP_FRAC_ZEROP_2(DA))
+ bit = 4; /* infinity */
+ else if (_FP_FRAC_HIGH_RAW_D(DA) & _FP_QNANBIT_D)
+ bit = 2; /* quiet NAN */
+ else
+ bit = 0; /* signaling NAN */
+ break;
+ }
+ if (!DA_s)
+ bit++;
+ emu_set_CC(((__u32) val >> bit) & 1);


X return 0;
X }
X

X /* Test data class float */
-static int emu_tceb (int rx, __u32 val) {
- display_emulation_not_implemented("tceb");
+static int emu_tceb (int rx, long val) {
+ FP_DECL_S(SA);
+ int bit;
+
+ FP_UNPACK_RAW_SP(SA, &current->thread.fp_regs.fprs[rx].f);
+ switch (SA_e) {
+ default:
+ bit = 8; /* normalized number */
+ break;
+ case 0:
+ if (_FP_FRAC_ZEROP_1(SA))
+ bit = 10; /* zero */
+ else
+ bit = 6; /* denormalized number */
+ break;
+ case _FP_EXPMAX_S:
+ if (_FP_FRAC_ZEROP_1(SA))
+ bit = 4; /* infinity */
+ else if (_FP_FRAC_HIGH_RAW_S(SA) & _FP_QNANBIT_S)
+ bit = 2; /* quiet NAN */
+ else
+ bit = 0; /* signaling NAN */
+ break;
+ }
+ if (!SA_s)
+ bit++;
+ emu_set_CC(((__u32) val >> bit) & 1);


X return 0;
X }
X

@@ -1796,13 +1874,13 @@
X int _fex = 0;
X
X static const __u8 format_table[256] = {
- [0x04] = 0x08,[0x05] = 0x07,[0x06] = 0x09,[0x07] = 0x07,
- [0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03,
- [0x0c] = 0x08,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06,
- [0x10] = 0x03,[0x11] = 0x02,[0x12] = 0x01,[0x14] = 0x03,
- [0x15] = 0x02,[0x17] = 0x03,[0x18] = 0x02,[0x19] = 0x02,
- [0x1a] = 0x02,[0x1b] = 0x02,[0x1c] = 0x02,[0x1d] = 0x02,
- [0x1e] = 0x05,[0x1f] = 0x05,
+ [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05,
+ [0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02,
+ [0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04,
+ [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02,
+ [0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01,
+ [0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01,
+ [0x1e] = 0x03,[0x1f] = 0x03,
X };
X static const void *jump_table[]= {
X [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb,
@@ -1817,25 +1895,7 @@
X };
X
X switch (format_table[opcode[5]]) {
- case 1: /* RXE format, long double constant */ {
- __u64 *dxb, temp[2];
- __u32 opc;
-
- if ((opcode[1] >> 4) & 2)
- return SIGILL;
- emu_store_regd((opcode[1] >> 4) & 15);
- emu_store_regd(((opcode[1] >> 4) & 15) + 2);
- opc = *((__u32 *) opcode);
- dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
- mathemu_copy_from_user(&temp, dxb, 16);
- /* call the emulation function */
- _fex = ((int (*)(int, long double *)) jump_table[opcode[5]])
- (opcode[1] >> 4, (long double *) &temp);
- emu_load_regd((opcode[1] >> 4) & 15);
- emu_load_regd(((opcode[1] >> 4) & 15) + 2);
- break;
- }
- case 2: /* RXE format, double constant */ {
+ case 1: /* RXE format, double constant */ {
X __u64 *dxb, temp;
X __u32 opc;
X
@@ -1849,7 +1909,7 @@
X emu_load_regd((opcode[1] >> 4) & 15);
X break;
X }
- case 3: /* RXE format, float constant */ {
+ case 2: /* RXE format, float constant */ {
X __u32 *dxb, temp;
X __u32 opc;
X
@@ -1863,27 +1923,7 @@
X emu_load_rege((opcode[1] >> 4) & 15);
X break;
X }
- case 4: /* RXF format, long double constant */ {
- __u64 *dxb, temp[2];
- __u32 opc;
-
- if (((opcode[1] >> 4) & 0x20) || ((opcode[4] >> 4) & 0x20))
- return SIGILL;
- emu_store_regd((opcode[1] >> 4) & 15);
- emu_store_regd(((opcode[1] >> 4) & 15) + 2);
- emu_store_regd((opcode[4] >> 4) & 15);
- emu_store_regd(((opcode[4] >> 4) & 15) + 2);
- opc = *((__u32 *) opcode);
- dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc);
- mathemu_copy_from_user(&temp, dxb, 16);
- /* call the emulation function */
- _fex = ((int (*)(int,long double *,int)) jump_table[opcode[5]])
- (opcode[1] >> 4, (double *) &temp, opcode[4] >> 4);
- emu_load_regd((opcode[1] >> 4) & 15);
- emu_load_regd(((opcode[1] >> 4) & 15) + 2);
- break;
- }
- case 5: /* RXF format, double constant */ {
+ case 3: /* RXF format, double constant */ {
X __u64 *dxb, temp;
X __u32 opc;
X
@@ -1898,7 +1938,7 @@
X emu_load_regd((opcode[1] >> 4) & 15);
X break;
X }
- case 6: /* RXF format, float constant */ {
+ case 4: /* RXF format, float constant */ {
X __u32 *dxb, temp;
X __u32 opc;
X
@@ -1913,7 +1953,7 @@
X emu_load_rege((opcode[4] >> 4) & 15);
X break;
X }
- case 7: /* RXE format, double constant */
+ case 5: /* RXE format, double constant */
X /* store double and load long double */
X {
X __u64 *dxb, temp;
@@ -1931,7 +1971,7 @@
X emu_load_regd(((opcode[1] >> 4) & 15) + 2);
X break;
X }
- case 8: /* RXE format, float constant */
+ case 6: /* RXE format, float constant */
X /* store float and load double */
X {
X __u32 *dxb, temp;
@@ -1946,7 +1986,7 @@
X emu_load_regd((opcode[1] >> 4) & 15);
X break;
X }
- case 9: /* RXE format, float constant */
+ case 7: /* RXE format, float constant */
X /* store float and load long double */
X {
X __u32 *dxb, temp;
@@ -1962,6 +2002,45 @@
X (opcode[1] >> 4, (float *) &temp);
X emu_load_regd((opcode[1] >> 4) & 15);
X emu_load_regd(((opcode[1] >> 4) & 15) + 2);
+ break;
+ }
+ case 8: /* RXE format, RX address used as int value */ {
+ __u64 dxb;
+ __u32 opc;
+
+ emu_store_rege((opcode[1] >> 4) & 15);
+ opc = *((__u32 *) opcode);
+ dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+ /* call the emulation function */
+ _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+ (opcode[1] >> 4, dxb);
+ break;
+ }
+ case 9: /* RXE format, RX address used as int value */ {
+ __u64 dxb;
+ __u32 opc;
+
+ emu_store_regd((opcode[1] >> 4) & 15);
+ opc = *((__u32 *) opcode);
+ dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+ /* call the emulation function */
+ _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+ (opcode[1] >> 4, dxb);
+ break;
+ }
+ case 10: /* RXE format, RX address used as int value */ {
+ __u64 dxb;
+ __u32 opc;
+
+ if ((opcode[1] >> 4) & 2)
+ return SIGILL;
+ emu_store_regd((opcode[1] >> 4) & 15);
+ emu_store_regd(((opcode[1] >> 4) & 15) + 2);
+ opc = *((__u32 *) opcode);
+ dxb = (__u64) calc_addr(regs, opc >> 16, opc >> 12, opc);
+ /* call the emulation function */
+ _fex = ((int (*)(int, long)) jump_table[opcode[5]])
+ (opcode[1] >> 4, dxb);
X break;
X }
X default: /* invalid operation */
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/extable.c linux/arch/s390/mm/extable.c
--- v2.4.12/linux/arch/s390/mm/extable.c Fri May 12 11:41:45 2000
+++ linux/arch/s390/mm/extable.c Thu Oct 11 09:04:57 2001
@@ -10,6 +10,7 @@
X

X #include <linux/config.h>
X #include <linux/module.h>

+#include <linux/spinlock.h>
X #include <asm/uaccess.h>
X
X extern const struct exception_table_entry __start___ex_table[];
@@ -36,28 +37,37 @@


X return 0;
X }
X

+extern spinlock_t modlist_lock;
+
X unsigned long
X search_exception_table(unsigned long addr)
X {

- unsigned long ret;
+ unsigned long ret = 0;


+ unsigned long flags;
X

X #ifndef CONFIG_MODULES
X addr &= 0x7fffffff; /* remove amode bit from address */


X /* There is only the kernel to search. */
X ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);

- if (ret) return FIX_PSW(ret);
+ if (ret) ret = FIX_PSW(ret);
+ return ret;


X #else
X /* The kernel is the last "module" -- no need to treat it special. */

X struct module *mp;
X addr &= 0x7fffffff; /* remove amode bit from address */
+


+ spin_lock_irqsave(&modlist_lock, flags);
X for (mp = module_list; mp != NULL; mp = mp->next) {
- if (mp->ex_table_start == NULL)

+ if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))


X continue;
X ret = search_one_table(mp->ex_table_start,
X mp->ex_table_end - 1, addr);

- if (ret) return FIX_PSW(ret);
+ if (ret) {
+ ret = FIX_PSW(ret);
+ break;
+ }
X }
+ spin_unlock_irqrestore(&modlist_lock, flags);
+ return ret;
X #endif
-
- return 0;
X }
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c
--- v2.4.12/linux/arch/s390/mm/fault.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390/mm/fault.c Thu Oct 11 09:04:57 2001
@@ -4,6 +4,7 @@
X * S390 version
X * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
X * Author(s): Hartmut Penner (h...@de.ibm.com)
+ * Ulrich Weigand (uwei...@de.ibm.com)
X *
X * Derived from "arch/i386/mm/fault.c"
X * Copyright (C) 1995 Linus Torvalds
@@ -23,6 +24,7 @@
X #include <linux/smp_lock.h>
X #include <linux/compatmac.h>
X #include <linux/init.h>
+#include <linux/console.h>
X
X #include <asm/system.h>
X #include <asm/uaccess.h>
@@ -34,6 +36,34 @@
X #endif
X
X extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);
+
+extern spinlock_t timerlist_lock;
+
+/*
+ * Unlock any spinlocks which will prevent us from getting the
+ * message out (timerlist_lock is acquired through the
+ * console unblank code)
+ */
+void bust_spinlocks(int yes)
+{
+ spin_lock_init(&timerlist_lock);
+ if (yes) {
+ oops_in_progress = 1;
+ } else {
+ int loglevel_save = console_loglevel;
+ oops_in_progress = 0;
+ console_unblank();
+ /*
+ * OK, the message is on the console. Now we call printk()
+ * without oops_in_progress set so that printk will give klogd
+ * a poke. Hold onto your hats...
+ */
+ console_loglevel = 15;
+ printk(" ");
+ console_loglevel = loglevel_save;
+ }
+}
X
X /*
X * This routine handles page faults. It determines the address,
@@ -56,18 +86,36 @@
X int si_code = SEGV_MAPERR;
X int kernel_address = 0;
X
+ tsk = current;
+ mm = tsk->mm;
+
+ /*
+ * Check for low-address protection. This needs to be treated
+ * as a special case because the translation exception code
+ * field is not guaranteed to contain valid data in this case.
+ */
+ if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+ /* Low-address protection hit in kernel mode means
+ NULL pointer write access in kernel mode. */
+ if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+ address = 0;
+ kernel_address = 1;
+ goto no_context;
+ }
+
+ /* Low-address protection hit in user mode 'cannot happen'. */
+ die ("Low-address protection", regs, error_code);
+ do_exit(SIGKILL);
+ }
+
X /*
X * get the failing address
X * more specific the segment and page table portion of
X * the address
X */
- address = S390_lowcore.trans_exc_code&0x7ffff000;


X
- tsk = current;

- mm = tsk->mm;
-
- if (in_interrupt() || !mm)
- goto no_context;
+ address = S390_lowcore.trans_exc_code&0x7ffff000;
X
X
X /*
@@ -99,6 +147,7 @@
X }
X }
X die("page fault via unknown access register", regs, error_code);
+ do_exit(SIGKILL);
X break;
X
X case 2: /* Secondary Segment Table Descriptor */
@@ -107,6 +156,11 @@
X break;
X }
X
+ /*
+ * Check whether we have a user MM in the first place.
+ */
+ if (in_interrupt() || !mm)
+ goto no_context;
X
X /*
X * When we get here, the fault happened in the current
@@ -146,6 +200,7 @@
X goto bad_area;
X }
X
+ survive:
X /*
X * If for any reason at all we couldn't handle the fault,
X * make sure we exit gracefully rather than endlessly redo
@@ -176,7 +231,6 @@
X
X /* User mode accesses just cause a SIGSEGV */
X if (regs->psw.mask & PSW_PROBLEM_STATE) {
- struct siginfo si;
X tsk->thread.prot_addr = address;
X tsk->thread.trap_no = error_code;
X #ifndef CONFIG_SYSCTL
@@ -193,10 +247,8 @@
X show_regs(regs);
X }
X #endif
- si.si_signo = SIGSEGV;
- si.si_code = si_code;
- si.si_addr = (void*) address;
- force_sig_info(SIGSEGV, &si, tsk);
+
+ force_sigsegv(tsk, si_code, (void *)address);
X return;
X }
X
@@ -218,9 +270,6 @@
X else
X printk(KERN_ALERT "Unable to handle kernel paging request"
X " at virtual user address %08lx\n", address);
-/*
- * need to define, which information is useful here
- */
X
X die("Oops", regs, error_code);
X do_exit(SIGKILL);
@@ -232,6 +281,12 @@
X */
X out_of_memory:
X up_read(&mm->mmap_sem);
+ if (tsk->pid == 1) {
+ tsk->policy |= SCHED_YIELD;
+ schedule();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
X printk("VM: killing process %s\n", tsk->comm);
X if (regs->psw.mask & PSW_PROBLEM_STATE)
X do_exit(SIGKILL);
@@ -253,6 +308,18 @@
X goto no_context;
X }
X
+/*
+ * Send SIGSEGV to task. This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+ struct siginfo si;
+ si.si_signo = SIGSEGV;
+ si.si_code = code;
+ si.si_addr = address;
+ force_sig_info(SIGSEGV, &si, tsk);
+}
X
X typedef struct _pseudo_wait_t {
X struct _pseudo_wait_t *next;
@@ -434,7 +501,6 @@
X asmlinkage void
X pfault_interrupt(struct pt_regs *regs, __u16 error_code)
X {
- DECLARE_WAITQUEUE(wait, current);
X struct task_struct *tsk;
X wait_queue_head_t queue;
X wait_queue_head_t *qp;
@@ -447,7 +513,7 @@
X * external interrupt.
X */
X subcode = S390_lowcore.cpu_addr;
- if ((subcode & 0xff00) != 0x06)
+ if ((subcode & 0xff00) != 0x0600)
X return;
X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390/mm/init.c linux/arch/s390/mm/init.c
--- v2.4.12/linux/arch/s390/mm/init.c Sun Sep 23 11:40:56 2001
+++ linux/arch/s390/mm/init.c Thu Oct 11 09:04:57 2001
@@ -44,44 +44,23 @@
X pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
X char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
X
-static int test_access(unsigned long loc)
-{
- static const int ssm_mask = 0x07000000L;
- int rc, i;
-
- rc = 0;
- for (i=0; i<4; i++) {
- __asm__ __volatile__(
- " slr %0,%0\n"
- " ssm %1\n"
- " tprot 0(%2),0\n"
- "0: jne 1f\n"
- " lhi %0,1\n"
- "1: ssm %3\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 0b,1b\n"
- ".previous"
- : "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
- : "cc");
- if (rc == 0)
- break;
- loc += 0x100000;
- }
- return rc;
-}
-
X int do_check_pgt_cache(int low, int high)
X {
X int freed = 0;
X if(pgtable_cache_size > high) {
X do {
- if(pgd_quicklist)
- free_pgd_slow(get_pgd_fast()), freed += 2;
- if(pmd_quicklist)
- pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed++;
- if(pte_quicklist)
- pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+ if(pgd_quicklist) {
+ free_pgd_slow(get_pgd_fast());
+ freed += 2;
+ }
+ if(pmd_quicklist) {
+ pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+ freed++;
+ }
+ if(pte_quicklist) {
+ pte_free_slow(pte_alloc_one_fast(NULL, 0));
+ freed++;
+ }
X } while(pgtable_cache_size > low);
X }
X return freed;
@@ -200,7 +179,6 @@
X void __init mem_init(void)
X {
X int codesize, reservedpages, datasize, initsize;
- int tmp;
X
X max_mapnr = num_physpages = max_low_pfn;
X high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
@@ -211,24 +189,7 @@
X /* this will put all low memory onto the freelists */
X totalram_pages += free_all_bootmem();
X
- /* mark usable pages in the mem_map[] and count reserved pages */
X reservedpages = 0;
- tmp = 0;
- do {
- if (tmp && (tmp & 0x3ff) == 0 &&
- test_access(tmp * PAGE_SIZE) == 0) {
- printk("4M Segment %lX not available\n",tmp*PAGE_SIZE);
- do {
- set_bit(PG_reserved, &mem_map[tmp].flags);
- reservedpages++;
- tmp++;
- } while (tmp < max_low_pfn && (tmp & 0x3ff));
- } else {
- if (PageReserved(mem_map+tmp))
- reservedpages++;
- tmp++;
- }
- } while (tmp < max_low_pfn);
X
X codesize = (unsigned long) &_etext - (unsigned long) &_text;
X datasize = (unsigned long) &_edata - (unsigned long) &_etext;
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/Makefile linux/arch/s390x/Makefile
--- v2.4.12/linux/arch/s390x/Makefile Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/Makefile Thu Oct 11 09:04:57 2001
@@ -52,16 +52,6 @@


X
X MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
X
-MAKESILO = $(MAKE) -C arch/$(ARCH)/tools/silo
-
-MAKEDASDFMT = $(MAKE) -C arch/$(ARCH)/tools/dasdfmt
-
-silo:

- @$(MAKE) -C arch/$(ARCH)/tools/silo
-
-dasdfmt:
- @$(MAKE) -C arch/$(ARCH)/tools/dasdfmt


-
X image: vmlinux
X @$(MAKEBOOT) image
X

diff -u --recursive --new-file v2.4.12/linux/arch/s390x/config.in linux/arch/s390x/config.in
--- v2.4.12/linux/arch/s390x/config.in Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/config.in Thu Oct 11 09:04:57 2001
@@ -8,6 +8,7 @@
X define_bool CONFIG_MCA n


X define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
X define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_BUST_SPINLOCK n
X

X mainmenu_name "Linux Kernel Configuration"
X define_bool CONFIG_ARCH_S390 y
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/defconfig linux/arch/s390x/defconfig
--- v2.4.12/linux/arch/s390x/defconfig Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/defconfig Thu Oct 11 09:04:57 2001
@@ -6,6 +6,7 @@
X # CONFIG_MCA is not set
X CONFIG_RWSEM_GENERIC_SPINLOCK=y
X # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_BUST_SPINLOCK=n
X CONFIG_ARCH_S390=y
X CONFIG_ARCH_S390X=y
X
@@ -72,6 +73,7 @@
X CONFIG_MD_RAID0=m
X CONFIG_MD_RAID1=m
X CONFIG_MD_RAID5=m
+# CONFIG_MD_MULTIPATH is not set
X CONFIG_BLK_DEV_LVM=m
X
X #
@@ -247,6 +249,7 @@
X CONFIG_IBM_PARTITION=y
X # CONFIG_MAC_PARTITION is not set
X # CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
X # CONFIG_SGI_PARTITION is not set
X # CONFIG_ULTRIX_PARTITION is not set
X # CONFIG_SUN_PARTITION is not set
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/Makefile linux/arch/s390x/kernel/Makefile
--- v2.4.12/linux/arch/s390x/kernel/Makefile Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/Makefile Thu Oct 11 09:04:57 2001
@@ -12,12 +12,14 @@
X
X all: kernel.o head.o init_task.o
X
-O_TARGET := kernel.o
+O_TARGET := kernel.o
X
-export-objs := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o


-obj-y := lowcore.o entry.o bitmap.o traps.o time.o process.o irq.o \

- setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
- semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
+export-objs := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o \
+ exec32.o
+


+obj-y := entry.o bitmap.o traps.o time.o process.o irq.o \

+ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
+ semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
X
X obj-$(CONFIG_MODULES) += s390_ksyms.o
X obj-$(CONFIG_SMP) += smp.o
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/cpcmd.c linux/arch/s390x/kernel/cpcmd.c
--- v2.4.12/linux/arch/s390x/kernel/cpcmd.c Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/cpcmd.c Thu Oct 11 09:04:57 2001
@@ -6,21 +6,25 @@
X * Author(s): Martin Schwidefsky (schwi...@de.ibm.com),
X */
X
-#include <linux/stddef.h>
-#include <linux/kernel.h>
X #include <linux/string.h>
-#include <asm/ebcdic.h>
+#include <linux/spinlock.h>
X #include <asm/cpcmd.h>
+#include <asm/ebcdic.h>
+#include <asm/system.h>
+
+static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED;
+static char cpcmd_buf[128];
X
X void cpcmd(char *cmd, char *response, int rlen)
X {
X const int mask = 0x40000000L;
- char obuffer[128];
- int olen;
+ unsigned long flags;
+ int cmdlen;
X
- olen = strlen(cmd);
- strcpy(obuffer, cmd);
- ASCEBC(obuffer,olen);
+ spin_lock_irqsave(&cpcmd_lock, flags);
+ cmdlen = strlen(cmd);
+ strcpy(cpcmd_buf, cmd);
+ ASCEBC(cpcmd_buf, cmdlen);
X
X if (response != NULL && rlen > 0) {
X asm volatile (" lrag 2,0(%0)\n"
@@ -32,7 +36,7 @@
X " .long 0x83240008 # Diagnose 83\n"
X " sam64"
X : /* no output */
- : "a" (obuffer), "d" (olen),
+ : "a" (cpcmd_buf), "d" (cmdlen),
X "a" (response), "d" (rlen), "m" (mask)
X : "2", "3", "4", "5" );
X EBCASC(response, rlen);
@@ -43,8 +47,9 @@
X " .long 0x83230008 # Diagnose 83\n"
X " sam64"
X : /* no output */
- : "a" (obuffer), "d" (olen)
+ : "a" (cpcmd_buf), "d" (cmdlen)
X : "2", "3" );
X }
+ spin_unlock_irqrestore(&cpcmd_lock, flags);
X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/debug.c linux/arch/s390x/kernel/debug.c
--- v2.4.12/linux/arch/s390x/kernel/debug.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/debug.c Thu Oct 11 09:04:57 2001

diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- v2.4.12/linux/arch/s390x/kernel/entry.S Tue Oct 9 17:06:51 2001
+++ linux/arch/s390x/kernel/entry.S Thu Oct 11 09:04:57 2001
@@ -89,17 +89,25 @@


X * R15 - kernel stack pointer
X */
X
- .macro SAVE_ALL psworg # system entry macro
+ .macro SAVE_ALL psworg,sync # system entry macro

X stmg %r14,%r15,__LC_SAVE_AREA
- stam %a2,%a4,__LC_SAVE_AREA+16


X tm \psworg+1,0x01 # test problem state bit

- jz 0f # skip stack setup save
- lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
- slr %r14,%r14
- sar %a2,%r14 # set ac.reg. 2 to primary space
- lhi %r14,1
- sar %a4,%r14 # set access reg. 4 to home space
-0: aghi %r15,-SP_SIZE # make room for registers & psw
+ stam %a2,%a4,__LC_SAVE_AREA+16
+ .if \sync
+ jz 1f # skip stack setup save
+ .else
+ jnz 0f # from user -> load kernel stack
+ lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ?
+ slgr %r14,%r15
+ srag %r14,%r14,14
+ jz 1f
+ lg %r15,__LC_ASYNC_STACK # load async. stack
+ j 1f
+ .endif
+0: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ larl %r14,.Lc_ac
+ lam %a2,%a4,0(%r14)
+1: aghi %r15,-SP_SIZE # make room for registers & psw
X nill %r15,0xfff8 # align stack pointer to 8
X stmg %r0,%r14,SP_R0(%r15) # store gprs 0-14 to kernel stack
X stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
@@ -112,7 +120,7 @@
X xc 0(8,%r15),0(%r15) # clear back chain


X .endm
X
- .macro RESTORE_ALL # system exit macro
+ .macro RESTORE_ALL sync # system exit macro

X mvc __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore


X lam %a0,%a15,SP_AREGS(%r15) # load the access registers

X lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
@@ -121,8 +129,8 @@


X .endm
X
X .macro GET_CURRENT

- lghi %r9,-16384 # load pointer to task_struct to %r9
- ngr %r9,15
+ lg %r9,__LC_KERNEL_STACK # load pointer to task_struct to %r9
+ aghi %r9,-16384
X .endm
X
X
@@ -161,13 +169,32 @@


X br %r14
X
X /*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+ .global do_call_softirq
+do_call_softirq:

+ stmg %r12,%r15,48(%r15)
+ lgr %r12,%r15
+ lg %r0,__LC_ASYNC_STACK
+ slgr %r0,%r15
+ srag %r0,%r0,14
+ je 0f
+ lg %r15,__LC_ASYNC_STACK
+0: aghi %r15,-STACK_FRAME_OVERHEAD
+ stg %r12,0(%r15) # store back chain
+ brasl %r14,do_softirq
+ lmg %r12,%r15,48(%r12)


+ br %r14
+
+/*
X * SVC interrupt handler routine. System calls are synchronous events and
X * are executed with interrupts enabled.
X */
X
X .globl system_call
X system_call:
- SAVE_ALL __LC_SVC_OLD_PSW
+ SAVE_ALL __LC_SVC_OLD_PSW,1
X mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid
X pgm_system_call:
X GET_CURRENT # load pointer to task_struct to R9

@@ -202,7 +229,7 @@
X tm SP_PGM_OLD_ILC(%r15),0xff
X jz pgm_svcret
X stnsm 48(%r15),0xfc # disable I/O and ext. interrupts


- RESTORE_ALL
+ RESTORE_ALL 1
X
X #
X # call do_signal before return

@@ -565,9 +592,9 @@
X .long SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
X .long SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
X .long SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
- .long SYSCALL(sys_ni_syscall,sys32_stat64) /* 195 */
- .long SYSCALL(sys_ni_syscall,sys32_lstat64)
- .long SYSCALL(sys_ni_syscall,sys32_fstat64)
+ .long SYSCALL(sys_ni_syscall,sys32_stat64_wrapper) /* 195 */
+ .long SYSCALL(sys_ni_syscall,sys32_lstat64_wrapper)
+ .long SYSCALL(sys_ni_syscall,sys32_fstat64_wrapper)
X .long SYSCALL(sys_lchown,sys32_lchown_wrapper)
X .long SYSCALL(sys_getuid,sys_getuid)
X .long SYSCALL(sys_getgid,sys_getgid) /* 200 */
@@ -592,7 +619,10 @@
X .long SYSCALL(sys_madvise,sys32_madvise_wrapper)
X .long SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
X .long SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
- .rept 255-221
+ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
+ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
+ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
+ .rept 255-224
X .long SYSCALL(sys_ni_syscall,sys_ni_syscall)
X .endr


X
@@ -626,7 +656,7 @@

X lpswe __LC_PGM_OLD_PSW
X # it was a single stepped SVC that is causing all the trouble
X pgm_svcper:


- SAVE_ALL __LC_SVC_OLD_PSW
+ SAVE_ALL __LC_SVC_OLD_PSW,1

X mvc SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
X j pgm_system_call # now do the svc
X pgm_svcret:
@@ -636,7 +666,7 @@


X mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid

X j pgm_no_sv
X pgm_sv:
- SAVE_ALL __LC_PGM_OLD_PSW
+ SAVE_ALL __LC_PGM_OLD_PSW,1


X mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid

X llgh %r7,__LC_PGM_ILC # load instruction length
X GET_CURRENT
@@ -668,7 +698,7 @@
X */


X .globl io_int_handler
X io_int_handler:
- SAVE_ALL __LC_IO_OLD_PSW
+ SAVE_ALL __LC_IO_OLD_PSW,0
X GET_CURRENT # load pointer to task_struct to R9
X la %r2,SP_PTREGS(%r15) # address of register-save area

X llgh %r3,__LC_SUBCHANNEL_NR # load subchannel number
@@ -701,7 +731,7 @@
X jnz io_signal_return
X io_leave:
X stnsm 48(%r15),0xfc # disable I/O and ext. interrupts


- RESTORE_ALL
+ RESTORE_ALL 0
X
X #

X # call do_softirq and return from syscall, if interrupt-level
@@ -732,7 +762,7 @@
X */


X .globl ext_int_handler
X ext_int_handler:
- SAVE_ALL __LC_EXT_OLD_PSW
+ SAVE_ALL __LC_EXT_OLD_PSW,0
X GET_CURRENT # load pointer to task_struct to R9
X la %r2,SP_PTREGS(%r15) # address of register-save area

X llgh %r3,__LC_EXT_INT_CODE # error code
@@ -760,10 +790,10 @@
X */


X .globl mcck_int_handler
X mcck_int_handler:
- SAVE_ALL __LC_MCK_OLD_PSW
+ SAVE_ALL __LC_MCK_OLD_PSW,0

X brasl %r14,s390_do_machine_check


X mcck_return:
- RESTORE_ALL
+ RESTORE_ALL 0
X
X #ifdef CONFIG_SMP
X /*

@@ -771,10 +801,10 @@


X */
X .globl restart_int_handler
X restart_int_handler:

- lg %r15,__LC_KERNEL_STACK # load ksp
- lhi %r10,__LC_CREGS_SAVE_AREA
+ lg %r15,__LC_SAVE_AREA+120 # load ksp
+ lghi %r10,__LC_CREGS_SAVE_AREA
X lctlg %c0,%c15,0(%r10) # get new ctl regs
- lhi %r10,__LC_AREGS_SAVE_AREA
+ lghi %r10,__LC_AREGS_SAVE_AREA
X lam %a0,%a15,0(%r10)


X stosm 0(%r15),0x04 # now we can turn dat on

X lmg %r6,%r15,48(%r15) # load registers from clone
@@ -794,3 +824,8 @@
X restart_go:
X #endif
X
+/*
+ * Integer constants
+ */
+ .align 4
+.Lc_ac: .long 0,0,1
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/head.S linux/arch/s390x/kernel/head.S
--- v2.4.12/linux/arch/s390x/kernel/head.S Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/head.S Thu Oct 11 09:04:57 2001
@@ -261,7 +261,7 @@
X l %r1,0xb8 # load ipl subchannel number
X la %r2,IPL_BS # load start address
X bas %r14,.Lloader # load rest of ipl image
- larl %r12,parmarea # pointer to parameter area
+ larl %r12,_pstart # pointer to parameter area
X st %r1,IPL_DEVICE+4-PARMAREA(%r12) # store ipl device number
X
X #
@@ -464,7 +464,7 @@
X sigp %r1,%r0,0x12 # switch to esame mode
X sam64 # switch to 64 bit mode
X lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
- larl %r12,parmarea # pointer to parameter area
+ larl %r12,_pstart # pointer to parameter area


X # move IPL device to lowcore

X mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
X # set program check new psw mask
@@ -472,42 +472,64 @@
X

X
X #
-# find out memory size.
+# find memory chunks.
X #

- la %r1,1f-.LPG1(%r13) # set program check address
+ larl %r1,.Lchkmem # set program check address
X stg %r1,__LC_PGM_NEW_PSW+8
- lghi %r2,1
- sllg %r2,%r2,17 # test in increments of 128KB
- lgr %r1,%r2
- aghi %r1,-8 # test last word in the segment
-0: lg %r0,0(%r1) # test 128KB segment
- stg %r0,0(%r1)
- algr %r1,%r2 # add 128KB
- bc 12,0b-.LPG1(%r13) # r1 < 2^64 -> loop
-1: ng %r1,.L4malign-.LPG1(%r13) # align to multiples of 4M
- larl %r3,memory_size-.
- stg %r1,0(%r3) # store memory size
-#
-# find out memory size part 2. Running native the HSA is located at
-# 2GB and we will get an addressing exception trying to access it.
-# We have to restart the scan at 2GB to find out if the machine has
-# more than 2GB of storage.
-#
- la %r1,1f-.LPG1(%r13) # set program check address
- stg %r1,__LC_PGM_NEW_PSW+8
- lg %r1,.Lscan2g-.LPG1(%r13) # restart scanning @ 2GB + 128K - 8
-0: lg %r0,0(%r1) # test 128KB segment
- stg %r0,0(%r1)
- algr %r1,%r2 # add 128 KB
- bc 12,0b-.LPG1(%r13) # r1 < 2^64 -> loop
-1: clg %r1,.Lscan2g-.LPG1(%r13) # program check @ 2GB + 128K - 8 ?
- be 2f-.LPG1(%r13)
- ng %r1,.L4malign-.LPG1(%r13) # align to multiples of 4M
- larl %r3,memory_size-.
- stg %r1,0(%r3) # store memory size
-2:


+ la %r1,1 # test in increments of 128KB

+ sllg %r1,%r1,17
+ larl %r3,memory_chunk
+ slgr %r4,%r4 # set start of chunk to zero
+ slgr %r5,%r5 # set end of chunk to zero


+ slr %r6,%r6 # set access code to zero
+.Lloop:
+ tprot 0(%r5),0 # test protection of first byte
+ ipm %r7
+ srl %r7,28
+ clr %r6,%r7 # compare cc with last access code

+ je .Lsame
+ clgr %r4,%r5 # chunk size > 0?
+ je .Lsize0
+ stg %r4,0(%r3) # store start address of chunk
+ lgr %r0,%r5
+ slgr %r0,%r4
+ stg %r0,8(%r3) # store size of chunk
+ st %r6,20(%r3) # store type of chunk
+ la %r3,24(%r3)
+ lgr %r4,%r5 # set start to end
+ larl %r8,memory_size
+ stg %r5,0(%r8) # store memory size


+.Lsize0:
+ lr %r6,%r7 # set access code to last cc
+.Lsame:

+ algr %r5,%r1 # add 128KB to end of chunk
+ brc 12,.Lloop
+.Lchkmem: # > 16EB or tprot got a program check
+ clgr %r4,%r5 # chunk size > 0?
+ je .Ldonemem
+ stg %r4,0(%r3) # store start address of chunk
+ lgr %r0,%r5
+ slgr %r0,%r4
+ stg %r0,8(%r3) # store size of chunk
+ st %r6,20(%r3) # store type of chunk
+ la %r3,24(%r3)
+ lgr %r4,%r5
+ larl %r8,memory_size
+ stg %r5,0(%r8) # store memory size
+#
+# Running native the HSA is located at 2GB and we will get an
+# addressing exception trying to access it. We have to restart


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 08'
echo 'File patch-2.4.13 is continued in part 09'
echo "09" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:39 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part09

#!/bin/sh -x
# this is part 09 of a 53 - part archive


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

if test "$Scheck" != 09; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+# the scan at 2GB to find out if the machine has more than 2GB.
+#
+ lghi %r4,1
+ sllg %r4,%r4,31
+ clgr %r5,%r4
+ jhe .Ldonemem
+ lgr %r5,%r4
+ j .Lloop
+.Ldonemem:
X
- larl %r12,machine_flags-.
+ larl %r12,machine_flags


X #
X # find out if we are running under VM

X #
@@ -539,7 +561,7 @@
X .Lentry:.quad 0x0000000180000000,_stext
X .Lctl: .quad 0x04b50002 # cr0: various things
X .quad 0 # cr1: primary space segment table
- .quad 0 # cr2: access register translation
+ .quad .Lduct # cr2: dispatchable unit control table
X .quad 0 # cr3: instruction authorization
X .quad 0 # cr4: instruction authorization
X .quad 0 # cr5: various things
@@ -557,11 +579,16 @@
X .L4malign:.quad 0xffffffffffc00000
X .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8


X
+ .org PARMAREA-64
+.Lduct: .long 0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0
+
X #
X # params at 10400 (setup.h)
X #
X .org PARMAREA
-parmarea:
+ .global _pstart
+_pstart:

X .quad 0 # IPL_DEVICE
X .quad RAMDISK_ORIGIN # INITRD_START
X .quad RAMDISK_SIZE # INITRD_SIZE
@@ -569,31 +596,28 @@

- st %r1,__LC_IPLDEV # store ipl device number
X larl %r15,init_task_union
X aghi %r15,16384 # init_task_union + 16384
X stg %r15,__LC_KERNEL_STACK # set end of kernel stack
X aghi %r15,-160
X xc 0(8,%r15),0(%r15) # set backchain to zero
- lghi %r0,-1
- stg %r0,__LC_KERNEL_LEVEL # set interrupt count to -1


X #
X # clear bss memory
X #

@@ -621,6 +645,5 @@


X #
X .align 8

X .Ldw: .quad 0x0002000180000000,0x0000000000000000
-.Lprefix: .long init_S390_lowcore
X .Laregs: .long 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/ioctl32.c linux/arch/s390x/kernel/ioctl32.c
--- v2.4.12/linux/arch/s390x/kernel/ioctl32.c Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/ioctl32.c Thu Oct 11 09:04:57 2001
@@ -27,6 +27,7 @@
X #include <asm/types.h>
X #include <asm/uaccess.h>
X #include <asm/dasd.h>
+#include <asm/sockios.h>
X
X #include "linux32.h"
X
@@ -451,6 +452,8 @@
X IOCTL32_DEFAULT(VT_RESIZEX),
X IOCTL32_DEFAULT(VT_LOCKSWITCH),
X IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
+
+ IOCTL32_DEFAULT(SIOCGSTAMP),
X
X IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
X IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- v2.4.12/linux/arch/s390x/kernel/linux32.c Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/linux32.c Thu Oct 11 09:04:57 2001
@@ -2884,7 +2884,7 @@
X err = copy_from_user(kaddr + offset, (char *)A(str),
X bytes_to_copy);
X flush_page_to_ram(page);
- kunmap((unsigned long)kaddr);
+ kunmap(page);
X
X if (err)
X return -EFAULT;
@@ -4038,57 +4038,55 @@
X }
X
X struct stat64_emu31 {
- unsigned short st_dev;
- unsigned char __pad0[6];
-
- long long st_ino;
- unsigned int st_mode;
- unsigned int st_nlink;
-
- __u32 st_uid;
- __u32 st_gid;
-
- unsigned short st_rdev;
- unsigned char __pad3[10];
-
- long long st_size;
- __u32 st_blksize;
-
- __u32 st_blocks; /* Number 512-byte blocks allocated. */
- __u32 __pad4; /* future possible st_blocks high bits */
-
- __u32 st_atime;
- __u32 __pad5;
-
- __u32 st_mtime;
- __u32 __pad6;
-
- __u32 st_ctime;
- __u32 __pad7; /* will be high 32 bits of ctime someday */
-
- __u32 __unused1;
- __u32 __unused2;
-};
+ unsigned char __pad0[6];
+ unsigned short st_dev;
+ unsigned int __pad1;
+#define STAT64_HAS_BROKEN_ST_INO 1
+ u32 __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ u32 st_uid;
+ u32 st_gid;
+ unsigned char __pad2[6];
+ unsigned short st_rdev;
+ unsigned int __pad3;
+ long st_size;
+ u32 st_blksize;
+ unsigned char __pad4[4];
+ u32 __pad5; /* future possible st_blocks high bits */
+ u32 st_blocks; /* Number 512-byte blocks allocated. */
+ u32 st_atime;
+ u32 __pad6;
+ u32 st_mtime;
+ u32 __pad7;
+ u32 st_ctime;
+ u32 __pad8; /* will be high 32 bits of ctime someday */
+ unsigned long st_ino;
+};
X
X static inline int
X putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
X {
- int err;
-
- err = put_user (kbuf->st_dev, &ubuf->st_dev);
- err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
- err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
- err |= __put_user (kbuf->st_nlink, &ubuf->st_nlink);
- err |= __put_user (kbuf->st_uid, &ubuf->st_uid);
- err |= __put_user (kbuf->st_gid, &ubuf->st_gid);
- err |= __put_user (kbuf->st_rdev, &ubuf->st_rdev);
- err |= __put_user (kbuf->st_size, &ubuf->st_size);
- err |= __put_user (kbuf->st_blksize, &ubuf->st_blksize);
- err |= __put_user (kbuf->st_blocks, &ubuf->st_blocks);
- err |= __put_user (kbuf->st_atime, &ubuf->st_atime);
- err |= __put_user (kbuf->st_mtime, &ubuf->st_mtime);
- err |= __put_user (kbuf->st_ctime, &ubuf->st_ctime);
- return err;
+ struct stat64_emu31 tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ tmp.st_dev = (unsigned short)kbuf->st_dev;
+ tmp.st_ino = kbuf->st_ino;
+ tmp.__st_ino = (u32)kbuf->st_ino;
+ tmp.st_mode = kbuf->st_mode;
+ tmp.st_nlink = (unsigned int)kbuf->st_nlink;
+ tmp.st_uid = kbuf->st_uid;
+ tmp.st_gid = kbuf->st_gid;
+ tmp.st_rdev = (unsigned short)kbuf->st_rdev;
+ tmp.st_size = kbuf->st_size;
+ tmp.st_blksize = (u32)kbuf->st_blksize;
+ tmp.st_blocks = (u32)kbuf->st_blocks;
+ tmp.st_atime = (u32)kbuf->st_atime;
+ tmp.st_mtime = (u32)kbuf->st_mtime;
+ tmp.st_ctime = (u32)kbuf->st_ctime;
+
+ return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
X }
X
X extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
@@ -4131,7 +4129,7 @@
X return err;
X
X set_fs (KERNEL_DS);
- ret = sys_newstat(tmp, &s);
+ ret = sys_newlstat(tmp, &s);
X set_fs (old_fs);
X putname(tmp);
X if (putstat64 (statbuf, &s))
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/linux32.h linux/arch/s390x/kernel/linux32.h
--- v2.4.12/linux/arch/s390x/kernel/linux32.h Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/linux32.h Thu Oct 11 09:04:57 2001
@@ -237,8 +237,8 @@
X __u32 uc_flags;
X __u32 uc_link; /* pointer */
X stack_t32 uc_stack;
+ _sigregs32 uc_mcontext;
X sigset_t32 uc_sigmask; /* mask last for extensibility */
- __u32 sc; /* pointer */
X };
X
X #endif /* !CONFIG_S390_SUPPORT */
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/lowcore.S linux/arch/s390x/kernel/lowcore.S
--- v2.4.12/linux/arch/s390x/kernel/lowcore.S Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/lowcore.S Wed Dec 31 16:00:00 1969
@@ -1,28 +0,0 @@


-/*
- * arch/s390/kernel/lowcore.S
- * S390 lowcore definition.
- *

- * S390 64 bit Version
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Hartmut Penner (hpe...@de.ibm.com)


- * Martin Schwidefsky (schwi...@de.ibm.com),
- */

-#include <asm/lowcore.h>
-
- .align 8192
- .globl init_S390_lowcore
-init_S390_lowcore:
- .fill 0x1a0-0x000,1,0
- .quad _RESTART_PSW_MASK
- .quad restart_int_handler
- .quad _EXT_PSW_MASK
- .quad ext_int_handler
- .quad _SVC_PSW_MASK
- .quad system_call
- .quad _PGM_PSW_MASK
- .quad pgm_check_handler
- .quad _MCCK_PSW_MASK
- .quad mcck_int_handler
-EXT_PSW: .quad _IO_PSW_MASK
- .quad io_int_handler
- .fill 0x2000-0x200,1,0
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/mathemu.c linux/arch/s390x/kernel/mathemu.c
--- v2.4.12/linux/arch/s390x/kernel/mathemu.c Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/mathemu.c Wed Dec 31 16:00:00 1969
@@ -1,920 +0,0 @@
-/*
- * arch/s390/kernel/mathemu.c


- *
- * S390 version

- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Martin Schwidefsky (schwi...@de.ibm.com),
- *
- * 'mathemu.c' handles IEEE instructions on a S390 processor
- * that does not have the IEEE fpu


- */
-
-#include <linux/config.h>

-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-
-#include <asm/uaccess.h>
-#include <asm/mathemu.h>
-
-#ifdef CONFIG_SYSCTL
-int sysctl_ieee_emulation_warnings=1;
-#endif
-
-static void display_emulation_not_implemented(char *instr)
-{
- struct pt_regs *regs;
- __u16 *location;
-
-#if CONFIG_SYSCTL
- if(sysctl_ieee_emulation_warnings)
-#endif
- {
- regs=current->thread.regs;
- location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);
- printk("%s ieee fpu instruction not emulated process name: %s pid: %d \n",
- instr,
- current->comm, current->pid);
- printk("%s's PSW: %08lx %08lx\n",instr,
- (unsigned long) regs->psw.mask,
- (unsigned long) location);
- }
-}
-
-
-static void set_CC_df(__u64 val1,__u64 val2) {
- int rc;
- rc = __cmpdf2(val1,val2);
- current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFFL;
- switch (rc) {
- case -1:
- current->thread.regs->psw.mask |= 0x0000100000000000L;
- break;
- case 1:
- current->thread.regs->psw.mask |= 0x0000200000000000L;


- break;
- }
-}
-

-static void set_CC_sf(__u32 val1,__u32 val2) {
- int rc;
- rc = __cmpsf2(val1,val2);
- current->thread.regs->psw.mask &= 0xFFFFCFFFFFFFFFFF;
- switch (rc) {
- case -1:
- current->thread.regs->psw.mask |= 0x0000100000000000L;
- break;
- case 1:
- current->thread.regs->psw.mask |= 0x0000200000000000L;


- break;
- }
-}
-
-

-static void emu_adb (int rx, __u64 val) {
- current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,val);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_adbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = __adddf3(current->thread.fp_regs.fprs[rx].d,
- current->thread.fp_regs.fprs[ry].d);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_aeb (int rx, __u32 val) {
- current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,val);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_aebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __addsf3(current->thread.fp_regs.fprs[rx].f,
- current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_axbr (int rx, int ry) {
- display_emulation_not_implemented("axbr");
-}
-
-static void emu_cdb (int rx, __u64 val) {
- set_CC_df(current->thread.fp_regs.fprs[rx].d,val);
-}
-
-static void emu_cdbr (int rx, int ry) {
- set_CC_df(current->thread.fp_regs.fprs[rx].d,current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cdfbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d =
- __floatsidf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_ceb (int rx, __u32 val) {
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,val);
-}
-
-static void emu_cebr (int rx, int ry) {
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cefbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f =
- __floatsisf(current->thread.regs->gprs[ry]);
-}
-
-static void emu_cfdbr (int rx, int ry, int mask) {
- current->thread.regs->gprs[rx] =
- __fixdfsi(current->thread.fp_regs.fprs[ry].d);
-}
-
-static void emu_cfebr (int rx, int ry, int mask) {
- current->thread.regs->gprs[rx] =
- __fixsfsi(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_cfxbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("cfxbr");
-}
-
-static void emu_cxbr (int rx, int ry) {
- display_emulation_not_implemented("cxbr");
-}
-
-static void emu_cxfbr (int rx, int ry) {
- display_emulation_not_implemented("cxfbr");
-}
-
-static void emu_ddb (int rx, __u64 val) {
- current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,val);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ddbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = __divdf3(current->thread.fp_regs.fprs[rx].d,
- current->thread.fp_regs.fprs[ry].d);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_deb (int rx, __u32 val) {
- current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,val);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_debr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __divsf3(current->thread.fp_regs.fprs[rx].f,
- current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_didbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("didbr");
-}
-
-static void emu_diebr (int rx, int ry, int mask) {
- display_emulation_not_implemented("diebr");
-}
-
-static void emu_dxbr (int rx, int ry) {
- display_emulation_not_implemented("dxbr");
-}
-
-static void emu_efpc (int rx, int ry) {
- display_emulation_not_implemented("efpc");
-}
-
-static void emu_fidbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("fidbr");
-}
-
-static void emu_fiebr (int rx, int ry, int mask) {
- display_emulation_not_implemented("fiebr");
-}
-
-static void emu_fixbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("fixbr");
-}
-
-static void emu_kdb (int rx, __u64 val) {
- display_emulation_not_implemented("kdb");
-}
-
-static void emu_kdbr (int rx, int ry) {
- display_emulation_not_implemented("kdbr");
-}
-
-static void emu_keb (int rx, __u32 val) {
- display_emulation_not_implemented("keb");
-}
-
-static void emu_kebr (int rx, int ry) {
- display_emulation_not_implemented("kebr");
-}
-
-static void emu_kxbr (int rx, int ry) {
- display_emulation_not_implemented("kxbr");
-}
-
-static void emu_lcdbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d =
- __negdf2(current->thread.fp_regs.fprs[ry].d);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_lcebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f =
- __negsf2(current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lcxbr (int rx, int ry) {
- display_emulation_not_implemented("lcxbr");
-}
-
-static void emu_ldeb (int rx, __u32 val) {
- current->thread.fp_regs.fprs[rx].d = __extendsfdf2(val);
-}
-
-static void emu_ldebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d =
- __extendsfdf2(current->thread.fp_regs.fprs[ry].f);
-}
-
-static void emu_ldxbr (int rx, int ry) {
- display_emulation_not_implemented("ldxbr");
-}
-
-static void emu_ledbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __truncdfsf2(current->thread.fp_regs.fprs[ry].d);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lexbr (int rx, int ry) {
- display_emulation_not_implemented("lexbr");
-}
-
-static void emu_lndbr (int rx, int ry) {
- display_emulation_not_implemented("lndbr");
-}
-
-static void emu_lnebr (int rx, int ry) {
- display_emulation_not_implemented("lnebr");
-}
-
-static void emu_lnxbr (int rx, int ry) {
- display_emulation_not_implemented("lnxbr");
-}
-
-static void emu_lpdbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = __absdf2(current->thread.fp_regs.fprs[ry].d);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0);
-}
-
-static void emu_lpebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __abssf2(current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_lpxbr (int rx, int ry) {
- display_emulation_not_implemented("lpxbr");
-}
-
-static void emu_ltdbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = current->thread.fp_regs.fprs[ry].d;
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_ltebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = current->thread.fp_regs.fprs[ry].f;
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_ltxbr (int rx, int ry) {
- display_emulation_not_implemented("ltxbr");
-}
-
-static void emu_lxdb (int rx, __u64 val) {
- display_emulation_not_implemented("lxdb");
-}
-
-static void emu_lxdbr (int rx, int ry) {
- display_emulation_not_implemented("lxdbr");
-}
-
-static void emu_lxeb (int rx, __u32 val) {
- display_emulation_not_implemented("lxeb");
-}
-
-static void emu_lxebr (int rx, int ry) {
- display_emulation_not_implemented("lxebr");
-}
-
-static void emu_madb (int rx, __u64 val, int mask) {
- display_emulation_not_implemented("madb");
-}
-
-static void emu_madbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("madbr");
-}
-
-static void emu_maeb (int rx, __u32 val, int mask) {
- display_emulation_not_implemented("maeb");
-}
-
-static void emu_maebr (int rx, int ry, int mask) {
- display_emulation_not_implemented("maebr");
-}
-
-static void emu_mdb (int rx, __u64 val) {
- current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,val);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = __muldf3(current->thread.fp_regs.fprs[rx].d,
- current->thread.fp_regs.fprs[ry].d);
- set_CC_df(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_mdeb (int rx, __u32 val) {
- display_emulation_not_implemented("mdeb");
-}
-
-static void emu_mdebr (int rx, int ry) {
- display_emulation_not_implemented("mdebr");
-}
-
-static void emu_meeb (int rx, __u32 val) {
- current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
- val);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_meebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __mulsf3(current->thread.fp_regs.fprs[rx].f,
- current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_msdb (int rx, __u64 val, int mask) {
- display_emulation_not_implemented("msdb");
-}
-
-static void emu_msdbr (int rx, int ry, int mask) {
- display_emulation_not_implemented("msdbr");
-}
-
-static void emu_mseb (int rx, __u32 val, int mask) {
- display_emulation_not_implemented("mseb");
-}
-
-static void emu_msebr (int rx, int ry, int mask) {
- display_emulation_not_implemented("msebr");
-}
-
-static void emu_mxbr (int rx, int ry) {
- display_emulation_not_implemented("mxbr");
-}
-
-static void emu_mxdb (int rx, __u64 val) {
- display_emulation_not_implemented("mxdb");
-}
-
-static void emu_mxdbr (int rx, int ry) {
- display_emulation_not_implemented("mxdbr");
-}
-
-static void emu_sdb (int rx, __u64 val) {
- current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
- val);
- set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_sdbr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].d = __subdf3(current->thread.fp_regs.fprs[rx].d,
- current->thread.fp_regs.fprs[ry].d);
- set_CC_sf(current->thread.fp_regs.fprs[rx].d,0ULL);
-}
-
-static void emu_seb (int rx, __u32 val) {
- current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
- val);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sebr (int rx, int ry) {
- current->thread.fp_regs.fprs[rx].f = __subsf3(current->thread.fp_regs.fprs[rx].f,
- current->thread.fp_regs.fprs[ry].f);
- set_CC_sf(current->thread.fp_regs.fprs[rx].f,0);
-}
-
-static void emu_sfpc (int rx, int ry) {
- display_emulation_not_implemented("sfpc");
-}
-
-static void emu_sqdb (int rx, __u64 val) {
- display_emulation_not_implemented("sqdb");
-}
-
-static void emu_sqdbr (int rx, int ry) {
- display_emulation_not_implemented("sqdbr");
-}
-
-static void emu_sqeb (int rx, __u32 val) {
- display_emulation_not_implemented("sqeb");
-}
-
-static void emu_sqebr (int rx, int ry) {
- display_emulation_not_implemented("sqebr");
-}
-
-static void emu_sqxbr (int rx, int ry) {
- display_emulation_not_implemented("sqxbr");
-}
-
-static void emu_sxbr (int rx, int ry) {
- display_emulation_not_implemented("sxbr");
-}
-
-static void emu_tcdb (int rx, __u64 val) {
- display_emulation_not_implemented("tcdb");
-}
-
-static void emu_tceb (int rx, __u32 val) {
- display_emulation_not_implemented("tceb");
-}
-
-static void emu_tcxb (int rx, __u64 val) {
- display_emulation_not_implemented("tcxb");
-}
-
-
-static inline void emu_load_regd(int reg) {
- if ((reg&9) == 0) { /* test if reg in {0,2,4,6} */
- __asm__ __volatile ( /* load reg from fp_regs.fprs[reg] */
- " bras 1,0f\n"
- " ld 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
- : "1" );
- }
-}
-
-static inline void emu_load_rege(int reg) {
- if ((reg&9) == 0) { /* test if reg in {0,2,4,6} */
- __asm__ __volatile ( /* load reg from fp_regs.fprs[reg] */
- " bras 1,0f\n"
- " le 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
- : "1" );
- }
-}
-
-static inline void emu_store_regd(int reg) {
- if ((reg&9) == 0) { /* test if reg in {0,2,4,6} */
- __asm__ __volatile ( /* store reg to fp_regs.fprs[reg] */
- " bras 1,0f\n"
- " std 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].d)
- : "1" );
- }
-}
-
-
-static inline void emu_store_rege(int reg) {
- if ((reg&9) == 0) { /* test if reg in {0,2,4,6} */
- __asm__ __volatile ( /* store reg to fp_regs.fprs[reg] */
- " bras 1,0f\n"
- " ste 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (reg<<4), "a" (&current->thread.fp_regs.fprs[reg].f)
- : "1" );
- }
-}
-
-int math_emu_b3(__u8 *opcode, struct pt_regs * regs) {
- static const __u8 format_table[] = {
- 2, 2, 2, 2, 9, 1, 2, 1, 2, 2, 2, 2, 9, 2, 4, 4,
- 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 3,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1,10, 1, 1, 3, 1, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 3,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
- 0, 0, 0, 0, 5, 6, 6, 0, 7, 8, 8, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- static const void *jump_table[]= {
- emu_lpebr, emu_lnebr, emu_ltebr, emu_lcebr,
- emu_ldebr, emu_lxdbr, emu_lxebr, emu_mxdbr,
- emu_kebr, emu_cebr, emu_aebr, emu_sebr,
- emu_mdebr, emu_debr, emu_maebr, emu_msebr,
- emu_lpdbr, emu_lndbr, emu_ltdbr, emu_lcdbr,
- emu_sqebr, emu_sqdbr, emu_sqxbr, emu_meebr,
- emu_kdbr, emu_cdbr, emu_adbr, emu_sdbr,
- emu_mdbr, emu_ddbr, emu_madbr, emu_msdbr,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- emu_lpxbr, emu_lnxbr, emu_ltxbr, emu_lcxbr,
- emu_ledbr, emu_ldxbr, emu_lexbr, emu_fixbr,
- emu_kxbr, emu_cxbr, emu_axbr, emu_sxbr,
- emu_mxbr, emu_dxbr, NULL, NULL,
- NULL, NULL, NULL, emu_diebr,
- NULL, NULL, NULL, emu_fiebr,
- NULL, NULL, NULL, emu_didbr,
- NULL, NULL, NULL, emu_fidbr,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- emu_sfpc, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- emu_efpc, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- emu_cefbr, emu_cdfbr, emu_cxfbr, NULL,
- emu_cfebr, emu_cfdbr, emu_cfxbr
- };
-
- switch (format_table[opcode[1]]) {
- case 1: /* RRE format, double operation */
- emu_store_regd((opcode[3]>>4)&15);
- emu_store_regd(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_regd((opcode[3]>>4)&15);
- emu_load_regd(opcode[3]&15);
- return 0;
- case 2: /* RRE format, float operation */
- emu_store_rege((opcode[3]>>4)&15);
- emu_store_rege(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_rege((opcode[3]>>4)&15);
- emu_load_rege(opcode[3]&15);
- return 0;
- case 3: /* RRF format, double operation */
- emu_store_regd((opcode[3]>>4)&15);
- emu_store_regd(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
- emu_load_regd((opcode[3]>>4)&15);
- emu_load_regd(opcode[3]&15);
- return 0;
- case 4: /* RRF format, float operation */
- emu_store_rege((opcode[3]>>4)&15);
- emu_store_rege(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
- emu_load_rege((opcode[3]>>4)&15);
- emu_load_rege(opcode[3]&15);
- return 0;
- case 5: /* RRE format, cefbr instruction */
- emu_store_rege((opcode[3]>>4)&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_rege((opcode[3]>>4)&15);
- return 0;
- case 6: /* RRE format, cdfbr & cxfbr instruction */
- emu_store_regd((opcode[3]>>4)&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_regd((opcode[3]>>4)&15);
- return 0;
- /* FIXME !! */
- return 0;
- case 7: /* RRF format, cfebr instruction */
- emu_store_rege(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
- return 0;
- case 8: /* RRF format, cfdbr & cfxbr instruction */
- emu_store_regd(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);
- return 0;
- case 9: /* RRE format, ldebr & mdebr instruction */
- /* float store but double load */
- emu_store_rege((opcode[3]>>4)&15);
- emu_store_rege(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_regd((opcode[3]>>4)&15);
- return 0;
- case 10: /* RRE format, ledbr instruction */
- /* double store but float load */
- emu_store_regd((opcode[3]>>4)&15);
- emu_store_regd(opcode[3]&15);


- /* call the emulation function */

- ((void (*)(int, int))jump_table[opcode[1]])
- (opcode[3]>>4,opcode[3]&15);
- emu_load_rege((opcode[3]>>4)&15);
- return 0;
- default:
- return 1;
- }
-}
-
-static void* calc_addr(struct pt_regs *regs,int rx,int rb,int disp)
-{
- rx &= 0xf;
- rb &= 0xf;
- disp &= 0xfff;
- return (void*) ((rx != 0 ? regs->gprs[rx] : 0) + /* index */
- (rb != 0 ? regs->gprs[rb] : 0) + /* base */
- disp);
-}
-
-int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {
- static const __u8 format_table[] = {
- 0, 0, 0, 0, 5, 1, 2, 1, 2, 2, 2, 2, 5, 2, 4, 4,
- 2, 1, 1, 0, 2, 1, 0, 2, 1, 1, 1, 1, 1, 1, 3, 3,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- static const void *jump_table[]= {
- NULL, NULL, NULL, NULL,
- emu_ldeb, emu_lxdb, emu_lxeb, emu_mxdb,
- emu_keb, emu_ceb, emu_aeb, emu_seb,
- emu_mdeb, emu_deb, emu_maeb, emu_mseb,
- emu_tceb, emu_tcdb, emu_tcxb, NULL,
- emu_sqeb, emu_sqdb, NULL, emu_meeb,
- emu_kdb, emu_cdb, emu_adb, emu_sdb,
- emu_mdb, emu_ddb, emu_madb, emu_msdb
- };
-
- switch (format_table[opcode[5]]) {
- case 1: /* RXE format, __u64 constant */ {
- __u64 *dxb, temp;
- __u32 opc;
-
- emu_store_regd((opcode[1]>>4)&15);


- opc = *((__u32 *) opcode);
- dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);

- /* FIXME: how to react if copy_from_user fails ? */
- copy_from_user(&temp, dxb, 8);


- /* call the emulation function */

- ((void (*)(int, __u64))jump_table[opcode[5]])
- (opcode[1]>>4,temp);
- emu_load_regd((opcode[1]>>4)&15);
- return 0;
- }
- case 2: /* RXE format, __u32 constant */ {
- __u32 *dxb, temp;
- __u32 opc;
-
- emu_store_rege((opcode[1]>>4)&15);


- opc = *((__u32 *) opcode);

- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if get_user fails ? */
- get_user(temp, dxb);


- /* call the emulation function */

- ((void (*)(int, __u32))jump_table[opcode[5]])
- (opcode[1]>>4,temp);
- emu_load_rege((opcode[1]>>4)&15);
- return 0;
- }
- case 3: /* RXF format, __u64 constant */ {
- __u32 *dxb, temp;
- __u32 opc;
-
- emu_store_regd((opcode[1]>>4)&15);


- opc = *((__u32 *) opcode);

- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if copy_from_user fails ? */
- copy_from_user(&temp, dxb, 8);


- /* call the emulation function */

- ((void (*)(int, __u32, int))jump_table[opcode[5]])
- (opcode[1]>>4,temp,opcode[4]>>4);
- emu_load_regd((opcode[1]>>4)&15);
- return 0;
- }
- case 4: /* RXF format, __u32 constant */ {
- __u32 *dxb, temp;
- __u32 opc;
-
- emu_store_rege((opcode[1]>>4)&15);


- opc = *((__u32 *) opcode);

- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if get_user fails ? */
- get_user(temp, dxb);


- /* call the emulation function */

- ((void (*)(int, __u32, int))jump_table[opcode[5]])
- (opcode[1]>>4,temp,opcode[4]>>4);
- emu_load_rege((opcode[1]>>4)&15);
- return 0;
- }
- case 5: /* RXE format, __u32 constant */
- /* store_rege and load_regd */
- {
- __u32 *dxb, temp;
- __u32 opc;
- emu_store_rege((opcode[1]>>4)&15);


- opc = *((__u32 *) opcode);

- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if get_user fails ? */
- get_user(temp, dxb);


- /* call the emulation function */

- ((void (*)(int, __u32))jump_table[opcode[5]])
- (opcode[1]>>4,temp);
- emu_load_regd((opcode[1]>>4)&15);
- return 0;
- }
- default:
- return 1;
- }
-}
-
-/*
- * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ldr(__u8 *opcode) {
- __u16 opc = *((__u16 *) opcode);
-
- if ((opc & 0x0090) == 0) { /* test if rx in {0,2,4,6} */
- /* we got an exception therfore ry can't be in {0,2,4,6} */
- __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */
- " bras 1,0f\n"
- " ld 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (opc&0x00f0),
- "a" (&current->thread.fp_regs.fprs[opc&0x000f].d)
- : "1" );
- } else if ((opc & 0x0009) == 0) { /* test if ry in {0,2,4,6} */
- __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */
- " bras 1,0f\n"
- " std 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" ((opc&0x000f)<<4),
- "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].d)
- : "1" );
- } else { /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
- current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
- current->thread.fp_regs.fprs[opc&0x000f];
- }
-}
-
-/*
- * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6}
- */
-void math_emu_ler(__u8 *opcode) {
- __u16 opc = *((__u16 *) opcode);
-
- if ((opc & 0x0090) == 0) { /* test if rx in {0,2,4,6} */
- /* we got an exception therfore ry can't be in {0,2,4,6} */
- __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */
- " bras 1,0f\n"
- " le 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" (opc&0x00f0),
- "a" (&current->thread.fp_regs.fprs[opc&0x000f].f)
- : "1" );
- } else if ((opc & 0x0009) == 0) { /* test if ry in {0,2,4,6} */
- __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */
- " bras 1,0f\n"
- " ste 0,0(%1)\n"
- "0: ex %0,0(1)"
- : /* no output */
- : "a" ((opc&0x000f)<<4),
- "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].f)
- : "1" );
- } else { /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */
- current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =
- current->thread.fp_regs.fprs[opc&0x000f];
- }
-}
-
-/*
- * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ld(__u8 *opcode, struct pt_regs * regs) {
- __u32 opc = *((__u32 *) opcode);
- __u64 *dxb;
-


- dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);

- /* FIXME: how to react if copy_from_user fails ? */
- copy_from_user(&current->thread.fp_regs.fprs[(opc>>20)&15].d, dxb, 8);
-}
-
-/*
- * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_le(__u8 *opcode, struct pt_regs * regs) {
- __u32 opc = *((__u32 *) opcode);
- __u32 *mem, *dxb;
-
- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if get_user fails ? */
- mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
- get_user(mem[0], dxb);
-}
-
-/*
- * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_std(__u8 *opcode, struct pt_regs * regs) {
- __u32 opc = *((__u32 *) opcode);
- __u64 *dxb;


- dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);

- /* FIXME: how to react if copy_to_user fails ? */
- copy_to_user(dxb, &current->thread.fp_regs.fprs[(opc>>20)&15].d, 8);
-}
-
-/*
- * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6}
- */
-void math_emu_ste(__u8 *opcode, struct pt_regs * regs) {
- __u32 opc = *((__u32 *) opcode);
- __u32 *mem, *dxb;
- dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);
- /* FIXME: how to react if put_user fails ? */
- mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);
- put_user(mem[0], dxb);
-}
-
-/*
- * Emulate LFPC D(B)
- */
-int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {
- /* FIXME: how to do that ?!? */


- return 0;
-}
-
-/*

- * Emulate STFPC D(B)
- */
-int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {
- /* FIXME: how to do that ?!? */


- return 0;
-}
-
-/*

- * Emulate SRNM D(B)
- */
-int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {
- /* FIXME: how to do that ?!? */


- return 0;
-}
-

-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
--- v2.4.12/linux/arch/s390x/kernel/process.c Tue Oct 9 17:06:51 2001
+++ linux/arch/s390x/kernel/process.c Thu Oct 11 09:04:57 2001


@@ -44,8 +44,6 @@
X #include <asm/processor.h>
X #include <asm/irq.h>
X
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
-
X asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
X
X /*

@@ -210,7 +208,7 @@


X void show_regs(struct pt_regs *regs)
X {
X char buff[80];
- int line;
+ int i, line;
X
X printk("CPU: %d\n",smp_processor_id());

X printk("Process %s (pid: %d, stackpage=%016lX)\n",
@@ -218,6 +216,17 @@


X
X for (line = 0; sprintf_regs(line, buff, current, regs); line++)
X printk(buff);
+
+ if (regs->psw.mask & PSW_PROBLEM_STATE)
+ {
+ printk("User Code:\n");
+ memset(buff, 0, 20);
+ copy_from_user(buff,
+ (char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
+ for (i = 0; i < 20; i++)
+ printk("%02x ", buff[i]);
+ printk("\n");
+ }
X }
X
X char *task_show_regs(struct task_struct *task, char *buffer)

@@ -323,28 +332,19 @@

+ return do_fork(clone_flags, newsp, &regs, 0);
X }
X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/s390_ksyms.c linux/arch/s390x/kernel/s390_ksyms.c
--- v2.4.12/linux/arch/s390x/kernel/s390_ksyms.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/s390_ksyms.c Thu Oct 11 09:04:57 2001
@@ -18,11 +18,11 @@


X /*
X * memory management
X */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(__copy_from_user_fixup);
-EXPORT_SYMBOL(__copy_to_user_fixup);
+EXPORT_SYMBOL_NOVERS(_oi_bitmap);
+EXPORT_SYMBOL_NOVERS(_ni_bitmap);
+EXPORT_SYMBOL_NOVERS(_zb_findmap);
+EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
+EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);

X
X /*
X * semaphore ops
@@ -41,12 +41,12 @@
X EXPORT_SYMBOL_NOVERS(strlen);
X EXPORT_SYMBOL_NOVERS(strchr);
X EXPORT_SYMBOL_NOVERS(strcmp);
-EXPORT_SYMBOL_NOVERS(strcat);
X EXPORT_SYMBOL_NOVERS(strncat);
X EXPORT_SYMBOL_NOVERS(strncmp);
X EXPORT_SYMBOL_NOVERS(strncpy);
X EXPORT_SYMBOL_NOVERS(strnlen);
X EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
X EXPORT_SYMBOL_NOVERS(strtok);
X EXPORT_SYMBOL_NOVERS(strpbrk);
X
@@ -66,8 +66,5 @@
X EXPORT_SYMBOL(kernel_thread);


X EXPORT_SYMBOL(console_mode);
X EXPORT_SYMBOL(console_device);
+EXPORT_SYMBOL_NOVERS(do_call_softirq);
X
-#if CONFIG_IP_MULTICAST

-/* Required for lcs gigibit ethernet multicast support */
-EXPORT_SYMBOL(arp_mc_map);
-#endif
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/setup.c linux/arch/s390x/kernel/setup.c
--- v2.4.12/linux/arch/s390x/kernel/setup.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/setup.c Thu Oct 11 09:04:57 2001


@@ -47,6 +47,9 @@
X unsigned int console_device = -1;
X unsigned long memory_size = 0;
X unsigned long machine_flags = 0;
+struct { unsigned long addr, size, type; } memory_chunk[16];
+#define CHUNK_READ_WRITE 0
+#define CHUNK_READ_ONLY 1
X __u16 boot_cpu_addr;
X int cpus_initialized = 0;
X unsigned long cpu_initialized = 0;

@@ -257,6 +260,8 @@


X * Setup function called from init/main.c just after the banner
X * was printed.
X */
+extern char _pstart, _pend, _stext;
+
X void __init setup_arch(char **cmdline_p)
X {
X unsigned long bootmap_size;

@@ -266,19 +271,14 @@


X unsigned long start_pfn, end_pfn;
X static unsigned int smptrap=0;
X unsigned long delay = 0;
+ struct _lowcore *lowcore;
+ int i;
X
X if (smptrap)
X return;
X smptrap=1;

X
X /*


- * Setup lowcore information for boot cpu
- */
- cpu_init();
- boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
- __cpu_logical_map[0] = boot_cpu_addr;
-
- /*
X * print what head.S has found out about the machine
X */
X printk((MACHINE_IS_VM) ?

@@ -287,7 +287,7 @@


X
X ROOT_DEV = to_kdev_t(0x0100);
X memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/

- memory_end = memory_size; /* detected in head.s */
+ memory_end = memory_size & ~0x200000UL; /* detected in head.s */
X init_mm.start_code = PAGE_OFFSET;
X init_mm.end_code = (unsigned long) &_etext;
X init_mm.end_data = (unsigned long) &_edata;
@@ -362,11 +362,26 @@


X bootmap_size = init_bootmem(start_pfn, end_pfn);

X
X /*


- * Register RAM pages with the bootmem allocator.
+ * Register RAM areas with the bootmem allocator.
X */
- free_bootmem(start_pfn << PAGE_SHIFT,
- (end_pfn - start_pfn) << PAGE_SHIFT);
+ for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+ unsigned long start_chunk, end_chunk;

X

+ if (memory_chunk[i].type != CHUNK_READ_WRITE)
+ continue;
+ start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+ start_chunk >>= PAGE_SHIFT;
+ end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+ end_chunk >>= PAGE_SHIFT;
+ if (start_chunk < start_pfn)
+ start_chunk = start_pfn;
+ if (end_chunk > end_pfn)
+ end_chunk = end_pfn;
+ if (start_chunk < end_chunk)
+ free_bootmem(start_chunk << PAGE_SHIFT,
+ (end_chunk - start_chunk) << PAGE_SHIFT);

+ }
+
X /*


X * Reserve the bootmem bitmap itself as well. We do this in two

X * steps (first step was init_bootmem()) because this catches
@@ -390,6 +405,36 @@
X }
X #endif
X
+ /*


+ * Setup lowcore for boot cpu
+ */

+ lowcore = (struct _lowcore *)
+ __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0);
+ memset(lowcore, 0, 2*PAGE_SIZE);


+ lowcore->restart_psw.mask = _RESTART_PSW_MASK;

+ lowcore->restart_psw.addr = (addr_t) &restart_int_handler;


+ lowcore->external_new_psw.mask = _EXT_PSW_MASK;

+ lowcore->external_new_psw.addr = (addr_t) &ext_int_handler;


+ lowcore->svc_new_psw.mask = _SVC_PSW_MASK;

+ lowcore->svc_new_psw.addr = (addr_t) &system_call;


+ lowcore->program_new_psw.mask = _PGM_PSW_MASK;

+ lowcore->program_new_psw.addr = (addr_t) &pgm_check_handler;


+ lowcore->mcck_new_psw.mask = _MCCK_PSW_MASK;

+ lowcore->mcck_new_psw.addr = (addr_t) &mcck_int_handler;


+ lowcore->io_new_psw.mask = _IO_PSW_MASK;

+ lowcore->io_new_psw.addr = (addr_t) &io_int_handler;


+ lowcore->ipl_device = S390_lowcore.ipl_device;

+ lowcore->kernel_stack = ((__u32) &init_task_union) + 16384;
+ lowcore->async_stack = (__u64)
+ __alloc_bootmem(4*PAGE_SIZE, 4*PAGE_SIZE, 0) + 16384;
+ set_prefix((__u32)(__u64) lowcore);


+ cpu_init();
+ boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+ __cpu_logical_map[0] = boot_cpu_addr;

+
+ /*


+ * Create kernel page tables and switch to virtual addressing.
+ */
X paging_init();
X
X res = alloc_bootmem_low(sizeof(struct resource));

@@ -422,30 +467,49 @@
X }
X
X /*

- for (i = 0; i < smp_num_cpus; i++) {

X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/signal.c linux/arch/s390x/kernel/signal.c
--- v2.4.12/linux/arch/s390x/kernel/signal.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/signal.c Thu Oct 11 09:04:57 2001
@@ -24,31 +24,25 @@

@@ -206,7 +200,7 @@


X err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
X if(!err)
X {
- regs->orig_gpr2 = -1; /* disable syscall checks */
+ regs->trap = -1; /* disable syscall checks */
X regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
X (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
X regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|

@@ -218,53 +212,51 @@

X
-asmlinkage long sys_sigreturn(struct pt_regs *regs)
-{
-


- if (sigreturn_common(regs,sizeof(sigframe)))
+ if (restore_sigregs(regs, &frame->sregs))
X goto badframe;
+
X return regs->gprs[2];
X
X badframe:
X force_sig(SIGSEGV, current);
X return 0;
-}
+}
X

X asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)


X {
X rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+ sigset_t set;

X
- if (sigreturn_common(regs,sizeof(rt_sigframe)))


+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;

+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
X goto badframe;


+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);

+


+ if (restore_sigregs(regs, &frame->uc.uc_mcontext))

+ goto badframe;
+


X /* It is more difficult to avoid calling this function than to
X call it and ignore errors. */
X do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);

@@ -273,7 +265,7 @@


X badframe:
X force_sig(SIGSEGV, current);
X return 0;
-}

+}
X
X /*


X * Set up a signal frame.

@@ -307,58 +299,48 @@

SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 09'
echo 'File patch-2.4.13 is continued in part 10'
echo "10" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:40 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part10

#!/bin/sh -x
# this is part 10 of a 53 - part archive


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

if test "$Scheck" != 10; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- }
X /* Set up to return from userspace. If provided, use a stub
X already in userspace. */
X if (ka->sa.sa_flags & SA_RESTORER) {
X regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
X } else {
X regs->gprs[14] = FIX_PSW(frame->retcode);
- err |= __put_user(retcode, (u16 *)(frame->retcode));
+ if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+ (u16 *)(frame->retcode)))

+ goto give_sigsegv;
X }


- return(err ? 0:frame);
-}
X
-static void setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs)
-{
- sigframe *frame;
+ /* Set up registers for signal handler */
+ regs->gprs[15] = (addr_t)frame;
+ regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+ regs->psw.mask = _USER_PSW_MASK;
X
- if((frame=setup_frame_common(sig,ka,set,regs,sizeof(sigframe),
- (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
- goto give_sigsegv;
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
- current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
- /* Martin wants this for pthreads */
+ regs->gprs[2] = map_signal(sig);
X regs->gprs[3] = (addr_t)&frame->sc;
X
X /* We forgot to include these in the sigcontext.

@@ -376,34 +358,44 @@


X static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
X sigset_t *set, struct pt_regs * regs)
X {
- rt_sigframe *frame;
- addr_t orig_sp=regs->gprs[15];
- int err;
+ int err = 0;
+ rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))

+ goto give_sigsegv;
X

@@ -558,13 +550,16 @@


X continue;
X /* FALLTHRU */
X
- case SIGSTOP:
+ case SIGSTOP: {
+ struct signal_struct *sig;
X set_current_state(TASK_STOPPED);
X current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+ sig = current->p_pptr->sig;
+ if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
X notify_parent(current, SIGCHLD);
X schedule();
X continue;
+ }
X
X case SIGQUIT: case SIGILL: case SIGTRAP:
X case SIGABRT: case SIGFPE: case SIGSEGV:

diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/signal32.c linux/arch/s390x/kernel/signal32.c
--- v2.4.12/linux/arch/s390x/kernel/signal32.c Wed Apr 11 19:02:29 2001
+++ linux/arch/s390x/kernel/signal32.c Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@


X * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
X */
X
+#include <linux/config.h>
X #include <linux/sched.h>
X #include <linux/mm.h>
X #include <linux/smp.h>

@@ -22,32 +23,27 @@


X #include <linux/ptrace.h>
X #include <linux/unistd.h>
X #include <linux/stddef.h>
+#include <linux/personality.h>
X #include <asm/ucontext.h>
X #include <asm/uaccess.h>

X #include "linux32.h"


X
-#define DEBUG_SIG 0
-
X #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
X
-/* pretcode & sig are used to store the return addr on Intel
- & the signal no as the first parameter we do this differently
- using gpr14 & gpr2. */
-

-#define SIGFRAME_COMMON32 \
-__u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; \
-struct sigcontext32 sc; \
-_sigregs32 sregs; \
-__u8 retcode[S390_SYSCALL_SIZE];
+#define _USER_PSW_MASK32 0x0701C00080000000


X
X typedef struct
X {

- SIGFRAME_COMMON32
+ __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+ struct sigcontext32 sc;
+ _sigregs32 sregs;
+ __u8 retcode[S390_SYSCALL_SIZE];
X } sigframe32;


X
X typedef struct
X {

- SIGFRAME_COMMON32
+ __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
+ __u8 retcode[S390_SYSCALL_SIZE];
X struct siginfo32 info;
X struct ucontext32 uc;
X } rt_sigframe32;
@@ -328,7 +324,7 @@
X

X if(!err)
X {
- regs->orig_gpr2 = -1; /* disable syscall checks */
+ regs->trap = -1; /* disable syscall checks */
X regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
X (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
X regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|

@@ -342,40 +338,25 @@


X return(err);
X }
X
-static int

-restore_sigcontext32(struct sigcontext32 *sc, struct pt_regs *regs,
- _sigregs32 *sregs,sigset_t *set)


-{
- unsigned int err;
-

- err=restore_sigregs32(regs,sregs);
- if(!err)
- err=__copy_from_user(&set->sig,&sc->oldmask,_SIGMASK_COPY_SIZE32);
- return(err);
-}
-
-int sigreturn_common32(struct pt_regs *regs)
+asmlinkage long sys32_sigreturn(struct pt_regs *regs)
X {
X sigframe32 *frame = (sigframe32 *)regs->gprs[15];


X sigset_t set;
X
X if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
- return -1;

- if (restore_sigcontext32(&frame->sc,regs,&frame->sregs,&set))


- return -1;
+ goto badframe;

+ if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))


+ goto badframe;
+
X sigdelsetmask(&set, ~_BLOCKABLE);
X spin_lock_irq(&current->sigmask_lock);
X current->blocked = set;
X recalc_sigpending(current);
X spin_unlock_irq(&current->sigmask_lock);
- return 0;
-}
X

-asmlinkage long sys32_sigreturn(struct pt_regs *regs)
-{
-
- if (sigreturn_common32(regs))
+ if (restore_sigregs32(regs, &frame->sregs))


X goto badframe;
+
X return regs->gprs[2];
X
X badframe:

@@ -386,11 +367,23 @@
X asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
X {
X rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
+ sigset_t set;
X stack_t st;
X int err;
X mm_segment_t old_fs = get_fs();
X
- if (sigreturn_common32(regs))


+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))

+ goto badframe;


+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+

+ if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
X goto badframe;
X
X err = __get_user(st.ss_sp, &frame->uc.uc_stack.ss_sp);
@@ -399,17 +392,18 @@
X err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
X if (err)
X goto badframe;
- set_fs (KERNEL_DS);

+
X /* It is more difficult to avoid calling this function than to
X call it and ignore errors. */

+ set_fs (KERNEL_DS);
X do_sigaltstack(&st, NULL, regs->gprs[15]);
X set_fs (old_fs);
X

X return regs->gprs[2];
X
X badframe:

- force_sig(SIGSEGV, current);
- return 0;
+ force_sig(SIGSEGV, current);
+ return 0;
X }
X
X /*
@@ -444,58 +438,54 @@


X return (void *)((sp - frame_size) & -8ul);
X }
X

-static void *setup_frame_common32(int sig, struct k_sigaction *ka,


- sigset_t *set, struct pt_regs * regs,
- int frame_size,u16 retcode)
+static inline int map_signal(int sig)
X {

- sigframe32 *frame;


- int err;
+ if (current->exec_domain
+ && current->exec_domain->signal_invmap
+ && sig < 32)
+ return current->exec_domain->signal_invmap[sig];
+ else
+ return sig;
+}
X
- frame = get_sigframe(ka, regs,frame_size);
- if (!access_ok(VERIFY_WRITE, frame,frame_size))
- return 0;

- err = save_sigregs32(regs,&frame->sregs);


- if(!err)
- err=__put_user(&frame->sregs,&frame->sc.sregs);
- if(!err)

+static void setup_frame32(int sig, struct k_sigaction *ka,


+ sigset_t *set, struct pt_regs * regs)
+{

+ sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
+ goto give_sigsegv;
+
+ if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
+ goto give_sigsegv;
+
+ if (save_sigregs32(regs, &frame->sregs))


+ goto give_sigsegv;
+ if (__put_user(&frame->sregs, &frame->sc.sregs))
+ goto give_sigsegv;
X

- err=__copy_to_user(&frame->sc.oldmask,&set->sig,_SIGMASK_COPY_SIZE32);


- if(!err)
- {
- regs->gprs[2]=(current->exec_domain
- && current->exec_domain->signal_invmap
- && sig < 32
- ? current->exec_domain->signal_invmap[sig]
- : sig);
- /* Set up registers for signal handler */
- regs->gprs[15] = (addr_t)frame;
- regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
- }

X /* Set up to return from userspace. If provided, use a stub
X already in userspace. */
X if (ka->sa.sa_flags & SA_RESTORER) {

- regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+ regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
X } else {
- regs->gprs[14] = FIX_PSW(frame->retcode);


- err |= __put_user(retcode, (u16 *)(frame->retcode));

- }


- return(err ? 0:frame);
-}

+ regs->gprs[14] = FIX_PSW(frame->retcode);

+ if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+ (u16 *)(frame->retcode)))
+ goto give_sigsegv;

+ }
X
-static void setup_frame32(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs)
-{
- sigframe32 *frame;
-
- if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(sigframe32),


- (S390_SYSCALL_OPCODE|__NR_sigreturn)))==0)
- goto give_sigsegv;
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
- current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
- /* Martin wants this for pthreads */

- regs->gprs[3] = (addr_t)&frame->sc;
+ /* Set up registers for signal handler */
+ regs->gprs[15] = (addr_t)frame;
+ regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+ regs->psw.mask = _USER_PSW_MASK32;


+
+ regs->gprs[2] = map_signal(sig);

+ regs->gprs[3] = (addr_t)&frame->sc;
+
+ /* We forgot to include these in the sigcontext.
+ To avoid breaking binary compatibility, they are passed as args. */
+ regs->gprs[4] = current->thread.trap_no;
+ regs->gprs[5] = current->thread.prot_addr;


X return;
X
X give_sigsegv:

@@ -507,33 +497,44 @@
X static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
X sigset_t *set, struct pt_regs * regs)
X {
- rt_sigframe32 *frame;


- addr_t orig_sp=regs->gprs[15];
- int err;
+ int err = 0;

+ rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
+ goto give_sigsegv;
X
- if((frame=setup_frame_common32(sig,ka,set,regs,sizeof(rt_sigframe32),
- (S390_SYSCALL_OPCODE|__NR_rt_sigreturn)))==0)
+ if (copy_siginfo_to_user32(&frame->info, info))
X goto give_sigsegv;
-
- err = copy_siginfo_to_user32(&frame->info, info);


X
X /* Create the ucontext. */
X err |= __put_user(0, &frame->uc.uc_flags);
X err |= __put_user(0, &frame->uc.uc_link);
X err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(orig_sp),

- &frame->uc.uc_stack.ss_flags);


+ err |= __put_user(sas_ss_flags(regs->gprs[15]),

+ &frame->uc.uc_stack.ss_flags);


X err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);

- regs->gprs[3] = (addr_t)&frame->info;
- regs->gprs[4] = (addr_t)&frame->uc;
-

+ err |= save_sigregs32(regs, &frame->uc.uc_mcontext);


+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
X if (err)
X goto give_sigsegv;
X
-#if DEBUG_SIG
- printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
- current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
+ } else {
+ regs->gprs[14] = FIX_PSW(frame->retcode);
+ err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+ (u16 *)(frame->retcode));
+ }
+

+ /* Set up registers for signal handler */
+ regs->gprs[15] = (addr_t)frame;
+ regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
+ regs->psw.mask = _USER_PSW_MASK32;


+
+ regs->gprs[2] = map_signal(sig);
+ regs->gprs[3] = (addr_t)&frame->info;
+ regs->gprs[4] = (addr_t)&frame->uc;
X return;
X
X give_sigsegv:

@@ -551,7 +552,7 @@
X siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
X {
X /* Are we from a system call? */
- if (regs->orig_gpr2 >= 0) {
+ if (regs->trap == __LC_SVC_OLD_PSW) {
X /* If so, check system call restarting.. */
X switch (regs->gprs[2]) {
X case -ERESTARTNOHAND:
@@ -692,12 +693,12 @@


X
X case SIGQUIT: case SIGILL: case SIGTRAP:
X case SIGABRT: case SIGFPE: case SIGSEGV:

+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
X if (do_coredump(signr, regs))
X exit_code |= 0x80;


X /* FALLTHRU */
X

X default:
- lock_kernel();
X sigaddset(&current->pending.signal, signr);
X recalc_sigpending(current);
X current->flags |= PF_SIGNALED;
@@ -712,7 +713,7 @@
X }
X
X /* Did we come from a system call? */
- if ( regs->trap == __LC_SVC_OLD_PSW /* System Call! */ ) {
+ if ( regs->trap == __LC_SVC_OLD_PSW /* System Call! */ ) {
X /* Restart the system call - no handlers present */
X if (regs->gprs[2] == -ERESTARTNOHAND ||
X regs->gprs[2] == -ERESTARTSYS ||
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/smp.c linux/arch/s390x/kernel/smp.c
--- v2.4.12/linux/arch/s390x/kernel/smp.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/smp.c Thu Oct 11 09:04:57 2001


@@ -57,6 +57,8 @@
X
X spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
X
+unsigned long cpu_online_map;

+
X /*

+}
+
+/*


+ * 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,

X unsigned long bits;
X
X /*
@@ -167,138 +257,15 @@


X do_machine_halt();
X if (test_bit(ec_power_off, &bits))
X do_machine_power_off();
-

- /*
- * Handle external call commands with a parameter area
- */

- ec = (ec_ext_call *) xchg(&S390_lowcore.ext_call_queue, 0);

- }
-}
-
-/*
- * Swap in a new request to external call queue
- */
-static inline void smp_add_ext_call(ec_ext_call *ec, struct _lowcore *lowcore)
-{
- int success;
-
- while (1) {
- ec->next = (ec_ext_call*) lowcore->ext_call_queue;
- __asm__ __volatile__ (
- " lgr 0,%2\n"
- " csg 0,%3,%1\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (success), "+m" (lowcore->ext_call_queue)
- : "d" (ec->next), "d" (ec)
- : "cc", "0" );
- if (success == 0) break;
- }
-}
-
-/*
- * Send an external call sigp to another cpu and wait for its completion.


- */
-sigp_ccode
-smp_ext_call(int cpu, void (*func)(void *info), void *info, int wait)
-{

- sigp_ccode ccode;
- ec_ext_call ec;
-
- ec.cmd = wait ? ec_callback_sync:ec_callback_async;
- atomic_set(&ec.status, ec_pending);
- ec.func = func;
- ec.info = info;

- /* swap in new request to external call queue */
- smp_add_ext_call(&ec, &get_cpu_lowcore(cpu));


- /*
- * We try once to deliver the signal. There are four possible
- * return codes:
- * 0) Order code accepted - can't show up on an external call
- * 1) Status stored - fine, wait for completion.
- * 2) Busy - there is another signal pending. Thats fine too, because
- * do_ext_call from the pending signal will execute all signals on
- * the queue. We wait for completion.
- * 3) Not operational - something very bad has happened to the cpu.
- * do not wait for completion.
- */
- ccode = signal_processor(cpu, sigp_external_call);
-
- if (ccode != sigp_not_operational)
- /* wait for completion, FIXME: possible seed of a deadlock */
- while (atomic_read(&ec.status) != (wait?ec_done:ec_executing));
-
- return ccode;

-}
-
-/*


- * Send a callback sigp to every other cpu in the system.
- */
-void smp_ext_call_others(void (*func)(void *info), void *info, int wait)
-{

- ec_ext_call ec[NR_CPUS];
- sigp_ccode ccode;
- int i;
-

- for (i = 0; i < smp_num_cpus; i++) {

- if (smp_processor_id() == i)
- continue;

- ec[i].cmd = wait ? ec_callback_sync : ec_callback_async;
- atomic_set(&ec[i].status, ec_pending);
- ec[i].func = func;
- ec[i].info = info;

- smp_add_ext_call(ec+i, &get_cpu_lowcore(i));


- ccode = signal_processor(i, sigp_external_call);
- }
-
- /* wait for completion, FIXME: possible seed of a deadlock */

- for (i = 0; i < smp_num_cpus; i++) {

- if (smp_processor_id() == i)
- continue;
- while (atomic_read(&ec[i].status) !=
- (wait ? ec_done:ec_executing));
- }
+ if (test_bit(ec_call_function, &bits))
+ do_call_function();
X }

X
X /*


X * Send an external call sigp to another cpu and return without waiting
X * for its completion.
X */
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
+static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
X {

X sigp_ccode ccode;
X
@@ -314,7 +281,7 @@


X * Send an external call sigp to every other cpu in the system and
X * return without waiting for its completion.
X */
-void smp_ext_bitcall_others(ec_bit_sig sig)
+static void smp_ext_bitcall_others(ec_bit_sig sig)
X {

X sigp_ccode ccode;
X int i;

@@ -331,51 +298,6 @@
X }
X
X /*

- break;
- }
- }
- }

- return i;
-}
-
-/*
X * this function sends a 'stop' sigp to all other CPUs in the system.
X * it goes straight through.
X */

@@ -392,7 +314,18 @@


X
X /* stop all processors */
X
- smp_signal_others(sigp_stop, 0, 1, NULL);
+ for (i = 0; i < smp_num_cpus; i++) {
+ if (smp_processor_id() != i) {
+ int ccode;
+ do {
+ ccode = signal_processor_ps(
+ &dummy,
+ 0,
+ i,
+ sigp_stop);
+ } while(ccode == sigp_busy);
+ }
+ }
X
X /* store status of all processors in their lowcores (real 0) */
X

@@ -469,7 +402,7 @@


X parms.end_ctl = cr;
X parms.orvals[cr] = 1 << bit;

X parms.andvals[cr] = -1L;


- smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+ smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
X }
X __ctl_set_bit(cr, bit);
X }

@@ -485,34 +418,11 @@
X parms.end_ctl = cr;
X parms.orvals[cr] = 0;
X parms.andvals[cr] = ~(1L << bit);


- smp_ext_call_others(smp_ctl_bit_callback, &parms, 1);
+ smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
X }
X __ctl_clear_bit(cr, bit);
X }
X

-/*


- * Call a function on all other processors
- */
-
-int
-smp_call_function(void (*func)(void *info), void *info, int retry, 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.
- * <retry> 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.
- */
-{
- if (atomic_read(&smp_commenced) != 0)
- smp_ext_call_others(func, info, wait);

- return 0;
-}
X

X /*


X * Lets check how many CPUs we have.

@@ -607,15 +517,20 @@


X init_tasks[cpu] = idle;
X
X cpu_lowcore=&get_cpu_lowcore(cpu);
- cpu_lowcore->kernel_stack=idle->thread.ksp;

- __asm__ __volatile__("stctg 0,15,%0\n\t"


- "stam 0,15,%1"
+ cpu_lowcore->save_area[15] = idle->thread.ksp;

+ cpu_lowcore->kernel_stack = (idle->thread.ksp | 16383) + 1;


+ __asm__ __volatile__("la 1,%0\n\t"

+ "stctg 0,15,0(1)\n\t"


+ "la 1,%1\n\t"
+ "stam 0,15,0(1)"
X : "=m" (cpu_lowcore->cregs_save_area[0]),
X "=m" (cpu_lowcore->access_regs_save_area[0])
- : : "memory");
+ : : "1", "memory");
X
X eieio();
X signal_processor(cpu,sigp_restart);

+ /* Mark this cpu as online. */


+ set_bit(cpu, &cpu_online_map);
X }
X
X /*

@@ -643,6 +558,7 @@


X void __init smp_boot_cpus(void)
X {

X struct _lowcore *curr_lowcore;


+ unsigned long async_stack;
X sigp_ccode ccode;
X int i;
X

@@ -673,8 +589,16 @@
X printk("smp_boot_cpus failed to allocate prefix memory\n");
X break;
X }
+ async_stack = __get_free_pages(GFP_KERNEL,2);


+ if (async_stack == 0) {

+ printk("smp_boot_cpus failed to allocate asyncronous"
+ " interrupt stack\n");
+ free_page((unsigned long) curr_lowcore);
+ break;
+ }
X lowcore_ptr[i] = curr_lowcore;
X memcpy(curr_lowcore, &S390_lowcore, sizeof(struct _lowcore));
+ curr_lowcore->async_stack = async_stack + (4 * PAGE_SIZE);


X /*
X * Most of the parameters are set up when the cpu is
X * started up.

@@ -733,8 +657,6 @@


X s390_do_profile(regs->psw.addr);
X
X if (!--prof_counter[cpu]) {
- int system = 1-user;
- struct task_struct * p = current;

X
X /*


X * The multiplier may have changed since the last time we got

@@ -756,9 +678,7 @@


X * WrongThing (tm) to do.
X */
X
- irq_enter(cpu, 0);
X update_process_times(user);
- irq_exit(cpu, 0);
X }

X }
X
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/time.c linux/arch/s390x/kernel/time.c
--- v2.4.12/linux/arch/s390x/kernel/time.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/time.c Thu Oct 11 09:04:57 2001
@@ -155,17 +155,16 @@
X extern __u16 boot_cpu_addr;
X #endif
X
-void do_timer_interrupt(struct pt_regs *regs,int error_code)
+void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)


X {
- unsigned long flags;
+ int cpu = smp_processor_id();
+
+ irq_enter(cpu, 0);

X
X /*


X * reset timer to 10ms minus time already elapsed
X * since timer-interrupt pending
X */
-
- save_flags(flags);
- cli();
X #ifdef CONFIG_SMP
X if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
X write_lock(&xtime_lock);

@@ -201,8 +200,8 @@


X write_unlock(&xtime_lock);
X #endif
X }
- restore_flags(flags);
X

+ irq_exit(cpu, 0);
X }
X
X /*
@@ -256,4 +255,7 @@


X init_timer_cc -= 0x8126d60e46000000LL -
X (0x3c26700LL*1000000*4096);
X tod_to_timeval(init_timer_cc, &xtime);
+
+ /* Set do_get_fast_time function pointer. */
+ do_get_fast_time = do_gettimeofday;

X }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/traps.c linux/arch/s390x/kernel/traps.c
--- v2.4.12/linux/arch/s390x/kernel/traps.c Sun Aug 12 13:27:58 2001
+++ linux/arch/s390x/kernel/traps.c Thu Oct 11 09:04:57 2001
@@ -31,7 +31,6 @@
X #include <asm/uaccess.h>
X #include <asm/io.h>
X #include <asm/atomic.h>
-#include <asm/mathemu.h>
X #if CONFIG_REMOTE_DEBUG
X #include <asm/gdb-stub.h>
X #endif
@@ -59,14 +58,16 @@


X extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
X #endif
X
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
X
X void die(const char * str, struct pt_regs * regs, long err)
X {
X console_verbose();
X spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
X printk("%s: %04lx\n", str, err & 0xffff);
X show_regs(regs);
+ bust_spinlocks(0);
X spin_unlock_irq(&die_lock);
X do_exit(SIGSEGV);

X }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/wrapper32.S linux/arch/s390x/kernel/wrapper32.S
--- v2.4.12/linux/arch/s390x/kernel/wrapper32.S Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/kernel/wrapper32.S Thu Oct 11 09:04:57 2001
@@ -1069,3 +1069,23 @@
X llgfr %r4,%r4 # unsigned long
X jg sys32_fcntl64 # branch to system call
X
+ .globl sys32_stat64_wrapper
+sys32_stat64_wrapper:
+ llgtr %r2,%r2 # char *
+ llgtr %r3,%r3 # struct stat64 *
+ llgfr %r4,%r4 # long
+ jg sys32_stat64 # branch to system call
+
+ .globl sys32_lstat64_wrapper
+sys32_lstat64_wrapper:
+ llgtr %r2,%r2 # char *
+ llgtr %r3,%r3 # struct stat64 *
+ llgfr %r4,%r4 # long
+ jg sys32_lstat64 # branch to system call
+
+ .globl sys32_fstat64_wrapper
+sys32_fstat64_wrapper:
+ llgfr %r2,%r2 # unsigned long
+ llgtr %r3,%r3 # struct stat64 *
+ llgfr %r4,%r4 # long
+ jg sys32_fstat64 # branch to system call
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/extable.c linux/arch/s390x/mm/extable.c
--- v2.4.12/linux/arch/s390x/mm/extable.c Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/mm/extable.c Thu Oct 11 09:04:57 2001


@@ -10,6 +10,7 @@
X
X #include <linux/config.h>
X #include <linux/module.h>
+#include <linux/spinlock.h>
X #include <asm/uaccess.h>
X
X extern const struct exception_table_entry __start___ex_table[];

@@ -36,26 +37,32 @@


X return 0;
X }
X
+extern spinlock_t modlist_lock;
+
X unsigned long
X search_exception_table(unsigned long addr)
X {
- unsigned long ret;
+ unsigned long ret = 0;
+ unsigned long flags;
X
X #ifndef CONFIG_MODULES

X /* There is only the kernel to search. */
X ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
- if (ret) return FIX_PSW(ret);

+ return ret;
X #else
X /* The kernel is the last "module" -- no need to treat it special. */
X struct module *mp;

+
+ spin_lock_irqsave(&modlist_lock, flags);
X for (mp = module_list; mp != NULL; mp = mp->next) {
- if (mp->ex_table_start == NULL)
+ if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
X continue;
X ret = search_one_table(mp->ex_table_start,
X mp->ex_table_end - 1, addr);
- if (ret) return FIX_PSW(ret);
+ if (ret)

+ break;


X }
+ spin_unlock_irqrestore(&modlist_lock, flags);
+ return ret;
X #endif
-
- return 0;

X }
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/fault.c linux/arch/s390x/mm/fault.c
--- v2.4.12/linux/arch/s390x/mm/fault.c Sun Aug 12 13:27:59 2001
+++ linux/arch/s390x/mm/fault.c Thu Oct 11 09:04:57 2001


@@ -4,6 +4,7 @@
X * S390 version
X * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
X * Author(s): Hartmut Penner (h...@de.ibm.com)
+ * Ulrich Weigand (uwei...@de.ibm.com)
X *
X * Derived from "arch/i386/mm/fault.c"
X * Copyright (C) 1995 Linus Torvalds

@@ -22,6 +23,7 @@
X #include <linux/smp.h>
X #include <linux/smp_lock.h>


X #include <linux/init.h>
+#include <linux/console.h>
X
X #include <asm/system.h>
X #include <asm/uaccess.h>

@@ -33,33 +35,33 @@


X #endif
X
X extern void die(const char *,struct pt_regs *,long);
+static void force_sigsegv(struct task_struct *tsk, int code, void *address);

X
X extern spinlock_t timerlist_lock;
X
X /*
X * Unlock any spinlocks which will prevent us from getting the
- * message out


+ * message out (timerlist_lock is acquired through the
+ * console unblank code)

X */
X void bust_spinlocks(int yes)
X {
- spin_lock_init(&timerlist_lock);
- if (yes) {
- oops_in_progress = 1;
-#ifdef CONFIG_SMP
- atomic_set(&global_irq_lock,0);
-#endif
- } else {
- int loglevel_save = console_loglevel;
- oops_in_progress = 0;
- /*
- * OK, the message is on the console. Now we call printk()
- * without oops_in_progress set so that printk will give klogd
- * a poke. Hold onto your hats...
- */
- console_loglevel = 15; /* NMI oopser may have shut the console up */
- printk(" ");
- console_loglevel = loglevel_save;
- }


+ spin_lock_init(&timerlist_lock);
+ if (yes) {
+ oops_in_progress = 1;
+ } else {
+ int loglevel_save = console_loglevel;
+ oops_in_progress = 0;
+ console_unblank();
+ /*
+ * OK, the message is on the console. Now we call printk()
+ * without oops_in_progress set so that printk will give klogd
+ * a poke. Hold onto your hats...
+ */
+ console_loglevel = 15;
+ printk(" ");
+ console_loglevel = loglevel_save;
+ }

X }
X
X /*
@@ -84,6 +86,29 @@


X int si_code = SEGV_MAPERR;
X int kernel_address = 0;
X
+ tsk = current;
+ mm = tsk->mm;

+
+ /*

+ * Check for low-address protection. This needs to be treated
+ * as a special case because the translation exception code
+ * field is not guaranteed to contain valid data in this case.
+ */
+ if ((error_code & 0xff) == 4 && !(S390_lowcore.trans_exc_code & 4)) {
+
+ /* Low-address protection hit in kernel mode means
+ NULL pointer write access in kernel mode. */
+ if (!(regs->psw.mask & PSW_PROBLEM_STATE)) {
+ address = 0;
+ kernel_address = 1;
+ goto no_context;
+ }
+
+ /* Low-address protection hit in user mode 'cannot happen'. */
+ die ("Low-address protection", regs, error_code);
+ do_exit(SIGKILL);

+ }
+
X /*

X * get the failing address
X * more specific the segment and page table portion of

@@ -92,11 +117,6 @@
X
X address = S390_lowcore.trans_exc_code&-4096L;


X
- tsk = current;
- mm = tsk->mm;
-
- if (in_interrupt() || !mm)
- goto no_context;

X
X /*
X * Check which address space the address belongs to
@@ -127,6 +147,7 @@


X }
X }
X die("page fault via unknown access register", regs, error_code);
+ do_exit(SIGKILL);
X break;
X
X case 2: /* Secondary Segment Table Descriptor */

@@ -135,6 +156,11 @@
X break;
X }
X
+ /*


+ * Check whether we have a user MM in the first place.
+ */
+ if (in_interrupt() || !mm)
+ goto no_context;

X
X /*


X * When we get here, the fault happened in the current

@@ -144,10 +170,8 @@
X down_read(&mm->mmap_sem);
X
X vma = find_vma(mm, address);
- if (!vma) {
- printk("no vma for address %lX\n",address);
+ if (!vma)
X goto bad_area;
- }
X if (vma->vm_start <= address)
X goto good_area;
X if (!(vma->vm_flags & VM_GROWSDOWN))
@@ -177,6 +201,7 @@


X goto bad_area;
X }
X
+ survive:
X /*
X * If for any reason at all we couldn't handle the fault,
X * make sure we exit gracefully rather than endlessly redo

@@ -207,7 +232,6 @@


X
X /* User mode accesses just cause a SIGSEGV */
X if (regs->psw.mask & PSW_PROBLEM_STATE) {
- struct siginfo si;
X tsk->thread.prot_addr = address;
X tsk->thread.trap_no = error_code;
X #ifndef CONFIG_SYSCTL

@@ -224,10 +248,8 @@


X show_regs(regs);
X }
X #endif
- si.si_signo = SIGSEGV;
- si.si_code = si_code;
- si.si_addr = (void*) address;
- force_sig_info(SIGSEGV, &si, tsk);
+
+ force_sigsegv(tsk, si_code, (void *)address);
X return;
X }
X

@@ -242,6 +264,7 @@
X * Oops. The kernel tried to access some bad page. We'll have to
X * terminate things with extreme prejudice.
X */
+
X if (kernel_address)
X printk(KERN_ALERT "Unable to handle kernel pointer dereference"
X " at virtual kernel address %016lx\n", address);
@@ -249,10 +272,6 @@


X printk(KERN_ALERT "Unable to handle kernel paging request"

X " at virtual user address %016lx\n", address);
X

-/*
- * need to define, which information is useful here
- */

-


X die("Oops", regs, error_code);
X do_exit(SIGKILL);

X
@@ -263,6 +282,12 @@


X */
X out_of_memory:
X up_read(&mm->mmap_sem);
+ if (tsk->pid == 1) {
+ tsk->policy |= SCHED_YIELD;
+ schedule();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
X printk("VM: killing process %s\n", tsk->comm);

X if (regs->psw.mask & PSW_PROBLEM_STATE)
X do_exit(SIGKILL);
@@ -284,6 +309,20 @@


X goto no_context;
X }
X
+/*
+ * Send SIGSEGV to task. This is an external routine
+ * to keep the stack usage of do_page_fault small.
+ */
+static void force_sigsegv(struct task_struct *tsk, int code, void *address)
+{
+ struct siginfo si;
+ si.si_signo = SIGSEGV;
+ si.si_code = code;
+ si.si_addr = address;
+ force_sig_info(SIGSEGV, &si, tsk);
+}

+
+
X #ifdef CONFIG_PFAULT
X /*
X * 'pfault' pseudo page faults routines.
@@ -316,13 +355,11 @@
X int resolved;
X } pseudo_wait_t;
X
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
X int pfault_init(void)
X {
X pfault_refbk_t refbk =
- { 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48, 0ULL };
+ { 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48,
+ 0x8000000000000000ULL };
X int rc;
X
X if (pfault_disable)
@@ -362,7 +399,6 @@


X asmlinkage void
X pfault_interrupt(struct pt_regs *regs, __u16 error_code)
X {
- DECLARE_WAITQUEUE(wait, current);
X struct task_struct *tsk;
X wait_queue_head_t queue;
X wait_queue_head_t *qp;

@@ -375,7 +411,7 @@


X * external interrupt.
X */
X subcode = S390_lowcore.cpu_addr;
- if ((subcode & 0xff00) != 0x06)
+ if ((subcode & 0xff00) != 0x0600)
X return;

X
X /*
diff -u --recursive --new-file v2.4.12/linux/arch/s390x/mm/init.c linux/arch/s390x/mm/init.c
--- v2.4.12/linux/arch/s390x/mm/init.c Sun Sep 23 11:40:56 2001
+++ linux/arch/s390x/mm/init.c Thu Oct 11 09:04:57 2001
@@ -36,7 +36,7 @@
X #include <asm/dma.h>
X #include <asm/lowcore.h>
X #include <asm/tlb.h>
-
+
X mmu_gather_t mmu_gathers[NR_CPUS];
X
X static unsigned long totalram_pages;


@@ -44,44 +44,23 @@
X pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
X char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
X
-static int test_access(unsigned long loc)
-{
- static const int ssm_mask = 0x07000000L;
- int rc, i;
-
- rc = 0;

- for (i=0; i<2; i++) {
- __asm__ __volatile__(
- " slgr %0,%0\n"


- " ssm %1\n"
- " tprot 0(%2),0\n"
- "0: jne 1f\n"

- " lghi %0,1\n"


- "1: ssm %3\n"
- ".section __ex_table,\"a\"\n"

- " .align 8\n"
- " .quad 0b,1b\n"


- ".previous"
- : "+&d" (rc) : "i" (0), "a" (loc), "m" (ssm_mask)
- : "cc");
- if (rc == 0)
- break;
- loc += 0x100000;
- }
- return rc;
-}
-
X int do_check_pgt_cache(int low, int high)
X {
X int freed = 0;
X if(pgtable_cache_size > high) {
X do {
- if(pgd_quicklist)

- free_pgd_slow(get_pgd_fast()), freed += 4;
- if(pmd_quicklist)
- pmd_free_slow(pmd_alloc_one_fast(NULL, 0)), freed += 4;


- if(pte_quicklist)
- pte_free_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+ if(pgd_quicklist) {
+ free_pgd_slow(get_pgd_fast());

+ freed += 4;


+ }
+ if(pmd_quicklist) {
+ pmd_free_slow(pmd_alloc_one_fast(NULL, 0));

+ freed += 4;


+ }
+ if(pte_quicklist) {
+ pte_free_slow(pte_alloc_one_fast(NULL, 0));

+ freed += 4;


+ }
X } while(pgtable_cache_size > low);
X }
X return freed;

@@ -139,7 +118,7 @@
X int i,j,k;
X unsigned long address=0;
X unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) |
- _REGION_TABLE;
+ _KERN_REGION_TABLE;
X unsigned long end_mem = (unsigned long) __va(max_low_pfn*PAGE_SIZE);
X static const int ssm_mask = 0x04000000L;
X
@@ -212,7 +191,6 @@


X void __init mem_init(void)
X {

X unsigned long codesize, reservedpages, datasize, initsize;
- unsigned long tmp;


X
X max_mapnr = num_physpages = max_low_pfn;
X high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);

@@ -223,25 +201,7 @@


X /* this will put all low memory onto the freelists */
X totalram_pages += free_all_bootmem();
X
- /* mark usable pages in the mem_map[] and count reserved pages */
X reservedpages = 0;
- tmp = 0;
- do {

- if (tmp && (tmp & 0x1ff) == 0 &&

- test_access(tmp * PAGE_SIZE) == 0) {

- printk("2M Segment 0x%016lX not available\n",
- tmp * PAGE_SIZE);


- do {
- set_bit(PG_reserved, &mem_map[tmp].flags);
- reservedpages++;
- tmp++;

- } while (tmp < max_low_pfn && (tmp & 0x1ff));


- } else {
- if (PageReserved(mem_map+tmp))
- reservedpages++;
- tmp++;
- }
- } while (tmp < max_low_pfn);
X
X codesize = (unsigned long) &_etext - (unsigned long) &_text;
X datasize = (unsigned long) &_edata - (unsigned long) &_etext;

diff -u --recursive --new-file v2.4.12/linux/arch/sh/Makefile linux/arch/sh/Makefile
--- v2.4.12/linux/arch/sh/Makefile Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/Makefile Mon Oct 15 13:36:48 2001
@@ -12,11 +12,6 @@
X # this architecture
X #
X
-#
-# Select the object file format to substitute into the linker script.
-#
-tool_prefix = sh-linux-gnu-
-
X ifdef CONFIG_CPU_LITTLE_ENDIAN
X CFLAGS += -ml
X AFLAGS += -ml
@@ -29,10 +24,6 @@
X LDFLAGS := -EB
X endif
X
-# ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE = $(tool_prefix)
-# endif
-
X LD =$(CROSS_COMPILE)ld $(LDFLAGS)
X OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr -S
X
@@ -46,8 +37,8 @@
X AFLAGS += -m3
X endif
X ifdef CONFIG_CPU_SH4
-CFLAGS += -m4-nofpu
-AFLAGS += -m4-nofpu
+CFLAGS += -m4 -mno-implicit-fp
+AFLAGS += -m4 -mno-implicit-fp
X endif
X
X #
diff -u --recursive --new-file v2.4.12/linux/arch/sh/config.in linux/arch/sh/config.in
--- v2.4.12/linux/arch/sh/config.in Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/config.in Mon Oct 15 13:36:48 2001
@@ -90,8 +90,17 @@
X fi
X bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
X # Platform-specific memory start and size definitions
-if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
- "$CONFIG_SH_BIGSUR" = "y" -o "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
+if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
+ define_hex CONFIG_MEMORY_START 0c000000
+ define_hex CONFIG_MEMORY_SIZE 02000000
+ define_bool CONFIG_MEMORY_SET y
+fi
+if [ "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" ]; then
+ define_hex CONFIG_MEMORY_START 0c000000
+ define_hex CONFIG_MEMORY_SIZE 04000000
+ define_bool CONFIG_MEMORY_SET y
+fi
+if [ "$CONFIG_SH_HP600" = "y" -o "$CONFIG_SH_BIGSUR" = "y" -o \
X "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then
X define_hex CONFIG_MEMORY_START 0c000000
X define_hex CONFIG_MEMORY_SIZE 00400000
@@ -326,6 +335,16 @@
X dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
X fi
X bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+
+mainmenu_option next_comment
+comment 'Watchdog Cards'
+bool 'Watchdog Timer Support' CONFIG_WATCHDOG
+if [ "$CONFIG_WATCHDOG" != "n" ]; then
+ bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+ dep_tristate ' SH 3/4 Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH
+fi
+endmenu
+
X tristate 'Enhanced Real Time Clock Support' CONFIG_RTC
X if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
X source drivers/char/pcmcia/Config.in
diff -u --recursive --new-file v2.4.12/linux/arch/sh/defconfig linux/arch/sh/defconfig
--- v2.4.12/linux/arch/sh/defconfig Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/defconfig Mon Oct 15 13:36:48 2001
@@ -201,6 +201,4 @@
X #
X # CONFIG_MAGIC_SYSRQ is not set
X CONFIG_SH_STANDARD_BIOS=y
-CONFIG_DEBUG_KERNEL_WITH_GDB_STUB=y
-CONFIG_GDB_STUB_VBR=a0000000
X CONFIG_SH_EARLY_PRINTK=y
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/io_generic.c linux/arch/sh/kernel/io_generic.c
--- v2.4.12/linux/arch/sh/kernel/io_generic.c Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_generic.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: io_generic.c,v 1.3 2000/05/07 23:31:58 gniibe Exp $
+/* $Id: io_generic.c,v 1.12 2000/11/14 16:45:11 sugioka Exp $
X *
X * linux/arch/sh/kernel/io_generic.c
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/io_hd64461.c linux/arch/sh/kernel/io_hd64461.c
--- v2.4.12/linux/arch/sh/kernel/io_hd64461.c Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_hd64461.c Mon Oct 15 13:36:48 2001


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

- * $Id: io_hd64461.c,v 1.1 2000/06/10 21:45:18 yaegashi Exp $
+ * $Id: io_hd64461.c,v 1.6 2000/11/16 23:28:44 yaegashi Exp $
X * Copyright (C) 2000 YAEGASHI Takeshi
X * Typical I/O routines for HD64461 system.
X */
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/io_se.c linux/arch/sh/kernel/io_se.c
--- v2.4.12/linux/arch/sh/kernel/io_se.c Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_se.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: io_se.c,v 1.5 2000/06/08 05:50:10 gniibe Exp $
+/* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $
X *
X * linux/arch/sh/kernel/io_se.c
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- v2.4.12/linux/arch/sh/kernel/process.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sh/kernel/process.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.34 2001/07/30 12:42:11 gniibe Exp $
+/* $Id: process.c,v 1.35 2001/10/11 09:18:17 gniibe Exp $
X *
X * linux/arch/sh/kernel/process.c
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/ptrace.c linux/arch/sh/kernel/ptrace.c
--- v2.4.12/linux/arch/sh/kernel/ptrace.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/kernel/ptrace.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.12 2001/07/23 00:00:56 gniibe Exp $
+/* $Id: ptrace.c,v 1.13 2001/10/01 02:21:50 gniibe Exp $
X *
X * linux/arch/sh/kernel/ptrace.c
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/signal.c linux/arch/sh/kernel/signal.c
--- v2.4.12/linux/arch/sh/kernel/signal.c Sun Jan 28 18:56:00 2001
+++ linux/arch/sh/kernel/signal.c Mon Oct 15 13:36:48 2001
@@ -21,6 +21,7 @@


X #include <linux/ptrace.h>
X #include <linux/unistd.h>
X #include <linux/stddef.h>
+#include <linux/personality.h>
X #include <asm/ucontext.h>
X #include <asm/uaccess.h>

X #include <asm/pgtable.h>
diff -u --recursive --new-file v2.4.12/linux/arch/sh/kernel/sys_sh.c linux/arch/sh/kernel/sys_sh.c
--- v2.4.12/linux/arch/sh/kernel/sys_sh.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/kernel/sys_sh.c Mon Oct 15 13:36:48 2001
@@ -68,7 +68,10 @@
X if (!addr)
X addr = TASK_UNMAPPED_BASE;
X
- addr = COLOUR_ALIGN(addr);
+ if (flags & MAP_PRIVATE)
+ addr = PAGE_ALIGN(addr);
+ else
+ addr = COLOUR_ALIGN(addr);
X
X for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
X /* At this point: (!vma || addr < vma->vm_end). */
@@ -77,7 +80,8 @@
X if (!vma || addr + len <= vma->vm_start)
X return addr;
X addr = vma->vm_end;
- addr = COLOUR_ALIGN(addr);
+ if (!(flags & MAP_PRIVATE))
+ addr = COLOUR_ALIGN(addr);
X }
X }
X #endif
diff -u --recursive --new-file v2.4.12/linux/arch/sh/lib/memchr.S linux/arch/sh/lib/memchr.S
--- v2.4.12/linux/arch/sh/lib/memchr.S Mon Oct 25 10:59:18 1999
+++ linux/arch/sh/lib/memchr.S Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: memchr.S,v 1.1 1999/10/17 11:32:38 gniibe Exp $
+/* $Id: memchr.S,v 1.1 2000/04/14 16:49:01 mjd Exp $
X *
X * "memchr" implementation of SuperH
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/lib/memcpy.S linux/arch/sh/lib/memcpy.S
--- v2.4.12/linux/arch/sh/lib/memcpy.S Mon Oct 18 11:16:13 1999
+++ linux/arch/sh/lib/memcpy.S Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: memcpy.S,v 1.3 1999/09/28 11:32:48 gniibe Exp $
+/* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
X *
X * "memcpy" implementation of SuperH
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/lib/memmove.S linux/arch/sh/lib/memmove.S
--- v2.4.12/linux/arch/sh/lib/memmove.S Mon Oct 18 11:16:13 1999
+++ linux/arch/sh/lib/memmove.S Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: memmove.S,v 1.2 1999/09/21 12:55:49 gniibe Exp $
+/* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $
X *
X * "memmove" implementation of SuperH
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/lib/memset.S linux/arch/sh/lib/memset.S
--- v2.4.12/linux/arch/sh/lib/memset.S Mon Oct 18 11:16:13 1999
+++ linux/arch/sh/lib/memset.S Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: memset.S,v 1.1 1999/09/18 16:57:09 gniibe Exp $
+/* $Id: memset.S,v 1.1 2000/04/14 16:49:01 mjd Exp $
X *
X * "memset" implementation of SuperH
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sh/mm/cache-sh3.c linux/arch/sh/mm/cache-sh3.c
--- v2.4.12/linux/arch/sh/mm/cache-sh3.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/mm/cache-sh3.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: cache-sh3.c,v 1.5 2001/08/24 15:31:41 dwmw2 Exp $
+/* $Id: cache-sh3.c,v 1.6 2001/09/10 08:59:59 dwmw2 Exp $
X *
X * linux/arch/sh/mm/cache-sh3.c
X *
@@ -20,10 +20,17 @@
X #include <asm/pgalloc.h>
X #include <asm/mmu_context.h>
X
+
X #define CCR 0xffffffec /* Address of Cache Control Register */
-#define CCR_CACHE_VAL 0x00000005 /* 8k-byte cache, P1-wb, enable */
-#define CCR_CACHE_INIT 0x0000000d /* 8k-byte cache, CF, P1-wb, enable */
-#define CCR_CACHE_ENABLE 1
+
+#define CCR_CACHE_CE 0x01 /* Cache Enable */
+#define CCR_CACHE_WT 0x02 /* Write-Through (for P0,U0,P3) (else writeback) */
+#define CCR_CACHE_CB 0x04 /* Write-Back (for P1) (else writethrough) */
+#define CCR_CACHE_CF 0x08 /* Cache Flush */
+#define CCR_CACHE_RA 0x20 /* RAM mode */
+
+#define CCR_CACHE_VAL (CCR_CACHE_CB|CCR_CACHE_CE) /* 8k-byte cache, P1-wb, enable */
+#define CCR_CACHE_INIT (CCR_CACHE_CF|CCR_CACHE_VAL) /* 8k-byte cache, CF, P1-wb, enable */
X
X #define CACHE_OC_ADDRESS_ARRAY 0xf0000000
X #define CACHE_VALID 1
@@ -131,7 +138,7 @@
X
X jump_to_P2();
X ccr = ctrl_inl(CCR);
- if (ccr & CCR_CACHE_ENABLE)
+ if (ccr & CCR_CACHE_CE)
X /*
X * XXX: Should check RA here.
X * If RA was 1, we only need to flush the half of the caches.
diff -u --recursive --new-file v2.4.12/linux/arch/sh/mm/cache-sh4.c linux/arch/sh/mm/cache-sh4.c
--- v2.4.12/linux/arch/sh/mm/cache-sh4.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/mm/cache-sh4.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: cache-sh4.c,v 1.15 2001/08/10 14:13:13 gniibe Exp $
+/* $Id: cache-sh4.c,v 1.16 2001/09/10 11:06:35 dwmw2 Exp $
X *
X * linux/arch/sh/mm/cache.c
X *
@@ -22,9 +22,21 @@
X #include <asm/mmu_context.h>
X
X #define CCR 0xff00001c /* Address of Cache Control Register */
-#define CCR_CACHE_VAL 0x00000105 /* 8k+16k-byte cache,P1-wb,enable */
-#define CCR_CACHE_INIT 0x0000090d /* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */
-#define CCR_CACHE_ENABLE 0x00000101
+
+#define CCR_CACHE_OCE 0x0001 /* Operand Cache Enable */
+#define CCR_CACHE_WT 0x0002 /* Write-Through (for P0,U0,P3) (else writeback)*/
+#define CCR_CACHE_CB 0x0004 /* Copy-Back (for P1) (else writethrough) */
+#define CCR_CACHE_OCI 0x0008 /* OC Invalidate */
+#define CCR_CACHE_ORA 0x0020 /* OC RAM Mode */
+#define CCR_CACHE_OIX 0x0080 /* OC Index Enable */
+#define CCR_CACHE_ICE 0x0100 /* Instruction Cache Enable */
+#define CCR_CACHE_ICI 0x0800 /* IC Invalidate */
+#define CCR_CACHE_IIX 0x8000 /* IC Index Enable */
+
+/* Default CCR setup: 8k+16k-byte cache,P1-wb,enable */
+#define CCR_CACHE_VAL (CCR_CACHE_ICE|CCR_CACHE_CB|CCR_CACHE_OCE)
+#define CCR_CACHE_INIT (CCR_CACHE_VAL|CCR_CACHE_OCI|CCR_CACHE_ICI)
+#define CCR_CACHE_ENABLE (CCR_CACHE_OCE|CCR_CACHE_ICE)
X
X #define CACHE_IC_ADDRESS_ARRAY 0xf0000000
X #define CACHE_OC_ADDRESS_ARRAY 0xf4000000
diff -u --recursive --new-file v2.4.12/linux/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- v2.4.12/linux/arch/sh/mm/fault.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/mm/fault.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.48 2001/08/09 00:27:04 gniibe Exp $
+/* $Id: fault.c,v 1.49 2001/10/06 19:46:00 lethal Exp $
X *
X * linux/arch/sh/mm/fault.c
X * Copyright (C) 1999 Niibe Yutaka
@@ -134,6 +134,7 @@


X * make sure we exit gracefully rather than endlessly redo

X * the fault.
X */
+survive:
X switch (handle_mm_fault(mm, vma, address, writeaccess)) {
X case 1:
X tsk->min_flt++;
@@ -205,6 +206,12 @@


X */
X out_of_memory:
X up_read(&mm->mmap_sem);

+ if (current->pid == 1) {
+ current->policy |= SCHED_YIELD;


+ schedule();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
X printk("VM: killing process %s\n", tsk->comm);

X if (user_mode(regs))
X do_exit(SIGKILL);
diff -u --recursive --new-file v2.4.12/linux/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- v2.4.12/linux/arch/sh/mm/init.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/mm/init.c Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.18 2001/08/03 11:22:06 gniibe Exp $
+/* $Id: init.c,v 1.19 2001/10/01 02:21:50 gniibe Exp $
X *
X * linux/arch/sh/mm/init.c
X *
diff -u --recursive --new-file v2.4.12/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- v2.4.12/linux/arch/sparc/kernel/systbls.S Thu Oct 11 08:02:26 2001
+++ linux/arch/sparc/kernel/systbls.S Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.100 2001/10/09 10:54:38 davem Exp $
+/* $Id: systbls.S,v 1.101 2001/10/18 08:27:05 davem Exp $
X * systbls.S: System call entry point tables for OS compatibility.
X * The native Linux system call table lives here also.
X *
@@ -59,7 +59,7 @@
X /*190*/ .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
X /*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
X /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
-/*205*/ .long sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
+/*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
X /*210*/ .long sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo
X /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex
X /*220*/ .long sys_sigprocmask, sys_create_module, sys_delete_module, sys_get_kernel_syms, sys_getpgid
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile
--- v2.4.12/linux/arch/sparc64/Makefile Sun Aug 12 13:27:59 2001
+++ linux/arch/sparc64/Makefile Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.47 2001/07/27 09:42:22 davem Exp $
+# $Id: Makefile,v 1.49 2001/10/17 18:26:58 davem Exp $
X # sparc64/Makefile
X #
X # Makefile for the architecture dependent flags and dependencies on the


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 10'
echo 'File patch-2.4.13 is continued in part 11'
echo "11" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:41 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part11

#!/bin/sh -x
# this is part 11 of a 53 - part archive


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

if test "$Scheck" != 11; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

@@ -15,7 +15,7 @@
X CC := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo gcc; else echo sparc64-linux-gcc; fi )
X
X NEW_GCC := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; )
-NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
+NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
X UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
X
X export NEW_GCC
@@ -61,6 +61,15 @@
X CFLAGS += -DSPIN_LOCK_DEBUG
X AFLAGS += -DSPIN_LOCK_DEBUG
X endif
+endif
+
+# Uncomment this to keep track of how often flush_dcache_page
+# actually flushes the caches, output via /proc/cpuinfo
+#
+# DEBUG_DCACHE_FLUSH = 1
+ifdef DEBUG_DCACHE_FLUSH
+ CFLAGS += -DDCFLUSH_DEBUG
+ AFLAGS += -DDCFLUSH_DEBUG
X endif
X
X LINKFLAGS = -T arch/sparc64/vmlinux.lds
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.12/linux/arch/sparc64/defconfig Thu Oct 11 08:02:26 2001
+++ linux/arch/sparc64/defconfig Sun Oct 21 10:36:54 2001
@@ -100,7 +100,6 @@
X CONFIG_FB_ATY=y
X # CONFIG_FB_ATY_GX is not set
X CONFIG_FB_ATY_CT=y
-# CONFIG_FB_ATY_CT_VAIO_LCD is not set
X # CONFIG_FB_RADEON is not set
X # CONFIG_FB_ATY128 is not set
X # CONFIG_FB_SIS is not set
@@ -464,7 +463,6 @@
X # CONFIG_TLAN is not set
X CONFIG_VIA_RHINE=m
X CONFIG_WINBOND_840=m
-# CONFIG_LAN_SAA9730 is not set
X # CONFIG_NET_POCKET is not set
X
X #
@@ -703,11 +701,14 @@
X #
X CONFIG_USB_DEVICEFS=y


X # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_LARGE_CONFIG is not set

X
X #
X # USB Controllers
X #
X CONFIG_USB_UHCI=y
+# CONFIG_USB_UHCI_ALT is not set
X CONFIG_USB_OHCI=y
X
X #
@@ -717,11 +718,13 @@
X CONFIG_USB_BLUETOOTH=m
X CONFIG_USB_STORAGE=m


X # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set

X CONFIG_USB_STORAGE_FREECOM=y
X CONFIG_USB_STORAGE_ISD200=y
X CONFIG_USB_STORAGE_DPCM=y
X CONFIG_USB_STORAGE_HP8200e=y
X CONFIG_USB_STORAGE_SDDR09=y


+# CONFIG_USB_STORAGE_JUMPSHOT is not set

X CONFIG_USB_ACM=m
X CONFIG_USB_PRINTER=m
X
@@ -729,6 +732,7 @@
X # USB Human Interface Devices (HID)
X #
X CONFIG_USB_HID=y
+# CONFIG_USB_HIDDEV is not set
X CONFIG_USB_WACOM=m
X
X #
@@ -754,9 +758,9 @@


X # USB Network adaptors
X #

X CONFIG_USB_PEGASUS=m
+CONFIG_USB_KAWETH=m
X CONFIG_USB_CATC=m
X CONFIG_USB_CDCETHER=m
-CONFIG_USB_KAWETH=m
X CONFIG_USB_USBNET=m
X
X #
@@ -794,7 +798,7 @@
X CONFIG_USB_SERIAL_OMNINET=m


X
X #
-# USB misc drivers
+# USB Miscellaneous drivers
X #

X CONFIG_USB_RIO500=m
X
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/dtlb_base.S linux/arch/sparc64/kernel/dtlb_base.S
--- v2.4.12/linux/arch/sparc64/kernel/dtlb_base.S Thu Oct 11 08:02:26 2001
+++ linux/arch/sparc64/kernel/dtlb_base.S Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_base.S,v 1.16 2001/10/09 04:02:11 davem Exp $
+/* $Id: dtlb_base.S,v 1.17 2001/10/11 22:33:52 davem Exp $
X * dtlb_base.S: Front end to DTLB miss replacement strategy.
X * This is included directly into the trap table.
X *
@@ -71,8 +71,8 @@
X be,pn %xcc, 3f ! Yep, special processing
X CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
X cmp %g5, 3 ! Last trap level?
- be,a,pn %xcc, 1f ! Yep, use non-faulting load
- ldxa [%g3 + %g6] ASI_SNF, %g5 ! Load VPTE (no-VPTE-fault)
+ be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
+ nop ! delay slot
X
X /* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
X ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- v2.4.12/linux/arch/sparc64/kernel/entry.S Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/entry.S Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.134 2001/08/27 18:42:07 kanoj Exp $
+/* $Id: entry.S,v 1.137 2001/10/18 09:06:36 davem 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)
@@ -725,19 +725,14 @@
X __do_data_access_exception_tl1:
X rdpr %pstate, %g4
X wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
- rdpr %tl, %g3
- cmp %g3, 1
X mov TLB_SFSR, %g3
X mov DMMU_SFAR, %g5
X ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
X ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
X stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
X membar #Sync
- bgu,pn %icc, winfix_dax
+ ba,pt %xcc, winfix_dax
X rdpr %tpc, %g3
- sethi %hi(109f), %g7
- ba,pt %xcc, etraptl1
- or %g7, %lo(109f), %g7 ! Merge in below
X __do_data_access_exception:
X rdpr %pstate, %g4
X wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
@@ -1186,7 +1181,7 @@
X ldxa [%g3] ASI_DMMU, %g5
X stxa %g0, [%g3] ASI_DMMU ! Clear FaultValid bit
X membar #Sync
- bgu,pn %icc, winfix_dax
+ bgu,pn %icc, winfix_mna
X rdpr %tpc, %g3
X
X 1: sethi %hi(109f), %g7
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.4.12/linux/arch/sparc64/kernel/ioctl32.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/ioctl32.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.125 2001/09/18 22:29:05 davem Exp $
+/* $Id: ioctl32.c,v 1.126 2001/10/18 11:41:02 davem Exp $
X * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
X *
X * Copyright (C) 1997-2000 Jakub Jelinek (ja...@redhat.com)
@@ -1404,6 +1404,229 @@


X return err;
X }
X

+typedef struct sg_io_hdr32 {
+ s32 interface_id; /* [i] 'S' for SCSI generic (required) */
+ s32 dxfer_direction; /* [i] data transfer direction */
+ u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ u8 mx_sb_len; /* [i] max length to write to sbp */
+ u16 iovec_count; /* [i] 0 implies no scatter gather */
+ u32 dxfer_len; /* [i] byte count of data transfer */
+ u32 dxferp; /* [i], [*io] points to data transfer memory
+ or scatter gather list */
+ u32 cmdp; /* [i], [*i] points to command to perform */
+ u32 sbp; /* [i], [*o] points to sense_buffer memory */
+ u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
+ u32 flags; /* [i] 0 -> default, see SG_FLAG... */
+ s32 pack_id; /* [i->o] unused internally (normally) */
+ u32 usr_ptr; /* [i->o] unused internally */
+ u8 status; /* [o] scsi status */
+ u8 masked_status; /* [o] shifted, masked scsi status */
+ u8 msg_status; /* [o] messaging level data (optional) */
+ u8 sb_len_wr; /* [o] byte count actually written to sbp */
+ u16 host_status; /* [o] errors from host adapter */
+ u16 driver_status; /* [o] errors from software driver */
+ s32 resid; /* [o] dxfer_len - actual_transferred */
+ u32 duration; /* [o] time taken by cmd (unit: millisec) */
+ u32 info; /* [o] auxiliary information */
+} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
+
+typedef struct sg_iovec32 {
+ u32 iov_base;
+ u32 iov_len;
+} sg_iovec32_t;
+
+static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
+{
+ sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
+ sg_iovec_t *kiov;
+ int i;
+
+ sgp->dxferp = kmalloc(sgp->iovec_count *
+ sizeof(sg_iovec_t), GFP_KERNEL);
+ if (!sgp->dxferp)
+ return -ENOMEM;
+ memset(sgp->dxferp, 0,
+ sgp->iovec_count * sizeof(sg_iovec_t));
+
+ kiov = (sg_iovec_t *) sgp->dxferp;
+ for (i = 0; i < sgp->iovec_count; i++) {
+ u32 iov_base32;
+ if (__get_user(iov_base32, &uiov->iov_base) ||
+ __get_user(kiov->iov_len, &uiov->iov_len))
+ return -EFAULT;
+
+ kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
+ if (!kiov->iov_base)
+ return -ENOMEM;
+ if (copy_from_user(kiov->iov_base,
+ (void *) A(iov_base32),
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }


+
+ return 0;
+}
+

+static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
+{
+ sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ u32 iov_base32;
+
+ if (__get_user(iov_base32, &uiov->iov_base))
+ return -EFAULT;
+
+ if (copy_to_user((void *) A(iov_base32),
+ kiov->iov_base,
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }


+
+ return 0;
+}
+

+static void free_sg_iovec(sg_io_hdr_t *sgp)
+{
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ if (kiov->iov_base) {
+ kfree(kiov->iov_base);
+ kiov->iov_base = NULL;
+ }
+ kiov++;
+ }
+ kfree(sgp->dxferp);
+ sgp->dxferp = NULL;
+}
+
+static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ sg_io_hdr32_t *sg_io32;
+ sg_io_hdr_t sg_io64;
+ u32 dxferp32, cmdp32, sbp32;
+ mm_segment_t old_fs;


+ int err = 0;
+

+ sg_io32 = (sg_io_hdr32_t *)arg;
+ err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
+ err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
+ err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
+ err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
+ err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
+ err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
+ err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
+ err |= __get_user(sg_io64.flags, &sg_io32->flags);
+ err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
+
+ sg_io64.dxferp = NULL;
+ sg_io64.cmdp = NULL;
+ sg_io64.sbp = NULL;
+
+ err |= __get_user(cmdp32, &sg_io32->cmdp);
+ sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
+ if (!sg_io64.cmdp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.cmdp,
+ (void *) A(cmdp32),
+ sg_io64.cmd_len)) {
+ err = -EFAULT;


+ goto out;
+ }
+

+ err |= __get_user(sbp32, &sg_io32->sbp);
+ sg_io64.sbp = kmalloc(64, GFP_KERNEL);
+ if (!sg_io64.sbp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ memset(sg_io64.sbp, 0, 64);
+
+ err |= __get_user(dxferp32, &sg_io32->dxferp);
+ if (sg_io64.iovec_count) {
+ int ret;
+
+ if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
+ err = ret;
+ goto out;
+ }
+ } else {
+ sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
+ if (!sg_io64.dxferp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.dxferp,
+ (void *) A(dxferp32),
+ sg_io64.dxfer_len)) {
+ err = -EFAULT;


+ goto out;
+ }
+ }

+
+ /* Unused internally, do not even bother to copy it over. */
+ sg_io64.usr_ptr = NULL;
+
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
+ set_fs (old_fs);
+
+ if (err < 0)
+ goto out;
+
+ err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
+ err |= __put_user(sg_io64.status, &sg_io32->status);
+ err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
+ err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
+ err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
+ err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
+ err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
+ err |= __put_user(sg_io64.resid, &sg_io32->resid);
+ err |= __put_user(sg_io64.duration, &sg_io32->duration);
+ err |= __put_user(sg_io64.info, &sg_io32->info);
+ err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, 64);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count)
+ err |= copy_back_sg_iovec(&sg_io64, dxferp32);
+ else
+ err |= copy_to_user((void *)A(dxferp32),
+ sg_io64.dxferp,
+ sg_io64.dxfer_len);
+ }
+ if (err)


+ err = -EFAULT;
+

+out:
+ if (sg_io64.cmdp)
+ kfree(sg_io64.cmdp);
+ if (sg_io64.sbp)
+ kfree(sg_io64.sbp);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count) {
+ free_sg_iovec(&sg_io64);
+ } else {
+ kfree(sg_io64.dxferp);
+ }


+ }
+ return err;
+}
+

X struct ppp_option_data32 {
X __kernel_caddr_t32 ptr;
X __u32 length;
@@ -3900,7 +4123,6 @@
X COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
X COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
X COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_IO)
X COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
X COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
X COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
@@ -4338,6 +4560,7 @@
X HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
X HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
X HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
+HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
X HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
X HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
X HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/iommu_common.c linux/arch/sparc64/kernel/iommu_common.c
--- v2.4.12/linux/arch/sparc64/kernel/iommu_common.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/iommu_common.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.c,v 1.5 2001/08/24 17:57:51 kanoj Exp $
+/* $Id: iommu_common.c,v 1.6 2001/10/09 02:24:33 davem Exp $
X * iommu_common.c: UltraSparc SBUS/PCI common iommu code.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -12,7 +12,7 @@
X */
X
X #ifdef VERIFY_SG
-int verify_lengths(struct scatterlist *sg, int nents, int npages)
+static int verify_lengths(struct scatterlist *sg, int nents, int npages)
X {
X int sg_len, dma_len;
X int i, pgcount;
@@ -22,8 +22,8 @@
X sg_len += sg[i].length;
X
X dma_len = 0;
- for (i = 0; i < nents && sg[i].dvma_length; i++)
- dma_len += sg[i].dvma_length;
+ for (i = 0; i < nents && sg[i].dma_length; i++)
+ dma_len += sg[i].dma_length;
X
X if (sg_len != dma_len) {
X printk("verify_lengths: Error, different, sg[%d] dma[%d]\n",
@@ -32,13 +32,13 @@
X }
X
X pgcount = 0;
- for (i = 0; i < nents && sg[i].dvma_length; i++) {
+ for (i = 0; i < nents && sg[i].dma_length; i++) {
X unsigned long start, end;
X
- start = sg[i].dvma_address;
+ start = sg[i].dma_address;
X start = start & IO_PAGE_MASK;
X
- end = sg[i].dvma_address + sg[i].dvma_length;
+ end = sg[i].dma_address + sg[i].dma_length;
X end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK;
X
X pgcount += ((end - start) >> IO_PAGE_SHIFT);
@@ -55,15 +55,16 @@


X return 0;
X }
X

-int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int nents, iopte_t **__iopte)
+static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int nents, iopte_t **__iopte)
X {
X struct scatterlist *sg = *__sg;
X iopte_t *iopte = *__iopte;
- u32 dlen = dma_sg->dvma_length;
- u32 daddr = dma_sg->dvma_address;
+ u32 dlen = dma_sg->dma_length;
+ u32 daddr;
X unsigned int sglen;
X unsigned long sgaddr;
X
+ daddr = dma_sg->dma_address;
X sglen = sg->length;
X sgaddr = (unsigned long) sg->address;
X while (dlen > 0) {
@@ -136,7 +137,7 @@
X return nents;
X }
X
-int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
+static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
X {
X struct scatterlist *dma_sg = sg;
X struct scatterlist *orig_dma_sg = dma_sg;
@@ -147,7 +148,7 @@
X if (nents <= 0)
X break;
X dma_sg++;
- if (dma_sg->dvma_length == 0)
+ if (dma_sg->dma_length == 0)
X break;
X }
X
@@ -174,14 +175,15 @@
X verify_maps(sg, nents, iopte) < 0) {
X int i;
X
- printk("verify_sglist: Crap, messed up mappings, dumping, iodma at %08x.\n",
- (u32) (sg->dvma_address & IO_PAGE_MASK));
+ printk("verify_sglist: Crap, messed up mappings, dumping, iodma at ");
+ printk("%016lx.\n", sg->dma_address & IO_PAGE_MASK);
+
X for (i = 0; i < nents; i++) {
X printk("sg(%d): address(%p) length(%x) "
- "dma_address[%08x] dma_length[%08x]\n",
+ "dma_address[%016lx] dma_length[%016lx]\n",
X i,
X sg[i].address, sg[i].length,
- sg[i].dvma_address, sg[i].dvma_length);
+ sg[i].dma_address, sg[i].dma_length);
X }
X }
X
@@ -204,8 +206,8 @@
X sg++;
X addr = (unsigned long) sg->address;
X if (! VCONTIG(prev, addr)) {
- dma_sg->dvma_address = dent_addr;
- dma_sg->dvma_length = dent_len;
+ dma_sg->dma_address = dent_addr;
+ dma_sg->dma_length = dent_len;
X dma_sg++;
X
X dent_addr = ((dent_addr +
@@ -218,8 +220,8 @@
X dent_len += sg->length;
X prev = addr + sg->length;
X }
- dma_sg->dvma_address = dent_addr;
- dma_sg->dvma_length = dent_len;
+ dma_sg->dma_address = dent_addr;
+ dma_sg->dma_length = dent_len;
X
X return ((unsigned long) dent_addr +
X (unsigned long) dent_len +
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/iommu_common.h linux/arch/sparc64/kernel/iommu_common.h
--- v2.4.12/linux/arch/sparc64/kernel/iommu_common.h Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/iommu_common.h Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.h,v 1.3 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: iommu_common.h,v 1.4 2001/10/09 02:24:33 davem Exp $
X * iommu_common.h: UltraSparc SBUS/PCI common iommu declarations.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -34,10 +34,7 @@
X #undef VERIFY_SG
X
X #ifdef VERIFY_SG
-int verify_lengths(struct scatterlist *sg, int nents, int npages);
-int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int nents, iopte_t **__iopte);
-int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte);
-void verify_sglist(struct scatterlist *sg, int nents, iopte_t *iopte, int npages);
+extern void verify_sglist(struct scatterlist *sg, int nents, iopte_t *iopte, int npages);
X #endif
X
X /* Two addresses are "virtually contiguous" if and only if:
@@ -47,4 +44,4 @@
X #define VCONTIG(__X, __Y) (((__X) == (__Y)) || \
X (((__X) | (__Y)) << (64UL - PAGE_SHIFT)) == 0UL)
X
-unsigned long prepare_sg(struct scatterlist *sg, int nents);
+extern unsigned long prepare_sg(struct scatterlist *sg, int nents);
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/pci_iommu.c linux/arch/sparc64/kernel/pci_iommu.c
--- v2.4.12/linux/arch/sparc64/kernel/pci_iommu.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/pci_iommu.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_iommu.c,v 1.15 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: pci_iommu.c,v 1.16 2001/10/09 02:24:33 davem Exp $
X * pci_iommu.c: UltraSparc PCI controller IOM/STC support.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -378,7 +378,8 @@
X ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
X #ifdef DEBUG_PCI_IOMMU
X if (iopte_val(*base) == IOPTE_INVALID)
- printk("pci_unmap_single called on non-mapped region %08x,%08x from %016lx\n", bus_addr, sz, __builtin_return_address(0));
+ printk("pci_unmap_single called on non-mapped region %08x,%08x from %016lx\n",
+ bus_addr, sz, __builtin_return_address(0));
X #endif
X bus_addr &= IO_PAGE_MASK;
X
@@ -423,18 +424,25 @@
X spin_unlock_irqrestore(&iommu->lock, flags);
X }
X
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, unsigned long iopte_protection)
+#define SG_ENT_PHYS_ADDRESS(SG) \
+ ((SG)->address ? \
+ __pa((SG)->address) : \
+ (__pa(page_address((SG)->page)) + (SG)->offset))
+
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
+ int nused, int nelems, unsigned long iopte_protection)
X {
X struct scatterlist *dma_sg = sg;
+ struct scatterlist *sg_end = sg + nelems;
X int i;
X
X for (i = 0; i < nused; i++) {
X unsigned long pteval = ~0UL;
X u32 dma_npages;
X
- dma_npages = ((dma_sg->dvma_address & (IO_PAGE_SIZE - 1UL)) +
- dma_sg->dvma_length +
- ((u32)(IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
+ dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) +
+ dma_sg->dma_length +
+ ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
X do {
X unsigned long offset;
X signed int len;
@@ -447,7 +455,7 @@
X for (;;) {
X unsigned long tmp;
X
- tmp = (unsigned long) __pa(sg->address);
+ tmp = SG_ENT_PHYS_ADDRESS(sg);


X len = sg->length;

X if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
X pteval = tmp & IO_PAGE_MASK;
@@ -479,10 +487,11 @@
X * adjusting pteval along the way. Stop when we
X * detect a page crossing event.
X */
- while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
- pteval == __pa(sg->address) &&
+ while (sg < sg_end &&
+ (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
+ (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
X ((pteval ^
- (__pa(sg->address) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
+ (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
X pteval += sg->length;
X sg++;
X }
@@ -511,8 +520,13 @@
X

X /* Fast path single entry scatterlists. */

X if (nelems == 1) {
- sglist->dvma_address = pci_map_single(pdev, sglist->address, sglist->length, direction);
- sglist->dvma_length = sglist->length;
+ sglist->dma_address =
+ pci_map_single(pdev,
+ (sglist->address ?
+ sglist->address :
+ (page_address(sglist->page) + sglist->offset)),
+ sglist->length, direction);
+ sglist->dma_length = sglist->length;
X return 1;
X }
X
@@ -540,8 +554,8 @@
X used = nelems;
X
X sgtmp = sglist;
- while (used && sgtmp->dvma_length) {
- sgtmp->dvma_address += dma_base;
+ while (used && sgtmp->dma_length) {
+ sgtmp->dma_address += dma_base;
X sgtmp++;
X used--;
X }
@@ -559,7 +573,7 @@
X iopte_protection = IOPTE_CONSISTENT(ctx);
X if (direction != PCI_DMA_TODEVICE)
X iopte_protection |= IOPTE_WRITE;
- fill_sg (base, sglist, used, iopte_protection);
+ fill_sg (base, sglist, used, nelems, iopte_protection);
X #ifdef VERIFY_SG
X verify_sglist(sglist, nelems, base, npages);
X #endif
@@ -591,20 +605,20 @@
X iommu = pcp->pbm->iommu;
X strbuf = &pcp->pbm->stc;
X
- bus_addr = sglist->dvma_address & IO_PAGE_MASK;
+ bus_addr = sglist->dma_address & IO_PAGE_MASK;
X
X for (i = 1; i < nelems; i++)
- if (sglist[i].dvma_length == 0)
+ if (sglist[i].dma_length == 0)
X break;
X i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> IO_PAGE_SHIFT;
+ npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
X
X base = iommu->page_table +
X ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
X
X #ifdef DEBUG_PCI_IOMMU
X if (iopte_val(*base) == IOPTE_INVALID)
- printk("pci_unmap_sg called on non-mapped region %08x,%d from %016lx\n", sglist->dvma_address, nelems, __builtin_return_address(0));
+ printk("pci_unmap_sg called on non-mapped region %016lx,%d from %016lx\n", sglist->dma_address, nelems, __builtin_return_address(0));
X #endif
X
X spin_lock_irqsave(&iommu->lock, flags);
@@ -616,7 +630,7 @@
X
X /* Step 1: Kick data out of streaming buffers if necessary. */
X if (strbuf->strbuf_enabled) {
- u32 vaddr = bus_addr;
+ u32 vaddr = (u32) bus_addr;
X
X PCI_STC_FLUSHFLAG_INIT(strbuf);
X if (strbuf->strbuf_ctxflush &&
@@ -735,7 +749,7 @@
X iopte_t *iopte;
X
X iopte = iommu->page_table +
- ((sglist[0].dvma_address - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
+ ((sglist[0].dma_address - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
X ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL;
X }
X
@@ -754,13 +768,13 @@
X unsigned long i, npages;
X u32 bus_addr;
X
- bus_addr = sglist[0].dvma_address & IO_PAGE_MASK;
+ bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
X
X for(i = 1; i < nelems; i++)
- if (!sglist[i].dvma_length)
+ if (!sglist[i].dma_length)
X break;
X i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> IO_PAGE_SHIFT;
+ npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
X for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
X pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
X }
@@ -774,10 +788,10 @@
X spin_unlock_irqrestore(&iommu->lock, flags);
X }
X
-int pci_dma_supported(struct pci_dev *pdev, dma_addr_t device_mask)
+int pci_dma_supported(struct pci_dev *pdev, u64 device_mask)
X {
X struct pcidev_cookie *pcp = pdev->sysdata;
- u32 dma_addr_mask;
+ u64 dma_addr_mask;
X
X if (pdev == NULL) {
X dma_addr_mask = 0xffffffff;
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- v2.4.12/linux/arch/sparc64/kernel/pci_psycho.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/pci_psycho.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.28 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: pci_psycho.c,v 1.29 2001/10/11 00:44:38 davem 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)
@@ -36,7 +36,8 @@
X __asm__ __volatile__("stxa %0, [%1] %2" \
X : /* no outputs */ \
X : "r" (__val), "r" (__reg), \
- "i" (ASI_PHYS_BYPASS_EC_E))
+ "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory")
X
X /* Misc. PSYCHO PCI controller register offsets and definitions. */
X #define PSYCHO_CONTROL 0x0010UL
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- v2.4.12/linux/arch/sparc64/kernel/pci_sabre.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/pci_sabre.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.39 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: pci_sabre.c,v 1.40 2001/10/11 00:44:38 davem Exp $
X * pci_sabre.c: Sabre specific PCI controller support.
X *
X * Copyright (C) 1997, 1998, 1999 David S. Miller (da...@caipfs.rutgers.edu)
@@ -37,7 +37,8 @@
X __asm__ __volatile__("stxa %0, [%1] %2" \
X : /* no outputs */ \
X : "r" (__val), "r" (__reg), \
- "i" (ASI_PHYS_BYPASS_EC_E))
+ "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory")
X
X /* SABRE PCI controller register offsets and definitions. */
X #define SABRE_UE_AFSR 0x0030UL
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- v2.4.12/linux/arch/sparc64/kernel/pci_schizo.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/pci_schizo.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.21 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: pci_schizo.c,v 1.22 2001/10/11 00:44:38 davem Exp $
X * pci_schizo.c: SCHIZO specific PCI controller support.
X *
X * Copyright (C) 2001 David S. Miller (da...@redhat.com)
@@ -34,7 +34,8 @@
X __asm__ __volatile__("stxa %0, [%1] %2" \
X : /* no outputs */ \
X : "r" (__val), "r" (__reg), \
- "i" (ASI_PHYS_BYPASS_EC_E))
+ "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory")
X
X /* This is a convention that at least Excalibur and Merlin
X * follow. I suppose the SCHIZO used in Starcat and friends
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.4.12/linux/arch/sparc64/kernel/process.c Thu Oct 11 08:02:26 2001
+++ linux/arch/sparc64/kernel/process.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.120 2001/10/02 02:22:26 davem Exp $
+/* $Id: process.c,v 1.122 2001/10/18 09:06:36 davem Exp $
X * arch/sparc64/kernel/process.c
X *
X * Copyright (C) 1995, 1996 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/rtrap.S linux/arch/sparc64/kernel/rtrap.S
--- v2.4.12/linux/arch/sparc64/kernel/rtrap.S Tue Jul 3 17:08:19 2001
+++ linux/arch/sparc64/kernel/rtrap.S Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.55 2001/06/05 09:56:06 davem Exp $
+/* $Id: rtrap.S,v 1.56 2001/10/13 00:14:34 kanoj Exp $
X * rtrap.S: Preparing for return from trap on Sparc V9.
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -82,12 +82,12 @@
X andn %l1, %l4, %l1
X
X .align 64
- .globl rtrap_clr_l6, rtrap
+ .globl rtrap_clr_l6, rtrap, irqsz_patchme
X rtrap_clr_l6: clr %l6
X rtrap: lduw [%g6 + AOFF_task_processor], %l0
X sethi %hi(irq_stat), %l2 ! &softirq_active
X or %l2, %lo(irq_stat), %l2 ! &softirq_active
- sllx %l0, 6, %l0
+irqsz_patchme: sllx %l0, 0, %l0
X lduw [%l2 + %l0], %l1 ! softirq_pending
X cmp %l1, 0
X
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/sbus.c linux/arch/sparc64/kernel/sbus.c
--- v2.4.12/linux/arch/sparc64/kernel/sbus.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/sbus.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.16 2001/08/24 19:36:58 kanoj Exp $
+/* $Id: sbus.c,v 1.17 2001/10/09 02:24:33 davem Exp $
X * sbus.c: UltraSparc SBUS controller support.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -376,18 +376,24 @@
X spin_unlock_irqrestore(&iommu->lock, flags);
X }
X
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, unsigned long iopte_bits)
+#define SG_ENT_PHYS_ADDRESS(SG) \
+ ((SG)->address ? \
+ __pa((SG)->address) : \
+ (__pa(page_address((SG)->page)) + (SG)->offset))
+
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, int nelems, unsigned long iopte_bits)
X {
X struct scatterlist *dma_sg = sg;
+ struct scatterlist *sg_end = sg + nelems;
X int i;
X
X for (i = 0; i < nused; i++) {
X unsigned long pteval = ~0UL;
X u32 dma_npages;
X
- dma_npages = ((dma_sg->dvma_address & (IO_PAGE_SIZE - 1UL)) +
- dma_sg->dvma_length +
- ((u32)(IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
+ dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) +
+ dma_sg->dma_length +
+ ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;
X do {
X unsigned long offset;
X signed int len;
@@ -400,7 +406,7 @@
X for (;;) {
X unsigned long tmp;
X
- tmp = (unsigned long) __pa(sg->address);
+ tmp = (unsigned long) SG_ENT_PHYS_ADDRESS(sg);


X len = sg->length;

X if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
X pteval = tmp & IO_PAGE_MASK;
@@ -432,10 +438,11 @@
X * adjusting pteval along the way. Stop when we
X * detect a page crossing event.
X */
- while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
- pteval == __pa(sg->address) &&
+ while (sg < sg_end &&
+ (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
+ (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
X ((pteval ^
- (__pa(sg->address) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
+ (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
X pteval += sg->length;
X sg++;
X }
@@ -461,8 +468,13 @@
X

X /* Fast path single entry scatterlists. */
X if (nents == 1) {

- sg->dvma_address = sbus_map_single(sdev, sg->address, sg->length, dir);
- sg->dvma_length = sg->length;
+ sg->dma_address =
+ sbus_map_single(sdev,
+ (sg->address ?
+ sg->address :
+ (page_address(sg->page) + sg->offset)),
+ sg->length, dir);
+ sg->dma_length = sg->length;
X return 1;
X }
X
@@ -478,8 +490,8 @@
X sgtmp = sg;
X used = nents;
X
- while (used && sgtmp->dvma_length) {
- sgtmp->dvma_address += dma_base;
+ while (used && sgtmp->dma_length) {
+ sgtmp->dma_address += dma_base;
X sgtmp++;
X used--;
X }
@@ -489,7 +501,7 @@
X if (dir != SBUS_DMA_TODEVICE)
X iopte_bits |= IOPTE_WRITE;
X
- fill_sg(iopte, sg, used, iopte_bits);
+ fill_sg(iopte, sg, used, nents, iopte_bits);
X #ifdef VERIFY_SG
X verify_sglist(sg, nents, iopte, npages);
X #endif
@@ -512,17 +524,17 @@
X

X /* Fast path single entry scatterlists. */
X if (nents == 1) {

- sbus_unmap_single(sdev, sg->dvma_address, sg->dvma_length, direction);
+ sbus_unmap_single(sdev, sg->dma_address, sg->dma_length, direction);
X return;
X }
X
- dvma_base = sg[0].dvma_address & IO_PAGE_MASK;
+ dvma_base = sg[0].dma_address & IO_PAGE_MASK;
X for (i = 0; i < nents; i++) {
- if (sg[i].dvma_length == 0)
+ if (sg[i].dma_length == 0)
X break;
X }
X i--;
- size = IO_PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - dvma_base;
+ size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - dvma_base;
X
X iommu = sdev->bus->iommu;
X spin_lock_irqsave(&iommu->lock, flags);
@@ -550,13 +562,13 @@
X u32 base;
X int i;
X
- base = sg[0].dvma_address & IO_PAGE_MASK;
+ base = sg[0].dma_address & IO_PAGE_MASK;
X for (i = 0; i < nents; i++) {
- if (sg[i].dvma_length == 0)
+ if (sg[i].dma_length == 0)
X break;
X }
X i--;
- size = IO_PAGE_ALIGN(sg[i].dvma_address + sg[i].dvma_length) - base;
+ size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
X
X spin_lock_irqsave(&iommu->lock, flags);
X strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.4.12/linux/arch/sparc64/kernel/setup.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/kernel/setup.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.67 2001/09/21 03:17:06 kanoj Exp $
+/* $Id: setup.c,v 1.69 2001/10/18 09:40:00 davem Exp $
X * linux/arch/sparc64/kernel/setup.c
X *
X * Copyright (C) 1995,1996 David S. Miller (da...@caip.rutgers.edu)
@@ -90,6 +90,7 @@
X struct console *cons, *saved_console = NULL;
X unsigned long flags;
X char *cmd;
+ extern spinlock_t prom_entry_lock;
X
X if (!args)
X return -1;
@@ -105,6 +106,7 @@
X */
X irq_exit(smp_processor_id(), 0);
X save_and_cli(flags);
+ spin_unlock(&prom_entry_lock);
X cons = console_drivers;
X while (cons) {
X unregister_console(cons);
@@ -279,6 +281,7 @@
X saved_console = cons->next;
X register_console(cons);
X }
+ spin_lock(&prom_entry_lock);
X restore_flags(flags);
X /*
X * Restore in-interrupt status for a resume from obp.
@@ -480,6 +483,18 @@
X conswitchp = &prom_con;
X #endif
X
+#ifdef CONFIG_SMP
+ i = (unsigned long)&irq_stat[1] - (unsigned long)&irq_stat[0];
+ if ((i == SMP_CACHE_BYTES) || (i == (2 * SMP_CACHE_BYTES))) {
+ extern unsigned int irqsz_patchme[1];
+ irqsz_patchme[0] |= ((i == SMP_CACHE_BYTES) ? SMP_CACHE_BYTES_SHIFT : \
+ SMP_CACHE_BYTES_SHIFT + 1);
+ flushi((long)&irqsz_patchme[1]);
+ } else {
+ prom_printf("Unexpected size of irq_stat[] elements\n");
+ prom_halt();
+ }
+#endif
X /* Work out if we are starfire early on */
X check_if_starfire();
X
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- v2.4.12/linux/arch/sparc64/kernel/smp.c Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/smp.c Sun Oct 21 10:36:54 2001
@@ -582,6 +582,68 @@
X extern unsigned long xcall_flush_cache_all;
X extern unsigned long xcall_report_regs;
X extern unsigned long xcall_receive_signal;
+extern unsigned long xcall_flush_dcache_page_cheetah;
+extern unsigned long xcall_flush_dcache_page_spitfire;
+
+static spinlock_t dcache_xcall_lock = SPIN_LOCK_UNLOCKED;
+static struct page *dcache_page;
+#ifdef DCFLUSH_DEBUG
+extern atomic_t dcpage_flushes;
+extern atomic_t dcpage_flushes_xcall;
+#endif
+
+static __inline__ void __smp_flush_dcache_page_client(struct page *page)
+{
+#if (L1DCACHE_SIZE > PAGE_SIZE)
+ __flush_dcache_page(page->virtual,
+ ((tlb_type == spitfire) &&
+ page->mapping != NULL));
+#else
+ if (page->mapping != NULL &&
+ tlb_type == spitfire)
+ __flush_icache_page(__pa(page->virtual));
+#endif
+}
+
+void smp_flush_dcache_page_client(void)
+{
+ __smp_flush_dcache_page_client(dcache_page);
+ spin_unlock(&dcache_xcall_lock);
+}
+
+void smp_flush_dcache_page_impl(struct page *page)
+{
+ if (smp_processors_ready) {
+ int cpu = dcache_dirty_cpu(page);
+ unsigned long mask = 1UL << cpu;
+
+#ifdef DCFLUSH_DEBUG
+ atomic_inc(&dcpage_flushes);
+#endif
+ if (cpu == smp_processor_id()) {
+ __smp_flush_dcache_page_client(page);
+ } else if ((cpu_present_map & mask) != 0) {
+ u64 data0;
+
+ if (tlb_type == spitfire) {
+ spin_lock(&dcache_xcall_lock);
+ dcache_page = page;
+ data0 = ((u64)&xcall_flush_dcache_page_spitfire);
+ spitfire_xcall_deliver(data0, 0, 0, mask);
+ /* Target cpu drops dcache_xcall_lock. */
+ } else {
+ /* Look mom, no locks... */
+ data0 = ((u64)&xcall_flush_dcache_page_cheetah);
+ cheetah_xcall_deliver(data0,
+ (u64) page->virtual,
+ 0, mask);
+ }
+#ifdef DCFLUSH_DEBUG
+ atomic_inc(&dcpage_flushes_xcall);
+#endif
+ }
+ }
+}
X
X void smp_receive_signal(int cpu)
X {
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.4.12/linux/arch/sparc64/kernel/sparc64_ksyms.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.112 2001/09/25 23:30:23 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.113 2001/10/17 18:26:58 davem Exp $
X * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
X *
X * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -183,7 +183,7 @@
X EXPORT_SYMBOL(tlb_type);
X EXPORT_SYMBOL(get_fb_unmapped_area);
X EXPORT_SYMBOL(flush_icache_range);
-EXPORT_SYMBOL(__flush_dcache_page);
+EXPORT_SYMBOL(flush_dcache_page);
X
X EXPORT_SYMBOL(mostek_lock);
X EXPORT_SYMBOL(mstk48t02_regs);
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.4.12/linux/arch/sparc64/kernel/sys_sparc32.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/kernel/sys_sparc32.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.179 2001/09/25 00:48:09 davem Exp $
+/* $Id: sys_sparc32.c,v 1.182 2001/10/18 09:06:36 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)
@@ -3999,6 +3999,12 @@
X return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
X }
X
+extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+
+asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
+{
+ return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
+}
X
X extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
X
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- v2.4.12/linux/arch/sparc64/kernel/systbls.S Thu Oct 11 08:02:26 2001
+++ linux/arch/sparc64/kernel/systbls.S Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.78 2001/10/09 10:54:38 davem Exp $
+/* $Id: systbls.S,v 1.79 2001/10/18 08:27:05 davem Exp $


X * systbls.S: System call entry point tables for OS compatibility.
X * The native Linux system call table lives here also.
X *

@@ -60,7 +60,7 @@
X /*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
X .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
X /*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
- .word sys_nis_syscall, sys32_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
+ .word sys32_readahead, sys32_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
X /*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo
X .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
X /*220*/ .word sys32_sigprocmask, sys32_create_module, sys32_delete_module, sys32_get_kernel_syms, sys_getpgid
@@ -119,7 +119,7 @@
X /*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
X .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
X /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
- .word sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
+ .word sys_readahead, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
X /*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo
X .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex
X /*220*/ .word sys_nis_syscall, sys_create_module, sys_delete_module, sys_get_kernel_syms, sys_getpgid
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.4.12/linux/arch/sparc64/mm/init.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/mm/init.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.193 2001/09/25 22:47:35 davem Exp $
+/* $Id: init.c,v 1.194 2001/10/17 18:26:58 davem Exp $
X * arch/sparc64/mm/init.c
X *
X * Copyright (C) 1996-1999 David S. Miller (da...@caip.rutgers.edu)
@@ -108,23 +108,73 @@
X
X extern void __update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
X
+#ifdef DCFLUSH_DEBUG
+atomic_t dcpage_flushes = ATOMIC_INIT(0);
+#ifdef CONFIG_SMP
+atomic_t dcpage_flushes_xcall = ATOMIC_INIT(0);
+#endif
+#endif
+
+__inline__ void flush_dcache_page_impl(struct page *page)
+{
+#ifdef DCFLUSH_DEBUG
+ atomic_inc(&dcpage_flushes);
+#endif
+
+#if (L1DCACHE_SIZE > PAGE_SIZE)
+ __flush_dcache_page(page->virtual,
+ ((tlb_type == spitfire) &&
+ page->mapping != NULL));
+#else
+ if (page->mapping != NULL &&
+ tlb_type == spitfire)
+ __flush_icache_page(__pa(page->virtual));
+#endif
+}
+
X void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
X {
X struct page *page = pte_page(pte);
X
X if (VALID_PAGE(page) && page->mapping &&
X test_bit(PG_dcache_dirty, &page->flags)) {
-#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */
- __flush_dcache_page(page->virtual, (tlb_type == spitfire));
-#else
- if (tlb_type == spitfire) /* fix local I$ coherency */
- __flush_icache_page(__get_phys((unsigned long)(page->virtual)));
-#endif
- clear_bit(PG_dcache_dirty, &page->flags);
+ /* This is just to optimize away some function calls
+ * in the SMP case.
+ */
+ if (dcache_dirty_cpu(page) == smp_processor_id())
+ flush_dcache_page_impl(page);
+ else
+ smp_flush_dcache_page_impl(page);
+
+ clear_dcache_dirty(page);
X }
X __update_mmu_cache(vma, address, pte);
X }
X
+void flush_dcache_page(struct page *page)
+{
+ int dirty = test_bit(PG_dcache_dirty, &page->flags);
+ int dirty_cpu = dcache_dirty_cpu(page);
+
+ if (page->mapping &&
+ page->mapping->i_mmap == NULL &&
+ page->mapping->i_mmap_shared == NULL) {
+ if (dirty) {
+ if (dirty_cpu == smp_processor_id())
+ return;
+ smp_flush_dcache_page_impl(page);
+ }
+ set_dcache_dirty(page);
+ } else {
+ /* We could delay the flush for the !page->mapping
+ * case too. But that case is for exec env/arg
+ * pages and those are %99 certainly going to get
+ * faulted into the tlb (and thus flushed) anyways.
+ */
+ flush_dcache_page_impl(page);
+ }
+}


+
X void flush_icache_range(unsigned long start, unsigned long end)

X {
X /* Cheetah has coherent I-cache. */
@@ -153,12 +203,25 @@
X
X int mmu_info(char *buf)
X {
+ int len;
+
X if (tlb_type == cheetah)
- return sprintf(buf, "MMU Type\t: Cheetah\n");
+ len = sprintf(buf, "MMU Type\t: Cheetah\n");
X else if (tlb_type == spitfire)
- return sprintf(buf, "MMU Type\t: Spitfire\n");
+ len = sprintf(buf, "MMU Type\t: Spitfire\n");
X else
- return sprintf(buf, "MMU Type\t: ???\n");
+ len = sprintf(buf, "MMU Type\t: ???\n");
+
+#ifdef DCFLUSH_DEBUG
+ len += sprintf(buf + len, "DCPageFlushes\t: %d\n",
+ atomic_read(&dcpage_flushes));
+#ifdef CONFIG_SMP
+ len += sprintf(buf + len, "DCPageFlushesXC\t: %d\n",
+ atomic_read(&dcpage_flushes_xcall));
+#endif /* CONFIG_SMP */
+#endif /* DCFLUSH_DEBUG */
+
+ return len;
X }
X
X struct linux_prom_translation {
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- v2.4.12/linux/arch/sparc64/mm/ultra.S Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/mm/ultra.S Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.61 2001/09/25 18:04:51 kanoj Exp $
+/* $Id: ultra.S,v 1.63 2001/10/17 19:30:21 davem Exp $
X * ultra.S: Don't expand these all over the place...
X *
X * Copyright (C) 1997, 2000 David S. Miller (da...@redhat.com)
@@ -500,6 +500,32 @@
X 109: or %g7, %lo(109b), %g7
X call __show_regs
X add %sp, STACK_BIAS + REGWIN_SZ, %o0
+ b,pt %xcc, rtrap
+ clr %l6
+
+ .align 32
+ .globl xcall_flush_dcache_page_cheetah
+xcall_flush_dcache_page_cheetah:
+ sethi %hi(PAGE_SIZE), %g3
+1: subcc %g3, (1 << 5), %g3
+ stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
+ membar #Sync
+ bne,pt %icc, 1b
+ nop
+ retry
+ nop
+
+ .globl xcall_flush_dcache_page_spitfire
+xcall_flush_dcache_page_spitfire:
+ rdpr %pstate, %g2
+ wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
+ rdpr %pil, %g2
+ wrpr %g0, 15, %pil
+ sethi %hi(109f), %g7
+ b,pt %xcc, etrap_irq
+109: or %g7, %lo(109b), %g7
+ call smp_flush_dcache_page_client
+ nop
X b,pt %xcc, rtrap
X clr %l6
X
diff -u --recursive --new-file v2.4.12/linux/arch/sparc64/prom/p1275.c linux/arch/sparc64/prom/p1275.c
--- v2.4.12/linux/arch/sparc64/prom/p1275.c Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/prom/p1275.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: p1275.c,v 1.21 2001/04/24 01:09:12 davem Exp $
+/* $Id: p1275.c,v 1.22 2001/10/18 09:40:00 davem Exp $
X * p1275.c: Sun IEEE 1275 PROM low level interface routines
X *
X * Copyright (C) 1996,1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -247,39 +247,12 @@
X " " : : "r" (&p1275buf), "i" (PSTATE_PRIV));
X }
X
-/* We need some SMP protection here. But be careful as
- * prom callback code can call into here too, this is why
- * the counter is needed. -DaveM
+/*
+ * This provides SMP safety on the p1275buf. prom_callback() drops this lock
+ * to allow recursuve acquisition.
X */
-static int prom_entry_depth = 0;
X spinlock_t prom_entry_lock = SPIN_LOCK_UNLOCKED;
X
-static __inline__ unsigned long prom_get_lock(void)
-{
- unsigned long flags;
-
- __save_and_cli(flags);
- if (prom_entry_depth == 0) {
- spin_lock(&prom_entry_lock);
-
-#if 1 /* DEBUGGING */
- if (prom_entry_depth != 0)
- panic("prom_get_lock");
-#endif
- }
- prom_entry_depth++;
-
- return flags;
-}
-
-static __inline__ void prom_release_lock(unsigned long flags)
-{
- if (--prom_entry_depth == 0)
- spin_unlock(&prom_entry_lock);
-
- __restore_flags(flags);
-}
-
X long p1275_cmd (char *service, long fmt, ...)
X {
X char *p, *q;
@@ -296,7 +269,7 @@
X spitfire_set_primary_context (0);
X }
X
- flags = prom_get_lock();
+ spin_lock_irqsave(&prom_entry_lock, flags);
X
X p1275buf.prom_args[0] = (unsigned long)p; /* service */
X strcpy (p, service);
@@ -388,7 +361,7 @@
X va_end(list);
X x = p1275buf.prom_args [nargs + 3];
X
- prom_release_lock(flags);
+ spin_unlock_irqrestore(&prom_entry_lock, flags);
X
X if (ctx)
X spitfire_set_primary_context (ctx);
diff -u --recursive --new-file v2.4.12/linux/drivers/Makefile linux/drivers/Makefile
--- v2.4.12/linux/drivers/Makefile Wed Jul 25 17:10:19 2001
+++ linux/drivers/Makefile Sun Oct 21 10:12:41 2001
@@ -7,7 +7,7 @@
X
X
X mod-subdirs := dio mtd sbus video macintosh usb input telephony sgi ide \
- i2o message/fusion scsi md ieee1394 pnp isdn atm \
+ message/i2o message/fusion scsi md ieee1394 pnp isdn atm \
X fc4 net/hamradio i2c acpi bluetooth
X
X subdir-y := parport char block net sound misc media cdrom
@@ -31,7 +31,7 @@
X subdir-$(CONFIG_SGI) += sgi
X subdir-$(CONFIG_IDE) += ide
X subdir-$(CONFIG_SCSI) += scsi
-subdir-$(CONFIG_I2O) += i2o
+subdir-$(CONFIG_I2O) += message/i2o
X subdir-$(CONFIG_FUSION) += message/fusion
X subdir-$(CONFIG_MD) += md
X subdir-$(CONFIG_IEEE1394) += ieee1394
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.4.12/linux/drivers/acorn/block/mfmhd.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/block/mfmhd.c Mon Oct 15 13:27:42 2001
@@ -1209,7 +1209,7 @@
X return 0;
X
X case BLKGETSIZE:
- return put_user (mfm[minor].nr_sects, (long *)arg);
+ return put_user (mfm[minor].nr_sects, (unsigned long *)arg);
X case BLKGETSIZE64:
X return put_user ((u64)mfm[minor].nr_sects << 9, (u64 *)arg);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/char/mouse_rpc.c linux/drivers/acorn/char/mouse_rpc.c
--- v2.4.12/linux/drivers/acorn/char/mouse_rpc.c Tue Jul 3 17:08:19 2001
+++ linux/drivers/acorn/char/mouse_rpc.c Thu Oct 11 09:04:57 2001
@@ -83,3 +83,8 @@
X
X module_init(mouse_rpc_init);
X module_exit(mouse_rpc_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("RiscPC mouse driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c
--- v2.4.12/linux/drivers/acorn/scsi/acornscsi.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/acornscsi.c Thu Oct 11 09:04:57 2001
@@ -3159,5 +3159,7 @@
X module_init(acornscsi_init);
X module_exit(acornscsi_exit);
X
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("AcornSCSI driver");
X MODULE_LICENSE("GPL");
X EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c
--- v2.4.12/linux/drivers/acorn/scsi/arxescsi.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/arxescsi.c Thu Oct 11 09:04:57 2001
@@ -439,4 +439,7 @@
X module_init(init_arxe_scsi_driver);
X module_exit(exit_arxe_scsi_driver);
X
+MODULE_AUTHOR("Stefan Hanske");
+MODULE_DESCRIPTION("ARXESCSI driver for Acorn machines");
X MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c
--- v2.4.12/linux/drivers/acorn/scsi/cumana_2.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/cumana_2.c Thu Oct 11 09:04:57 2001
@@ -82,12 +82,6 @@
X
X static struct expansion_card *ecs[MAX_ECARDS];
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Cumana SCSI II driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
X /*
X * Use term=0,1,0,0,0 to turn terminators on/off
X */
@@ -600,3 +594,10 @@
X
X module_init(cumanascsi2_init);
X module_exit(cumanascsi2_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Cumana SCSI-2 driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/ecoscsi.c linux/drivers/acorn/scsi/ecoscsi.c
--- v2.4.12/linux/drivers/acorn/scsi/ecoscsi.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/ecoscsi.c Thu Oct 11 09:04:57 2001
@@ -293,5 +293,7 @@
X module_init(ecoscsi_init);
X module_exit(ecoscsi_exit);
X
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
X MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c
--- v2.4.12/linux/drivers/acorn/scsi/eesox.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/eesox.c Thu Oct 11 09:04:57 2001
@@ -80,11 +80,6 @@
X
X static struct expansion_card *ecs[MAX_ECARDS];
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("EESOX SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-
X /*
X * Use term=0,1,0,0,0 to turn terminators on/off
X */
@@ -602,5 +597,9 @@
X module_init(eesox_init);
X module_exit(eesox_exit);
X
-EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("EESOX 'Fast' SCSI driver for Acorn machines");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
X MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c
--- v2.4.12/linux/drivers/acorn/scsi/fas216.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/fas216.c Thu Oct 11 09:04:57 2001
@@ -60,9 +60,6 @@
X #include "../../scsi/hosts.h"
X #include "fas216.h"
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
-
X #define VER_MAJOR 0
X #define VER_MINOR 0
X #define VER_PATCH 5
@@ -2767,15 +2764,6 @@
X EXPORT_SYMBOL(fas216_print_stats);
X EXPORT_SYMBOL(fas216_print_device);
X
-#ifdef MODULE
-int __init init_module(void)
-{


- return 0;
-}
-

-void __exit cleanup_module(void)
-{
-}
-#endif
-
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
X MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/msgqueue.c linux/drivers/acorn/scsi/msgqueue.c
--- v2.4.12/linux/drivers/acorn/scsi/msgqueue.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/msgqueue.c Thu Oct 11 09:04:57 2001
@@ -16,10 +16,6 @@
X
X #include "msgqueue.h"
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI message queue handling");
-MODULE_LICENSE("GPL");
-
X /*
X * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
X * Purpose : Allocate a message queue entry
@@ -170,13 +166,6 @@
X EXPORT_SYMBOL(msgqueue_addmsg);
X EXPORT_SYMBOL(msgqueue_flush);
X
-#ifdef MODULE
-int __init init_module(void)
-{


- return 0;
-}
-

-void __exit cleanup_module(void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI message queue handling");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/oak.c linux/drivers/acorn/scsi/oak.c
--- v2.4.12/linux/drivers/acorn/scsi/oak.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/oak.c Thu Oct 11 09:04:57 2001
@@ -286,5 +286,7 @@
X module_init(oakscsi_init);
X module_exit(oakscsi_exit);
X
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Oak SCSI driver");
X MODULE_LICENSE("GPL");
X EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c
--- v2.4.12/linux/drivers/acorn/scsi/powertec.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/powertec.c Thu Oct 11 09:04:57 2001
@@ -77,12 +77,6 @@
X #define VER_MINOR 0
X #define VER_PATCH 5
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("Powertec SCSI driver");
-MODULE_PARM(term, "1-8i");
-MODULE_PARM_DESC(term, "SCSI bus termination");
-MODULE_LICENSE("GPL");
-
X static struct expansion_card *ecs[MAX_ECARDS];
X
X /*
@@ -502,3 +496,10 @@
X
X module_init(powertecscsi_init);
X module_exit(powertecscsi_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Powertec SCSI driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/acorn/scsi/queue.c linux/drivers/acorn/scsi/queue.c
--- v2.4.12/linux/drivers/acorn/scsi/queue.c Sun Sep 23 11:40:56 2001
+++ linux/drivers/acorn/scsi/queue.c Thu Oct 11 09:04:57 2001
@@ -25,10 +25,6 @@
X
X #include "../../scsi/scsi.h"
X
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("SCSI command queueing");
-MODULE_LICENSE("GPL");
-
X #define DEBUG
X
X typedef struct queue_entry {
@@ -296,13 +292,6 @@
X EXPORT_SYMBOL(queue_remove_cmd);
X EXPORT_SYMBOL(queue_probetgtlun);
X
-#ifdef MODULE
-int __init init_module (void)
-{


- return 0;
-}
-

-void __exit cleanup_module (void)
-{
-}
-#endif
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI command queueing");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/acpi/include/platform/acgcc.h linux/drivers/acpi/include/platform/acgcc.h
--- v2.4.12/linux/drivers/acpi/include/platform/acgcc.h Sun Sep 23 11:40:56 2001
+++ linux/drivers/acpi/include/platform/acgcc.h Mon Oct 15 18:48:28 2001
@@ -39,7 +39,6 @@
X #define BREAKPOINT3
X #define disable() __cli()
X #define enable() __sti()
-#define wbinvd()
X
X /*! [Begin] no source code translation */
X
diff -u --recursive --new-file v2.4.12/linux/drivers/acpi/ospm/thermal/tz_osl.c linux/drivers/acpi/ospm/thermal/tz_osl.c
--- v2.4.12/linux/drivers/acpi/ospm/thermal/tz_osl.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/acpi/ospm/thermal/tz_osl.c Thu Oct 11 09:04:57 2001
@@ -177,7 +177,7 @@
X tz_osl_add_device(
X TZ_CONTEXT *thermal_zone)
X {
- struct proc_dir_entry *proc_entry = NULL;
+ struct proc_dir_entry *proc_entry = NULL, *proc;
X
X if (!thermal_zone) {
X return(AE_BAD_PARAMETER);
@@ -186,15 +186,18 @@
X printk("Thermal Zone: found\n");
X
X proc_entry = proc_mkdir(thermal_zone->uid, tz_proc_root);
- if (!proc_entry) {
+ if (!proc_entry)
X return(AE_ERROR);
- }
X
- create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
+ proc = create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
X proc_entry, tz_osl_proc_read_status, (void*)thermal_zone);
+ if (!proc)
+ return(AE_ERROR);
X
- create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
+ proc = create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
X proc_entry, tz_osl_proc_read_info, (void*)thermal_zone);
+ if (!proc)
+ return(AE_ERROR);
X
X return(AE_OK);
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- v2.4.12/linux/drivers/block/DAC960.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/DAC960.c Wed Oct 17 14:46:29 2001
@@ -19,8 +19,8 @@
X */
X
X
-#define DAC960_DriverVersion "2.4.10"
-#define DAC960_DriverDate "23 July 2001"
+#define DAC960_DriverVersion "2.4.11"
+#define DAC960_DriverDate "11 October 2001"
X
X
X #include <linux/version.h>
@@ -42,6 +42,7 @@
X #include <linux/spinlock.h>
X #include <linux/timer.h>
X #include <linux/pci.h>
+#include <linux/init.h>
X #include <asm/io.h>
X #include <asm/segment.h>
X #include <asm/uaccess.h>
@@ -99,7 +100,7 @@
X */
X
X static NotifierBlock_T
- DAC960_NotifierBlock = { DAC960_Finalize, NULL, 0 };
+ DAC960_NotifierBlock = { DAC960_Notifier, NULL, 0 };
X
X
X /*
@@ -269,7 +270,9 @@
X
X /*
X DAC960_AllocateCommand allocates a Command structure from Controller's


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 11'
echo 'File patch-2.4.13 is continued in part 12'
echo "12" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:42 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part12

#!/bin/sh -x
# this is part 12 of a 53 - part archive


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

if test "$Scheck" != 12; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- free list.
+ free list. During driver initialization, a special initialization command
+ has been placed on the free list to guarantee that command allocation can
+ never fail.
X */
X
X static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
@@ -480,6 +483,52 @@
X
X
X /*
+ DAC960_P_QueueCommand queues Command for DAC960 P Series Controllers.
+*/
+
+static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ switch (CommandMailbox->Common.CommandOpcode)
+ {
+ case DAC960_V1_Enquiry:
+ CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old;
+ break;
+ case DAC960_V1_GetDeviceState:
+ CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old;
+ break;
+ case DAC960_V1_Read:
+ CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old;
+ DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_Write:
+ CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old;
+ DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_ReadWithScatterGather:
+ CommandMailbox->Common.CommandOpcode =
+ DAC960_V1_ReadWithScatterGather_Old;
+ DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_WriteWithScatterGather:
+ CommandMailbox->Common.CommandOpcode =
+ DAC960_V1_WriteWithScatterGather_Old;
+ DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ default:
+ break;
+ }
+ while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+ DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
+/*
X DAC960_ExecuteCommand executes Command and waits for completion.
X */
X
@@ -522,6 +571,32 @@
X
X
X /*
+ DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B
+ Command and waits for completion. It returns true on success and false
+ on failure.
+*/
+
+static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
+ DAC960_V1_CommandOpcode_T CommandOpcode,
+ unsigned char CommandOpcode2,
+ void *DataPointer)
+{
+ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandStatus_T CommandStatus;
+ DAC960_V1_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+ CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
+ CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
+ CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V1.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V1_NormalCompletion);
+}
+
+
+/*
X DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
X Command and waits for completion. It returns true on success and false
X on failure.
@@ -1055,7 +1130,17 @@
X DAC1164P 5.06 and above
X DAC960PTL/PRL/PJ/PG 4.06 and above
X DAC960PU/PD/PL 3.51 and above
+ DAC960PU/PD/PL/P 2.73 and above
X */
+ if (Enquiry2.FirmwareID.MajorVersion == 0)
+ {
+ Enquiry2.FirmwareID.MajorVersion =
+ Controller->V1.Enquiry.MajorFirmwareVersion;
+ Enquiry2.FirmwareID.MinorVersion =
+ Controller->V1.Enquiry.MinorFirmwareVersion;
+ Enquiry2.FirmwareID.FirmwareType = '0';
+ Enquiry2.FirmwareID.TurnID = 0;
+ }
X sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
X Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
X Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
@@ -1064,7 +1149,9 @@
X (Controller->FirmwareVersion[0] == '4' &&
X strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
X (Controller->FirmwareVersion[0] == '3' &&
- strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
+ strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
+ (Controller->FirmwareVersion[0] == '2' &&
+ strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
X {
X DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
X DAC960_Error("Firmware Version = '%s'\n", Controller,
@@ -1120,6 +1207,20 @@
X return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
X }
X /*
+ Initialize the Background Initialization Status.
+ */
+ if ((Controller->FirmwareVersion[0] == '4' &&
+ strcmp(Controller->FirmwareVersion, "4.08") >= 0) ||
+ (Controller->FirmwareVersion[0] == '5' &&
+ strcmp(Controller->FirmwareVersion, "5.08") >= 0))
+ {
+ Controller->V1.BackgroundInitializationStatusSupported = true;
+ DAC960_V1_ExecuteType3B(Controller,
+ DAC960_V1_BackgroundInitializationControl, 0x20,
+ &Controller->
+ V1.LastBackgroundInitializationStatus);
+ }
+ /*
X Initialize the Logical Drive Initially Accessible flag.
X */
X for (LogicalDriveNumber = 0;
@@ -1573,7 +1674,7 @@
X DeviceState->DeviceType == DAC960_V1_DiskType)
X {
X if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
- DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
+ DAC960_Info(" Disk Status: %s, %u blocks, %d resets\n",
X Controller,
X (DeviceState->DeviceState == DAC960_V1_Device_Dead
X ? "Dead"
@@ -1586,7 +1687,7 @@
X DeviceState->DiskSize,
X Controller->V1.DeviceResetCount[Channel][TargetID]);
X else
- DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
+ DAC960_Info(" Disk Status: %s, %u blocks\n", Controller,
X (DeviceState->DeviceState == DAC960_V1_Device_Dead
X ? "Dead"
X : DeviceState->DeviceState
@@ -1615,7 +1716,7 @@
X {
X DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
X &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
- DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
+ DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %s\n",
X Controller, Controller->ControllerNumber, LogicalDriveNumber,
X LogicalDriveInformation->RAIDLevel,
X (LogicalDriveInformation->LogicalDriveState
@@ -1681,18 +1782,32 @@
X if (PhysicalDeviceInfo->PhysicalDeviceState ==
X DAC960_V2_Device_Unconfigured)
X continue;
- DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
+ DAC960_Info(" Disk Status: %s, %u blocks\n", Controller,
X (PhysicalDeviceInfo->PhysicalDeviceState
X == DAC960_V2_Device_Online
X ? "Online"
X : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_WriteOnly
- ? "Write-Only"
+ == DAC960_V2_Device_Rebuild
+ ? "Rebuild"
X : PhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Dead
- ? "Dead" : "Standby"),
- PhysicalDeviceInfo
- ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ == DAC960_V2_Device_Missing
+ ? "Missing"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Critical
+ ? "Critical"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Dead
+ ? "Dead"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_SuspectedDead
+ ? "Suspected-Dead"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_CommandedOffline
+ ? "Commanded-Offline"
+ : PhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Standby
+ ? "Standby" : "Unknown"),
+ PhysicalDeviceInfo->ConfigurableDeviceSize);
X if (PhysicalDeviceInfo->ParityErrors == 0 &&
X PhysicalDeviceInfo->SoftErrors == 0 &&
X PhysicalDeviceInfo->HardErrors == 0 &&
@@ -1734,7 +1849,7 @@
X "-", "-", "-", "-" };
X unsigned char *GeometryTranslation;
X if (LogicalDeviceInfo == NULL) continue;
- switch(LogicalDeviceInfo->DriveGeometry)
+ switch (LogicalDeviceInfo->DriveGeometry)
X {
X case DAC960_V2_Geometry_128_32:
X GeometryTranslation = "128/32";
@@ -1748,7 +1863,7 @@
X Controller, LogicalDeviceInfo->DriveGeometry);
X break;
X }
- DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+ DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %u blocks\n",
X Controller, Controller->ControllerNumber, LogicalDriveNumber,
X LogicalDeviceInfo->RAIDLevel,
X (LogicalDeviceInfo->LogicalDeviceState
@@ -1757,7 +1872,7 @@
X : LogicalDeviceInfo->LogicalDeviceState
X == DAC960_V2_LogicalDevice_Critical
X ? "Critical" : "Offline"),
- LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ LogicalDeviceInfo->ConfigurableDeviceSize);
X DAC960_Info(" Logical Device %s, BIOS Geometry: %s\n",
X Controller,
X (LogicalDeviceInfo->LogicalDeviceControl
@@ -1907,15 +2022,11 @@
X RequestQueue->queuedata = Controller;
X Controller->RequestQueue = RequestQueue;
X /*
- Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
- array, and Max Sectors per Request array.
+ Initialize the Max Sectors per Request array.
X */
X for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
- {
- Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
- Controller->MaxSectorsPerRequest[MinorNumber] =
- Controller->MaxBlocksPerCommand;
- }
+ Controller->MaxSectorsPerRequest[MinorNumber] =
+ Controller->MaxBlocksPerCommand;
X Controller->GenericDiskInfo.part = Controller->DiskPartitions;
X Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
X blksize_size[MajorNumber] = Controller->BlockSizes;
@@ -1931,7 +2042,8 @@
X Controller->GenericDiskInfo.major_name = "rd";
X Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
X Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
- Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
+ Controller->GenericDiskInfo.nr_real = DAC960_MaxLogicalDrives;
+ Controller->GenericDiskInfo.real_devices = Controller;
X Controller->GenericDiskInfo.next = NULL;
X Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
X /*
@@ -1978,6 +2090,46 @@
X
X
X /*
+ DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk
+ Information Partition Sector Counts and Block Sizes.
+*/
+
+static void DAC960_ComputeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
+{
+ DAC960_Controller_T *Controller =
+ (DAC960_Controller_T *) GenericDiskInfo->real_devices;
+ int LogicalDriveNumber, i;
+ for (LogicalDriveNumber = 0;
+ LogicalDriveNumber < DAC960_MaxLogicalDrives;
+ LogicalDriveNumber++)
+ {
+ int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, 0);
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ {
+ if (LogicalDriveNumber < Controller->LogicalDriveCount)
+ GenericDiskInfo->part[MinorNumber].nr_sects =
+ Controller->V1.LogicalDriveInformation
+ [LogicalDriveNumber].LogicalDriveSize;
+ else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+ }
+ else
+ {
+ DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+ Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+ if (LogicalDeviceInfo != NULL)
+ GenericDiskInfo->part[MinorNumber].nr_sects =
+ LogicalDeviceInfo->ConfigurableDeviceSize;
+ else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+ }
+ for (i = 0; i < DAC960_MaxPartitions; i++)
+ if (GenericDiskInfo->part[MinorNumber].nr_sects > 0)
+ Controller->BlockSizes[MinorNumber + i] = BLOCK_SIZE;
+ else Controller->BlockSizes[MinorNumber + i] = 0;
+ }
+}
+
+
+/*
X DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
X Drive Number if it exists.
X */
@@ -1991,7 +2143,8 @@
X register_disk(&Controller->GenericDiskInfo,
X DAC960_KernelDevice(Controller->ControllerNumber,
X LogicalDriveNumber, 0),
- DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
+ DAC960_MaxPartitions,
+ &DAC960_BlockDeviceOperations,
X Controller->V1.LogicalDriveInformation
X [LogicalDriveNumber].LogicalDriveSize);
X }
@@ -2003,9 +2156,9 @@
X register_disk(&Controller->GenericDiskInfo,
X DAC960_KernelDevice(Controller->ControllerNumber,
X LogicalDriveNumber, 0),
- DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
- LogicalDeviceInfo
- ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ DAC960_MaxPartitions,
+ &DAC960_BlockDeviceOperations,
+ LogicalDeviceInfo->ConfigurableDeviceSize);
X }
X }
X
@@ -2116,6 +2269,13 @@
X InterruptHandler = DAC960_PD_InterruptHandler;
X MemoryWindowSize = DAC960_PD_RegisterWindowSize;
X break;
+ case DAC960_P_Controller:
+ VendorID = PCI_VENDOR_ID_MYLEX;
+ DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
+ FirmwareType = DAC960_V1_Controller;
+ InterruptHandler = DAC960_P_InterruptHandler;
+ MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+ break;
X }
X while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
X {
@@ -2151,6 +2311,10 @@
X IO_Address = pci_resource_start(PCI_Device, 0);
X PCI_Address = pci_resource_start(PCI_Device, 1);
X break;
+ case DAC960_P_Controller:
+ IO_Address = pci_resource_start(PCI_Device, 0);
+ PCI_Address = pci_resource_start(PCI_Device, 1);
+ break;
X }
X if (DAC960_ControllerCount == DAC960_MaxControllers)
X {
@@ -2348,6 +2512,32 @@
X Controller->QueueReadWriteCommand =
X DAC960_V1_QueueReadWriteCommand;
X break;
+ case DAC960_P_Controller:
+ request_region(Controller->IO_Address, 0x80,
+ Controller->FullModelName);
+ DAC960_PD_DisableInterrupts(BaseAddress);
+ DAC960_PD_AcknowledgeStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_PD_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+ Controller->QueueCommand = DAC960_P_QueueCommand;
+ Controller->ReadControllerConfiguration =
+ DAC960_V1_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V1_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V1_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V1_QueueReadWriteCommand;
+ break;
X }
X /*
X Acquire shared access to the IRQ Channel.
@@ -2519,7 +2709,7 @@
X DAC960_Initialize initializes the DAC960 Driver.
X */
X
-void DAC960_Initialize(void)
+static int DAC960_Initialize(void)
X {
X int ControllerNumber;
X DAC960_DetectControllers(DAC960_BA_Controller);
@@ -2527,8 +2717,9 @@
X DAC960_DetectControllers(DAC960_LA_Controller);
X DAC960_DetectControllers(DAC960_PG_Controller);
X DAC960_DetectControllers(DAC960_PD_Controller);
+ DAC960_DetectControllers(DAC960_P_Controller);
X DAC960_SortControllers();
- if (DAC960_ActiveControllerCount == 0) return;
+ if (DAC960_ActiveControllerCount == 0) return -ENODEV;
X for (ControllerNumber = 0;
X ControllerNumber < DAC960_ControllerCount;
X ControllerNumber++)
@@ -2537,6 +2728,7 @@
X int LogicalDriveNumber;
X if (Controller == NULL) continue;
X DAC960_InitializeController(Controller);
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
X for (LogicalDriveNumber = 0;
X LogicalDriveNumber < DAC960_MaxLogicalDrives;
X LogicalDriveNumber++)
@@ -2544,6 +2736,7 @@
X }
X DAC960_CreateProcEntries();
X register_reboot_notifier(&DAC960_NotifierBlock);


+ return 0;
X }
X
X

@@ -2551,14 +2744,10 @@
X DAC960_Finalize finalizes the DAC960 Driver.
X */
X
-static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
- unsigned long Event,
- void *Buffer)
+static void DAC960_Finalize(void)
X {
X int ControllerNumber;
- if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
- return NOTIFY_DONE;
- if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
+ if (DAC960_ActiveControllerCount == 0) return;
X for (ControllerNumber = 0;
X ControllerNumber < DAC960_ControllerCount;
X ControllerNumber++)
@@ -2566,6 +2755,20 @@
X DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
X DAC960_DestroyProcEntries();
X unregister_reboot_notifier(&DAC960_NotifierBlock);
+}
+
+
+/*
+ DAC960_Notifier is the notifier for the DAC960 Driver.
+*/
+
+static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
+ unsigned long Event,
+ void *Buffer)
+{
+ if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
+ return NOTIFY_DONE;
+ DAC960_Finalize();
X return NOTIFY_OK;
X }
X
@@ -2599,11 +2802,9 @@
X char *LastDataEndPointer = NULL;
X int SegmentNumber = 0;
X if (Command->CommandType == DAC960_ReadCommand)
- CommandMailbox->Type5.CommandOpcode =
- DAC960_V1_ReadWithOldScatterGather;
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
X else
- CommandMailbox->Type5.CommandOpcode =
- DAC960_V1_WriteWithOldScatterGather;
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
X CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
X CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
X CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -2865,12 +3066,12 @@
X Controller, Command->V1.CommandStatus, CommandName);
X break;
X }
- DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
+ DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %u..%u\n",
X Controller, Controller->ControllerNumber,
X Command->LogicalDriveNumber, Command->BlockNumber,
X Command->BlockNumber + Command->BlockCount - 1);
X if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
- DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+ DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
X Controller, Controller->ControllerNumber,
X Command->LogicalDriveNumber,
X DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3027,6 +3228,8 @@
X LogicalDriveNumber,
X Controller->ControllerNumber,
X LogicalDriveNumber);
+ Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
X }
X if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount)
X {
@@ -3037,8 +3240,9 @@
X LogicalDriveNumber,
X Controller->ControllerNumber,
X LogicalDriveNumber);
+ Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
X }
- Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
X if (NewEnquiry->StatusFlags.DeferredWriteError !=
X OldEnquiry->StatusFlags.DeferredWriteError)
X DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -3064,6 +3268,8 @@
X Controller->V1.NeedErrorTableInformation = true;
X Controller->V1.NeedDeviceStateInformation = true;
X Controller->V1.StartDeviceStateScan = true;
+ Controller->V1.NeedBackgroundInitializationStatus =
+ Controller->V1.BackgroundInitializationStatusSupported;
X Controller->SecondaryMonitoringTime = jiffies;
X }
X if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
@@ -3186,7 +3392,7 @@
X AdditionalSenseCodeQualifier == 0x02))))
X {
X DAC960_Critical("Physical Device %d:%d Error Log: "
- "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+ "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
X Controller,
X EventLogEntry->Channel,
X EventLogEntry->TargetID,
@@ -3396,6 +3602,77 @@
X Controller->EphemeralProgressMessage = false;
X }
X }
+ else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
+ {
+ unsigned int LogicalDriveNumber =
+ Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
+ unsigned int LogicalDriveSize =
+ Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
+ unsigned int BlocksCompleted =
+ Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
+ switch (CommandStatus)
+ {
+ case DAC960_V1_NormalCompletion:
+ switch (Controller->V1.BackgroundInitializationStatus.Status)
+ {
+ case DAC960_V1_BackgroundInitializationInvalid:
+ break;
+ case DAC960_V1_BackgroundInitializationStarted:
+ DAC960_Progress("Background Initialization Started\n",
+ Controller);
+ break;
+ case DAC960_V1_BackgroundInitializationInProgress:
+ if (BlocksCompleted ==
+ Controller->V1.LastBackgroundInitializationStatus
+ .BlocksCompleted &&
+ LogicalDriveNumber ==
+ Controller->V1.LastBackgroundInitializationStatus
+ .LogicalDriveNumber)
+ break;
+ Controller->EphemeralProgressMessage = true;
+ DAC960_Progress("Background Initialization in Progress: "
+ "Logical Drive %d (/dev/rd/c%dd%d) "
+ "%d%% completed\n",
+ Controller, LogicalDriveNumber,
+ Controller->ControllerNumber,
+ LogicalDriveNumber,
+ (100 * (BlocksCompleted >> 7))
+ / (LogicalDriveSize >> 7));
+ Controller->EphemeralProgressMessage = false;
+ break;
+ case DAC960_V1_BackgroundInitializationSuspended:
+ DAC960_Progress("Background Initialization Suspended\n",
+ Controller);
+ break;
+ case DAC960_V1_BackgroundInitializationCancelled:
+ DAC960_Progress("Background Initialization Cancelled\n",
+ Controller);
+ break;
+ }
+ memcpy(&Controller->V1.LastBackgroundInitializationStatus,
+ &Controller->V1.BackgroundInitializationStatus,
+ sizeof(DAC960_V1_BackgroundInitializationStatus_T));
+ break;
+ case DAC960_V1_BackgroundInitSuccessful:
+ if (Controller->V1.BackgroundInitializationStatus.Status ==
+ DAC960_V1_BackgroundInitializationInProgress)
+ DAC960_Progress("Background Initialization "
+ "Completed Successfully\n", Controller);
+ Controller->V1.BackgroundInitializationStatus.Status =
+ DAC960_V1_BackgroundInitializationInvalid;
+ break;
+ case DAC960_V1_BackgroundInitAborted:
+ if (Controller->V1.BackgroundInitializationStatus.Status ==
+ DAC960_V1_BackgroundInitializationInProgress)
+ DAC960_Progress("Background Initialization Aborted\n",
+ Controller);
+ Controller->V1.BackgroundInitializationStatus.Status =
+ DAC960_V1_BackgroundInitializationInvalid;
+ break;
+ case DAC960_V1_NoBackgroundInitInProgress:
+ break;
+ }
+ }
X }
X if (CommandType == DAC960_MonitoringCommand)
X {
@@ -3562,6 +3839,17 @@
X DAC960_QueueCommand(Command);
X return;
X }
+ if (Controller->V1.NeedBackgroundInitializationStatus)
+ {
+ Controller->V1.NeedBackgroundInitializationStatus = false;
+ Command->V1.CommandMailbox.Type3B.CommandOpcode =
+ DAC960_V1_BackgroundInitializationControl;
+ Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
+ Command->V1.CommandMailbox.Type3B.BusAddress =
+ Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
+ DAC960_QueueCommand(Command);
+ return;
+ }
X Controller->MonitoringTimerCount++;
X Controller->MonitoringTimer.expires =
X jiffies + DAC960_MonitoringTimerInterval;
@@ -3642,12 +3930,12 @@
X }
X DAC960_Error("Error Condition %s on %s:\n", Controller,
X SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
- DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
+ DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %u..%u\n",
X Controller, Controller->ControllerNumber,
X Command->LogicalDriveNumber, Command->BlockNumber,
X Command->BlockNumber + Command->BlockCount - 1);
X if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
- DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+ DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
X Controller, Controller->ControllerNumber,
X Command->LogicalDriveNumber,
X DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3680,11 +3968,14 @@
X { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
X { 0x000C, "S Offline" },
X { 0x000D, "P Found" },
- { 0x000E, "P Gone" },
+ { 0x000E, "P Removed" },
X { 0x000F, "P Unconfigured" },
X { 0x0010, "P Expand Capacity Started" },
X { 0x0011, "P Expand Capacity Completed" },
X { 0x0012, "P Expand Capacity Failed" },
+ { 0x0013, "P Command Timed Out" },
+ { 0x0014, "P Command Aborted" },
+ { 0x0015, "P Command Retried" },
X { 0x0016, "P Parity Error" },
X { 0x0017, "P Soft Error" },
X { 0x0018, "P Miscellaneous Error" },
@@ -3715,6 +4006,8 @@
X { 0x0031, "P Failed because BDT Write Operation Failed" },
X { 0x0039, "P Missing at Startup" },
X { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+ { 0x003C, "P Temporarily Offline Device Automatically Made Online" },
+ { 0x003D, "P Standby Rebuild Started" },
X /* Logical Device Events (0x0080 - 0x00FF) */
X { 0x0080, "M Consistency Check Started" },
X { 0x0081, "M Consistency Check Completed" },
@@ -3737,7 +4030,7 @@
X { 0x0092, "M Initialization Cancelled" },
X { 0x0093, "M Initialization Failed" },
X { 0x0094, "L Found" },
- { 0x0095, "L Gone" },
+ { 0x0095, "L Deleted" },
X { 0x0096, "M Expand Capacity Started" },
X { 0x0097, "M Expand Capacity Completed" },
X { 0x0098, "M Expand Capacity Failed" },
@@ -3747,6 +4040,9 @@
X { 0x009C, "L Bad Data Block Found" },
X { 0x009E, "L Read of Data Block in BDT" },
X { 0x009F, "L Write Back Data for Disk Block Lost" },
+ { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
+ { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
+ { 0x00A2, "L Standby Rebuild Started" },
X /* Fault Management Events (0x0100 - 0x017F) */
X { 0x0140, "E Fan %d Failed" },
X { 0x0141, "E Fan %d OK" },
@@ -3754,24 +4050,31 @@
X { 0x0143, "E Power Supply %d Failed" },
X { 0x0144, "E Power Supply %d OK" },
X { 0x0145, "E Power Supply %d Not Present" },
- { 0x0146, "E Temperature Sensor %d Failed" },
- { 0x0147, "E Temperature Sensor %d Critical" },
- { 0x0148, "E Temperature Sensor %d OK" },
+ { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
+ { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
+ { 0x0148, "E Temperature Sensor %d Temperature Normal" },
X { 0x0149, "E Temperature Sensor %d Not Present" },
- { 0x014A, "E Unit %d Access Critical" },
- { 0x014B, "E Unit %d Access OK" },
- { 0x014C, "E Unit %d Access Offline" },
+ { 0x014A, "E Enclosure Management Unit %d Access Critical" },
+ { 0x014B, "E Enclosure Management Unit %d Access OK" },
+ { 0x014C, "E Enclosure Management Unit %d Access Offline" },
X /* Controller Events (0x0180 - 0x01FF) */
X { 0x0181, "C Cache Write Back Error" },
X { 0x0188, "C Battery Backup Unit Found" },
X { 0x0189, "C Battery Backup Unit Charge Level Low" },
X { 0x018A, "C Battery Backup Unit Charge Level OK" },
X { 0x0193, "C Installation Aborted" },
- { 0x0195, "C Mirror Race Recovery In Progress" },
- { 0x0196, "C Mirror Race on Critical Drive" },
- { 0x019E, "C Memory Soft ECC Error" },
- { 0x019F, "C Memory Hard ECC Error" },
+ { 0x0195, "C Battery Backup Unit Physically Removed" },
+ { 0x0196, "C Memory Error During Warm Boot" },
+ { 0x019E, "C Memory Soft ECC Error Corrected" },
+ { 0x019F, "C Memory Hard ECC Error Corrected" },
X { 0x01A2, "C Battery Backup Unit Failed" },
+ { 0x01AB, "C Mirror Race Recovery Failed" },
+ { 0x01AC, "C Mirror Race on Critical Drive" },
+ /* Controller Internal Processor Events */
+ { 0x0380, "C Internal Controller Hung" },
+ { 0x0381, "C Internal Controller Firmware Breakpoint" },
+ { 0x0390, "C Internal Controller i960 Processor Specific Error" },
+ { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
X { 0, "" } };
X int EventListIndex = 0, EventCode;
X unsigned char EventType, *EventMessage;
@@ -3821,7 +4124,7 @@
X DAC960_Critical("Physical Device %d:%d %s\n", Controller,
X Event->Channel, Event->TargetID, EventMessage);
X DAC960_Critical("Physical Device %d:%d Request Sense: "
- "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+ "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
X Controller,
X Event->Channel,
X Event->TargetID,
@@ -4142,22 +4445,34 @@
X {
X if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
X PhysicalDeviceInfo->PhysicalDeviceState)
- DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
- NewPhysicalDeviceInfo->Channel,
- NewPhysicalDeviceInfo->TargetID,
- (NewPhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Unconfigured
- ? "UNCONFIGURED"
- : NewPhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_Online
- ? "ONLINE"
- : NewPhysicalDeviceInfo->PhysicalDeviceState
- == DAC960_V2_Device_WriteOnly
- ? "WRITE-ONLY"
- : NewPhysicalDeviceInfo
- ->PhysicalDeviceState
- == DAC960_V2_Device_Dead
- ? "DEAD" : "STANDBY"));
+ DAC960_Critical(
+ "Physical Device %d:%d is now %s\n", Controller,
+ NewPhysicalDeviceInfo->Channel,
+ NewPhysicalDeviceInfo->TargetID,
+ (NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Online
+ ? "ONLINE"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Rebuild
+ ? "REBUILD"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Missing
+ ? "MISSING"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Critical
+ ? "CRITICAL"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Dead
+ ? "DEAD"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_SuspectedDead
+ ? "SUSPECTED-DEAD"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_CommandedOffline
+ ? "COMMANDED-OFFLINE"
+ : NewPhysicalDeviceInfo->PhysicalDeviceState
+ == DAC960_V2_Device_Standby
+ ? "STANDBY" : "UNKNOWN"));
X if ((NewPhysicalDeviceInfo->ParityErrors !=
X PhysicalDeviceInfo->ParityErrors) ||
X (NewPhysicalDeviceInfo->SoftErrors !=
@@ -4263,13 +4578,16 @@
X (LogicalDeviceInfo != NULL
X ? "" : " - Allocation Failed"));
X if (LogicalDeviceInfo != NULL)
- memset(LogicalDeviceInfo, 0,
- sizeof(DAC960_V2_LogicalDeviceInfo_T));
+ {
+ memset(LogicalDeviceInfo, 0,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T));
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
+ }
X }
X if (LogicalDeviceInfo != NULL)
X {
X unsigned long LogicalDeviceSize =
- NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+ NewLogicalDeviceInfo->ConfigurableDeviceSize;
X if (NewLogicalDeviceInfo->LogicalDeviceState !=
X LogicalDeviceInfo->LogicalDeviceState)
X DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -4380,6 +4698,7 @@
X kfree(LogicalDeviceInfo);
X Controller->LogicalDriveInitiallyAccessible
X [LogicalDriveNumber] = false;
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
X }
X Controller->V2.NeedLogicalDeviceInformation = false;
X }
@@ -4785,6 +5104,85 @@
X
X
X /*
+ DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
+ Controllers.
+*/
+
+static void DAC960_P_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ Registers_T *InterruptRegisters)
+{
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ void *ControllerBaseAddress = Controller->BaseAddress;
+ ProcessorFlags_T ProcessorFlags;
+ /*
+ Acquire exclusive access to Controller.
+ */
+ DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+ /*
+ Process Hardware Interrupts for Controller.
+ */
+ while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
+ {
+ DAC960_V1_CommandIdentifier_T CommandIdentifier =
+ DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_CommandOpcode_T CommandOpcode =
+ CommandMailbox->Common.CommandOpcode;
+ Command->V1.CommandStatus =
+ DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+ DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+ DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+ switch (CommandOpcode)
+ {
+ case DAC960_V1_Enquiry_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
+ DAC960_P_To_PD_TranslateEnquiry(
+ Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+ break;
+ case DAC960_V1_GetDeviceState_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode =
+ DAC960_V1_GetDeviceState;
+ DAC960_P_To_PD_TranslateDeviceState(
+ Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+ break;
+ case DAC960_V1_Read_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
+ DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_Write_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
+ DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_ReadWithScatterGather_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode =
+ DAC960_V1_ReadWithScatterGather;
+ DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ case DAC960_V1_WriteWithScatterGather_Old:
+ Command->V1.CommandMailbox.Common.CommandOpcode =
+ DAC960_V1_WriteWithScatterGather;
+ DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+ break;
+ default:
+ break;
+ }
+ DAC960_V1_ProcessCompletedCommand(Command);
+ }
+ /*
+ Attempt to remove additional I/O Requests from the Controller's
+ I/O Request Queue and queue them to the Controller.
+ */
+ while (DAC960_ProcessRequest(Controller, false)) ;
+ /*
+ Release exclusive access to Controller.
+ */
+ DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
X DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
X Firmware Controllers.
X */
@@ -4881,8 +5279,7 @@
X Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
X if (LogicalDeviceInfo == NULL) continue;
X if (!LogicalDeviceInfo->LogicalDeviceControl
- .LogicalDeviceInitialized &&
- Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 0)
+ .LogicalDeviceInitialized)
X {
X ForceMonitoringCommand = true;
X break;
@@ -4970,6 +5367,7 @@
X if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
X {
X Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+ DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
X DAC960_RegisterDisk(Controller, LogicalDriveNumber);
X }
X if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
@@ -5049,7 +5447,7 @@
X Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
X if (LogicalDeviceInfo == NULL)
X return -EINVAL;
- switch(LogicalDeviceInfo->DriveGeometry)
+ switch (LogicalDeviceInfo->DriveGeometry)
X {
X case DAC960_V2_Geometry_128_32:
X Geometry.heads = 128;
@@ -5065,7 +5463,7 @@
X return -EINVAL;
X }
X Geometry.cylinders =
- LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+ LogicalDeviceInfo->ConfigurableDeviceSize
X / (Geometry.heads * Geometry.sectors);
X }
X Geometry.start =
@@ -5074,19 +5472,22 @@
X sizeof(DiskGeometry_T)) ? -EFAULT : 0);
X case BLKGETSIZE:
X /* Get Device Size. */
+ if ((unsigned long *) Argument == NULL) return -EINVAL;
X return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
X .nr_sects,
- (long *) Argument);
+ (unsigned long *) Argument);
X case BLKGETSIZE64:
- return put_user((u64)Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].nr_sects << 9,
+ if ((u64 *) Argument == NULL) return -EINVAL;
+ return put_user((u64) Controller->GenericDiskInfo
+ .part[MINOR(Inode->i_rdev)]
+ .nr_sects << 9,
X (u64 *) Argument);
X case BLKRAGET:
X case BLKRASET:
X case BLKFLSBUF:
X case BLKBSZGET:
X case BLKBSZSET:
- return blk_ioctl (Inode->i_rdev, Request, Argument);
-
+ return blk_ioctl(Inode->i_rdev, Request, Argument);
X case BLKRRPART:
X /* Re-Read Partition Table. */
X if (!capable(CAP_SYS_ADMIN)) return -EACCES;
@@ -5120,20 +5521,7 @@
X */
X set_blocksize(Device, BLOCK_SIZE);
X }
- if (Controller->FirmwareType == DAC960_V1_Controller)
- grok_partitions(&Controller->GenericDiskInfo,
- LogicalDriveNumber,
- DAC960_MaxPartitions,
- Controller->V1.LogicalDriveInformation
- [LogicalDriveNumber]
- .LogicalDriveSize);
- else
- grok_partitions(
- &Controller->GenericDiskInfo,
- LogicalDriveNumber,
- DAC960_MaxPartitions,
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]
- ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+ DAC960_RegisterDisk(Controller, LogicalDriveNumber);
X return 0;
X }
X return -EINVAL;
@@ -6365,6 +6753,43 @@
X == DAC960_V2_NormalCompletion
X ? "Cancelled" : "Not Cancelled"));
X }
+ else if (strcmp(UserCommand, "perform-discovery") == 0)
+ {
+ CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
+ DAC960_ExecuteCommand(Command);
+ DAC960_UserCritical("Discovery %s\n", Controller,
+ (Command->V2.CommandStatus
+ == DAC960_V2_NormalCompletion
+ ? "Initiated" : "Not Initiated"));
+ if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
+ {
+ CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->ControllerInfo.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->ControllerInfo.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->ControllerInfo.DataTransferSize =
+ sizeof(DAC960_V2_ControllerInfo_T);
+ CommandMailbox->ControllerInfo.ControllerNumber = 0;
+ CommandMailbox->ControllerInfo.IOCTL_Opcode =
+ DAC960_V2_GetControllerInfo;
+ CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
+ CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->ControllerInfo.DataTransferSize;
+ DAC960_ExecuteCommand(Command);
+ while (Controller->V2.NewControllerInformation.PhysicalScanActive)
+ {
+ DAC960_ExecuteCommand(Command);
+ sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
+ }
+ DAC960_UserCritical("Discovery Completed\n", Controller);
+ }
+ }
X else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
X Controller->SuppressEnclosureMessages = true;
X else DAC960_UserCritical("Illegal User Command: '%s'\n",
@@ -6587,24 +7012,5 @@
X }
X
X
-/*
- Include Module support if requested.
-*/
-
-#ifdef MODULE
-
-
-int init_module(void)
-{
- DAC960_Initialize();
- return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
-}
-
-
-void cleanup_module(void)
-{
- DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
-}
-
-
-#endif
+module_init(DAC960_Initialize);
+module_exit(DAC960_Finalize);
diff -u --recursive --new-file v2.4.12/linux/drivers/block/DAC960.h linux/drivers/block/DAC960.h
--- v2.4.12/linux/drivers/block/DAC960.h Sun Aug 12 13:27:59 2001
+++ linux/drivers/block/DAC960.h Wed Oct 17 14:46:29 2001
@@ -224,9 +224,9 @@
X DAC960_V1_ReadExtendedWithScatterGather = 0xB3,
X DAC960_V1_WriteExtendedWithScatterGather = 0xB4,
X DAC960_V1_Read = 0x36,
- DAC960_V1_ReadWithOldScatterGather = 0xB6,
+ DAC960_V1_ReadWithScatterGather = 0xB6,
X DAC960_V1_Write = 0x37,
- DAC960_V1_WriteWithOldScatterGather = 0xB7,
+ DAC960_V1_WriteWithScatterGather = 0xB7,
X DAC960_V1_DCDB = 0x04,
X DAC960_V1_DCDBWithScatterGather = 0x84,
X DAC960_V1_Flush = 0x0A,
@@ -280,7 +280,14 @@
X DAC960_V1_RunDiagnostic = 0x32,
X /* Subsystem Service Commands */
X DAC960_V1_GetSubsystemData = 0x70,
- DAC960_V1_SetSubsystemParameters = 0x71
+ DAC960_V1_SetSubsystemParameters = 0x71,
+ /* Version 2.xx Firmware Commands */
+ DAC960_V1_Enquiry_Old = 0x05,
+ DAC960_V1_GetDeviceState_Old = 0x14,
+ DAC960_V1_Read_Old = 0x02,
+ DAC960_V1_Write_Old = 0x03,
+ DAC960_V1_ReadWithScatterGather_Old = 0x82,
+ DAC960_V1_WriteWithScatterGather_Old = 0x83
X }
X __attribute__ ((packed))
X DAC960_V1_CommandOpcode_T;
@@ -327,6 +334,9 @@
X #define DAC960_V1_RebuildFailed_NewDriveFailed 0x0004 /* Consistency */
X #define DAC960_V1_RebuildSuccessful 0x0100 /* Consistency */
X #define DAC960_V1_RebuildSuccessfullyTerminated 0x0107 /* Consistency */
+#define DAC960_V1_BackgroundInitSuccessful 0x0100 /* Consistency */
+#define DAC960_V1_BackgroundInitAborted 0x0005 /* Consistency */
+#define DAC960_V1_NoBackgroundInitInProgress 0x0105 /* Consistency */
X #define DAC960_V1_AddCapacityInProgress 0x0004 /* Consistency */
X #define DAC960_V1_AddCapacityFailedOrSuspended 0x00F4 /* Consistency */
X #define DAC960_V1_Config2ChecksumError 0x0002 /* Configuration */
@@ -634,6 +644,8 @@
X
X /*
X Define the DAC960 V1 Firmware Get Device State Command reply structure.
+ The structure is padded by 2 bytes for compatibility with Version 2.xx
+ Firmware.
X */
X
X typedef struct DAC960_V1_DeviceState
@@ -658,6 +670,7 @@
X unsigned char SynchronousOffset:5; /* Byte 5 Bits 0-4 */
X unsigned char :3; /* Byte 5 Bits 5-7 */
X unsigned int DiskSize __attribute__ ((packed)); /* Bytes 6-9 */
+ unsigned short :16; /* Bytes 10-11 */
X }
X DAC960_V1_DeviceState_T;
X
@@ -676,6 +689,30 @@
X
X
X /*
+ Define the DAC960 V1 Firmware Background Initialization Status Command
+ reply structure.
+*/
+
+typedef struct DAC960_V1_BackgroundInitializationStatus
+{
+ unsigned int LogicalDriveSize; /* Bytes 0-3 */
+ unsigned int BlocksCompleted; /* Bytes 4-7 */
+ unsigned char Reserved1[12]; /* Bytes 8-19 */
+ unsigned int LogicalDriveNumber; /* Bytes 20-23 */
+ unsigned char RAIDLevel; /* Byte 24 */
+ enum {
+ DAC960_V1_BackgroundInitializationInvalid = 0x00,
+ DAC960_V1_BackgroundInitializationStarted = 0x02,
+ DAC960_V1_BackgroundInitializationInProgress = 0x04,
+ DAC960_V1_BackgroundInitializationSuspended = 0x05,
+ DAC960_V1_BackgroundInitializationCancelled = 0x06
+ } __attribute__ ((packed)) Status; /* Byte 25 */
+ unsigned char Reserved2[6]; /* Bytes 26-31 */
+}
+DAC960_V1_BackgroundInitializationStatus_T;
+
+
+/*
X Define the DAC960 V1 Firmware Error Table Entry structure.
X */
X
@@ -853,6 +890,14 @@
X struct {
X DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */
X DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
+ unsigned char CommandOpcode2; /* Byte 2 */
+ unsigned char Dummy1[5]; /* Bytes 3-7 */
+ DAC960_BusAddress32_T BusAddress; /* Bytes 8-11 */
+ unsigned char Dummy2[4]; /* Bytes 12-15 */
+ } __attribute__ ((packed)) Type3B;
+ struct {
+ DAC960_V1_CommandOpcode_T CommandOpcode; /* Byte 0 */
+ DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
X unsigned char Dummy1[5]; /* Bytes 2-6 */
X unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */
X boolean AutoRestore:1; /* Byte 7 Bit 7 */
@@ -956,6 +1001,7 @@
X DAC960_V2_GetPhysicalDeviceInfoValid = 0x05,
X DAC960_V2_GetHealthStatus = 0x11,
X DAC960_V2_GetEvent = 0x15,
+ DAC960_V2_StartDiscovery = 0x81,
X DAC960_V2_SetDeviceState = 0x82,
X DAC960_V2_RebuildDeviceStart = 0x88,
X DAC960_V2_RebuildDeviceStop = 0x89,
@@ -982,7 +1028,10 @@
X
X #define DAC960_V2_NormalCompletion 0x00
X #define DAC960_V2_AbormalCompletion 0x02
+#define DAC960_V2_DeviceBusy 0x08
X #define DAC960_V2_DeviceNonresponsive 0x0E
+#define DAC960_V2_DeviceNonresponsive2 0x0F
+#define DAC960_V2_DeviceRevervationConflict 0x18
X
X typedef unsigned char DAC960_V2_CommandStatus_T;
X
@@ -1056,7 +1105,8 @@
X DAC960_V2_EXR2000P = 0x1C,
X DAC960_V2_EXR3000P = 0x1D,
X DAC960_V2_AcceleRAID352 = 0x1E,
- DAC960_V2_AcceleRAID351 = 0x1F,
+ DAC960_V2_AcceleRAID170 = 0x1F,
+ DAC960_V2_AcceleRAID160 = 0x20,
X DAC960_V2_DAC960S = 0x60,
X DAC960_V2_DAC960SU = 0x61,
X DAC960_V2_DAC960SX = 0x62,
@@ -1073,7 +1123,9 @@
X unsigned char :8; /* Byte 3 */
X unsigned short BusInterfaceSpeedMHz; /* Bytes 4-5 */
X unsigned char BusWidthBits; /* Byte 6 */
- unsigned char Reserved1[9]; /* Bytes 7-15 */
+ unsigned char FlashCodeTypeOrProductID; /* Byte 7 */
+ unsigned char NumberOfHostPortsPresent; /* Byte 8 */
+ unsigned char Reserved1[7]; /* Bytes 9-15 */
X unsigned char BusInterfaceName[16]; /* Bytes 16-31 */
X unsigned char ControllerName[16]; /* Bytes 32-47 */
X unsigned char Reserved2[16]; /* Bytes 48-63 */
@@ -1102,17 +1154,17 @@
X unsigned char HardwareManufacturingMonth; /* Byte 85 */
X unsigned char HardwareManufacturingYearHigh2Digits; /* Byte 86 */
X unsigned char HardwareManufacturingYearLow2Digits; /* Byte 87 */
- unsigned char MaximumNumberOfPDDperXLDD; /* Byte 88 */
- unsigned char MaximumNumberOfILDDperXLDD; /* Byte 89 */
+ unsigned char MaximumNumberOfPDDperXLD; /* Byte 88 */
+ unsigned char MaximumNumberOfILDperXLD; /* Byte 89 */
X unsigned short NonvolatileMemorySizeKB; /* Bytes 90-91 */
- unsigned char MaximumNumberOfXLDD; /* Byte 92 */
+ unsigned char MaximumNumberOfXLD; /* Byte 92 */
X unsigned int :24; /* Bytes 93-95 */
X /* Unique Information per Controller */
X unsigned char ControllerSerialNumber[16]; /* Bytes 96-111 */
X unsigned char Reserved3[16]; /* Bytes 112-127 */
X /* Vendor Information */
X unsigned int :24; /* Bytes 128-130 */
- unsigned char OEM_Information; /* Byte 131 */
+ unsigned char OEM_Code; /* Byte 131 */
X unsigned char VendorName[16]; /* Bytes 132-147 */
X /* Other Physical/Controller/Operation Information */
X boolean BBU_Present:1; /* Byte 148 Bit 0 */
@@ -1193,12 +1245,14 @@
X unsigned short PhysicalDeviceHostCommandAbortsDone; /* Bytes 370-371 */
X unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */
X unsigned short PhysicalDeviceHostCommandsFailed; /* Bytes 374-375 */
- unsigned char Reserved9[8]; /* Bytes 376-383 */
+ unsigned short PhysicalDeviceHardErrors; /* Bytes 376-377 */
+ unsigned char Reserved9[6]; /* Bytes 378-383 */
X /* Error Counters on Logical Devices */
X unsigned short LogicalDeviceSoftErrors; /* Bytes 384-385 */
X unsigned short LogicalDeviceCommandsFailed; /* Bytes 386-387 */
X unsigned short LogicalDeviceHostCommandAbortsDone; /* Bytes 388-389 */
X unsigned short :16; /* Bytes 390-391 */
+ /* Error Counters on Controller */
X unsigned short ControllerMemoryErrors; /* Bytes 392-393 */
X unsigned short ControllerHostCommandAbortsDone; /* Bytes 394-395 */
X unsigned int :32; /* Bytes 396-399 */
@@ -1210,8 +1264,7 @@
X unsigned short RebuildsActive; /* Bytes 408-409 */
X unsigned short OnlineExpansionsActive; /* Bytes 410-411 */
X unsigned short PatrolActivitiesActive; /* Bytes 412-413 */
- unsigned char LongOperationStatus; /* Byte 414 */
- unsigned char :8; /* Byte 415 */
+ unsigned short :16; /* Bytes 414-415 */
X /* Flash ROM Information */
X unsigned char FlashType; /* Byte 416 */
X unsigned char :8; /* Byte 417 */
@@ -1234,8 +1287,7 @@
X unsigned short NumberOfConfigurationGroups; /* Bytes 474-475 */
X boolean InstallationAbortStatus:1; /* Byte 476 Bit 0 */
X boolean MaintenanceModeStatus:1; /* Byte 476 Bit 1 */
- unsigned int :6; /* Byte 476 Bits 2-7 */
- unsigned int :24; /* Bytes 477-479 */
+ unsigned int :24; /* Bytes 476-479 */
X unsigned char Reserved10[32]; /* Bytes 480-511 */
X unsigned char Reserved11[512]; /* Bytes 512-1023 */
X }
@@ -1311,7 +1363,7 @@
X DAC960_V2_Geometry_Reserved1 = 0x2,
X DAC960_V2_Geometry_Reserved2 = 0x3
X } __attribute__ ((packed)) DriveGeometry:2; /* Byte 14 Bits 5-6 */
- unsigned char :1; /* Byte 14 Bit 7 */
+ boolean SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */
X unsigned char :8; /* Byte 15 */
X /* Error Counters */
X unsigned short SoftErrors; /* Bytes 16-17 */
@@ -1323,8 +1375,8 @@
X /* Device Size Information */
X unsigned short :16; /* Bytes 32-33 */
X unsigned short DeviceBlockSizeInBytes; /* Bytes 34-35 */
- unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB; /* Bytes 36-39 */
- unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 40-43 */
+ unsigned int OriginalDeviceSize; /* Bytes 36-39 */
+ unsigned int ConfigurableDeviceSize; /* Bytes 40-43 */
X unsigned int :32; /* Bytes 44-47 */
X unsigned char LogicalDeviceName[32]; /* Bytes 48-79 */
X unsigned char SCSI_InquiryData[36]; /* Bytes 80-115 */
@@ -1350,8 +1402,12 @@
X {
X DAC960_V2_Device_Unconfigured = 0x00,
X DAC960_V2_Device_Online = 0x01,
- DAC960_V2_Device_WriteOnly = 0x03,
+ DAC960_V2_Device_Rebuild = 0x03,
+ DAC960_V2_Device_Missing = 0x04,
+ DAC960_V2_Device_Critical = 0x05,
X DAC960_V2_Device_Dead = 0x08,
+ DAC960_V2_Device_SuspectedDead = 0x0C,
+ DAC960_V2_Device_CommandedOffline = 0x10,
X DAC960_V2_Device_Standby = 0x21,
X DAC960_V2_Device_InvalidState = 0xFF
X }
@@ -1371,7 +1427,7 @@
X unsigned char LogicalUnit; /* Byte 3 */
X /* Configuration Status Bits */
X boolean PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */
- boolean :1; /* Byte 4 Bit 1 */
+ boolean PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */
X boolean PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */
X unsigned char :5; /* Byte 4 Bits 3-7 */
X /* Multiple Host/Controller Status Bits */
@@ -1407,15 +1463,15 @@
X unsigned int :32; /* Bytes 44-47 */
X unsigned short :16; /* Bytes 48-49 */
X unsigned short DeviceBlockSizeInBytes; /* Bytes 50-51 */
- unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB; /* Bytes 52-55 */
- unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 56-59 */
+ unsigned int OriginalDeviceSize; /* Bytes 52-55 */
+ unsigned int ConfigurableDeviceSize; /* Bytes 56-59 */
X unsigned int :32; /* Bytes 60-63 */
X unsigned char PhysicalDeviceName[16]; /* Bytes 64-79 */
X unsigned char Reserved1[16]; /* Bytes 80-95 */
X unsigned char Reserved2[32]; /* Bytes 96-127 */
X unsigned char SCSI_InquiryData[36]; /* Bytes 128-163 */
- unsigned char Reserved3[12]; /* Bytes 164-175 */
- unsigned char Reserved4[16]; /* Bytes 176-191 */
+ unsigned char Reserved3[20]; /* Bytes 164-183 */
+ unsigned char Reserved4[8]; /* Bytes 184-191 */
X DAC960_ByteCount64_T LastReadBlockNumber; /* Bytes 192-199 */
X DAC960_ByteCount64_T LastWrittenBlockNumber; /* Bytes 200-207 */
X DAC960_ByteCount64_T ConsistencyCheckBlockNumber; /* Bytes 208-215 */
@@ -1549,7 +1605,8 @@
X DAC960_V2_RAID_Channel = 0x03,
X DAC960_V2_Physical_Controller = 0x04,
X DAC960_V2_RAID_Controller = 0x05,
- DAC960_V2_Configuration_Group = 0x10
+ DAC960_V2_Configuration_Group = 0x10,
+ DAC960_V2_Enclosure = 0x11
X }
X __attribute__ ((packed))
X DAC960_V2_OperationDevice_T;
@@ -1630,8 +1687,7 @@
X DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */
X DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */
X DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */
- DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */
- unsigned char DataTransferPageNumber; /* Byte 7 */
+ DAC960_ByteCount32_T DataTransferSize; /* Bytes 4-7 */
X DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */
X DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */
X DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */
@@ -1645,8 +1701,7 @@
X DAC960_V2_CommandIdentifier_T CommandIdentifier; /* Bytes 0-1 */
X DAC960_V2_CommandOpcode_T CommandOpcode; /* Byte 2 */
X DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */
- DAC960_ByteCount32_T DataTransferSize:24; /* Bytes 4-6 */
- unsigned char DataTransferPageNumber; /* Byte 7 */
+ DAC960_ByteCount32_T DataTransferSize; /* Bytes 4-7 */
X DAC960_BusAddress64_T RequestSenseBusAddress; /* Bytes 8-15 */
X DAC960_V2_PhysicalDevice_T PhysicalDevice; /* Bytes 16-18 */
X DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */
@@ -1795,7 +1850,6 @@
X DataTransferMemoryAddress; /* Bytes 32-63 */
X } DeviceOperation;
X }
-__attribute__ ((packed))
X DAC960_V2_CommandMailbox_T;
X
X
@@ -2074,7 +2128,8 @@
X DAC960_LP_Controller = 2, /* AcceleRAID 352 */
X DAC960_LA_Controller = 3, /* DAC1164P */
X DAC960_PG_Controller = 4, /* DAC960PTL/PJ/PG */
- DAC960_PD_Controller = 5 /* DAC960PU/PD/PL */
+ DAC960_PD_Controller = 5, /* DAC960PU/PD/PL/P */
+ DAC960_P_Controller = 6 /* DAC960PU/PD/PL/P */
X }
X DAC960_HardwareType_T;
X
@@ -2336,6 +2391,7 @@
X unsigned short DeviceStateChannel;
X unsigned short DeviceStateTargetID;
X boolean DualModeMemoryMailboxInterface;
+ boolean BackgroundInitializationStatusSupported;
X boolean SAFTE_EnclosureManagementEnabled;
X boolean NeedLogicalDriveInformation;
X boolean NeedErrorTableInformation;
@@ -2344,6 +2400,7 @@
X boolean NeedDeviceSerialNumberInformation;
X boolean NeedRebuildProgress;
X boolean NeedConsistencyCheckProgress;
+ boolean NeedBackgroundInitializationStatus;
X boolean StartDeviceStateScan;
X boolean RebuildProgressFirst;
X boolean RebuildFlagPending;
@@ -2367,6 +2424,10 @@
X DAC960_V1_CommandStatus_T PendingRebuildStatus;
X DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
X DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
+ DAC960_V1_BackgroundInitializationStatus_T
+ BackgroundInitializationStatus;
+ DAC960_V1_BackgroundInitializationStatus_T
+ LastBackgroundInitializationStatus;
X DAC960_V1_DeviceState_T
X DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
X DAC960_V1_DeviceState_T NewDeviceState;
@@ -4143,13 +4204,46 @@
X return true;
X }
X
+static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry)
+{
+ memcpy(Enquiry + 132, Enquiry + 36, 64);
+ memset(Enquiry + 36, 0, 96);
+}
+
+static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState)
+{
+ memcpy(DeviceState + 2, DeviceState + 3, 1);
+ memcpy(DeviceState + 4, DeviceState + 5, 2);
+ memcpy(DeviceState + 6, DeviceState + 8, 4);
+}
+
+static inline
+void DAC960_PD_To_P_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
+ *CommandMailbox)
+{
+ int LogicalDriveNumber = CommandMailbox->Type5.LD.LogicalDriveNumber;
+ CommandMailbox->Bytes[3] &= 0x7;
+ CommandMailbox->Bytes[3] |= CommandMailbox->Bytes[7] << 6;
+ CommandMailbox->Bytes[7] = LogicalDriveNumber;
+}
+
+static inline
+void DAC960_P_To_PD_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
+ *CommandMailbox)
+{
+ int LogicalDriveNumber = CommandMailbox->Bytes[7];
+ CommandMailbox->Bytes[7] = CommandMailbox->Bytes[3] >> 6;
+ CommandMailbox->Bytes[3] &= 0x7;
+ CommandMailbox->Bytes[3] |= LogicalDriveNumber << 3;


+}
+
X
X /*

X Define prototypes for the forward referenced DAC960 Driver Internal Functions.
X */
X
X static void DAC960_FinalizeController(DAC960_Controller_T *);
-static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
+static int DAC960_Notifier(NotifierBlock_T *, unsigned long, void *);
X static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
X static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
X static void DAC960_RequestFunction(RequestQueue_T *);
@@ -4158,6 +4252,7 @@
X static void DAC960_LA_InterruptHandler(int, void *, Registers_T *);
X static void DAC960_PG_InterruptHandler(int, void *, Registers_T *);
X static void DAC960_PD_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_P_InterruptHandler(int, void *, Registers_T *);
X static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
X static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 12'
echo 'File patch-2.4.13 is continued in part 13'
echo "13" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:43 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part13

#!/bin/sh -x
# this is part 13 of a 53 - part archive


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

if test "$Scheck" != 13; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X static void DAC960_MonitoringTimerFunction(unsigned long);
diff -u --recursive --new-file v2.4.12/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.4.12/linux/drivers/block/acsi.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/acsi.c Mon Oct 15 13:27:42 2001


@@ -1136,7 +1136,7 @@
X

X case BLKGETSIZE: /* Return device size */
X return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects,
- (long *) arg);
+ (unsigned long *) arg);
X
X case BLKGETSIZE64: /* Return device size */
X return put_user((u64)acsi_part[MINOR(inode->i_rdev)].nr_sects << 9,
diff -u --recursive --new-file v2.4.12/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- v2.4.12/linux/drivers/block/amiflop.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/amiflop.c Mon Oct 15 13:27:41 2001
@@ -1555,7 +1555,7 @@
X return -EFAULT;
X break;
X case BLKGETSIZE:
- return put_user(unit[drive].blocks,(long *)param);
+ return put_user(unit[drive].blocks,(unsigned long *)param);
X break;
X case BLKGETSIZE64:
X return put_user((u64)unit[drive].blocks << 9, (u64 *)param);
diff -u --recursive --new-file v2.4.12/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c
--- v2.4.12/linux/drivers/block/ataflop.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/ataflop.c Mon Oct 15 13:27:42 2001
@@ -1600,7 +1600,7 @@
X dtp = UDT;
X }
X if (cmd == BLKGETSIZE)
- return put_user(dtp->blocks, (long *)param);
+ return put_user(dtp->blocks, (unsigned long *)param);
X
X memset((void *)&getprm, 0, sizeof(getprm));
X getprm.size = dtp->blocks;
diff -u --recursive --new-file v2.4.12/linux/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- v2.4.12/linux/drivers/block/blkpg.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/blkpg.c Mon Oct 15 13:27:42 2001
@@ -242,10 +242,10 @@
X /* add BLKGETSIZE64 too */
X g = get_gendisk(dev);
X if (!g)
- longval = 0;
+ ulongval = 0;
X else
- longval = g->part[MINOR(dev)].nr_sects;
- return put_user(longval, (long *) arg);
+ ulongval = g->part[MINOR(dev)].nr_sects;
+ return put_user(ulongval, (unsigned long *) arg);
X #endif
X #if 0
X case BLKRRPART: /* Re-read partition tables */
diff -u --recursive --new-file v2.4.12/linux/drivers/block/cciss.c linux/drivers/block/cciss.c
--- v2.4.12/linux/drivers/block/cciss.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/cciss.c Mon Oct 15 13:27:42 2001
@@ -401,7 +401,7 @@
X put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect, &geo->start);
X return 0;
X case BLKGETSIZE:
- put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (long*)arg);
+ put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
X return 0;
X case BLKGETSIZE64:
X put_user((u64)hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects << 9, (u64*)arg);
diff -u --recursive --new-file v2.4.12/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.4.12/linux/drivers/block/cpqarray.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/cpqarray.c Mon Oct 15 13:27:42 2001
@@ -1217,7 +1217,7 @@
X case IDAGETDRVINFO:
X return copy_to_user(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t));
X case BLKGETSIZE:
- return put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (long*)arg);
+ return put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
X case BLKGETSIZE64:
X return put_user((u64)(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
X case BLKRRPART:
diff -u --recursive --new-file v2.4.12/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.4.12/linux/drivers/block/floppy.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/floppy.c Mon Oct 15 13:27:41 2001
@@ -3496,7 +3496,7 @@
X
X case BLKGETSIZE:
X ECALL(get_floppy_geometry(drive, type, &g));
- return put_user(g->size, (long *) param);
+ return put_user(g->size, (unsigned long *) param);
X
X case BLKGETSIZE64:
X ECALL(get_floppy_geometry(drive, type, &g));
diff -u --recursive --new-file v2.4.12/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.4.12/linux/drivers/block/genhd.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/block/genhd.c Wed Oct 17 14:46:29 2001
@@ -161,9 +161,6 @@
X
X
X extern int blk_dev_init(void);
-#ifdef CONFIG_BLK_DEV_DAC960
-extern void DAC960_Initialize(void);
-#endif
X #ifdef CONFIG_FUSION_BOOT
X extern int fusion_init(void);
X #endif
@@ -181,9 +178,6 @@
X sti();
X #ifdef CONFIG_I2O
X i2o_init();
-#endif
-#ifdef CONFIG_BLK_DEV_DAC960
- DAC960_Initialize();
X #endif
X #ifdef CONFIG_FUSION_BOOT
X fusion_init();
diff -u --recursive --new-file v2.4.12/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.4.12/linux/drivers/block/ll_rw_blk.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/ll_rw_blk.c Sat Oct 13 10:30:30 2001
@@ -149,8 +149,8 @@
X return 0;
X
X do {
- rq = list_entry(head->next, struct request, table);
- list_del(&rq->table);
+ rq = list_entry(head->next, struct request, queue);
+ list_del(&rq->queue);
X kmem_cache_free(request_cachep, rq);
X i++;
X } while (!list_empty(head));
@@ -349,7 +349,7 @@
X }
X memset(rq, 0, sizeof(struct request));
X rq->rq_status = RQ_INACTIVE;
- list_add(&rq->table, &q->request_freelist[i & 1]);
+ list_add(&rq->queue, &q->request_freelist[i & 1]);
X }
X
X init_waitqueue_head(&q->wait_for_request);
@@ -415,7 +415,7 @@
X q->head_active = 1;
X }
X
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, table);
+#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
X /*
X * Get a free request. io_request_lock must be held and interrupts
X * disabled on the way in.


@@ -426,7 +426,7 @@
X

X if (!list_empty(&q->request_freelist[rw])) {
X rq = blkdev_free_rq(&q->request_freelist[rw]);
- list_del(&rq->table);
+ list_del(&rq->queue);
X rq->rq_status = RQ_ACTIVE;
X rq->special = NULL;
X rq->q = q;
@@ -570,7 +570,7 @@
X /*
X * Add to pending free list and batch wakeups
X */
- list_add(&req->table, &q->pending_freelist[rw]);
+ list_add(&req->queue, &q->pending_freelist[rw]);
X
X if (++q->pending_free[rw] >= batch_requests) {
X int wake_up = q->pending_free[rw];
diff -u --recursive --new-file v2.4.12/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.4.12/linux/drivers/block/loop.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/block/loop.c Mon Oct 15 18:53:51 2001
@@ -151,7 +151,7 @@
X
X #define MAX_DISK_SIZE 1024*1024*1024
X
-static int compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry, kdev_t lodev)
+static unsigned long compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry, kdev_t lodev)
X {
X if (S_ISREG(lo_dentry->d_inode->i_mode))
X return (lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS;
@@ -865,7 +865,7 @@
X err = -ENXIO;
X break;
X }
- err = put_user(loop_sizes[lo->lo_number] << 1, (long *) arg);
+ err = put_user((unsigned long)loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
X break;
X case BLKGETSIZE64:
X if (lo->lo_state != Lo_bound) {
diff -u --recursive --new-file v2.4.12/linux/drivers/block/nbd.c linux/drivers/block/nbd.c
--- v2.4.12/linux/drivers/block/nbd.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/nbd.c Mon Oct 15 13:27:42 2001
@@ -445,7 +445,7 @@
X return 0;
X #endif
X case BLKGETSIZE:
- return put_user(nbd_bytesizes[dev] >> 9, (long *) arg);
+ return put_user(nbd_bytesizes[dev] >> 9, (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)nbd_bytesizes[dev], (u64 *) arg);
X }
@@ -542,4 +542,6 @@
X module_exit(nbd_cleanup);
X
X MODULE_DESCRIPTION("Network Block Device");
+MODULE_LICENSE("GPL");
+
X
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/aten.c linux/drivers/block/paride/aten.c
--- v2.4.12/linux/drivers/block/paride/aten.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/aten.c Thu Oct 11 09:04:57 2001
@@ -171,3 +171,4 @@
X #endif
X
X /* end of aten.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/bpck.c linux/drivers/block/paride/bpck.c
--- v2.4.12/linux/drivers/block/paride/bpck.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/bpck.c Thu Oct 11 09:04:57 2001
@@ -482,3 +482,4 @@
X #endif
X
X /* end of bpck.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/comm.c linux/drivers/block/paride/comm.c
--- v2.4.12/linux/drivers/block/paride/comm.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/comm.c Thu Oct 11 09:04:57 2001
@@ -227,3 +227,4 @@
X #endif
X
X /* end of comm.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/dstr.c linux/drivers/block/paride/dstr.c
--- v2.4.12/linux/drivers/block/paride/dstr.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/dstr.c Thu Oct 11 09:04:57 2001
@@ -242,3 +242,4 @@
X #endif
X
X /* end of dstr.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/epat.c linux/drivers/block/paride/epat.c
--- v2.4.12/linux/drivers/block/paride/epat.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/epat.c Thu Oct 11 09:04:57 2001
@@ -320,3 +320,4 @@
X #endif
X
X /* end of epat.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/epia.c linux/drivers/block/paride/epia.c
--- v2.4.12/linux/drivers/block/paride/epia.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/epia.c Thu Oct 11 09:04:57 2001


@@ -325,3 +325,4 @@
X

X /* end of epia.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/fit2.c linux/drivers/block/paride/fit2.c
--- v2.4.12/linux/drivers/block/paride/fit2.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/fit2.c Thu Oct 11 09:04:57 2001
@@ -160,3 +160,4 @@
X #endif
X
X /* end of fit2.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/fit3.c linux/drivers/block/paride/fit3.c
--- v2.4.12/linux/drivers/block/paride/fit3.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/fit3.c Thu Oct 11 09:04:57 2001
@@ -220,3 +220,4 @@
X #endif
X
X /* end of fit3.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/friq.c linux/drivers/block/paride/friq.c
--- v2.4.12/linux/drivers/block/paride/friq.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/friq.c Thu Oct 11 09:04:57 2001
@@ -281,3 +281,4 @@
X #endif
X
X /* end of friq.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/frpw.c linux/drivers/block/paride/frpw.c
--- v2.4.12/linux/drivers/block/paride/frpw.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/frpw.c Thu Oct 11 09:04:57 2001
@@ -322,3 +322,4 @@
X #endif
X
X /* end of frpw.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/kbic.c linux/drivers/block/paride/kbic.c
--- v2.4.12/linux/drivers/block/paride/kbic.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/kbic.c Thu Oct 11 09:04:57 2001
@@ -310,3 +310,4 @@
X #endif
X
X /* end of kbic.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/ktti.c linux/drivers/block/paride/ktti.c
--- v2.4.12/linux/drivers/block/paride/ktti.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/ktti.c Thu Oct 11 09:04:57 2001
@@ -137,3 +137,4 @@
X #endif
X
X /* end of ktti.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/on20.c linux/drivers/block/paride/on20.c
--- v2.4.12/linux/drivers/block/paride/on20.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/on20.c Thu Oct 11 09:04:57 2001
@@ -162,3 +162,4 @@
X #endif
X
X /* end of on20.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/on26.c linux/drivers/block/paride/on26.c
--- v2.4.12/linux/drivers/block/paride/on26.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/on26.c Thu Oct 11 09:04:57 2001
@@ -328,3 +328,4 @@
X
X /* end of on26.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- v2.4.12/linux/drivers/block/paride/paride.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/block/paride/paride.c Thu Oct 11 09:04:57 2001
@@ -547,3 +547,4 @@
X #endif
X
X /* end of paride.c */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
--- v2.4.12/linux/drivers/block/paride/pcd.c Sun Feb 4 10:05:29 2001
+++ linux/drivers/block/paride/pcd.c Thu Oct 11 09:04:57 2001
@@ -948,3 +948,4 @@
X
X /* end of pcd.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.4.12/linux/drivers/block/paride/pd.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/pd.c Mon Oct 15 13:27:41 2001
@@ -478,9 +478,9 @@
X return 0;
X case BLKGETSIZE:
X if (!arg) return -EINVAL;
- err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
+ err = verify_area(VERIFY_WRITE,(unsigned long *) arg,sizeof(unsigned long));
X if (err) return (err);
- put_user(pd_hd[dev].nr_sects,(long *) arg);
+ put_user(pd_hd[dev].nr_sects,(unsigned long *) arg);
X return (0);
X case BLKGETSIZE64:
X return put_user((u64)pd_hd[dev].nr_sects << 9, (u64 *)arg);
@@ -586,8 +586,7 @@
X }
X
X void cleanup_module(void)
-
-{ struct gendisk **gdp;
+{
X int unit;
X
X devfs_unregister_blkdev(MAJOR_NR,name);


@@ -1069,3 +1068,4 @@
X

X /* end of pd.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- v2.4.12/linux/drivers/block/paride/pf.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/pf.c Thu Oct 11 09:04:57 2001
@@ -1111,3 +1111,4 @@
X
X /* end of pf.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
--- v2.4.12/linux/drivers/block/paride/pg.c Fri Feb 9 11:30:22 2001
+++ linux/drivers/block/paride/pg.c Thu Oct 11 09:04:57 2001


@@ -694,3 +694,4 @@
X

X /* end of pg.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/ppc6lnx.c linux/drivers/block/paride/ppc6lnx.c
--- v2.4.12/linux/drivers/block/paride/ppc6lnx.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/ppc6lnx.c Thu Oct 11 09:04:57 2001
@@ -724,3 +724,4 @@
X
X //***************************************************************************
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- v2.4.12/linux/drivers/block/paride/pt.c Tue Jul 3 17:08:19 2001
+++ linux/drivers/block/paride/pt.c Thu Oct 11 09:04:57 2001
@@ -964,3 +964,4 @@
X
X /* end of pt.c */
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.4.12/linux/drivers/block/ps2esdi.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/ps2esdi.c Mon Oct 15 13:27:42 2001
@@ -1107,9 +1107,9 @@
X
X case BLKGETSIZE:
X if (arg) {
- if ((err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long))))
+ if ((err = verify_area(VERIFY_WRITE, (unsigned long *) arg, sizeof(unsigned long))))
X return (err);
- put_user(ps2esdi[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
+ put_user(ps2esdi[MINOR(inode->i_rdev)].nr_sects, (unsigned long *) arg);
X
X return (0);
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.4.12/linux/drivers/block/rd.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/block/rd.c Mon Oct 15 13:27:41 2001
@@ -384,7 +384,7 @@
X case BLKGETSIZE: /* Return device size */
X if (!arg)
X break;
- error = put_user(rd_kbsize[minor] << 1, (long *) arg);
+ error = put_user(rd_kbsize[minor] << 1, (unsigned long *) arg);
X break;
X case BLKGETSIZE64:
X error = put_user((u64)rd_kbsize[minor]<<10, (u64*)arg);
diff -u --recursive --new-file v2.4.12/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.4.12/linux/drivers/block/xd.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/xd.c Mon Oct 15 13:27:41 2001


@@ -336,7 +336,7 @@
X }

X case BLKGETSIZE:
X if (!arg) return -EINVAL;
- return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
+ return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)xd_struct[MINOR(inode->i_rdev)].nr_sects << 9, (u64 *)arg);
X case HDIO_SET_DMA:
diff -u --recursive --new-file v2.4.12/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.4.12/linux/drivers/cdrom/cdrom.c Mon Aug 27 12:41:40 2001
+++ linux/drivers/cdrom/cdrom.c Sun Oct 14 08:53:25 2001
@@ -2659,3 +2659,4 @@
X
X module_init(cdrom_init);
X module_exit(cdrom_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.4.12/linux/drivers/char/Config.in Tue Oct 9 17:06:51 2001
+++ linux/drivers/char/Config.in Mon Oct 15 13:31:51 2001
@@ -155,6 +155,7 @@
X tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
X tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
X tristate ' Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+ tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
X tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
X tristate ' W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
X tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD
@@ -191,7 +192,7 @@
X tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
X tristate 'Siemens R3964 line discipline' CONFIG_R3964
X tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" ]; then
X dep_tristate 'Sony Vaio Programmable I/O Control Device support' CONFIG_SONYPI $CONFIG_PCI
X fi
X
@@ -219,4 +220,7 @@


X if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
X source drivers/char/pcmcia/Config.in

X fi
+
+tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE
+
X endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.12/linux/drivers/char/Makefile Tue Oct 9 17:06:51 2001
+++ linux/drivers/char/Makefile Mon Oct 15 13:36:48 2001
@@ -220,6 +220,7 @@
X obj-$(CONFIG_PCWATCHDOG) += pcwd.o
X obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
X obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
+obj-$(CONFIG_IB700_WDT) += ib700wdt.o
X obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
X obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
X obj-$(CONFIG_WDT) += wdt.o
@@ -228,8 +229,13 @@
X obj-$(CONFIG_977_WATCHDOG) += wdt977.o
X obj-$(CONFIG_I810_TCO) += i810-tco.o
X obj-$(CONFIG_MACHZ_WDT) += machzwd.o
+obj-$(CONFIG_SH_WDT) += shwdt.o
X obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
X
+subdir-$(CONFIG_MWAVE) += mwave
+ifeq ($(CONFIG_MWAVE),y)
+ obj-y += mwave/mwave.o
+endif
X
X include $(TOPDIR)/Rules.make
X
diff -u --recursive --new-file v2.4.12/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c
--- v2.4.12/linux/drivers/char/adbmouse.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/adbmouse.c Thu Oct 11 09:07:00 2001
@@ -206,4 +206,4 @@
X module_init(adb_mouse_init);
X module_exit(adb_mouse_cleanup);
X
-MODULE_LICENSE("GPL"):
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.4.12/linux/drivers/char/console.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/console.c Mon Oct 15 14:00:43 2001
@@ -399,20 +399,28 @@
X else {
X u16 *q = p;
X int cnt = count;
+ u16 a;
X
X if (!can_do_color) {
- while (cnt--) *q++ ^= 0x0800;
+ while (cnt--) {
+ a = scr_readw(q);
+ a ^= 0x0800;
+ scr_writew(a, q);
+ q++;
+ }
X } else if (hi_font_mask == 0x100) {
X while (cnt--) {
- u16 a = *q;
+ a = scr_readw(q);
X a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
- *q++ = a;
+ scr_writew(a, q);
+ q++;
X }
X } else {
X while (cnt--) {
- u16 a = *q;
+ a = scr_readw(q);
X a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
- *q++ = a;
+ scr_writew(a, q);
+ q++;
X }
X }
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/char/drm/drm_drv.h linux/drivers/char/drm/drm_drv.h
--- v2.4.12/linux/drivers/char/drm/drm_drv.h Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/drm/drm_drv.h Sun Oct 21 10:40:36 2001
@@ -1047,6 +1047,25 @@
X
X atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
X
+#if __HAVE_KERNEL_CTX_SWITCH
+ /* We no longer really hold it, but if we are the next
+ * agent to request it then we should just be able to
+ * take it immediately and not eat the ioctl.
+ */
+ dev->lock.pid = 0;
+ {
+ __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
+ unsigned int old, new, prev, ctx;
+
+ ctx = lock.context;
+ do {
+ old = *plock;
+ new = ctx;
+ prev = cmpxchg(plock, old, new);
+ } while (prev != old);
+ }
+ wake_up_interruptible(&dev->lock.lock_queue);
+#else
X DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
X DRM_KERNEL_CONTEXT );
X #if __HAVE_DMA_SCHEDULE
@@ -1061,6 +1080,7 @@
X DRM_ERROR( "\n" );
X }
X }
+#endif /* !__HAVE_KERNEL_CTX_SWITCH */
X
X unblock_all_signals();
X return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/char/drm/drm_proc.h linux/drivers/char/drm/drm_proc.h
--- v2.4.12/linux/drivers/char/drm/drm_proc.h Thu Oct 18 13:48:13 2001
+++ linux/drivers/char/drm/drm_proc.h Tue Oct 23 22:00:11 2001
@@ -186,7 +186,7 @@
X DRM_PROC_PRINT("slot offset size type flags "
X "address mtrr\n\n");
X i = 0;
- list_for_each(list, &dev->maplist->head) {
+ if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
X r_list = (drm_map_list_t *)list;
X map = r_list->map;
X if(!map) continue;
diff -u --recursive --new-file v2.4.12/linux/drivers/char/drm/drm_vm.h linux/drivers/char/drm/drm_vm.h
--- v2.4.12/linux/drivers/char/drm/drm_vm.h Thu Oct 18 13:48:13 2001
+++ linux/drivers/char/drm/drm_vm.h Tue Oct 23 22:00:11 2001
@@ -175,7 +175,7 @@
X page = pte_page(*pte);
X get_page(page);
X
- DRM_DEBUG("0x%08lx => 0x%08x\n", address, page_to_bus(page));
+ DRM_DEBUG("shm_nopage 0x%lx\n", address);
X #if LINUX_VERSION_CODE < 0x020317
X return page_address(page);
X #else
@@ -299,8 +299,7 @@
X
X get_page(page);
X
- DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr,
- page_to_bus(page));
+ DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
X #if LINUX_VERSION_CODE < 0x020317
X return page_address(page);
X #else
@@ -532,10 +531,17 @@
X vma->vm_flags |= VM_IO; /* not in core dump */
X }
X offset = DRIVER_GET_REG_OFS();
+#ifdef __sparc__
+ if (io_remap_page_range(vma->vm_start,
+ VM_OFFSET(vma) + offset,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot, 0))
+#else
X if (remap_page_range(vma->vm_start,
X VM_OFFSET(vma) + offset,
X vma->vm_end - vma->vm_start,
X vma->vm_page_prot))
+#endif
X return -EAGAIN;
X DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
X " offset = 0x%lx\n",
diff -u --recursive --new-file v2.4.12/linux/drivers/char/drm/ffb_drv.c linux/drivers/char/drm/ffb_drv.c
--- v2.4.12/linux/drivers/char/drm/ffb_drv.c Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/ffb_drv.c Sun Oct 21 10:40:36 2001
@@ -1,4 +1,4 @@
-/* $Id: ffb_drv.c,v 1.15 2001/08/09 17:47:51 davem Exp $
+/* $Id: ffb_drv.c,v 1.16 2001/10/18 16:00:24 davem Exp $
X * ffb_drv.c: Creator/Creator3D direct rendering driver.
X *
X * Copyright (C) 2000 David S. Miller (da...@redhat.com)
@@ -45,16 +45,16 @@
X #define DRIVER_PRESETUP() do { \
X int _ret; \
X _ret = ffb_presetup(dev); \
- if(_ret != 0) return _ret; \
+ if (_ret != 0) return _ret; \
X } while(0)
X
X /* Free private structure */
X #define DRIVER_PRETAKEDOWN() do { \
- if(dev->dev_private) kfree(dev->dev_private); \
+ if (dev->dev_private) kfree(dev->dev_private); \
X } while(0)
X
X #define DRIVER_POSTCLEANUP() do { \
- if(ffb_position != NULL) kfree(ffb_position); \
+ if (ffb_position != NULL) kfree(ffb_position); \
X } while(0)
X
X /* We have to free up the rogue hw context state holding error or
@@ -66,7 +66,9 @@
X int idx; \
X \
X idx = context - 1; \
- if (fpriv && fpriv->hw_state[idx] != NULL) { \
+ if (fpriv && \
+ context != DRM_KERNEL_CONTEXT && \
+ fpriv->hw_state[idx] != NULL) { \
X kfree(fpriv->hw_state[idx]); \
X fpriv->hw_state[idx] = NULL; \
X } \
diff -u --recursive --new-file v2.4.12/linux/drivers/char/epca.c linux/drivers/char/epca.c
--- v2.4.12/linux/drivers/char/epca.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/epca.c Fri Oct 12 13:48:42 2001
@@ -1572,7 +1572,8 @@
X cli();
X
X if ((tty_unregister_driver(&pc_driver)) ||
- (tty_unregister_driver(&pc_callout)))
+ (tty_unregister_driver(&pc_callout)) ||
+ (tty_unregister_driver(&pc_info)))
X {
X printk(KERN_WARNING "<Error> - DIGI : cleanup_module failed to un-register tty driver\n");
X restore_flags(flags);
diff -u --recursive --new-file v2.4.12/linux/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c
--- v2.4.12/linux/drivers/char/i810_rng.c Thu Apr 12 12:15:25 2001
+++ linux/drivers/char/i810_rng.c Thu Oct 11 09:14:32 2001
@@ -342,6 +342,7 @@
X
X MODULE_AUTHOR("Jeff Garzik, Philipp Rumpf, Matt Sottek");
X MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
X
X
X /*
diff -u --recursive --new-file v2.4.12/linux/drivers/char/ib700wdt.c linux/drivers/char/ib700wdt.c
--- v2.4.12/linux/drivers/char/ib700wdt.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ib700wdt.c Thu Oct 11 09:07:00 2001
@@ -0,0 +1,272 @@
+/*
+ * IB700 Single Board Computer WDT driver for Linux 2.4.x
+ *
+ * (c) Copyright 2001 Charles Howes <cho...@vsol.net>
+ *
+ * Based on advantechwdt.c which is based on acquirewdt.c which
+ * is based on wdt.c.
+ *
+ * (c) Copyright 2000-2001 Marek Michalkiewicz <mar...@linux.org.pl>
+ *
+ * Based on acquirewdt.c which is based on wdt.c.
+ * Original copyright messages:
+ *
+ * (c) Copyright 1996 Alan Cox <al...@redhat.com>, All Rights Reserved.
+ * http://www.redhat.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.
+ *
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 1995 Alan Cox <al...@redhat.com>
+ *


+ */
+
+#include <linux/config.h>
+#include <linux/module.h>

+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+
+static int ibwdt_is_open;
+static spinlock_t ibwdt_lock;
+
+/*
+ *
+ * Watchdog Timer Configuration
+ *
+ * The function of the watchdog timer is to reset the system
+ * automatically and is defined at I/O port 0443H. To enable the
+ * watchdog timer and allow the system to reset, write I/O port 0443H.
+ * To disable the timer, write I/O port 0441H for the system to stop the
+ * watchdog function. The timer has a tolerance of 20% for its
+ * intervals.
+ *
+ * The following describes how the timer should be programmed.
+ *
+ * Enabling Watchdog:
+ * MOV AX,000FH (Choose the values from 0 to F)
+ * MOV DX,0443H
+ * OUT DX,AX
+ *
+ * Disabling Watchdog:
+ * MOV AX,000FH (Any value is fine.)
+ * MOV DX,0441H
+ * OUT DX,AX
+ *
+ * Watchdog timer control table:
+ * Level Value Time/sec | Level Value Time/sec
+ * 1 F 0 | 9 7 16
+ * 2 E 2 | 10 6 18
+ * 3 D 4 | 11 5 20
+ * 4 C 6 | 12 4 22
+ * 5 B 8 | 13 3 24
+ * 6 A 10 | 14 2 26
+ * 7 9 12 | 15 1 28
+ * 8 8 14 | 16 0 30
+ *
+ */
+
+#define WDT_STOP 0x441
+#define WDT_START 0x443
+
+#define WD_TIMO 0 /* 30 seconds +/- 20%, from table */
+
+/*
+ * Kernel methods.


+ */
+
+static void

+ibwdt_ping(void)
+{
+ /* Write a watchdog value */
+ outb_p(WD_TIMO, WDT_START);
+}
+
+static ssize_t
+ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ if (count) {
+ ibwdt_ping();
+ return 1;


+ }
+ return 0;
+}
+

+static ssize_t
+ibwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static int
+ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ static struct watchdog_info ident = {
+ WDIOF_KEEPALIVEPING, 1, "IB700 WDT"
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+ return -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ if (copy_to_user((int *)arg, &ibwdt_is_open, sizeof(int)))
+ return -EFAULT;
+ break;
+
+ case WDIOC_KEEPALIVE:
+ ibwdt_ping();


+ break;
+
+ default:

+ return -ENOTTY;


+ }
+ return 0;
+}
+
+static int

+ibwdt_open(struct inode *inode, struct file *file)
+{
+ switch (MINOR(inode->i_rdev)) {
+ case WATCHDOG_MINOR:
+ spin_lock(&ibwdt_lock);
+ if (ibwdt_is_open) {
+ spin_unlock(&ibwdt_lock);
+ return -EBUSY;
+ }
+ /*
+ * Activate
+ */
+
+ ibwdt_is_open = 1;
+ ibwdt_ping();
+ spin_unlock(&ibwdt_lock);
+ return 0;
+ default:


+ return -ENODEV;
+ }
+}
+

+static int
+ibwdt_close(struct inode *inode, struct file *file)
+{
+ lock_kernel();
+ if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
+ spin_lock(&ibwdt_lock);
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ outb_p(WD_TIMO, WDT_STOP);
+#endif
+ ibwdt_is_open = 0;
+ spin_unlock(&ibwdt_lock);
+ }
+ unlock_kernel();


+ return 0;
+}
+

+/*
+ * Notifier for system down


+ */
+
+static int

+ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT) {
+ /* Turn the WDT off */
+ outb_p(WD_TIMO, WDT_STOP);
+ }
+ return NOTIFY_DONE;
+}
+
+/*
+ * Kernel Interfaces
+ */
+
+static struct file_operations ibwdt_fops = {
+ owner: THIS_MODULE,
+ read: ibwdt_read,
+ write: ibwdt_write,
+ ioctl: ibwdt_ioctl,
+ open: ibwdt_open,
+ release: ibwdt_close,
+};
+
+static struct miscdevice ibwdt_miscdev = {
+ WATCHDOG_MINOR,
+ "watchdog",
+ &ibwdt_fops
+};
+
+/*
+ * The WDT needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block ibwdt_notifier = {
+ ibwdt_notify_sys,
+ NULL,
+ 0
+};
+
+static int __init
+ibwdt_init(void)
+{
+ printk("WDT driver for IB700 single board computer initialising.\n");
+
+ spin_lock_init(&ibwdt_lock);
+ misc_register(&ibwdt_miscdev);
+#if WDT_START != WDT_STOP
+ request_region(WDT_STOP, 1, "IB700 WDT");
+#endif
+ request_region(WDT_START, 1, "IB700 WDT");
+ register_reboot_notifier(&ibwdt_notifier);


+ return 0;
+}
+

+static void __exit
+ibwdt_exit(void)
+{
+ misc_deregister(&ibwdt_miscdev);
+ unregister_reboot_notifier(&ibwdt_notifier);
+#if WDT_START != WDT_STOP
+ release_region(WDT_STOP,1);
+#endif
+ release_region(WDT_START,1);
+}
+
+module_init(ibwdt_init);
+module_exit(ibwdt_exit);
+
+MODULE_AUTHOR("Charles Howes <cho...@vsol.net>");
+MODULE_DESCRIPTION("IB700 SBC watchdog driver");
+MODULE_LICENSE("GPL");
+
+/* end of ib700wdt.c */
diff -u --recursive --new-file v2.4.12/linux/drivers/char/ip2main.c linux/drivers/char/ip2main.c
--- v2.4.12/linux/drivers/char/ip2main.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/ip2main.c Thu Oct 11 09:14:32 2001
@@ -3458,3 +3458,4 @@
X }
X
X
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
--- v2.4.12/linux/drivers/char/istallion.c Wed Jul 25 17:10:19 2001
+++ linux/drivers/char/istallion.c Thu Oct 11 09:14:32 2001
@@ -386,6 +386,8 @@
X */
X MODULE_AUTHOR("Greg Ungerer");
X MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
+MODULE_LICENSE("GPL");
+
X
X MODULE_PARM(board0, "1-3s");
X MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
diff -u --recursive --new-file v2.4.12/linux/drivers/char/joystick/analog.c linux/drivers/char/joystick/analog.c
--- v2.4.12/linux/drivers/char/joystick/analog.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/joystick/analog.c Thu Oct 18 09:08:16 2001
@@ -138,7 +138,7 @@
X
X #ifdef __i386__
X #define TSC_PRESENT (test_bit(X86_FEATURE_TSC, &boot_cpu_data.x86_capability))
-#define GET_TIME(x) do { if (TSC_PRESENT) rdtscl(x); else outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } while (0)
+#define GET_TIME(x) do { if (TSC_PRESENT) rdtscl(x); else { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } } while (0)
X #define DELTA(x,y) (TSC_PRESENT?((y)-(x)):((x)-(y)+((x)<(y)?1193180L/HZ:0)))
X #define TIME_NAME (TSC_PRESENT?"TSC":"PIT")
X #elif __x86_64__
@@ -499,7 +499,9 @@
X else
X printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
X port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
- port->speed > 10000 ? "M" : "k", (port->loop * 1000000) / port->speed);
+ port->speed > 10000 ? "M" : "k",
+ port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
+ : (port->loop * 1000000) / port->speed);
X }
X
X /*
diff -u --recursive --new-file v2.4.12/linux/drivers/char/mwave/mwavedd.c linux/drivers/char/mwave/mwavedd.c
--- v2.4.12/linux/drivers/char/mwave/mwavedd.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/char/mwave/mwavedd.c Thu Oct 11 09:14:32 2001
@@ -71,6 +71,10 @@
X #define __exit
X #endif
X
+MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
+MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
+MODULE_LICENSE("GPL");
+
X #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
X static int mwave_get_info(char *buf, char **start, off_t offset, int len);
X #else
diff -u --recursive --new-file v2.4.12/linux/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- v2.4.12/linux/drivers/char/nwflash.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/nwflash.c Fri Oct 12 13:48:42 2001
@@ -59,6 +59,7 @@
X static int gbWriteBase64Enable;
X static volatile unsigned char *FLASH_BASE;
X static int gbFlashSize = KFLASH_SIZE;
+static DECLARE_MUTEX(nwflash_sem);
X
X extern spinlock_t gpio_lock;
X

@@ -132,7 +133,6 @@
X

X static ssize_t flash_read(struct file *file, char *buf, size_t size, loff_t * ppos)
X {
- struct inode *inode = file->f_dentry->d_inode;
X unsigned long p = *ppos;
X unsigned int count = size;
X int ret = 0;
@@ -151,7 +151,7 @@
X /*
X * We now lock against reads and writes. --rmk
X */
- if (down_interruptible(&inode->i_sem))
+ if (down_interruptible(&nwflash_sem))
X return -ERESTARTSYS;
X
X ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count);
@@ -159,14 +159,13 @@
X ret = count;
X *ppos += count;
X }
- up(&inode->i_sem);
+ up(&nwflash_sem);
X }
X return ret;
X }
X
X static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff_t * ppos)
X {
- struct inode *inode = file->f_dentry->d_inode;
X unsigned long p = *ppos;
X unsigned int count = size;
X int written;
@@ -198,7 +197,7 @@
X /*
X * We now lock against reads and writes. --rmk
X */
- if (down_interruptible(&inode->i_sem))
+ if (down_interruptible(&nwflash_sem))
X return -ERESTARTSYS;
X
X written = 0;
@@ -286,7 +285,7 @@
X */
X leds_event(led_release);
X
- up(&inode->i_sem);
+ up(&nwflash_sem);
X
X return written;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.4.12/linux/drivers/char/random.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/random.c Sun Oct 21 10:19:36 2001
@@ -164,25 +164,32 @@
X * sequence:
X *
X * echo "Initializing random number generator..."
- * random_seed=/var/run/random-seed
+ * random_seed=/var/run/random-seed
X * # Carry a random seed from start-up to start-up
- * # Load and then save 512 bytes, which is the size of the entropy pool
- * if [ -f $random_seed ]; then
+ * # Load and then save the whole entropy pool
+ * if [ -f $random_seed ]; then
X * cat $random_seed >/dev/urandom
- * fi
- * dd if=/dev/urandom of=$random_seed count=1
- * chmod 600 $random_seed
+ * else
+ * touch $random_seed
+ * fi
+ * chmod 600 $random_seed
+ * poolfile=/proc/sys/kernel/random/poolsize
+ * [ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512
+ * dd if=/dev/urandom of=$random_seed count=1 bs=bytes
X *
X * and the following lines in an appropriate script which is run as
X * the system is shutdown:
- *
+ *
X * # Carry a random seed from shut-down to start-up
- * # Save 512 bytes, which is the size of the entropy pool
+ * # Save the whole entropy pool
X * echo "Saving random seed..."
- * random_seed=/var/run/random-seed
- * dd if=/dev/urandom of=$random_seed count=1
- * chmod 600 $random_seed
- *
+ * random_seed=/var/run/random-seed
+ * touch $random_seed
+ * chmod 600 $random_seed
+ * poolfile=/proc/sys/kernel/random/poolsize
+ * [ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512
+ * dd if=/dev/urandom of=$random_seed count=1 bs=bytes
+ *
X * For example, on most modern systems using the System V init
X * scripts, such code fragments would be found in
X * /etc/rc.d/init.d/random. On older Linux systems, the correct script
@@ -272,8 +279,8 @@
X static int random_write_wakeup_thresh = 128;
X
X /*
- * A pool of size POOLWORDS is stirred with a primitive polynomial
- * of degree POOLWORDS over GF(2). The taps for various sizes are
+ * A pool of size .poolwords is stirred with a primitive polynomial
+ * of degree .poolwords over GF(2). The taps for various sizes are
X * defined below. They are chosen to be evenly spaced (minimum RMS
X * distance from evenly spaced; the numbers in the comments are a
X * scaled squared error sum) except for the last tap, which is 1 to
@@ -284,19 +291,17 @@
X int tap1, tap2, tap3, tap4, tap5;
X } poolinfo_table[] = {
X /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
- { 2048, 1638, 1231, 819, 411, 1 },
+ { 2048, 1638, 1231, 819, 411, 1 },
X
X /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
- { 1024, 817, 615, 412, 204, 1 },
-
+ { 1024, 817, 615, 412, 204, 1 },
X #if 0 /* Alternate polynomial */
X /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
X { 1024, 819, 616, 410, 207, 2 },
X #endif
-
+
X /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
X { 512, 411, 308, 208, 104, 1 },
-
X #if 0 /* Alternates */
X /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
X { 512, 409, 307, 206, 102, 2 },
@@ -306,10 +311,9 @@
X
X /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
X { 256, 205, 155, 101, 52, 1 },
-
+
X /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
X { 128, 103, 76, 51, 25, 1 },
-
X #if 0 /* Alternate polynomial */
X /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
X { 128, 103, 78, 51, 27, 2 },
@@ -321,9 +325,12 @@
X /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
X { 32, 26, 20, 14, 7, 1 },
X

- { 0, 0, 0, 0, 0, 0 },

-};
-
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+#define POOLBITS poolwords*32
+#define POOLBYTES poolwords*4
+
X /*
X * For the purposes of better mixing, we use the CRC-32 polynomial as
X * well to make a twisted Generalized Feedback Shift Reigster
@@ -461,6 +468,12 @@
X }
X #endif
X
+#if 0
+#define DEBUG_ENT(fmt, arg...) printk(KERN_DEBUG "random: " fmt, ## arg)
+#else
+#define DEBUG_ENT(fmt, arg...) do {} while (0)
+#endif
+
X /**********************************************************************
X *
X * OS independent entropy store. Here are the functions which handle
@@ -480,7 +493,7 @@
X /*
X * Initialize the entropy store. The input argument is the size of
X * the random pool.
- *
+ *
X * Returns an negative error if there is a problem.
X */
X static int create_entropy_store(int size, struct entropy_store **ret_bucket)
@@ -507,12 +520,12 @@
X memset (r, 0, sizeof(struct entropy_store));
X r->poolinfo = *p;
X
- r->pool = kmalloc(poolwords*4, GFP_KERNEL);
+ r->pool = kmalloc(POOLBYTES, GFP_KERNEL);
X if (!r->pool) {
X kfree(r);
X return -ENOMEM;
X }
- memset(r->pool, 0, poolwords*4);
+ memset(r->pool, 0, POOLBYTES);
X *ret_bucket = r;
X return 0;
X }
@@ -524,7 +537,7 @@
X r->entropy_count = 0;
X r->input_rotate = 0;
X r->extract_count = 0;
- memset(r->pool, 0, r->poolinfo.poolwords*4);
+ memset(r->pool, 0, r->poolinfo.POOLBYTES);
X }
X
X static void free_entropy_store(struct entropy_store *r)
@@ -545,18 +558,19 @@
X * the entropy is concentrated in the low-order bits.
X */
X static void add_entropy_words(struct entropy_store *r, const __u32 *in,
- int num)
+ int nwords)
X {
X static __u32 const twist_table[8] = {
X 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
X 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
X unsigned i;
X int new_rotate;
+ int wordmask = r->poolinfo.poolwords - 1;
X __u32 w;
X
- while (num--) {
+ while (nwords--) {
X w = rotate_left(r->input_rotate, *in);
- i = r->add_ptr = (r->add_ptr - 1) & (r->poolinfo.poolwords-1);
+ i = r->add_ptr = (r->add_ptr - 1) & wordmask;
X /*
X * Normally, we add 7 bits of rotation to the pool.
X * At the beginning of the pool, add an extra 7 bits
@@ -569,11 +583,11 @@
X r->input_rotate = new_rotate & 31;
X
X /* XOR in the various taps */
- w ^= r->pool[(i+r->poolinfo.tap1)&(r->poolinfo.poolwords-1)];
- w ^= r->pool[(i+r->poolinfo.tap2)&(r->poolinfo.poolwords-1)];
- w ^= r->pool[(i+r->poolinfo.tap3)&(r->poolinfo.poolwords-1)];
- w ^= r->pool[(i+r->poolinfo.tap4)&(r->poolinfo.poolwords-1)];
- w ^= r->pool[(i+r->poolinfo.tap5)&(r->poolinfo.poolwords-1)];
+ w ^= r->pool[(i + r->poolinfo.tap1) & wordmask];
+ w ^= r->pool[(i + r->poolinfo.tap2) & wordmask];
+ w ^= r->pool[(i + r->poolinfo.tap3) & wordmask];
+ w ^= r->pool[(i + r->poolinfo.tap4) & wordmask];
+ w ^= r->pool[(i + r->poolinfo.tap5) & wordmask];
X w ^= r->pool[i];
X r->pool[i] = (w >> 3) ^ twist_table[w & 7];
X }
@@ -582,16 +596,22 @@
X /*
X * Credit (or debit) the entropy store with n bits of entropy
X */
-static void credit_entropy_store(struct entropy_store *r, int num)
+static void credit_entropy_store(struct entropy_store *r, int nbits)
X {
- int max_entropy = r->poolinfo.poolwords*32;
-
- if (r->entropy_count + num < 0)
+ if (r->entropy_count + nbits < 0) {
+ DEBUG_ENT("negative entropy/overflow (%d+%d)\n",
+ r->entropy_count, nbits);
X r->entropy_count = 0;
- else if (r->entropy_count + num > max_entropy)
- r->entropy_count = max_entropy;
- else
- r->entropy_count = r->entropy_count + num;
+ } else if (r->entropy_count + nbits > r->poolinfo.POOLBITS) {
+ r->entropy_count = r->poolinfo.POOLBITS;
+ } else {
+ r->entropy_count += nbits;
+ if (nbits)
+ DEBUG_ENT("%s added %d bits, now %d\n",
+ r == sec_random_state ? "secondary" :
+ r == random_state ? "primary" : "unknown",
+ nbits, r->entropy_count);
+ }
X }
X
X /**********************************************************************
@@ -627,6 +647,12 @@


X return 0;
X }
X

+/*
+ * Changes to the entropy data is put into a queue rather than being added to
+ * the entropy counts directly. This is presumably to avoid doing heavy
+ * hashing calculations during an interrupt in add_timer_randomness().
+ * Instead, the entropy is only added to the pool once per timer tick.
+ */
X void batch_entropy_store(u32 a, u32 b, int num)
X {
X int new;
@@ -643,32 +669,35 @@
X queue_task(&batch_tqueue, &tq_timer);
X batch_head = new;
X } else {
-#if 0
- printk(KERN_NOTICE "random: batch entropy buffer full\n");
-#endif
+ DEBUG_ENT("batch entropy buffer full\n");
X }
X }
X
+/*
+ * Flush out the accumulated entropy operations, adding entropy to the passed
+ * store (normally random_state). If that store has enough entropy, alternate
+ * between randomizing the data of the primary and secondary stores.
+ */
X static void batch_entropy_process(void *private_)
X {
- int num = 0;
- int max_entropy;
X struct entropy_store *r = (struct entropy_store *) private_, *p;
-
+ int max_entropy = r->poolinfo.POOLBITS;
+
X if (!batch_max)
X return;
X
- max_entropy = r->poolinfo.poolwords*32;
+ p = r;
X while (batch_head != batch_tail) {
+ if (r->entropy_count >= max_entropy) {
+ r = (r == sec_random_state) ? random_state :
+ sec_random_state;
+ max_entropy = r->poolinfo.POOLBITS;
+ }
X add_entropy_words(r, batch_entropy_pool + 2*batch_tail, 2);
- p = r;
- if (r->entropy_count > max_entropy && (num & 1))
- r = sec_random_state;
X credit_entropy_store(r, batch_entropy_credit[batch_tail]);
X batch_tail = (batch_tail+1) & (batch_max-1);
- num++;
X }
- if (r->entropy_count >= random_read_wakeup_thresh)
+ if (p->entropy_count >= random_read_wakeup_thresh)
X wake_up_interruptible(&random_read_wait);
X }
X
@@ -1204,9 +1233,9 @@
X
X /*
X * This utility inline function is responsible for transfering entropy
- * from the primary pool to the secondary extraction pool. We pull
- * randomness under two conditions; one is if there isn't enough entropy
- * in the secondary pool. The other is after we have extract 1024 bytes,
+ * from the primary pool to the secondary extraction pool. We pull
+ * randomness under two conditions; one is if there isn't enough entropy
+ * in the secondary pool. The other is after we have extracted 1024 bytes,
X * at which point we do a "catastrophic reseeding".
X */
X static inline void xfer_secondary_pool(struct entropy_store *r,
@@ -1214,14 +1243,26 @@
X {
X __u32 tmp[TMP_BUF_SIZE];
X
- if (r->entropy_count < nbytes*8) {
- extract_entropy(random_state, tmp, sizeof(tmp), 0);
- add_entropy_words(r, tmp, TMP_BUF_SIZE);
- credit_entropy_store(r, TMP_BUF_SIZE*8);
+ if (r->entropy_count < nbytes * 8 &&
+ r->entropy_count < r->poolinfo.POOLBITS) {
+ int nwords = min(r->poolinfo.poolwords - r->entropy_count/32,
+ sizeof(tmp) / 4);
+
+ DEBUG_ENT("xfer %d from primary to %s (have %d, need %d)\n",
+ nwords * 32,
+ r == sec_random_state ? "secondary" : "unknown",
+ r->entropy_count, nbytes * 8);
+
+ extract_entropy(random_state, tmp, nwords, 0);
+ add_entropy_words(r, tmp, nwords);
+ credit_entropy_store(r, nwords * 32);
X }
X if (r->extract_count > 1024) {
+ DEBUG_ENT("reseeding %s with %d from primary\n",
+ r == sec_random_state ? "secondary" : "unknown",
+ sizeof(tmp) * 8);
X extract_entropy(random_state, tmp, sizeof(tmp), 0);
- add_entropy_words(r, tmp, TMP_BUF_SIZE);
+ add_entropy_words(r, tmp, sizeof(tmp) / 4);
X r->extract_count = 0;
X }
X }
@@ -1232,9 +1273,12 @@
X * bits of entropy are left in the pool, but it does not restrict the
X * number of bytes that are actually obtained. If the EXTRACT_ENTROPY_USER
X * flag is given, then the buf pointer is assumed to be in user space.
- * If the EXTRACT_ENTROPY_SECONDARY flag is given, then this function will
X *
- * Note: extract_entropy() assumes that POOLWORDS is a multiple of 16 words.
+ * If the EXTRACT_ENTROPY_SECONDARY flag is given, then we are actually
+ * extracting entropy from the secondary pool, and can refill from the
+ * primary pool if needed.
+ *
+ * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
X */
X static ssize_t extract_entropy(struct entropy_store *r, void * buf,
X size_t nbytes, int flags)
@@ -1244,14 +1288,19 @@
X __u32 x;
X
X add_timer_randomness(&extract_timer_state, nbytes);
-
+
X /* Redundant, but just in case... */
- if (r->entropy_count > r->poolinfo.poolwords)
- r->entropy_count = r->poolinfo.poolwords;
+ if (r->entropy_count > r->poolinfo.POOLBITS)
+ r->entropy_count = r->poolinfo.POOLBITS;
X
X if (flags & EXTRACT_ENTROPY_SECONDARY)
X xfer_secondary_pool(r, nbytes);
X
+ DEBUG_ENT("%s has %d bits, want %d bits\n",
+ r == sec_random_state ? "secondary" :
+ r == random_state ? "primary" : "unknown",
+ r->entropy_count, nbytes * 8);
+
X if (r->entropy_count / 8 >= nbytes)
X r->entropy_count -= nbytes*8;
X else
@@ -1547,9 +1596,7 @@
X c -= bytes;
X p += bytes;
X
- /* Convert bytes to words */
- bytes = (bytes + 3) / sizeof(__u32);
- add_entropy_words(random_state, buf, bytes);
+ add_entropy_words(random_state, buf, (bytes + 3) / 4);
X }
X if (p == buffer) {
X return (ssize_t)ret;
@@ -1599,7 +1646,7 @@
X return -EINVAL;
X if (size > random_state->poolinfo.poolwords)
X size = random_state->poolinfo.poolwords;
- if (copy_to_user(p, random_state->pool, size*sizeof(__u32)))
+ if (copy_to_user(p, random_state->pool, size * 4))
X return -EFAULT;
X return 0;
X case RNDADDENTROPY:
@@ -1716,11 +1763,11 @@
X {
X int ret;
X
- sysctl_poolsize = random_state->poolinfo.poolwords * 4;
+ sysctl_poolsize = random_state->poolinfo.POOLBYTES;
X
X ret = proc_dointvec(table, write, filp, buffer, lenp);
X if (ret || !write ||
- (sysctl_poolsize == random_state->poolinfo.poolwords * 4))
+ (sysctl_poolsize == random_state->poolinfo.POOLBYTES))
X return ret;
X
X return change_poolsize(sysctl_poolsize);
@@ -1732,7 +1779,7 @@
X {
X int len;
X
- sysctl_poolsize = random_state->poolinfo.poolwords * 4;
+ sysctl_poolsize = random_state->poolinfo.POOLBYTES;
X
X /*
X * We only handle the write case, since the read case gets
@@ -1747,7 +1794,7 @@
X return -EFAULT;
X }
X
- if (sysctl_poolsize != random_state->poolinfo.poolwords * 4)
+ if (sysctl_poolsize != random_state->poolinfo.POOLBYTES)
X return change_poolsize(sysctl_poolsize);
X
X return 0;
@@ -1846,8 +1893,7 @@
X {
X min_read_thresh = 8;
X min_write_thresh = 0;
- max_read_thresh = max_write_thresh =
- random_state->poolinfo.poolwords * 32;
+ max_read_thresh = max_write_thresh = random_state->poolinfo.POOLBITS;
X random_table[1].data = &random_state->entropy_count;
X }
X #endif /* CONFIG_SYSCTL */
@@ -2239,4 +2285,5 @@
X EXPORT_SYMBOL(add_interrupt_randomness);
X EXPORT_SYMBOL(add_blkdev_randomness);
X EXPORT_SYMBOL(batch_entropy_store);
+EXPORT_SYMBOL(generate_random_uuid);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- v2.4.12/linux/drivers/char/sh-sci.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sh-sci.c Mon Oct 15 13:36:48 2001
@@ -1131,7 +1131,7 @@
X }
X }
X
-static char banner[] __initdata[] =
+static char banner[] __initdata =
X KERN_INFO "SuperH SCI(F) driver initialized\n";
X
X int __init sci_init(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/char/shwdt.c linux/drivers/char/shwdt.c
--- v2.4.12/linux/drivers/char/shwdt.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/shwdt.c Mon Oct 15 13:36:48 2001
@@ -0,0 +1,365 @@
+/*
+ * drivers/char/shwdt.c
+ *
+ * Watchdog driver for integrated watchdog in the SuperH 3/4 processors.
+ *
+ * Copyright (C) 2001 Paul Mundt <let...@chaoticdreams.org>
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>

+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/smp_lock.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#if defined(CONFIG_CPU_SH4)
+ #define WTCNT 0xffc00008
+ #define WTCSR 0xffc0000c
+#elif defined(CONFIG_CPU_SH3)
+ #define WTCNT 0xffffff84
+ #define WTCSR 0xffffff86
+#else
+ #error "Can't use SH 3/4 watchdog on non-SH 3/4 processor."
+#endif
+
+#define WTCNT_HIGH 0x5a00
+#define WTCSR_HIGH 0xa500
+
+#define WTCSR_TME 0x80
+#define WTCSR_WT 0x40
+#define WTCSR_RSTS 0x20
+#define WTCSR_WOVF 0x10
+#define WTCSR_IOVF 0x08
+#define WTCSR_CKS2 0x04
+#define WTCSR_CKS1 0x02
+#define WTCSR_CKS0 0x01
+
+#define WTCSR_CKS 0x07
+#define WTCSR_CKS_1 0x00
+#define WTCSR_CKS_4 0x01
+#define WTCSR_CKS_16 0x02
+#define WTCSR_CKS_32 0x03
+#define WTCSR_CKS_64 0x04
+#define WTCSR_CKS_256 0x05
+#define WTCSR_CKS_1024 0x06
+#define WTCSR_CKS_4096 0x07
+
+static int sh_is_open = 0;
+static struct watchdog_info sh_wdt_info;
+
+/**
+ * sh_wdt_write_cnt - Write to Counter
+ *
+ * @val: Value to write
+ *
+ * Writes the given value @val to the lower byte of the timer counter.
+ * The upper byte is set manually on each write.
+ */
+static void sh_wdt_write_cnt(__u8 val)
+{
+ ctrl_outw(WTCNT_HIGH | (__u16)val, WTCNT);
+}
+
+/**
+ * sh_wdt_write_csr - Write to Control/Status Register
+ *
+ * @val: Value to write
+ *
+ * Writes the given value @val to the lower byte of the control/status
+ * register. The upper byte is set manually on each write.
+ */
+static void sh_wdt_write_csr(__u8 val)
+{
+ ctrl_outw(WTCSR_HIGH | (__u16)val, WTCSR);
+}
+
+/**
+ * sh_wdt_start - Start the Watchdog
+ *
+ * Starts the watchdog.
+ */
+static void sh_wdt_start(void)
+{
+ sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096);
+ sh_wdt_write_cnt(0);
+ sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME));
+}
+
+/**
+ * sh_wdt_stop - Stop the Watchdog
+ *
+ * Stops the watchdog.
+ */
+static void sh_wdt_stop(void)
+{
+ sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME));
+}
+
+/**
+ * sh_wdt_ping - Ping the Watchdog
+ *
+ * @data: Unused
+ *
+ * Clears overflow bit, resets timer counter.
+ */
+static void sh_wdt_ping(unsigned long data)
+{
+ sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
+ sh_wdt_write_cnt(0);
+}
+
+/**
+ * sh_wdt_open - Open the Device
+ *
+ * @inode: inode of device
+ * @file: file handle of device
+ *
+ * Watchdog device is opened and started.
+ */
+static int sh_wdt_open(struct inode *inode, struct file *file)
+{
+ switch (MINOR(inode->i_rdev)) {
+ case WATCHDOG_MINOR:
+ if (sh_is_open) {
+ return -EBUSY;
+ }
+
+ sh_is_open = 1;
+ sh_wdt_start();
+
+ return 0;
+ default:
+ return -ENODEV;


+ }
+
+ return 0;
+}
+

+/**
+ * sh_wdt_close - Close the Device
+ *
+ * @inode: inode of device
+ * @file: file handle of device
+ *
+ * Watchdog device is closed and stopped.
+ */
+static int sh_wdt_close(struct inode *inode, struct file *file)
+{
+ lock_kernel();
+
+ if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ sh_wdt_stop();
+#endif
+ sh_is_open = 0;
+ }
+
+ unlock_kernel();


+
+ return 0;
+}
+

+/**
+ * sh_wdt_read - Read from Device
+ *
+ * @file: file handle of device
+ * @char: buffer to write to
+ * @count: length of buffer
+ * @ppos: offset
+ *
+ * Unsupported.
+ */
+static ssize_t sh_wdt_read(struct file *file, char *buf,
+ size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+/**
+ * sh_wdt_write - Write to Device
+ *
+ * @file: file handle of device
+ * @char: buffer to write
+ * @count: length of buffer
+ * @ppos: offset
+ *
+ * Pings the watchdog on write.
+ */
+static ssize_t sh_wdt_write(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
+{
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ if (count) {
+ sh_wdt_ping(0);
+ return 1;


+ }
+
+ return 0;
+}
+

+/**
+ * sh_wdt_ioctl - Query Device
+ *
+ * @inode: inode of device
+ * @file: file handle of device
+ * @cmd: watchdog command
+ * @arg: argument
+ *
+ * Query basic information from the device or ping it, as outlined by the
+ * watchdog API.
+ */
+static int sh_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user((struct watchdog_info *)arg,
+ &sh_wdt_info,
+ sizeof(sh_wdt_info))) {


+ return -EFAULT;
+ }
+

+ break;
+ case WDIOC_GETSTATUS:
+ if (copy_to_user((int *)arg,
+ &sh_is_open,
+ sizeof(int))) {


+ return -EFAULT;
+ }
+

+ break;
+ case WDIOC_KEEPALIVE:
+ sh_wdt_ping(0);
+
+ break;
+ default:
+ return -ENOTTY;


+ }
+
+ return 0;
+}
+

+/**
+ * sh_wdt_notify_sys - Notifier Handler
+ *
+ * @this: notifier block
+ * @code: notifier event
+ * @unused: unused
+ *
+ * Handles specific events, such as turning off the watchdog during a
+ * shutdown event.
+ */
+static int sh_wdt_notify_sys(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_DOWN || SYS_HALT) {
+ sh_wdt_stop();
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct file_operations sh_wdt_fops = {
+ owner: THIS_MODULE,
+ read: sh_wdt_read,
+ write: sh_wdt_write,
+ ioctl: sh_wdt_ioctl,
+ open: sh_wdt_open,
+ release: sh_wdt_close,
+};
+
+static struct watchdog_info sh_wdt_info = {
+ WDIOF_KEEPALIVEPING,
+ 1,
+ "SH WDT",
+};
+
+static struct notifier_block sh_wdt_notifier = {
+ sh_wdt_notify_sys,
+ NULL,


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 13'
echo 'File patch-2.4.13 is continued in part 14'
echo "14" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:44 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part14

#!/bin/sh -x
# this is part 14 of a 53 - part archive


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

if test "$Scheck" != 14; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ 0
+};
+
+static struct miscdevice sh_wdt_miscdev = {


+ WATCHDOG_MINOR,
+ "watchdog",

+ &sh_wdt_fops,
+};
+
+/**
+ * sh_wdt_init - Initialize module
+ *
+ * Registers the device and notifier handler. Actual device
+ * initialization is handled by sh_wdt_open().
+ */
+static int __init sh_wdt_init(void)
+{
+ if (misc_register(&sh_wdt_miscdev)) {
+ printk(KERN_ERR "shwdt: Can't register misc device\n");


+ return -EINVAL;
+ }
+

+ if (!request_region(WTCNT, 1, "shwdt")) {
+ printk(KERN_ERR "shwdt: Can't request WTCNT region\n");
+ misc_deregister(&sh_wdt_miscdev);
+ return -ENXIO;
+ }
+
+ if (!request_region(WTCSR, 1, "shwdt")) {
+ printk(KERN_ERR "shwdt: Can't request WTCSR region\n");
+ release_region(WTCNT, 1);
+ misc_deregister(&sh_wdt_miscdev);
+ return -ENXIO;
+ }
+
+ if (register_reboot_notifier(&sh_wdt_notifier)) {
+ printk(KERN_ERR "shwdt: Can't register reboot notifier\n");
+ release_region(WTCSR, 1);
+ release_region(WTCNT, 1);
+ misc_deregister(&sh_wdt_miscdev);


+ return -EINVAL;
+ }
+

+ return 0;
+}
+
+/**

+ * sh_wdt_exit - Deinitialize module
+ *
+ * Unregisters the device and notifier handler. Actual device
+ * deinitialization is handled by sh_wdt_close().
+ */
+static void __exit sh_wdt_exit(void)
+{
+ unregister_reboot_notifier(&sh_wdt_notifier);
+ release_region(WTCSR, 1);
+ release_region(WTCNT, 1);
+ misc_deregister(&sh_wdt_miscdev);
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Paul Mundt <let...@chaoticdreams.org>");
+MODULE_DESCRIPTION("SH 3/4 watchdog driver");
+MODULE_LICENSE("GPL");
+
+module_init(sh_wdt_init);
+module_exit(sh_wdt_exit);
+
diff -u --recursive --new-file v2.4.12/linux/drivers/char/sonypi.c linux/drivers/char/sonypi.c
--- v2.4.12/linux/drivers/char/sonypi.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sonypi.c Mon Oct 15 08:38:31 2001
@@ -39,6 +39,7 @@
X #include <linux/delay.h>


X #include <asm/uaccess.h>
X #include <asm/io.h>

+#include <asm/system.h>
X
X #include "sonypi.h"
X #include <linux/sonypi.h>
@@ -48,7 +49,7 @@
X static int verbose; /* = 0 */
X static int fnkeyinit; /* = 0 */
X static int camera; /* = 0 */
-extern int is_sony_vaio_laptop; /* set in DMI table parse routines */
+static int compat; /* = 0 */
X
X /* Inits the queue */
X static inline void sonypi_initq(void) {
@@ -110,27 +111,27 @@
X
X static void sonypi_ecrset(u16 addr, u16 value) {
X
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+ wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
X outw_p(0x81, SONYPI_CST_IOPORT);
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+ wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
X outw_p(addr, SONYPI_DATA_IOPORT);
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+ wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
X outw_p(value, SONYPI_DATA_IOPORT);
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+ wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
X }
X
X static u16 sonypi_ecrget(u16 addr) {
X
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
+ wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3);
X outw_p(0x80, SONYPI_CST_IOPORT);
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+ wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
X outw_p(addr, SONYPI_DATA_IOPORT);
- wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
+ wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2);
X return inw_p(SONYPI_DATA_IOPORT);
X }
X
X /* Initializes the device - this comes from the AML code in the ACPI bios */
-static void __devinit sonypi_normal_srs(void) {
+static void __devinit sonypi_type1_srs(void) {
X u32 v;
X
X pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -152,7 +153,7 @@
X pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
X }
X
-static void __devinit sonypi_r505_srs(void) {
+static void __devinit sonypi_type2_srs(void) {
X sonypi_ecrset(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8);
X sonypi_ecrset(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF);
X sonypi_ecrset(SONYPI_SIRQ, sonypi_device.bits);
@@ -160,7 +161,7 @@
X }
X
X /* Disables the device - this comes from the AML code in the ACPI bios */
-static void __devexit sonypi_normal_dis(void) {
+static void __devexit sonypi_type1_dis(void) {
X u32 v;
X
X pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
@@ -172,7 +173,7 @@
X outl(v, SONYPI_IRQ_PORT);
X }
X
-static void __devexit sonypi_r505_dis(void) {
+static void __devexit sonypi_type2_dis(void) {
X sonypi_ecrset(SONYPI_SHIB, 0);
X sonypi_ecrset(SONYPI_SLOB, 0);
X sonypi_ecrset(SONYPI_SIRQ, 0);
@@ -181,7 +182,7 @@
X static u8 sonypi_call1(u8 dev) {
X u8 v1, v2;
X
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(dev, sonypi_device.ioport2);
X v1 = inb_p(sonypi_device.ioport2);
X v2 = inb_p(sonypi_device.ioport1);
@@ -191,9 +192,9 @@
X static u8 sonypi_call2(u8 dev, u8 fn) {
X u8 v1;
X
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(dev, sonypi_device.ioport2);
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(fn, sonypi_device.ioport1);
X v1 = inb_p(sonypi_device.ioport1);
X return v1;
@@ -202,11 +203,11 @@
X static u8 sonypi_call3(u8 dev, u8 fn, u8 v) {
X u8 v1;
X
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(dev, sonypi_device.ioport2);
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(fn, sonypi_device.ioport1);
- wait_on_command(inb_p(sonypi_device.ioport2) & 2);
+ wait_on_command(0, inb_p(sonypi_device.ioport2) & 2);
X outb(v, sonypi_device.ioport1);
X v1 = inb_p(sonypi_device.ioport1);
X return v1;
@@ -228,7 +229,7 @@
X /* Set brightness, hue etc */
X static void sonypi_set(u8 fn, u8 v) {
X
- wait_on_command(sonypi_call3(0x90, fn, v));
+ wait_on_command(0, sonypi_call3(0x90, fn, v));
X }
X
X /* Tests if the camera is ready */
@@ -291,19 +292,19 @@
X int i;
X u8 sonypi_jogger_ev, sonypi_fnkey_ev;
X
- if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
- sonypi_jogger_ev = SONYPI_R505_JOGGER_EV;
- sonypi_fnkey_ev = SONYPI_R505_FNKEY_EV;
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+ sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
+ sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
X }
X else {
- sonypi_jogger_ev = SONYPI_NORMAL_JOGGER_EV;
- sonypi_fnkey_ev = SONYPI_NORMAL_FNKEY_EV;
+ sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
+ sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
X }
X
X v1 = inb_p(sonypi_device.ioport1);
X v2 = inb_p(sonypi_device.ioport2);
X
- if ((v2 & SONYPI_NORMAL_PKEY_EV) == SONYPI_NORMAL_PKEY_EV) {
+ if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) {
X for (i = 0; sonypi_pkeyev[i].event; i++)
X if (sonypi_pkeyev[i].data == v1) {
X event = sonypi_pkeyev[i].event;
@@ -338,9 +339,23 @@
X goto found;
X }
X }
+ if ((v2 & SONYPI_BACK_EV) == SONYPI_BACK_EV) {
+ for (i = 0; sonypi_backev[i].event; i++)
+ if (sonypi_backev[i].data == v1) {
+ event = sonypi_backev[i].event;
+ goto found;
+ }
+ }
+ if ((v2 & SONYPI_LID_EV) == SONYPI_LID_EV) {
+ for (i = 0; sonypi_lidev[i].event; i++)
+ if (sonypi_lidev[i].data == v1) {
+ event = sonypi_lidev[i].event;
+ goto found;
+ }
+ }
X if (verbose)
X printk(KERN_WARNING
- "sonypi: unknown event port1=0x%x,port2=0x%x\n",v1,v2);
+ "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2);
X return;
X
X found:
@@ -535,23 +550,20 @@
X -1, "sonypi", &sonypi_misc_fops
X };
X
-static int __devinit sonypi_probe(struct pci_dev *pcidev,
- const struct pci_device_id *ent) {
+static int __devinit sonypi_probe(struct pci_dev *pcidev) {
X int i, ret;
X struct sonypi_ioport_list *ioport_list;
X struct sonypi_irq_list *irq_list;
X
- if (sonypi_device.dev) {
- printk(KERN_ERR "sonypi: only one device allowed!\n"),
- ret = -EBUSY;
- goto out1;
- }
X sonypi_device.dev = pcidev;
- sonypi_device.model = (int)ent->driver_data;
+ if (pcidev)
+ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
+ else
+ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
X sonypi_initq();
X init_MUTEX(&sonypi_device.lock);
X
- if (pci_enable_device(pcidev)) {
+ if (pcidev && pci_enable_device(pcidev)) {
X printk(KERN_ERR "sonypi: pci_enable_device failed\n");
X ret = -EIO;
X goto out1;
@@ -564,15 +576,15 @@
X goto out1;
X }
X
- if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505) {
- ioport_list = sonypi_r505_ioport_list;
- sonypi_device.region_size = SONYPI_R505_REGION_SIZE;
- irq_list = sonypi_r505_irq_list;
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+ ioport_list = sonypi_type2_ioport_list;
+ sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
+ irq_list = sonypi_type2_irq_list;
X }
X else {
- ioport_list = sonypi_normal_ioport_list;
- sonypi_device.region_size = SONYPI_NORMAL_REGION_SIZE;
- irq_list = sonypi_normal_irq_list;
+ ioport_list = sonypi_type1_ioport_list;
+ sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
+ irq_list = sonypi_type1_irq_list;
X }
X
X for (i = 0; ioport_list[i].port1; i++) {
@@ -608,22 +620,27 @@
X if (fnkeyinit)
X outb(0xf0, 0xb2);
X
- if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
- sonypi_r505_srs();
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+ sonypi_type2_srs();
X else
- sonypi_normal_srs();
+ sonypi_type1_srs();
X
X sonypi_call1(0x82);
X sonypi_call2(0x81, 0xff);
- sonypi_call1(0x92);
+ if (compat)
+ sonypi_call1(0x92);
+ else
+ sonypi_call1(0x82);
X
X printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n",
X SONYPI_DRIVER_MAJORVERSION,
X SONYPI_DRIVER_MINORVERSION);
- printk(KERN_INFO "sonypi: detected %s model, camera = %s\n",
- (sonypi_device.model == SONYPI_DEVICE_MODEL_NORMAL) ?
- "normal" : "R505",
- camera ? "on" : "off");
+ printk(KERN_INFO "sonypi: detected %s model, "
+ "camera = %s, compat = %s\n",
+ (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
+ "type1" : "type2",
+ camera ? "on" : "off",
+ compat ? "on" : "off");
X printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
X sonypi_device.irq,
X sonypi_device.ioport1, sonypi_device.ioport2);
@@ -641,50 +658,64 @@


X return ret;
X }
X

-static void __devexit sonypi_remove(struct pci_dev *pcidev) {
+static void __devexit sonypi_remove(void) {
X sonypi_call2(0x81, 0); /* make sure we don't get any more events */
X if (camera)
X sonypi_camera_off();
- if (sonypi_device.model == SONYPI_DEVICE_MODEL_R505)
- sonypi_r505_dis();
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+ sonypi_type2_dis();
X else
- sonypi_normal_dis();
+ sonypi_type1_dis();
X free_irq(sonypi_device.irq, sonypi_irq);
X release_region(sonypi_device.ioport1, sonypi_device.region_size);
X misc_deregister(&sonypi_misc_device);
X printk(KERN_INFO "sonypi: removed.\n");
X }
X
-static struct pci_device_id sonypi_id_tbl[] __devinitdata = {
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- (unsigned long) SONYPI_DEVICE_MODEL_NORMAL },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- (unsigned long) SONYPI_DEVICE_MODEL_R505 },
- { }
-};
-
-MODULE_DEVICE_TABLE(pci, sonypi_id_tbl);
-
-static struct pci_driver sonypi_driver = {
- name: "sonypi",
- id_table: sonypi_id_tbl,
- probe: sonypi_probe,
- remove: sonypi_remove,
-};
-
X static int __init sonypi_init_module(void) {
- if (is_sony_vaio_laptop)
- return pci_module_init(&sonypi_driver);
+ struct pci_dev *pcidev = NULL;
+
+ if (is_sony_vaio_laptop) {
+ pcidev = pci_find_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_3,
+ NULL);
+ return sonypi_probe(pcidev);
+ }
X else
X return -ENODEV;
X }
X
X static void __exit sonypi_cleanup_module(void) {
- pci_unregister_driver(&sonypi_driver);
+ sonypi_remove();
X }
X
+#ifndef MODULE
+static int __init sonypi_setup(char *str) {
+ int ints[6];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+ if (ints[0] <= 0)
+ goto out;
+ minor = ints[1];
+ if (ints[0] == 1)
+ goto out;
+ verbose = ints[2];
+ if (ints[0] == 2)
+ goto out;
+ fnkeyinit = ints[3];
+ if (ints[0] == 3)
+ goto out;
+ camera = ints[4];
+ if (ints[0] == 4)
+ goto out;
+ compat = ints[5];
+out:


+ return 1;
+}
+

+__setup("sonypi=", sonypi_setup);
+#endif /* !MODULE */
+
X /* Module entry points */
X module_init(sonypi_init_module);
X module_exit(sonypi_cleanup_module);
@@ -702,5 +733,7 @@
X MODULE_PARM_DESC(fnkeyinit, "set this if your Fn keys do not generate any event");
X MODULE_PARM(camera,"i");
X MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
+MODULE_PARM(compat,"i");
+MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
X
X EXPORT_SYMBOL(sonypi_camera_command);
diff -u --recursive --new-file v2.4.12/linux/drivers/char/sonypi.h linux/drivers/char/sonypi.h
--- v2.4.12/linux/drivers/char/sonypi.h Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sonypi.h Mon Oct 15 08:38:31 2001
@@ -35,26 +35,26 @@
X #ifdef __KERNEL__
X
X #define SONYPI_DRIVER_MAJORVERSION 1
-#define SONYPI_DRIVER_MINORVERSION 5
+#define SONYPI_DRIVER_MINORVERSION 7
X
X #include <linux/types.h>
X #include <linux/pci.h>
X #include "linux/sonypi.h"
X
-/* Normal models use those */
+/* type1 models use those */
X #define SONYPI_IRQ_PORT 0x8034
X #define SONYPI_IRQ_SHIFT 22
X #define SONYPI_BASE 0x50
X #define SONYPI_G10A (SONYPI_BASE+0x14)
-#define SONYPI_NORMAL_REGION_SIZE 0x08
+#define SONYPI_TYPE1_REGION_SIZE 0x08
X
-/* R505 series specifics */
-#define SONYPI_SIRQ 0x9b
-#define SONYPI_SLOB 0x9c
-#define SONYPI_SHIB 0x9d
-#define SONYPI_R505_REGION_SIZE 0x20
+/* type2 series specifics */
+#define SONYPI_SIRQ 0x9b
+#define SONYPI_SLOB 0x9c
+#define SONYPI_SHIB 0x9d
+#define SONYPI_TYPE2_REGION_SIZE 0x20
X
-/* ioports used for brightness and R505 events */
+/* ioports used for brightness and type2 events */
X #define SONYPI_DATA_IOPORT 0x62
X #define SONYPI_CST_IOPORT 0x66
X
@@ -64,7 +64,7 @@
X u16 port2;
X };
X
-static struct sonypi_ioport_list sonypi_normal_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
X { 0x10c0, 0x10c4 }, /* looks like the default on C1Vx */
X { 0x1080, 0x1084 },
X { 0x1090, 0x1094 },
@@ -73,7 +73,7 @@
X { 0x0, 0x0 }
X };
X
-static struct sonypi_ioport_list sonypi_r505_ioport_list[] = {
+static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
X { 0x1080, 0x1084 },
X { 0x10a0, 0x10a4 },
X { 0x10c0, 0x10c4 },
@@ -87,14 +87,14 @@
X u16 bits;
X };
X
-static struct sonypi_irq_list sonypi_normal_irq_list[] = {
+static struct sonypi_irq_list sonypi_type1_irq_list[] = {
X { 11, 0x2 }, /* IRQ 11, GO22=0,GO23=1 in AML */
X { 10, 0x1 }, /* IRQ 10, GO22=1,GO23=0 in AML */
X { 5, 0x0 }, /* IRQ 5, GO22=0,GO23=0 in AML */
X { 0, 0x3 } /* no IRQ, GO22=1,GO23=1 in AML */
X };
X
-static struct sonypi_irq_list sonypi_r505_irq_list[] = {
+static struct sonypi_irq_list sonypi_type2_irq_list[] = {
X { 11, 0x80 }, /* IRQ 11, 0x80 in SIRQ in AML */
X { 10, 0x40 }, /* IRQ 10, 0x40 in SIRQ in AML */
X { 9, 0x20 }, /* IRQ 9, 0x20 in SIRQ in AML */
@@ -132,13 +132,15 @@
X #define SONYPI_CAMERA_ROMVERSION 9
X
X /* key press event data (ioport2) */
-#define SONYPI_NORMAL_JOGGER_EV 0x10
-#define SONYPI_R505_JOGGER_EV 0x08
+#define SONYPI_TYPE1_JOGGER_EV 0x10
+#define SONYPI_TYPE2_JOGGER_EV 0x08
X #define SONYPI_CAPTURE_EV 0x60
-#define SONYPI_NORMAL_FNKEY_EV 0x20
-#define SONYPI_R505_FNKEY_EV 0x08
+#define SONYPI_TYPE1_FNKEY_EV 0x20
+#define SONYPI_TYPE2_FNKEY_EV 0x08
X #define SONYPI_BLUETOOTH_EV 0x30
-#define SONYPI_NORMAL_PKEY_EV 0x40
+#define SONYPI_TYPE1_PKEY_EV 0x40
+#define SONYPI_BACK_EV 0x08
+#define SONYPI_LID_EV 0x38
X
X struct sonypi_event {
X u8 data;
@@ -204,6 +206,19 @@
X { 0x00, 0x00 }
X };
X
+/* The set of possible back button events */
+static struct sonypi_event sonypi_backev[] = {
+ { 0x20, SONYPI_EVENT_BACK_PRESSED },
+ { 0x00, 0x00 }
+};
+
+/* The set of possible lid events */
+static struct sonypi_event sonypi_lidev[] = {
+ { 0x51, SONYPI_EVENT_LID_CLOSED },
+ { 0x50, SONYPI_EVENT_LID_OPENED },
+ { 0x00, 0x00 }
+};
+
X #define SONYPI_BUF_SIZE 128
X struct sonypi_queue {
X unsigned long head;
@@ -215,8 +230,8 @@
X unsigned char buf[SONYPI_BUF_SIZE];
X };
X
-#define SONYPI_DEVICE_MODEL_NORMAL 1
-#define SONYPI_DEVICE_MODEL_R505 2
+#define SONYPI_DEVICE_MODEL_TYPE1 1
+#define SONYPI_DEVICE_MODEL_TYPE2 2
X
X struct sonypi_device {
X struct pci_dev *dev;
@@ -232,11 +247,11 @@
X int model;
X };
X
-#define wait_on_command(command) { \
+#define wait_on_command(quiet, command) { \
X unsigned int n = 10000; \
X while (--n && (command)) \
X udelay(1); \
- if (!n) \
+ if (!n && (verbose || !quiet)) \
X printk(KERN_WARNING "sonypi command failed at " __FILE__ " : " __FUNCTION__ "(line %d)\n", __LINE__); \
X }
X
diff -u --recursive --new-file v2.4.12/linux/drivers/char/toshiba.c linux/drivers/char/toshiba.c
--- v2.4.12/linux/drivers/char/toshiba.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/toshiba.c Thu Oct 11 09:04:57 2001
@@ -17,7 +17,9 @@
X * 0xfc15: Tom May <t...@you-bastards.com>
X * 0xfc17: Dave Konrad <kon...@xenia.it>
X * 0xfc1a: George Betzos <bet...@engr.colostate.edu>
+ * 0xfc1b: Munemasa Wada <mune...@jnovel.co.jp>
X * 0xfc1d: Arthur Liu <ar...@slap.mine.nu>
+ * 0xfc5a: Jacques L'helgoualc'h <l...@free.fr>
X * 0xfcd1: Mr. Dave Konrad <kon...@xenia.it>
X *
X * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -51,7 +53,7 @@
X *
X */
X
-#define TOSH_VERSION "1.9 22/3/2001"
+#define TOSH_VERSION "1.11 26/9/2001"
X #define TOSH_DEBUG 0
X
X #include <linux/module.h>
@@ -264,7 +266,7 @@
X if (!arg)
X return -EINVAL;
X
- if(copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+ if (copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
X return -EFAULT;
X
X switch (cmd) {
@@ -288,7 +290,7 @@
X return -EINVAL;
X }
X
- if(copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+ if (copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
X return -EFAULT;
X
X return (err==0) ? 0:-EINVAL;
@@ -335,7 +337,8 @@
X {
X switch (tosh_id) {
X case 0xfc02: case 0xfc04: case 0xfc09: case 0xfc0a: case 0xfc10:
- case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
+ case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a: case 0xfc1b:
+ case 0xfc5a:
X tosh_fn = 0x62;
X break;
X case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1: case 0xfce0:
@@ -412,8 +415,19 @@
X */
X int tosh_probe(void)
X {
- int major,minor,day,year,month,flag;
+ int i,major,minor,day,year,month,flag;
+ unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 };
X SMMRegisters regs;
+
+ /* extra sanity check for the string "TOSHIBA" in the BIOS because
+ some machines that are not Toshiba's pass the next test */
+
+ for (i=0;i<7;i++) {
+ if (isa_readb(0xfe010+i)!=signature[i]) {
+ printk("toshiba: not a supported Toshiba laptop\n");


+ return -ENODEV;
+ }
+ }

X
X /* call the Toshiba SCI support check routine */
X
diff -u --recursive --new-file v2.4.12/linux/drivers/fc4/soc.c linux/drivers/fc4/soc.c
--- v2.4.12/linux/drivers/fc4/soc.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/fc4/soc.c Thu Oct 11 09:14:32 2001
@@ -764,3 +764,4 @@
X
X module_init(soc_probe);
X module_exit(soc_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/fc4/socal.c linux/drivers/fc4/socal.c
--- v2.4.12/linux/drivers/fc4/socal.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/fc4/socal.c Thu Oct 11 09:14:32 2001
@@ -904,3 +904,4 @@
X
X module_init(socal_probe);
X module_exit(socal_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/Config.in linux/drivers/i2c/Config.in
--- v2.4.12/linux/drivers/i2c/Config.in Sun Sep 23 11:40:57 2001
+++ linux/drivers/i2c/Config.in Thu Oct 11 08:05:47 2001
@@ -26,11 +26,24 @@
X dep_tristate ' ITE I2C Adapter' CONFIG_ITE_I2C_ADAP $CONFIG_ITE_I2C_ALGO
X fi
X fi
+ if [ "$CONFIG_8xx" = "y" ]; then
+ dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C
+ if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
+ dep_tristate ' Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX
+ fi
+ fi
+ if [ "$CONFIG_405" = "y" ]; then
+ dep_tristate 'PPC 405 I2C Algorithm' CONFIG_I2C_PPC405_ALGO $CONFIG_I2C
+ if [ "$CONFIG_I2C_PPC405_ALGO" != "n" ]; then
+ dep_tristate ' PPC 405 I2C Adapter' CONFIG_I2C_PPC405_ADAP $CONFIG_I2C_PPC405_ALGO
+ fi
+ fi
X
X # This is needed for automatic patch generation: sensors code starts here
X # This is needed for automatic patch generation: sensors code ends here
X
X dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C
+ dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C
X
X fi
X endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/Makefile linux/drivers/i2c/Makefile
--- v2.4.12/linux/drivers/i2c/Makefile Fri Dec 29 14:07:21 2000
+++ linux/drivers/i2c/Makefile Thu Oct 11 08:05:47 2001
@@ -4,7 +4,8 @@
X
X O_TARGET := i2c.o
X
-export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o
+export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
+ i2c-algo-ite.o i2c-proc.o
X
X obj-$(CONFIG_I2C) += i2c-core.o
X obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
@@ -14,6 +15,9 @@
X obj-$(CONFIG_I2C_VELLEMAN) += i2c-velleman.o
X obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
X obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
+obj-$(CONFIG_ITE_I2C_ALGO) += i2c-algo-ite.o
+obj-$(CONFIG_ITE_I2C_ADAP) += i2c-adap-ite.o
+obj-$(CONFIG_I2C_PROC) += i2c-proc.o
X
X # This is needed for automatic patch generation: sensors code starts here
X # This is needed for automatic patch generation: sensors code ends here
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- v2.4.12/linux/drivers/i2c/i2c-adap-ite.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-adap-ite.c Thu Oct 11 08:05:47 2001
@@ -37,7 +37,7 @@
X #include <linux/ioport.h>
X #include <linux/module.h>
X #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/version.h>
X #include <linux/init.h>
X #include <asm/irq.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-bit.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-bit.c Thu Oct 11 08:05:47 2001
@@ -21,7 +21,7 @@
X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi> and even
X Frodo Looijaard <fro...@dds.nl> */
X
-/* $Id: i2c-algo-bit.c,v 1.27 2000/07/09 15:16:16 frodo Exp $ */
+/* $Id: i2c-algo-bit.c,v 1.30 2001/07/29 02:44:25 mds Exp $ */
X
X #include <linux/kernel.h>
X #include <linux/module.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-ite.c linux/drivers/i2c/i2c-algo-ite.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-ite.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-ite.c Thu Oct 11 08:05:47 2001
@@ -37,7 +37,7 @@
X #include <linux/kernel.h>
X #include <linux/module.h>
X #include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/version.h>
X #include <linux/init.h>
X #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-algo-pcf.c linux/drivers/i2c/i2c-algo-pcf.c
--- v2.4.12/linux/drivers/i2c/i2c-algo-pcf.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-algo-pcf.c Thu Oct 11 08:05:47 2001
@@ -1,4 +1,3 @@
-
X /* ------------------------------------------------------------------------- */
X /* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */
X /* ------------------------------------------------------------------------- */
@@ -24,7 +23,9 @@
X Frodo Looijaard <fro...@dds.nl> ,and also from Martin Bailey
X <mba...@littlefeet-inc.com> */
X
-/* $Id: i2c-algo-pcf.c,v 1.25 2000/11/10 13:43:32 frodo Exp $ */
+/* Partially rewriten by Oleg I. Vdovikin <vdov...@jscc.ru> to handle multiple
+ messages, proper stop/repstart signaling during receive,
+ added detect code */
X
X #include <linux/kernel.h>
X #include <linux/module.h>
@@ -49,26 +50,9 @@
X /* debug the protocol by showing transferred bits */
X #define DEF_TIMEOUT 16
X
-/* debugging - slow down transfer to have a look at the data .. */
-/* I use this with two leds&resistors, each one connected to sda,scl */
-/* respectively. This makes sure that the algorithm works. Some chips */
-/* might not like this, as they have an internal timeout of some mils */
-/*
-#define SLO_IO jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
- if (need_resched) schedule();
-*/
-
-
-/* ----- global variables --------------------------------------------- */
-
-#ifdef SLO_IO
- int jif;
-#endif
-
X /* module parameters:
X */
-static int i2c_debug=1;
-static int pcf_test=0; /* see if the line-setting functions work */
+static int i2c_debug=0;
X static int pcf_scan=0; /* have a look at what's hanging 'round */
X
X /* --- setting states on the bus with the right timing: --------------- */
@@ -80,7 +64,6 @@
X #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
X #define i2c_inb(adap) adap->getpcf(adap->data, 0)
X
-
X /* --- other auxiliary functions -------------------------------------- */
X
X static void i2c_start(struct i2c_algo_pcf_data *adap)
@@ -111,16 +94,15 @@
X status = get_pcf(adap, 1);
X #ifndef STUB_I2C
X while (timeout-- && !(status & I2C_PCF_BB)) {
- udelay(1000); /* How much is this? */
+ udelay(100); /* wait for 100 us */
X status = get_pcf(adap, 1);
X }
X #endif
- if (timeout<=0)
+ if (timeout <= 0) {
X printk("Timeout waiting for Bus Busy\n");
- /*
- set_pcf(adap, 1, I2C_PCF_STOP);
- */
- return(timeout<=0);
+ }
+
+ return (timeout<=0);
X }
X
X
@@ -147,7 +129,6 @@
X return(0);
X }
X
-
X /*
X * This should perform the 'PCF8584 initialization sequence' as described
X * in the Philips IC12 data book (1995, Aug 29).
@@ -156,111 +137,64 @@
X * There should be a delay at the end equal to the longest I2C message
X * to synchronize the BB-bit (in multimaster systems). How long is
X * this? I assume 1 second is always long enough.
+ *
+ * vdovikin: added detect code for PCF8584
X */
X static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
X {
+ unsigned char temp;
+
+ DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
X
- /* S1=0x80: S0 selected, serial interface off */
+ /* S1=0x80: S0 selected, serial interface off */
X set_pcf(adap, 1, I2C_PCF_PIN);
+ /* check to see S1 now used as R/W ctrl -
+ PCF8584 does that when ESO is zero */
+ /* PCF also resets PIN bit */
+ if ((temp = get_pcf(adap, 1)) != (0)) {
+ DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
+ return -ENXIO; /* definetly not PCF8584 */
+ }
X
X /* load own address in S0, effective address is (own << 1) */
X i2c_outb(adap, get_own(adap));
+ /* check it's realy writen */
+ if ((temp = i2c_inb(adap)) != get_own(adap)) {
+ DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
+ return -ENXIO;
+ }
X
X /* S1=0xA0, next byte in S2 */
X set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
+ /* check to see S2 now selected */
+ if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) {
+ DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
+ return -ENXIO;
+ }
X
X /* load clock register S2 */
X i2c_outb(adap, get_clock(adap));
+ /* check it's realy writen, the only 5 lowest bits does matter */
+ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
+ DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
+ return -ENXIO;
+ }
X
X /* Enable serial interface, idle, S0 selected */
X set_pcf(adap, 1, I2C_PCF_IDLE);
X
- DEB2(printk("i2c-algo-pcf.o: irq: Initialized 8584.\n"));


- return 0;
-}
-
-

-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_algo_pcf_data *adap, char *name) {
-#if 0
- int scl,sda;
- sda=getsda(adap);
- if (adap->getscl==NULL) {
- printk("i2c-algo-pcf.o: Warning: Adapter can't read from clock line - skipping test.\n");
- return 0;
- }
- scl=getscl(adap);
- printk("i2c-algo-pcf.o: Adapter: %s scl: %d sda: %d -- testing...\n",
- name,getscl(adap),getsda(adap));
- if (!scl || !sda ) {
- printk("i2c-algo-pcf.o: %s seems to be busy.\n",adap->name);
- goto bailout;
- }
- sdalo(adap);
- printk("i2c-algo-pcf.o:1 scl: %d sda: %d \n",getscl(adap),
- getsda(adap));
- if ( 0 != getsda(adap) ) {
- printk("i2c-algo-pcf.o: %s SDA stuck high!\n",name);
- sdahi(adap);
- goto bailout;
- }
- if ( 0 == getscl(adap) ) {
- printk("i2c-algo-pcf.o: %s SCL unexpected low while pulling SDA low!\n",
- name);
- goto bailout;
- }
- sdahi(adap);
- printk("i2c-algo-pcf.o:2 scl: %d sda: %d \n",getscl(adap),
- getsda(adap));
- if ( 0 == getsda(adap) ) {
- printk("i2c-algo-pcf.o: %s SDA stuck low!\n",name);
- sdahi(adap);
- goto bailout;
- }
- if ( 0 == getscl(adap) ) {
- printk("i2c-algo-pcf.o: %s SCL unexpected low while SDA high!\n",
- adap->name);
- goto bailout;
+ /* check to see PCF is realy idled and we can access status register */
+ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
+ DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
+ return -ENXIO;
X }
- scllo(adap);
- printk("i2c-algo-pcf.o:3 scl: %d sda: %d \n",getscl(adap),
- getsda(adap));
- if ( 0 != getscl(adap) ) {
- printk("i2c-algo-pcf.o: %s SCL stuck high!\n",name);
- sclhi(adap);
- goto bailout;
- }
- if ( 0 == getsda(adap) ) {
- printk("i2c-algo-pcf.o: %s SDA unexpected low while pulling SCL low!\n",
- name);
- goto bailout;
- }
- sclhi(adap);
- printk("i2c-algo-pcf.o:4 scl: %d sda: %d \n",getscl(adap),
- getsda(adap));
- if ( 0 == getscl(adap) ) {
- printk("i2c-algo-pcf.o: %s SCL stuck low!\n",name);
- sclhi(adap);
- goto bailout;
- }
- if ( 0 == getsda(adap) ) {
- printk("i2c-algo-pcf.o: %s SDA unexpected low while SCL high!\n",
- name);
- goto bailout;
- }
- printk("i2c-algo-pcf.o: %s passed test.\n",name);
+
+ printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
+
X return 0;
-bailout:
- sdahi(adap);
- sclhi(adap);
- return -ENODEV;
-#endif
- return (0);
X }
X
+
X /* ----- Utility functions
X */
X
@@ -287,8 +221,8 @@
X }
X
X
-static int pcf_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
- int count)
+static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
+ int count, int last)
X {
X struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
X int wrcount, status, timeout;
@@ -313,58 +247,59 @@
X }
X #endif
X }
- i2c_stop(adap);
+ if (last) {
+ i2c_stop(adap);
+ }
+ else {
+ i2c_repstart(adap);
+ }
+
X return (wrcount);
X }
X
X
-static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
+static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
+ int count, int last)
X {
- int rdcount=0, i, status, timeout, dummy=1;
+ int i, status;
X struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
-
- for (i=0; i<count; ++i) {
- buf[rdcount] = i2c_inb(adap);
- if (dummy) {
- dummy = 0;
- } else {
- rdcount++;
- }
- timeout = wait_for_pin(adap, &status);
- if (timeout) {
+
+ /* increment number of bytes to read by one -- read dummy byte */
+ for (i = 0; i <= count; i++) {
+
+ if (wait_for_pin(adap, &status)) {
X i2c_stop(adap);
- printk("i2c-algo-pcf.o: i2c_read: "
- "i2c_inb timed out.\n");
+ printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n");
X return (-1);
X }
+
X #ifndef STUB_I2C
- if (status & I2C_PCF_LRB) {
+ if ((status & I2C_PCF_LRB) && (i != count)) {
X i2c_stop(adap);
X printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
X return (-1);
X }
X #endif
- }
- set_pcf(adap, 1, I2C_PCF_ESO);
- buf[rdcount] = i2c_inb(adap);
- if (dummy) {
- dummy = 0;
- } else {
- rdcount++;
- }
- timeout = wait_for_pin(adap, &status);
- if (timeout) {
- i2c_stop(adap);
- printk("i2c-algo-pcf.o: i2c_read: i2c_inb timed out.\n");
- return (-1);
- }
-
- i2c_stop(adap);
+
+ if (i == count - 1) {
+ set_pcf(adap, 1, I2C_PCF_ESO);
+ } else
+ if (i == count) {
+ if (last) {
+ i2c_stop(adap);
+ } else {
+ i2c_repstart(adap);
+ }
+ };
X
- /* Read final byte from S0 register */
- buf[rdcount++] = i2c_inb(adap);
+ if (i) {
+ buf[i - 1] = i2c_inb(adap);
+ } else {
+ i2c_inb(adap); /* dummy read */
+ }
+ }
X
- return (rdcount);
+ return (i - 1);
X }
X
X
@@ -418,16 +353,10 @@
X {
X struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
X struct i2c_msg *pmsg;
- int i = 0;
- int ret, timeout, status;
-
- pmsg = &msgs[i];
-
- /* Send address here if Read */
- if (pmsg->flags & I2C_M_RD) {
- ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
- }
+ int i;
+ int ret=0, timeout, status;
X
+
X /* Check for bus busy */
X timeout = wait_for_bb(adap);
X if (timeout) {
@@ -435,60 +364,68 @@
X "Timeout waiting for BB in pcf_xfer\n");)
X return -EIO;
X }
+
+ for (i = 0;ret >= 0 && i < num; i++) {
+ pmsg = &msgs[i];
+
+ DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+ pmsg->flags & I2C_M_RD ? "read" : "write",
+ pmsg->len, pmsg->addr, i + 1, num);)
X
- /* Send address here if Write */
- if (!(pmsg->flags & I2C_M_RD)) {
X ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
- }
- /* Send START */
- i2c_start(adap);
+
+ /* Send START */
+ if (i == 0) {
+ i2c_start(adap);
+ }
X
- /* Wait for PIN (pending interrupt NOT) */
- timeout = wait_for_pin(adap, &status);
- if (timeout) {
- i2c_stop(adap);
- DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
- "for PIN(1) in pcf_xfer\n");)
- return (-EREMOTEIO);
- }
+ /* Wait for PIN (pending interrupt NOT) */
+ timeout = wait_for_pin(adap, &status);
+ if (timeout) {
+ i2c_stop(adap);
+ DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
+ "for PIN(1) in pcf_xfer\n");)
+ return (-EREMOTEIO);
+ }
X
X #ifndef STUB_I2C
- /* Check LRB (last rcvd bit - slave ack) */
- if (status & I2C_PCF_LRB) {
- i2c_stop(adap);
- DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
- return (-EREMOTEIO);
- }
+ /* Check LRB (last rcvd bit - slave ack) */
+ if (status & I2C_PCF_LRB) {
+ i2c_stop(adap);
+ DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
+ return (-EREMOTEIO);
+ }
X #endif
X
- DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
- i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
+ DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
+ i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
X
- /* Read */
- if (pmsg->flags & I2C_M_RD) {
+ /* Read */
+ if (pmsg->flags & I2C_M_RD) {
+ /* read bytes into buffer*/
+ ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
+ (i + 1 == num));
X
- /* read bytes into buffer*/
- ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len);
-
- if (ret != pmsg->len) {
- DEB2(printk("i2c-algo-pcf.o: fail: "
- "only read %d bytes.\n",ret));
- } else {
- DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
- }
- } else { /* Write */
-
- /* Write bytes from buffer */
- ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
+ if (ret != pmsg->len) {
+ DEB2(printk("i2c-algo-pcf.o: fail: "
+ "only read %d bytes.\n",ret));
+ } else {
+ DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
+ }
+ } else { /* Write */
+ ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
+ (i + 1 == num));
X
- if (ret != pmsg->len) {
- DEB2(printk("i2c-algo-pcf.o: fail: "
- "only wrote %d bytes.\n",ret));
- } else {
- DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+ if (ret != pmsg->len) {
+ DEB2(printk("i2c-algo-pcf.o: fail: "
+ "only wrote %d bytes.\n",ret));
+ } else {
+ DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+ }
X }
X }
- return (num);
+
+ return (i);
X }
X
X static int algo_control(struct i2c_adapter *adapter,
@@ -524,12 +461,6 @@
X int i, status;
X struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
X
- if (pcf_test) {
- int ret = test_bus(pcf_adap, adap->name);
- if (ret<0)
- return -ENODEV;
- }
-
X DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n",
X adap->name));
X
@@ -538,21 +469,29 @@
X adap->id |= pcf_algo.id;
X adap->algo = &pcf_algo;
X
- adap->timeout = 100; /* default values, should */
+ adap->timeout = 100; /* default values, should */
X adap->retries = 3; /* be replaced by defines */
X
+ if ((i = pcf_init_8584(pcf_adap))) {
+ return i;
+ }
+
X #ifdef MODULE
X MOD_INC_USE_COUNT;
X #endif
X
X i2c_add_adapter(adap);
- pcf_init_8584(pcf_adap);
X
X /* scan bus */
X if (pcf_scan) {
X printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",
X adap->name);
X for (i = 0x00; i < 0xff; i+=2) {
+ if (wait_for_bb(pcf_adap)) {
+ printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n",
+ adap->name);
+ break;
+ }
X i2c_outb(pcf_adap, i);
X i2c_start(pcf_adap);
X if ((wait_for_pin(pcf_adap, &status) >= 0) &&
@@ -598,11 +537,9 @@
X MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");


X MODULE_LICENSE("GPL");
X

-MODULE_PARM(pcf_test, "i");
X MODULE_PARM(pcf_scan, "i");
X MODULE_PARM(i2c_debug,"i");
X
-MODULE_PARM_DESC(pcf_test, "Test if the I2C bus is available");
X MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");
X MODULE_PARM_DESC(i2c_debug,
X "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- v2.4.12/linux/drivers/i2c/i2c-core.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-core.c Thu Oct 11 08:05:47 2001
@@ -20,7 +20,7 @@
X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi>.
X All SMBus-related things are written by Frodo Looijaard <fro...@dds.nl> */
X
-/* $Id: i2c-core.c,v 1.58 2000/10/29 22:57:38 frodo Exp $ */
+/* $Id: i2c-core.c,v 1.64 2001/08/13 01:35:56 mds Exp $ */
X
X #include <linux/module.h>
X #include <linux/kernel.h>
@@ -248,7 +248,7 @@
X */
X if ((res=client->driver->detach_client(client))) {
X printk("i2c-core.o: adapter %s not "
- "unregisted, because client at "
+ "unregistered, because client at "
X "address %02x can't be detached. ",
X adap->name, client->addr);
X goto ERROR0;
@@ -563,6 +563,7 @@
X if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)
X return adapters[j]->clients[i];
X }
+ i = 0;
X }
X
X return 0;
@@ -658,7 +659,7 @@
X int i,j,k,order_nr,len=0,len_total;
X int order[I2C_CLIENT_MAX];
X
- if (count < 0)
+ if (count > 4000)
X return -EINVAL;
X len_total = file->f_pos + count;
X /* Too bad if this gets longer (unlikely) */
@@ -1277,14 +1278,41 @@
X }
X
X #ifndef MODULE
+#ifdef CONFIG_I2C_CHARDEV
X extern int i2c_dev_init(void);
+#endif
+#ifdef CONFIG_I2C_ALGOBIT
X extern int i2c_algo_bit_init(void);
+#endif
+#ifdef CONFIG_I2C_CONFIG_I2C_PHILIPSPAR
X extern int i2c_bitlp_init(void);
+#endif
+#ifdef CONFIG_I2C_ELV
X extern int i2c_bitelv_init(void);
+#endif
+#ifdef CONFIG_I2C_VELLEMAN
X extern int i2c_bitvelle_init(void);
+#endif
+#ifdef CONFIG_I2C_BITVIA
X extern int i2c_bitvia_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGOPCF
X extern int i2c_algo_pcf_init(void);
+#endif
+#ifdef CONFIG_I2C_ELEKTOR
X extern int i2c_pcfisa_init(void);
+#endif
+
+#ifdef CONFIG_I2C_ALGO8XX
+ extern int i2c_algo_8xx_init(void);
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+ extern int i2c_rpx_init(void);
+#endif
+#ifdef CONFIG_I2C_PROC
+ extern int sensors_init(void);
+#endif
X
X /* This is needed for automatic patch generation: sensors code starts here */
X /* This is needed for automatic patch generation: sensors code ends here */
@@ -1317,6 +1345,19 @@
X #endif
X #ifdef CONFIG_I2C_ELEKTOR
X i2c_pcfisa_init();
+#endif
+
+ /* --------------------- 8xx -------- */
+#ifdef CONFIG_I2C_ALGO8XX
+ i2c_algo_8xx_init();
+#endif
+#ifdef CONFIG_I2C_RPXLITE
+ i2c_rpx_init();
+#endif
+
+ /* -------------- proc interface ---- */
+#ifdef CONFIG_I2C_PROC
+ sensors_init();
X #endif
X /* This is needed for automatic patch generation: sensors code starts here */
X /* This is needed for automatic patch generation: sensors code ends here */
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c
--- v2.4.12/linux/drivers/i2c/i2c-dev.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-dev.c Thu Oct 11 08:05:47 2001
@@ -28,7 +28,7 @@
X /* The devfs code is contributed by Philipp Matthias Hahn
X <pmh...@titan.lahn.de> */
X
-/* $Id: i2c-dev.c,v 1.36 2000/09/22 02:19:35 mds Exp $ */
+/* $Id: i2c-dev.c,v 1.40 2001/08/25 01:28:01 mds Exp $ */
X
X #include <linux/config.h>
X #include <linux/kernel.h>
@@ -60,6 +60,9 @@
X
X /* struct file_operations changed too often in the 2.1 series for nice code */
X
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin);
+#endif
X static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
X loff_t *offset);
X static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
@@ -88,7 +91,11 @@
X #if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
X owner: THIS_MODULE,
X #endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+ llseek: i2cdev_lseek,
+#else
X llseek: no_llseek,
+#endif
X read: i2cdev_read,
X write: i2cdev_write,
X ioctl: i2cdev_ioctl,
@@ -126,6 +133,20 @@
X
X static int i2cdev_initialized;
X
+#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9)
+/* Note that the lseek function is called llseek in 2.1 kernels. But things
+ are complicated enough as is. */
+loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin)
+{
+#ifdef DEBUG
+ struct inode *inode = file->f_dentry->d_inode;
+ printk("i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n",
+ MINOR(inode->i_rdev),(long) offset,origin);
+#endif /* DEBUG */
+ return -ESPIPE;
+}
+#endif
+
X static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
X loff_t *offset)
X {
@@ -227,9 +248,6 @@
X sizeof(rdwr_arg)))
X return -EFAULT;
X
- if(rdwr_arg.nmsgs > 2048)
- return -EINVAL;
-
X rdwr_pa = (struct i2c_msg *)
X kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
X GFP_KERNEL);
@@ -505,7 +523,7 @@
X "module not removed.\n");
X return res;
X }
- i2cdev_initialized ++;
+ i2cdev_initialized --;
X }
X
X if (i2cdev_initialized >= 1) {
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-elektor.c linux/drivers/i2c/i2c-elektor.c
--- v2.4.12/linux/drivers/i2c/i2c-elektor.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-elektor.c Thu Oct 11 08:05:47 2001
@@ -22,7 +22,8 @@
X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi> and even
X Frodo Looijaard <fro...@dds.nl> */
X
-/* $Id: i2c-elektor.c,v 1.19 2000/07/25 23:52:17 frodo Exp $ */
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
+ for Alpha Processor Inc. UP-2000(+) boards */
X
X #include <linux/kernel.h>
X #include <linux/ioport.h>
@@ -31,6 +32,7 @@
X #include <linux/slab.h>
X #include <linux/version.h>
X #include <linux/init.h>
+#include <linux/pci.h>
X #include <asm/irq.h>
X #include <asm/io.h>
X
@@ -39,17 +41,20 @@
X #include <linux/i2c-elektor.h>
X #include "i2c-pcf8584.h"
X
-#define DEFAULT_BASE 0x300
-#define DEFAULT_IRQ 0
-#define DEFAULT_CLOCK 0x1c
-#define DEFAULT_OWN 0x55
-
-static int base = 0;
-static int irq = 0;
-static int clock = 0;
-static int own = 0;
-static int i2c_debug=0;
-static struct i2c_pcf_isa gpi;
+#define DEFAULT_BASE 0x330
+
+static int base = 0;
+static int irq = 0;
+static int clock = 0x1c;
+static int own = 0x55;
+static int mmapped = 0;
+static int i2c_debug = 0;
+
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code -
+ this module in real supports only one device, due to missing arguments
+ in some functions, called from the algo-pcf module. Sometimes it's
+ need to be rewriten - but for now just remove this for simpler reading */
+
X #if (LINUX_VERSION_CODE < 0x020301)
X static struct wait_queue *pcf_wait = NULL;
X #else
@@ -63,81 +68,63 @@
X #define DEB3(x) if (i2c_debug>=3) x
X #define DEBE(x) x /* error messages */
X
-
-/* --- Convenience defines for the i2c port: */
-#define BASE ((struct i2c_pcf_isa *)(data))->pi_base
-#define DATA BASE /* Adapter data port */
-#define CTRL (BASE+1) /* Adapter control port */
-
X /* ----- local functions ---------------------------------------------- */
X
X static void pcf_isa_setbyte(void *data, int ctl, int val)
X {
- unsigned long j = jiffies + 10;
+ int address = ctl ? (base + 1) : base;
X
- if (ctl) {
- if (gpi.pi_irq > 0) {
- DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n",
- val|I2C_PCF_ENI));
- DEB3({while (jiffies < j) schedule();})
- outb(val | I2C_PCF_ENI, CTRL);
- } else {
- DEB3(printk("i2c-elektor.o: Write Ctrl 0x%02X\n", val|I2C_PCF_ENI));
- DEB3({while (jiffies < j) schedule();})
- outb(val|I2C_PCF_ENI, CTRL);
- }
- } else {
- DEB3(printk("i2c-elektor.o: Write Data 0x%02X\n", val&0xff));
- DEB3({while (jiffies < j) schedule();})
- outb(val, DATA);
+ if (ctl && irq) {
+ val |= I2C_PCF_ENI;
+ }
+
+ DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+
+ switch (mmapped) {
+ case 0: /* regular I/O */
+ outb(val, address);
+ break;
+ case 2: /* double mapped I/O needed for UP2000 board,
+ I don't know why this... */
+ writeb(val, address);
+ /* fall */
+ case 1: /* memory mapped I/O */
+ writeb(val, address);


+ break;
X }
X }
X

X static int pcf_isa_getbyte(void *data, int ctl)
X {
- int val;
+ int address = ctl ? (base + 1) : base;
+ int val = mmapped ? readb(address) : inb(address);
+
+ DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
X
- if (ctl) {
- val = inb(CTRL);
- DEB3(printk("i2c-elektor.o: Read Ctrl 0x%02X\n", val));
- } else {
- val = inb(DATA);
- DEB3(printk("i2c-elektor.o: Read Data 0x%02X\n", val));
- }
X return (val);
X }
X
X static int pcf_isa_getown(void *data)
X {
- return (gpi.pi_own);
+ return (own);
X }
X
X
X static int pcf_isa_getclock(void *data)
X {
- return (gpi.pi_clock);
-}
-
-
-
-#if 0
-static void pcf_isa_sleep(unsigned long timeout)
-{
- schedule_timeout( timeout * HZ);
+ return (clock);
X }
-#endif
-
X
X static void pcf_isa_waitforpin(void) {
X
X int timeout = 2;
X
- if (gpi.pi_irq > 0) {
+ if (irq > 0) {
X cli();
- if (pcf_pending == 0) {
- interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
- } else
- pcf_pending = 0;
+ if (pcf_pending == 0) {
+ interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
+ } else
+ pcf_pending = 0;
X sti();
X } else {
X udelay(100);
@@ -153,30 +140,34 @@
X
X static int pcf_isa_init(void)
X {
- if (check_region(gpi.pi_base, 2) < 0 ) {
- return -ENODEV;
- } else {
- request_region(gpi.pi_base, 2, "i2c (isa bus adapter)");
+ if (!mmapped) {
+ if (check_region(base, 2) < 0 ) {
+ printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base);
+ return -ENODEV;
+ } else {
+ request_region(base, 2, "i2c (isa bus adapter)");
+ }
X }
- if (gpi.pi_irq > 0) {
- if (request_irq(gpi.pi_irq, pcf_isa_handler, 0, "PCF8584", 0)
- < 0) {
- printk("i2c-elektor.o: Request irq%d failed\n", gpi.pi_irq);
- gpi.pi_irq = 0;
- } else
- enable_irq(gpi.pi_irq);
+ if (irq > 0) {
+ if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
+ printk("i2c-elektor.o: Request irq%d failed\n", irq);
+ irq = 0;
+ } else
+ enable_irq(irq);
X }


X return 0;
X }
X

X
-static void pcf_isa_exit(void)
+static void __exit pcf_isa_exit(void)
X {
- if (gpi.pi_irq > 0) {
- disable_irq(gpi.pi_irq);
- free_irq(gpi.pi_irq, 0);
+ if (irq > 0) {
+ disable_irq(irq);
+ free_irq(irq, 0);
+ }
+ if (!mmapped) {
+ release_region(base , 2);
X }
- release_region(gpi.pi_base , 2);
X }
X
X
@@ -217,7 +208,7 @@
X pcf_isa_getown,
X pcf_isa_getclock,
X pcf_isa_waitforpin,
- 80, 80, 100, /* waits, timeout */
+ 10, 10, 100, /* waits, timeout */
X };
X
X static struct i2c_adapter pcf_isa_ops = {
@@ -233,31 +224,61 @@
X
X int __init i2c_pcfisa_init(void)
X {
+#ifdef __alpha__
+ /* check to see we have memory mapped PCF8584 connected to the
+ Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+ if ((base == 0) && pci_present()) {
+
+ struct pci_dev *cy693_dev =
+ pci_find_device(PCI_VENDOR_ID_CONTAQ,
+ PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+
+ if (cy693_dev) {
+ char config;
+ /* yeap, we've found cypress, let's check config */
+ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+
+ DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+
+ /* UP2000 board has this register set to 0xe1,
+ but the most significant bit as seems can be
+ reset during the proper initialisation
+ sequence if guys from API decides to do that
+ (so, we can even enable Tsunami Pchip
+ window for the upper 1 Gb) */
+
+ /* so just check for ROMCS at 0xe0000,
+ ROMCS enabled for writes
+ and external XD Bus buffer in use. */
+ if ((config & 0x7f) == 0x61) {
+ /* seems to be UP2000 like board */
+ base = 0xe0000;
+ /* I don't know why we need to
+ write twice */
+ mmapped = 2;
+ /* UP2000 drives ISA with
+ 8.25 MHz (PCI/4) clock
+ (this can be read from cypress) */
+ clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+ printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+ }
+ }
+ }
+ }
+#endif
X
- struct i2c_pcf_isa *pisa = &gpi;
+ /* sanity checks for mmapped I/O */
+ if (mmapped && base < 0xc8000) {
+ printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+ return -ENODEV;
+ }
X
X printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n");
- if (base == 0)
- pisa->pi_base = DEFAULT_BASE;
- else
- pisa->pi_base = base;
-
- if (irq == 0)
- pisa->pi_irq = DEFAULT_IRQ;
- else
- pisa->pi_irq = irq;
-
- if (clock == 0)
- pisa->pi_clock = DEFAULT_CLOCK;
- else
- pisa->pi_clock = clock;
-
- if (own == 0)
- pisa->pi_own = DEFAULT_OWN;
- else
- pisa->pi_own = own;
X
- pcf_isa_data.data = (void *)pisa;
+ if (base == 0) {
+ base = DEFAULT_BASE;
+ }
+
X #if (LINUX_VERSION_CODE >= 0x020301)
X init_waitqueue_head(&pcf_wait);
X #endif
@@ -267,7 +288,9 @@
X } else {
X return -ENODEV;
X }
- printk("i2c-elektor.o: found device at %#x.\n", pisa->pi_base);
+
+ printk("i2c-elektor.o: found device at %#x.\n", base);
+


X return 0;
X }
X

@@ -283,7 +306,8 @@
X MODULE_PARM(irq, "i");
X MODULE_PARM(clock, "i");
X MODULE_PARM(own, "i");
-MODULE_PARM(i2c_debug,"i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
X
X int init_module(void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-elv.c linux/drivers/i2c/i2c-elv.c
--- v2.4.12/linux/drivers/i2c/i2c-elv.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-elv.c Thu Oct 11 08:05:47 2001
@@ -21,7 +21,7 @@
X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi> and even
X Frodo Looijaard <fro...@dds.nl> */
X
-/* $Id: i2c-elv.c,v 1.16 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elv.c,v 1.17 2001/07/29 02:44:25 mds Exp $ */
X
X #include <linux/kernel.h>
X #include <linux/module.h>
@@ -115,7 +115,7 @@


X return 0;
X }
X

-static void bit_elv_exit(void)
+static void __exit bit_elv_exit(void)
X {
X release_region( base , (base == 0x3bc)? 3 : 8 );
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-proc.c linux/drivers/i2c/i2c-proc.c
--- v2.4.12/linux/drivers/i2c/i2c-proc.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2c/i2c-proc.c Thu Oct 11 08:05:47 2001
@@ -0,0 +1,906 @@
+/*
+ i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
+ monitoring
+ Copyright (c) 1998 - 2001 Frodo Looijaard <fro...@dds.nl> and
+ Mark D. Studebaker <mdsx...@yahoo.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.
+*/
+
+/*
+ This driver puts entries in /proc/sys/dev/sensors for each I2C device
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-proc.h>
+
+#include <linux/init.h>
+
+/* FIXME need i2c versioning */
+#define LM_DATE "20010825"
+#define LM_VERSION "2.6.1"
+
+#ifndef THIS_MODULE
+#define THIS_MODULE NULL
+#endif
+
+static int i2c_create_name(char **name, const char *prefix,
+ struct i2c_adapter *adapter, int addr);
+static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
+ long *results, int magnitude);
+static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+ long *results, int magnitude);
+static int i2c_proc_chips(ctl_table * ctl, int write,
+ struct file *filp, void *buffer,
+ size_t * lenp);
+static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+ void *oldval, size_t * oldlenp,
+ void *newval, size_t newlen,
+ void **context);
+
+int __init sensors_init(void);
+
+#define SENSORS_ENTRY_MAX 20
+static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
+
+static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
+static unsigned short i2c_inodes[SENSORS_ENTRY_MAX];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
+static void i2c_fill_inode(struct inode *inode, int fill);
+static void i2c_dir_fill_inode(struct inode *inode, int fill);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) */
+
+static ctl_table sysctl_table[] = {
+ {CTL_DEV, "dev", NULL, 0, 0555},
+ {0},
+ {DEV_SENSORS, "sensors", NULL, 0, 0555},
+ {0},
+ {0, NULL, NULL, 0, 0555},
+ {0}
+};
+
+static ctl_table i2c_proc_dev_sensors[] = {
+ {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
+ &i2c_sysctl_chips},
+ {0}
+};
+
+static ctl_table i2c_proc_dev[] = {
+ {DEV_SENSORS, "sensors", NULL, 0, 0555, i2c_proc_dev_sensors},
+ {0},
+};
+
+
+static ctl_table i2c_proc[] = {
+ {CTL_DEV, "dev", NULL, 0, 0555, i2c_proc_dev},
+ {0}
+};
+
+
+static struct ctl_table_header *i2c_proc_header;
+static int i2c_initialized;
+
+/* This returns a nice name for a new directory; for example lm78-isa-0310
+ (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
+ a LM75 chip on the third i2c bus at address 0x4e).
+ name is allocated first. */
+int i2c_create_name(char **name, const char *prefix,
+ struct i2c_adapter *adapter, int addr)
+{
+ char name_buffer[50];
+ int id;
+ if (i2c_is_isa_adapter(adapter))
+ sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
+ else {
+ if ((id = i2c_adapter_id(adapter)) < 0)
+ return -ENOENT;
+ sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
+ }
+ *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
+ strcpy(*name, name_buffer);


+ return 0;
+}
+

+/* This rather complex function must be called when you want to add an entry
+ to /proc/sys/dev/sensors/chips. It also creates a new directory within
+ /proc/sys/dev/sensors/.
+ ctl_template should be a template of the newly created directory. It is
+ copied in memory. The extra2 field of each file is set to point to client.
+ If any driver wants subdirectories within the newly created directory,
+ this function must be updated!
+ controlling_mod is the controlling module. It should usually be
+ THIS_MODULE when calling. Note that this symbol is not defined in
+ kernels before 2.3.13; define it to NULL in that case. We will not use it
+ for anything older than 2.3.27 anyway. */
+int i2c_register_entry(struct i2c_client *client, const char *prefix,


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 14'
echo 'File patch-2.4.13 is continued in part 15'
echo "15" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:45 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part15

#!/bin/sh -x
# this is part 15 of a 53 - part archive


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

if test "$Scheck" != 15; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ ctl_table * ctl_template,
+ struct module *controlling_mod)
+{
+ int i, res, len, id;
+ ctl_table *new_table;
+ char *name;
+ struct ctl_table_header *new_header;
+
+ if ((res = i2c_create_name(&name, prefix, client->adapter,
+ client->addr))) return res;
+
+ for (id = 0; id < SENSORS_ENTRY_MAX; id++)
+ if (!i2c_entries[id]) {
+ break;
+ }
+ if (id == SENSORS_ENTRY_MAX) {
+ kfree(name);
+ return -ENOMEM;
+ }
+ id += 256;
+
+ len = 0;
+ while (ctl_template[len].procname)
+ len++;
+ len += 7;
+ if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
+ kfree(name);
+ return -ENOMEM;
+ }
+
+ memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
+ new_table[0].child = &new_table[2];
+ new_table[2].child = &new_table[4];
+ new_table[4].child = &new_table[6];
+ new_table[4].procname = name;
+ new_table[4].ctl_name = id;
+ memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
+ for (i = 6; i < len; i++)
+ new_table[i].extra2 = client;
+
+ if (!(new_header = register_sysctl_table(new_table, 0))) {
+ kfree(new_table);
+ kfree(name);
+ return -ENOMEM;
+ }
+
+ i2c_entries[id - 256] = new_header;
+
+ i2c_clients[id - 256] = client;
+#ifdef DEBUG
+ if (!new_header || !new_header->ctl_table ||
+ !new_header->ctl_table->child ||
+ !new_header->ctl_table->child->child ||
+ !new_header->ctl_table->child->child->de) {
+ printk
+ ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
+ return id;
+ }
+#endif /* DEBUG */
+ i2c_inodes[id - 256] =
+ new_header->ctl_table->child->child->de->low_ino;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27))
+ new_header->ctl_table->child->child->de->owner = controlling_mod;
+#else
+ new_header->ctl_table->child->child->de->fill_inode =
+ &i2c_dir_fill_inode;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */
+
+ return id;
+}
+
+void i2c_deregister_entry(int id)
+{
+ ctl_table *table;
+ char *temp;
+ id -= 256;
+ if (i2c_entries[id]) {
+ table = i2c_entries[id]->ctl_table;
+ unregister_sysctl_table(i2c_entries[id]);
+ /* 2-step kfree needed to keep gcc happy about const points */
+ (const char *) temp = table[4].procname;
+ kfree(temp);
+ kfree(table);
+ i2c_entries[id] = NULL;
+ i2c_clients[id] = NULL;
+ }
+}
+
+/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o
+ impossible if some process still uses it or some file in it */
+void i2c_fill_inode(struct inode *inode, int fill)
+{
+ if (fill)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
+}
+
+/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
+ the corresponding module impossible if some process still uses it or
+ some file in it */
+void i2c_dir_fill_inode(struct inode *inode, int fill)
+{
+ int i;
+ struct i2c_client *client;
+
+#ifdef DEBUG
+ if (!inode) {
+ printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n");
+ return;
+ }
+#endif /* def DEBUG */
+
+ for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+ if (i2c_clients[i]
+ && (i2c_inodes[i] == inode->i_ino)) break;
+#ifdef DEBUG
+ if (i == SENSORS_ENTRY_MAX) {
+ printk
+ ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n",
+ inode->i_ino);
+ return;
+ }
+#endif /* def DEBUG */
+ client = i2c_clients[i];
+ if (fill)
+ client->driver->inc_use(client);
+ else
+ client->driver->dec_use(client);
+}
+
+int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
+ void *buffer, size_t * lenp)
+{
+ char BUF[SENSORS_PREFIX_MAX + 30];
+ int buflen, curbufsize, i;
+ struct ctl_table *client_tbl;
+
+ if (write)
+ return 0;
+
+ /* If buffer is size 0, or we try to read when not at the start, we
+ return nothing. Note that I think writing when not at the start
+ does not work either, but anyway, this is straight from the kernel
+ sources. */
+ if (!*lenp || (filp->f_pos && !write)) {
+ *lenp = 0;
+ return 0;
+ }
+ curbufsize = 0;
+ for (i = 0; i < SENSORS_ENTRY_MAX; i++)
+ if (i2c_entries[i]) {
+ client_tbl =
+ i2c_entries[i]->ctl_table->child->child;
+ buflen =
+ sprintf(BUF, "%d\t%s\n", client_tbl->ctl_name,
+ client_tbl->procname);
+ if (buflen + curbufsize > *lenp)
+ buflen = *lenp - curbufsize;
+ if(copy_to_user(buffer, BUF, buflen))
+ return -EFAULT;
+ curbufsize += buflen;
+ (char *) buffer += buflen;
+ }
+ *lenp = curbufsize;
+ filp->f_pos += curbufsize;


+ return 0;
+}
+

+int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
+ void *oldval, size_t * oldlenp, void *newval,
+ size_t newlen, void **context)
+{
+ struct i2c_chips_data data;
+ int i, oldlen, nrels, maxels,ret=0;
+ struct ctl_table *client_tbl;
+
+ if (oldval && oldlenp && !((ret = get_user(oldlen, oldlenp))) &&
+ oldlen) {
+ maxels = oldlen / sizeof(struct i2c_chips_data);
+ nrels = 0;
+ for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels);
+ i++)
+ if (i2c_entries[i]) {
+ client_tbl =
+ i2c_entries[i]->ctl_table->child->
+ child;
+ data.sysctl_id = client_tbl->ctl_name;
+ strcpy(data.name, client_tbl->procname);
+ if(copy_to_user(oldval, &data,
+ sizeof(struct
+ i2c_chips_data)))
+ return -EFAULT;
+ (char *) oldval +=
+ sizeof(struct i2c_chips_data);
+ nrels++;
+ }
+ oldlen = nrels * sizeof(struct i2c_chips_data);
+ if(put_user(oldlen, oldlenp))
+ return -EFAULT;
+ }
+ return ret;
+}
+
+
+/* This funcion reads or writes a 'real' value (encoded by the combination
+ of an integer and a magnitude, the last is the power of ten the value
+ should be divided with) to a /proc/sys directory. To use this function,
+ you must (before registering the ctl_table) set the extra2 field to the
+ client, and the extra1 field to a function of the form:
+ void func(struct i2c_client *client, int operation, int ctl_name,
+ int *nrels_mag, long *results)
+ This function can be called for three values of operation. If operation
+ equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in
+ nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+ be read into results. nrels_mag should return the number of elements
+ read; the maximum number is put in it on entry. Finally, if operation
+ equals SENSORS_PROC_REAL_WRITE, the values in results should be
+ written to the chip. nrels_mag contains on entry the number of elements
+ found.
+ In all cases, client points to the client we wish to interact with,
+ and ctl_name is the SYSCTL id of the file we are accessing. */
+int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+ void *buffer, size_t * lenp)
+{
+#define MAX_RESULTS 32
+ int mag, nrels = MAX_RESULTS;
+ long results[MAX_RESULTS];
+ i2c_real_callback callback = ctl->extra1;
+ struct i2c_client *client = ctl->extra2;
+ int res;
+
+ /* If buffer is size 0, or we try to read when not at the start, we
+ return nothing. Note that I think writing when not at the start
+ does not work either, but anyway, this is straight from the kernel
+ sources. */
+ if (!*lenp || (filp->f_pos && !write)) {
+ *lenp = 0;


+ return 0;
+ }
+

+ /* Get the magnitude */
+ callback(client, SENSORS_PROC_REAL_INFO, ctl->ctl_name, &mag,
+ NULL);
+
+ if (write) {
+ /* Read the complete input into results, converting to longs */
+ res = i2c_parse_reals(&nrels, buffer, *lenp, results, mag);
+ if (res)
+ return res;
+
+ if (!nrels)
+ return 0;
+
+ /* Now feed this information back to the client */
+ callback(client, SENSORS_PROC_REAL_WRITE, ctl->ctl_name,
+ &nrels, results);
+
+ filp->f_pos += *lenp;
+ return 0;
+ } else { /* read */
+ /* Get the information from the client into results */
+ callback(client, SENSORS_PROC_REAL_READ, ctl->ctl_name,
+ &nrels, results);
+
+ /* And write them to buffer, converting to reals */
+ res = i2c_write_reals(nrels, buffer, lenp, results, mag);
+ if (res)
+ return res;
+ filp->f_pos += *lenp;


+ return 0;
+ }
+}
+

+/* This function is equivalent to i2c_proc_real, only it interacts with
+ the sysctl(2) syscall, and returns no reals, but integers */
+int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+ void *oldval, size_t * oldlenp, void *newval,
+ size_t newlen, void **context)
+{
+ long results[MAX_RESULTS];
+ int oldlen, nrels = MAX_RESULTS,ret=0;
+ i2c_real_callback callback = table->extra1;
+ struct i2c_client *client = table->extra2;
+
+ /* Check if we need to output the old values */
+ if (oldval && oldlenp && !((ret=get_user(oldlen, oldlenp))) && oldlen) {
+ callback(client, SENSORS_PROC_REAL_READ, table->ctl_name,
+ &nrels, results);
+
+ /* Note the rounding factor! */
+ if (nrels * sizeof(long) < oldlen)
+ oldlen = nrels * sizeof(long);
+ oldlen = (oldlen / sizeof(long)) * sizeof(long);
+ if(copy_to_user(oldval, results, oldlen))
+ return -EFAULT;
+ if(put_user(oldlen, oldlenp))


+ return -EFAULT;
+ }
+

+ if (newval && newlen) {
+ /* Note the rounding factor! */
+ newlen -= newlen % sizeof(long);
+ nrels = newlen / sizeof(long);
+ if(copy_from_user(results, newval, newlen))
+ return -EFAULT;
+
+ /* Get the new values back to the client */
+ callback(client, SENSORS_PROC_REAL_WRITE, table->ctl_name,
+ &nrels, results);


+ }
+ return ret;
+}
+
+

+/* nrels contains initially the maximum number of elements which can be
+ put in results, and finally the number of elements actually put there.
+ A magnitude of 1 will multiply everything with 10; etc.
+ buffer, bufsize is the character buffer we read from and its length.
+ results will finally contain the parsed integers.
+
+ Buffer should contain several reals, separated by whitespace. A real
+ has the following syntax:
+ [ Minus ] Digit* [ Dot Digit* ]
+ (everything between [] is optional; * means zero or more).
+ When the next character is unparsable, everything is skipped until the
+ next whitespace.
+
+ WARNING! This is tricky code. I have tested it, but there may still be
+ hidden bugs in it, even leading to crashes and things!
+*/
+int i2c_parse_reals(int *nrels, void *buffer, int bufsize,


+ long *results, int magnitude)

+{
+ int maxels, min, mag;
+ long res,ret=0;
+ char nextchar = 0;
+
+ maxels = *nrels;
+ *nrels = 0;
+
+ while (bufsize && (*nrels < maxels)) {
+
+ /* Skip spaces at the start */
+ while (bufsize &&
+ !((ret=get_user(nextchar, (char *) buffer))) &&
+ isspace((int) nextchar)) {
+ bufsize--;
+ ((char *) buffer)++;
+ }
+
+ if (ret)
+ return -EFAULT;
+ /* Well, we may be done now */
+ if (!bufsize)
+ return 0;
+
+ /* New defaults for our result */
+ min = 0;
+ res = 0;
+ mag = magnitude;
+
+ /* Check for a minus */
+ if (!((ret=get_user(nextchar, (char *) buffer)))
+ && (nextchar == '-')) {
+ min = 1;
+ bufsize--;
+ ((char *) buffer)++;
+ }
+ if (ret)
+ return -EFAULT;
+
+ /* Digits before a decimal dot */
+ while (bufsize &&
+ !((ret=get_user(nextchar, (char *) buffer))) &&
+ isdigit((int) nextchar)) {
+ res = res * 10 + nextchar - '0';
+ bufsize--;
+ ((char *) buffer)++;
+ }
+ if (ret)
+ return -EFAULT;
+
+ /* If mag < 0, we must actually divide here! */
+ while (mag < 0) {
+ res = res / 10;
+ mag++;
+ }
+
+ if (bufsize && (nextchar == '.')) {
+ /* Skip the dot */
+ bufsize--;
+ ((char *) buffer)++;
+
+ /* Read digits while they are significant */
+ while (bufsize && (mag > 0) &&
+ !((ret=get_user(nextchar, (char *) buffer))) &&
+ isdigit((int) nextchar)) {
+ res = res * 10 + nextchar - '0';
+ mag--;
+ bufsize--;
+ ((char *) buffer)++;
+ }
+ if (ret)
+ return -EFAULT;
+ }
+ /* If we are out of data, but mag > 0, we need to scale here */
+ while (mag > 0) {
+ res = res * 10;
+ mag--;
+ }
+
+ /* Skip everything until we hit whitespace */
+ while (bufsize &&
+ !((ret=get_user(nextchar, (char *) buffer))) &&
+ isspace((int) nextchar)) {
+ bufsize--;
+ ((char *) buffer)++;
+ }
+ if (ret)
+ return -EFAULT;
+
+ /* Put res in results */
+ results[*nrels] = (min ? -1 : 1) * res;
+ (*nrels)++;
+ }
+
+ /* Well, there may be more in the buffer, but we need no more data.
+ Ignore anything that is left. */


+ return 0;
+}
+

+int i2c_write_reals(int nrels, void *buffer, int *bufsize,


+ long *results, int magnitude)

+{
+#define BUFLEN 20
+ char BUF[BUFLEN + 1]; /* An individual representation should fit! */
+ char printfstr[10];
+ int nr = 0;
+ int buflen, mag, times;
+ int curbufsize = 0;
+
+ while ((nr < nrels) && (curbufsize < *bufsize)) {
+ mag = magnitude;
+
+ if (nr != 0) {
+ if(put_user(' ', (char *) buffer))
+ return -EFAULT;
+ curbufsize++;
+ ((char *) buffer)++;
+ }
+
+ /* Fill BUF with the representation of the next string */
+ if (mag <= 0) {
+ buflen = sprintf(BUF, "%ld", results[nr]);
+ if (buflen < 0) { /* Oops, a sprintf error! */
+ *bufsize = 0;
+ return -EINVAL;
+ }
+ while ((mag < 0) && (buflen < BUFLEN)) {
+ BUF[buflen++] = '0';
+ mag++;
+ }
+ BUF[buflen] = 0;
+ } else {
+ times = 1;
+ for (times = 1; mag-- > 0; times *= 10);
+ if (results[nr] < 0) {
+ BUF[0] = '-';
+ buflen = 1;
+ } else
+ buflen = 0;
+ strcpy(printfstr, "%ld.%0Xld");
+ printfstr[6] = magnitude + '0';
+ buflen +=
+ sprintf(BUF + buflen, printfstr,
+ abs(results[nr]) / times,
+ abs(results[nr]) % times);
+ if (buflen < 0) { /* Oops, a sprintf error! */
+ *bufsize = 0;


+ return -EINVAL;
+ }
+ }
+

+ /* Now copy it to the user-space buffer */
+ if (buflen + curbufsize > *bufsize)
+ buflen = *bufsize - curbufsize;
+ if(copy_to_user(buffer, BUF, buflen))
+ return -EFAULT;
+ curbufsize += buflen;
+ (char *) buffer += buflen;
+
+ nr++;
+ }
+ if (curbufsize < *bufsize) {
+ if(put_user('\n', (char *) buffer))
+ return -EFAULT;
+ curbufsize++;
+ }
+ *bufsize = curbufsize;


+ return 0;
+}
+
+

+/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */
+int i2c_detect(struct i2c_adapter *adapter,
+ struct i2c_address_data *address_data,
+ i2c_found_addr_proc * found_proc)
+{
+ int addr, i, found, j, err;
+ struct i2c_force_data *this_force;
+ int is_isa = i2c_is_isa_adapter(adapter);
+ int adapter_id =
+ is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter);
+
+ /* Forget it if we can't probe using SMBUS_QUICK */
+ if ((!is_isa)
+ && !i2c_check_functionality(adapter,
+ I2C_FUNC_SMBUS_QUICK)) return -1;
+
+ for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
+ if ((is_isa && check_region(addr, 1)) ||
+ (!is_isa && i2c_check_addr(adapter, addr)))
+ continue;
+
+ /* If it is in one of the force entries, we don't do any
+ detection at all */
+ found = 0;


+ for (i = 0;

+ !found
+ && (this_force =
+ address_data->forces + i, this_force->force); i++) {
+ for (j = 0;
+ !found
+ && (this_force->force[j] != SENSORS_I2C_END);
+ j += 2) {
+ if (
+ ((adapter_id == this_force->force[j])
+ ||
+ ((this_force->
+ force[j] == SENSORS_ANY_I2C_BUS)
+ && !is_isa))
+ && (addr == this_force->force[j + 1])) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
+ adapter_id, addr);
+#endif
+ if (
+ (err =
+ found_proc(adapter, addr, 0,
+ this_force->
+ kind))) return err;
+ found = 1;
+ }
+ }
+ }
+ if (found)
+ continue;
+
+ /* If this address is in one of the ignores, we can forget about it
+ right now */


+ for (i = 0;

+ !found
+ && (address_data->ignore[i] != SENSORS_I2C_END);
+ i += 2) {
+ if (
+ ((adapter_id == address_data->ignore[i])
+ ||
+ ((address_data->
+ ignore[i] == SENSORS_ANY_I2C_BUS)
+ && !is_isa))
+ && (addr == address_data->ignore[i + 1])) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found ignore parameter for adapter %d, "
+ "addr %04x\n", adapter_id, addr);
+#endif
+ found = 1;
+ }


+ }
+ for (i = 0;

+ !found
+ && (address_data->ignore_range[i] != SENSORS_I2C_END);
+ i += 3) {
+ if (
+ ((adapter_id == address_data->ignore_range[i])
+ ||
+ ((address_data->
+ ignore_range[i] ==
+ SENSORS_ANY_I2C_BUS) & !is_isa))
+ && (addr >= address_data->ignore_range[i + 1])
+ && (addr <= address_data->ignore_range[i + 2])) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found ignore_range parameter for adapter %d, "
+ "addr %04x\n", adapter_id, addr);
+#endif
+ found = 1;
+ }
+ }
+ if (found)
+ continue;
+
+ /* Now, we will do a detection, but only if it is in the normal or
+ probe entries */
+ if (is_isa) {


+ for (i = 0;

+ !found
+ && (address_data->normal_isa[i] !=
+ SENSORS_ISA_END); i += 1) {
+ if (addr == address_data->normal_isa[i]) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found normal isa entry for adapter %d, "
+ "addr %04x\n", adapter_id,
+ addr);
+#endif
+ found = 1;
+ }


+ }
+ for (i = 0;

+ !found
+ && (address_data->normal_isa_range[i] !=
+ SENSORS_ISA_END); i += 3) {
+ if ((addr >=
+ address_data->normal_isa_range[i])
+ && (addr <=
+ address_data->normal_isa_range[i + 1])
+ &&
+ ((addr -
+ address_data->normal_isa_range[i]) %
+ address_data->normal_isa_range[i + 2] ==
+ 0)) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found normal isa_range entry for adapter %d, "
+ "addr %04x", adapter_id, addr);
+#endif
+ found = 1;
+ }
+ }
+ } else {


+ for (i = 0;

+ !found && (address_data->normal_i2c[i] !=
+ SENSORS_I2C_END); i += 1) {
+ if (addr == address_data->normal_i2c[i]) {
+ found = 1;
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found normal i2c entry for adapter %d, "
+ "addr %02x", adapter_id, addr);
+#endif
+ }


+ }
+ for (i = 0;

+ !found
+ && (address_data->normal_i2c_range[i] !=
+ SENSORS_I2C_END); i += 2) {
+ if ((addr >=
+ address_data->normal_i2c_range[i])
+ && (addr <=
+ address_data->normal_i2c_range[i + 1]))
+ {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found normal i2c_range entry for adapter %d, "
+ "addr %04x\n", adapter_id, addr);
+#endif
+ found = 1;
+ }
+ }
+ }


+
+ for (i = 0;

+ !found && (address_data->probe[i] != SENSORS_I2C_END);
+ i += 2) {
+ if (((adapter_id == address_data->probe[i]) ||
+ ((address_data->
+ probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa))
+ && (addr == address_data->probe[i + 1])) {
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found probe parameter for adapter %d, "
+ "addr %04x\n", adapter_id, addr);
+#endif
+ found = 1;
+ }
+ }
+ for (i = 0; !found &&
+ (address_data->probe_range[i] != SENSORS_I2C_END);
+ i += 3) {
+ if (
+ ((adapter_id == address_data->probe_range[i])
+ ||
+ ((address_data->probe_range[i] ==
+ SENSORS_ANY_I2C_BUS) & !is_isa))
+ && (addr >= address_data->probe_range[i + 1])
+ && (addr <= address_data->probe_range[i + 2])) {
+ found = 1;
+#ifdef DEBUG
+ printk
+ ("i2c-proc.o: found probe_range parameter for adapter %d, "
+ "addr %04x\n", adapter_id, addr);
+#endif
+ }
+ }
+ if (!found)
+ continue;
+
+ /* OK, so we really should examine this address. First check
+ whether there is some client here at all! */
+ if (is_isa ||
+ (i2c_smbus_xfer
+ (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0))
+ if ((err = found_proc(adapter, addr, 0, -1)))
+ return err;


+ }
+ return 0;
+}
+

+int __init sensors_init(void)
+{
+ printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE);
+ i2c_initialized = 0;
+ if (!
+ (i2c_proc_header =
+ register_sysctl_table(i2c_proc, 0))) return -ENOMEM;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1))
+ i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;
+#else
+ i2c_proc_header->ctl_table->child->de->fill_inode =
+ &i2c_fill_inode;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */
+ i2c_initialized++;


+ return 0;
+}
+

+EXPORT_SYMBOL(i2c_deregister_entry);
+EXPORT_SYMBOL(i2c_detect);
+EXPORT_SYMBOL(i2c_proc_real);
+EXPORT_SYMBOL(i2c_register_entry);
+EXPORT_SYMBOL(i2c_sysctl_real);
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Frodo Looijaard <fro...@dds.nl>");
+MODULE_DESCRIPTION("i2c-proc driver");
+MODULE_LICENSE("GPL");
+
+int i2c_cleanup(void)
+{
+ if (i2c_initialized >= 1) {
+ unregister_sysctl_table(i2c_proc_header);
+ i2c_initialized--;


+ }
+ return 0;
+}
+

+int init_module(void)
+{
+ return sensors_init();
+}
+
+int cleanup_module(void)
+{
+ return i2c_cleanup();
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.4.12/linux/drivers/i2c/i2c-velleman.c linux/drivers/i2c/i2c-velleman.c
--- v2.4.12/linux/drivers/i2c/i2c-velleman.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/i2c/i2c-velleman.c Thu Oct 11 08:05:47 2001
@@ -103,7 +103,7 @@


X return 0;
X }
X

-static void bit_velle_exit(void)
+static void __exit bit_velle_exit(void)


X {
X release_region( base , (base == 0x3bc)? 3 : 8 );
X }

diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/Config.in linux/drivers/i2o/Config.in
--- v2.4.12/linux/drivers/i2o/Config.in Wed Apr 12 09:38:53 2000
+++ linux/drivers/i2o/Config.in Wed Dec 31 16:00:00 1969
@@ -1,16 +0,0 @@
-mainmenu_option next_comment
-comment 'I2O device support'
-
-tristate 'I2O support' CONFIG_I2O
-
-if [ "$CONFIG_PCI" = "y" ]; then
- dep_tristate ' I2O PCI support' CONFIG_I2O_PCI $CONFIG_I2O
-fi
-dep_tristate ' I2O Block OSM' CONFIG_I2O_BLOCK $CONFIG_I2O
-if [ "$CONFIG_NET" = "y" ]; then
- dep_tristate ' I2O LAN OSM' CONFIG_I2O_LAN $CONFIG_I2O
-fi
-dep_tristate ' I2O SCSI OSM' CONFIG_I2O_SCSI $CONFIG_I2O $CONFIG_SCSI
-dep_tristate ' I2O /proc support' CONFIG_I2O_PROC $CONFIG_I2O
-
-endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/Makefile linux/drivers/i2o/Makefile
--- v2.4.12/linux/drivers/i2o/Makefile Fri Dec 29 14:07:21 2000
+++ linux/drivers/i2o/Makefile Wed Dec 31 16:00:00 1969
@@ -1,20 +0,0 @@
-#
-# Makefile for the kernel I2O OSM.
-#
-# Note : at this point, these files are compiled on all systems.
-# In the future, some of these should be built conditionally.
-#
-
-O_TARGET := i2o.o
-
-export-objs := i2o_pci.o i2o_core.o i2o_config.o i2o_block.o i2o_lan.o i2o_scsi.o i2o_proc.o
-
-obj-$(CONFIG_I2O_PCI) += i2o_pci.o
-obj-$(CONFIG_I2O) += i2o_core.o i2o_config.o
-obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
-obj-$(CONFIG_I2O_LAN) += i2o_lan.o
-obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o
-obj-$(CONFIG_I2O_PROC) += i2o_proc.o
-
-include $(TOPDIR)/Rules.make
-
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/README linux/drivers/i2o/README
--- v2.4.12/linux/drivers/i2o/README Mon Jun 19 13:30:55 2000
+++ linux/drivers/i2o/README Wed Dec 31 16:00:00 1969
@@ -1,98 +0,0 @@
-
- Linux I2O Support (c) Copyright 1999 Red Hat Software
- and others.
-
- 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.
-
-AUTHORS (so far)
-
-Alan Cox, Building Number Three Ltd.
- Core code, SCSI and Block OSMs
-
-Steve Ralston, LSI Logic Corp.
- Debugging SCSI and Block OSM
-
-Deepak Saxena, Intel Corp.
- Various core/block extensions
- /proc interface, bug fixes
- Ioctl interfaces for control
- Debugging LAN OSM
-
-Philip Rumpf
- Fixed assorted dumb SMP locking bugs
-
-Juha Sievanen, University of Helsinki Finland
- LAN OSM code
- /proc interface to LAN class
- Bug fixes
- Core code extensions
-
-Auvo Häkkinen, University of Helsinki Finland
- LAN OSM code
- /Proc interface to LAN class
- Bug fixes
- Core code extensions
-
-Taneli Vähäkangas, University of Helsinki Finland
- Fixes to i2o_config
-
-CREDITS
-
- This work was made possible by
-
-Red Hat Software
- Funding for the Building #3 part of the project
-
-Symbios Logic (Now LSI)
- Host adapters, hints, known to work platforms when I hit
- compatibility problems
-
-BoxHill Corporation
- Loan of initial FibreChannel disk array used for development work.
-
-European Comission
- Funding the work done by the University of Helsinki
-
-SysKonnect
- Loan of FDDI and Gigabit Ethernet cards
-
-ASUSTeK
- Loan of I2O motherboard
-
-STATUS:
-
-o The core setup works within limits.
-o The scsi layer seems to almost work.
- I'm still chasing down the hang bug.
-o The block OSM is mostly functional
-o LAN OSM works with FDDI and Ethernet cards.
-
-TO DO:
-
-General:
-o Provide hidden address space if asked
-o Long term message flow control
-o PCI IOP's without interrupts are not supported yet
-o Push FAIL handling into the core
-o DDM control interfaces for module load etc
-o Add I2O 2.0 support (Deffered to 2.5 kernel)
-
-Block:
-o Multiple major numbers
-o Read ahead and cache handling stuff. Talk to Ingo and people
-o Power management
-o Finish Media changers
-
-SCSI:
-o Find the right way to associate drives/luns/busses
-
-Lan:
-o Performance tuning
-o Test Fibre Channel code
-
-Tape:
-o Anyone seen anything implementing this ?
- (D.S: Will attempt to do so if spare cycles permit)
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/README.ioctl linux/drivers/i2o/README.ioctl
--- v2.4.12/linux/drivers/i2o/README.ioctl Mon Jun 19 13:30:55 2000
+++ linux/drivers/i2o/README.ioctl Wed Dec 31 16:00:00 1969
@@ -1,394 +0,0 @@
-
-Linux I2O User Space Interface
-rev 0.3 - 04/20/99
-
-=============================================================================
-Originally written by Deepak Saxena(dee...@plexity.net)
-Currently maintained by Deepak Saxena(dee...@plexity.net)
-=============================================================================
-
-I. Introduction
-
-The Linux I2O subsystem provides a set of ioctl() commands that can be
-utilized by user space applications to communicate with IOPs and devices
-on individual IOPs. This document defines the specific ioctl() commands
-that are available to the user and provides examples of their uses.
-
-This document assumes the reader is familiar with or has access to the
-I2O specification as no I2O message parameters are outlined. For information
-on the specification, see http://www.i2osig.org
-
-This document and the I2O user space interface are currently maintained
-by Deepak Saxena. Please send all comments, errata, and bug fixes to
-dee...@csociety.purdue.edu
-
-II. IOP Access
-
-Access to the I2O subsystem is provided through the device file named
-/dev/i2o/ctl. This file is a character file with major number 10 and minor
-number 166. It can be created through the following command:
-
- mknod /dev/i2o/ctl c 10 166
-
-III. Determining the IOP Count
-
- SYNOPSIS
-
- ioctl(fd, I2OGETIOPS, int *count);
-
- u8 count[MAX_I2O_CONTROLLERS];
-
- DESCRIPTION
-
- This function returns the system's active IOP table. count should
- point to a buffer containing MAX_I2O_CONTROLLERS entries. Upon
- returning, each entry will contain a non-zero value if the given
- IOP unit is active, and NULL if it is inactive or non-existent.
-
- RETURN VALUE.
-
- Returns 0 if no errors occur, and -1 otherwise. If an error occurs,
- errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
-
-IV. Getting Hardware Resource Table
-
- SYNOPSIS
-
- ioctl(fd, I2OHRTGET, struct i2o_cmd_hrt *hrt);
-
- struct i2o_cmd_hrtlct
- {
- u32 iop; /* IOP unit number */
- void *resbuf; /* Buffer for result */
- u32 *reslen; /* Buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function returns the Hardware Resource Table of the IOP specified
- by hrt->iop in the buffer pointed to by hrt->resbuf. The actual size of
- the data is written into *(hrt->reslen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(hrt->reslen)
-
-V. Getting Logical Configuration Table
-
- SYNOPSIS
-
- ioctl(fd, I2OLCTGET, struct i2o_cmd_lct *lct);
-
- struct i2o_cmd_hrtlct
- {
- u32 iop; /* IOP unit number */
- void *resbuf; /* Buffer for result */
- u32 *reslen; /* Buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function returns the Logical Configuration Table of the IOP specified
- by lct->iop in the buffer pointed to by lct->resbuf. The actual size of
- the data is written into *(lct->reslen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(lct->reslen)
-
-VI. Settting Parameters
-
- SYNOPSIS
-
- ioctl(fd, I2OPARMSET, struct i2o_parm_setget *ops);
-
- struct i2o_cmd_psetget
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device TID */
- void *opbuf; /* Operation List buffer */
- u32 oplen; /* Operation List buffer length in bytes */
- void *resbuf; /* Result List buffer */
- u32 *reslen; /* Result List buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function posts a UtilParamsSet message to the device identified
- by ops->iop and ops->tid. The operation list for the message is
- sent through the ops->opbuf buffer, and the result list is written
- into the buffer pointed to by ops->resbuf. The number of bytes
- written is placed into *(ops->reslen).
-
- RETURNS
-
- The return value is the size in bytes of the data written into
- ops->resbuf if no errors occur. If an error occurs, -1 is returned
- and errno is set appropriatly:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
- A return value of 0 does not mean that the value was actually
- changed properly on the IOP. The user should check the result
- list to determine the specific status of the transaction.
-
-VII. Getting Parameters
-
- SYNOPSIS
-
- ioctl(fd, I2OPARMGET, struct i2o_parm_setget *ops);
-
- struct i2o_parm_setget
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device TID */
- void *opbuf; /* Operation List buffer */
- u32 oplen; /* Operation List buffer length in bytes */
- void *resbuf; /* Result List buffer */
- u32 *reslen; /* Result List buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function posts a UtilParamsGet message to the device identified
- by ops->iop and ops->tid. The operation list for the message is
- sent through the ops->opbuf buffer, and the result list is written
- into the buffer pointed to by ops->resbuf. The actual size of data
- written is placed into *(ops->reslen).
-
- RETURNS
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
- A return value of 0 does not mean that the value was actually
- properly retreived. The user should check the result list
- to determine the specific status of the transaction.
-
-VIII. Downloading Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWDL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* DownloadFlags field */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Pointer to software buffer */
- u32 *swlen; /* Length of software buffer */
- u32 *maxfrag; /* Number of fragments */
- u32 *curfrag; /* Current fragment number */
- };
-
- DESCRIPTION
-
- This function downloads a software fragment pointed by sw->buf
- to the iop identified by sw->iop. The DownloadFlags, SwID, SwType
- and SwSize fields of the ExecSwDownload message are filled in with
- the values of sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen).
-
- The fragments _must_ be sent in order and be 8K in size. The last
- fragment _may_ be shorter, however. The kernel will compute its
- size based on information in the sw->swlen field.
-
- Please note that SW transfers can take a long time.
-
- RETURNS
-
- This function returns 0 no errors occur. If an error occurs, -1
- is returned and errno is set appropriatly:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-IX. Uploading Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* UploadFlags */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Pointer to software buffer */
- u32 *swlen; /* Length of software buffer */
- u32 *maxfrag; /* Number of fragments */
- u32 *curfrag; /* Current fragment number */
- };
-
- DESCRIPTION
-
- This function uploads a software fragment from the IOP identified
- by sw->iop, sw->sw_type, sw->sw_id and optionally sw->swlen fields.
- The UploadFlags, SwID, SwType and SwSize fields of the ExecSwUpload
- message are filled in with the values of sw->flags, sw->sw_id,
- sw->sw_type and *(sw->swlen).
-
- The fragments _must_ be requested in order and be 8K in size. The
- user is responsible for allocating memory pointed by sw->buf. The
- last fragment _may_ be shorter.
-
- Please note that SW transfers can take a long time.
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriatly:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-X. Removing Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWDEL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* RemoveFlags */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Unused */
- u32 *swlen; /* Length of the software data */
- u32 *maxfrag; /* Unused */
- u32 *curfrag; /* Unused */
- };
-
- DESCRIPTION
-
- This function removes software from the IOP identified by sw->iop.
- The RemoveFlags, SwID, SwType and SwSize fields of the ExecSwRemove message
- are filled in with the values of sw->flags, sw->sw_id, sw->sw_type and
- *(sw->swlen). Give zero in *(sw->len) if the value is unknown. IOP uses
- *(sw->swlen) value to verify correct identication of the module to remove.
- The actual size of the module is written into *(sw->swlen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriatly:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-X. Validating Configuration
-
- SYNOPSIS
-
- ioctl(fd, I2OVALIDATE, int *iop);
- u32 iop;
-
- DESCRIPTION
-
- This function posts an ExecConfigValidate message to the controller
- identified by iop. This message indicates that the the current
- configuration is accepted. The iop changes the status of suspect drivers
- to valid and may delete old drivers from its store.
-
- RETURNS
-
- This function returns 0 if no erro occur. If an error occurs, -1 is
- returned and errno is set appropriatly:
-
- ETIMEDOUT Timeout waiting for reply message
- ENXIO Invalid IOP number
-
-XI. Configuration Dialog
-
- SYNOPSIS
-
- ioctl(fd, I2OHTML, struct i2o_html *htquery);
- struct i2o_html
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device ID */
- u32 page; /* HTML page */
- void *resbuf; /* Buffer for reply HTML page */
- u32 *reslen; /* Length in bytes of reply buffer */
- void *qbuf; /* Pointer to HTTP query string */
- u32 qlen; /* Length in bytes of query string buffer */
- };
-
- DESCRIPTION
-
- This function posts an UtilConfigDialog message to the device identified
- by htquery->iop and htquery->tid. The requested HTML page number is
- provided by the htquery->page field, and the resultant data is stored
- in the buffer pointed to by htquery->resbuf. If there is an HTTP query
- string that is to be sent to the device, it should be sent in the buffer
- pointed to by htquery->qbuf. If there is no query string, this field
- should be set to NULL. The actual size of the reply received is written
- into *(htquery->reslen).
-
- RETURNS
-
- This function returns 0 if no error occur. If an error occurs, -1
- is returned and errno is set appropriatly:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-XII. Events
-
- In the process of determining this. Current idea is to have use
- the select() interface to allow user apps to periodically poll
- the /dev/i2o/ctl device for events. When select() notifies the user
- that an event is available, the user would call read() to retrieve
- a list of all the events that are pending for the specific device.
-
-=============================================================================
-Revision History
-=============================================================================
-
-Rev 0.1 - 04/01/99
-- Initial revision
-
-Rev 0.2 - 04/06/99
-- Changed return values to match UNIX ioctl() standard. Only return values
- are 0 and -1. All errors are reported through errno.
-- Added summary of proposed possible event interfaces
-
-Rev 0.3 - 04/20/99
-- Changed all ioctls() to use pointers to user data instead of actual data
-- Updated error values to match the code
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.4.12/linux/drivers/i2o/i2o_block.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/i2o/i2o_block.c Wed Dec 31 16:00:00 1969
@@ -1,2051 +0,0 @@
-/*
- * I2O Random Block Storage Class OSM
- *
- * (C) Copyright 1999 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three 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 is a beta test release. Most of the good code was taken
- * from the nbd driver by Pavel Machek, who in turn took some of it
- * from loop.c. Isn't free software great for reusability 8)
- *
- * Fixes/additions:
- * Steve Ralston:
- * Multiple device handling error fixes,
- * Added a queue depth.
- * Alan Cox:
- * FC920 has an rmw bug. Dont or in the end marker.
- * Removed queue walk, fixed for 64bitness.
- * Deepak Saxena:
- * Independent queues per IOP
- * Support for dynamic device creation/deletion
- * Code cleanup
- * Support for larger I/Os through merge* functions
- * (taken from DAC960 driver)
- * Boji T Kannanthanam:
- * Set the I2O Block devices to be detected in increasing
- * order of TIDs during boot.
- * Search and set the I2O block device that we boot off from as
- * the first device to be claimed (as /dev/i2o/hda)
- * Properly attach/detach I2O gendisk structure from the system
- * gendisk list. The I2O block devices now appear in
- * /proc/partitions.
- *
- * To do:
- * Serial number scanning to find duplicates for FC multipathing
- */
-
-#include <linux/major.h>
-
-#include <linux/module.h>
-
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/file.h>
-#include <linux/ioctl.h>
-#include <linux/i2o.h>
-#include <linux/blkdev.h>
-#include <linux/blkpg.h>
-#include <linux/slab.h>
-#include <linux/hdreg.h>
-
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-#include <asm/uaccess.h>
-#include <asm/semaphore.h>
-#include <linux/completion.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <linux/smp_lock.h>
-#include <linux/wait.h>
-
-#define MAJOR_NR I2O_MAJOR
-
-#include <linux/blk.h>
-
-#define MAX_I2OB 16
-
-#define MAX_I2OB_DEPTH 128
-#define MAX_I2OB_RETRIES 4
-
-//#define DRIVERDEBUG
-#ifdef DRIVERDEBUG
-#define DEBUG( s )
-#else
-#define DEBUG( s ) printk( s )
-#endif
-
-/*
- * Events that this OSM is interested in
- */
-#define I2OB_EVENT_MASK (I2O_EVT_IND_BSA_VOLUME_LOAD | \
- I2O_EVT_IND_BSA_VOLUME_UNLOAD | \
- I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ | \
- I2O_EVT_IND_BSA_CAPACITY_CHANGE | \
- I2O_EVT_IND_BSA_SCSI_SMART )
-
-
-/*
- * I2O Block Error Codes - should be in a header file really...
- */
-#define I2O_BSA_DSC_SUCCESS 0x0000
-#define I2O_BSA_DSC_MEDIA_ERROR 0x0001
-#define I2O_BSA_DSC_ACCESS_ERROR 0x0002
-#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003
-#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004
-#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005
-#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006
-#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007
-#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008
-#define I2O_BSA_DSC_BUS_FAILURE 0x0009
-#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A
-#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B
-#define I2O_BSA_DSC_DEVICE_RESET 0x000C
-#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D
-#define I2O_BSA_DSC_TIMEOUT 0x000E
-
-/*
- * Some of these can be made smaller later
- */
-
-static int i2ob_blksizes[MAX_I2OB<<4];
-static int i2ob_hardsizes[MAX_I2OB<<4];
-static int i2ob_sizes[MAX_I2OB<<4];
-static int i2ob_media_change_flag[MAX_I2OB];
-static u32 i2ob_max_sectors[MAX_I2OB<<4];
-
-static int i2ob_context;
-
-/*
- * I2O Block device descriptor
- */
-struct i2ob_device
-{
- struct i2o_controller *controller;
- struct i2o_device *i2odev;
- int unit;
- int tid;
- int flags;
- int refcnt;
- struct request *head, *tail;
- request_queue_t *req_queue;
- int max_segments;
- int done_flag;
- int constipated;
- int depth;
-};
-
-/*
- * FIXME:
- * We should cache align these to avoid ping-ponging lines on SMP
- * boxes under heavy I/O load...
- */
-struct i2ob_request
-{
- struct i2ob_request *next;
- struct request *req;
- int num;
-};
-
-/*
- * Per IOP requst queue information
- *
- * We have a separate requeust_queue_t per IOP so that a heavilly
- * loaded I2O block device on an IOP does not starve block devices
- * across all I2O controllers.
- *
- */
-struct i2ob_iop_queue
-{
- atomic_t queue_depth;
- struct i2ob_request request_queue[MAX_I2OB_DEPTH];
- struct i2ob_request *i2ob_qhead;
- request_queue_t req_queue;
-};
-static struct i2ob_iop_queue *i2ob_queues[MAX_I2O_CONTROLLERS];
-static struct i2ob_request *i2ob_backlog[MAX_I2O_CONTROLLERS];
-static struct i2ob_request *i2ob_backlog_tail[MAX_I2O_CONTROLLERS];
-
-/*
- * Each I2O disk is one of these.
- */
-
-static struct i2ob_device i2ob_dev[MAX_I2OB<<4];
-static int i2ob_dev_count = 0;
-static struct hd_struct i2ob[MAX_I2OB<<4];
-static struct gendisk i2ob_gendisk; /* Declared later */
-
-/*
- * Mutex and spin lock for event handling synchronization
- * evt_msg contains the last event.
- */
-static DECLARE_MUTEX_LOCKED(i2ob_evt_sem);
-static DECLARE_COMPLETION(i2ob_thread_dead);
-static spinlock_t i2ob_evt_lock = SPIN_LOCK_UNLOCKED;
-static u32 evt_msg[MSG_FRAME_SIZE>>2];
-
-static struct timer_list i2ob_timer;
-static int i2ob_timer_started = 0;
-
-static void i2o_block_reply(struct i2o_handler *, struct i2o_controller *,
- struct i2o_message *);
-static void i2ob_new_device(struct i2o_controller *, struct i2o_device *);
-static void i2ob_del_device(struct i2o_controller *, struct i2o_device *);
-static void i2ob_reboot_event(void);
-static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
-static void i2ob_end_request(struct request *);
-static void i2ob_request(request_queue_t *);
-static int i2ob_backlog_request(struct i2o_controller *, struct i2ob_device *);
-static int i2ob_init_iop(unsigned int);
-static request_queue_t* i2ob_get_queue(kdev_t);
-static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
-static int do_i2ob_revalidate(kdev_t, int);
-static int i2ob_evt(void *);
-
-static int evt_pid = 0;
-static int evt_running = 0;
-static int scan_unit = 0;
-
-/*
- * I2O OSM registration structure...keeps getting bigger and bigger :)
- */
-static struct i2o_handler i2o_block_handler =
-{
- i2o_block_reply,
- i2ob_new_device,
- i2ob_del_device,
- i2ob_reboot_event,
- "I2O Block OSM",
- 0,
- I2O_CLASS_RANDOM_BLOCK_STORAGE
-};
-
-/*
- * Get a message
- */
-
-static u32 i2ob_get(struct i2ob_device *dev)
-{
- struct i2o_controller *c=dev->controller;
- return I2O_POST_READ32(c);
-}
-
-/*
- * Turn a Linux block request into an I2O block read/write.
- */
-
-static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq, u32 base, int unit)
-{
- struct i2o_controller *c = dev->controller;
- int tid = dev->tid;
- unsigned long msg;
- unsigned long mptr;
- u64 offset;
- struct request *req = ireq->req;
- struct buffer_head *bh = req->bh;
- int count = req->nr_sectors<<9;
- char *last = NULL;
- unsigned short size = 0;
-
- // printk(KERN_INFO "i2ob_send called\n");
- /* Map the message to a virtual address */
- msg = c->mem_offset + m;
-
- /*
- * Build the message based on the request.
- */
- __raw_writel(i2ob_context|(unit<<8), msg+8);
- __raw_writel(ireq->num, msg+12);
- __raw_writel(req->nr_sectors << 9, msg+20);
-
- /*
- * Mask out partitions from now on
- */
- unit &= 0xF0;
-
- /* This can be optimised later - just want to be sure its right for
- starters */
- offset = ((u64)(req->sector+base)) << 9;
- __raw_writel( offset & 0xFFFFFFFF, msg+24);
- __raw_writel(offset>>32, msg+28);
- mptr=msg+32;
-
- if(req->cmd == READ)
- {
- __raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
- while(bh!=NULL)
- {
- if(bh->b_data == last) {
- size += bh->b_size;
- last += bh->b_size;
- if(bh->b_reqnext)
- __raw_writel(0x14000000|(size), mptr-8);
- else
- __raw_writel(0xD4000000|(size), mptr-8);
- }
- else
- {
- if(bh->b_reqnext)
- __raw_writel(0x10000000|(bh->b_size), mptr);
- else
- __raw_writel(0xD0000000|(bh->b_size), mptr);
- __raw_writel(virt_to_bus(bh->b_data), mptr+4);
- mptr += 8;
- size = bh->b_size;
- last = bh->b_data + size;
- }
-
- count -= bh->b_size;
- bh = bh->b_reqnext;
- }
- /*
- * Heuristic for now since the block layer doesnt give
- * us enough info. If its a big write assume sequential
- * readahead on controller. If its small then don't read
- * ahead but do use the controller cache.
- */
- if(size >= 8192)
- __raw_writel((8<<24)|(1<<16)|8, msg+16);
- else
- __raw_writel((8<<24)|(1<<16)|4, msg+16);
- }
- else if(req->cmd == WRITE)
- {
- __raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
- while(bh!=NULL)
- {
- if(bh->b_data == last) {
- size += bh->b_size;
- last += bh->b_size;
- if(bh->b_reqnext)
- __raw_writel(0x14000000|(size), mptr-8);
- else
- __raw_writel(0xD4000000|(size), mptr-8);
- }
- else
- {
- if(bh->b_reqnext)
- __raw_writel(0x14000000|(bh->b_size), mptr);
- else
- __raw_writel(0xD4000000|(bh->b_size), mptr);
- __raw_writel(virt_to_bus(bh->b_data), mptr+4);
- mptr += 8;
- size = bh->b_size;
- last = bh->b_data + size;
- }
-
- count -= bh->b_size;
- bh = bh->b_reqnext;
- }
-
- if(c->battery)
- {
-
- if(size>16384)
- __raw_writel(4, msg+16);
- else
- /*
- * Allow replies to come back once data is cached in the controller
- * This allows us to handle writes quickly thus giving more of the
- * queue to reads.
- */
- __raw_writel(16, msg+16);
- }
- else
- {
- /* Large write, don't cache */
- if(size>8192)
- __raw_writel(4, msg+16);
- else
- /* write through */
- __raw_writel(8, msg+16);
- }
- }
- __raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
-
- if(count != 0)
- {
- printk(KERN_ERR "Request count botched by %d.\n", count);
- }
-
- i2o_post_message(c,m);
- atomic_inc(&i2ob_queues[c->unit]->queue_depth);
-


- return 0;
-}
-

-/*
- * Remove a request from the _locked_ request list. We update both the
- * list chain and if this is the last item the tail pointer. Caller
- * must hold the lock.
- */
-
-static inline void i2ob_unhook_request(struct i2ob_request *ireq,
- unsigned int iop)
-{
- ireq->next = i2ob_queues[iop]->i2ob_qhead;
- i2ob_queues[iop]->i2ob_qhead = ireq;
-}
-
-/*
- * Request completion handler
- */
-
-static inline void i2ob_end_request(struct request *req)
-{
- /*
- * Loop until all of the buffers that are linked
- * to this request have been marked updated and
- * unlocked.
- */
-
- while (end_that_request_first( req, !req->errors, "i2o block" ));
-
- /*
- * It is now ok to complete the request.
- */
- end_that_request_last( req );
-}
-
-/*
- * Request merging functions
- */
-static inline int i2ob_new_segment(request_queue_t *q, struct request *req,
- int __max_segments)
-{
- int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
-
- if (__max_segments < max_segments)
- max_segments = __max_segments;
-
- if (req->nr_segments < max_segments) {
- req->nr_segments++;
- return 1;
- }


- return 0;
-}
-

-static int i2ob_back_merge(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
-{
- if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
- return 1;
- return i2ob_new_segment(q, req, __max_segments);
-}
-
-static int i2ob_front_merge(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
-{
- if (bh->b_data + bh->b_size == req->bh->b_data)
- return 1;
- return i2ob_new_segment(q, req, __max_segments);
-}
-
-static int i2ob_merge_requests(request_queue_t *q,
- struct request *req,
- struct request *next,
- int __max_segments)
-{
- int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
- int total_segments = req->nr_segments + next->nr_segments;
-
- if (__max_segments < max_segments)
- max_segments = __max_segments;
-
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
- total_segments--;
-
- if (total_segments > max_segments)
- return 0;
-
- req->nr_segments = total_segments;


- return 1;
-}
-

-static int i2ob_flush(struct i2o_controller *c, struct i2ob_device *d, int unit)
-{
- unsigned long msg;
- u32 m = i2ob_get(d);
-
- if(m == 0xFFFFFFFF)
- return -1;
-
- msg = c->mem_offset + m;
-
- /*
- * Ask the controller to write the cache back. This sorts out
- * the supertrak firmware flaw and also does roughly the right
- * thing for other cases too.
- */
-
- __raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
- __raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
- __raw_writel(i2ob_context|(unit<<8), msg+8);
- __raw_writel(0, msg+12);
- __raw_writel(60<<16, msg+16);
-
- i2o_post_message(c,m);


- return 0;
-}
-

-/*
- * OSM reply handler. This gets all the message replies
- */
-
-static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)


-{
- unsigned long flags;

- struct i2ob_request *ireq = NULL;
- u8 st;
- u32 *m = (u32 *)msg;
- u8 unit = (m[2]>>8)&0xF0; /* low 4 bits are partition */
- struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)];
-
- /*
- * FAILed message
- */
- if(m[0] & (1<<13))
- {
- /*
- * FAILed message from controller
- * We increment the error count and abort it
- *
- * In theory this will never happen. The I2O block class
- * speficiation states that block devices never return
- * FAILs but instead use the REQ status field...but
- * better be on the safe side since no one really follows
- * the spec to the book :)
- */
- ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
- ireq->req->errors++;
-
- spin_lock_irqsave(&io_request_lock, flags);
- i2ob_unhook_request(ireq, c->unit);
- i2ob_end_request(ireq->req);
- spin_unlock_irqrestore(&io_request_lock, flags);
-
- /* Now flush the message by making it a NOP */
- m[0]&=0x00FFFFFF;
- m[0]|=(I2O_CMD_UTIL_NOP)<<24;
- i2o_post_message(c,virt_to_bus(m));
-
- return;
- }
-
- if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
- {
- spin_lock(&i2ob_evt_lock);
- memcpy(evt_msg, msg, (m[0]>>16)<<2);
- spin_unlock(&i2ob_evt_lock);
- up(&i2ob_evt_sem);
- return;
- }
-
- if(msg->function == I2O_CMD_BLOCK_CFLUSH)
- {
- spin_lock_irqsave(&io_request_lock, flags);
- dev->constipated=0;
- DEBUG(("unconstipated\n"));
- if(i2ob_backlog_request(c, dev)==0)
- i2ob_request(dev->req_queue);
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
-
- if(!dev->i2odev)
- {
- /*
- * This is HACK, but Intel Integrated RAID allows user
- * to delete a volume that is claimed, locked, and in use
- * by the OS. We have to check for a reply from a
- * non-existent device and flag it as an error or the system
- * goes kaput...
- */
- ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
- ireq->req->errors++;
- printk(KERN_WARNING "I2O Block: Data transfer to deleted device!\n");
- spin_lock_irqsave(&io_request_lock, flags);
- i2ob_unhook_request(ireq, c->unit);
- i2ob_end_request(ireq->req);
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
-
- /*
- * Lets see what is cooking. We stuffed the
- * request in the context.
- */
-
- ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
- st=m[4]>>24;
-
- if(st!=0)
- {
- int err;
- char *bsa_errors[] =
- {
- "Success",
- "Media Error",
- "Failure communicating to device",
- "Device Failure",
- "Device is not ready",
- "Media not present",
- "Media is locked by another user",
- "Media has failed",
- "Failure communicating to device",
- "Device bus failure",
- "Device is locked by another user",
- "Device is write protected",
- "Device has reset",
- "Volume has changed, waiting for acknowledgement"
- };
-
- err = m[4]&0xFFFF;
-
- /*
- * Device not ready means two things. One is that the
- * the thing went offline (but not a removal media)
- *
- * The second is that you have a SuperTrak 100 and the
- * firmware got constipated. Unlike standard i2o card
- * setups the supertrak returns an error rather than
- * blocking for the timeout in these cases.
- */
-
-
- spin_lock_irqsave(&io_request_lock, flags);
- if(err==4)
- {
- /*
- * Time to uncork stuff
- */
-
- if(!dev->constipated)
- {
- dev->constipated = 1;
- DEBUG(("constipated\n"));
- /* Now pull the chain */
- if(i2ob_flush(c, dev, unit)<0)
- {
- DEBUG(("i2ob: Unable to queue flush. Retrying I/O immediately.\n"));
- dev->constipated=0;
- }
- DEBUG(("flushing\n"));
- }
-
- /*
- * Recycle the request
- */
-
-// i2ob_unhook_request(ireq, c->unit);
-
- /*
- * Place it on the recycle queue
- */
-
- ireq->next = NULL;
- if(i2ob_backlog_tail[c->unit]!=NULL)
- i2ob_backlog_tail[c->unit]->next = ireq;
- else
- i2ob_backlog[c->unit] = ireq;
- i2ob_backlog_tail[c->unit] = ireq;
-
- atomic_dec(&i2ob_queues[c->unit]->queue_depth);
-
- /*
- * If the constipator flush failed we want to
- * poke the queue again.
- */
-
- i2ob_request(dev->req_queue);
- spin_unlock_irqrestore(&io_request_lock, flags);
-
- /*
- * and out
- */
-
- return;
- }
- spin_unlock_irqrestore(&io_request_lock, flags);
- printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name,
- bsa_errors[m[4]&0XFFFF]);
- if(m[4]&0x00FF0000)
- printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF );
- printk(".\n");
- ireq->req->errors++;
- }
- else
- ireq->req->errors = 0;
-
- /*
- * Dequeue the request. We use irqsave locks as one day we


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 15'
echo 'File patch-2.4.13 is continued in part 16'
echo "16" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:46 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part16

#!/bin/sh -x
# this is part 16 of a 53 - part archive


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

if test "$Scheck" != 16; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- * may be running polled controllers from a BH...
- */


-
- spin_lock_irqsave(&io_request_lock, flags);
- i2ob_unhook_request(ireq, c->unit);
- i2ob_end_request(ireq->req);

- atomic_dec(&i2ob_queues[c->unit]->queue_depth);
-
- /*

- * We may be able to do more I/O
- */
-


- if(i2ob_backlog_request(c, dev)==0)
- i2ob_request(dev->req_queue);
-

- spin_unlock_irqrestore(&io_request_lock, flags);
-}
-

-/*
- * Event handler. Needs to be a separate thread b/c we may have
- * to do things like scan a partition table, or query parameters
- * which cannot be done from an interrupt or from a bottom half.
- */
-static int i2ob_evt(void *dummy)
-{
- unsigned int evt;
- unsigned long flags;
- int unit;
- int i;
- //The only event that has data is the SCSI_SMART event.
- struct i2o_reply {
- u32 header[4];
- u32 evt_indicator;
- u8 ASC;
- u8 ASCQ;
- u8 data[16];
- } *evt_local;
-
- lock_kernel();
- daemonize();
- unlock_kernel();
-
- strcpy(current->comm, "i2oblock");
- evt_running = 1;
-
- while(1)
- {
- if(down_interruptible(&i2ob_evt_sem))
- {
- evt_running = 0;
- printk("exiting...");
- break;
- }
-
- /*
- * Keep another CPU/interrupt from overwriting the
- * message while we're reading it
- *
- * We stuffed the unit in the TxContext and grab the event mask
- * None of the BSA we care about events have EventData
- */
- spin_lock_irqsave(&i2ob_evt_lock, flags);
- evt_local = (struct i2o_reply *)evt_msg;
- spin_unlock_irqrestore(&i2ob_evt_lock, flags);
-
- unit = evt_local->header[3];
- evt = evt_local->evt_indicator;
-
- switch(evt)
- {
- /*
- * New volume loaded on same TID, so we just re-install.
- * The TID/controller don't change as it is the same
- * I2O device. It's just new media that we have to
- * rescan.
- */
- case I2O_EVT_IND_BSA_VOLUME_LOAD:
- {
- i2ob_install_device(i2ob_dev[unit].i2odev->controller,
- i2ob_dev[unit].i2odev, unit);
- break;
- }
-
- /*
- * No media, so set all parameters to 0 and set the media
- * change flag. The I2O device is still valid, just doesn't
- * have media, so we don't want to clear the controller or
- * device pointer.
- */
- case I2O_EVT_IND_BSA_VOLUME_UNLOAD:
- {
- for(i = unit; i <= unit+15; i++)
- {
- i2ob_sizes[i] = 0;
- i2ob_hardsizes[i] = 0;
- i2ob_max_sectors[i] = 0;
- i2ob[i].nr_sects = 0;
- i2ob_gendisk.part[i].nr_sects = 0;
- }
- i2ob_media_change_flag[unit] = 1;
- break;
- }
-
- case I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ:
- printk(KERN_WARNING "%s: Attempt to eject locked media\n",
- i2ob_dev[unit].i2odev->dev_name);
- break;
-
- /*
- * The capacity has changed and we are going to be
- * updating the max_sectors and other information
- * about this disk. We try a revalidate first. If
- * the block device is in use, we don't want to
- * do that as there may be I/Os bound for the disk
- * at the moment. In that case we read the size
- * from the device and update the information ourselves
- * and the user can later force a partition table
- * update through an ioctl.
- */
- case I2O_EVT_IND_BSA_CAPACITY_CHANGE:
- {
- u64 size;
-
- if(do_i2ob_revalidate(MKDEV(MAJOR_NR, unit),0) != -EBUSY)
- continue;
-
- if(i2ob_query_device(&i2ob_dev[unit], 0x0004, 0, &size, 8) !=0 )
- i2ob_query_device(&i2ob_dev[unit], 0x0000, 4, &size, 8);
-
- spin_lock_irqsave(&io_request_lock, flags);
- i2ob_sizes[unit] = (int)(size>>10);
- i2ob_gendisk.part[unit].nr_sects = size>>9;
- i2ob[unit].nr_sects = (int)(size>>9);
- spin_unlock_irqrestore(&io_request_lock, flags);
- break;
- }
-
- /*
- * We got a SCSI SMART event, we just log the relevant
- * information and let the user decide what they want
- * to do with the information.
- */
- case I2O_EVT_IND_BSA_SCSI_SMART:
- {
- char buf[16];
- printk(KERN_INFO "I2O Block: %s received a SCSI SMART Event\n",i2ob_dev[unit].i2odev->dev_name);
- evt_local->data[16]='\0';
- sprintf(buf,"%s",&evt_local->data[0]);
- printk(KERN_INFO " Disk Serial#:%s\n",buf);
- printk(KERN_INFO " ASC 0x%02x \n",evt_local->ASC);
- printk(KERN_INFO " ASCQ 0x%02x \n",evt_local->ASCQ);
- break;
- }
-
- /*
- * Non event
- */
-
- case 0:
- break;
-
- /*
- * An event we didn't ask for. Call the card manufacturer
- * and tell them to fix their firmware :)
- */
- default:
- printk(KERN_INFO "%s: Received event %d we didn't register for\n"
- KERN_INFO " Blame the I2O card manufacturer 8)\n",
- i2ob_dev[unit].i2odev->dev_name, evt);


- break;
- }
- };
-

- complete_and_exit(&i2ob_thread_dead,0);


- return 0;
-}
-
-/*

- * The timer handler will attempt to restart requests
- * that are queued to the driver. This handler
- * currently only gets called if the controller
- * had no more room in its inbound fifo.
- */
-
-static void i2ob_timer_handler(unsigned long q)


-{
- unsigned long flags;
-

- /*
- * We cannot touch the request queue or the timer
- * flag without holding the io_request_lock.
- */
- spin_lock_irqsave(&io_request_lock,flags);
-
- /*
- * Clear the timer started flag so that
- * the timer can be queued again.
- */
- i2ob_timer_started = 0;
-
- /*
- * Restart any requests.
- */
- i2ob_request((request_queue_t*)q);
-
- /*
- * Free the lock.
- */
- spin_unlock_irqrestore(&io_request_lock,flags);
-}
-
-static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev)
-{
- u32 m;
- struct i2ob_request *ireq;
-
- while((ireq=i2ob_backlog[c->unit])!=NULL)
- {
- int unit;
-
- if(atomic_read(&i2ob_queues[c->unit]->queue_depth) > dev->depth/4)
- break;
-
- m = i2ob_get(dev);
- if(m == 0xFFFFFFFF)
- break;
-
- i2ob_backlog[c->unit] = ireq->next;
- if(i2ob_backlog[c->unit] == NULL)
- i2ob_backlog_tail[c->unit] = NULL;
-
- unit = MINOR(ireq->req->rq_dev);
- i2ob_send(m, dev, ireq, i2ob[unit].start_sect, unit);
- }
- if(i2ob_backlog[c->unit])
- return 1;


- return 0;
-}
-
-/*

- * The I2O block driver is listed as one of those that pulls the
- * front entry off the queue before processing it. This is important
- * to remember here. If we drop the io lock then CURRENT will change
- * on us. We must unlink CURRENT in this routine before we return, if
- * we use it.
- */
-
-static void i2ob_request(request_queue_t *q)
-{
- struct request *req;
- struct i2ob_request *ireq;
- int unit;
- struct i2ob_device *dev;
- u32 m;
-
-
- while (!list_empty(&q->queue_head)) {
- /*
- * On an IRQ completion if there is an inactive
- * request on the queue head it means it isnt yet
- * ready to dispatch.
- */
- req = blkdev_entry_next_request(&q->queue_head);
-
- if(req->rq_status == RQ_INACTIVE)
- return;
-
- unit = MINOR(req->rq_dev);
- dev = &i2ob_dev[(unit&0xF0)];
-
- /*
- * Queue depths probably belong with some kind of
- * generic IOP commit control. Certainly its not right
- * its global!
- */
- if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) >= dev->depth)
- break;
-
- /*
- * Is the channel constipated ?
- */
-
- if(i2ob_backlog[dev->unit]!=NULL)
- break;
-
- /* Get a message */
- m = i2ob_get(dev);
-
- if(m==0xFFFFFFFF)
- {
- /*
- * See if the timer has already been queued.
- */
- if (!i2ob_timer_started)
- {
- DEBUG((KERN_ERR "i2ob: starting timer\n"));
-
- /*
- * Set the timer_started flag to insure
- * that the timer is only queued once.
- * Queing it more than once will corrupt
- * the timer queue.
- */
- i2ob_timer_started = 1;
-
- /*
- * Set up the timer to expire in
- * 500ms.
- */
- i2ob_timer.expires = jiffies + (HZ >> 1);
- i2ob_timer.data = (unsigned int)q;
-
- /*
- * Start it.
- */
-
- add_timer(&i2ob_timer);


- return;
- }
- }
-

- /*
- * Everything ok, so pull from kernel queue onto our queue
- */
- req->errors = 0;
- blkdev_dequeue_request(req);
- req->waiting = NULL;
-
- ireq = i2ob_queues[dev->unit]->i2ob_qhead;
- i2ob_queues[dev->unit]->i2ob_qhead = ireq->next;
- ireq->req = req;
-
- i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));
- }
-}
-
-
-/*
- * SCSI-CAM for ioctl geometry mapping
- * Duplicated with SCSI - this should be moved into somewhere common
- * perhaps genhd ?
- *
- * LBA -> CHS mapping table taken from:
- *
- * "Incorporating the I2O Architecture into BIOS for Intel Architecture
- * Platforms"
- *
- * This is an I2O document that is only available to I2O members,
- * not developers.
- *
- * From my understanding, this is how all the I2O cards do this
- *
- * Disk Size | Sectors | Heads | Cylinders
- * ---------------+---------+-------+-------------------
- * 1 < X <= 528M | 63 | 16 | X/(63 * 16 * 512)
- * 528M < X <= 1G | 63 | 32 | X/(63 * 32 * 512)
- * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
- * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
- *
- */
-#define BLOCK_SIZE_528M 1081344
-#define BLOCK_SIZE_1G 2097152
-#define BLOCK_SIZE_21G 4403200
-#define BLOCK_SIZE_42G 8806400
-#define BLOCK_SIZE_84G 17612800
-
-static void i2o_block_biosparam(
- unsigned long capacity,
- unsigned short *cyls,
- unsigned char *hds,
- unsigned char *secs)
-{
- unsigned long heads, sectors, cylinders;
-
- sectors = 63L; /* Maximize sectors per track */
- if(capacity <= BLOCK_SIZE_528M)
- heads = 16;
- else if(capacity <= BLOCK_SIZE_1G)
- heads = 32;
- else if(capacity <= BLOCK_SIZE_21G)
- heads = 64;
- else if(capacity <= BLOCK_SIZE_42G)
- heads = 128;
- else
- heads = 255;
-
- cylinders = capacity / (heads * sectors);
-
- *cyls = (unsigned short) cylinders; /* Stuff return values */
- *secs = (unsigned char) sectors;
- *hds = (unsigned char) heads;
-}
-
-
-/*
- * Rescan the partition tables
- */
-
-static int do_i2ob_revalidate(kdev_t dev, int maxu)
-{
- int minor=MINOR(dev);
- int i;
-
- minor&=0xF0;
-
- i2ob_dev[minor].refcnt++;
- if(i2ob_dev[minor].refcnt>maxu+1)
- {
- i2ob_dev[minor].refcnt--;
- return -EBUSY;
- }
-
- for( i = 15; i>=0 ; i--)
- {
- int m = minor+i;
- invalidate_device(MKDEV(MAJOR_NR, m), 1);
- i2ob_gendisk.part[m].start_sect = 0;
- i2ob_gendisk.part[m].nr_sects = 0;
- }
-
- /*
- * Do a physical check and then reconfigure
- */
-
- i2ob_install_device(i2ob_dev[minor].controller, i2ob_dev[minor].i2odev,
- minor);
- i2ob_dev[minor].refcnt--;


- return 0;
-}
-
-/*

- * Issue device specific ioctl calls.
- */
-
-static int i2ob_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct i2ob_device *dev;
- int minor;
-
- /* Anyone capable of this syscall can do *real bad* things */
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (!inode)
- return -EINVAL;
- minor = MINOR(inode->i_rdev);
- if (minor >= (MAX_I2OB<<4))
- return -ENODEV;
-
- dev = &i2ob_dev[minor];
- switch (cmd) {
- case BLKGETSIZE:
- return put_user(i2ob[minor].nr_sects, (long *) arg);
- case BLKGETSIZE64:
- return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg);
-
- case HDIO_GETGEO:
- {
- struct hd_geometry g;
- int u=minor&0xF0;
- i2o_block_biosparam(i2ob_sizes[u]<<1,
- &g.cylinders, &g.heads, &g.sectors);
- g.start = i2ob[minor].start_sect;
- return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
- }
-
- case BLKRRPART:
- if(!capable(CAP_SYS_ADMIN))
- return -EACCES;
- return do_i2ob_revalidate(inode->i_rdev,1);
-
- case BLKFLSBUF:
- case BLKROSET:
- case BLKROGET:
- case BLKRASET:
- case BLKRAGET:
- case BLKPG:
- return blk_ioctl(inode->i_rdev, cmd, arg);
-
- default:
- return -EINVAL;
- }
-}
-
-/*
- * Close the block device down
- */
-
-static int i2ob_release(struct inode *inode, struct file *file)
-{
- struct i2ob_device *dev;
- int minor;
-
- minor = MINOR(inode->i_rdev);
- if (minor >= (MAX_I2OB<<4))
- return -ENODEV;
- dev = &i2ob_dev[(minor&0xF0)];
-
- /*
- * This is to deail with the case of an application
- * opening a device and then the device dissapears while
- * it's in use, and then the application tries to release
- * it. ex: Unmounting a deleted RAID volume at reboot.
- * If we send messages, it will just cause FAILs since
- * the TID no longer exists.
- */
- if(!dev->i2odev)
- return 0;
-
- if (dev->refcnt <= 0)
- printk(KERN_ALERT "i2ob_release: refcount(%d) <= 0\n", dev->refcnt);
- dev->refcnt--;
- if(dev->refcnt==0)
- {
- /*
- * Flush the onboard cache on unmount
- */
- u32 msg[5];
- int *query_done = &dev->done_flag;
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
- msg[2] = i2ob_context|0x40000000;
- msg[3] = (u32)query_done;
- msg[4] = 60<<16;
- DEBUG("Flushing...");
- i2o_post_wait(dev->controller, msg, 20, 60);
-
- /*
- * Unlock the media
- */
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;
- msg[2] = i2ob_context|0x40000000;
- msg[3] = (u32)query_done;
- msg[4] = -1;
- DEBUG("Unlocking...");
- i2o_post_wait(dev->controller, msg, 20, 2);
- DEBUG("Unlocked.\n");
-
- /*
- * Now unclaim the device.
- */
-
- if (i2o_release_device(dev->i2odev, &i2o_block_handler))
- printk(KERN_ERR "i2ob_release: controller rejected unclaim.\n");
-
- DEBUG("Unclaim\n");
- }
- MOD_DEC_USE_COUNT;


- return 0;
-}
-
-/*

- * Open the block device.
- */
-
-static int i2ob_open(struct inode *inode, struct file *file)
-{
- int minor;
- struct i2ob_device *dev;
-
- if (!inode)
- return -EINVAL;
- minor = MINOR(inode->i_rdev);
- if (minor >= MAX_I2OB<<4)
- return -ENODEV;
- dev=&i2ob_dev[(minor&0xF0)];
-
- if(!dev->i2odev)
- return -ENODEV;
-
- if(dev->refcnt++==0)
- {
- u32 msg[6];
-
- DEBUG("Claim ");
- if(i2o_claim_device(dev->i2odev, &i2o_block_handler))
- {
- dev->refcnt--;
- printk(KERN_INFO "I2O Block: Could not open device\n");
- return -EBUSY;
- }
- DEBUG("Claimed ");
-
- /*
- * Mount the media if needed. Note that we don't use
- * the lock bit. Since we have to issue a lock if it
- * refuses a mount (quite possible) then we might as
- * well just send two messages out.
- */
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_MMOUNT<<24|HOST_TID<<12|dev->tid;
- msg[4] = -1;
- msg[5] = 0;
- DEBUG("Mount ");
- i2o_post_wait(dev->controller, msg, 24, 2);
-
- /*
- * Lock the media
- */
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_MLOCK<<24|HOST_TID<<12|dev->tid;
- msg[4] = -1;
- DEBUG("Lock ");
- i2o_post_wait(dev->controller, msg, 20, 2);
- DEBUG("Ready.\n");
- }
- MOD_INC_USE_COUNT;


- return 0;
-}
-
-/*

- * Issue a device query
- */
-
-static int i2ob_query_device(struct i2ob_device *dev, int table,
- int field, void *buf, int buflen)
-{
- return i2o_query_scalar(dev->controller, dev->tid,
- table, field, buf, buflen);
-}
-
-
-/*
- * Install the I2O block device we found.
- */
-
-static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, int unit)
-{
- u64 size;
- u32 blocksize;
- u32 limit;
- u8 type;
- u32 flags, status;
- struct i2ob_device *dev=&i2ob_dev[unit];
- int i;
-
- /*
- * For logging purposes...
- */
- printk(KERN_INFO "i2ob: Installing tid %d device at unit %d\n",
- d->lct_data.tid, unit);
-
- /*
- * Ask for the current media data. If that isn't supported
- * then we ask for the device capacity data
- */
- if(i2ob_query_device(dev, 0x0004, 1, &blocksize, 4) != 0
- || i2ob_query_device(dev, 0x0004, 0, &size, 8) !=0 )
- {
- i2ob_query_device(dev, 0x0000, 3, &blocksize, 4);
- i2ob_query_device(dev, 0x0000, 4, &size, 8);
- }
-
- i2ob_query_device(dev, 0x0000, 5, &flags, 4);
- i2ob_query_device(dev, 0x0000, 6, &status, 4);
- i2ob_sizes[unit] = (int)(size>>10);
- for(i=unit; i <= unit+15 ; i++)
- i2ob_hardsizes[i] = blocksize;
- i2ob_gendisk.part[unit].nr_sects = size>>9;
- i2ob[unit].nr_sects = (int)(size>>9);
-
- /* Set limit based on inbound frame size */
- limit = (d->controller->status_block->inbound_frame_size - 8)/2;
- limit = limit<<9;
-
- /*
- * Max number of Scatter-Gather Elements
- */
-
- for(i=unit;i<=unit+15;i++)
- {
- if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy)
- {
- i2ob_max_sectors[i] = 32;
- i2ob_dev[i].max_segments = 8;
- i2ob_dev[i].depth = 4;
- }
- else if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
- {
- i2ob_max_sectors[i] = 8;
- i2ob_dev[i].max_segments = 8;
- }
- else
- {
- /* MAX_SECTORS was used but 255 is a dumb number for
- striped RAID */
- i2ob_max_sectors[i]=256;
- i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
- }
- }
-
- printk(KERN_INFO "Max segments set to %d\n",
- i2ob_dev[unit].max_segments);
- printk(KERN_INFO "Byte limit is %d.\n", limit);
-
- i2ob_query_device(dev, 0x0000, 0, &type, 1);
-
- sprintf(d->dev_name, "%s%c", i2ob_gendisk.major_name, 'a' + (unit>>4));
-
- printk(KERN_INFO "%s: ", d->dev_name);
- switch(type)
- {
- case 0: printk("Disk Storage");break;
- case 4: printk("WORM");break;
- case 5: printk("CD-ROM");break;
- case 7: printk("Optical device");break;
- default:
- printk("Type %d", type);
- }
- if(status&(1<<10))
- printk("(RAID)");
- if(((flags & (1<<3)) && !(status & (1<<3))) ||
- ((flags & (1<<4)) && !(status & (1<<4))))
- {
- printk(KERN_INFO " Not loaded.\n");
- return 1;
- }
- printk("- %dMb, %d byte sectors",
- (int)(size>>20), blocksize);
- if(status&(1<<0))
- {
- u32 cachesize;
- i2ob_query_device(dev, 0x0003, 0, &cachesize, 4);
- cachesize>>=10;
- if(cachesize>4095)
- printk(", %dMb cache", cachesize>>10);
- else
- printk(", %dKb cache", cachesize);
-
- }


- printk(".\n");

- printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n",
- d->dev_name, i2ob_max_sectors[unit]);
-
- /*
- * If this is the first I2O block device found on this IOP,
- * we need to initialize all the queue data structures
- * before any I/O can be performed. If it fails, this
- * device is useless.
- */
- if(!i2ob_queues[c->unit]) {
- if(i2ob_init_iop(c->unit))


- return 1;
- }
-

- /*
- * This will save one level of lookup/indirection in critical
- * code so that we can directly get the queue ptr from the
- * device instead of having to go the IOP data structure.
- */
- dev->req_queue = &i2ob_queues[c->unit]->req_queue;
-
- grok_partitions(&i2ob_gendisk, unit>>4, 1<<4, (long)(size>>9));
-
- /*
- * Register for the events we're interested in and that the
- * device actually supports.
- */
- i2o_event_register(c, d->lct_data.tid, i2ob_context, unit,
- (I2OB_EVENT_MASK & d->lct_data.event_capabilities));


-
- return 0;
-}
-
-/*

- * Initialize IOP specific queue structures. This is called
- * once for each IOP that has a block device sitting behind it.
- */
-static int i2ob_init_iop(unsigned int unit)
-{
- int i;
-
- i2ob_queues[unit] = (struct i2ob_iop_queue*)
- kmalloc(sizeof(struct i2ob_iop_queue), GFP_ATOMIC);
- if(!i2ob_queues[unit])
- {
- printk(KERN_WARNING
- "Could not allocate request queue for I2O block device!\n");


- return -1;
- }
-

- for(i = 0; i< MAX_I2OB_DEPTH; i++)
- {
- i2ob_queues[unit]->request_queue[i].next =
- &i2ob_queues[unit]->request_queue[i+1];
- i2ob_queues[unit]->request_queue[i].num = i;
- }
-
- /* Queue is MAX_I2OB + 1... */
- i2ob_queues[unit]->request_queue[i].next = NULL;
- i2ob_queues[unit]->i2ob_qhead = &i2ob_queues[unit]->request_queue[0];
- atomic_set(&i2ob_queues[unit]->queue_depth, 0);
-
- blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request);
- blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0);
- i2ob_queues[unit]->req_queue.back_merge_fn = i2ob_back_merge;
- i2ob_queues[unit]->req_queue.front_merge_fn = i2ob_front_merge;
- i2ob_queues[unit]->req_queue.merge_requests_fn = i2ob_merge_requests;
- i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit];


-
- return 0;
-}
-
-/*

- * Get the request queue for the given device.
- */
-static request_queue_t* i2ob_get_queue(kdev_t dev)
-{
- int unit = MINOR(dev)&0xF0;
-
- return i2ob_dev[unit].req_queue;
-}
-
-/*
- * Probe the I2O subsytem for block class devices
- */
-static void i2ob_scan(int bios)
-{
- int i;
- int warned = 0;
-
- struct i2o_device *d, *b=NULL;
- struct i2o_controller *c;
- struct i2ob_device *dev;
-
- for(i=0; i< MAX_I2O_CONTROLLERS; i++)
- {
- c=i2o_find_controller(i);
-
- if(c==NULL)
- continue;
-
- /*
- * The device list connected to the I2O Controller is doubly linked
- * Here we traverse the end of the list , and start claiming devices
- * from that end. This assures that within an I2O controller atleast
- * the newly created volumes get claimed after the older ones, thus
- * mapping to same major/minor (and hence device file name) after
- * every reboot.
- * The exception being:
- * 1. If there was a TID reuse.
- * 2. There was more than one I2O controller.
- */
-
- if(!bios)
- {
- for (d=c->devices;d!=NULL;d=d->next)
- if(d->next == NULL)
- b = d;
- }
- else
- b = c->devices;
-
- while(b != NULL)
- {
- d=b;
- if(bios)
- b = b->next;
- else
- b = b->prev;
-
- if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)
- continue;
-
- if(d->lct_data.user_tid != 0xFFF)
- continue;
-
- if(bios)
- {
- if(d->lct_data.bios_info != 0x80)
- continue;
- printk(KERN_INFO "Claiming as Boot device: Controller %d, TID %d\n", c->unit, d->lct_data.tid);
- }
- else
- {
- if(d->lct_data.bios_info == 0x80)
- continue; /*Already claimed on pass 1 */
- }
-
- if(i2o_claim_device(d, &i2o_block_handler))
- {
- printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit,
- d->lct_data.tid);
- printk(KERN_WARNING "\t%sevice refused claim! Skipping installation\n", bios?"Boot d":"D");
- continue;
- }
-
- if(scan_unit<MAX_I2OB<<4)
- {
- /*
- * Get the device and fill in the
- * Tid and controller.
- */
- dev=&i2ob_dev[scan_unit];
- dev->i2odev = d;
- dev->controller = c;
- dev->unit = c->unit;
- dev->tid = d->lct_data.tid;
-
- if(i2ob_install_device(c,d,scan_unit))
- printk(KERN_WARNING "Could not install I2O block device\n");
- else
- {
- scan_unit+=16;
- i2ob_dev_count++;
-
- /* We want to know when device goes away */
- i2o_device_notify_on(d, &i2o_block_handler);
- }
- }
- else
- {
- if(!warned++)
- printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
- }
- i2o_release_device(d, &i2o_block_handler);
- }
- i2o_unlock_controller(c);
- }
-}
-
-static void i2ob_probe(void)
-{
- /*
- * Some overhead/redundancy involved here, while trying to
- * claim the first boot volume encountered as /dev/i2o/hda
- * everytime. All the i2o_controllers are searched and the
- * first i2o block device marked as bootable is claimed
- * If an I2O block device was booted off , the bios sets
- * its bios_info field to 0x80, this what we search for.
- * Assuming that the bootable volume is /dev/i2o/hda
- * everytime will prevent any kernel panic while mounting
- * root partition
- */
-
- printk(KERN_INFO "i2o_block: Checking for Boot device...\n");
- i2ob_scan(1);
-
- /*
- * Now the remainder.
- */
- printk(KERN_INFO "i2o_block: Checking for I2O Block devices...\n");
- i2ob_scan(0);
-}
-
-
-/*
- * New device notification handler. Called whenever a new
- * I2O block storage device is added to the system.
- *
- * Should we spin lock around this to keep multiple devs from
- * getting updated at the same time?
- *
- */
-void i2ob_new_device(struct i2o_controller *c, struct i2o_device *d)
-{
- struct i2ob_device *dev;
- int unit = 0;
-
- printk(KERN_INFO "i2o_block: New device detected\n");
- printk(KERN_INFO " Controller %d Tid %d\n",c->unit, d->lct_data.tid);
-
- /* Check for available space */
- if(i2ob_dev_count>=MAX_I2OB<<4)
- {
- printk(KERN_ERR "i2o_block: No more devices allowed!\n");
- return;
- }
- for(unit = 0; unit < (MAX_I2OB<<4); unit += 16)
- {
- if(!i2ob_dev[unit].i2odev)
- break;
- }
-
- if(i2o_claim_device(d, &i2o_block_handler))
- {
- printk(KERN_INFO
- "i2o_block: Unable to claim device. Installation aborted\n");
- return;
- }
-
- dev = &i2ob_dev[unit];
- dev->i2odev = d;
- dev->controller = c;
- dev->tid = d->lct_data.tid;
-
- if(i2ob_install_device(c,d,unit))
- printk(KERN_ERR "i2o_block: Could not install new device\n");
- else
- {
- i2ob_dev_count++;
- i2o_device_notify_on(d, &i2o_block_handler);
- }
-
- i2o_release_device(d, &i2o_block_handler);


-
- return;
-}
-

-/*
- * Deleted device notification handler. Called when a device we
- * are talking to has been deleted by the user or some other
- * mysterious fource outside the kernel.
- */
-void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
-{
- int unit = 0;


- int i = 0;

- unsigned long flags;
-

- spin_lock_irqsave(&io_request_lock, flags);
-
- /*
- * Need to do this...we somtimes get two events from the IRTOS
- * in a row and that causes lots of problems.
- */
- i2o_device_notify_off(d, &i2o_block_handler);
-
- printk(KERN_INFO "I2O Block Device Deleted\n");
-
- for(unit = 0; unit < MAX_I2OB<<4; unit += 16)
- {
- if(i2ob_dev[unit].i2odev == d)
- {
- printk(KERN_INFO " /dev/%s: Controller %d Tid %d\n",
- d->dev_name, c->unit, d->lct_data.tid);
- break;
- }
- }
- if(unit >= MAX_I2OB<<4)
- {
- printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n");


- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
-
- /*

- * This will force errors when i2ob_get_queue() is called
- * by the kenrel.
- */
- i2ob_dev[unit].req_queue = NULL;
- for(i = unit; i <= unit+15; i++)
- {
- i2ob_dev[i].i2odev = NULL;
- i2ob_sizes[i] = 0;
- i2ob_hardsizes[i] = 0;
- i2ob_max_sectors[i] = 0;
- i2ob[i].nr_sects = 0;
- i2ob_gendisk.part[i].nr_sects = 0;


- }
- spin_unlock_irqrestore(&io_request_lock, flags);
-

- /*
- * Sync the device...this will force all outstanding I/Os
- * to attempt to complete, thus causing error messages.
- * We have to do this as the user could immediatelly create
- * a new volume that gets assigned the same minor number.
- * If there are still outstanding writes to the device,
- * that could cause data corruption on the new volume!
- *
- * The truth is that deleting a volume that you are currently
- * accessing will do _bad things_ to your system. This
- * handler will keep it from crashing, but must probably
- * you'll have to do a 'reboot' to get the system running
- * properly. Deleting disks you are using is dumb.
- * Umount them first and all will be good!
- *
- * It's not this driver's job to protect the system from
- * dumb user mistakes :)
- */
- if(i2ob_dev[unit].refcnt)
- fsync_dev(MKDEV(MAJOR_NR,unit));
-
- /*
- * Decrease usage count for module
- */
- while(i2ob_dev[unit].refcnt--)
- MOD_DEC_USE_COUNT;
-
- i2ob_dev[unit].refcnt = 0;
-
- i2ob_dev[i].tid = 0;
-
- /*
- * Do we need this?
- * The media didn't really change...the device is just gone
- */
- i2ob_media_change_flag[unit] = 1;
-
- i2ob_dev_count--;
-}
-
-/*
- * Have we seen a media change ?
- */
-static int i2ob_media_change(kdev_t dev)
-{
- int i=MINOR(dev);
- i>>=4;
- if(i2ob_media_change_flag[i])
- {
- i2ob_media_change_flag[i]=0;


- return 1;
- }
- return 0;
-}
-

-static int i2ob_revalidate(kdev_t dev)
-{
- return do_i2ob_revalidate(dev, 0);
-}
-
-/*
- * Reboot notifier. This is called by i2o_core when the system
- * shuts down.
- */
-static void i2ob_reboot_event(void)
-{
- int i;
-
- for(i=0;i<MAX_I2OB;i++)
- {
- struct i2ob_device *dev=&i2ob_dev[(i<<4)];
-
- if(dev->refcnt!=0)
- {
- /*
- * Flush the onboard cache
- */
- u32 msg[5];
- int *query_done = &dev->done_flag;
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
- msg[2] = i2ob_context|0x40000000;
- msg[3] = (u32)query_done;
- msg[4] = 60<<16;
-
- DEBUG("Flushing...");
- i2o_post_wait(dev->controller, msg, 20, 60);
-
- DEBUG("Unlocking...");
- /*
- * Unlock the media
- */
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;
- msg[2] = i2ob_context|0x40000000;
- msg[3] = (u32)query_done;
- msg[4] = -1;
- i2o_post_wait(dev->controller, msg, 20, 2);
-
- DEBUG("Unlocked.\n");
- }
- }
-}
-
-static struct block_device_operations i2ob_fops =
-{
- open: i2ob_open,
- release: i2ob_release,
- ioctl: i2ob_ioctl,
- check_media_change: i2ob_media_change,
- revalidate: i2ob_revalidate,
-};
-
-static struct gendisk i2ob_gendisk =
-{
- major: MAJOR_NR,
- major_name: "i2o/hd",
- minor_shift: 4,
- max_p: 1<<4,
- part: i2ob,
- sizes: i2ob_sizes,
- nr_real: MAX_I2OB,
- fops: &i2ob_fops,
-};
-
-
-/*
- * And here should be modules and kernel interface
- * (Just smiley confuses emacs :-)
- */
-
-#ifdef MODULE
-#define i2o_block_init init_module
-#endif
-
-int i2o_block_init(void)
-{
- int i;
-
- printk(KERN_INFO "I2O Block Storage OSM v0.9\n");
- printk(KERN_INFO " (c) Copyright 1999-2001 Red Hat Software.\n");
-
- /*
- * Register the block device interfaces
- */
-
- if (register_blkdev(MAJOR_NR, "i2o_block", &i2ob_fops)) {
- printk(KERN_ERR "Unable to get major number %d for i2o_block\n",
- MAJOR_NR);
- return -EIO;
- }
-#ifdef MODULE
- printk(KERN_INFO "i2o_block: registered device at major %d\n", MAJOR_NR);
-#endif
-
- /*
- * Now fill in the boiler plate
- */
-
- blksize_size[MAJOR_NR] = i2ob_blksizes;
- hardsect_size[MAJOR_NR] = i2ob_hardsizes;
- blk_size[MAJOR_NR] = i2ob_sizes;
- max_sectors[MAJOR_NR] = i2ob_max_sectors;
- blk_dev[MAJOR_NR].queue = i2ob_get_queue;
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
-
- for (i = 0; i < MAX_I2OB << 4; i++) {
- i2ob_dev[i].refcnt = 0;
- i2ob_dev[i].flags = 0;
- i2ob_dev[i].controller = NULL;
- i2ob_dev[i].i2odev = NULL;
- i2ob_dev[i].tid = 0;
- i2ob_dev[i].head = NULL;
- i2ob_dev[i].tail = NULL;
- i2ob_dev[i].depth = MAX_I2OB_DEPTH;
- i2ob_blksizes[i] = 1024;
- i2ob_max_sectors[i] = 2;
- }
-
- /*
- * Set up the queue
- */
- for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
- {
- i2ob_queues[i] = NULL;
- }
-
- /*
- * Timers
- */
-
- init_timer(&i2ob_timer);
- i2ob_timer.function = i2ob_timer_handler;
- i2ob_timer.data = 0;
-
- /*
- * Register the OSM handler as we will need this to probe for
- * drives, geometry and other goodies.
- */
-
- if(i2o_install_handler(&i2o_block_handler)<0)
- {
- unregister_blkdev(MAJOR_NR, "i2o_block");
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- printk(KERN_ERR "i2o_block: unable to register OSM.\n");
- return -EINVAL;
- }
- i2ob_context = i2o_block_handler.context;
-
- /*
- * Initialize event handling thread
- */
- init_MUTEX_LOCKED(&i2ob_evt_sem);
- evt_pid = kernel_thread(i2ob_evt, NULL, CLONE_SIGHAND);
- if(evt_pid < 0)
- {
- printk(KERN_ERR
- "i2o_block: Could not initialize event thread. Aborting\n");
- i2o_remove_handler(&i2o_block_handler);


- return 0;
- }
-
- /*

- * Finally see what is actually plugged in to our controllers
- */
- for (i = 0; i < MAX_I2OB; i++)
- register_disk(&i2ob_gendisk, MKDEV(MAJOR_NR,i<<4), 1<<4,
- &i2ob_fops, 0);
- i2ob_probe();
-
- /*
- * Adding i2ob_gendisk into the gendisk list.
- */
- add_gendisk(&i2ob_gendisk);


-
- return 0;
-}
-

-#ifdef MODULE
-
-EXPORT_NO_SYMBOLS;
-MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Block Device OSM");
-
-void cleanup_module(void)
-{
- struct gendisk *gdp;
- int i;
-
- if(evt_running) {
- printk(KERN_INFO "Killing I2O block threads...");
- i = kill_proc(evt_pid, SIGTERM, 1);
- if(!i) {
- printk("waiting...");
- }
- /* Be sure it died */
- wait_for_completion(&i2ob_thread_dead);
- printk("done.\n");
- }
-
- /*
- * Unregister for updates from any devices..otherwise we still
- * get them and the core jumps to random memory :O
- */
- if(i2ob_dev_count) {
- struct i2o_device *d;
- for(i = 0; i < MAX_I2OB; i++)
- if((d=i2ob_dev[i<<4].i2odev)) {
- i2o_device_notify_off(d, &i2o_block_handler);
- i2o_event_register(d->controller, d->lct_data.tid,
- i2ob_context, i<<4, 0);
- }
- }
-
- /*
- * We may get further callbacks for ourself. The i2o_core
- * code handles this case reasonably sanely. The problem here
- * is we shouldn't get them .. but a couple of cards feel
- * obliged to tell us stuff we dont care about.
- *
- * This isnt ideal at all but will do for now.
- */
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ);
-
- /*
- * Flush the OSM
- */
-
- i2o_remove_handler(&i2o_block_handler);
-
- /*
- * Return the block device
- */
- if (unregister_blkdev(MAJOR_NR, "i2o_block") != 0)
- printk("i2o_block: cleanup_module failed\n");
-
- /*
- * free request queue
- */
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
- del_gendisk(&i2ob_gendisk);
-}
-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c
--- v2.4.12/linux/drivers/i2o/i2o_config.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_config.c Wed Dec 31 16:00:00 1969
@@ -1,965 +0,0 @@
-/*
- * I2O Configuration Interface Driver


- *
- * (C) Copyright 1999 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *

- * Modified 04/20/1999 by Deepak Saxena
- * - Added basic ioctl() support
- * Modified 06/07/1999 by Deepak Saxena
- * - Added software download ioctl (still testing)
- * Modified 09/10/1999 by Auvo Häkkinen
- * - Changes to i2o_cfg_reply(), ioctl_parms()
- * - Added ioct_validate()
- * Modified 09/30/1999 by Taneli Vähäkangas
- * - Fixed ioctl_swdl()
- * Modified 10/04/1999 by Taneli Vähäkangas
- * - Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
- * Modified 11/18/199 by Deepak Saxena
- * - Added event managmenet support


- *
- * 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 <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-static int i2o_cfg_context = -1;
-static void *page_buf;
-static spinlock_t i2o_config_lock = SPIN_LOCK_UNLOCKED;
-struct wait_queue *i2o_wait_queue;
-
-#define MODINC(x,y) (x = x++ % y)
-
-struct i2o_cfg_info
-{
- struct file* fp;
- struct fasync_struct *fasync;
- struct i2o_evt_info event_q[I2O_EVT_Q_LEN];
- u16 q_in; // Queue head index
- u16 q_out; // Queue tail index
- u16 q_len; // Queue length
- u16 q_lost; // Number of lost events
- u32 q_id; // Event queue ID...used as tx_context
- struct i2o_cfg_info *next;
-};
-static struct i2o_cfg_info *open_files = NULL;
-static int i2o_cfg_info_id = 0;
-
-static int ioctl_getiops(unsigned long);
-static int ioctl_gethrt(unsigned long);
-static int ioctl_getlct(unsigned long);
-static int ioctl_parms(unsigned long, unsigned int);
-static int ioctl_html(unsigned long);
-static int ioctl_swdl(unsigned long);
-static int ioctl_swul(unsigned long);
-static int ioctl_swdel(unsigned long);
-static int ioctl_validate(unsigned long);
-static int ioctl_evt_reg(unsigned long, struct file *);
-static int ioctl_evt_get(unsigned long, struct file *);
-static int cfg_fasync(int, struct file*, int);
-
-/*
- * This is the callback for any message we have posted. The message itself
- * will be returned to the message pool when we return from the IRQ
- *
- * This runs in irq context so be short and sweet.
- */
-static void i2o_cfg_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *m)
-{
- u32 *msg = (u32 *)m;
-
- if (msg[0] & MSG_FAIL) {
- u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
-
- printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n");
-
- /* Release the preserved msg frame by resubmitting it as a NOP */
-
- preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
- preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
- preserved_msg[2] = 0;
- i2o_post_message(c, msg[7]);
- }
-
- if (msg[4] >> 24) // ReqStatus != SUCCESS
- i2o_report_status(KERN_INFO,"i2o_config", msg);
-
- if(m->function == I2O_CMD_UTIL_EVT_REGISTER)
- {
- struct i2o_cfg_info *inf;
-
- for(inf = open_files; inf; inf = inf->next)
- if(inf->q_id == msg[3])
- break;
-
- //
- // If this is the case, it means that we're getting
- // events for a file descriptor that's been close()'d
- // w/o the user unregistering for events first.
- // The code currently assumes that the user will
- // take care of unregistering for events before closing
- // a file.
- //
- // TODO:
- // Should we track event registartion and deregister
- // for events when a file is close()'d so this doesn't
- // happen? That would get rid of the search through
- // the linked list since file->private_data could point
- // directly to the i2o_config_info data structure...but
- // it would mean having all sorts of tables to track
- // what each file is registered for...I think the
- // current method is simpler. - DS
- //
- if(!inf)
- return;
-
- inf->event_q[inf->q_in].id.iop = c->unit;
- inf->event_q[inf->q_in].id.tid = m->target_tid;
- inf->event_q[inf->q_in].id.evt_mask = msg[4];
-
- //
- // Data size = msg size - reply header
- //
- inf->event_q[inf->q_in].data_size = (m->size - 5) * 4;
- if(inf->event_q[inf->q_in].data_size)
- memcpy(inf->event_q[inf->q_in].evt_data,
- (unsigned char *)(msg + 5),
- inf->event_q[inf->q_in].data_size);
-
- spin_lock(&i2o_config_lock);
- MODINC(inf->q_in, I2O_EVT_Q_LEN);
- if(inf->q_len == I2O_EVT_Q_LEN)
- {
- MODINC(inf->q_out, I2O_EVT_Q_LEN);
- inf->q_lost++;
- }
- else
- {
- // Keep I2OEVTGET on another CPU from touching this
- inf->q_len++;
- }
- spin_unlock(&i2o_config_lock);
-
-
-// printk(KERN_INFO "File %p w/id %d has %d events\n",
-// inf->fp, inf->q_id, inf->q_len);
-
- kill_fasync(&inf->fasync, SIGIO, POLL_IN);
- }


-
- return;
-}
-

-/*
- * Each of these describes an i2o message handler. They are
- * multiplexed by the i2o_core code
- */
-
-struct i2o_handler cfg_handler=
-{
- i2o_cfg_reply,
- NULL,
- NULL,
- NULL,
- "Configuration",
- 0,
- 0xffffffff // All classes
-};
-
-static ssize_t cfg_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
- printk(KERN_INFO "i2o_config write not yet supported\n");


-
- return 0;
-}
-
-

-static ssize_t cfg_read(struct file *file, char *buf, size_t count, loff_t *ptr)


-{
- return 0;
-}
-
-/*

- * IOCTL Handler
- */
-static int cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- int ret;
-
- switch(cmd)
- {
- case I2OGETIOPS:
- ret = ioctl_getiops(arg);
- break;
-
- case I2OHRTGET:
- ret = ioctl_gethrt(arg);
- break;
-
- case I2OLCTGET:
- ret = ioctl_getlct(arg);
- break;
-
- case I2OPARMSET:
- ret = ioctl_parms(arg, I2OPARMSET);
- break;
-
- case I2OPARMGET:
- ret = ioctl_parms(arg, I2OPARMGET);
- break;
-
- case I2OSWDL:
- ret = ioctl_swdl(arg);
- break;
-
- case I2OSWUL:
- ret = ioctl_swul(arg);
- break;
-
- case I2OSWDEL:
- ret = ioctl_swdel(arg);
- break;
-
- case I2OVALIDATE:
- ret = ioctl_validate(arg);
- break;
-
- case I2OHTML:
- ret = ioctl_html(arg);
- break;
-
- case I2OEVTREG:
- ret = ioctl_evt_reg(arg, fp);
- break;
-
- case I2OEVTGET:
- ret = ioctl_evt_get(arg, fp);
- break;
-
- default:
- ret = -EINVAL;


- }
-
- return ret;
-}
-

-int ioctl_getiops(unsigned long arg)
-{
- u8 *user_iop_table = (u8*)arg;
- struct i2o_controller *c = NULL;
- int i;
- u8 foo[MAX_I2O_CONTROLLERS];
-
- if(!access_ok(VERIFY_WRITE, user_iop_table, MAX_I2O_CONTROLLERS))
- return -EFAULT;
-
- for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
- {
- c = i2o_find_controller(i);
- if(c)
- {
- foo[i] = 1;
- i2o_unlock_controller(c);
- }
- else
- {
- foo[i] = 0;
- }
- }
-
- __copy_to_user(user_iop_table, foo, MAX_I2O_CONTROLLERS);


- return 0;
-}
-

-int ioctl_gethrt(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg;
- struct i2o_cmd_hrtlct kcmd;
- i2o_hrt *hrt;
- int len;
- u32 reslen;


- int ret = 0;
-

- if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
- return -EFAULT;
-
- if(get_user(reslen, kcmd.reslen) < 0)
- return -EFAULT;
-
- if(kcmd.resbuf == NULL)
- return -EFAULT;
-
- c = i2o_find_controller(kcmd.iop);
- if(!c)
- return -ENXIO;
-
- hrt = (i2o_hrt *)c->hrt;
-
- i2o_unlock_controller(c);
-
- len = 8 + ((hrt->entry_len * hrt->num_entries) << 2);
-
- /* We did a get user...so assuming mem is ok...is this bad? */
- put_user(len, kcmd.reslen);
- if(len > reslen)
- ret = -ENOBUFS;
- if(copy_to_user(kcmd.resbuf, (void*)hrt, len))
- ret = -EFAULT;


-
- return ret;
-}
-

-int ioctl_getlct(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg;
- struct i2o_cmd_hrtlct kcmd;
- i2o_lct *lct;
- int len;


- int ret = 0;

- u32 reslen;
-
- if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
- return -EFAULT;
-
- if(get_user(reslen, kcmd.reslen) < 0)
- return -EFAULT;
-
- if(kcmd.resbuf == NULL)
- return -EFAULT;
-
- c = i2o_find_controller(kcmd.iop);
- if(!c)
- return -ENXIO;
-
- lct = (i2o_lct *)c->lct;
- i2o_unlock_controller(c);
-
- len = (unsigned int)lct->table_size << 2;
- put_user(len, kcmd.reslen);
- if(len > reslen)
- ret = -ENOBUFS;
- else if(copy_to_user(kcmd.resbuf, (void*)lct, len))
- ret = -EFAULT;


-
- return ret;
-}
-

-static int ioctl_parms(unsigned long arg, unsigned int type)


-{
- int ret = 0;

- struct i2o_controller *c;
- struct i2o_cmd_psetget *cmd = (struct i2o_cmd_psetget*)arg;
- struct i2o_cmd_psetget kcmd;
- u32 reslen;
- u8 *ops;
- u8 *res;
- int len;
-
- u32 i2o_cmd = (type == I2OPARMGET ?
- I2O_CMD_UTIL_PARAMS_GET :
- I2O_CMD_UTIL_PARAMS_SET);
-
- if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_psetget)))
- return -EFAULT;
-
- if(get_user(reslen, kcmd.reslen))
- return -EFAULT;
-
- c = i2o_find_controller(kcmd.iop);
- if(!c)
- return -ENXIO;
-
- ops = (u8*)kmalloc(kcmd.oplen, GFP_KERNEL);
- if(!ops)
- {
- i2o_unlock_controller(c);
- return -ENOMEM;
- }
-
- if(copy_from_user(ops, kcmd.opbuf, kcmd.oplen))
- {
- i2o_unlock_controller(c);
- kfree(ops);
- return -EFAULT;
- }
-
- /*
- * It's possible to have a _very_ large table
- * and that the user asks for all of it at once...
- */
- res = (u8*)kmalloc(65536, GFP_KERNEL);
- if(!res)
- {
- i2o_unlock_controller(c);
- kfree(ops);
- return -ENOMEM;
- }
-
- len = i2o_issue_params(i2o_cmd, c, kcmd.tid,
- ops, kcmd.oplen, res, 65536);
- i2o_unlock_controller(c);
- kfree(ops);
-
- if (len < 0) {
- kfree(res);
- return -EAGAIN;
- }
-
- put_user(len, kcmd.reslen);
- if(len > reslen)
- ret = -ENOBUFS;
- else if(copy_to_user(cmd->resbuf, res, len))
- ret = -EFAULT;
-
- kfree(res);


-
- return ret;
-}
-

-int ioctl_html(unsigned long arg)
-{
- struct i2o_html *cmd = (struct i2o_html*)arg;
- struct i2o_html kcmd;
- struct i2o_controller *c;
- u8 *res = NULL;
- void *query = NULL;


- int ret = 0;

- int token;
- u32 len;
- u32 reslen;
- u32 msg[MSG_FRAME_SIZE/4];
-
- if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_html)))
- {
- printk(KERN_INFO "i2o_config: can't copy html cmd\n");
- return -EFAULT;
- }
-
- if(get_user(reslen, kcmd.reslen) < 0)
- {
- printk(KERN_INFO "i2o_config: can't copy html reslen\n");
- return -EFAULT;
- }
-
- if(!kcmd.resbuf)
- {
- printk(KERN_INFO "i2o_config: NULL html buffer\n");
- return -EFAULT;
- }
-
- c = i2o_find_controller(kcmd.iop);
- if(!c)
- return -ENXIO;
-
- if(kcmd.qlen) /* Check for post data */
- {
- query = kmalloc(kcmd.qlen, GFP_KERNEL);
- if(!query)
- {
- i2o_unlock_controller(c);
- return -ENOMEM;
- }
- if(copy_from_user(query, kcmd.qbuf, kcmd.qlen))
- {
- i2o_unlock_controller(c);
- printk(KERN_INFO "i2o_config: could not get query\n");
- kfree(query);
- return -EFAULT;
- }
- }
-
- res = kmalloc(65536, GFP_KERNEL);
- if(!res)
- {
- i2o_unlock_controller(c);
- kfree(query);
- return -ENOMEM;
- }
-
- msg[1] = (I2O_CMD_UTIL_CONFIG_DIALOG << 24)|HOST_TID<<12|kcmd.tid;
- msg[2] = i2o_cfg_context;
- msg[3] = 0;
- msg[4] = kcmd.page;
- msg[5] = 0xD0000000|65536;
- msg[6] = virt_to_bus(res);
- if(!kcmd.qlen) /* Check for post data */
- msg[0] = SEVEN_WORD_MSG_SIZE|SGL_OFFSET_5;
- else
- {
- msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
- msg[5] = 0x50000000|65536;
- msg[7] = 0xD4000000|(kcmd.qlen);
- msg[8] = virt_to_bus(query);
- }
- /*
- Wait for a considerable time till the Controller
- does its job before timing out. The controller might
- take more time to process this request if there are
- many devices connected to it.
- */
- token = i2o_post_wait_mem(c, msg, 9*4, 400, query, res);
- if(token < 0)
- {
- printk(KERN_DEBUG "token = %#10x\n", token);
- i2o_unlock_controller(c);
-
- if(token != -ETIMEDOUT)
- {
- kfree(res);
- if(kcmd.qlen) kfree(query);
- }
-
- return token;
- }
- i2o_unlock_controller(c);
-
- len = strnlen(res, 65536);
- put_user(len, kcmd.reslen);
- if(len > reslen)
- ret = -ENOMEM;
- if(copy_to_user(kcmd.resbuf, res, len))
- ret = -EFAULT;
-
- kfree(res);
- if(kcmd.qlen)
- kfree(query);


-
- return ret;
-}
-

-int ioctl_swdl(unsigned long arg)
-{
- struct i2o_sw_xfer kxfer;
- struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg;
- unsigned char maxfrag = 0, curfrag = 1;
- unsigned char *buffer;
- u32 msg[9];
- unsigned int status = 0, swlen = 0, fragsize = 8192;
- struct i2o_controller *c;
-
- if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if(get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- if(get_user(maxfrag, kxfer.maxfrag) < 0)
- return -EFAULT;
-
- if(get_user(curfrag, kxfer.curfrag) < 0)
- return -EFAULT;
-
- if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192;
-
- if(!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize))
- return -EFAULT;
-
- c = i2o_find_controller(kxfer.iop);
- if(!c)
- return -ENXIO;
-
- buffer=kmalloc(fragsize, GFP_KERNEL);
- if (buffer==NULL)
- {
- i2o_unlock_controller(c);
- return -ENOMEM;
- }
- __copy_from_user(buffer, kxfer.buf, fragsize);
-
- msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7;
- msg[1]= I2O_CMD_SW_DOWNLOAD<<24 | HOST_TID<<12 | ADAPTER_TID;
- msg[2]= (u32)cfg_handler.context;
- msg[3]= 0;
- msg[4]= (((u32)kxfer.flags)<<24) | (((u32)kxfer.sw_type)<<16) |
- (((u32)maxfrag)<<8) | (((u32)curfrag));
- msg[5]= swlen;
- msg[6]= kxfer.sw_id;
- msg[7]= (0xD0000000 | fragsize);
- msg[8]= virt_to_bus(buffer);
-
-// printk("i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
-
- i2o_unlock_controller(c);
- if(status != -ETIMEDOUT)
- kfree(buffer);
-
- if (status != I2O_POST_WAIT_OK)
- {
- // it fails if you try and send frags out of order
- // and for some yet unknown reasons too
- printk(KERN_INFO "i2o_config: swdl failed, DetailedStatus = %d\n", status);
- return status;
- }


-
- return 0;
-}
-

-int ioctl_swul(unsigned long arg)
-{
- struct i2o_sw_xfer kxfer;
- struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg;
- unsigned char maxfrag = 0, curfrag = 1;
- unsigned char *buffer;
- u32 msg[9];
- unsigned int status = 0, swlen = 0, fragsize = 8192;
- struct i2o_controller *c;
-
- if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if(get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- if(get_user(maxfrag, kxfer.maxfrag) < 0)
- return -EFAULT;
-
- if(get_user(curfrag, kxfer.curfrag) < 0)
- return -EFAULT;
-
- if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192;
-
- if(!kxfer.buf || !access_ok(VERIFY_WRITE, kxfer.buf, fragsize))
- return -EFAULT;
-
- c = i2o_find_controller(kxfer.iop);
- if(!c)
- return -ENXIO;
-
- buffer=kmalloc(fragsize, GFP_KERNEL);
- if (buffer==NULL)
- {
- i2o_unlock_controller(c);
- return -ENOMEM;
- }
-
- msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7;
- msg[1]= I2O_CMD_SW_UPLOAD<<24 | HOST_TID<<12 | ADAPTER_TID;
- msg[2]= (u32)cfg_handler.context;
- msg[3]= 0;
- msg[4]= (u32)kxfer.flags<<24|(u32)kxfer.sw_type<<16|(u32)maxfrag<<8|(u32)curfrag;
- msg[5]= swlen;
- msg[6]= kxfer.sw_id;
- msg[7]= (0xD0000000 | fragsize);
- msg[8]= virt_to_bus(buffer);
-
-// printk("i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
- i2o_unlock_controller(c);
-
- if (status != I2O_POST_WAIT_OK)
- {
- if(status != -ETIMEDOUT)
- kfree(buffer);
- printk(KERN_INFO "i2o_config: swul failed, DetailedStatus = %d\n", status);
- return status;
- }
-
- __copy_to_user(kxfer.buf, buffer, fragsize);
- kfree(buffer);


-
- return 0;
-}
-

-int ioctl_swdel(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_sw_xfer kxfer, *pxfer = (struct i2o_sw_xfer *)arg;
- u32 msg[7];
- unsigned int swlen;
- int token;
-
- if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if (get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- c = i2o_find_controller(kxfer.iop);
- if (!c)
- return -ENXIO;
-
- msg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
- msg[1] = I2O_CMD_SW_REMOVE<<24 | HOST_TID<<12 | ADAPTER_TID;
- msg[2] = (u32)i2o_cfg_context;
- msg[3] = 0;
- msg[4] = (u32)kxfer.flags<<24 | (u32)kxfer.sw_type<<16;
- msg[5] = swlen;
- msg[6] = kxfer.sw_id;
-
- token = i2o_post_wait(c, msg, sizeof(msg), 10);
- i2o_unlock_controller(c);
-
- if (token != I2O_POST_WAIT_OK)
- {
- printk(KERN_INFO "i2o_config: swdel failed, DetailedStatus = %d\n", token);
- return -ETIMEDOUT;
- }


-
- return 0;
-}
-

-int ioctl_validate(unsigned long arg)
-{
- int token;
- int iop = (int)arg;
- u32 msg[4];
- struct i2o_controller *c;
-
- c=i2o_find_controller(iop);
- if (!c)
- return -ENXIO;
-
- msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_CONFIG_VALIDATE<<24 | HOST_TID<<12 | iop;
- msg[2] = (u32)i2o_cfg_context;
- msg[3] = 0;
-
- token = i2o_post_wait(c, msg, sizeof(msg), 10);
- i2o_unlock_controller(c);
-
- if (token != I2O_POST_WAIT_OK)
- {
- printk(KERN_INFO "Can't validate configuration, ErrorStatus = %d\n",
- token);
- return -ETIMEDOUT;
- }


-
- return 0;
-}
-

-static int ioctl_evt_reg(unsigned long arg, struct file *fp)
-{
- u32 msg[5];
- struct i2o_evt_id *pdesc = (struct i2o_evt_id *)arg;
- struct i2o_evt_id kdesc;
- struct i2o_controller *iop;
- struct i2o_device *d;
-
- if (copy_from_user(&kdesc, pdesc, sizeof(struct i2o_evt_id)))
- return -EFAULT;
-
- /* IOP exists? */
- iop = i2o_find_controller(kdesc.iop);
- if(!iop)
- return -ENXIO;
- i2o_unlock_controller(iop);
-
- /* Device exists? */
- for(d = iop->devices; d; d = d->next)
- if(d->lct_data.tid == kdesc.tid)
- break;
-
- if(!d)
- return -ENODEV;
-
- msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_UTIL_EVT_REGISTER<<24 | HOST_TID<<12 | kdesc.tid;
- msg[2] = (u32)i2o_cfg_context;
- msg[3] = (u32)fp->private_data;
- msg[4] = kdesc.evt_mask;
-
- i2o_post_this(iop, msg, 20);


-
- return 0;
-}
-

-static int ioctl_evt_get(unsigned long arg, struct file *fp)
-{
- u32 id = (u32)fp->private_data;
- struct i2o_cfg_info *p = NULL;
- struct i2o_evt_get *uget = (struct i2o_evt_get*)arg;
- struct i2o_evt_get kget;


- unsigned long flags;
-

- for(p = open_files; p; p = p->next)
- if(p->q_id == id)
- break;
-
- if(!p->q_len)
- {
- return -ENOENT;


- return 0;
- }
-

- memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info));
- MODINC(p->q_out, I2O_EVT_Q_LEN);
- spin_lock_irqsave(&i2o_config_lock, flags);
- p->q_len--;
- kget.pending = p->q_len;
- kget.lost = p->q_lost;
- spin_unlock_irqrestore(&i2o_config_lock, flags);
-
- if(copy_to_user(uget, &kget, sizeof(struct i2o_evt_get)))
- return -EFAULT;


- return 0;
-}
-

-static int cfg_open(struct inode *inode, struct file *file)
-{
- struct i2o_cfg_info *tmp =
- (struct i2o_cfg_info *)kmalloc(sizeof(struct i2o_cfg_info), GFP_KERNEL);


- unsigned long flags;
-

- if(!tmp)
- return -ENOMEM;
-
- file->private_data = (void*)(i2o_cfg_info_id++);
- tmp->fp = file;
- tmp->fasync = NULL;
- tmp->q_id = (u32)file->private_data;
- tmp->q_len = 0;
- tmp->q_in = 0;
- tmp->q_out = 0;
- tmp->q_lost = 0;
- tmp->next = open_files;
-
- spin_lock_irqsave(&i2o_config_lock, flags);
- open_files = tmp;
- spin_unlock_irqrestore(&i2o_config_lock, flags);


-
- return 0;
-}
-

-static int cfg_release(struct inode *inode, struct file *file)
-{
- u32 id = (u32)file->private_data;
- struct i2o_cfg_info *p1, *p2;


- unsigned long flags;
-

- lock_kernel();
- p1 = p2 = NULL;
-
- spin_lock_irqsave(&i2o_config_lock, flags);
- for(p1 = open_files; p1; )
- {
- if(p1->q_id == id)
- {
-
- if(p1->fasync)
- cfg_fasync(-1, file, 0);
- if(p2)
- p2->next = p1->next;
- else
- open_files = p1->next;
-
- kfree(p1);
- break;
- }
- p2 = p1;
- p1 = p1->next;
- }
- spin_unlock_irqrestore(&i2o_config_lock, flags);
- unlock_kernel();


-
- return 0;
-}
-

-static int cfg_fasync(int fd, struct file *fp, int on)
-{
- u32 id = (u32)fp->private_data;
- struct i2o_cfg_info *p;
-
- for(p = open_files; p; p = p->next)
- if(p->q_id == id)
- break;
-
- if(!p)
- return -EBADF;
-
- return fasync_helper(fd, fp, on, &p->fasync);
-}
-
-static struct file_operations config_fops =
-{
- owner: THIS_MODULE,
- llseek: no_llseek,
- read: cfg_read,
- write: cfg_write,
- ioctl: cfg_ioctl,
- open: cfg_open,
- release: cfg_release,
- fasync: cfg_fasync,
-};
-
-static struct miscdevice i2o_miscdev = {
- I2O_MINOR,
- "i2octl",
- &config_fops
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int __init i2o_config_init(void)
-#endif
-{
- printk(KERN_INFO "I2O configuration manager v 0.04.\n");
- printk(KERN_INFO " (C) Copyright 1999 Red Hat Software\n");
-
- if((page_buf = kmalloc(4096, GFP_KERNEL))==NULL)
- {
- printk(KERN_ERR "i2o_config: no memory for page buffer.\n");
- return -ENOBUFS;
- }
- if(misc_register(&i2o_miscdev)==-1)
- {
- printk(KERN_ERR "i2o_config: can't register device.\n");
- kfree(page_buf);
- return -EBUSY;
- }
- /*
- * Install our handler
- */
- if(i2o_install_handler(&cfg_handler)<0)
- {
- kfree(page_buf);
- printk(KERN_ERR "i2o_config: handler register failed.\n");
- misc_deregister(&i2o_miscdev);
- return -EBUSY;
- }
- /*
- * The low 16bits of the transaction context must match this
- * for everything we post. Otherwise someone else gets our mail
- */
- i2o_cfg_context = cfg_handler.context;


- return 0;
-}
-

-#ifdef MODULE
-
-void cleanup_module(void)
-{
- misc_deregister(&i2o_miscdev);
-
- if(page_buf)
- kfree(page_buf);
- if(i2o_cfg_context != -1)
- i2o_remove_handler(&cfg_handler);
-}
-
-EXPORT_NO_SYMBOLS;
-MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Configuration");
-
-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c
--- v2.4.12/linux/drivers/i2o/i2o_core.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_core.c Wed Dec 31 16:00:00 1969
@@ -1,3564 +0,0 @@
-/*
- * Core I2O structure management

- *
- * (C) Copyright 1999 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three 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.
- *

- * A lot of the I2O message side code from this is taken from the
- * Red Creek RCPCI45 adapter driver by Red Creek Communications
- *
- * Fixes by:
- * Philipp Rumpf
- * Juha Sievänen <Juha.S...@cs.Helsinki.FI>
- * Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
- * Deepak Saxena <dee...@plexity.net>
- * Boji T Kannanthanam <boji.t.ka...@intel.com>
- *

- */
-
-#include <linux/config.h>

-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-#include <linux/i2o.h>
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/tqueue.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <asm/semaphore.h>
-#include <linux/completion.h>
-
-#include <asm/io.h>
-#include <linux/reboot.h>
-
-#include "i2o_lan.h"
-
-//#define DRIVERDEBUG
-
-#ifdef DRIVERDEBUG
-#define dprintk(s, args...) printk(s, ## args)
-#else
-#define dprintk(s, args...)
-#endif
-
-/* OSM table */
-static struct i2o_handler *i2o_handlers[MAX_I2O_MODULES];
-
-/* Controller list */
-static struct i2o_controller *i2o_controllers[MAX_I2O_CONTROLLERS];
-struct i2o_controller *i2o_controller_chain;
-int i2o_num_controllers;
-
-/* Initiator Context for Core message */
-static int core_context;
-
-/* Initialization && shutdown functions */
-static void i2o_sys_init(void);
-static void i2o_sys_shutdown(void);
-static int i2o_reset_controller(struct i2o_controller *);
-static int i2o_reboot_event(struct notifier_block *, unsigned long , void *);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 16'
echo 'File patch-2.4.13 is continued in part 17'
echo "17" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:47 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part17

#!/bin/sh -x
# this is part 17 of a 53 - part archive


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

if test "$Scheck" != 17; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

-static int i2o_online_controller(struct i2o_controller *);
-static int i2o_init_outbound_q(struct i2o_controller *);
-static int i2o_post_outbound_messages(struct i2o_controller *);
-
-/* Reply handler */
-static void i2o_core_reply(struct i2o_handler *, struct i2o_controller *,


- struct i2o_message *);
-

-/* Various helper functions */
-static int i2o_lct_get(struct i2o_controller *);
-static int i2o_lct_notify(struct i2o_controller *);
-static int i2o_hrt_get(struct i2o_controller *);
-
-static int i2o_build_sys_table(void);
-static int i2o_systab_send(struct i2o_controller *c);
-
-/* I2O core event handler */
-static int i2o_core_evt(void *);
-static int evt_pid;
-static int evt_running;
-
-/* Dynamic LCT update handler */
-static int i2o_dyn_lct(void *);
-
-void i2o_report_controller_unit(struct i2o_controller *, struct i2o_device *);
-
-/*
- * I2O System Table. Contains information about
- * all the IOPs in the system. Used to inform IOPs
- * about each other's existence.
- *
- * sys_tbl_ver is the CurrentChangeIndicator that is
- * used by IOPs to track changes.
- */
-static struct i2o_sys_tbl *sys_tbl;
-static int sys_tbl_ind;
-static int sys_tbl_len;
-
-/*
- * This spin lock is used to keep a device from being
- * added and deleted concurrently across CPUs or interrupts.
- * This can occur when a user creates a device and immediatelly
- * deletes it before the new_dev_notify() handler is called.
- */
-static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
-
-#ifdef MODULE
-/*
- * Function table to send to bus specific layers
- * See <include/linux/i2o.h> for explanation of this
- */
-static struct i2o_core_func_table i2o_core_functions =
-{
- i2o_install_controller,
- i2o_activate_controller,
- i2o_find_controller,
- i2o_unlock_controller,
- i2o_run_queue,
- i2o_delete_controller
-};
-
-#ifdef CONFIG_I2O_PCI_MODULE
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* CONFIG_I2O_PCI_MODULE */
-
-#endif /* MODULE */
-
-/*
- * Structures and definitions for synchronous message posting.
- * See i2o_post_wait() for description.
- */
-struct i2o_post_wait_data
-{
- int *status; /* Pointer to status block on caller stack */
- int *complete; /* Pointer to completion flag on caller stack */
- u32 id; /* Unique identifier */
- wait_queue_head_t *wq; /* Wake up for caller (NULL for dead) */
- struct i2o_post_wait_data *next; /* Chain */
- void *mem[2]; /* Memory blocks to recover on failure path */
-};
-static struct i2o_post_wait_data *post_wait_queue;
-static u32 post_wait_id; // Unique ID for each post_wait
-static spinlock_t post_wait_lock = SPIN_LOCK_UNLOCKED;
-static void i2o_post_wait_complete(u32, int);
-
-/* OSM descriptor handler */
-static struct i2o_handler i2o_core_handler =
-{
- (void *)i2o_core_reply,


- NULL,
- NULL,
- NULL,

- "I2O core layer",
- 0,
- I2O_CLASS_EXECUTIVE
-};
-
-/*
- * Used when queueing a reply to be handled later
- */
-
-struct reply_info
-{
- struct i2o_controller *iop;
- u32 msg[MSG_FRAME_SIZE];
-};
-static struct reply_info evt_reply;
-static struct reply_info events[I2O_EVT_Q_LEN];
-static int evt_in;
-static int evt_out;
-static int evt_q_len;
-#define MODINC(x,y) ((x) = ((x) + 1) % (y))
-
-/*
- * I2O configuration spinlock. This isnt a big deal for contention
- * so we have one only
- */
-
-static DECLARE_MUTEX(i2o_configuration_lock);
-
-/*
- * Event spinlock. Used to keep event queue sane and from
- * handling multiple events simultaneously.
- */
-static spinlock_t i2o_evt_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * Semaphore used to synchronize event handling thread with
- * interrupt handler.
- */
-
-static DECLARE_MUTEX(evt_sem);
-static DECLARE_COMPLETION(evt_dead);
-DECLARE_WAIT_QUEUE_HEAD(evt_wait);
-
-static struct notifier_block i2o_reboot_notifier =
-{
- i2o_reboot_event,
- NULL,
- 0
-};
-
-/*
- * Config options
- */
-
-static int verbose;
-MODULE_PARM(verbose, "i");
-
-/*
- * I2O Core reply handler
- */
-static void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c,
- struct i2o_message *m)


-{
- u32 *msg=(u32 *)m;

- u32 status;
- u32 context = msg[2];
-
- if (msg[0] & MSG_FAIL) // Fail bit is set
- {


- u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
-

- i2o_report_status(KERN_INFO, "i2o_core", msg);
- i2o_dump_message(preserved_msg);
-
- /* If the failed request needs special treatment,
- * it should be done here. */
-
- /* Release the preserved msg by resubmitting it as a NOP */


-
- preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
- preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
- preserved_msg[2] = 0;
- i2o_post_message(c, msg[7]);
-

- /* If reply to i2o_post_wait failed, return causes a timeout */


-
- return;
- }
-

-#ifdef DRIVERDEBUG
- i2o_report_status(KERN_INFO, "i2o_core", msg);
-#endif
-
- if(msg[2]&0x80000000) // Post wait message


- {
- if (msg[4] >> 24)

- status = (msg[4] & 0xFFFF);
- else
- status = I2O_POST_WAIT_OK;
-
- i2o_post_wait_complete(context, status);
- return;
- }
-


- if(m->function == I2O_CMD_UTIL_EVT_REGISTER)
- {

- memcpy(events[evt_in].msg, msg, (msg[0]>>16)<<2);
- events[evt_in].iop = c;
-
- spin_lock(&i2o_evt_lock);
- MODINC(evt_in, I2O_EVT_Q_LEN);
- if(evt_q_len == I2O_EVT_Q_LEN)
- MODINC(evt_out, I2O_EVT_Q_LEN);
- else
- evt_q_len++;
- spin_unlock(&i2o_evt_lock);
-
- up(&evt_sem);
- wake_up_interruptible(&evt_wait);
- return;
- }
-
- if(m->function == I2O_CMD_LCT_NOTIFY)
- {
- up(&c->lct_sem);


- return;
- }
-
- /*

- * If this happens, we want to dump the message to the syslog so
- * it can be sent back to the card manufacturer by the end user
- * to aid in debugging.
- *
- */
- printk(KERN_WARNING "%s: Unsolicited message reply sent to core!"
- "Message dumped to syslog\n",
- c->name);
- i2o_dump_message(msg);


-
- return;
-}
-

-/**
- * i2o_install_handler - install a message handler
- * @h: Handler structure
- *
- * Install an I2O handler - these handle the asynchronous messaging
- * from the card once it has initialised. If the table of handlers is
- * full then -ENOSPC is returned. On a success 0 is returned and the
- * context field is set by the function. The structure is part of the
- * system from this time onwards. It must not be freed until it has
- * been uninstalled
- */
-
-int i2o_install_handler(struct i2o_handler *h)
-{
- int i;
- down(&i2o_configuration_lock);
- for(i=0;i<MAX_I2O_MODULES;i++)
- {
- if(i2o_handlers[i]==NULL)
- {
- h->context = i;
- i2o_handlers[i]=h;
- up(&i2o_configuration_lock);


- return 0;
- }
- }

- up(&i2o_configuration_lock);
- return -ENOSPC;
-}
-
-/**
- * i2o_remove_handler - remove an i2o message handler
- * @h: handler
- *
- * Remove a message handler previously installed with i2o_install_handler.
- * After this function returns the handler object can be freed or re-used
- */
-
-int i2o_remove_handler(struct i2o_handler *h)
-{
- i2o_handlers[h->context]=NULL;


- return 0;
-}
-
-

-/*
- * Each I2O controller has a chain of devices on it.
- * Each device has a pointer to it's LCT entry to be used
- * for fun purposes.
- */
-
-/**
- * i2o_install_device - attach a device to a controller
- * @c: controller
- * @d: device
- *
- * Add a new device to an i2o controller. This can be called from
- * non interrupt contexts only. It adds the device and marks it as
- * unclaimed. The device memory becomes part of the kernel and must
- * be uninstalled before being freed or reused. Zero is returned
- * on success.
- */
-
-int i2o_install_device(struct i2o_controller *c, struct i2o_device *d)
-{
- int i;
-
- down(&i2o_configuration_lock);
- d->controller=c;
- d->owner=NULL;
- d->next=c->devices;
- d->prev=NULL;
- if (c->devices != NULL)
- c->devices->prev=d;
- c->devices=d;
- *d->dev_name = 0;
-
- for(i = 0; i < I2O_MAX_MANAGERS; i++)
- d->managers[i] = NULL;
-
- up(&i2o_configuration_lock);


- return 0;
-}
-

-/* we need this version to call out of i2o_delete_controller */
-
-int __i2o_delete_device(struct i2o_device *d)
-{
- struct i2o_device **p;
- int i;
-
- p=&(d->controller->devices);
-
- /*
- * Hey we have a driver!
- * Check to see if the driver wants us to notify it of
- * device deletion. If it doesn't we assume that it
- * is unsafe to delete a device with an owner and
- * fail.
- */
- if(d->owner)
- {
- if(d->owner->dev_del_notify)
- {
- dprintk(KERN_INFO "Device has owner, notifying\n");
- d->owner->dev_del_notify(d->controller, d);
- if(d->owner)
- {
- printk(KERN_WARNING
- "Driver \"%s\" did not release device!\n", d->owner->name);


- return -EBUSY;
- }
- }

- else


- return -EBUSY;
- }
-

- /*
- * Tell any other users who are talking to this device
- * that it's going away. We assume that everything works.
- */
- for(i=0; i < I2O_MAX_MANAGERS; i++)
- {
- if(d->managers[i] && d->managers[i]->dev_del_notify)
- d->managers[i]->dev_del_notify(d->controller, d);
- }
-
- while(*p!=NULL)
- {
- if(*p==d)
- {
- /*
- * Destroy
- */
- *p=d->next;
- kfree(d);
- return 0;
- }
- p=&((*p)->next);
- }
- printk(KERN_ERR "i2o_delete_device: passed invalid device.\n");


- return -EINVAL;
-}
-

-/**
- * i2o_delete_device - remove an i2o device
- * @d: device to remove
- *
- * This function unhooks a device from a controller. The device
- * will not be unhooked if it has an owner who does not wish to free
- * it, or if the owner lacks a dev_del_notify function. In that case
- * -EBUSY is returned. On success 0 is returned. Other errors cause
- * negative errno values to be returned
- */
-
-int i2o_delete_device(struct i2o_device *d)
-{
- int ret;
-
- down(&i2o_configuration_lock);
-
- /*
- * Seek, locate
- */
-
- ret = __i2o_delete_device(d);
-
- up(&i2o_configuration_lock);


-
- return ret;
-}
-

-/**
- * i2o_install_controller - attach a controller
- * @c: controller
- *
- * Add a new controller to the i2o layer. This can be called from
- * non interrupt contexts only. It adds the controller and marks it as
- * unused with no devices. If the tables are full or memory allocations
- * fail then a negative errno code is returned. On success zero is
- * returned and the controller is bound to the system. The structure
- * must not be freed or reused until being uninstalled.
- */
-
-int i2o_install_controller(struct i2o_controller *c)
-{
- int i;
- down(&i2o_configuration_lock);


- for(i=0;i<MAX_I2O_CONTROLLERS;i++)
- {

- if(i2o_controllers[i]==NULL)
- {
- c->dlct = (i2o_lct*)kmalloc(8192, GFP_KERNEL);
- if(c->dlct==NULL)
- {
- up(&i2o_configuration_lock);
- return -ENOMEM;
- }
- i2o_controllers[i]=c;
- c->devices = NULL;
- c->next=i2o_controller_chain;
- i2o_controller_chain=c;
- c->unit = i;
- c->page_frame = NULL;
- c->hrt = NULL;
- c->lct = NULL;
- c->status_block = NULL;
- sprintf(c->name, "i2o/iop%d", i);
- i2o_num_controllers++;
- init_MUTEX_LOCKED(&c->lct_sem);
- up(&i2o_configuration_lock);


- return 0;
- }
- }

- printk(KERN_ERR "No free i2o controller slots.\n");
- up(&i2o_configuration_lock);


- return -EBUSY;
-}
-

-/**
- * i2o_delete_controller - delete a controller
- * @c: controller
- *
- * Remove an i2o controller from the system. If the controller or its
- * devices are busy then -EBUSY is returned. On a failure a negative
- * errno code is returned. On success zero is returned.
- */
-
-int i2o_delete_controller(struct i2o_controller *c)
-{
- struct i2o_controller **p;
- int users;
- char name[16];
- int stat;
-
- dprintk(KERN_INFO "Deleting controller %s\n", c->name);
-
- /*
- * Clear event registration as this can cause weird behavior
- */
- if(c->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
- i2o_event_register(c, core_context, 0, 0, 0);
-
- down(&i2o_configuration_lock);
- if((users=atomic_read(&c->users)))
- {
- dprintk(KERN_INFO "I2O: %d users for controller %s\n", users,
- c->name);
- up(&i2o_configuration_lock);
- return -EBUSY;
- }
- while(c->devices)
- {
- if(__i2o_delete_device(c->devices)<0)
- {
- /* Shouldnt happen */
- c->bus_disable(c);
- up(&i2o_configuration_lock);


- return -EBUSY;
- }
- }
-

- /*
- * If this is shutdown time, the thread's already been killed
- */
- if(c->lct_running) {
- stat = kill_proc(c->lct_pid, SIGTERM, 1);
- if(!stat) {
- int count = 10 * 100;
- while(c->lct_running && --count) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
-
- if(!count)
- printk(KERN_ERR
- "%s: LCT thread still running!\n",
- c->name);
- }
- }
-
- p=&i2o_controller_chain;
-
- while(*p)
- {
- if(*p==c)
- {
- /* Ask the IOP to switch to RESET state */
- i2o_reset_controller(c);
-
- /* Release IRQ */
- c->destructor(c);
-
- *p=c->next;
- up(&i2o_configuration_lock);
-
- if(c->page_frame)
- kfree(c->page_frame);
- if(c->hrt)
- kfree(c->hrt);
- if(c->lct)
- kfree(c->lct);
- if(c->status_block)
- kfree(c->status_block);
- if(c->dlct)
- kfree(c->dlct);
-
- i2o_controllers[c->unit]=NULL;
- memcpy(name, c->name, strlen(c->name)+1);
- kfree(c);
- dprintk(KERN_INFO "%s: Deleted from controller chain.\n", name);
-
- i2o_num_controllers--;
- return 0;
- }
- p=&((*p)->next);
- }
- up(&i2o_configuration_lock);
- printk(KERN_ERR "i2o_delete_controller: bad pointer!\n");
- return -ENOENT;
-}
-
-/**
- * i2o_unlock_controller - unlock a controller
- * @c: controller to unlock
- *
- * Take a lock on an i2o controller. This prevents it being deleted.
- * i2o controllers are not refcounted so a deletion of an in use device
- * will fail, not take affect on the last dereference.
- */
-
-void i2o_unlock_controller(struct i2o_controller *c)
-{
- atomic_dec(&c->users);
-}
-
-/**
- * i2o_find_controller - return a locked controller
- * @n: controller number
- *
- * Returns a pointer to the controller object. The controller is locked
- * on return. NULL is returned if the controller is not found.
- */
-
-struct i2o_controller *i2o_find_controller(int n)


-{
- struct i2o_controller *c;
-

- if(n<0 || n>=MAX_I2O_CONTROLLERS)
- return NULL;
-
- down(&i2o_configuration_lock);
- c=i2o_controllers[n];
- if(c!=NULL)
- atomic_inc(&c->users);
- up(&i2o_configuration_lock);
- return c;
-}
-
-/**
- * i2o_issue_claim - claim or release a device
- * @cmd: command
- * @c: controller to claim for
- * @tid: i2o task id
- * @type: type of claim
- *
- * Issue I2O UTIL_CLAIM and UTIL_RELEASE messages. The message to be sent
- * is set by cmd. The tid is the task id of the object to claim and the
- * type is the claim type (see the i2o standard)
- *
- * Zero is returned on success.
- */
-
-static int i2o_issue_claim(u32 cmd, struct i2o_controller *c, int tid, u32 type)


-{
- u32 msg[5];
-

- msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;

- msg[1] = cmd << 24 | HOST_TID<<12 | tid;


- msg[3] = 0;

- msg[4] = type;
-
- return i2o_post_wait(c, msg, sizeof(msg), 60);
-}
-
-/*
- * i2o_claim_device - claim a device for use by an OSM
- * @d: device to claim
- * @h: handler for this device
- *
- * Do the leg work to assign a device to a given OSM on Linux. The
- * kernel updates the internal handler data for the device and then
- * performs an I2O claim for the device, attempting to claim the
- * device as primary. If the attempt fails a negative errno code
- * is returned. On success zero is returned.
- */
-
-int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h)
-{
- down(&i2o_configuration_lock);
- if (d->owner) {
- printk(KERN_INFO "Device claim called, but dev already owned by %s!",
- h->name);
- up(&i2o_configuration_lock);
- return -EBUSY;
- }
- d->owner=h;
-
- if(i2o_issue_claim(I2O_CMD_UTIL_CLAIM ,d->controller,d->lct_data.tid,
- I2O_CLAIM_PRIMARY))
- {
- d->owner = NULL;
- return -EBUSY;
- }
- up(&i2o_configuration_lock);


- return 0;
-}
-

-/**
- * i2o_release_device - release a device that the OSM is using
- * @d: device to claim
- * @h: handler for this device
- *
- * Drop a claim by an OSM on a given I2O device. The handler is cleared
- * and 0 is returned on success.
- *
- * AC - some devices seem to want to refuse an unclaim until they have
- * finished internal processing. It makes sense since you don't want a
- * new device to go reconfiguring the entire system until you are done.
- * Thus we are prepared to wait briefly.
- */
-
-int i2o_release_device(struct i2o_device *d, struct i2o_handler *h)
-{


- int err = 0;

- int tries;
-
- down(&i2o_configuration_lock);
- if (d->owner != h) {
- printk(KERN_INFO "Claim release called, but not owned by %s!\n",
- h->name);
- up(&i2o_configuration_lock);
- return -ENOENT;
- }
-
- for(tries=0;tries<10;tries++)
- {
- d->owner = NULL;
-
- /*
- * If the controller takes a nonblocking approach to
- * releases we have to sleep/poll for a few times.
- */
-
- if((err=i2o_issue_claim(I2O_CMD_UTIL_RELEASE, d->controller, d->lct_data.tid, I2O_CLAIM_PRIMARY)) )
- {
- err = -ENXIO;
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ);
- }
- else
- {
- err=0;
- break;
- }
- }
- up(&i2o_configuration_lock);
- return err;
-}
-
-/**
- * i2o_device_notify_on - Enable deletion notifiers
- * @d: device for notification
- * @h: handler to install
- *
- * Called by OSMs to let the core know that they want to be
- * notified if the given device is deleted from the system.
- */
-
-int i2o_device_notify_on(struct i2o_device *d, struct i2o_handler *h)


-{
- int i;
-

- if(d->num_managers == I2O_MAX_MANAGERS)
- return -ENOSPC;
-
- for(i = 0; i < I2O_MAX_MANAGERS; i++)
- {
- if(!d->managers[i])
- {
- d->managers[i] = h;


- break;
- }
- }
-

- d->num_managers++;


-
- return 0;
-}
-

-/**
- * i2o_device_notify_off - Remove deletion notifiers
- * @d: device for notification
- * @h: handler to remove
- *
- * Called by OSMs to let the core know that they no longer
- * are interested in the fate of the given device.
- */
-int i2o_device_notify_off(struct i2o_device *d, struct i2o_handler *h)


-{
- int i;
-

- for(i=0; i < I2O_MAX_MANAGERS; i++)
- {
- if(d->managers[i] == h)
- {
- d->managers[i] = NULL;
- d->num_managers--;


- return 0;
- }
- }
-

- return -ENOENT;
-}
-
-/**
- * i2o_event_register - register interest in an event
- * @c: Controller to register interest with
- * @tid: I2O task id
- * @init_context: initiator context to use with this notifier
- * @tr_context: transaction context to use with this notifier
- * @evt_mask: mask of events
- *
- * Create and posts an event registration message to the task. No reply
- * is waited for, or expected. Errors in posting will be reported.
- */
-
-int i2o_event_register(struct i2o_controller *c, u32 tid,
- u32 init_context, u32 tr_context, u32 evt_mask)
-{
- u32 msg[5]; // Not performance critical, so we just
- // i2o_post_this it instead of building it
- // in IOP memory
-

- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;

- msg[1] = I2O_CMD_UTIL_EVT_REGISTER<<24 | HOST_TID<<12 | tid;
- msg[2] = init_context;
- msg[3] = tr_context;
- msg[4] = evt_mask;
-
- return i2o_post_this(c, msg, sizeof(msg));
-}
-
-/*
- * i2o_event_ack - acknowledge an event
- * @c: controller
- * @msg: pointer to the UTIL_EVENT_REGISTER reply we received
- *
- * We just take a pointer to the original UTIL_EVENT_REGISTER reply
- * message and change the function code since that's what spec
- * describes an EventAck message looking like.
- */
-
-int i2o_event_ack(struct i2o_controller *c, u32 *msg)
-{
- struct i2o_message *m = (struct i2o_message *)msg;
-
- m->function = I2O_CMD_UTIL_EVT_ACK;
-
- return i2o_post_wait(c, msg, m->size * 4, 2);
-}
-
-/*
- * Core event handler. Runs as a separate thread and is woken
- * up whenever there is an Executive class event.
- */
-static int i2o_core_evt(void *reply_data)
-{
- struct reply_info *reply = (struct reply_info *) reply_data;
- u32 *msg = reply->msg;


- struct i2o_controller *c = NULL;

- unsigned long flags;
-
- lock_kernel();

- daemonize();
- unlock_kernel();
-

- strcpy(current->comm, "i2oevtd");


- evt_running = 1;
-
- while(1)
- {

- if(down_interruptible(&evt_sem))
- {
- dprintk(KERN_INFO "I2O event thread dead\n");
- printk("exiting...");
- evt_running = 0;
- complete_and_exit(&evt_dead, 0);
- }
-
- /*
- * Copy the data out of the queue so that we don't have to lock
- * around the whole function and just around the qlen update
- */
- spin_lock_irqsave(&i2o_evt_lock, flags);
- memcpy(reply, &events[evt_out], sizeof(struct reply_info));
- MODINC(evt_out, I2O_EVT_Q_LEN);
- evt_q_len--;
- spin_unlock_irqrestore(&i2o_evt_lock, flags);
-
- c = reply->iop;
- dprintk(KERN_INFO "I2O IRTOS EVENT: iop%d, event %#10x\n", c->unit, msg[4]);
-
- /*
- * We do not attempt to delete/quiesce/etc. the controller if
- * some sort of error indidication occurs. We may want to do
- * so in the future, but for now we just let the user deal with
- * it. One reason for this is that what to do with an error
- * or when to send what ærror is not really agreed on, so
- * we get errors that may not be fatal but just look like they
- * are...so let the user deal with it.
- */
- switch(msg[4])
- {
- case I2O_EVT_IND_EXEC_RESOURCE_LIMITS:
- printk(KERN_ERR "%s: Out of resources\n", c->name);
- break;
-
- case I2O_EVT_IND_EXEC_POWER_FAIL:
- printk(KERN_ERR "%s: Power failure\n", c->name);
- break;
-
- case I2O_EVT_IND_EXEC_HW_FAIL:
- {
- char *fail[] =
- {
- "Unknown Error",
- "Power Lost",
- "Code Violation",
- "Parity Error",
- "Code Execution Exception",
- "Watchdog Timer Expired"
- };
-
- if(msg[5] <= 6)
- printk(KERN_ERR "%s: Hardware Failure: %s\n",
- c->name, fail[msg[5]]);
- else
- printk(KERN_ERR "%s: Unknown Hardware Failure\n", c->name);
-


- break;
- }
-
- /*

- * New device created
- * - Create a new i2o_device entry
- * - Inform all interested drivers about this device's existence
- */
- case I2O_EVT_IND_EXEC_NEW_LCT_ENTRY:
- {
- struct i2o_device *d = (struct i2o_device *)
- kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
- int i;
-
- if (d == NULL) {
- printk(KERN_EMERG "i2oevtd: out of memory\n");
- break;
- }
- memcpy(&d->lct_data, &msg[5], sizeof(i2o_lct_entry));
-
- d->next = NULL;
- d->controller = c;
- d->flags = 0;
-
- i2o_report_controller_unit(c, d);
- i2o_install_device(c,d);
-
- for(i = 0; i < MAX_I2O_MODULES; i++)
- {
- if(i2o_handlers[i] &&
- i2o_handlers[i]->new_dev_notify &&
- (i2o_handlers[i]->class&d->lct_data.class_id))
- {
- spin_lock(&i2o_dev_lock);
- i2o_handlers[i]->new_dev_notify(c,d);
- spin_unlock(&i2o_dev_lock);
- }
- }
-

- break;
- }
-
- /*

- * LCT entry for a device has been modified, so update it
- * internally.
- */
- case I2O_EVT_IND_EXEC_MODIFIED_LCT:
- {
- struct i2o_device *d;
- i2o_lct_entry *new_lct = (i2o_lct_entry *)&msg[5];
-
- for(d = c->devices; d; d = d->next)
- {
- if(d->lct_data.tid == new_lct->tid)
- {
- memcpy(&d->lct_data, new_lct, sizeof(i2o_lct_entry));
- break;
- }
- }
- break;
- }
-
- case I2O_EVT_IND_CONFIGURATION_FLAG:
- printk(KERN_WARNING "%s requires user configuration\n", c->name);
- break;
-
- case I2O_EVT_IND_GENERAL_WARNING:
- printk(KERN_WARNING "%s: Warning notification received!"
- "Check configuration for errors!\n", c->name);
- break;
-
- case I2O_EVT_IND_EVT_MASK_MODIFIED:
- /* Well I guess that was us hey .. */


- break;
-
- default:

- printk(KERN_WARNING "%s: No handler for event (0x%08x)\n", c->name, msg[4]);


- break;
- }
- }
-

- return 0;
-}
-
-/*

- * Dynamic LCT update. This compares the LCT with the currently
- * installed devices to check for device deletions..this needed b/c there
- * is no DELETED_LCT_ENTRY EventIndicator for the Executive class so
- * we can't just have the event handler do this...annoying
- *
- * This is a hole in the spec that will hopefully be fixed someday.
- */
-static int i2o_dyn_lct(void *foo)
-{
- struct i2o_controller *c = (struct i2o_controller *)foo;
- struct i2o_device *d = NULL;
- struct i2o_device *d1 = NULL;
- int i = 0;
- int found = 0;
- int entries;
- void *tmp;
- char name[16];


-
- lock_kernel();
- daemonize();
- unlock_kernel();
-

- sprintf(name, "iop%d_lctd", c->unit);
- strcpy(current->comm, name);
-
- c->lct_running = 1;
-
- while(1)
- {
- down_interruptible(&c->lct_sem);
- if(signal_pending(current))
- {
- dprintk(KERN_ERR "%s: LCT thread dead\n", c->name);
- c->lct_running = 0;


- return 0;
- }
-

- entries = c->dlct->table_size;
- entries -= 3;
- entries /= 9;
-
- dprintk(KERN_INFO "%s: Dynamic LCT Update\n",c->name);
- dprintk(KERN_INFO "%s: Dynamic LCT contains %d entries\n", c->name, entries);
-
- if(!entries)
- {
- printk(KERN_INFO "%s: Empty LCT???\n", c->name);
- continue;
- }
-
- /*
- * Loop through all the devices on the IOP looking for their
- * LCT data in the LCT. We assume that TIDs are not repeated.
- * as that is the only way to really tell. It's been confirmed
- * by the IRTOS vendor(s?) that TIDs are not reused until they
- * wrap arround(4096), and I doubt a system will up long enough
- * to create/delete that many devices.
- */
- for(d = c->devices; d; )
- {
- found = 0;
- d1 = d->next;
-
- for(i = 0; i < entries; i++)
- {
- if(d->lct_data.tid == c->dlct->lct_entry[i].tid)
- {
- found = 1;
- break;
- }
- }
- if(!found)
- {
- dprintk(KERN_INFO "i2o_core: Deleted device!\n");
- spin_lock(&i2o_dev_lock);
- i2o_delete_device(d);
- spin_unlock(&i2o_dev_lock);
- }
- d = d1;
- }
-
- /*
- * Tell LCT to renotify us next time there is a change
- */
- i2o_lct_notify(c);
-
- /*
- * Copy new LCT into public LCT
- *
- * Possible race if someone is reading LCT while we are copying
- * over it. If this happens, we'll fix it then. but I doubt that
- * the LCT will get updated often enough or will get read by
- * a user often enough to worry.
- */
- if(c->lct->table_size < c->dlct->table_size)
- {
- tmp = c->lct;
- c->lct = kmalloc(c->dlct->table_size<<2, GFP_KERNEL);
- if(!c->lct)
- {
- printk(KERN_ERR "%s: No memory for LCT!\n", c->name);
- c->lct = tmp;
- continue;
- }
- kfree(tmp);
- }
- memcpy(c->lct, c->dlct, c->dlct->table_size<<2);


- }
-
- return 0;
-}
-

-/**
- * i2o_run_queue - process pending events on a controller
- * @c: controller to process
- *
- * This is called by the bus specific driver layer when an interrupt
- * or poll of this card interface is desired.
- */
-
-void i2o_run_queue(struct i2o_controller *c)
-{
- struct i2o_message *m;
- u32 mv;
- u32 *msg;
-
- /*
- * Old 960 steppings had a bug in the I2O unit that caused
- * the queue to appear empty when it wasn't.
- */
- if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF)
- mv=I2O_REPLY_READ32(c);
-
- while(mv!=0xFFFFFFFF)
- {
- struct i2o_handler *i;
- m=(struct i2o_message *)bus_to_virt(mv);
- msg=(u32*)m;
-
- i=i2o_handlers[m->initiator_context&(MAX_I2O_MODULES-1)];
- if(i && i->reply)
- i->reply(i,c,m);
- else
- {
- printk(KERN_WARNING "I2O: Spurious reply to handler %d\n",
- m->initiator_context&(MAX_I2O_MODULES-1));
- }
- i2o_flush_reply(c,mv);
- mb();
-
- /* That 960 bug again... */
- if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF)
- mv=I2O_REPLY_READ32(c);
- }
-}
-
-
-/**
- * i2o_get_class_name - do i2o class name lookup
- * @class: class number
- *
- * Return a descriptive string for an i2o class
- */
-
-const char *i2o_get_class_name(int class)
-{
- int idx = 16;
- static char *i2o_class_name[] = {
- "Executive",
- "Device Driver Module",
- "Block Device",
- "Tape Device",
- "LAN Interface",
- "WAN Interface",
- "Fibre Channel Port",
- "Fibre Channel Device",
- "SCSI Device",
- "ATE Port",
- "ATE Device",
- "Floppy Controller",
- "Floppy Device",
- "Secondary Bus Port",
- "Peer Transport Agent",
- "Peer Transport",
- "Unknown"
- };
-
- switch(class&0xFFF)
- {
- case I2O_CLASS_EXECUTIVE:
- idx = 0; break;
- case I2O_CLASS_DDM:
- idx = 1; break;
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- idx = 2; break;
- case I2O_CLASS_SEQUENTIAL_STORAGE:
- idx = 3; break;
- case I2O_CLASS_LAN:
- idx = 4; break;
- case I2O_CLASS_WAN:
- idx = 5; break;
- case I2O_CLASS_FIBRE_CHANNEL_PORT:
- idx = 6; break;
- case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
- idx = 7; break;
- case I2O_CLASS_SCSI_PERIPHERAL:
- idx = 8; break;
- case I2O_CLASS_ATE_PORT:
- idx = 9; break;
- case I2O_CLASS_ATE_PERIPHERAL:
- idx = 10; break;
- case I2O_CLASS_FLOPPY_CONTROLLER:
- idx = 11; break;
- case I2O_CLASS_FLOPPY_DEVICE:
- idx = 12; break;
- case I2O_CLASS_BUS_ADAPTER_PORT:
- idx = 13; break;
- case I2O_CLASS_PEER_TRANSPORT_AGENT:
- idx = 14; break;
- case I2O_CLASS_PEER_TRANSPORT:
- idx = 15; break;
- }
-
- return i2o_class_name[idx];
-}
-
-
-/**
- * i2o_wait_message - obtain an i2o message from the IOP
- * @c: controller
- * @why: explanation
- *
- * This function waits up to 5 seconds for a message slot to be
- * available. If no message is available it prints an error message
- * that is expected to be what the message will be used for (eg
- * "get_status"). 0xFFFFFFFF is returned on a failure.
- *
- * On a success the message is returned. This is the physical page
- * frame offset address from the read port. (See the i2o spec)
- */
-
-u32 i2o_wait_message(struct i2o_controller *c, char *why)
-{
- long time=jiffies;
- u32 m;
- while((m=I2O_POST_READ32(c))==0xFFFFFFFF)
- {
- if((jiffies-time)>=5*HZ)
- {
- dprintk(KERN_ERR "%s: Timeout waiting for message frame to send %s.\n",
- c->name, why);
- return 0xFFFFFFFF;
- }
- schedule();
- barrier();
- }
- return m;
-}
-
-/**
- * i2o_report_controller_unit - print information about a tid
- * @c: controller
- * @d: device
- *
- * Dump an information block associated with a given unit (TID). The
- * tables are read and a block of text is output to printk that is
- * formatted intended for the user.
- */
-
-void i2o_report_controller_unit(struct i2o_controller *c, struct i2o_device *d)
-{
- char buf[64];
- char str[22];
- int ret;
- int unit = d->lct_data.tid;
-
- if(verbose==0)
- return;
-
- printk(KERN_INFO "Target ID %d.\n", unit);
- if((ret=i2o_query_scalar(c, unit, 0xF100, 3, buf, 16))>=0)
- {
- buf[16]=0;
- printk(KERN_INFO " Vendor: %s\n", buf);
- }
- if((ret=i2o_query_scalar(c, unit, 0xF100, 4, buf, 16))>=0)
- {
- buf[16]=0;
- printk(KERN_INFO " Device: %s\n", buf);
- }
- if(i2o_query_scalar(c, unit, 0xF100, 5, buf, 16)>=0)
- {
- buf[16]=0;
- printk(KERN_INFO " Description: %s\n", buf);
- }
- if((ret=i2o_query_scalar(c, unit, 0xF100, 6, buf, 8))>=0)
- {
- buf[8]=0;
- printk(KERN_INFO " Rev: %s\n", buf);
- }
-
- printk(KERN_INFO " Class: ");
- sprintf(str, "%-21s", i2o_get_class_name(d->lct_data.class_id));
- printk("%s\n", str);
-
- printk(KERN_INFO " Subclass: 0x%04X\n", d->lct_data.sub_class);
- printk(KERN_INFO " Flags: ");
-
- if(d->lct_data.device_flags&(1<<0))
- printk("C"); // ConfigDialog requested
- if(d->lct_data.device_flags&(1<<1))
- printk("U"); // Multi-user capable
- if(!(d->lct_data.device_flags&(1<<4)))
- printk("P"); // Peer service enabled!
- if(!(d->lct_data.device_flags&(1<<5)))
- printk("M"); // Mgmt service enabled!
- printk("\n");
-
-}
-
-
-/*
- * Parse the hardware resource table. Right now we print it out
- * and don't do a lot with it. We should collate these and then
- * interact with the Linux resource allocation block.
- *
- * Lets prove we can read it first eh ?
- *
- * This is full of endianisms!
- */
-
-static int i2o_parse_hrt(struct i2o_controller *c)
-{
-#ifdef DRIVERDEBUG
- u32 *rows=(u32*)c->hrt;
- u8 *p=(u8 *)c->hrt;
- u8 *d;
- int count;
- int length;
- int i;
- int state;
-
- if(p[3]!=0)
- {
- printk(KERN_ERR "%s: HRT table for controller is too new a version.\n",
- c->name);


- return -1;
- }
-

- count=p[0]|(p[1]<<8);
- length = p[2];
-
- printk(KERN_INFO "%s: HRT has %d entries of %d bytes each.\n",
- c->name, count, length<<2);
-
- rows+=2;
-
- for(i=0;i<count;i++)
- {
- printk(KERN_INFO "Adapter %08X: ", rows[0]);
- p=(u8 *)(rows+1);
- d=(u8 *)(rows+2);
- state=p[1]<<8|p[0];
-
- printk("TID %04X:[", state&0xFFF);
- state>>=12;
- if(state&(1<<0))
- printk("H"); /* Hidden */
- if(state&(1<<2))
- {
- printk("P"); /* Present */
- if(state&(1<<1))
- printk("C"); /* Controlled */
- }
- if(state>9)
- printk("*"); /* Hard */
-
- printk("]:");
-
- switch(p[3]&0xFFFF)
- {
- case 0:
- /* Adapter private bus - easy */
- printk("Local bus %d: I/O at 0x%04X Mem 0x%08X",
- p[2], d[1]<<8|d[0], *(u32 *)(d+4));


- break;
- case 1:

- /* ISA bus */
- printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X",
- p[2], d[2], d[1]<<8|d[0], *(u32 *)(d+4));
- break;
-
- case 2: /* EISA bus */
- printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X",
- p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4));
- break;
-
- case 3: /* MCA bus */
- printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X",
- p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4));
- break;
-
- case 4: /* PCI bus */
- printk("PCI %d: Bus %d Device %d Function %d",
- p[2], d[2], d[1], d[0]);
- break;
-
- case 0x80: /* Other */
- default:
- printk("Unsupported bus type.");
- break;
- }
- printk("\n");
- rows+=length;
- }
-#endif


- return 0;
-}
-
-/*

- * The logical configuration table tells us what we can talk to
- * on the board. Most of the stuff isn't interesting to us.
- */
-
-static int i2o_parse_lct(struct i2o_controller *c)
-{
- int i;
- int max;
- int tid;
- struct i2o_device *d;
- i2o_lct *lct = c->lct;
-
- if (lct == NULL) {
- printk(KERN_ERR "%s: LCT is empty???\n", c->name);


- return -1;
- }
-

- max = lct->table_size;
- max -= 3;
- max /= 9;
-
- printk(KERN_INFO "%s: LCT has %d entries.\n", c->name, max);
-
- if(lct->iop_flags&(1<<0))
- printk(KERN_WARNING "%s: Configuration dialog desired.\n", c->name);
-
- for(i=0;i<max;i++)
- {
- d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
- if(d==NULL)
- {
- printk(KERN_CRIT "i2o_core: Out of memory for I2O device data.\n");


- return -ENOMEM;
- }
-

- d->controller = c;
- d->next = NULL;
-
- memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
-
- d->flags = 0;
- tid = d->lct_data.tid;
-
- i2o_report_controller_unit(c, d);
-
- i2o_install_device(c, d);


- }
- return 0;
-}
-
-

-/**
- * i2o_quiesce_controller - quiesce controller
- * @c: controller
- *
- * Quiesce an IOP. Causes IOP to make external operation quiescent
- * (i2o 'READY' state). Internal operation of the IOP continues normally.
- */
-
-int i2o_quiesce_controller(struct i2o_controller *c)
-{
- u32 msg[4];
- int ret;
-
- i2o_status_get(c);
-
- /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
-
- if ((c->status_block->iop_state != ADAPTER_STATE_READY) &&
- (c->status_block->iop_state != ADAPTER_STATE_OPERATIONAL))


- {
- return 0;
- }
-

- msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;

- msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;


- msg[3] = 0;
-

- /* Long timeout needed for quiesce if lots of devices */
-
- if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240)))
- printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n",
- c->name, -ret);
- else
- dprintk(KERN_INFO "%s: Quiesced.\n", c->name);
-
- i2o_status_get(c); // Entered READY state


- return ret;
-}
-

-/**
- * i2o_enable_controller - move controller from ready to operational
- * @c: controller
- *
- * Enable IOP. This allows the IOP to resume external operations and
- * reverses the effect of a quiesce. In the event of an error a negative
- * errno code is returned.
- */
-
-int i2o_enable_controller(struct i2o_controller *c)
-{
- u32 msg[4];
- int ret;
-
- i2o_status_get(c);
-
- /* Enable only allowed on READY state */
- if(c->status_block->iop_state != ADAPTER_STATE_READY)
- return -EINVAL;
-
- msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
-
- /* How long of a timeout do we need? */
-
- if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240)))
- printk(KERN_ERR "%s: Could not enable (status=%#x).\n",
- c->name, -ret);
- else
- dprintk(KERN_INFO "%s: Enabled.\n", c->name);
-
- i2o_status_get(c); // entered OPERATIONAL state


-
- return ret;
-}
-

-/**
- * i2o_clear_controller - clear a controller
- * @c: controller
- *
- * Clear an IOP to HOLD state, ie. terminate external operations, clear all
- * input queues and prepare for a system restart. IOP's internal operation
- * continues normally and the outbound queue is alive.
- * The IOP is not expected to rebuild its LCT.
- */
-
-int i2o_clear_controller(struct i2o_controller *c)
-{
- struct i2o_controller *iop;
- u32 msg[4];
- int ret;
-
- /* Quiesce all IOPs first */
-
- for (iop = i2o_controller_chain; iop; iop = iop->next)
- i2o_quiesce_controller(iop);
-
- msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1]=I2O_CMD_ADAPTER_CLEAR<<24|HOST_TID<<12|ADAPTER_TID;
- msg[3]=0;
-
- if ((ret=i2o_post_wait(c, msg, sizeof(msg), 30)))
- printk(KERN_INFO "%s: Unable to clear (status=%#x).\n",
- c->name, -ret);
- else
- dprintk(KERN_INFO "%s: Cleared.\n",c->name);
-
- i2o_status_get(c);
-
- /* Enable other IOPs */
-
- for (iop = i2o_controller_chain; iop; iop = iop->next)
- if (iop != c)
- i2o_enable_controller(iop);


-
- return ret;
-}
-
-

-/**
- * i2o_reset_controller - reset an IOP
- * @c: controller to reset
- *
- * Reset the IOP into INIT state and wait until IOP gets into RESET state.
- * Terminate all external operations, clear IOP's inbound and outbound
- * queues, terminate all DDMs, and reload the IOP's operating environment
- * and all local DDMs. The IOP rebuilds its LCT.
- */
-
-static int i2o_reset_controller(struct i2o_controller *c)
-{
- struct i2o_controller *iop;
- u32 m;
- u8 *status;
- u32 *msg;
- long time;
-
- /* Quiesce all IOPs first */
-
- for (iop = i2o_controller_chain; iop; iop = iop->next)
- {
- if(iop->type != I2O_TYPE_PCI || !iop->bus.pci.dpt)
- i2o_quiesce_controller(iop);
- }
-
- m=i2o_wait_message(c, "AdapterReset");
- if(m==0xFFFFFFFF)
- return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
-
- status=(void *)kmalloc(4, GFP_KERNEL);
- if(status==NULL) {
- printk(KERN_ERR "IOP reset failed - no free memory.\n");
- return -ENOMEM;
- }
- memset(status, 0, 4);
-
- msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
- msg[2]=core_context;
- msg[3]=0;
- msg[4]=0;
- msg[5]=0;
- msg[6]=virt_to_bus(status);
- msg[7]=0; /* 64bit host FIXME */
-
- i2o_post_message(c,m);
-
- /* Wait for a reply */
- time=jiffies;
- while(*status==0)
- {
- if((jiffies-time)>=20*HZ)
- {
- printk(KERN_ERR "IOP reset timeout.\n");
- // Better to leak this for safety: kfree(status);
- return -ETIMEDOUT;
- }
- schedule();
- barrier();
- }
-
- if (*status==I2O_CMD_IN_PROGRESS)
- {
- /*
- * Once the reset is sent, the IOP goes into the INIT state
- * which is indeterminate. We need to wait until the IOP
- * has rebooted before we can let the system talk to
- * it. We read the inbound Free_List until a message is
- * available. If we can't read one in the given ammount of
- * time, we assume the IOP could not reboot properly.
- */
-
- dprintk(KERN_INFO "%s: Reset in progress, waiting for reboot...\n",
- c->name);
-
- time = jiffies;
- m = I2O_POST_READ32(c);
- while(m == 0XFFFFFFFF)
- {
- if((jiffies-time) >= 30*HZ)
- {
- printk(KERN_ERR "%s: Timeout waiting for IOP reset.\n",
- c->name);
- return -ETIMEDOUT;
- }
- schedule();
- barrier();
- m = I2O_POST_READ32(c);
- }
- i2o_flush_reply(c,m);
- }
-
- /* If IopReset was rejected or didn't perform reset, try IopClear */
-
- i2o_status_get(c);
- if (status[0] == I2O_CMD_REJECTED ||
- c->status_block->iop_state != ADAPTER_STATE_RESET)
- {
- printk(KERN_WARNING "%s: Reset rejected, trying to clear\n",c->name);
- i2o_clear_controller(c);
- }
- else
- dprintk(KERN_INFO "%s: Reset completed.\n", c->name);
-
- /* Enable other IOPs */
-
- for (iop = i2o_controller_chain; iop; iop = iop->next)
- if (iop != c)
- i2o_enable_controller(iop);
-
- kfree(status);


- return 0;
-}
-
-

-/**
- * i2o_status_get - get the status block for the IOP
- * @c: controller
- *
- * Issue a status query on the controller. This updates the
- * attached status_block. If the controller fails to reply or an
- * error occurs then a negative errno code is returned. On success
- * zero is returned and the status_blok is updated.
- */
-
-int i2o_status_get(struct i2o_controller *c)
-{
- long time;
- u32 m;
- u32 *msg;
- u8 *status_block;
-
- if (c->status_block == NULL)
- {
- c->status_block = (i2o_status_block *)
- kmalloc(sizeof(i2o_status_block),GFP_KERNEL);
- if (c->status_block == NULL)
- {
- printk(KERN_CRIT "%s: Get Status Block failed; Out of memory.\n",
- c->name);


- return -ENOMEM;
- }
- }
-

- status_block = (u8*)c->status_block;
- memset(c->status_block,0,sizeof(i2o_status_block));
-
- m=i2o_wait_message(c, "StatusGet");
- if(m==0xFFFFFFFF)
- return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
-
- msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
- msg[2]=core_context;
- msg[3]=0;
- msg[4]=0;
- msg[5]=0;
- msg[6]=virt_to_bus(c->status_block);
- msg[7]=0; /* 64bit host FIXME */
- msg[8]=sizeof(i2o_status_block); /* always 88 bytes */
-
- i2o_post_message(c,m);
-
- /* Wait for a reply */
-
- time=jiffies;
- while(status_block[87]!=0xFF)
- {
- if((jiffies-time)>=5*HZ)
- {
- printk(KERN_ERR "%s: Get status timeout.\n",c->name);
- return -ETIMEDOUT;
- }
- schedule();
- barrier();
- }
-
-#ifdef DRIVERDEBUG
- printk(KERN_INFO "%s: State = ", c->name);
- switch (c->status_block->iop_state) {
- case 0x01:
- printk("INIT\n");
- break;
- case 0x02:
- printk("RESET\n");
- break;
- case 0x04:
- printk("HOLD\n");
- break;
- case 0x05:
- printk("READY\n");
- break;
- case 0x08:
- printk("OPERATIONAL\n");
- break;
- case 0x10:
- printk("FAILED\n");
- break;
- case 0x11:
- printk("FAULTED\n");
- break;
- default:
- printk("%x (unknown !!)\n",c->status_block->iop_state);
-}
-#endif

-
- return 0;
-}
-
-/*

- * Get the Hardware Resource Table for the device.
- * The HRT contains information about possible hidden devices
- * but is mostly useless to us
- */
-int i2o_hrt_get(struct i2o_controller *c)


-{
- u32 msg[6];

- int ret, size = sizeof(i2o_hrt);
-
- /* First read just the header to figure out the real size */
-
- do {
- if (c->hrt == NULL) {
- c->hrt=kmalloc(size, GFP_KERNEL);
- if (c->hrt == NULL) {
- printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", c->name);


- return -ENOMEM;
- }
- }
-

- msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
- msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;


- msg[3]= 0;

- msg[4]= (0xD0000000 | size); /* Simple transaction */
- msg[5]= virt_to_bus(c->hrt); /* Dump it here */
-
- ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL);
-
- if(ret == -ETIMEDOUT)
- {
- /* The HRT block we used is in limbo somewhere. When the iop wakes up
- we will recover it */
- c->hrt = NULL;


- return ret;
- }
-

- if(ret<0)
- {
- printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n",
- c->name, -ret);

- return ret;
- }
-

- if (c->hrt->num_entries * c->hrt->entry_len << 2 > size) {
- size = c->hrt->num_entries * c->hrt->entry_len << 2;
- kfree(c->hrt);
- c->hrt = NULL;
- }
- } while (c->hrt == NULL);
-
- i2o_parse_hrt(c); // just for debugging


-
- return 0;
-}
-
-/*

- * Send the I2O System Table to the specified IOP
- *
- * The system table contains information about all the IOPs in the
- * system. It is build and then sent to each IOP so that IOPs can
- * establish connections between each other.
- *
- */
-static int i2o_systab_send(struct i2o_controller *iop)
-{
- u32 msg[12];
- int ret;
- u32 *privbuf = kmalloc(16, GFP_KERNEL);
- if(privbuf == NULL)
- return -ENOMEM;
-
- if(iop->type == I2O_TYPE_PCI)
- {
- struct resource *root;
-
- if(iop->status_block->current_mem_size < iop->status_block->desired_mem_size)
- {
- struct resource *res = &iop->mem_resource;
- res->name = iop->bus.pci.pdev->bus->name;
- res->flags = IORESOURCE_MEM;
- res->start = 0;
- res->end = 0;
- printk("%s: requires private memory resources.\n", iop->name);
- root = pci_find_parent_resource(iop->bus.pci.pdev, res);
- if(root==NULL)
- printk("Can't find parent resource!\n");
- if(root && allocate_resource(root, res,
- iop->status_block->desired_mem_size,
- iop->status_block->desired_mem_size,
- iop->status_block->desired_mem_size,
- 1<<20, /* Unspecified, so use 1Mb and play safe */
- NULL,
- NULL)>=0)
- {
- iop->mem_alloc = 1;
- iop->status_block->current_mem_size = 1 + res->end - res->start;
- iop->status_block->current_mem_base = res->start;
- printk(KERN_INFO "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n",
- iop->name, 1+res->end-res->start, res->start);
- }
- }
- if(iop->status_block->current_io_size < iop->status_block->desired_io_size)
- {
- struct resource *res = &iop->io_resource;
- res->name = iop->bus.pci.pdev->bus->name;
- res->flags = IORESOURCE_IO;
- res->start = 0;
- res->end = 0;
- printk("%s: requires private memory resources.\n", iop->name);
- root = pci_find_parent_resource(iop->bus.pci.pdev, res);
- if(root==NULL)
- printk("Can't find parent resource!\n");
- if(root && allocate_resource(root, res,
- iop->status_block->desired_io_size,
- iop->status_block->desired_io_size,
- iop->status_block->desired_io_size,
- 1<<20, /* Unspecified, so use 1Mb and play safe */
- NULL,
- NULL)>=0)
- {
- iop->io_alloc = 1;
- iop->status_block->current_io_size = 1 + res->end - res->start;
- iop->status_block->current_mem_base = res->start;
- printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n",
- iop->name, 1+res->end-res->start, res->start);
- }
- }
- }
- else
- {
- privbuf[0] = iop->status_block->current_mem_base;
- privbuf[1] = iop->status_block->current_mem_size;
- privbuf[2] = iop->status_block->current_io_base;
- privbuf[3] = iop->status_block->current_io_size;
- }
-
- msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
- msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;


- msg[3] = 0;

- msg[4] = (0<<16) | ((iop->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
- msg[5] = 0; /* Segment 0 */
-
- /*
- * Provide three SGL-elements:
- * System table (SysTab), Private memory space declaration and
- * Private i/o space declaration
- *
- * FIXME: provide these for controllers needing them
- */
- msg[6] = 0x54000000 | sys_tbl_len;
- msg[7] = virt_to_bus(sys_tbl);
- msg[8] = 0x54000000 | 8;
- msg[9] = virt_to_bus(privbuf);
- msg[10] = 0xD4000000 | 8;
- msg[11] = virt_to_bus(privbuf+2);
-
- ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
-
- if(ret==-ETIMEDOUT)
- {
- printk(KERN_ERR "%s: SysTab setup timed out.\n", iop->name);
- }
- else if(ret<0)
- {
- printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n",
- iop->name, -ret);
- kfree(privbuf);
- }
- else
- {
- dprintk(KERN_INFO "%s: SysTab set.\n", iop->name);
- kfree(privbuf);
- }
- i2o_status_get(iop); // Entered READY state


-
- return ret;
-
- }

-
-/*
- * Initialize I2O subsystem.
- */
-static void __init i2o_sys_init(void)
-{
- struct i2o_controller *iop, *niop = NULL;
-
- printk(KERN_INFO "Activating I2O controllers...\n");
- printk(KERN_INFO "This may take a few minutes if there are many devices\n");
-
- /* In INIT state, Activate IOPs */
- for (iop = i2o_controller_chain; iop; iop = niop) {
- dprintk(KERN_INFO "Calling i2o_activate_controller for %s...\n",
- iop->name);
- niop = iop->next;
- if (i2o_activate_controller(iop) < 0)
- i2o_delete_controller(iop);
- }
-
- /* Active IOPs in HOLD state */
-
-rebuild_sys_tab:
- if (i2o_controller_chain == NULL)
- return;
-
- /*
- * If build_sys_table fails, we kill everything and bail
- * as we can't init the IOPs w/o a system table
- */
- dprintk(KERN_INFO "i2o_core: Calling i2o_build_sys_table...\n");
- if (i2o_build_sys_table() < 0) {
- i2o_sys_shutdown();
- return;
- }
-
- /* If IOP don't get online, we need to rebuild the System table */
- for (iop = i2o_controller_chain; iop; iop = niop) {
- niop = iop->next;
- dprintk(KERN_INFO "Calling i2o_online_controller for %s...\n", iop->name);
- if (i2o_online_controller(iop) < 0) {
- i2o_delete_controller(iop);
- goto rebuild_sys_tab;
- }
- }
-
- /* Active IOPs now in OPERATIONAL state */
-
- /*
- * Register for status updates from all IOPs
- */
- for(iop = i2o_controller_chain; iop; iop=iop->next) {
-
- /* Create a kernel thread to deal with dynamic LCT updates */
- iop->lct_pid = kernel_thread(i2o_dyn_lct, iop, CLONE_SIGHAND);
-
- /* Update change ind on DLCT */
- iop->dlct->change_ind = iop->lct->change_ind;
-
- /* Start dynamic LCT updates */
- i2o_lct_notify(iop);
-
- /* Register for all events from IRTOS */
- i2o_event_register(iop, core_context, 0, 0, 0xFFFFFFFF);
- }
-}
-
-/**
- * i2o_sys_shutdown - shutdown I2O system
- *
- * Bring down each i2o controller and then return. Each controller
- * is taken through an orderly shutdown
- */
-
-static void i2o_sys_shutdown(void)
-{
- struct i2o_controller *iop, *niop;
-
- /* Delete all IOPs from the controller chain */
- /* that will reset all IOPs too */
-
- for (iop = i2o_controller_chain; iop; iop = niop) {
- niop = iop->next;
- i2o_delete_controller(iop);
- }
-}
-
-/**
- * i2o_activate_controller - bring controller up to HOLD
- * @iop: controller
- *
- * This function brings an I2O controller into HOLD state. The adapter
- * is reset if neccessary and then the queues and resource table
- * are read. -1 is returned on a failure, 0 on success.


- *
- */
-

-int i2o_activate_controller(struct i2o_controller *iop)
-{
- /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
- /* In READY state, Get status */
-
- if (i2o_status_get(iop) < 0) {
- printk(KERN_INFO "Unable to obtain status of %s, "
- "attempting a reset.\n", iop->name);
- if (i2o_reset_controller(iop) < 0)


- return -1;
- }
-

- if(iop->status_block->iop_state == ADAPTER_STATE_FAULTED) {
- printk(KERN_CRIT "%s: hardware fault\n", iop->name);


- return -1;
- }
-

- if (iop->status_block->i2o_version > I2OVER15) {
- printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O Specification.\n",
- iop->name);


- return -1;
- }
-

- if (iop->status_block->iop_state == ADAPTER_STATE_READY ||
- iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
- iop->status_block->iop_state == ADAPTER_STATE_HOLD ||
- iop->status_block->iop_state == ADAPTER_STATE_FAILED)
- {
- dprintk(KERN_INFO "%s: Already running, trying to reset...\n",
- iop->name);
- if (i2o_reset_controller(iop) < 0)


- return -1;
- }
-

- if (i2o_init_outbound_q(iop) < 0)
- return -1;
-
- if (i2o_post_outbound_messages(iop))
- return -1;
-
- /* In HOLD state */
-
- if (i2o_hrt_get(iop) < 0)
- return -1;
-


- return 0;
-}
-
-

-/**
- * i2o_init_outbound_queue - setup the outbound queue
- * @c: controller
- *
- * Clear and (re)initialize IOP's outbound queue. Returns 0 on
- * success or a negative errno code on a failure.
- */
-
-int i2o_init_outbound_q(struct i2o_controller *c)
-{
- u8 *status;
- u32 m;
- u32 *msg;
- u32 time;
-
- dprintk(KERN_INFO "%s: Initializing Outbound Queue...\n", c->name);
- m=i2o_wait_message(c, "OutboundInit");
- if(m==0xFFFFFFFF)
- return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
-
- status = kmalloc(4,GFP_KERNEL);
- if (status==NULL) {
- printk(KERN_ERR "%s: Outbound Queue initialization failed - no free memory.\n",
- c->name);
- return -ENOMEM;
- }
- memset(status, 0, 4);
-
- msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6;
- msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID;
- msg[2]= core_context;
- msg[3]= 0x0106; /* Transaction context */
- msg[4]= 4096; /* Host page frame size */
- /* Frame size is in words. Pick 128, its what everyone elses uses and
- other sizes break some adapters. */
- msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */
- msg[6]= 0xD0000004; /* Simple SG LE, EOB */
- msg[7]= virt_to_bus(status);
-
- i2o_post_message(c,m);
-
- barrier();
- time=jiffies;
- while(status[0] < I2O_CMD_REJECTED)
- {
- if((jiffies-time)>=30*HZ)
- {
- if(status[0]==0x00)
- printk(KERN_ERR "%s: Ignored queue initialize request.\n",
- c->name);
- else
- printk(KERN_ERR "%s: Outbound queue initialize timeout.\n",
- c->name);
- kfree(status);
- return -ETIMEDOUT;
- }
- schedule();
- barrier();
- }
-
- if(status[0] != I2O_CMD_COMPLETED)
- {
- printk(KERN_ERR "%s: IOP outbound initialise failed.\n", c->name);
- kfree(status);


- return -ETIMEDOUT;
- }
-
- return 0;
-}
-

-/**
- * i2o_post_outbound_messages - fill message queue
- * @c: controller
- *
- * Allocate a message frame and load the messages into the IOP. The
- * function returns zero on success or a negative errno code on
- * failure.
- */
-
-int i2o_post_outbound_messages(struct i2o_controller *c)
-{
- int i;
- u32 m;
- /* Alloc space for IOP's outbound queue message frames */
-
- c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL);
- if(c->page_frame==NULL) {
- printk(KERN_CRIT "%s: Outbound Q initialize failed; out of memory.\n",
- c->name);
- return -ENOMEM;
- }
- m=virt_to_bus(c->page_frame);
-
- /* Post frames */
-
- for(i=0; i< NMBR_MSG_FRAMES; i++) {
- I2O_REPLY_WRITE32(c,m);
- mb();
- m += MSG_FRAME_SIZE;


- }
-
- return 0;
-}
-

-/*
- * Get the IOP's Logical Configuration Table
- */
-int i2o_lct_get(struct i2o_controller *c)
-{
- u32 msg[8];
- int ret, size = c->status_block->expected_lct_size;
-
- do {
- if (c->lct == NULL) {
- c->lct = kmalloc(size, GFP_KERNEL);
- if(c->lct == NULL) {
- printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
- c->name);


- return -ENOMEM;
- }
- }

- memset(c->lct, 0, size);
-
- msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
- msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
- /* msg[2] filled in i2o_post_wait */


- msg[3] = 0;

- msg[4] = 0xFFFFFFFF; /* All devices */
- msg[5] = 0x00000000; /* Report now */
- msg[6] = 0xD0000000|size;
- msg[7] = virt_to_bus(c->lct);
-
- ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL);
-
- if(ret == -ETIMEDOUT)
- {
- c->lct = NULL;


- return ret;
- }
-

- if(ret<0)
- {
- printk(KERN_ERR "%s: LCT Get failed (status=%#x.\n",
- c->name, -ret);

- return ret;
- }
-

- if (c->lct->table_size << 2 > size) {
- size = c->lct->table_size << 2;
- kfree(c->lct);
- c->lct = NULL;
- }
- } while (c->lct == NULL);
-
- if ((ret=i2o_parse_lct(c)) < 0)
- return ret;
-


- return 0;
-}
-
-/*

- * Like above, but used for async notification. The main
- * difference is that we keep track of the CurrentChangeIndiicator
- * so that we only get updates when it actually changes.
- *
- */
-int i2o_lct_notify(struct i2o_controller *c)
-{
- u32 msg[8];
-
- msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
- msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
- msg[2] = core_context;
- msg[3] = 0xDEADBEEF;
- msg[4] = 0xFFFFFFFF; /* All devices */
- msg[5] = c->dlct->change_ind+1; /* Next change */
- msg[6] = 0xD0000000|8192;
- msg[7] = virt_to_bus(c->dlct);
-
- return i2o_post_this(c, msg, sizeof(msg));
-}
-
-/*
- * Bring a controller online into OPERATIONAL state.
- */
-
-int i2o_online_controller(struct i2o_controller *iop)
-{
- u32 v;
-
- if (i2o_systab_send(iop) < 0)
- return -1;
-
- /* In READY state */
-
- dprintk(KERN_INFO "%s: Attempting to enable...\n", iop->name);
- if (i2o_enable_controller(iop) < 0)
- return -1;
-
- /* In OPERATIONAL state */
-
- dprintk(KERN_INFO "%s: Attempting to get/parse lct...\n", iop->name);
- if (i2o_lct_get(iop) < 0)
- return -1;
-
- /* Check battery status */
-
- iop->battery = 0;
- if(i2o_query_scalar(iop, ADAPTER_TID, 0x0000, 4, &v, 4)>=0)
- {
- if(v&16)
- iop->battery = 1;


- }
-
- return 0;
-}
-

-/*
- * Build system table
- *
- * The system table contains information about all the IOPs in the
- * system (duh) and is used by the Executives on the IOPs to establish
- * peer2peer connections. We're not supporting peer2peer at the moment,
- * but this will be needed down the road for things like lan2lan forwarding.
- */
-static int i2o_build_sys_table(void)
-{
- struct i2o_controller *iop = NULL;
- struct i2o_controller *niop = NULL;
- int count = 0;
-
- sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
- (i2o_num_controllers) *
- sizeof(struct i2o_sys_tbl_entry);
-
- if(sys_tbl)
- kfree(sys_tbl);
-
- sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL);
- if(!sys_tbl) {
- printk(KERN_CRIT "SysTab Set failed. Out of memory.\n");
- return -ENOMEM;
- }
- memset((void*)sys_tbl, 0, sys_tbl_len);
-
- sys_tbl->num_entries = i2o_num_controllers;
- sys_tbl->version = I2OVERSION; /* TODO: Version 2.0 */
- sys_tbl->change_ind = sys_tbl_ind++;
-
- for(iop = i2o_controller_chain; iop; iop = niop)
- {
- niop = iop->next;
-
- /*
- * Get updated IOP state so we have the latest information
- *
- * We should delete the controller at this point if it
- * doesn't respond since if it's not on the system table
- * it is techninically not part of the I2O subsyßtem...


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 17'
echo 'File patch-2.4.13 is continued in part 18'
echo "18" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:48 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part18

#!/bin/sh -x
# this is part 18 of a 53 - part archive


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

if test "$Scheck" != 18; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- */
- if(i2o_status_get(iop)) {
- printk(KERN_ERR "%s: Deleting b/c could not get status while"
- "attempting to build system table\n", iop->name);
- i2o_delete_controller(iop);
- sys_tbl->num_entries--;
- continue; // try the next one
- }
-
- sys_tbl->iops[count].org_id = iop->status_block->org_id;
- sys_tbl->iops[count].iop_id = iop->unit + 2;
- sys_tbl->iops[count].seg_num = 0;
- sys_tbl->iops[count].i2o_version =
- iop->status_block->i2o_version;
- sys_tbl->iops[count].iop_state =
- iop->status_block->iop_state;
- sys_tbl->iops[count].msg_type =
- iop->status_block->msg_type;
- sys_tbl->iops[count].frame_size =
- iop->status_block->inbound_frame_size;
- sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
- sys_tbl->iops[count].iop_capabilities =
- iop->status_block->iop_capabilities;
- sys_tbl->iops[count].inbound_low =
- (u32)virt_to_bus(iop->post_port);
- sys_tbl->iops[count].inbound_high = 0; // TODO: 64-bit support
-
- count++;
- }
-
-#ifdef DRIVERDEBUG
-{
- u32 *table;
- table = (u32*)sys_tbl;
- for(count = 0; count < (sys_tbl_len >>2); count++)
- printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", count, table[count]);


-}
-#endif
-
- return 0;
-}
-
-

-/*
- * Run time support routines
- */
-
-/*
- * Generic "post and forget" helpers. This is less efficient - we do
- * a memcpy for example that isnt strictly needed, but for most uses
- * this is simply not worth optimising
- */
-
-int i2o_post_this(struct i2o_controller *c, u32 *data, int len)
-{


- u32 m;
- u32 *msg;

- unsigned long t=jiffies;
-
- do
- {
- mb();


- m = I2O_POST_READ32(c);
- }

- while(m==0xFFFFFFFF && (jiffies-t)<HZ);
-
- if(m==0xFFFFFFFF)
- {
- printk(KERN_ERR "%s: Timeout waiting for message frame!\n",


- c->name);
- return -ETIMEDOUT;
- }

- msg = (u32 *)(c->mem_offset + m);
- memcpy_toio(msg, data, len);
- i2o_post_message(c,m);


- return 0;
-}
-
-/**

- * i2o_post_wait_mem - I2O query/reply with DMA buffers
- * @c: controller
- * @msg: message to send
- * @len: length of message
- * @timeout: time in seconds to wait
- * @mem1: attached memory buffer 1
- * @mem2: attached memory buffer 2
- *
- * This core API allows an OSM to post a message and then be told whether
- * or not the system received a successful reply.
- *
- * If the message times out then the value '-ETIMEDOUT' is returned. This
- * is a special case. In this situation the message may (should) complete
- * at an indefinite time in the future. When it completes it will use the
- * memory buffers attached to the request. If -ETIMEDOUT is returned then
- * the memory buffers must not be freed. Instead the event completion will
- * free them for you. In all other cases the buffers are your problem.
- *
- * Pass NULL for unneeded buffers.
- */
-
-int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2)
-{
- DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post);
- int complete = 0;
- int status;
- unsigned long flags = 0;
- struct i2o_post_wait_data *wait_data =
- kmalloc(sizeof(struct i2o_post_wait_data), GFP_KERNEL);
-
- if(!wait_data)
- return -ENOMEM;
-
- /*
- * Create a new notification object
- */
- wait_data->status = &status;
- wait_data->complete = &complete;
- wait_data->mem[0] = mem1;
- wait_data->mem[1] = mem2;
- /*
- * Queue the event with its unique id
- */
- spin_lock_irqsave(&post_wait_lock, flags);
-
- wait_data->next = post_wait_queue;
- post_wait_queue = wait_data;
- wait_data->id = (++post_wait_id) & 0x7fff;
- wait_data->wq = &wq_i2o_post;
-
- spin_unlock_irqrestore(&post_wait_lock, flags);
-
- /*
- * Fill in the message id
- */
-
- msg[2] = 0x80000000|(u32)core_context|((u32)wait_data->id<<16);
-
- /*
- * Post the message to the controller. At some point later it
- * will return. If we time out before it returns then
- * complete will be zero. From the point post_this returns
- * the wait_data may have been deleted.
- */
- if ((status = i2o_post_this(c, msg, len))==0) {
- sleep_on_timeout(&wq_i2o_post, HZ * timeout);
- }
- else
- return -EIO;
-
- if(signal_pending(current))
- status = -EINTR;
-
- spin_lock_irqsave(&post_wait_lock, flags);
- barrier(); /* Be sure we see complete as it is locked */
- if(!complete)
- {
- /*
- * Mark the entry dead. We cannot remove it. This is important.
- * When it does terminate (which it must do if the controller hasnt
- * died..) then it will otherwise scribble on stuff.
- * !complete lets us safely check if the entry is still
- * allocated and thus we can write into it
- */
- wait_data->wq = NULL;
- status = -ETIMEDOUT;
- }
- else
- {
- /* Debugging check - remove me soon */
- if(status == -ETIMEDOUT)
- {
- printk("TIMEDOUT BUG!\n");
- status = -EIO;
- }
- }
- /* And the wait_data is not leaked either! */
- spin_unlock_irqrestore(&post_wait_lock, flags);
- return status;
-}
-
-/**
- * i2o_post_wait - I2O query/reply
- * @c: controller
- * @msg: message to send
- * @len: length of message
- * @timeout: time in seconds to wait
- *
- * This core API allows an OSM to post a message and then be told whether
- * or not the system received a successful reply.
- */
-
-int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout)
-{
- return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL);
-}
-
-/*
- * i2o_post_wait is completed and we want to wake up the
- * sleeping proccess. Called by core's reply handler.
- */
-
-static void i2o_post_wait_complete(u32 context, int status)
-{
- struct i2o_post_wait_data **p1, *q;


- unsigned long flags;
-

- /*
- * We need to search through the post_wait
- * queue to see if the given message is still
- * outstanding. If not, it means that the IOP
- * took longer to respond to the message than we
- * had allowed and timer has already expired.
- * Not much we can do about that except log
- * it for debug purposes, increase timeout, and recompile
- *
- * Lock needed to keep anyone from moving queue pointers
- * around while we're looking through them.
- */
-
- spin_lock_irqsave(&post_wait_lock, flags);
-
- for(p1 = &post_wait_queue; *p1!=NULL; p1 = &((*p1)->next))
- {
- q = (*p1);
- if(q->id == ((context >> 16) & 0x7fff)) {
- /*
- * Delete it
- */
-
- *p1 = q->next;
-
- /*
- * Live or dead ?
- */
-
- if(q->wq)
- {
- /* Live entry - wakeup and set status */
- *q->status = status;
- *q->complete = 1;
- wake_up(q->wq);
- }
- else
- {
- /*
- * Free resources. Caller is dead
- */
- if(q->mem[0])
- kfree(q->mem[0]);
- if(q->mem[1])
- kfree(q->mem[1]);
- printk(KERN_WARNING "i2o_post_wait event completed after timeout.\n");
- }
- kfree(q);
- spin_unlock(&post_wait_lock);
- return;
- }
- }
- spin_unlock(&post_wait_lock);
-
- printk(KERN_DEBUG "i2o_post_wait: Bogus reply!\n");
-}
-
-/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
- *
- * This function can be used for all UtilParamsGet/Set operations.
- * The OperationList is given in oplist-buffer,
- * and results are returned in reslist-buffer.
- * Note that the minimum sized reslist is 8 bytes and contains
- * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
- */
-int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid,
- void *oplist, int oplen, void *reslist, int reslen)
-{
- u32 msg[9];
- u32 *res32 = (u32*)reslist;
- u32 *restmp = (u32*)reslist;
- int len = 0;


- int i = 0;

- int wait_status;
- u32 *opmem, *resmem;
-
- /* Get DMAable memory */
- opmem = kmalloc(oplen, GFP_KERNEL);
- if(opmem == NULL)
- return -ENOMEM;
- memcpy(opmem, oplist, oplen);
-
- resmem = kmalloc(reslen, GFP_KERNEL);
- if(resmem == NULL)
- {
- kfree(opmem);


- return -ENOMEM;
- }
-

- msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;

- msg[1] = cmd << 24 | HOST_TID << 12 | tid;
- msg[3] = 0;

- msg[4] = 0;
- msg[5] = 0x54000000 | oplen; /* OperationList */
- msg[6] = virt_to_bus(opmem);
- msg[7] = 0xD0000000 | reslen; /* ResultList */
- msg[8] = virt_to_bus(resmem);
-
- wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem);
-
- /*
- * This only looks like a memory leak - don't "fix" it.
- */
- if(wait_status == -ETIMEDOUT)
- return wait_status;
-
- /* Query failed */
- if(wait_status != 0)
- {
- kfree(resmem);
- kfree(opmem);
- return wait_status;
- }
-
- memcpy(reslist, resmem, reslen);
- /*
- * Calculate number of bytes of Result LIST
- * We need to loop through each Result BLOCK and grab the length
- */
- restmp = res32 + 1;
- len = 1;
- for(i = 0; i < (res32[0]&0X0000FFFF); i++)
- {
- if(restmp[0]&0x00FF0000) /* BlockStatus != SUCCESS */
- {
- printk(KERN_WARNING "%s - Error:\n ErrorInfoSize = 0x%02x, "
- "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
- (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
- : "PARAMS_GET",
- res32[1]>>24, (res32[1]>>16)&0xFF, res32[1]&0xFFFF);
-
- /*
- * If this is the only request,than we return an error
- */
- if((res32[0]&0x0000FFFF) == 1)
- {
- return -((res32[1] >> 16) & 0xFF); /* -BlockStatus */
- }
- }
- len += restmp[0] & 0x0000FFFF; /* Length of res BLOCK */
- restmp += restmp[0] & 0x0000FFFF; /* Skip to next BLOCK */
- }
- return (len << 2); /* bytes used by result list */
-}
-
-/*
- * Query one scalar group value or a whole scalar group.
- */
-int i2o_query_scalar(struct i2o_controller *iop, int tid,
- int group, int field, void *buf, int buflen)
-{
- u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
- u8 resblk[8+buflen]; /* 8 bytes for header */
- int size;
-
- if (field == -1) /* whole group */
- opblk[4] = -1;
-
- size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid,
- opblk, sizeof(opblk), resblk, sizeof(resblk));
-
- memcpy(buf, resblk+8, buflen); /* cut off header */
-
- if(size>buflen)
- return buflen;
- return size;
-}
-
-/*
- * Set a scalar group value or a whole group.
- */
-int i2o_set_scalar(struct i2o_controller *iop, int tid,
- int group, int field, void *buf, int buflen)
-{
- u16 *opblk;
- u8 resblk[8+buflen]; /* 8 bytes for header */
- int size;
-
- opblk = kmalloc(buflen+64, GFP_KERNEL);
- if (opblk == NULL)
- {
- printk(KERN_ERR "i2o: no memory for operation buffer.\n");


- return -ENOMEM;
- }
-

- opblk[0] = 1; /* operation count */
- opblk[1] = 0; /* pad */
- opblk[2] = I2O_PARAMS_FIELD_SET;
- opblk[3] = group;
-
- if(field == -1) { /* whole group */
- opblk[4] = -1;
- memcpy(opblk+5, buf, buflen);
- }
- else /* single field */
- {
- opblk[4] = 1;
- opblk[5] = field;
- memcpy(opblk+6, buf, buflen);
- }
-
- size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
- opblk, 12+buflen, resblk, sizeof(resblk));
-
- kfree(opblk);
- if(size>buflen)
- return buflen;
- return size;
-}
-
-/*
- * if oper == I2O_PARAMS_TABLE_GET, get from all rows
- * if fieldcount == -1 return all fields
- * ibuf and ibuflen are unused (use NULL, 0)
- * else return specific fields
- * ibuf contains fieldindexes
- *
- * if oper == I2O_PARAMS_LIST_GET, get from specific rows
- * if fieldcount == -1 return all fields
- * ibuf contains rowcount, keyvalues
- * else return specific fields
- * fieldcount is # of fieldindexes
- * ibuf contains fieldindexes, rowcount, keyvalues
- *
- * You could also use directly function i2o_issue_params().
- */
-int i2o_query_table(int oper, struct i2o_controller *iop, int tid, int group,
- int fieldcount, void *ibuf, int ibuflen,
- void *resblk, int reslen)
-{
- u16 *opblk;
- int size;
-
- opblk = kmalloc(10 + ibuflen, GFP_KERNEL);
- if (opblk == NULL)
- {
- printk(KERN_ERR "i2o: no memory for query buffer.\n");


- return -ENOMEM;
- }
-

- opblk[0] = 1; /* operation count */
- opblk[1] = 0; /* pad */
- opblk[2] = oper;
- opblk[3] = group;
- opblk[4] = fieldcount;
- memcpy(opblk+5, ibuf, ibuflen); /* other params */
-
- size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid,
- opblk, 10+ibuflen, resblk, reslen);
-
- kfree(opblk);
- if(size>reslen)
- return reslen;
- return size;
-}
-
-/*
- * Clear table group, i.e. delete all rows.
- */
-int i2o_clear_table(struct i2o_controller *iop, int tid, int group)
-{
- u16 opblk[] = { 1, 0, I2O_PARAMS_TABLE_CLEAR, group };
- u8 resblk[32]; /* min 8 bytes for result header */
-
- return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
- opblk, sizeof(opblk), resblk, sizeof(resblk));
-}
-
-/*
- * Add a new row into a table group.
- *
- * if fieldcount==-1 then we add whole rows
- * buf contains rowcount, keyvalues
- * else just specific fields are given, rest use defaults
- * buf contains fieldindexes, rowcount, keyvalues
- */
-int i2o_row_add_table(struct i2o_controller *iop, int tid,
- int group, int fieldcount, void *buf, int buflen)
-{
- u16 *opblk;
- u8 resblk[32]; /* min 8 bytes for header */
- int size;
-
- opblk = kmalloc(buflen+64, GFP_KERNEL);
- if (opblk == NULL)
- {
- printk(KERN_ERR "i2o: no memory for operation buffer.\n");


- return -ENOMEM;
- }
-

- opblk[0] = 1; /* operation count */
- opblk[1] = 0; /* pad */
- opblk[2] = I2O_PARAMS_ROW_ADD;
- opblk[3] = group;
- opblk[4] = fieldcount;
- memcpy(opblk+5, buf, buflen);
-
- size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
- opblk, 10+buflen, resblk, sizeof(resblk));
-
- kfree(opblk);
- if(size>buflen)
- return buflen;
- return size;
-}
-
-
-/*
- * Used for error reporting/debugging purposes.
- * Following fail status are common to all classes.
- * The preserved message must be handled in the reply handler.
- */
-void i2o_report_fail_status(u8 req_status, u32* msg)
-{
- static char *FAIL_STATUS[] = {
- "0x80", /* not used */
- "SERVICE_SUSPENDED", /* 0x81 */
- "SERVICE_TERMINATED", /* 0x82 */
- "CONGESTION",
- "FAILURE",
- "STATE_ERROR",
- "TIME_OUT",
- "ROUTING_FAILURE",
- "INVALID_VERSION",
- "INVALID_OFFSET",
- "INVALID_MSG_FLAGS",
- "FRAME_TOO_SMALL",
- "FRAME_TOO_LARGE",
- "INVALID_TARGET_ID",
- "INVALID_INITIATOR_ID",
- "INVALID_INITIATOR_CONTEX", /* 0x8F */
- "UNKNOWN_FAILURE" /* 0xFF */
- };
-
- if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
- printk("TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.", req_status);
- else
- printk("TRANSPORT_%s.\n", FAIL_STATUS[req_status & 0x0F]);
-
- /* Dump some details */
-
- printk(KERN_ERR " InitiatorId = %d, TargetId = %d\n",
- (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF);
- printk(KERN_ERR " LowestVersion = 0x%02X, HighestVersion = 0x%02X\n",
- (msg[4] >> 8) & 0xFF, msg[4] & 0xFF);
- printk(KERN_ERR " FailingHostUnit = 0x%04X, FailingIOP = 0x%03X\n",
- msg[5] >> 16, msg[5] & 0xFFF);
-
- printk(KERN_ERR " Severity: 0x%02X ", (msg[4] >> 16) & 0xFF);
- if (msg[4] & (1<<16))
- printk("(FormatError), "
- "this msg can never be delivered/processed.\n");
- if (msg[4] & (1<<17))
- printk("(PathError), "
- "this msg can no longer be delivered/processed.\n");
- if (msg[4] & (1<<18))
- printk("(PathState), "
- "the system state does not allow delivery.\n");
- if (msg[4] & (1<<19))
- printk("(Congestion), resources temporarily not available;"
- "do not retry immediately.\n");
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Following reply status are common to all classes.
- */
-void i2o_report_common_status(u8 req_status)
-{
- static char *REPLY_STATUS[] = {
- "SUCCESS",
- "ABORT_DIRTY",
- "ABORT_NO_DATA_TRANSFER",
- "ABORT_PARTIAL_TRANSFER",
- "ERROR_DIRTY",
- "ERROR_NO_DATA_TRANSFER",
- "ERROR_PARTIAL_TRANSFER",
- "PROCESS_ABORT_DIRTY",
- "PROCESS_ABORT_NO_DATA_TRANSFER",
- "PROCESS_ABORT_PARTIAL_TRANSFER",
- "TRANSACTION_ERROR",
- "PROGRESS_REPORT"
- };
-
- if (req_status > I2O_REPLY_STATUS_PROGRESS_REPORT)
- printk("RequestStatus = %0#2x", req_status);
- else
- printk("%s", REPLY_STATUS[req_status]);
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Following detailed status are valid for executive class,
- * utility class, DDM class and for transaction error replies.
- */
-static void i2o_report_common_dsc(u16 detailed_status)
-{
- static char *COMMON_DSC[] = {
- "SUCCESS",
- "0x01", // not used
- "BAD_KEY",
- "TCL_ERROR",
- "REPLY_BUFFER_FULL",
- "NO_SUCH_PAGE",
- "INSUFFICIENT_RESOURCE_SOFT",
- "INSUFFICIENT_RESOURCE_HARD",
- "0x08", // not used
- "CHAIN_BUFFER_TOO_LARGE",
- "UNSUPPORTED_FUNCTION",
- "DEVICE_LOCKED",
- "DEVICE_RESET",
- "INAPPROPRIATE_FUNCTION",
- "INVALID_INITIATOR_ADDRESS",
- "INVALID_MESSAGE_FLAGS",
- "INVALID_OFFSET",
- "INVALID_PARAMETER",
- "INVALID_REQUEST",
- "INVALID_TARGET_ADDRESS",
- "MESSAGE_TOO_LARGE",
- "MESSAGE_TOO_SMALL",
- "MISSING_PARAMETER",
- "TIMEOUT",
- "UNKNOWN_ERROR",
- "UNKNOWN_FUNCTION",
- "UNSUPPORTED_VERSION",
- "DEVICE_BUSY",
- "DEVICE_NOT_AVAILABLE"
- };
-
- if (detailed_status > I2O_DSC_DEVICE_NOT_AVAILABLE)
- printk(" / DetailedStatus = %0#4x.\n", detailed_status);
- else
- printk(" / %s.\n", COMMON_DSC[detailed_status]);
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_lan_dsc(u16 detailed_status)
-{
- static char *LAN_DSC[] = { // Lan detailed status code strings
- "SUCCESS",
- "DEVICE_FAILURE",
- "DESTINATION_NOT_FOUND",
- "TRANSMIT_ERROR",
- "TRANSMIT_ABORTED",
- "RECEIVE_ERROR",
- "RECEIVE_ABORTED",
- "DMA_ERROR",
- "BAD_PACKET_DETECTED",
- "OUT_OF_MEMORY",
- "BUCKET_OVERRUN",
- "IOP_INTERNAL_ERROR",
- "CANCELED",
- "INVALID_TRANSACTION_CONTEXT",
- "DEST_ADDRESS_DETECTED",
- "DEST_ADDRESS_OMITTED",
- "PARTIAL_PACKET_RETURNED",
- "TEMP_SUSPENDED_STATE", // last Lan detailed status code
- "INVALID_REQUEST" // general detailed status code
- };
-
- if (detailed_status > I2O_DSC_INVALID_REQUEST)
- printk(" / %0#4x.\n", detailed_status);
- else
- printk(" / %s.\n", LAN_DSC[detailed_status]);
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_util_cmd(u8 cmd)
-{
- switch (cmd) {
- case I2O_CMD_UTIL_NOP:
- printk("UTIL_NOP, ");
- break;
- case I2O_CMD_UTIL_ABORT:
- printk("UTIL_ABORT, ");
- break;
- case I2O_CMD_UTIL_CLAIM:
- printk("UTIL_CLAIM, ");
- break;
- case I2O_CMD_UTIL_RELEASE:
- printk("UTIL_CLAIM_RELEASE, ");
- break;
- case I2O_CMD_UTIL_CONFIG_DIALOG:
- printk("UTIL_CONFIG_DIALOG, ");
- break;
- case I2O_CMD_UTIL_DEVICE_RESERVE:
- printk("UTIL_DEVICE_RESERVE, ");
- break;
- case I2O_CMD_UTIL_DEVICE_RELEASE:
- printk("UTIL_DEVICE_RELEASE, ");
- break;
- case I2O_CMD_UTIL_EVT_ACK:
- printk("UTIL_EVENT_ACKNOWLEDGE, ");
- break;
- case I2O_CMD_UTIL_EVT_REGISTER:
- printk("UTIL_EVENT_REGISTER, ");
- break;
- case I2O_CMD_UTIL_LOCK:
- printk("UTIL_LOCK, ");
- break;
- case I2O_CMD_UTIL_LOCK_RELEASE:
- printk("UTIL_LOCK_RELEASE, ");
- break;
- case I2O_CMD_UTIL_PARAMS_GET:
- printk("UTIL_PARAMS_GET, ");
- break;
- case I2O_CMD_UTIL_PARAMS_SET:
- printk("UTIL_PARAMS_SET, ");
- break;
- case I2O_CMD_UTIL_REPLY_FAULT_NOTIFY:
- printk("UTIL_REPLY_FAULT_NOTIFY, ");
- break;
- default:
- printk("Cmd = %0#2x, ",cmd);
- }
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_exec_cmd(u8 cmd)
-{
- switch (cmd) {
- case I2O_CMD_ADAPTER_ASSIGN:
- printk("EXEC_ADAPTER_ASSIGN, ");
- break;
- case I2O_CMD_ADAPTER_READ:
- printk("EXEC_ADAPTER_READ, ");
- break;
- case I2O_CMD_ADAPTER_RELEASE:
- printk("EXEC_ADAPTER_RELEASE, ");
- break;
- case I2O_CMD_BIOS_INFO_SET:
- printk("EXEC_BIOS_INFO_SET, ");
- break;
- case I2O_CMD_BOOT_DEVICE_SET:
- printk("EXEC_BOOT_DEVICE_SET, ");
- break;
- case I2O_CMD_CONFIG_VALIDATE:
- printk("EXEC_CONFIG_VALIDATE, ");
- break;
- case I2O_CMD_CONN_SETUP:
- printk("EXEC_CONN_SETUP, ");
- break;
- case I2O_CMD_DDM_DESTROY:
- printk("EXEC_DDM_DESTROY, ");
- break;
- case I2O_CMD_DDM_ENABLE:
- printk("EXEC_DDM_ENABLE, ");
- break;
- case I2O_CMD_DDM_QUIESCE:
- printk("EXEC_DDM_QUIESCE, ");
- break;
- case I2O_CMD_DDM_RESET:
- printk("EXEC_DDM_RESET, ");
- break;
- case I2O_CMD_DDM_SUSPEND:
- printk("EXEC_DDM_SUSPEND, ");
- break;
- case I2O_CMD_DEVICE_ASSIGN:
- printk("EXEC_DEVICE_ASSIGN, ");
- break;
- case I2O_CMD_DEVICE_RELEASE:
- printk("EXEC_DEVICE_RELEASE, ");
- break;
- case I2O_CMD_HRT_GET:
- printk("EXEC_HRT_GET, ");
- break;
- case I2O_CMD_ADAPTER_CLEAR:
- printk("EXEC_IOP_CLEAR, ");
- break;
- case I2O_CMD_ADAPTER_CONNECT:
- printk("EXEC_IOP_CONNECT, ");
- break;
- case I2O_CMD_ADAPTER_RESET:
- printk("EXEC_IOP_RESET, ");
- break;
- case I2O_CMD_LCT_NOTIFY:
- printk("EXEC_LCT_NOTIFY, ");
- break;
- case I2O_CMD_OUTBOUND_INIT:
- printk("EXEC_OUTBOUND_INIT, ");
- break;
- case I2O_CMD_PATH_ENABLE:
- printk("EXEC_PATH_ENABLE, ");
- break;
- case I2O_CMD_PATH_QUIESCE:
- printk("EXEC_PATH_QUIESCE, ");
- break;
- case I2O_CMD_PATH_RESET:
- printk("EXEC_PATH_RESET, ");
- break;
- case I2O_CMD_STATIC_MF_CREATE:
- printk("EXEC_STATIC_MF_CREATE, ");
- break;
- case I2O_CMD_STATIC_MF_RELEASE:
- printk("EXEC_STATIC_MF_RELEASE, ");
- break;
- case I2O_CMD_STATUS_GET:
- printk("EXEC_STATUS_GET, ");
- break;
- case I2O_CMD_SW_DOWNLOAD:
- printk("EXEC_SW_DOWNLOAD, ");
- break;
- case I2O_CMD_SW_UPLOAD:
- printk("EXEC_SW_UPLOAD, ");
- break;
- case I2O_CMD_SW_REMOVE:
- printk("EXEC_SW_REMOVE, ");
- break;
- case I2O_CMD_SYS_ENABLE:
- printk("EXEC_SYS_ENABLE, ");
- break;
- case I2O_CMD_SYS_MODIFY:
- printk("EXEC_SYS_MODIFY, ");
- break;
- case I2O_CMD_SYS_QUIESCE:
- printk("EXEC_SYS_QUIESCE, ");
- break;
- case I2O_CMD_SYS_TAB_SET:
- printk("EXEC_SYS_TAB_SET, ");
- break;
- default:
- printk("Cmd = %#02x, ",cmd);
- }
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_lan_cmd(u8 cmd)
-{
- switch (cmd) {
- case LAN_PACKET_SEND:
- printk("LAN_PACKET_SEND, ");
- break;
- case LAN_SDU_SEND:
- printk("LAN_SDU_SEND, ");
- break;
- case LAN_RECEIVE_POST:
- printk("LAN_RECEIVE_POST, ");
- break;
- case LAN_RESET:
- printk("LAN_RESET, ");
- break;
- case LAN_SUSPEND:
- printk("LAN_SUSPEND, ");
- break;
- default:
- printk("Cmd = %0#2x, ",cmd);
- }
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Report Cmd name, Request status, Detailed Status.
- */
-void i2o_report_status(const char *severity, const char *str, u32 *msg)
-{
- u8 cmd = (msg[1]>>24)&0xFF;
- u8 req_status = (msg[4]>>24)&0xFF;
- u16 detailed_status = msg[4]&0xFFFF;
- struct i2o_handler *h = i2o_handlers[msg[2] & (MAX_I2O_MODULES-1)];
-
- printk("%s%s: ", severity, str);
-
- if (cmd < 0x1F) // Utility cmd
- i2o_report_util_cmd(cmd);
-
- else if (cmd >= 0xA0 && cmd <= 0xEF) // Executive cmd
- i2o_report_exec_cmd(cmd);
-
- else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F)
- i2o_report_lan_cmd(cmd); // LAN cmd
- else
- printk("Cmd = %0#2x, ", cmd); // Other cmds
-
- if (msg[0] & MSG_FAIL) {
- i2o_report_fail_status(req_status, msg);
- return;
- }
-
- i2o_report_common_status(req_status);
-
- if (cmd < 0x1F || (cmd >= 0xA0 && cmd <= 0xEF))
- i2o_report_common_dsc(detailed_status);
- else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F)
- i2o_report_lan_dsc(detailed_status);
- else
- printk(" / DetailedStatus = %0#4x.\n", detailed_status);
-}
-
-/* Used to dump a message to syslog during debugging */
-void i2o_dump_message(u32 *msg)
-{
-#ifdef DRIVERDEBUG
- int i;
- printk(KERN_INFO "Dumping I2O message size %d @ %p\n",
- msg[0]>>16&0xffff, msg);
- for(i = 0; i < ((msg[0]>>16)&0xffff); i++)
- printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]);
-#endif
-}
-
-/*
- * I2O reboot/shutdown notification.
- *
- * - Call each OSM's reboot notifier (if one exists)
- * - Quiesce each IOP in the system
- *
- * Each IOP has to be quiesced before we can ensure that the system
- * can be properly shutdown as a transaction that has already been
- * acknowledged still needs to be placed in permanent store on the IOP.
- * The SysQuiesce causes the IOP to force all HDMs to complete their
- * transactions before returning, so only at that point is it safe
- *
- */
-static int i2o_reboot_event(struct notifier_block *n, unsigned long code, void
-*p)
-{


- int i = 0;

- struct i2o_controller *c = NULL;
-

- if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
- return NOTIFY_DONE;
-
- printk(KERN_INFO "Shutting down I2O system.\n");
- printk(KERN_INFO
- " This could take a few minutes if there are many devices attached\n");


-
- for(i = 0; i < MAX_I2O_MODULES; i++)
- {

- if(i2o_handlers[i] && i2o_handlers[i]->reboot_notify)
- i2o_handlers[i]->reboot_notify();
- }
-
- for(c = i2o_controller_chain; c; c = c->next)
- {
- if(i2o_quiesce_controller(c))
- {
- printk(KERN_WARNING "i2o: Could not quiesce %s." "
- Verify setup on next system power up.\n", c->name);
- }
- }
-
- printk(KERN_INFO "I2O system down.\n");
- return NOTIFY_DONE;
-}
-
-
-EXPORT_SYMBOL(i2o_controller_chain);
-EXPORT_SYMBOL(i2o_num_controllers);
-EXPORT_SYMBOL(i2o_find_controller);
-EXPORT_SYMBOL(i2o_unlock_controller);
-EXPORT_SYMBOL(i2o_status_get);
-
-EXPORT_SYMBOL(i2o_install_handler);
-EXPORT_SYMBOL(i2o_remove_handler);
-
-EXPORT_SYMBOL(i2o_claim_device);
-EXPORT_SYMBOL(i2o_release_device);
-EXPORT_SYMBOL(i2o_device_notify_on);
-EXPORT_SYMBOL(i2o_device_notify_off);
-
-EXPORT_SYMBOL(i2o_post_this);
-EXPORT_SYMBOL(i2o_post_wait);
-EXPORT_SYMBOL(i2o_post_wait_mem);
-
-EXPORT_SYMBOL(i2o_query_scalar);
-EXPORT_SYMBOL(i2o_set_scalar);
-EXPORT_SYMBOL(i2o_query_table);
-EXPORT_SYMBOL(i2o_clear_table);
-EXPORT_SYMBOL(i2o_row_add_table);
-EXPORT_SYMBOL(i2o_issue_params);
-
-EXPORT_SYMBOL(i2o_event_register);
-EXPORT_SYMBOL(i2o_event_ack);
-
-EXPORT_SYMBOL(i2o_report_status);
-EXPORT_SYMBOL(i2o_dump_message);
-
-EXPORT_SYMBOL(i2o_get_class_name);
-
-#ifdef MODULE
-


-MODULE_AUTHOR("Red Hat Software");

-MODULE_DESCRIPTION("I2O Core");


-
-
-int init_module(void)
-{

- printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
- if (i2o_install_handler(&i2o_core_handler) < 0)
- {
- printk(KERN_ERR
- "i2o_core: Unable to install core handler.\nI2O stack not loaded!");


- return 0;
- }
-

- core_context = i2o_core_handler.context;
-
- /*
- * Attach core to I2O PCI transport (and others as they are developed)
- */
-#ifdef CONFIG_I2O_PCI_MODULE
- if(i2o_pci_core_attach(&i2o_core_functions) < 0)
- printk(KERN_INFO "i2o: No PCI I2O controllers found\n");
-#endif
-
- /*


- * Initialize event handling thread
- */

- init_MUTEX_LOCKED(&evt_sem);
- evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND);
- if(evt_pid < 0)
- {
- printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
- i2o_remove_handler(&i2o_core_handler);
- return 0;
- }
- else
- printk(KERN_INFO "I2O: Event thread created as pid %d\n", evt_pid);
-
- if(i2o_num_controllers)
- i2o_sys_init();
-
- register_reboot_notifier(&i2o_reboot_notifier);


-
- return 0;
-}
-

-void cleanup_module(void)
-{
- int stat;
-
- unregister_reboot_notifier(&i2o_reboot_notifier);
-
- if(i2o_num_controllers)
- i2o_sys_shutdown();
-
- /*
- * If this is shutdown time, the thread has already been killed
- */
- if(evt_running) {
- printk("Terminating i2o threads...");
- stat = kill_proc(evt_pid, SIGTERM, 1);
- if(!stat) {
- printk("waiting...");
- wait_for_completion(&evt_dead);
- }


- printk("done.\n");
- }
-

-#ifdef CONFIG_I2O_PCI_MODULE
- i2o_pci_core_detach();
-#endif
-
- i2o_remove_handler(&i2o_core_handler);
-
- unregister_reboot_notifier(&i2o_reboot_notifier);
-}
-
-#else
-
-extern int i2o_block_init(void);
-extern int i2o_config_init(void);
-extern int i2o_lan_init(void);
-extern int i2o_pci_init(void);
-extern int i2o_proc_init(void);
-extern int i2o_scsi_init(void);
-
-int __init i2o_init(void)
-{
- printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n");
-
- if (i2o_install_handler(&i2o_core_handler) < 0)
- {
- printk(KERN_ERR
- "i2o_core: Unable to install core handler.\nI2O stack not loaded!");


- return 0;
- }
-

- core_context = i2o_core_handler.context;
-
- /*


- * Initialize event handling thread

- * We may not find any controllers, but still want this as
- * down the road we may have hot pluggable controllers that
- * need to be dealt with.
- */
- init_MUTEX_LOCKED(&evt_sem);
- if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0)
- {
- printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
- i2o_remove_handler(&i2o_core_handler);


- return 0;
- }
-
-

-#ifdef CONFIG_I2O_PCI
- i2o_pci_init();
-#endif
-
- if(i2o_num_controllers)
- i2o_sys_init();
-
- register_reboot_notifier(&i2o_reboot_notifier);
-
- i2o_config_init();
-#ifdef CONFIG_I2O_BLOCK
- i2o_block_init();
-#endif
-#ifdef CONFIG_I2O_LAN
- i2o_lan_init();
-#endif
-#ifdef CONFIG_I2O_PROC
- i2o_proc_init();


-#endif
- return 0;
-}
-

-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c
--- v2.4.12/linux/drivers/i2o/i2o_lan.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_lan.c Wed Dec 31 16:00:00 1969
@@ -1,1577 +0,0 @@
-/*
- * drivers/i2o/i2o_lan.c
- *
- * I2O LAN CLASS OSM May 26th 2000
- *
- * (C) Copyright 1999, 2000 University of Helsinki,
- * Department of Computer Science
- *
- * This code is still under development / test.
- *


- * 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.
- *

- * Authors: Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
- * Fixes: Juha Sievänen <Juha.S...@cs.Helsinki.FI>
- * Taneli Vähäkangas <Taneli.V...@cs.Helsinki.FI>


- * Deepak Saxena <dee...@plexity.net>
- *

- * Tested: in FDDI environment (using SysKonnect's DDM)
- * in Gigabit Eth environment (using SysKonnect's DDM)
- * in Fast Ethernet environment (using Intel 82558 DDM)
- *
- * TODO: tests for other LAN classes (Token Ring, Fibre Channel)


- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-

-#include <linux/pci.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/fddidevice.h>
-#include <linux/trdevice.h>
-#include <linux/fcdevice.h>
-
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/tqueue.h>
-#include <asm/io.h>
-
-#include <linux/errno.h>
-
-#include <linux/i2o.h>


-#include "i2o_lan.h"
-
-//#define DRIVERDEBUG

-#ifdef DRIVERDEBUG
-#define dprintk(s, args...) printk(s, ## args)
-#else
-#define dprintk(s, args...)
-#endif
-

-/* The following module parameters are used as default values
- * for per interface values located in the net_device private area.
- * Private values are changed via /proc filesystem.
- */
-static u32 max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
-static u32 bucket_thresh = I2O_LAN_BUCKET_THRESH;
-static u32 rx_copybreak = I2O_LAN_RX_COPYBREAK;
-static u8 tx_batch_mode = I2O_LAN_TX_BATCH_MODE;
-static u32 i2o_event_mask = I2O_LAN_EVENT_MASK;
-
-#define MAX_LAN_CARDS 16
-static struct net_device *i2o_landevs[MAX_LAN_CARDS+1];
-static int unit = -1; /* device unit number */
-
-static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static void i2o_lan_send_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static int i2o_lan_receive_post(struct net_device *dev);
-static void i2o_lan_receive_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg);
-
-static int i2o_lan_reset(struct net_device *dev);
-static void i2o_lan_handle_event(struct net_device *dev, u32 *msg);
-
-/* Structures to register handlers for the incoming replies. */
-
-static struct i2o_handler i2o_lan_send_handler = {
- i2o_lan_send_post_reply, // For send replies


- NULL,
- NULL,
- NULL,

- "I2O LAN OSM send",
- -1,
- I2O_CLASS_LAN
-};
-static int lan_send_context;
-
-static struct i2o_handler i2o_lan_receive_handler = {
- i2o_lan_receive_post_reply, // For receive replies


- NULL,
- NULL,
- NULL,

- "I2O LAN OSM receive",
- -1,
- I2O_CLASS_LAN
-};
-static int lan_receive_context;
-
-static struct i2o_handler i2o_lan_handler = {
- i2o_lan_reply, // For other replies


- NULL,
- NULL,
- NULL,

- "I2O LAN OSM",
- -1,
- I2O_CLASS_LAN
-};
-static int lan_context;
-
-DECLARE_TASK_QUEUE(i2o_post_buckets_task);
-struct tq_struct run_i2o_post_buckets_task = {
- routine: (void (*)(void *)) run_task_queue,
- data: (void *) 0
-};
-
-/* Functions to handle message failures and transaction errors:
-==============================================================*/
-
-/*
- * i2o_lan_handle_failure(): Fail bit has been set since IOP's message
- * layer cannot deliver the request to the target, or the target cannot
- * process the request.
- */
-static void i2o_lan_handle_failure(struct net_device *dev, u32 *msg)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
-
- u32 *preserved_msg = (u32*)(iop->mem_offset + msg[7]);
- u32 *sgl_elem = &preserved_msg[4];
- struct sk_buff *skb = NULL;
- u8 le_flag;
-
- i2o_report_status(KERN_INFO, dev->name, msg);
-
- /* If PacketSend failed, free sk_buffs reserved by upper layers */
-
- if (msg[1] >> 24 == LAN_PACKET_SEND) {
- do {
- skb = (struct sk_buff *)(sgl_elem[1]);
- dev_kfree_skb_irq(skb);
-
- atomic_dec(&priv->tx_out);
-
- le_flag = *sgl_elem >> 31;
- sgl_elem +=3;
- } while (le_flag == 0); /* Last element flag not set */
-
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
- }
-
- /* If ReceivePost failed, free sk_buffs we have reserved */
-
- if (msg[1] >> 24 == LAN_RECEIVE_POST) {
- do {
- skb = (struct sk_buff *)(sgl_elem[1]);
- dev_kfree_skb_irq(skb);
-
- atomic_dec(&priv->buckets_out);
-
- le_flag = *sgl_elem >> 31;
- sgl_elem +=3;
- } while (le_flag == 0); /* Last element flag not set */
- }
-
- /* Release the preserved msg frame by resubmitting it as a NOP */


-
- preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
- preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
- preserved_msg[2] = 0;

- i2o_post_message(iop, msg[7]);
-}
-/*
- * i2o_lan_handle_transaction_error(): IOP or DDM has rejected the request
- * for general cause (format error, bad function code, insufficient resources,
- * etc.). We get one transaction_error for each failed transaction.
- */
-static void i2o_lan_handle_transaction_error(struct net_device *dev, u32 *msg)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct sk_buff *skb;
-
- i2o_report_status(KERN_INFO, dev->name, msg);
-
- /* If PacketSend was rejected, free sk_buff reserved by upper layers */
-
- if (msg[1] >> 24 == LAN_PACKET_SEND) {
- skb = (struct sk_buff *)(msg[3]); // TransactionContext
- dev_kfree_skb_irq(skb);
- atomic_dec(&priv->tx_out);
-
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
- }
-
- /* If ReceivePost was rejected, free sk_buff we have reserved */
-
- if (msg[1] >> 24 == LAN_RECEIVE_POST) {
- skb = (struct sk_buff *)(msg[3]);
- dev_kfree_skb_irq(skb);
- atomic_dec(&priv->buckets_out);
- }
-}
-
-/*
- * i2o_lan_handle_status(): Common parts of handling a not succeeded request
- * (status != SUCCESS).
- */
-static int i2o_lan_handle_status(struct net_device *dev, u32 *msg)
-{
- /* Fail bit set? */
-
- if (msg[0] & MSG_FAIL) {
- i2o_lan_handle_failure(dev, msg);


- return -1;
- }
-

- /* Message rejected for general cause? */
-
- if ((msg[4]>>24) == I2O_REPLY_STATUS_TRANSACTION_ERROR) {
- i2o_lan_handle_transaction_error(dev, msg);


- return -1;
- }
-

- /* Else have to handle it in the callback function */


-
- return 0;
-}
-

-/* Callback functions called from the interrupt routine:
-=======================================================*/
-
-/*
- * i2o_lan_send_post_reply(): Callback function to handle PostSend replies.
- */
-static void i2o_lan_send_post_reply(struct i2o_handler *h,
- struct i2o_controller *iop, struct i2o_message *m)
-{


- u32 *msg = (u32 *)m;

- u8 unit = (u8)(msg[2]>>16); // InitiatorContext
- struct net_device *dev = i2o_landevs[unit];
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- u8 trl_count = msg[3] & 0x000000FF;
-
- if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
- if (i2o_lan_handle_status(dev, msg))


- return;
- }
-
-#ifdef DRIVERDEBUG

- i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
-
- /* DDM has handled transmit request(s), free sk_buffs.
- * We get similar single transaction reply also in error cases
- * (except if msg failure or transaction error).
- */
- while (trl_count) {
- dev_kfree_skb_irq((struct sk_buff *)msg[4 + trl_count]);
- dprintk(KERN_INFO "%s: tx skb freed (trl_count=%d).\n",
- dev->name, trl_count);
- atomic_dec(&priv->tx_out);
- trl_count--;
- }
-
- /* If priv->tx_out had reached tx_max_out, the queue was stopped */
-
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-}
-
-/*
- * i2o_lan_receive_post_reply(): Callback function to process incoming packets.
- */
-static void i2o_lan_receive_post_reply(struct i2o_handler *h,
- struct i2o_controller *iop, struct i2o_message *m)
-{


- u32 *msg = (u32 *)m;

- u8 unit = (u8)(msg[2]>>16); // InitiatorContext
- struct net_device *dev = i2o_landevs[unit];
-
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_bucket_descriptor *bucket = (struct i2o_bucket_descriptor *)&msg[6];
- struct i2o_packet_info *packet;
- u8 trl_count = msg[3] & 0x000000FF;
- struct sk_buff *skb, *old_skb;
- unsigned long flags = 0;
-
- if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
- if (i2o_lan_handle_status(dev, msg))
- return;
-
- i2o_lan_release_buckets(dev, msg);


- return;
- }
-
-#ifdef DRIVERDEBUG

- i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
-
- /* Else we are receiving incoming post. */
-
- while (trl_count--) {
- skb = (struct sk_buff *)bucket->context;
- packet = (struct i2o_packet_info *)bucket->packet_info;
- atomic_dec(&priv->buckets_out);
-
- /* Sanity checks: Any weird characteristics in bucket? */
-
- if (packet->flags & 0x0f || ! packet->flags & 0x40) {
- if (packet->flags & 0x01)
- printk(KERN_WARNING "%s: packet with errors, error code=0x%02x.\n",
- dev->name, packet->status & 0xff);
-
- /* The following shouldn't happen, unless parameters in
- * LAN_OPERATION group are changed during the run time.
- */
- if (packet->flags & 0x0c)
- printk(KERN_DEBUG "%s: multi-bucket packets not supported!\n",
- dev->name);
-
- if (! packet->flags & 0x40)
- printk(KERN_DEBUG "%s: multiple packets in a bucket not supported!\n",
- dev->name);
-
- dev_kfree_skb_irq(skb);
-
- bucket++;
- continue;
- }
-
- /* Copy short packet to a new skb */
-
- if (packet->len < priv->rx_copybreak) {
- old_skb = skb;
- skb = (struct sk_buff *)dev_alloc_skb(packet->len+2);
- if (skb == NULL) {
- printk(KERN_ERR "%s: Can't allocate skb.\n", dev->name);
- return;
- }
- skb_reserve(skb, 2);
- memcpy(skb_put(skb, packet->len), old_skb->data, packet->len);
-
- spin_lock_irqsave(&priv->fbl_lock, flags);
- if (priv->i2o_fbl_tail < I2O_LAN_MAX_BUCKETS_OUT)
- priv->i2o_fbl[++priv->i2o_fbl_tail] = old_skb;
- else
- dev_kfree_skb_irq(old_skb);
-
- spin_unlock_irqrestore(&priv->fbl_lock, flags);
- } else
- skb_put(skb, packet->len);
-
- /* Deliver to upper layers */
-
- skb->dev = dev;
- skb->protocol = priv->type_trans(skb, dev);
- netif_rx(skb);
-
- dev->last_rx = jiffies;
-
- dprintk(KERN_INFO "%s: Incoming packet (%d bytes) delivered "
- "to upper level.\n", dev->name, packet->len);
-
- bucket++; // to next Packet Descriptor Block
- }
-
-#ifdef DRIVERDEBUG
- if (msg[5] == 0)
- printk(KERN_INFO "%s: DDM out of buckets (priv->count = %d)!\n",
- dev->name, atomic_read(&priv->buckets_out));
-#endif
-
- /* If DDM has already consumed bucket_thresh buckets, post new ones */
-
- if (atomic_read(&priv->buckets_out) <= priv->max_buckets_out - priv->bucket_thresh) {
- run_i2o_post_buckets_task.data = (void *)dev;
- queue_task(&run_i2o_post_buckets_task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- }


-
- return;
-}
-

-/*
- * i2o_lan_reply(): Callback function to handle other incoming messages
- * except SendPost and ReceivePost.
- */
-static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop,


- struct i2o_message *m)
-{

- u32 *msg = (u32 *)m;

- u8 unit = (u8)(msg[2]>>16); // InitiatorContext
- struct net_device *dev = i2o_landevs[unit];
-
- if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
- if (i2o_lan_handle_status(dev, msg))
- return;
-
- /* In other error cases just report and continue */
-
- i2o_report_status(KERN_INFO, dev->name, msg);
- }
-
-#ifdef DRIVERDEBUG
- i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
- switch (msg[1] >> 24) {
- case LAN_RESET:
- case LAN_SUSPEND:
- /* default reply without payload */
- break;
-
- case I2O_CMD_UTIL_EVT_REGISTER:
- case I2O_CMD_UTIL_EVT_ACK:
- i2o_lan_handle_event(dev, msg);
- break;
-
- case I2O_CMD_UTIL_PARAMS_SET:
- /* default reply, results in ReplyPayload (not examined) */
- switch (msg[3] >> 16) {
- case 1: dprintk(KERN_INFO "%s: Reply to set MAC filter mask.\n",
- dev->name);
- break;
- case 2: dprintk(KERN_INFO "%s: Reply to set MAC table.\n",
- dev->name);
- break;
- default: printk(KERN_WARNING "%s: Bad group 0x%04X\n",
- dev->name,msg[3] >> 16);
- }
- break;
-
- default:
- printk(KERN_ERR "%s: No handler for the reply.\n",
- dev->name);
- i2o_report_status(KERN_INFO, dev->name, msg);
- }
-}
-
-/* Functions used by the above callback functions:
-=================================================*/
-/*
- * i2o_lan_release_buckets(): Free unused buckets (sk_buffs).
- */
-static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- u8 trl_elem_size = (u8)(msg[3]>>8 & 0x000000FF);
- u8 trl_count = (u8)(msg[3] & 0x000000FF);
- u32 *pskb = &msg[6];
-
- while (trl_count--) {
- dprintk(KERN_DEBUG "%s: Releasing unused rx skb %p (trl_count=%d).\n",
- dev->name, (struct sk_buff*)(*pskb),trl_count+1);
- dev_kfree_skb_irq((struct sk_buff *)(*pskb));
- pskb += 1 + trl_elem_size;
- atomic_dec(&priv->buckets_out);
- }
-}
-
-/*
- * i2o_lan_event_reply(): Handle events.
- */
-static void i2o_lan_handle_event(struct net_device *dev, u32 *msg)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- u32 max_evt_data_size =iop->status_block->inbound_frame_size-5;


- struct i2o_reply {
- u32 header[4];
- u32 evt_indicator;

- u32 data[max_evt_data_size];
- } *evt = (struct i2o_reply *)msg;
- int evt_data_len = ((msg[0]>>16) - 5) * 4; /* real size*/
-
- printk(KERN_INFO "%s: I2O event - ", dev->name);
-
- if (msg[1]>>24 == I2O_CMD_UTIL_EVT_ACK) {
- printk("Event acknowledgement reply.\n");
- return;
- }
-
- /* Else evt->function == I2O_CMD_UTIL_EVT_REGISTER) */
-
- switch (evt->evt_indicator) {
- case I2O_EVT_IND_STATE_CHANGE: {
- struct state_data {
- u16 status;
- u8 state;
- u8 data;
- } *evt_data = (struct state_data *)(evt->data[0]);
-
- printk("State chance 0x%08x.\n", evt->data[0]);
-
- /* If the DDM is in error state, recovery may be
- * possible if status = Transmit or Receive Control
- * Unit Inoperable.
- */
- if (evt_data->state==0x05 && evt_data->status==0x0003)
- i2o_lan_reset(dev);
- break;
- }
-
- case I2O_EVT_IND_FIELD_MODIFIED: {
- u16 *work16 = (u16 *)evt->data;
- printk("Group 0x%04x, field %d changed.\n", work16[0], work16[1]);
- break;
- }
-
- case I2O_EVT_IND_VENDOR_EVT: {
- int i;
- printk("Vendor event:\n");
- for (i = 0; i < evt_data_len / 4; i++)
- printk(" 0x%08x\n", evt->data[i]);
- break;
- }
-
- case I2O_EVT_IND_DEVICE_RESET:
- /* Spec 2.0 p. 6-121:
- * The event of _DEVICE_RESET should also be responded
- */
- printk("Device reset.\n");
- if (i2o_event_ack(iop, msg) < 0)
- printk("%s: Event Acknowledge timeout.\n", dev->name);
- break;
-
-#if 0
- case I2O_EVT_IND_EVT_MASK_MODIFIED:
- printk("Event mask modified, 0x%08x.\n", evt->data[0]);
- break;
-
- case I2O_EVT_IND_GENERAL_WARNING:
- printk("General warning 0x%04x.\n", evt->data[0]);
- break;
-
- case I2O_EVT_IND_CONFIGURATION_FLAG:
- printk("Configuration requested.\n");
- break;
-
- case I2O_EVT_IND_CAPABILITY_CHANGE:
- printk("Capability change 0x%04x.\n", evt->data[0]);
- break;
-
- case I2O_EVT_IND_DEVICE_STATE:
- printk("Device state changed 0x%08x.\n", evt->data[0]);
- break;
-#endif
- case I2O_LAN_EVT_LINK_DOWN:
- netif_carrier_off(dev);
- printk("Link to the physical device is lost.\n");
- break;
-
- case I2O_LAN_EVT_LINK_UP:
- netif_carrier_on(dev);
- printk("Link to the physical device is (re)established.\n");
- break;
-
- case I2O_LAN_EVT_MEDIA_CHANGE:
- printk("Media change.\n");
- break;
- default:
- printk("0x%08x. No handler.\n", evt->evt_indicator);
- }
-}
-
-/*
- * i2o_lan_receive_post(): Post buckets to receive packets.
- */
-static int i2o_lan_receive_post(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- struct sk_buff *skb;
- u32 m, *msg;
- u32 bucket_len = (dev->mtu + dev->hard_header_len);
- u32 total = priv->max_buckets_out - atomic_read(&priv->buckets_out);
- u32 bucket_count;
- u32 *sgl_elem;


- unsigned long flags;
-

- /* Send (total/bucket_count) separate I2O requests */
-
- while (total) {
- m = I2O_POST_READ32(iop);
- if (m == 0xFFFFFFFF)
- return -ETIMEDOUT;
- msg = (u32 *)(iop->mem_offset + m);
-
- bucket_count = (total >= priv->sgl_max) ? priv->sgl_max : total;
- total -= bucket_count;
- atomic_add(bucket_count, &priv->buckets_out);
-
- dprintk(KERN_INFO "%s: Sending %d buckets (size %d) to LAN DDM.\n",
- dev->name, bucket_count, bucket_len);
-
- /* Fill in the header */
-
- __raw_writel(I2O_MESSAGE_SIZE(4 + 3 * bucket_count) | SGL_OFFSET_4, msg);
- __raw_writel(LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
- __raw_writel(priv->unit << 16 | lan_receive_context, msg+2);
- __raw_writel(bucket_count, msg+3);
- sgl_elem = &msg[4];
-
- /* Fill in the payload - contains bucket_count SGL elements */
-
- while (bucket_count--) {
- spin_lock_irqsave(&priv->fbl_lock, flags);
- if (priv->i2o_fbl_tail >= 0)
- skb = priv->i2o_fbl[priv->i2o_fbl_tail--];
- else {
- skb = dev_alloc_skb(bucket_len + 2);
- if (skb == NULL) {
- spin_unlock_irqrestore(&priv->fbl_lock, flags);
- return -ENOMEM;
- }
- skb_reserve(skb, 2);
- }
- spin_unlock_irqrestore(&priv->fbl_lock, flags);
-
- __raw_writel(0x51000000 | bucket_len, sgl_elem);
- __raw_writel((u32)skb, sgl_elem+1);
- __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
- sgl_elem += 3;
- }
-
- /* set LE flag and post */
- __raw_writel(__raw_readl(sgl_elem-3) | 0x80000000, (sgl_elem-3));
- i2o_post_message(iop, m);


- }
-
- return 0;
-}
-

-/* Functions called from the network stack, and functions called by them:
-========================================================================*/
-
-/*
- * i2o_lan_reset(): Reset the LAN adapter into the operational state and
- * restore it to full operation.
- */
-static int i2o_lan_reset(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;


- u32 msg[5];
-

- dprintk(KERN_INFO "%s: LAN RESET MESSAGE.\n", dev->name);


- msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;

- msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
- msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
- msg[3] = 0; // TransactionContext
- msg[4] = 0; // Keep posted buckets
-
- if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
- return -ETIMEDOUT;
-


- return 0;
-}
-
-/*

- * i2o_lan_suspend(): Put LAN adapter into a safe, non-active state.
- * IOP replies to any LAN class message with status error_no_data_transfer
- * / suspended.
- */
-static int i2o_lan_suspend(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;


- u32 msg[5];
-

- dprintk(KERN_INFO "%s: LAN SUSPEND MESSAGE.\n", dev->name);


- msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;

- msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
- msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
- msg[3] = 0; // TransactionContext
- msg[4] = 1 << 16; // return posted buckets
-
- if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
- return -ETIMEDOUT;
-


- return 0;
-}
-
-/*

- * i2o_set_ddm_parameters:
- * These settings are done to ensure proper initial values for DDM.
- * They can be changed via proc file system or vai configuration utility.
- */
-static void i2o_set_ddm_parameters(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- u32 val;
-
- /*
- * When PacketOrphanlimit is set to the maximum packet length,
- * the packets will never be split into two separate buckets
- */
- val = dev->mtu + dev->hard_header_len;
- if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0004, 2, &val, sizeof(val)) < 0)
- printk(KERN_WARNING "%s: Unable to set PacketOrphanLimit.\n",
- dev->name);
- else
- dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d.\n",
- dev->name, val);
-
- /* When RxMaxPacketsBucket = 1, DDM puts only one packet into bucket */
-
- val = 1;
- if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0008, 4, &val, sizeof(val)) <0)
- printk(KERN_WARNING "%s: Unable to set RxMaxPacketsBucket.\n",
- dev->name);
- else
- dprintk(KERN_INFO "%s: RxMaxPacketsBucket set to %d.\n",
- dev->name, val);
- return;
-}
-
-/* Functions called from the network stack:
-==========================================*/
-
-/*
- * i2o_lan_open(): Open the device to send/receive packets via
- * the network device.
- */
-static int i2o_lan_open(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- u32 mc_addr_group[64];
-
- MOD_INC_USE_COUNT;
-
- if (i2o_claim_device(i2o_dev, &i2o_lan_handler)) {
- printk(KERN_WARNING "%s: Unable to claim the I2O LAN device.\n", dev->name);
- MOD_DEC_USE_COUNT;
- return -EAGAIN;
- }
- dprintk(KERN_INFO "%s: I2O LAN device (tid=%d) claimed by LAN OSM.\n",
- dev->name, i2o_dev->lct_data.tid);
-
- if (i2o_event_register(iop, i2o_dev->lct_data.tid,
- priv->unit << 16 | lan_context, 0, priv->i2o_event_mask) < 0)
- printk(KERN_WARNING "%s: Unable to set the event mask.\n", dev->name);
-
- i2o_lan_reset(dev);
-
- /* Get the max number of multicast addresses */
-
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0001, -1,
- &mc_addr_group, sizeof(mc_addr_group)) < 0 ) {
- printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name);
- MOD_DEC_USE_COUNT;
- return -EAGAIN;
- }
- priv->max_size_mc_table = mc_addr_group[8];
-
- /* Malloc space for free bucket list to resuse reveive post buckets */
-
- priv->i2o_fbl = kmalloc(priv->max_buckets_out * sizeof(struct sk_buff *),
- GFP_KERNEL);
- if (priv->i2o_fbl == NULL) {
- MOD_DEC_USE_COUNT;
- return -ENOMEM;
- }
- priv->i2o_fbl_tail = -1;
- priv->send_active = 0;
-
- i2o_set_ddm_parameters(dev);
- i2o_lan_receive_post(dev);
-
- netif_start_queue(dev);


-
- return 0;
-}
-
-/*

- * i2o_lan_close(): End the transfering.
- */
-static int i2o_lan_close(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;


- int ret = 0;
-

- netif_stop_queue(dev);
- i2o_lan_suspend(dev);
-
- if (i2o_event_register(iop, i2o_dev->lct_data.tid,
- priv->unit << 16 | lan_context, 0, 0) < 0)
- printk(KERN_WARNING "%s: Unable to clear the event mask.\n",
- dev->name);
-
- while (priv->i2o_fbl_tail >= 0)
- dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
-
- kfree(priv->i2o_fbl);
-
- if (i2o_release_device(i2o_dev, &i2o_lan_handler)) {
- printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device "
- "(tid=%d).\n", dev->name, i2o_dev->lct_data.tid);


- ret = -EBUSY;
- }

-
- MOD_DEC_USE_COUNT;


-
- return ret;
-}
-
-/*

- * i2o_lan_tx_timeout(): Tx timeout handler.
- */
-static void i2o_lan_tx_timeout(struct net_device *dev)
-{
- if (!netif_queue_stopped(dev))
- netif_start_queue(dev);
-}
-
-/*
- * i2o_lan_batch_send(): Send packets in batch.
- * Both i2o_lan_sdu_send and i2o_lan_packet_send use this.
- */
-static void i2o_lan_batch_send(struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_controller *iop = priv->i2o_dev->controller;
-
- spin_lock_irq(&priv->tx_lock);
- if (priv->tx_count != 0) {
- dev->trans_start = jiffies;
- i2o_post_message(iop, priv->m);
- dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
- priv->tx_count = 0;
- }
- priv->send_active = 0;
- spin_unlock_irq(&priv->tx_lock);
- MOD_DEC_USE_COUNT;
-}
-
-#ifdef CONFIG_NET_FC
-/*
- * i2o_lan_sdu_send(): Send a packet, MAC header added by the DDM.
- * Must be supported by Fibre Channel, optional for Ethernet/802.3,
- * Token Ring, FDDI
- */
-static int i2o_lan_sdu_send(struct sk_buff *skb, struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- int tickssofar = jiffies - dev->trans_start;
- u32 m, *msg;
- u32 *sgl_elem;
-
- spin_lock_irq(&priv->tx_lock);
-
- priv->tx_count++;
- atomic_inc(&priv->tx_out);
-
- /*
- * If tx_batch_mode = 0x00 forced to immediate mode
- * If tx_batch_mode = 0x01 forced to batch mode
- * If tx_batch_mode = 0x10 switch automatically, current mode immediate
- * If tx_batch_mode = 0x11 switch automatically, current mode batch
- * If gap between two packets is > 0 ticks, switch to immediate
- */
- if (priv->tx_batch_mode >> 1) // switch automatically
- priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
-
- if (priv->tx_count == 1) {
- m = I2O_POST_READ32(iop);
- if (m == 0xFFFFFFFF) {
- spin_unlock_irq(&priv->tx_lock);
- return 1;
- }
- msg = (u32 *)(iop->mem_offset + m);
- priv->m = m;
-
- __raw_writel(NINE_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);
- __raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
- __raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
- __raw_writel(1 << 30 | 1 << 3, msg+3); // TransmitControlWord
-
- __raw_writel(0xD7000000 | skb->len, msg+4); // MAC hdr included
- __raw_writel((u32)skb, msg+5); // TransactionContext
- __raw_writel(virt_to_bus(skb->data), msg+6);
- __raw_writel((u32)skb->mac.raw, msg+7);
- __raw_writel((u32)skb->mac.raw+4, msg+8);
-
- if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
- priv->send_active = 1;
- MOD_INC_USE_COUNT;
- if (schedule_task(&priv->i2o_batch_send_task) == 0)
- MOD_DEC_USE_COUNT;
- }
- } else { /* Add new SGL element to the previous message frame */
-
- msg = (u32 *)(iop->mem_offset + priv->m);
- sgl_elem = &msg[priv->tx_count * 5 + 1];
-
- __raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 5) | 1<<12 | SGL_OFFSET_4, msg);
- __raw_writel(__raw_readl(sgl_elem-5) & 0x7FFFFFFF, sgl_elem-5); /* clear LE flag */
- __raw_writel(0xD5000000 | skb->len, sgl_elem);
- __raw_writel((u32)skb, sgl_elem+1);
- __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
- __raw_writel((u32)(skb->mac.raw), sgl_elem+3);
- __raw_writel((u32)(skb->mac.raw)+1, sgl_elem+4);
- }
-
- /* If tx not in batch mode or frame is full, send immediatelly */
-
- if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
- dev->trans_start = jiffies;
- i2o_post_message(iop, priv->m);
- dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
- priv->tx_count = 0;
- }
-
- /* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
-
- if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
- netif_stop_queue(dev);
-
- spin_unlock_irq(&priv->tx_lock);
- return 0;
-}
-#endif /* CONFIG_NET_FC */
-
-/*
- * i2o_lan_packet_send(): Send a packet as is, including the MAC header.
- *
- * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for
- * Fibre Channel
- */
-static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev)
-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;
- int tickssofar = jiffies - dev->trans_start;
- u32 m, *msg;
- u32 *sgl_elem;
-
- spin_lock_irq(&priv->tx_lock);
-
- priv->tx_count++;
- atomic_inc(&priv->tx_out);
-
- /*
- * If tx_batch_mode = 0x00 forced to immediate mode
- * If tx_batch_mode = 0x01 forced to batch mode
- * If tx_batch_mode = 0x10 switch automatically, current mode immediate
- * If tx_batch_mode = 0x11 switch automatically, current mode batch
- * If gap between two packets is > 0 ticks, switch to immediate


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 18'
echo 'File patch-2.4.13 is continued in part 19'
echo "19" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:49 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part19

#!/bin/sh -x
# this is part 19 of a 53 - part archive


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

if test "$Scheck" != 19; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&
- */

- if (priv->tx_batch_mode >> 1) // switch automatically
- priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
-
- if (priv->tx_count == 1) {
- m = I2O_POST_READ32(iop);
- if (m == 0xFFFFFFFF) {
- spin_unlock_irq(&priv->tx_lock);
- return 1;
- }
- msg = (u32 *)(iop->mem_offset + m);
- priv->m = m;
-

- __raw_writel(SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);


- __raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
- __raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
- __raw_writel(1 << 30 | 1 << 3, msg+3); // TransmitControlWord

- // bit 30: reply as soon as transmission attempt is complete
- // bit 3: Suppress CRC generation
- __raw_writel(0xD5000000 | skb->len, msg+4); // MAC hdr included


- __raw_writel((u32)skb, msg+5); // TransactionContext
- __raw_writel(virt_to_bus(skb->data), msg+6);
-

- if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
- priv->send_active = 1;
- MOD_INC_USE_COUNT;
- if (schedule_task(&priv->i2o_batch_send_task) == 0)
- MOD_DEC_USE_COUNT;
- }
- } else { /* Add new SGL element to the previous message frame */
-
- msg = (u32 *)(iop->mem_offset + priv->m);

- sgl_elem = &msg[priv->tx_count * 3 + 1];
-
- __raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 3) | 1<<12 | SGL_OFFSET_4, msg);
- __raw_writel(__raw_readl(sgl_elem-3) & 0x7FFFFFFF, sgl_elem-3); /* clear LE flag */


- __raw_writel(0xD5000000 | skb->len, sgl_elem);
- __raw_writel((u32)skb, sgl_elem+1);
- __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
- }

-
- /* If tx is in immediate mode or frame is full, send now */


-
- if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
- dev->trans_start = jiffies;
- i2o_post_message(iop, priv->m);
- dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
- priv->tx_count = 0;
- }
-
- /* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
-
- if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
- netif_stop_queue(dev);
-
- spin_unlock_irq(&priv->tx_lock);
- return 0;
-}
-

-/*
- * i2o_lan_get_stats(): Fill in the statistics.
- */
-static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev)


-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;

- u64 val64[16];
- u64 supported_group[4] = { 0, 0, 0, 0 };
-
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0100, -1, val64,
- sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_HISTORICAL_STATS.\n", dev->name);
- else {
- dprintk(KERN_DEBUG "%s: LAN_HISTORICAL_STATS queried.\n", dev->name);
- priv->stats.tx_packets = val64[0];
- priv->stats.tx_bytes = val64[1];
- priv->stats.rx_packets = val64[2];
- priv->stats.rx_bytes = val64[3];
- priv->stats.tx_errors = val64[4];
- priv->stats.rx_errors = val64[5];
- priv->stats.rx_dropped = val64[6];
- }
-
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0180, -1,
- &supported_group, sizeof(supported_group)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_OPTIONAL_HISTORICAL_STATS.\n", dev->name);
-
- if (supported_group[2]) {
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0183, -1,
- val64, sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_RX_HISTORICAL_STATS.\n", dev->name);
- else {
- dprintk(KERN_DEBUG "%s: LAN_OPTIONAL_RX_HISTORICAL_STATS queried.\n", dev->name);
- priv->stats.multicast = val64[4];
- priv->stats.rx_length_errors = val64[10];
- priv->stats.rx_crc_errors = val64[0];
- }
- }
-
- if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET) {
- u64 supported_stats = 0;
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0200, -1,
- val64, sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_802_3_HISTORICAL_STATS.\n", dev->name);
- else {
- dprintk(KERN_DEBUG "%s: LAN_802_3_HISTORICAL_STATS queried.\n", dev->name);
- priv->stats.transmit_collision = val64[1] + val64[2];
- priv->stats.rx_frame_errors = val64[0];
- priv->stats.tx_carrier_errors = val64[6];
- }
-
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0280, -1,
- &supported_stats, sizeof(supported_stats)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_802_3_HISTORICAL_STATS.\n", dev->name);
-
- if (supported_stats != 0) {
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0281, -1,
- val64, sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_802_3_HISTORICAL_STATS.\n", dev->name);
- else {
- dprintk(KERN_DEBUG "%s: LAN_OPTIONAL_802_3_HISTORICAL_STATS queried.\n", dev->name);
- if (supported_stats & 0x1)
- priv->stats.rx_over_errors = val64[0];
- if (supported_stats & 0x4)
- priv->stats.tx_heartbeat_errors = val64[2];
- }
- }
- }
-
-#ifdef CONFIG_TR
- if (i2o_dev->lct_data.sub_class == I2O_LAN_TR) {
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0300, -1,
- val64, sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_802_5_HISTORICAL_STATS.\n", dev->name);
- else {
- struct tr_statistics *stats =
- (struct tr_statistics *)&priv->stats;
- dprintk(KERN_DEBUG "%s: LAN_802_5_HISTORICAL_STATS queried.\n", dev->name);
-
- stats->line_errors = val64[0];
- stats->internal_errors = val64[7];
- stats->burst_errors = val64[4];
- stats->A_C_errors = val64[2];
- stats->abort_delimiters = val64[3];
- stats->lost_frames = val64[1];
- /* stats->recv_congest_count = ?; FIXME ??*/
- stats->frame_copied_errors = val64[5];
- stats->frequency_errors = val64[6];
- stats->token_errors = val64[9];
- }
- /* Token Ring optional stats not yet defined */
- }
-#endif
-
-#ifdef CONFIG_FDDI
- if (i2o_dev->lct_data.sub_class == I2O_LAN_FDDI) {
- if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0400, -1,
- val64, sizeof(val64)) < 0)
- printk(KERN_INFO "%s: Unable to query LAN_FDDI_HISTORICAL_STATS.\n", dev->name);
- else {
- dprintk(KERN_DEBUG "%s: LAN_FDDI_HISTORICAL_STATS queried.\n", dev->name);
- priv->stats.smt_cf_state = val64[0];
- memcpy(priv->stats.mac_upstream_nbr, &val64[1], FDDI_K_ALEN);
- memcpy(priv->stats.mac_downstream_nbr, &val64[2], FDDI_K_ALEN);
- priv->stats.mac_error_cts = val64[3];
- priv->stats.mac_lost_cts = val64[4];
- priv->stats.mac_rmt_state = val64[5];
- memcpy(priv->stats.port_lct_fail_cts, &val64[6], 8);
- memcpy(priv->stats.port_lem_reject_cts, &val64[7], 8);
- memcpy(priv->stats.port_lem_cts, &val64[8], 8);
- memcpy(priv->stats.port_pcm_state, &val64[9], 8);
- }
- /* FDDI optional stats not yet defined */
- }
-#endif
-
-#ifdef CONFIG_NET_FC
- /* Fibre Channel Statistics not yet defined in 1.53 nor 2.0 */
-#endif
-
- return (struct net_device_stats *)&priv->stats;
-}
-
-/*
- * i2o_lan_set_mc_filter(): Post a request to set multicast filter.
- */
-int i2o_lan_set_mc_filter(struct net_device *dev, u32 filter_mask)


-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;

- u32 msg[10];
-
- msg[0] = TEN_WORD_MSG_SIZE | SGL_OFFSET_5;
- msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;


- msg[2] = priv->unit << 16 | lan_context;

- msg[3] = 0x0001 << 16 | 3 ; // TransactionContext: group&field


- msg[4] = 0;

- msg[5] = 0xCC000000 | 16; // Immediate data SGL
- msg[6] = 1; // OperationCount
- msg[7] = 0x0001<<16 | I2O_PARAMS_FIELD_SET; // Group, Operation
- msg[8] = 3 << 16 | 1; // FieldIndex, FieldCount
- msg[9] = filter_mask; // Value
-
- return i2o_post_this(iop, msg, sizeof(msg));
-}
-
-/*
- * i2o_lan_set_mc_table(): Post a request to set LAN_MULTICAST_MAC_ADDRESS table.
- */
-int i2o_lan_set_mc_table(struct net_device *dev)


-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
- struct i2o_controller *iop = i2o_dev->controller;

- struct dev_mc_list *mc;
- u32 msg[10 + 2 * dev->mc_count];
- u8 *work8 = (u8 *)(msg + 10);
-
- msg[0] = I2O_MESSAGE_SIZE(10 + 2 * dev->mc_count) | SGL_OFFSET_5;
- msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;


- msg[2] = priv->unit << 16 | lan_context; // InitiatorContext

- msg[3] = 0x0002 << 16 | (u16)-1; // TransactionContext
- msg[4] = 0; // OperationFlags
- msg[5] = 0xCC000000 | (16 + 8 * dev->mc_count); // Immediate data SGL
- msg[6] = 2; // OperationCount
- msg[7] = 0x0002 << 16 | I2O_PARAMS_TABLE_CLEAR; // Group, Operation
- msg[8] = 0x0002 << 16 | I2O_PARAMS_ROW_ADD; // Group, Operation
- msg[9] = dev->mc_count << 16 | (u16)-1; // RowCount, FieldCount
-
- for (mc = dev->mc_list; mc ; mc = mc->next, work8 += 8) {
- memset(work8, 0, 8);
- memcpy(work8, mc->dmi_addr, mc->dmi_addrlen); // Values
- }
-
- return i2o_post_this(iop, msg, sizeof(msg));
-}
-
-/*
- * i2o_lan_set_multicast_list(): Enable a network device to receive packets
- * not send to the protocol address.
- */
-static void i2o_lan_set_multicast_list(struct net_device *dev)


-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;

- u32 filter_mask;
-
- if (dev->flags & IFF_PROMISC) {
- filter_mask = 0x00000002;
- dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name);
- } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > priv->max_size_mc_table) {
- filter_mask = 0x00000004;
- dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name);
- } else if (dev->mc_count) {
- filter_mask = 0x00000000;
- dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name);
- if (i2o_lan_set_mc_table(dev) < 0)
- printk(KERN_WARNING "%s: Unable to send MAC table.\n", dev->name);
- } else {
- filter_mask = 0x00000300; // Broadcast, Multicast disabled
- dprintk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name);
- }
-
- /* Finally copy new FilterMask to DDM */
-
- if (i2o_lan_set_mc_filter(dev, filter_mask) < 0)
- printk(KERN_WARNING "%s: Unable to send MAC FilterMask.\n", dev->name);
-}
-
-/*
- * i2o_lan_change_mtu(): Change maximum transfer unit size.
- */
-static int i2o_lan_change_mtu(struct net_device *dev, int new_mtu)


-{
- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;

- u32 max_pkt_size;
-
- if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
- 0x0000, 6, &max_pkt_size, 4) < 0)
- return -EFAULT;
-
- if (new_mtu < 68 || new_mtu > 9000 || new_mtu > max_pkt_size)
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- i2o_lan_suspend(dev); // to SUSPENDED state, return buckets
-
- while (priv->i2o_fbl_tail >= 0) // free buffered buckets


- dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
-

- i2o_lan_reset(dev); // to OPERATIONAL state
- i2o_set_ddm_parameters(dev); // reset some parameters
- i2o_lan_receive_post(dev); // post new buckets (new size)


-
- return 0;
-}
-

-/* Functions to initialize I2O LAN OSM:
-======================================*/
-
-/*
- * i2o_lan_register_device(): Register LAN class device to kernel.
- */
-struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev)
-{
- struct net_device *dev = NULL;
- struct i2o_lan_local *priv = NULL;
- u8 hw_addr[8];
- u32 tx_max_out = 0;
- unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
- void (*unregister_dev)(struct net_device *dev);
-
- switch (i2o_dev->lct_data.sub_class) {
- case I2O_LAN_ETHERNET:
- dev = init_etherdev(NULL, sizeof(struct i2o_lan_local));
- if (dev == NULL)
- return NULL;
- type_trans = eth_type_trans;
- unregister_dev = unregister_netdev;
- break;
-
-#ifdef CONFIG_ANYLAN
- case I2O_LAN_100VG:
- printk(KERN_ERR "i2o_lan: 100base VG not yet supported.\n");
- return NULL;
- break;
-#endif
-
-#ifdef CONFIG_TR
- case I2O_LAN_TR:
- dev = init_trdev(NULL, sizeof(struct i2o_lan_local));
- if (dev==NULL)
- return NULL;
- type_trans = tr_type_trans;
- unregister_dev = unregister_trdev;
- break;
-#endif
-
-#ifdef CONFIG_FDDI
- case I2O_LAN_FDDI:
- {
- int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local);
-
- dev = (struct net_device *) kmalloc(size, GFP_KERNEL);
- if (dev == NULL)
- return NULL;
- memset((char *)dev, 0, size);
- dev->priv = (void *)(dev + 1);
-
- if (dev_alloc_name(dev, "fddi%d") < 0) {
- printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n");
- kfree(dev);
- return NULL;
- }
- type_trans = fddi_type_trans;
- unregister_dev = (void *)unregister_netdevice;
-
- fddi_setup(dev);
- register_netdev(dev);
- }
- break;
-#endif
-
-#ifdef CONFIG_NET_FC
- case I2O_LAN_FIBRE_CHANNEL:
- dev = init_fcdev(NULL, sizeof(struct i2o_lan_local));
- if (dev == NULL)
- return NULL;
- type_trans = NULL;
-/* FIXME: Move fc_type_trans() from drivers/net/fc/iph5526.c to net/802/fc.c
- * and export it in include/linux/fcdevice.h
- * type_trans = fc_type_trans;
- */
- unregister_dev = (void *)unregister_fcdev;
- break;
-#endif
-
- case I2O_LAN_UNKNOWN:
- default:
- printk(KERN_ERR "i2o_lan: LAN type 0x%04x not supported.\n",
- i2o_dev->lct_data.sub_class);


- return NULL;
- }
-

- priv = (struct i2o_lan_local *)dev->priv;
- priv->i2o_dev = i2o_dev;
- priv->type_trans = type_trans;
- priv->sgl_max = (i2o_dev->controller->status_block->inbound_frame_size - 4) / 3;
- atomic_set(&priv->buckets_out, 0);
-
- /* Set default values for user configurable parameters */
- /* Private values are changed via /proc file system */
-
- priv->max_buckets_out = max_buckets_out;
- priv->bucket_thresh = bucket_thresh;
- priv->rx_copybreak = rx_copybreak;
- priv->tx_batch_mode = tx_batch_mode & 0x03;
- priv->i2o_event_mask = i2o_event_mask;
-
- priv->tx_lock = SPIN_LOCK_UNLOCKED;
- priv->fbl_lock = SPIN_LOCK_UNLOCKED;
-
- unit++;
- i2o_landevs[unit] = dev;
- priv->unit = unit;
-
- if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
- 0x0001, 0, &hw_addr, sizeof(hw_addr)) < 0) {
- printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name);
- unit--;
- unregister_dev(dev);
- kfree(dev);
- return NULL;
- }
- dprintk(KERN_DEBUG "%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
- dev->name, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3],
- hw_addr[4], hw_addr[5]);
-
- dev->addr_len = 6;
- memcpy(dev->dev_addr, hw_addr, 6);
-
- if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
- 0x0007, 2, &tx_max_out, sizeof(tx_max_out)) < 0) {
- printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name);
- unit--;
- unregister_dev(dev);
- kfree(dev);
- return NULL;
- }
- dprintk(KERN_INFO "%s: Max TX Outstanding = %d.\n", dev->name, tx_max_out);
- priv->tx_max_out = tx_max_out;
- atomic_set(&priv->tx_out, 0);


- priv->tx_count = 0;
-

- INIT_LIST_HEAD(&priv->i2o_batch_send_task.list);
- priv->i2o_batch_send_task.sync = 0;
- priv->i2o_batch_send_task.routine = (void *)i2o_lan_batch_send;
- priv->i2o_batch_send_task.data = (void *)dev;
-
- dev->open = i2o_lan_open;
- dev->stop = i2o_lan_close;
- dev->get_stats = i2o_lan_get_stats;
- dev->set_multicast_list = i2o_lan_set_multicast_list;
- dev->tx_timeout = i2o_lan_tx_timeout;
- dev->watchdog_timeo = I2O_LAN_TX_TIMEOUT;
-
-#ifdef CONFIG_NET_FC
- if (i2o_dev->lct_data.sub_class == I2O_LAN_FIBRE_CHANNEL)
- dev->hard_start_xmit = i2o_lan_sdu_send;
- else
-#endif
- dev->hard_start_xmit = i2o_lan_packet_send;
-
- if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET)
- dev->change_mtu = i2o_lan_change_mtu;
-
- return dev;
-}
-
-#ifdef MODULE
-#define i2o_lan_init init_module
-#endif
-
-int __init i2o_lan_init(void)
-{
- struct net_device *dev;
- int i;
-
- printk(KERN_INFO "I2O LAN OSM (C) 1999 University of Helsinki.\n");
-
- /* Module params are used as global defaults for private values */
-
- if (max_buckets_out > I2O_LAN_MAX_BUCKETS_OUT)
- max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
- if (bucket_thresh > max_buckets_out)
- bucket_thresh = max_buckets_out;
-
- /* Install handlers for incoming replies */
-
- if (i2o_install_handler(&i2o_lan_send_handler) < 0) {
- printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
- return -EINVAL;
- }
- lan_send_context = i2o_lan_send_handler.context;
-
- if (i2o_install_handler(&i2o_lan_receive_handler) < 0) {
- printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
- return -EINVAL;
- }
- lan_receive_context = i2o_lan_receive_handler.context;
-
- if (i2o_install_handler(&i2o_lan_handler) < 0) {
- printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
- return -EINVAL;
- }
- lan_context = i2o_lan_handler.context;
-
- for(i=0; i <= MAX_LAN_CARDS; i++)
- i2o_landevs[i] = NULL;
-
- for (i=0; i < MAX_I2O_CONTROLLERS; i++) {
- struct i2o_controller *iop = i2o_find_controller(i);
- struct i2o_device *i2o_dev;
-
- if (iop==NULL)
- continue;
-
- for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) {
-
- if (i2o_dev->lct_data.class_id != I2O_CLASS_LAN)
- continue;
-
- /* Make sure device not already claimed by an ISM */
- if (i2o_dev->lct_data.user_tid != 0xFFF)
- continue;
-
- if (unit == MAX_LAN_CARDS) {
- i2o_unlock_controller(iop);
- printk(KERN_WARNING "i2o_lan: Too many I2O LAN devices.\n");


- return -EINVAL;
- }
-

- dev = i2o_lan_register_device(i2o_dev);
- if (dev == NULL) {
- printk(KERN_ERR "i2o_lan: Unable to register I2O LAN device 0x%04x.\n",
- i2o_dev->lct_data.sub_class);
- continue;
- }
-
- printk(KERN_INFO "%s: I2O LAN device registered, "
- "subclass = 0x%04x, unit = %d, tid = %d.\n",
- dev->name, i2o_dev->lct_data.sub_class,
- ((struct i2o_lan_local *)dev->priv)->unit,
- i2o_dev->lct_data.tid);
- }
-
- i2o_unlock_controller(iop);
- }
-
- dprintk(KERN_INFO "%d I2O LAN devices found and registered.\n", unit+1);


-
- return 0;
-}
-

-#ifdef MODULE
-
-void cleanup_module(void)
-{
- int i;
-
- for (i = 0; i <= unit; i++) {
- struct net_device *dev = i2o_landevs[i];


- struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
- struct i2o_device *i2o_dev = priv->i2o_dev;
-

- switch (i2o_dev->lct_data.sub_class) {
- case I2O_LAN_ETHERNET:
- unregister_netdev(dev);
- break;
-#ifdef CONFIG_FDDI
- case I2O_LAN_FDDI:
- unregister_netdevice(dev);
- break;
-#endif
-#ifdef CONFIG_TR
- case I2O_LAN_TR:
- unregister_trdev(dev);
- break;
-#endif
-#ifdef CONFIG_NET_FC
- case I2O_LAN_FIBRE_CHANNEL:
- unregister_fcdev(dev);
- break;
-#endif
- default:
- printk(KERN_WARNING "%s: Spurious I2O LAN subclass 0x%08x.\n",
- dev->name, i2o_dev->lct_data.sub_class);
- }
-
- dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n",
- dev->name);
- kfree(dev);
- }
-
- i2o_remove_handler(&i2o_lan_handler);
- i2o_remove_handler(&i2o_lan_send_handler);
- i2o_remove_handler(&i2o_lan_receive_handler);
-}
-
-EXPORT_NO_SYMBOLS;
-
-MODULE_AUTHOR("University of Helsinki, Department of Computer Science");
-MODULE_DESCRIPTION("I2O Lan OSM");
-
-MODULE_PARM(max_buckets_out, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
-MODULE_PARM_DESC(max_buckets_out, "Total number of buckets to post (1-)");
-MODULE_PARM(bucket_thresh, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
-MODULE_PARM_DESC(bucket_thresh, "Bucket post threshold (1-)");
-MODULE_PARM(rx_copybreak, "1-" "i");
-MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy only small frames (1-)");
-MODULE_PARM(tx_batch_mode, "0-2" "i");
-MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");
-
-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_lan.h linux/drivers/i2o/i2o_lan.h
--- v2.4.12/linux/drivers/i2o/i2o_lan.h Mon Dec 11 13:20:00 2000
+++ linux/drivers/i2o/i2o_lan.h Wed Dec 31 16:00:00 1969
@@ -1,159 +0,0 @@
-/*
- * i2o_lan.h I2O LAN Class definitions


- *
- * I2O LAN CLASS OSM May 26th 2000
- *
- * (C) Copyright 1999, 2000 University of Helsinki,
- * Department of Computer Science
- *
- * This code is still under development / test.
- *

- * Author: Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
- * Juha Sievänen <Juha.S...@cs.Helsinki.FI>


- * Taneli Vähäkangas <Taneli.V...@cs.Helsinki.FI>

- */
-
-#ifndef _I2O_LAN_H
-#define _I2O_LAN_H
-
-/* Default values for tunable parameters first */
-
-#define I2O_LAN_MAX_BUCKETS_OUT 96
-#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
-#define I2O_LAN_RX_COPYBREAK 200
-#define I2O_LAN_TX_TIMEOUT (1*HZ)
-#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */
-#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */
-
-/* LAN types */
-#define I2O_LAN_ETHERNET 0x0030
-#define I2O_LAN_100VG 0x0040
-#define I2O_LAN_TR 0x0050
-#define I2O_LAN_FDDI 0x0060
-#define I2O_LAN_FIBRE_CHANNEL 0x0070
-#define I2O_LAN_UNKNOWN 0x00000000
-
-/* Connector types */
-
-/* Ethernet */
-#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001
-#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002
-#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003
-#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004
-#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005
-#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006
-#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007
-#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008
-#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009
-#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A
-#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B
-#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C
-#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D
-#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E
-#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F
-#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010
-
-/* AnyLAN */
-#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001
-#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002
-
-/* Token Ring */
-#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001
-#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002
-
-/* FDDI */
-#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001
-
-/* Fibre Channel */
-#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001
-#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002
-#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003
-#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004
-
-#define I2O_LAN_EMULATION 0x00000F00
-#define I2O_LAN_OTHER 0x00000F01
-#define I2O_LAN_DEFAULT 0xFFFFFFFF
-
-/* LAN class functions */
-
-#define LAN_PACKET_SEND 0x3B
-#define LAN_SDU_SEND 0x3D
-#define LAN_RECEIVE_POST 0x3E
-#define LAN_RESET 0x35
-#define LAN_SUSPEND 0x37
-
-/* LAN DetailedStatusCode defines */
-#define I2O_LAN_DSC_SUCCESS 0x00
-#define I2O_LAN_DSC_DEVICE_FAILURE 0x01
-#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02
-#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03
-#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04
-#define I2O_LAN_DSC_RECEIVE_ERROR 0x05
-#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06
-#define I2O_LAN_DSC_DMA_ERROR 0x07
-#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08
-#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09
-#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A
-#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B
-#define I2O_LAN_DSC_CANCELED 0x0C
-#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D
-#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E
-#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F
-#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10
-#define I2O_LAN_DSC_SUSPENDED 0x11
-
-struct i2o_packet_info {
- u32 offset : 24;
- u32 flags : 8;
- u32 len : 24;
- u32 status : 8;
-};
-
-struct i2o_bucket_descriptor {
- u32 context; /* FIXME: 64bit support */
- struct i2o_packet_info packet_info[1];
-};
-
-/* Event Indicator Mask Flags for LAN OSM */
-
-#define I2O_LAN_EVT_LINK_DOWN 0x01
-#define I2O_LAN_EVT_LINK_UP 0x02
-#define I2O_LAN_EVT_MEDIA_CHANGE 0x04
-
-#include <linux/netdevice.h>
-#include <linux/fddidevice.h>
-
-struct i2o_lan_local {
- u8 unit;
- struct i2o_device *i2o_dev;
-
- struct fddi_statistics stats; /* see also struct net_device_stats */
- unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
- atomic_t buckets_out; /* nbr of unused buckets on DDM */
- atomic_t tx_out; /* outstanding TXes */
- u8 tx_count; /* packets in one TX message frame */
- u16 tx_max_out; /* DDM's Tx queue len */
- u8 sgl_max; /* max SGLs in one message frame */
- u32 m; /* IOP address of the batch msg frame */
-
- struct tq_struct i2o_batch_send_task;
- int send_active;
- struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */
- int i2o_fbl_tail;
- spinlock_t fbl_lock;
-
- spinlock_t tx_lock;
-
- u32 max_size_mc_table; /* max number of multicast addresses */
-
- /* LAN OSM configurable parameters are here: */
-
- u16 max_buckets_out; /* max nbr of buckets to send to DDM */
- u16 bucket_thresh; /* send more when this many used */
- u16 rx_copybreak;
-
- u8 tx_batch_mode; /* Set when using batch mode sends */
- u32 i2o_event_mask; /* To turn on interesting event flags */
-};
-
-#endif /* _I2O_LAN_H */
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_pci.c linux/drivers/i2o/i2o_pci.c
--- v2.4.12/linux/drivers/i2o/i2o_pci.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_pci.c Wed Dec 31 16:00:00 1969
@@ -1,377 +0,0 @@
-/*
- * Find I2O capable controllers on the PCI bus, and register/install
- * them with the I2O layer
- *


- * (C) Copyright 1999 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd

- * Modified by Deepak Saxena <dee...@plexity.net>
- * Modified by Boji T Kannanthanam <boji.t.ka...@intel.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.
- *

- * TODO:
- * Support polled I2O PCI controllers.

- */
-
-#include <linux/config.h>
-#include <linux/module.h>

-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>

-#include <asm/io.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif // CONFIG_MTRR
-
-#ifdef MODULE
-/*
- * Core function table
- * See <include/linux/i2o.h> for an explanation
- */
-static struct i2o_core_func_table *core;
-
-/* Core attach function */


-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);

-#endif /* MODULE */
-
-/*
- * Free bus specific resources
- */
-static void i2o_pci_dispose(struct i2o_controller *c)
-{
- I2O_IRQ_WRITE32(c,0xFFFFFFFF);
- if(c->bus.pci.irq > 0)
- free_irq(c->bus.pci.irq, c);
- iounmap(((u8 *)c->post_port)-0x40);
-
-#ifdef CONFIG_MTRR
- if(c->bus.pci.mtrr_reg0 > 0)
- mtrr_del(c->bus.pci.mtrr_reg0, 0, 0);
- if(c->bus.pci.mtrr_reg1 > 0)
- mtrr_del(c->bus.pci.mtrr_reg1, 0, 0);
-#endif
-}
-
-/*
- * No real bus specific handling yet (note that later we will
- * need to 'steal' PCI devices on i960 mainboards)
- */
-
-static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
-{
- MOD_INC_USE_COUNT;


- return 0;
-}
-

-static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev)
-{
- MOD_DEC_USE_COUNT;


- return 0;
-}
-
-/*

- * Bus specific enable/disable functions
- */
-static void i2o_pci_enable(struct i2o_controller *c)
-{
- I2O_IRQ_WRITE32(c, 0);
- c->enabled = 1;
-}
-
-static void i2o_pci_disable(struct i2o_controller *c)
-{
- I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
- c->enabled = 0;
-}
-
-/*
- * Bus specific interrupt handler
- */
-
-static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
-{
- struct i2o_controller *c = dev_id;
-#ifdef MODULE
- core->run_queue(c);
-#else
- i2o_run_queue(c);
-#endif /* MODULE */
-}
-
-/*
- * Install a PCI (or in theory AGP) i2o controller
- *
- * TODO: Add support for polled controllers
- */
-int __init i2o_pci_install(struct pci_dev *dev)
-{
- struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
- GFP_KERNEL);
- u8 *mem;
- u32 memptr = 0;
- u32 size;


-
- int i;
-

- if(c==NULL)
- {
- printk(KERN_ERR "i2o: Insufficient memory to add controller.\n");
- return -ENOMEM;
- }
- memset(c, 0, sizeof(*c));
-
- for(i=0; i<6; i++)
- {
- /* Skip I/O spaces */
- if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
- {
- memptr = pci_resource_start(dev, i);


- break;
- }
- }
-

- if(i==6)
- {
- printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
- kfree(c);
- return -EINVAL;
- }
-
- size = dev->resource[i].end-dev->resource[i].start+1;
- /* Map the I2O controller */
-
- printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
- mem = ioremap(memptr, size);
- if(mem==NULL)
- {
- printk(KERN_ERR "i2o: Unable to map controller.\n");
- kfree(c);


- return -EINVAL;
- }
-

- c->bus.pci.irq = -1;
- c->bus.pci.queue_buggy = 0;
- c->bus.pci.dpt = 0;
- c->bus.pci.short_req = 0;
- c->bus.pci.pdev = dev;
-
- c->irq_mask = (volatile u32 *)(mem+0x34);
- c->post_port = (volatile u32 *)(mem+0x40);
- c->reply_port = (volatile u32 *)(mem+0x44);
-
- c->mem_phys = memptr;
- c->mem_offset = (u32)mem;
- c->destructor = i2o_pci_dispose;
-
- c->bind = i2o_pci_bind;
- c->unbind = i2o_pci_unbind;
- c->bus_enable = i2o_pci_enable;
- c->bus_disable = i2o_pci_disable;
-
- c->type = I2O_TYPE_PCI;
-
- /*
- * Cards that fall apart if you hit them with large I/O
- * loads...
- */
-
- if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
- {
- c->bus.pci.short_req=1;
- printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
- }
- if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
- {
- c->bus.pci.queue_buggy=1;
- printk(KERN_INFO "I2O: Promise workarounds activated.\n");
- }
-
- /*
- * Cards that go bananas if you quiesce them before you reset
- * them
- */
-
- if(dev->vendor == PCI_VENDOR_ID_DPT)
- c->bus.pci.dpt=1;
-
- /*
- * Enable Write Combining MTRR for IOP's memory region
- */
-#ifdef CONFIG_MTRR
- c->bus.pci.mtrr_reg0 =
- mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
-/*
-* If it is an INTEL i960 I/O processor then set the first 64K to Uncacheable
-* since the region contains the Messaging unit which shouldn't be cached.
-*/
- c->bus.pci.mtrr_reg1 = -1;
- if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
- {
- printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n");
- c->bus.pci.mtrr_reg1 = mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
- if(c->bus.pci.mtrr_reg1< 0)
- printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
- }
-
-#endif
-
- I2O_IRQ_WRITE32(c,0xFFFFFFFF);
-
-#ifdef MODULE
- i = core->install(c);
-#else
- i = i2o_install_controller(c);


-#endif /* MODULE */
-

- if(i<0)
- {
- printk(KERN_ERR "i2o: Unable to install controller.\n");
- kfree(c);
- iounmap(mem);


- return i;
- }
-

- c->bus.pci.irq = dev->irq;
- if(c->bus.pci.irq)
- {
- i=request_irq(dev->irq, i2o_pci_interrupt, SA_SHIRQ,
- c->name, c);
- if(i<0)
- {
- printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
- c->name, dev->irq);
- c->bus.pci.irq = -1;
-#ifdef MODULE
- core->delete(c);
-#else
- i2o_delete_controller(c);
-#endif /* MODULE */
- iounmap(mem);
- return -EBUSY;
- }
- }
-
- printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq);
- I2O_IRQ_WRITE32(c,0x0);
- c->enabled = 1;


- return 0;
-}
-

-int __init i2o_pci_scan(void)
-{
- struct pci_dev *dev;
- int count=0;
-
- printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
-
- pci_for_each_dev(dev)
- {
- if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
- continue;
- if((dev->class&0xFF)>1)
- {
- printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
- continue;
- }
- if (pci_enable_device(dev))
- continue;
- printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n",
- dev->bus->number, dev->devfn);
- pci_set_master(dev);
- if(i2o_pci_install(dev)==0)
- count++;
- }
- if(count)
- printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count,
- count==1?"":"s");
- return count?count:-ENODEV;
-}
-
-#ifdef I2O_HOTPLUG_SUPPORT
-/*
- * Activate a newly found PCI I2O controller
- * Not used now, but will be needed in future for
- * hot plug PCI support
- */
-static void i2o_pci_activate(i2o_controller * c)
-{
- int i=0;


- struct i2o_controller *c;
-

- if(c->type == I2O_TYPE_PCI)
- {
- I2O_IRQ_WRITE32(c,0);
-#ifdef MODULE
- if(core->activate(c))
-#else
- if(i2o_activate_controller(c))
-#endif /* MODULE */
- {
- printk("%s: Failed to initialize.\n", c->name);
-#ifdef MODULE
- core->unlock(c);
- core->delete(c);
-#else
- i2o_unlock_controller(c);
- i2o_delete_controller(c);
-#endif


- continue;
- }
- }
-}

-#endif // I2O_HOTPLUG_SUPPORT
-
-#ifdef MODULE
-
-int i2o_pci_core_attach(struct i2o_core_func_table *table)
-{
- MOD_INC_USE_COUNT;
-
- core = table;
-
- return i2o_pci_scan();
-}
-
-void i2o_pci_core_detach(void)
-{
- core = NULL;


-
- MOD_DEC_USE_COUNT;
-}
-

-int init_module(void)
-{
- printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-
- core = NULL;


-
- return 0;
-
-}
-

-void cleanup_module(void)
-{
-}
-
-EXPORT_SYMBOL(i2o_pci_core_attach);
-EXPORT_SYMBOL(i2o_pci_core_detach);


-
-MODULE_AUTHOR("Red Hat Software");

-MODULE_DESCRIPTION("I2O PCI Interface");
-
-#else
-void __init i2o_pci_init(void)
-{
- printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
- i2o_pci_scan();
-}
-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c
--- v2.4.12/linux/drivers/i2o/i2o_proc.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_proc.c Wed Dec 31 16:00:00 1969
@@ -1,3379 +0,0 @@
-/*
- * procfs handler for Linux I2O subsystem
- *
- * (c) Copyright 1999 Deepak Saxena
- *
- * Originally written by Deepak Saxena(dee...@plexity.net)
- *
- * 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 is an initial test release. The code is based on the design
- * of the ide procfs system (drivers/block/ide-proc.c). Some code
- * taken from i2o-core module by Alan Cox.
- *
- * DISCLAIMER: This code is still under development/test and may cause
- * your system to behave unpredictably. Use at your own discretion.
- *
- * LAN entries by Juha Sievänen (Juha.S...@cs.Helsinki.FI),
- * Auvo Häkkinen (Auvo.H...@cs.Helsinki.FI)
- * University of Helsinki, Department of Computer Science
- */
-
-/*
- * set tabstop=3
- */
-
-/*
- * TODO List
- *
- * - Add support for any version 2.0 spec changes once 2.0 IRTOS is
- * is available to test with
- * - Clean up code to use official structure definitions
- */
-
-// FIXME!
-#define FMT_U64_HEX "0x%08x%08x"
-#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64))
-
-#include <linux/types.h>


-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>

-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-#include "i2o_lan.h"
-
-/*
- * Structure used to define /proc entries
- */
-typedef struct _i2o_proc_entry_t
-{
- char *name; /* entry name */
- mode_t mode; /* mode */
- read_proc_t *read_proc; /* read func */
- write_proc_t *write_proc; /* write func */
-} i2o_proc_entry;
-
-// #define DRIVERDEBUG
-
-static int i2o_proc_read_lct(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_hrt(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_status(char *, char **, off_t, int, int *, void *);
-
-static int i2o_proc_read_hw(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_ddm_table(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_driver_store(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_drivers_stored(char *, char **, off_t, int, int *, void *);
-
-static int i2o_proc_read_groups(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_phys_device(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_claimed(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_users(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_priv_msgs(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_authorized_users(char *, char **, off_t, int, int *, void *);
-
-static int i2o_proc_read_dev_name(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_dev_identity(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_ddm_identity(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_uinfo(char *, char **, off_t, int, int *, void *);
-static int i2o_proc_read_sgl_limits(char *, char **, off_t, int, int *, void *);
-
-static int i2o_proc_read_sensors(char *, char **, off_t, int, int *, void *);
-
-static int print_serial_number(char *, int, u8 *, int);
-
-static int i2o_proc_create_entries(void *, i2o_proc_entry *,
- struct proc_dir_entry *);
-static void i2o_proc_remove_entries(i2o_proc_entry *, struct proc_dir_entry *);
-static int i2o_proc_add_controller(struct i2o_controller *,
- struct proc_dir_entry * );
-static void i2o_proc_remove_controller(struct i2o_controller *,
- struct proc_dir_entry * );
-static void i2o_proc_add_device(struct i2o_device *, struct proc_dir_entry *);
-static void i2o_proc_remove_device(struct i2o_device *);
-static int create_i2o_procfs(void);
-static int destroy_i2o_procfs(void);
-static void i2o_proc_new_dev(struct i2o_controller *, struct i2o_device *);
-static void i2o_proc_dev_del(struct i2o_controller *, struct i2o_device *);
-
-static int i2o_proc_read_lan_dev_info(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_mac_addr(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_mcast_addr(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_batch_control(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_operation(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_media_operation(char *, char **, off_t, int,
- int *, void *);
-static int i2o_proc_read_lan_alt_addr(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_tx_info(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_rx_info(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_hist_stats(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_eth_stats(char *, char **, off_t, int,
- int *, void *);
-static int i2o_proc_read_lan_tr_stats(char *, char **, off_t, int, int *,
- void *);
-static int i2o_proc_read_lan_fddi_stats(char *, char **, off_t, int, int *,
- void *);
-
-static struct proc_dir_entry *i2o_proc_dir_root;
-
-/*
- * I2O OSM descriptor
- */
-static struct i2o_handler i2o_proc_handler =
-{
- NULL,
- i2o_proc_new_dev,
- i2o_proc_dev_del,
- NULL,
- "I2O procfs Layer",


- 0,
- 0xffffffff // All classes

-};
-
-/*
- * IOP specific entries...write field just in case someone
- * ever wants one.
- */
-static i2o_proc_entry generic_iop_entries[] =
-{
- {"hrt", S_IFREG|S_IRUGO, i2o_proc_read_hrt, NULL},
- {"lct", S_IFREG|S_IRUGO, i2o_proc_read_lct, NULL},
- {"status", S_IFREG|S_IRUGO, i2o_proc_read_status, NULL},
- {"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL},
- {"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL},
- {"driver_store", S_IFREG|S_IRUGO, i2o_proc_read_driver_store, NULL},
- {"drivers_stored", S_IFREG|S_IRUGO, i2o_proc_read_drivers_stored, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-/*
- * Device specific entries
- */
-static i2o_proc_entry generic_dev_entries[] =
-{
- {"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL},
- {"phys_dev", S_IFREG|S_IRUGO, i2o_proc_read_phys_device, NULL},
- {"claimed", S_IFREG|S_IRUGO, i2o_proc_read_claimed, NULL},
- {"users", S_IFREG|S_IRUGO, i2o_proc_read_users, NULL},
- {"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL},
- {"authorized_users", S_IFREG|S_IRUGO, i2o_proc_read_authorized_users, NULL},
- {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev_identity, NULL},
- {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm_identity, NULL},
- {"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL},
- {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL},
- {"sensors", S_IFREG|S_IRUGO, i2o_proc_read_sensors, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-/*
- * Storage unit specific entries (SCSI Periph, BS) with device names
- */
-static i2o_proc_entry rbs_dev_entries[] =
-{
- {"dev_name", S_IFREG|S_IRUGO, i2o_proc_read_dev_name, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-#define SCSI_TABLE_SIZE 13
-static char *scsi_devices[] =
-{
- "Direct-Access Read/Write",
- "Sequential-Access Storage",
- "Printer",
- "Processor",
- "WORM Device",
- "CD-ROM Device",
- "Scanner Device",
- "Optical Memory Device",
- "Medium Changer Device",
- "Communications Device",
- "Graphics Art Pre-Press Device",
- "Graphics Art Pre-Press Device",
- "Array Controller Device"
-};
-
-/* private */
-
-/*
- * Generic LAN specific entries
- *
- * Should groups with r/w entries have their own subdirectory?
- *
- */
-static i2o_proc_entry lan_entries[] =
-{
- {"lan_dev_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_dev_info, NULL},
- {"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL},
- {"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR,
- i2o_proc_read_lan_mcast_addr, NULL},
- {"lan_batch_ctrl", S_IFREG|S_IRUGO|S_IWUSR,
- i2o_proc_read_lan_batch_control, NULL},
- {"lan_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_operation, NULL},
- {"lan_media_operation", S_IFREG|S_IRUGO,
- i2o_proc_read_lan_media_operation, NULL},
- {"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL},
- {"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL},
- {"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL},
-
- {"lan_hist_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-/*
- * Port specific LAN entries
- *
- */
-static i2o_proc_entry lan_eth_entries[] =
-{
- {"lan_eth_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-static i2o_proc_entry lan_tr_entries[] =
-{
- {"lan_tr_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_tr_stats, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-static i2o_proc_entry lan_fddi_entries[] =
-{
- {"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL},
- {NULL, 0, NULL, NULL}
-};
-
-
-static char *chtostr(u8 *chars, int n)
-{
- char tmp[256];
- tmp[0] = 0;
- return strncat(tmp, (char *)chars, n);
-}
-
-static int i2o_report_query_status(char *buf, int block_status, char *group)
-{
- switch (block_status)
- {
- case -ETIMEDOUT:
- return sprintf(buf, "Timeout reading group %s.\n",group);
- case -ENOMEM:
- return sprintf(buf, "No free memory to read the table.\n");
- case -I2O_PARAMS_STATUS_INVALID_GROUP_ID:
- return sprintf(buf, "Group %s not supported.\n", group);
- default:
- return sprintf(buf, "Error reading group %s. BlockStatus 0x%02X\n",
- group, -block_status);
- }
-}
-
-static char* bus_strings[] =
-{
- "Local Bus",
- "ISA",
- "EISA",
- "MCA",
- "PCI",
- "PCMCIA",
- "NUBUS",
- "CARDBUS"
-};
-
-static spinlock_t i2o_proc_lock = SPIN_LOCK_UNLOCKED;
-
-int i2o_proc_read_hrt(char *buf, char **start, off_t offset, int len,
- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller *)data;
- i2o_hrt *hrt = (i2o_hrt *)c->hrt;
- u32 bus;
- int count;
- int i;
-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-
- if(hrt->hrt_version)
- {
- len += sprintf(buf+len,
- "HRT table for controller is too new a version.\n");
- spin_unlock(&i2o_proc_lock);
- return len;
- }
-
- count = hrt->num_entries;
-
- if((count * hrt->entry_len + 8) > 2048) {
- printk(KERN_WARNING "i2o_proc: HRT does not fit into buffer\n");
- len += sprintf(buf+len,
- "HRT table too big to fit in buffer.\n");
- spin_unlock(&i2o_proc_lock);
- return len;
- }
-
- len += sprintf(buf+len, "HRT has %d entries of %d bytes each.\n",
- count, hrt->entry_len << 2);
-
- for(i = 0; i < count; i++)
- {
- len += sprintf(buf+len, "Entry %d:\n", i);
- len += sprintf(buf+len, " Adapter ID: %0#10x\n",
- hrt->hrt_entry[i].adapter_id);
- len += sprintf(buf+len, " Controlling tid: %0#6x\n",
- hrt->hrt_entry[i].parent_tid);
-
- if(hrt->hrt_entry[i].bus_type != 0x80)
- {
- bus = hrt->hrt_entry[i].bus_type;
- len += sprintf(buf+len, " %s Information\n", bus_strings[bus]);
-
- switch(bus)
- {
- case I2O_BUS_LOCAL:
- len += sprintf(buf+len, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.local_bus.LbBaseIOPort);
- len += sprintf(buf+len, " MemoryBase: %0#10x\n",
- hrt->hrt_entry[i].bus.local_bus.LbBaseMemoryAddress);
- break;
-
- case I2O_BUS_ISA:
- len += sprintf(buf+len, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.isa_bus.IsaBaseIOPort);
- len += sprintf(buf+len, " MemoryBase: %0#10x,",
- hrt->hrt_entry[i].bus.isa_bus.IsaBaseMemoryAddress);
- len += sprintf(buf+len, " CSN: %0#4x,",
- hrt->hrt_entry[i].bus.isa_bus.CSN);
- break;
-
- case I2O_BUS_EISA:
- len += sprintf(buf+len, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.eisa_bus.EisaBaseIOPort);
- len += sprintf(buf+len, " MemoryBase: %0#10x,",
- hrt->hrt_entry[i].bus.eisa_bus.EisaBaseMemoryAddress);
- len += sprintf(buf+len, " Slot: %0#4x,",
- hrt->hrt_entry[i].bus.eisa_bus.EisaSlotNumber);
- break;
-
- case I2O_BUS_MCA:
- len += sprintf(buf+len, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.mca_bus.McaBaseIOPort);
- len += sprintf(buf+len, " MemoryBase: %0#10x,",
- hrt->hrt_entry[i].bus.mca_bus.McaBaseMemoryAddress);
- len += sprintf(buf+len, " Slot: %0#4x,",
- hrt->hrt_entry[i].bus.mca_bus.McaSlotNumber);
- break;
-
- case I2O_BUS_PCI:
- len += sprintf(buf+len, " Bus: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.PciBusNumber);
- len += sprintf(buf+len, " Dev: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.PciDeviceNumber);
- len += sprintf(buf+len, " Func: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.PciFunctionNumber);
- len += sprintf(buf+len, " Vendor: %0#6x",
- hrt->hrt_entry[i].bus.pci_bus.PciVendorID);
- len += sprintf(buf+len, " Device: %0#6x\n",
- hrt->hrt_entry[i].bus.pci_bus.PciDeviceID);


- break;
-
- default:

- len += sprintf(buf+len, " Unsupported Bus Type\n");
- }
- }
- else
- len += sprintf(buf+len, " Unknown Bus Type\n");
- }
-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-int i2o_proc_read_lct(char *buf, char **start, off_t offset, int len,
- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller*)data;
- i2o_lct *lct = (i2o_lct *)c->lct;
- int entries;
- int i;
-
-#define BUS_TABLE_SIZE 3
- static char *bus_ports[] =
- {
- "Generic Bus",
- "SCSI Bus",
- "Fibre Channel Bus"
- };
-
- spin_lock(&i2o_proc_lock);
- len = 0;
-
- entries = (lct->table_size - 3)/9;
-
- len += sprintf(buf, "LCT contains %d %s\n", entries,
- entries == 1 ? "entry" : "entries");
- if(lct->boot_tid)
- len += sprintf(buf+len, "Boot Device @ ID %d\n", lct->boot_tid);
-
- len +=
- sprintf(buf+len, "Current Change Indicator: %#10x\n", lct->change_ind);
-
- for(i = 0; i < entries; i++)
- {
- len += sprintf(buf+len, "Entry %d\n", i);
- len += sprintf(buf+len, " Class, SubClass : %s", i2o_get_class_name(lct->lct_entry[i].class_id));
-
- /*
- * Classes which we'll print subclass info for
- */
- switch(lct->lct_entry[i].class_id & 0xFFF)
- {
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- switch(lct->lct_entry[i].sub_class)
- {
- case 0x00:
- len += sprintf(buf+len, ", Direct-Access Read/Write");
- break;
-
- case 0x04:
- len += sprintf(buf+len, ", WORM Drive");
- break;
-
- case 0x05:
- len += sprintf(buf+len, ", CD-ROM Drive");
- break;
-
- case 0x07:
- len += sprintf(buf+len, ", Optical Memory Device");
- break;
-
- default:
- len += sprintf(buf+len, ", Unknown (0x%02x)",
- lct->lct_entry[i].sub_class);
- break;
- }
- break;
-
- case I2O_CLASS_LAN:
- switch(lct->lct_entry[i].sub_class & 0xFF)
- {
- case 0x30:
- len += sprintf(buf+len, ", Ethernet");
- break;
-
- case 0x40:
- len += sprintf(buf+len, ", 100base VG");
- break;
-
- case 0x50:
- len += sprintf(buf+len, ", IEEE 802.5/Token-Ring");
- break;
-
- case 0x60:
- len += sprintf(buf+len, ", ANSI X3T9.5 FDDI");
- break;
-
- case 0x70:
- len += sprintf(buf+len, ", Fibre Channel");
- break;
-
- default:
- len += sprintf(buf+len, ", Unknown Sub-Class (0x%02x)",
- lct->lct_entry[i].sub_class & 0xFF);
- break;
- }
- break;
-
- case I2O_CLASS_SCSI_PERIPHERAL:
- if(lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE)
- len += sprintf(buf+len, ", %s",
- scsi_devices[lct->lct_entry[i].sub_class]);
- else
- len += sprintf(buf+len, ", Unknown Device Type");
- break;
-
- case I2O_CLASS_BUS_ADAPTER_PORT:
- if(lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
- len += sprintf(buf+len, ", %s",
- bus_ports[lct->lct_entry[i].sub_class]);
- else
- len += sprintf(buf+len, ", Unknown Bus Type");
- break;
- }
- len += sprintf(buf+len, "\n");
-
- len += sprintf(buf+len, " Local TID : 0x%03x\n", lct->lct_entry[i].tid);
- len += sprintf(buf+len, " User TID : 0x%03x\n", lct->lct_entry[i].user_tid);
- len += sprintf(buf+len, " Parent TID : 0x%03x\n",
- lct->lct_entry[i].parent_tid);
- len += sprintf(buf+len, " Identity Tag : 0x%x%x%x%x%x%x%x%x\n",
- lct->lct_entry[i].identity_tag[0],
- lct->lct_entry[i].identity_tag[1],
- lct->lct_entry[i].identity_tag[2],
- lct->lct_entry[i].identity_tag[3],
- lct->lct_entry[i].identity_tag[4],
- lct->lct_entry[i].identity_tag[5],
- lct->lct_entry[i].identity_tag[6],
- lct->lct_entry[i].identity_tag[7]);
- len += sprintf(buf+len, " Change Indicator : %0#10x\n",
- lct->lct_entry[i].change_ind);
- len += sprintf(buf+len, " Event Capab Mask : %0#10x\n",
- lct->lct_entry[i].device_flags);
- }
-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-
-int i2o_proc_read_status(char *buf, char **start, off_t offset, int len,
- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller*)data;
- char prodstr[25];
- int version;
-
- spin_lock(&i2o_proc_lock);
- len = 0;
-
- i2o_status_get(c); // reread the status block
-
- len += sprintf(buf+len,"Organization ID : %0#6x\n",
- c->status_block->org_id);
-
- version = c->status_block->i2o_version;
-
-/* FIXME for Spec 2.0
- if (version == 0x02) {
- len += sprintf(buf+len,"Lowest I2O version supported: ");
- switch(workspace[2]) {
- case 0x00:
- len += sprintf(buf+len,"1.0\n");
- break;
- case 0x01:
- len += sprintf(buf+len,"1.5\n");
- break;
- case 0x02:
- len += sprintf(buf+len,"2.0\n");
- break;
- }
-
- len += sprintf(buf+len, "Highest I2O version supported: ");
- switch(workspace[3]) {
- case 0x00:
- len += sprintf(buf+len,"1.0\n");
- break;
- case 0x01:
- len += sprintf(buf+len,"1.5\n");
- break;
- case 0x02:
- len += sprintf(buf+len,"2.0\n");
- break;
- }
- }
-*/
- len += sprintf(buf+len,"IOP ID : %0#5x\n",
- c->status_block->iop_id);
- len += sprintf(buf+len,"Host Unit ID : %0#6x\n",
- c->status_block->host_unit_id);
- len += sprintf(buf+len,"Segment Number : %0#5x\n",
- c->status_block->segment_number);
-
- len += sprintf(buf+len, "I2O version : ");
- switch (version) {
- case 0x00:
- len += sprintf(buf+len,"1.0\n");
- break;
- case 0x01:
- len += sprintf(buf+len,"1.5\n");
- break;
- case 0x02:
- len += sprintf(buf+len,"2.0\n");
- break;
- default:
- len += sprintf(buf+len,"Unknown version\n");
- }
-
- len += sprintf(buf+len, "IOP State : ");


- switch (c->status_block->iop_state) {
- case 0x01:

- len += sprintf(buf+len,"INIT\n");
- break;
-
- case 0x02:
- len += sprintf(buf+len,"RESET\n");
- break;
-
- case 0x04:
- len += sprintf(buf+len,"HOLD\n");
- break;
-
- case 0x05:
- len += sprintf(buf+len,"READY\n");
- break;
-
- case 0x08:
- len += sprintf(buf+len,"OPERATIONAL\n");
- break;
-
- case 0x10:
- len += sprintf(buf+len,"FAILED\n");
- break;
-
- case 0x11:
- len += sprintf(buf+len,"FAULTED\n");
- break;
-
- default:
- len += sprintf(buf+len,"Unknown\n");
- break;
- }
-
- len += sprintf(buf+len,"Messenger Type : ");
- switch (c->status_block->msg_type) {
- case 0x00:
- len += sprintf(buf+len,"Memory mapped\n");
- break;
- case 0x01:
- len += sprintf(buf+len,"Memory mapped only\n");
- break;
- case 0x02:
- len += sprintf(buf+len,"Remote only\n");
- break;
- case 0x03:
- len += sprintf(buf+len,"Memory mapped and remote\n");
- break;
- default:
- len += sprintf(buf+len,"Unknown\n");
- }
-
- len += sprintf(buf+len,"Inbound Frame Size : %d bytes\n",
- c->status_block->inbound_frame_size<<2);
- len += sprintf(buf+len,"Max Inbound Frames : %d\n",
- c->status_block->max_inbound_frames);
- len += sprintf(buf+len,"Current Inbound Frames : %d\n",
- c->status_block->cur_inbound_frames);
- len += sprintf(buf+len,"Max Outbound Frames : %d\n",
- c->status_block->max_outbound_frames);
-
- /* Spec doesn't say if NULL terminated or not... */
- memcpy(prodstr, c->status_block->product_id, 24);
- prodstr[24] = '\0';
- len += sprintf(buf+len,"Product ID : %s\n", prodstr);
- len += sprintf(buf+len,"Expected LCT Size : %d bytes\n",
- c->status_block->expected_lct_size);
-
- len += sprintf(buf+len,"IOP Capabilities\n");
- len += sprintf(buf+len," Context Field Size Support : ");
- switch (c->status_block->iop_capabilities & 0x0000003) {
- case 0:
- len += sprintf(buf+len,"Supports only 32-bit context fields\n");
- break;
- case 1:
- len += sprintf(buf+len,"Supports only 64-bit context fields\n");
- break;
- case 2:
- len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields, "
- "but not concurrently\n");
- break;
- case 3:
- len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields "
- "concurrently\n");
- break;
- default:
- len += sprintf(buf+len,"0x%08x\n",c->status_block->iop_capabilities);
- }
- len += sprintf(buf+len," Current Context Field Size : ");
- switch (c->status_block->iop_capabilities & 0x0000000C) {
- case 0:
- len += sprintf(buf+len,"not configured\n");
- break;
- case 4:
- len += sprintf(buf+len,"Supports only 32-bit context fields\n");
- break;
- case 8:
- len += sprintf(buf+len,"Supports only 64-bit context fields\n");
- break;
- case 12:
- len += sprintf(buf+len,"Supports both 32-bit or 64-bit context fields "
- "concurrently\n");
- break;
- default:
- len += sprintf(buf+len,"\n");
- }
- len += sprintf(buf+len," Inbound Peer Support : %s\n",
- (c->status_block->iop_capabilities & 0x00000010) ? "Supported" : "Not supported");
- len += sprintf(buf+len," Outbound Peer Support : %s\n",
- (c->status_block->iop_capabilities & 0x00000020) ? "Supported" : "Not supported");
- len += sprintf(buf+len," Peer to Peer Support : %s\n",
- (c->status_block->iop_capabilities & 0x00000040) ? "Supported" : "Not supported");
-
- len += sprintf(buf+len, "Desired private memory size : %d kB\n",
- c->status_block->desired_mem_size>>10);
- len += sprintf(buf+len, "Allocated private memory size : %d kB\n",
- c->status_block->current_mem_size>>10);
- len += sprintf(buf+len, "Private memory base address : %0#10x\n",
- c->status_block->current_mem_base);
- len += sprintf(buf+len, "Desired private I/O size : %d kB\n",
- c->status_block->desired_io_size>>10);
- len += sprintf(buf+len, "Allocated private I/O size : %d kB\n",
- c->status_block->current_io_size>>10);
- len += sprintf(buf+len, "Private I/O base address : %0#10x\n",
- c->status_block->current_io_base);
-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-int i2o_proc_read_hw(char *buf, char **start, off_t offset, int len,
- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller*)data;
- static u32 work32[5];
- static u8 *work8 = (u8*)work32;
- static u16 *work16 = (u16*)work32;
- int token;
- u32 hwcap;
-
- static char *cpu_table[] =
- {
- "Intel 80960 series",
- "AMD2900 series",
- "Motorola 68000 series",
- "ARM series",
- "MIPS series",
- "Sparc series",
- "PowerPC series",
- "Intel x86 series"
- };
-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-
- token = i2o_query_scalar(c, ADAPTER_TID, 0x0000, -1, &work32, sizeof(work32));
-
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0000 IOP Hardware");


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 19'
echo 'File patch-2.4.13 is continued in part 20'
echo "20" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:50 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part20

#!/bin/sh -x
# this is part 20 of a 53 - part archive


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

if test "$Scheck" != 20; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "I2O Vendor ID : %0#6x\n", work16[0]);
- len += sprintf(buf+len, "Product ID : %0#6x\n", work16[1]);
- len += sprintf(buf+len, "CPU : ");
- if(work8[16] > 8)


- len += sprintf(buf+len, "Unknown\n");

- else
- len += sprintf(buf+len, "%s\n", cpu_table[work8[16]]);
- /* Anyone using ProcessorVersion? */
-
- len += sprintf(buf+len, "RAM : %dkB\n", work32[1]>>10);
- len += sprintf(buf+len, "Non-Volatile Mem : %dkB\n", work32[2]>>10);
-
- hwcap = work32[3];
- len += sprintf(buf+len, "Capabilities : 0x%08x\n", hwcap);
- len += sprintf(buf+len, " [%s] Self booting\n",
- (hwcap&0x00000001) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Upgradable IRTOS\n",
- (hwcap&0x00000002) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Supports downloading DDMs\n",
- (hwcap&0x00000004) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Supports installing DDMs\n",
- (hwcap&0x00000008) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Battery-backed RAM\n",
- (hwcap&0x00000010) ? "+" : "-");


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-/* Executive group 0003h - Executing DDM List (table) */
-int i2o_proc_read_ddm_table(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller*)data;

- int token;
- int i;
-
- typedef struct _i2o_exec_execute_ddm_table {
- u16 ddm_tid;
- u8 module_type;
- u8 reserved;
- u16 i2o_vendor_id;
- u16 module_id;
- u8 module_name_version[28];
- u32 data_size;
- u32 code_size;
- } i2o_exec_execute_ddm_table;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_exec_execute_ddm_table ddm_table[MAX_I2O_MODULES];
- } result;
-
- i2o_exec_execute_ddm_table ddm_table;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- c, ADAPTER_TID,
- 0x0003, -1,
- NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0003 Executing DDM List");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Tid Module_type Vendor Mod_id Module_name Vrs Data_size Code_size\n");
- ddm_table=result.ddm_table[0];
-
- for(i=0; i < result.row_count; ddm_table=result.ddm_table[++i])
- {
- len += sprintf(buf+len, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
-
- switch(ddm_table.module_type)
- {
- case 0x01:
- len += sprintf(buf+len, "Downloaded DDM ");
- break;
- case 0x22:
- len += sprintf(buf+len, "Embedded DDM ");
- break;
- default:
- len += sprintf(buf+len, " ");
- }
-
- len += sprintf(buf+len, "%-#7x", ddm_table.i2o_vendor_id);
- len += sprintf(buf+len, "%-#8x", ddm_table.module_id);
- len += sprintf(buf+len, "%-29s", chtostr(ddm_table.module_name_version, 28));
- len += sprintf(buf+len, "%9d ", ddm_table.data_size);
- len += sprintf(buf+len, "%8d", ddm_table.code_size);


-
- len += sprintf(buf+len, "\n");
- }
-

- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-/* Executive group 0004h - Driver Store (scalar) */
-int i2o_proc_read_driver_store(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{
- struct i2o_controller *c = (struct i2o_controller*)data;

- u32 work32[8];
- int token;


-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_scalar(c, ADAPTER_TID, 0x0004, -1, &work32, sizeof(work32));
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0004 Driver Store");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Module limit : %d\n"
- "Module count : %d\n"
- "Current space : %d kB\n"
- "Free space : %d kB\n",
- work32[0], work32[1], work32[2]>>10, work32[3]>>10);


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-/* Executive group 0005h - Driver Store Table (table) */
-int i2o_proc_read_drivers_stored(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
- typedef struct _i2o_driver_store {
- u16 stored_ddm_index;
- u8 module_type;
- u8 reserved;
- u16 i2o_vendor_id;
- u16 module_id;
- u8 module_name_version[28];
- u8 date[8];
- u32 module_size;
- u32 mpb_size;
- u32 module_flags;
- } i2o_driver_store_table;


-
- struct i2o_controller *c = (struct i2o_controller*)data;

- int token;
- int i;
-
- typedef struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_driver_store_table dst[MAX_I2O_MODULES];
- } i2o_driver_result_table;
-
- i2o_driver_result_table *result;
- i2o_driver_store_table *dst;


-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL);
- if(result == NULL)
- return -ENOMEM;
-
- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- c, ADAPTER_TID, 0x0005, -1, NULL, 0,
- result, sizeof(*result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0005 DRIVER STORE TABLE");
- spin_unlock(&i2o_proc_lock);
- kfree(result);


- return len;
- }
-

- len += sprintf(buf+len, "# Module_type Vendor Mod_id Module_name Vrs"
- "Date Mod_size Par_size Flags\n");
- for(i=0, dst=&result->dst[0]; i < result->row_count; dst=&result->dst[++i])
- {
- len += sprintf(buf+len, "%-3d", dst->stored_ddm_index);
- switch(dst->module_type)
- {
- case 0x01:
- len += sprintf(buf+len, "Downloaded DDM ");
- break;
- case 0x22:
- len += sprintf(buf+len, "Embedded DDM ");
- break;
- default:
- len += sprintf(buf+len, " ");
- }
-
-#if 0
- if(c->i2oversion == 0x02)
- len += sprintf(buf+len, "%-d", dst->module_state);
-#endif
-
- len += sprintf(buf+len, "%-#7x", dst->i2o_vendor_id);
- len += sprintf(buf+len, "%-#8x", dst->module_id);
- len += sprintf(buf+len, "%-29s", chtostr(dst->module_name_version,28));
- len += sprintf(buf+len, "%-9s", chtostr(dst->date,8));
- len += sprintf(buf+len, "%8d ", dst->module_size);
- len += sprintf(buf+len, "%8d ", dst->mpb_size);
- len += sprintf(buf+len, "0x%04x", dst->module_flags);
-#if 0
- if(c->i2oversion == 0x02)
- len += sprintf(buf+len, "%d",
- dst->notification_level);
-#endif


- len += sprintf(buf+len, "\n");
- }
-

- spin_unlock(&i2o_proc_lock);
- kfree(result);


- return len;
-}
-
-

-/* Generic group F000h - Params Descriptor (table) */
-int i2o_proc_read_groups(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
- u8 properties;
-
- typedef struct _i2o_group_info
- {
- u16 group_number;
- u16 field_count;
- u16 row_count;
- u8 properties;
- u8 reserved;
- } i2o_group_info;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_group_info group[256];
- } result;


-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid, 0xF000, -1, NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len = i2o_report_query_status(buf+len, token, "0xF000 Params Descriptor");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "# Group FieldCount RowCount Type Add Del Clear\n");
-
- for (i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%-3d", i);
- len += sprintf(buf+len, "0x%04X ", result.group[i].group_number);
- len += sprintf(buf+len, "%10d ", result.group[i].field_count);
- len += sprintf(buf+len, "%8d ", result.group[i].row_count);
-
- properties = result.group[i].properties;
- if (properties & 0x1) len += sprintf(buf+len, "Table ");
- else len += sprintf(buf+len, "Scalar ");
- if (properties & 0x2) len += sprintf(buf+len, " + ");
- else len += sprintf(buf+len, " - ");
- if (properties & 0x4) len += sprintf(buf+len, " + ");
- else len += sprintf(buf+len, " - ");
- if (properties & 0x8) len += sprintf(buf+len, " + ");
- else len += sprintf(buf+len, " - ");
-
- len += sprintf(buf+len, "\n");
- }
-
- if (result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-/* Generic group F001h - Physical Device Table (table) */
-int i2o_proc_read_phys_device(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u32 adapter_id[64];
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0xF001, -1, NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF001 Physical Device Table");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- if (result.row_count)
- len += sprintf(buf+len, "# AdapterId\n");
-
- for (i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%-2d", i);
- len += sprintf(buf+len, "%#7x\n", result.adapter_id[i]);
- }
-
- if (result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* Generic group F002h - Claimed Table (table) */
-int i2o_proc_read_claimed(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u16 claimed_tid[64];
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0xF002, -1, NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF002 Claimed Table");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- if (result.row_count)
- len += sprintf(buf+len, "# ClaimedTid\n");
-
- for (i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%-2d", i);
- len += sprintf(buf+len, "%#7x\n", result.claimed_tid[i]);
- }
-
- if (result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* Generic group F003h - User Table (table) */
-int i2o_proc_read_users(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
-
- typedef struct _i2o_user_table
- {
- u16 instance;
- u16 user_tid;
- u8 claim_type;
- u8 reserved1;
- u16 reserved2;
- } i2o_user_table;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_user_table user[64];
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0xF003, -1, NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF003 User Table");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "# Instance UserTid ClaimType\n");
-
- for(i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%-3d", i);
- len += sprintf(buf+len, "%#8x ", result.user[i].instance);
- len += sprintf(buf+len, "%#7x ", result.user[i].user_tid);
- len += sprintf(buf+len, "%#9x\n", result.user[i].claim_type);
- }
-
- if (result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* Generic group F005h - Private message extensions (table) (optional) */
-int i2o_proc_read_priv_msgs(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
-
- typedef struct _i2o_private
- {
- u16 ext_instance;
- u16 organization_id;
- u16 x_function_code;
- } i2o_private;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_private extension[64];
- } result;


-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0xF000, -1,
- NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF005 Private Message Extensions (optional)");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Instance# OrgId FunctionCode\n");
-
- for(i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%0#9x ", result.extension[i].ext_instance);
- len += sprintf(buf+len, "%0#6x ", result.extension[i].organization_id);
- len += sprintf(buf+len, "%0#6x", result.extension[i].x_function_code);


-
- len += sprintf(buf+len, "\n");
- }
-

- if(result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-/* Generic group F006h - Authorized User Table (table) */
-int i2o_proc_read_authorized_users(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u32 alternate_tid[64];
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0xF006, -1,
- NULL, 0,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF006 Autohorized User Table");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- if (result.row_count)
- len += sprintf(buf+len, "# AlternateTid\n");
-
- for(i=0; i < result.row_count; i++)
- {
- len += sprintf(buf+len, "%-2d", i);
- len += sprintf(buf+len, "%#7x ", result.alternate_tid[i]);
- }
-
- if (result.more_flag)
- len += sprintf(buf+len, "There is more...\n");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-
-

-/* Generic group F100h - Device Identity (scalar) */
-int i2o_proc_read_dev_identity(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number
- // == (allow) 512d bytes (max)


- static u16 *work16 = (u16*)work32;
- int token;
-

- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0xF100, -1,
- &work32, sizeof(work32));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token ,"0xF100 Device Identity");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Device Class : %s\n", i2o_get_class_name(work16[0]));
- len += sprintf(buf+len, "Owner TID : %0#5x\n", work16[2]);
- len += sprintf(buf+len, "Parent TID : %0#5x\n", work16[3]);
- len += sprintf(buf+len, "Vendor info : %s\n", chtostr((u8 *)(work32+2), 16));
- len += sprintf(buf+len, "Product info : %s\n", chtostr((u8 *)(work32+6), 16));
- len += sprintf(buf+len, "Description : %s\n", chtostr((u8 *)(work32+10), 16));
- len += sprintf(buf+len, "Product rev. : %s\n", chtostr((u8 *)(work32+14), 8));
-
- len += sprintf(buf+len, "Serial number : ");
- len = print_serial_number(buf, len,
- (u8*)(work32+16),
- /* allow for SNLen plus
- * possible trailing '\0'
- */
- sizeof(work32)-(16*sizeof(u32))-2
- );
- len += sprintf(buf+len, "\n");


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-
-

-int i2o_proc_read_dev_name(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
-
- if ( d->dev_name[0] == '\0' )
- return 0;
-
- len = sprintf(buf, "%s\n", d->dev_name);


-
- return len;
-}
-
-

-/* Generic group F101h - DDM Identity (scalar) */
-int i2o_proc_read_ddm_identity(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {
- u16 ddm_tid;
- u8 module_name[24];
- u8 module_rev[8];
- u8 sn_format;
- u8 serial_number[12];
- u8 pad[256]; // allow up to 256 byte (max) serial number
- } result;

-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0xF101, -1,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF101 DDM Identity");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
- len += sprintf(buf+len, "Module name : %s\n", chtostr(result.module_name, 24));
- len += sprintf(buf+len, "Module revision : %s\n", chtostr(result.module_rev, 8));
-
- len += sprintf(buf+len, "Serial number : ");
- len = print_serial_number(buf, len, result.serial_number, sizeof(result)-36);
- /* allow for SNLen plus possible trailing '\0' */


-
- len += sprintf(buf+len, "\n");
-

- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-

-/* Generic group F102h - User Information (scalar) */
-int i2o_proc_read_uinfo(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {
- u8 device_name[64];
- u8 service_name[64];
- u8 physical_location[64];
- u8 instance_number[4];
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0xF102, -1,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF102 User Information");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Device name : %s\n", chtostr(result.device_name, 64));
- len += sprintf(buf+len, "Service name : %s\n", chtostr(result.service_name, 64));
- len += sprintf(buf+len, "Physical name : %s\n", chtostr(result.physical_location, 64));
- len += sprintf(buf+len, "Instance number : %s\n", chtostr(result.instance_number, 4));


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* Generic group F103h - SGL Operating Limits (scalar) */
-int i2o_proc_read_sgl_limits(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[12];


- static u16 *work16 = (u16 *)work32;
- static u8 *work8 = (u8 *)work32;

- int token;


-
- spin_lock(&i2o_proc_lock);
-
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0xF103, -1,
- &work32, sizeof(work32));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF103 SGL Operating Limits");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "SGL chain size : %d\n", work32[0]);
- len += sprintf(buf+len, "Max SGL chain size : %d\n", work32[1]);
- len += sprintf(buf+len, "SGL chain size target : %d\n", work32[2]);
- len += sprintf(buf+len, "SGL frag count : %d\n", work16[6]);
- len += sprintf(buf+len, "Max SGL frag count : %d\n", work16[7]);
- len += sprintf(buf+len, "SGL frag count target : %d\n", work16[8]);
-
- if (d->i2oversion == 0x02)
- {
- len += sprintf(buf+len, "SGL data alignment : %d\n", work16[8]);
- len += sprintf(buf+len, "SGL addr limit : %d\n", work8[20]);
- len += sprintf(buf+len, "SGL addr sizes supported : ");
- if (work8[21] & 0x01)
- len += sprintf(buf+len, "32 bit ");
- if (work8[21] & 0x02)
- len += sprintf(buf+len, "64 bit ");
- if (work8[21] & 0x04)
- len += sprintf(buf+len, "96 bit ");
- if (work8[21] & 0x08)
- len += sprintf(buf+len, "128 bit ");
- len += sprintf(buf+len, "\n");


- }
-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-

-/* Generic group F200h - Sensors (scalar) */
-int i2o_proc_read_sensors(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {
- u16 sensor_instance;
- u8 component;
- u16 component_instance;
- u8 sensor_class;
- u8 sensor_type;
- u8 scaling_exponent;
- u32 actual_reading;
- u32 minimum_reading;
- u32 low2lowcat_treshold;
- u32 lowcat2low_treshold;
- u32 lowwarn2low_treshold;
- u32 low2lowwarn_treshold;
- u32 norm2lowwarn_treshold;
- u32 lowwarn2norm_treshold;
- u32 nominal_reading;
- u32 hiwarn2norm_treshold;
- u32 norm2hiwarn_treshold;
- u32 high2hiwarn_treshold;
- u32 hiwarn2high_treshold;
- u32 hicat2high_treshold;
- u32 hi2hicat_treshold;
- u32 maximum_reading;
- u8 sensor_state;
- u16 event_enable;
- } result;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0xF200, -1,
- &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0xF200 Sensors (optional)");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Sensor instance : %d\n", result.sensor_instance);
-
- len += sprintf(buf+len, "Component : %d = ", result.component);
- switch (result.component)
- {
- case 0: len += sprintf(buf+len, "Other");
- break;
- case 1: len += sprintf(buf+len, "Planar logic Board");
- break;
- case 2: len += sprintf(buf+len, "CPU");
- break;
- case 3: len += sprintf(buf+len, "Chassis");
- break;
- case 4: len += sprintf(buf+len, "Power Supply");
- break;
- case 5: len += sprintf(buf+len, "Storage");
- break;
- case 6: len += sprintf(buf+len, "External");


- break;
- }
- len += sprintf(buf+len,"\n");
-

- len += sprintf(buf+len, "Component instance : %d\n", result.component_instance);
- len += sprintf(buf+len, "Sensor class : %s\n",
- result.sensor_class ? "Analog" : "Digital");
-
- len += sprintf(buf+len, "Sensor type : %d = ",result.sensor_type);
- switch (result.sensor_type)
- {
- case 0: len += sprintf(buf+len, "Other\n");
- break;
- case 1: len += sprintf(buf+len, "Thermal\n");
- break;
- case 2: len += sprintf(buf+len, "DC voltage (DC volts)\n");
- break;
- case 3: len += sprintf(buf+len, "AC voltage (AC volts)\n");
- break;
- case 4: len += sprintf(buf+len, "DC current (DC amps)\n");
- break;
- case 5: len += sprintf(buf+len, "AC current (AC volts)\n");
- break;
- case 6: len += sprintf(buf+len, "Door open\n");
- break;
- case 7: len += sprintf(buf+len, "Fan operational\n");
- break;
- }
-
- len += sprintf(buf+len, "Scaling exponent : %d\n", result.scaling_exponent);
- len += sprintf(buf+len, "Actual reading : %d\n", result.actual_reading);
- len += sprintf(buf+len, "Minimum reading : %d\n", result.minimum_reading);
- len += sprintf(buf+len, "Low2LowCat treshold : %d\n", result.low2lowcat_treshold);
- len += sprintf(buf+len, "LowCat2Low treshold : %d\n", result.lowcat2low_treshold);
- len += sprintf(buf+len, "LowWarn2Low treshold : %d\n", result.lowwarn2low_treshold);
- len += sprintf(buf+len, "Low2LowWarn treshold : %d\n", result.low2lowwarn_treshold);
- len += sprintf(buf+len, "Norm2LowWarn treshold : %d\n", result.norm2lowwarn_treshold);
- len += sprintf(buf+len, "LowWarn2Norm treshold : %d\n", result.lowwarn2norm_treshold);
- len += sprintf(buf+len, "Nominal reading : %d\n", result.nominal_reading);
- len += sprintf(buf+len, "HiWarn2Norm treshold : %d\n", result.hiwarn2norm_treshold);
- len += sprintf(buf+len, "Norm2HiWarn treshold : %d\n", result.norm2hiwarn_treshold);
- len += sprintf(buf+len, "High2HiWarn treshold : %d\n", result.high2hiwarn_treshold);
- len += sprintf(buf+len, "HiWarn2High treshold : %d\n", result.hiwarn2high_treshold);
- len += sprintf(buf+len, "HiCat2High treshold : %d\n", result.hicat2high_treshold);
- len += sprintf(buf+len, "High2HiCat treshold : %d\n", result.hi2hicat_treshold);
- len += sprintf(buf+len, "Maximum reading : %d\n", result.maximum_reading);
-
- len += sprintf(buf+len, "Sensor state : %d = ", result.sensor_state);
- switch (result.sensor_state)
- {
- case 0: len += sprintf(buf+len, "Normal\n");
- break;
- case 1: len += sprintf(buf+len, "Abnormal\n");
- break;
- case 2: len += sprintf(buf+len, "Unknown\n");
- break;
- case 3: len += sprintf(buf+len, "Low Catastrophic (LoCat)\n");
- break;
- case 4: len += sprintf(buf+len, "Low (Low)\n");
- break;
- case 5: len += sprintf(buf+len, "Low Warning (LoWarn)\n");
- break;
- case 6: len += sprintf(buf+len, "High Warning (HiWarn)\n");
- break;
- case 7: len += sprintf(buf+len, "High (High)\n");
- break;
- case 8: len += sprintf(buf+len, "High Catastrophic (HiCat)\n");
- break;
- }
-
- len += sprintf(buf+len, "Event_enable : 0x%02X\n", result.event_enable);
- len += sprintf(buf+len, " [%s] Operational state change. \n",
- (result.event_enable & 0x01) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] Low catastrophic. \n",
- (result.event_enable & 0x02) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] Low reading. \n",
- (result.event_enable & 0x04) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] Low warning. \n",
- (result.event_enable & 0x08) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] Change back to normal from out of range state. \n",
- (result.event_enable & 0x10) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] High warning. \n",
- (result.event_enable & 0x20) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] High reading. \n",
- (result.event_enable & 0x40) ? "+" : "-" );
- len += sprintf(buf+len, " [%s] High catastrophic. \n",
- (result.event_enable & 0x80) ? "+" : "-" );


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-
-

-static int print_serial_number(char *buff, int pos, u8 *serialno, int max_len)


-{
- int i;
-

- /* 19990419 -sralston
- * The I2O v1.5 (and v2.0 so far) "official specification"
- * got serial numbers WRONG!
- * Apparently, and despite what Section 3.4.4 says and
- * Figure 3-35 shows (pg 3-39 in the pdf doc),
- * the convention / consensus seems to be:
- * + First byte is SNFormat
- * + Second byte is SNLen (but only if SNFormat==7 (?))
- * + (v2.0) SCSI+BS may use IEEE Registered (64 or 128 bit) format
- */
- switch(serialno[0])
- {
- case I2O_SNFORMAT_BINARY: /* Binary */
- pos += sprintf(buff+pos, "0x");
- for(i = 0; i < serialno[1]; i++)
- {
- pos += sprintf(buff+pos, "%02X", serialno[2+i]);
- }
- break;
-
- case I2O_SNFORMAT_ASCII: /* ASCII */
- if ( serialno[1] < ' ' ) /* printable or SNLen? */
- {
- /* sanity */
- max_len = (max_len < serialno[1]) ? max_len : serialno[1];
- serialno[1+max_len] = '\0';
-
- /* just print it */
- pos += sprintf(buff+pos, "%s", &serialno[2]);
- }
- else
- {
- /* print chars for specified length */
- for(i = 0; i < serialno[1]; i++)
- {
- pos += sprintf(buff+pos, "%c", serialno[2+i]);
- }
- }
- break;
-
- case I2O_SNFORMAT_UNICODE: /* UNICODE */
- pos += sprintf(buff+pos, "UNICODE Format. Can't Display\n");
- break;
-
- case I2O_SNFORMAT_LAN48_MAC: /* LAN-48 MAC Address */
- pos += sprintf(buff+pos,
- "LAN-48 MAC address @ %02X:%02X:%02X:%02X:%02X:%02X",
- serialno[2], serialno[3],
- serialno[4], serialno[5],
- serialno[6], serialno[7]);
- break;
-
- case I2O_SNFORMAT_WAN: /* WAN MAC Address */
- /* FIXME: Figure out what a WAN access address looks like?? */
- pos += sprintf(buff+pos, "WAN Access Address");
- break;
-
-/* plus new in v2.0 */
- case I2O_SNFORMAT_LAN64_MAC: /* LAN-64 MAC Address */
- /* FIXME: Figure out what a LAN-64 address really looks like?? */
- pos += sprintf(buff+pos,
- "LAN-64 MAC address @ [?:%02X:%02X:?] %02X:%02X:%02X:%02X:%02X:%02X",
- serialno[8], serialno[9],
- serialno[2], serialno[3],
- serialno[4], serialno[5],
- serialno[6], serialno[7]);
- break;
-
-
- case I2O_SNFORMAT_DDM: /* I2O DDM */
- pos += sprintf(buff+pos,
- "DDM: Tid=%03Xh, Rsvd=%04Xh, OrgId=%04Xh",
- *(u16*)&serialno[2],
- *(u16*)&serialno[4],
- *(u16*)&serialno[6]);
- break;
-
- case I2O_SNFORMAT_IEEE_REG64: /* IEEE Registered (64-bit) */
- case I2O_SNFORMAT_IEEE_REG128: /* IEEE Registered (128-bit) */
- /* FIXME: Figure if this is even close?? */
- pos += sprintf(buff+pos,
- "IEEE NodeName(hi,lo)=(%08Xh:%08Xh), PortName(hi,lo)=(%08Xh:%08Xh)\n",
- *(u32*)&serialno[2],
- *(u32*)&serialno[6],
- *(u32*)&serialno[10],
- *(u32*)&serialno[14]);
- break;
-
-
- case I2O_SNFORMAT_UNKNOWN: /* Unknown 0 */
- case I2O_SNFORMAT_UNKNOWN2: /* Unknown 0xff */
- default:
- pos += sprintf(buff+pos, "Unknown data format (0x%02x)",
- serialno[0]);
- break;
- }
-
- return pos;
-}
-
-const char * i2o_get_connector_type(int conn)


-{
- int idx = 16;

- static char *i2o_connector_type[] = {
- "OTHER",
- "UNKNOWN",
- "AUI",
- "UTP",
- "BNC",
- "RJ45",
- "STP DB9",
- "FIBER MIC",
- "APPLE AUI",
- "MII",
- "DB9",
- "HSSDC",
- "DUPLEX SC FIBER",
- "DUPLEX ST FIBER",
- "TNC/BNC",
- "HW DEFAULT"
- };
-
- switch(conn)
- {
- case 0x00000000:
- idx = 0;
- break;
- case 0x00000001:
- idx = 1;
- break;
- case 0x00000002:
- idx = 2;
- break;
- case 0x00000003:
- idx = 3;
- break;
- case 0x00000004:
- idx = 4;
- break;
- case 0x00000005:
- idx = 5;
- break;
- case 0x00000006:
- idx = 6;
- break;
- case 0x00000007:
- idx = 7;
- break;
- case 0x00000008:
- idx = 8;
- break;
- case 0x00000009:
- idx = 9;
- break;
- case 0x0000000A:
- idx = 10;
- break;
- case 0x0000000B:
- idx = 11;
- break;
- case 0x0000000C:
- idx = 12;
- break;
- case 0x0000000D:
- idx = 13;
- break;
- case 0x0000000E:
- idx = 14;
- break;
- case 0xFFFFFFFF:
- idx = 15;
- break;
- }
-
- return i2o_connector_type[idx];
-}
-
-
-const char * i2o_get_connection_type(int conn)
-{
- int idx = 0;
- static char *i2o_connection_type[] = {
- "Unknown",
- "AUI",
- "10BASE5",
- "FIORL",
- "10BASE2",
- "10BROAD36",
- "10BASE-T",
- "10BASE-FP",
- "10BASE-FB",
- "10BASE-FL",
- "100BASE-TX",
- "100BASE-FX",
- "100BASE-T4",
- "1000BASE-SX",
- "1000BASE-LX",
- "1000BASE-CX",
- "1000BASE-T",
- "100VG-ETHERNET",
- "100VG-TOKEN RING",
- "4MBIT TOKEN RING",
- "16 Mb Token Ring",
- "125 MBAUD FDDI",
- "Point-to-point",
- "Arbitrated loop",
- "Public loop",
- "Fabric",
- "Emulation",
- "Other",
- "HW default"
- };
-
- switch(conn)
- {
- case I2O_LAN_UNKNOWN:
- idx = 0;
- break;
- case I2O_LAN_AUI:
- idx = 1;
- break;
- case I2O_LAN_10BASE5:
- idx = 2;
- break;
- case I2O_LAN_FIORL:
- idx = 3;
- break;
- case I2O_LAN_10BASE2:
- idx = 4;
- break;
- case I2O_LAN_10BROAD36:
- idx = 5;
- break;
- case I2O_LAN_10BASE_T:
- idx = 6;
- break;
- case I2O_LAN_10BASE_FP:
- idx = 7;
- break;
- case I2O_LAN_10BASE_FB:
- idx = 8;
- break;
- case I2O_LAN_10BASE_FL:
- idx = 9;
- break;
- case I2O_LAN_100BASE_TX:
- idx = 10;
- break;
- case I2O_LAN_100BASE_FX:
- idx = 11;
- break;
- case I2O_LAN_100BASE_T4:
- idx = 12;
- break;
- case I2O_LAN_1000BASE_SX:
- idx = 13;
- break;
- case I2O_LAN_1000BASE_LX:
- idx = 14;
- break;
- case I2O_LAN_1000BASE_CX:
- idx = 15;
- break;
- case I2O_LAN_1000BASE_T:
- idx = 16;
- break;
- case I2O_LAN_100VG_ETHERNET:
- idx = 17;
- break;
- case I2O_LAN_100VG_TR:
- idx = 18;
- break;
- case I2O_LAN_4MBIT:
- idx = 19;
- break;
- case I2O_LAN_16MBIT:
- idx = 20;
- break;
- case I2O_LAN_125MBAUD:
- idx = 21;
- break;
- case I2O_LAN_POINT_POINT:
- idx = 22;
- break;
- case I2O_LAN_ARB_LOOP:
- idx = 23;
- break;
- case I2O_LAN_PUBLIC_LOOP:
- idx = 24;
- break;
- case I2O_LAN_FABRIC:
- idx = 25;
- break;
- case I2O_LAN_EMULATION:
- idx = 26;
- break;
- case I2O_LAN_OTHER:
- idx = 27;
- break;
- case I2O_LAN_DEFAULT:
- idx = 28;
- break;
- }
-
- return i2o_connection_type[idx];
-}
-
-
-/* LAN group 0000h - Device info (scalar) */
-int i2o_proc_read_lan_dev_info(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[56];


- static u8 *work8 = (u8*)work32;
- static u16 *work16 = (u16*)work32;

- static u64 *work64 = (u64*)work32;
- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0000, -1, &work32, 56*4);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token, "0x0000 LAN Device Info");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "LAN Type : ");
- switch (work16[0])
- {
- case 0x0030:
- len += sprintf(buf+len, "Ethernet, ");
- break;
- case 0x0040:
- len += sprintf(buf+len, "100Base VG, ");
- break;
- case 0x0050:
- len += sprintf(buf+len, "Token Ring, ");
- break;
- case 0x0060:
- len += sprintf(buf+len, "FDDI, ");
- break;
- case 0x0070:
- len += sprintf(buf+len, "Fibre Channel, ");
- break;
- default:
- len += sprintf(buf+len, "Unknown type (0x%04x), ", work16[0]);
- break;
- }
-
- if (work16[1]&0x00000001)
- len += sprintf(buf+len, "emulated LAN, ");
- else
- len += sprintf(buf+len, "physical LAN port, ");
-
- if (work16[1]&0x00000002)
- len += sprintf(buf+len, "full duplex\n");
- else
- len += sprintf(buf+len, "simplex\n");
-
- len += sprintf(buf+len, "Address format : ");
- switch(work8[4]) {
- case 0x00:
- len += sprintf(buf+len, "IEEE 48bit\n");


- break;
- case 0x01:

- len += sprintf(buf+len, "FC IEEE\n");
- break;
- default:
- len += sprintf(buf+len, "Unknown (0x%02x)\n", work8[4]);
- break;
- }
-
- len += sprintf(buf+len, "State : ");
- switch(work8[5])
- {
- case 0x00:
- len += sprintf(buf+len, "Unknown\n");
- break;
- case 0x01:
- len += sprintf(buf+len, "Unclaimed\n");


- break;
- case 0x02:

- len += sprintf(buf+len, "Operational\n");


- break;
- case 0x03:

- len += sprintf(buf+len, "Suspended\n");
- break;
- case 0x04:
- len += sprintf(buf+len, "Resetting\n");
- break;
- case 0x05:
- len += sprintf(buf+len, "ERROR: ");
- if(work16[3]&0x0001)
- len += sprintf(buf+len, "TxCU inoperative ");
- if(work16[3]&0x0002)
- len += sprintf(buf+len, "RxCU inoperative ");
- if(work16[3]&0x0004)
- len += sprintf(buf+len, "Local mem alloc ");
- len += sprintf(buf+len, "\n");
- break;
- case 0x06:
- len += sprintf(buf+len, "Operational no Rx\n");
- break;
- case 0x07:
- len += sprintf(buf+len, "Suspended no Rx\n");
- break;
- default:
- len += sprintf(buf+len, "Unspecified\n");
- break;
- }
-
- len += sprintf(buf+len, "Min packet size : %d\n", work32[2]);
- len += sprintf(buf+len, "Max packet size : %d\n", work32[3]);
- len += sprintf(buf+len, "HW address : "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- work8[16],work8[17],work8[18],work8[19],
- work8[20],work8[21],work8[22],work8[23]);
-
- len += sprintf(buf+len, "Max Tx wire speed : %d bps\n", (int)work64[3]);
- len += sprintf(buf+len, "Max Rx wire speed : %d bps\n", (int)work64[4]);
-
- len += sprintf(buf+len, "Min SDU packet size : 0x%08x\n", work32[10]);
- len += sprintf(buf+len, "Max SDU packet size : 0x%08x\n", work32[11]);


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0001h - MAC address table (scalar) */
-int i2o_proc_read_lan_mac_addr(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[48];


- static u8 *work8 = (u8*)work32;

- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0001, -1, &work32, 48*4);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0001 LAN MAC Address");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Active address : "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- work8[0],work8[1],work8[2],work8[3],
- work8[4],work8[5],work8[6],work8[7]);
- len += sprintf(buf+len, "Current address : "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- work8[8],work8[9],work8[10],work8[11],
- work8[12],work8[13],work8[14],work8[15]);
- len += sprintf(buf+len, "Functional address mask : "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- work8[16],work8[17],work8[18],work8[19],
- work8[20],work8[21],work8[22],work8[23]);
-
- len += sprintf(buf+len,"HW/DDM capabilities : 0x%08x\n", work32[7]);
- len += sprintf(buf+len," [%s] Unicast packets supported\n",
- (work32[7]&0x00000001)?"+":"-");
- len += sprintf(buf+len," [%s] Promiscuous mode supported\n",
- (work32[7]&0x00000002)?"+":"-");
- len += sprintf(buf+len," [%s] Promiscuous multicast mode supported\n",
- (work32[7]&0x00000004)?"+":"-");
- len += sprintf(buf+len," [%s] Broadcast reception disabling supported\n",
- (work32[7]&0x00000100)?"+":"-");
- len += sprintf(buf+len," [%s] Multicast reception disabling supported\n",
- (work32[7]&0x00000200)?"+":"-");
- len += sprintf(buf+len," [%s] Functional address disabling supported\n",
- (work32[7]&0x00000400)?"+":"-");
- len += sprintf(buf+len," [%s] MAC reporting supported\n",
- (work32[7]&0x00000800)?"+":"-");
-
- len += sprintf(buf+len,"Filter mask : 0x%08x\n", work32[6]);
- len += sprintf(buf+len," [%s] Unicast packets disable\n",
- (work32[6]&0x00000001)?"+":"-");
- len += sprintf(buf+len," [%s] Promiscuous mode enable\n",
- (work32[6]&0x00000002)?"+":"-");
- len += sprintf(buf+len," [%s] Promiscuous multicast mode enable\n",
- (work32[6]&0x00000004)?"+":"-");
- len += sprintf(buf+len," [%s] Broadcast packets disable\n",
- (work32[6]&0x00000100)?"+":"-");
- len += sprintf(buf+len," [%s] Multicast packets disable\n",
- (work32[6]&0x00000200)?"+":"-");
- len += sprintf(buf+len," [%s] Functional address disable\n",
- (work32[6]&0x00000400)?"+":"-");
-
- if (work32[7]&0x00000800) {
- len += sprintf(buf+len, " MAC reporting mode : ");
- if (work32[6]&0x00000800)
- len += sprintf(buf+len, "Pass only priority MAC packets to user\n");
- else if (work32[6]&0x00001000)
- len += sprintf(buf+len, "Pass all MAC packets to user\n");
- else if (work32[6]&0x00001800)
- len += sprintf(buf+len, "Pass all MAC packets (promiscuous) to user\n");
- else
- len += sprintf(buf+len, "Do not pass MAC packets to user\n");
- }
- len += sprintf(buf+len, "Number of multicast addresses : %d\n", work32[8]);
- len += sprintf(buf+len, "Perfect filtering for max %d multicast addresses\n",
- work32[9]);
- len += sprintf(buf+len, "Imperfect filtering for max %d multicast addresses\n",
- work32[10]);


-
- spin_unlock(&i2o_proc_lock);
-
- return len;
-}
-

-/* LAN group 0002h - Multicast MAC address table (table) */
-int i2o_proc_read_lan_mcast_addr(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
- u8 mc_addr[8];
-
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u8 mc_addr[256][8];
- } result;

-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid, 0x0002, -1,
- NULL, 0, &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x002 LAN Multicast MAC Address");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- for (i = 0; i < result.row_count; i++)
- {
- memcpy(mc_addr, result.mc_addr[i], 8);
-
- len += sprintf(buf+len, "MC MAC address[%d]: "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- i, mc_addr[0], mc_addr[1], mc_addr[2],
- mc_addr[3], mc_addr[4], mc_addr[5],
- mc_addr[6], mc_addr[7]);
- }
-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-
-/* LAN group 0003h - Batch Control (scalar) */
-int i2o_proc_read_lan_batch_control(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[9];
- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0003, -1, &work32, 9*4);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0003 LAN Batch Control");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Batch mode ");
- if (work32[0]&0x00000001)
- len += sprintf(buf+len, "disabled");
- else
- len += sprintf(buf+len, "enabled");
- if (work32[0]&0x00000002)
- len += sprintf(buf+len, " (current setting)");
- if (work32[0]&0x00000004)
- len += sprintf(buf+len, ", forced");
- else
- len += sprintf(buf+len, ", toggle");


- len += sprintf(buf+len, "\n");
-

- len += sprintf(buf+len, "Max Rx batch count : %d\n", work32[5]);
- len += sprintf(buf+len, "Max Rx batch delay : %d\n", work32[6]);
- len += sprintf(buf+len, "Max Tx batch delay : %d\n", work32[7]);
- len += sprintf(buf+len, "Max Tx batch count : %d\n", work32[8]);


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0004h - LAN Operation (scalar) */
-int i2o_proc_read_lan_operation(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;


- static u32 work32[5];

- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0004, -1, &work32, 20);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0004 LAN Operation");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Packet prepadding (32b words) : %d\n", work32[0]);
- len += sprintf(buf+len, "Transmission error reporting : %s\n",
- (work32[1]&1)?"on":"off");
- len += sprintf(buf+len, "Bad packet handling : %s\n",
- (work32[1]&0x2)?"by host":"by DDM");
- len += sprintf(buf+len, "Packet orphan limit : %d\n", work32[2]);
-
- len += sprintf(buf+len, "Tx modes : 0x%08x\n", work32[3]);
- len += sprintf(buf+len, " [%s] HW CRC suppression\n",
- (work32[3]&0x00000004) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW IPv4 checksum\n",
- (work32[3]&0x00000100) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW TCP checksum\n",
- (work32[3]&0x00000200) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW UDP checksum\n",
- (work32[3]&0x00000400) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW RSVP checksum\n",
- (work32[3]&0x00000800) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW ICMP checksum\n",
- (work32[3]&0x00001000) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Loopback suppression enable\n",
- (work32[3]&0x00002000) ? "+" : "-");
-
- len += sprintf(buf+len, "Rx modes : 0x%08x\n", work32[4]);
- len += sprintf(buf+len, " [%s] FCS in payload\n",
- (work32[4]&0x00000004) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW IPv4 checksum validation\n",
- (work32[4]&0x00000100) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW TCP checksum validation\n",
- (work32[4]&0x00000200) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW UDP checksum validation\n",
- (work32[4]&0x00000400) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW RSVP checksum validation\n",
- (work32[4]&0x00000800) ? "+" : "-");
- len += sprintf(buf+len, " [%s] HW ICMP checksum validation\n",
- (work32[4]&0x00001000) ? "+" : "-");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0005h - Media operation (scalar) */
-int i2o_proc_read_lan_media_operation(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {
- u32 connector_type;
- u32 connection_type;
- u64 current_tx_wire_speed;
- u64 current_rx_wire_speed;
- u8 duplex_mode;
- u8 link_status;
- u8 reserved;
- u8 duplex_mode_target;
- u32 connector_type_target;
- u32 connection_type_target;
- } result;

-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0005, -1, &result, sizeof(result));
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token, "0x0005 LAN Media Operation");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Connector type : %s\n",
- i2o_get_connector_type(result.connector_type));
- len += sprintf(buf+len, "Connection type : %s\n",
- i2o_get_connection_type(result.connection_type));
-
- len += sprintf(buf+len, "Current Tx wire speed : %d bps\n", (int)result.current_tx_wire_speed);
- len += sprintf(buf+len, "Current Rx wire speed : %d bps\n", (int)result.current_rx_wire_speed);
- len += sprintf(buf+len, "Duplex mode : %s duplex\n",
- (result.duplex_mode)?"Full":"Half");
-
- len += sprintf(buf+len, "Link status : ");
- switch (result.link_status)
- {
- case 0x00:
- len += sprintf(buf+len, "Unknown\n");
- break;
- case 0x01:
- len += sprintf(buf+len, "Normal\n");


- break;
- case 0x02:

- len += sprintf(buf+len, "Failure\n");


- break;
- case 0x03:

- len += sprintf(buf+len, "Reset\n");
- break;
- default:
- len += sprintf(buf+len, "Unspecified\n");
- }
-
- len += sprintf(buf+len, "Duplex mode target : ");
- switch (result.duplex_mode_target){
- case 0:
- len += sprintf(buf+len, "Half duplex\n");


- break;
- case 1:

- len += sprintf(buf+len, "Full duplex\n");


- break;
- default:
- len += sprintf(buf+len, "\n");
- }
-

- len += sprintf(buf+len, "Connector type target : %s\n",
- i2o_get_connector_type(result.connector_type_target));
- len += sprintf(buf+len, "Connection type target : %s\n",
- i2o_get_connection_type(result.connection_type_target));


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0006h - Alternate address (table) (optional) */
-int i2o_proc_read_lan_alt_addr(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
- int i;
- u8 alt_addr[8];
- struct
- {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u8 alt_addr[256][8];
- } result;

-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_table(I2O_PARAMS_TABLE_GET,
- d->controller, d->lct_data.tid,
- 0x0006, -1, NULL, 0, &result, sizeof(result));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token, "0x0006 LAN Alternate Address (optional)");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- for (i=0; i < result.row_count; i++)
- {
- memcpy(alt_addr,result.alt_addr[i],8);
- len += sprintf(buf+len, "Alternate address[%d]: "
- "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- i, alt_addr[0], alt_addr[1], alt_addr[2],
- alt_addr[3], alt_addr[4], alt_addr[5],
- alt_addr[6], alt_addr[7]);
- }
-
- spin_unlock(&i2o_proc_lock);


- return len;
-}
-
-

-/* LAN group 0007h - Transmit info (scalar) */
-int i2o_proc_read_lan_tx_info(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[8];
- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0007, -1, &work32, 8*4);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0007 LAN Transmit Info");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "Tx Max SG elements per packet : %d\n", work32[0]);
- len += sprintf(buf+len, "Tx Max SG elements per chain : %d\n", work32[1]);
- len += sprintf(buf+len, "Tx Max outstanding packets : %d\n", work32[2]);
- len += sprintf(buf+len, "Tx Max packets per request : %d\n", work32[3]);
-
- len += sprintf(buf+len, "Tx modes : 0x%08x\n", work32[4]);
- len += sprintf(buf+len, " [%s] No DA in SGL\n",
- (work32[4]&0x00000002) ? "+" : "-");
- len += sprintf(buf+len, " [%s] CRC suppression\n",
- (work32[4]&0x00000004) ? "+" : "-");
- len += sprintf(buf+len, " [%s] MAC insertion\n",
- (work32[4]&0x00000010) ? "+" : "-");
- len += sprintf(buf+len, " [%s] RIF insertion\n",
- (work32[4]&0x00000020) ? "+" : "-");
- len += sprintf(buf+len, " [%s] IPv4 checksum generation\n",
- (work32[4]&0x00000100) ? "+" : "-");
- len += sprintf(buf+len, " [%s] TCP checksum generation\n",
- (work32[4]&0x00000200) ? "+" : "-");
- len += sprintf(buf+len, " [%s] UDP checksum generation\n",
- (work32[4]&0x00000400) ? "+" : "-");
- len += sprintf(buf+len, " [%s] RSVP checksum generation\n",
- (work32[4]&0x00000800) ? "+" : "-");
- len += sprintf(buf+len, " [%s] ICMP checksum generation\n",
- (work32[4]&0x00001000) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Loopback enabled\n",
- (work32[4]&0x00010000) ? "+" : "-");
- len += sprintf(buf+len, " [%s] Loopback suppression enabled\n",
- (work32[4]&0x00020000) ? "+" : "-");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0008h - Receive info (scalar) */
-int i2o_proc_read_lan_rx_info(char *buf, char **start, off_t offset, int len,

- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- static u32 work32[8];
- int token;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0008, -1, &work32, 8*4);
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x0008 LAN Receive Info");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf ,"Rx Max size of chain element : %d\n", work32[0]);
- len += sprintf(buf+len, "Rx Max Buckets : %d\n", work32[1]);
- len += sprintf(buf+len, "Rx Max Buckets in Reply : %d\n", work32[3]);
- len += sprintf(buf+len, "Rx Max Packets in Bucket : %d\n", work32[4]);
- len += sprintf(buf+len, "Rx Max Buckets in Post : %d\n", work32[5]);
-
- len += sprintf(buf+len, "Rx Modes : 0x%08x\n", work32[2]);
- len += sprintf(buf+len, " [%s] FCS reception\n",
- (work32[2]&0x00000004) ? "+" : "-");
- len += sprintf(buf+len, " [%s] IPv4 checksum validation \n",
- (work32[2]&0x00000100) ? "+" : "-");
- len += sprintf(buf+len, " [%s] TCP checksum validation \n",
- (work32[2]&0x00000200) ? "+" : "-");
- len += sprintf(buf+len, " [%s] UDP checksum validation \n",
- (work32[2]&0x00000400) ? "+" : "-");
- len += sprintf(buf+len, " [%s] RSVP checksum validation \n",
- (work32[2]&0x00000800) ? "+" : "-");
- len += sprintf(buf+len, " [%s] ICMP checksum validation \n",
- (work32[2]&0x00001000) ? "+" : "-");


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-static int i2o_report_opt_field(char *buf, char *field_name,
- int field_nbr, int supp_fields, u64 *value)
-{
- if (supp_fields & (1 << field_nbr))
- return sprintf(buf, "%-24s : " FMT_U64_HEX "\n", field_name, U64_VAL(value));
- else
- return sprintf(buf, "%-24s : Not supported\n", field_name);
-}
-
-/* LAN group 0100h - LAN Historical statistics (scalar) */
-/* LAN group 0180h - Supported Optional Historical Statistics (scalar) */
-/* LAN group 0182h - Optional Non Media Specific Transmit Historical Statistics (scalar) */
-/* LAN group 0183h - Optional Non Media Specific Receive Historical Statistics (scalar) */
-
-int i2o_proc_read_lan_hist_stats(char *buf, char **start, off_t offset, int len,


- int *eof, void *data)
-{

- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {
- u64 tx_packets;
- u64 tx_bytes;
- u64 rx_packets;
- u64 rx_bytes;
- u64 tx_errors;
- u64 rx_errors;
- u64 rx_dropped;
- u64 adapter_resets;
- u64 adapter_suspends;
- } stats; // 0x0100
-
- static u64 supp_groups[4]; // 0x0180
-
- struct
- {
- u64 tx_retries;
- u64 tx_directed_bytes;
- u64 tx_directed_packets;
- u64 tx_multicast_bytes;
- u64 tx_multicast_packets;
- u64 tx_broadcast_bytes;
- u64 tx_broadcast_packets;
- u64 tx_group_addr_packets;
- u64 tx_short_packets;
- } tx_stats; // 0x0182
-
- struct
- {
- u64 rx_crc_errors;
- u64 rx_directed_bytes;
- u64 rx_directed_packets;
- u64 rx_multicast_bytes;
- u64 rx_multicast_packets;
- u64 rx_broadcast_bytes;
- u64 rx_broadcast_packets;
- u64 rx_group_addr_packets;
- u64 rx_short_packets;
- u64 rx_long_packets;
- u64 rx_runt_packets;
- } rx_stats; // 0x0183
-
- struct
- {
- u64 ipv4_generate;
- u64 ipv4_validate_success;
- u64 ipv4_validate_errors;
- u64 tcp_generate;
- u64 tcp_validate_success;
- u64 tcp_validate_errors;
- u64 udp_generate;
- u64 udp_validate_success;
- u64 udp_validate_errors;
- u64 rsvp_generate;
- u64 rsvp_validate_success;
- u64 rsvp_validate_errors;
- u64 icmp_generate;
- u64 icmp_validate_success;
- u64 icmp_validate_errors;
- } chksum_stats; // 0x0184


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-

- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0100, -1, &stats, sizeof(stats));
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x100 LAN Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Tx packets : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_packets));
- len += sprintf(buf+len, "Tx bytes : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_bytes));
- len += sprintf(buf+len, "Rx packets : " FMT_U64_HEX "\n",
- U64_VAL(&stats.rx_packets));
- len += sprintf(buf+len, "Rx bytes : " FMT_U64_HEX "\n",
- U64_VAL(&stats.rx_bytes));
- len += sprintf(buf+len, "Tx errors : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_errors));
- len += sprintf(buf+len, "Rx errors : " FMT_U64_HEX "\n",
- U64_VAL(&stats.rx_errors));
- len += sprintf(buf+len, "Rx dropped : " FMT_U64_HEX "\n",
- U64_VAL(&stats.rx_dropped));
- len += sprintf(buf+len, "Adapter resets : " FMT_U64_HEX "\n",
- U64_VAL(&stats.adapter_resets));
- len += sprintf(buf+len, "Adapter suspends : " FMT_U64_HEX "\n",
- U64_VAL(&stats.adapter_suspends));
-
- /* Optional statistics follows */
- /* Get 0x0180 to see which optional groups/fields are supported */
-
- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0180, -1, &supp_groups, sizeof(supp_groups));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token, "0x180 LAN Supported Optional Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- if (supp_groups[1]) /* 0x0182 */
- {
- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0182, -1, &tx_stats, sizeof(tx_stats));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x182 LAN Optional Tx Historical Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "==== Optional TX statistics (group 0182h)\n");
-
- len += i2o_report_opt_field(buf+len, "Tx RetryCount",
- 0, supp_groups[1], &tx_stats.tx_retries);
- len += i2o_report_opt_field(buf+len, "Tx DirectedBytes",
- 1, supp_groups[1], &tx_stats.tx_directed_bytes);
- len += i2o_report_opt_field(buf+len, "Tx DirectedPackets",
- 2, supp_groups[1], &tx_stats.tx_directed_packets);
- len += i2o_report_opt_field(buf+len, "Tx MulticastBytes",
- 3, supp_groups[1], &tx_stats.tx_multicast_bytes);
- len += i2o_report_opt_field(buf+len, "Tx MulticastPackets",
- 4, supp_groups[1], &tx_stats.tx_multicast_packets);
- len += i2o_report_opt_field(buf+len, "Tx BroadcastBytes",
- 5, supp_groups[1], &tx_stats.tx_broadcast_bytes);
- len += i2o_report_opt_field(buf+len, "Tx BroadcastPackets",
- 6, supp_groups[1], &tx_stats.tx_broadcast_packets);
- len += i2o_report_opt_field(buf+len, "Tx TotalGroupAddrPackets",
- 7, supp_groups[1], &tx_stats.tx_group_addr_packets);
- len += i2o_report_opt_field(buf+len, "Tx TotalPacketsTooShort",
- 8, supp_groups[1], &tx_stats.tx_short_packets);
- }
-
- if (supp_groups[2]) /* 0x0183 */
- {
- token = i2o_query_scalar(d->controller, d->lct_data.tid,
- 0x0183, -1, &rx_stats, sizeof(rx_stats));
- if (token < 0) {
- len += i2o_report_query_status(buf+len, token,"0x183 LAN Optional Rx Historical Stats");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "==== Optional RX statistics (group 0183h)\n");
-
- len += i2o_report_opt_field(buf+len, "Rx CRCErrorCount",
- 0, supp_groups[2], &rx_stats.rx_crc_errors);
- len += i2o_report_opt_field(buf+len, "Rx DirectedBytes",
- 1, supp_groups[2], &rx_stats.rx_directed_bytes);
- len += i2o_report_opt_field(buf+len, "Rx DirectedPackets",
- 2, supp_groups[2], &rx_stats.rx_directed_packets);
- len += i2o_report_opt_field(buf+len, "Rx MulticastBytes",
- 3, supp_groups[2], &rx_stats.rx_multicast_bytes);
- len += i2o_report_opt_field(buf+len, "Rx MulticastPackets",
- 4, supp_groups[2], &rx_stats.rx_multicast_packets);
- len += i2o_report_opt_field(buf+len, "Rx BroadcastBytes",
- 5, supp_groups[2], &rx_stats.rx_broadcast_bytes);
- len += i2o_report_opt_field(buf+len, "Rx BroadcastPackets",
- 6, supp_groups[2], &rx_stats.rx_broadcast_packets);
- len += i2o_report_opt_field(buf+len, "Rx TotalGroupAddrPackets",


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 20'
echo 'File patch-2.4.13 is continued in part 21'
echo "21" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:51 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part21

#!/bin/sh -x
# this is part 21 of a 53 - part archive


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

if test "$Scheck" != 21; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- 7, supp_groups[2], &rx_stats.rx_group_addr_packets);
- len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooShort",
- 8, supp_groups[2], &rx_stats.rx_short_packets);
- len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooLong",
- 9, supp_groups[2], &rx_stats.rx_long_packets);
- len += i2o_report_opt_field(buf+len, "Rx TotalPacketsRunt",
- 10, supp_groups[2], &rx_stats.rx_runt_packets);
- }
-
- if (supp_groups[3]) /* 0x0184 */


- {
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0184, -1, &chksum_stats, sizeof(chksum_stats));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x184 LAN Optional Chksum Historical Stats");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "==== Optional CHKSUM statistics (group 0x0184)\n");
-
- len += i2o_report_opt_field(buf+len, "IPv4 Generate",
- 0, supp_groups[3], &chksum_stats.ipv4_generate);
- len += i2o_report_opt_field(buf+len, "IPv4 ValidateSuccess",
- 1, supp_groups[3], &chksum_stats.ipv4_validate_success);
- len += i2o_report_opt_field(buf+len, "IPv4 ValidateError",
- 2, supp_groups[3], &chksum_stats.ipv4_validate_errors);
- len += i2o_report_opt_field(buf+len, "TCP Generate",
- 3, supp_groups[3], &chksum_stats.tcp_generate);
- len += i2o_report_opt_field(buf+len, "TCP ValidateSuccess",
- 4, supp_groups[3], &chksum_stats.tcp_validate_success);
- len += i2o_report_opt_field(buf+len, "TCP ValidateError",
- 5, supp_groups[3], &chksum_stats.tcp_validate_errors);
- len += i2o_report_opt_field(buf+len, "UDP Generate",
- 6, supp_groups[3], &chksum_stats.udp_generate);
- len += i2o_report_opt_field(buf+len, "UDP ValidateSuccess",
- 7, supp_groups[3], &chksum_stats.udp_validate_success);
- len += i2o_report_opt_field(buf+len, "UDP ValidateError",
- 8, supp_groups[3], &chksum_stats.udp_validate_errors);
- len += i2o_report_opt_field(buf+len, "RSVP Generate",
- 9, supp_groups[3], &chksum_stats.rsvp_generate);
- len += i2o_report_opt_field(buf+len, "RSVP ValidateSuccess",
- 10, supp_groups[3], &chksum_stats.rsvp_validate_success);
- len += i2o_report_opt_field(buf+len, "RSVP ValidateError",
- 11, supp_groups[3], &chksum_stats.rsvp_validate_errors);
- len += i2o_report_opt_field(buf+len, "ICMP Generate",
- 12, supp_groups[3], &chksum_stats.icmp_generate);
- len += i2o_report_opt_field(buf+len, "ICMP ValidateSuccess",
- 13, supp_groups[3], &chksum_stats.icmp_validate_success);
- len += i2o_report_opt_field(buf+len, "ICMP ValidateError",
- 14, supp_groups[3], &chksum_stats.icmp_validate_errors);


- }
-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0200h - Required Ethernet Statistics (scalar) */
-/* LAN group 0280h - Optional Ethernet Statistics Supported (scalar) */
-/* LAN group 0281h - Optional Ethernet Historical Statistics (scalar) */
-int i2o_proc_read_lan_eth_stats(char *buf, char **start, off_t offset,


- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;
- int token;
-
- struct
- {

- u64 rx_align_errors;
- u64 tx_one_collisions;
- u64 tx_multiple_collisions;
- u64 tx_deferred;
- u64 tx_late_collisions;
- u64 tx_max_collisions;
- u64 tx_carrier_lost;
- u64 tx_excessive_deferrals;
- } stats;
-
- static u64 supp_fields;
- struct
- {
- u64 rx_overrun;
- u64 tx_underrun;
- u64 tx_heartbeat_failure;
- } hist_stats;


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0200, -1, &stats, sizeof(stats));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0200 LAN Ethernet Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "Rx alignment errors : " FMT_U64_HEX "\n",
- U64_VAL(&stats.rx_align_errors));
- len += sprintf(buf+len, "Tx one collisions : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_one_collisions));
- len += sprintf(buf+len, "Tx multicollisions : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_multiple_collisions));
- len += sprintf(buf+len, "Tx deferred : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_deferred));
- len += sprintf(buf+len, "Tx late collisions : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_late_collisions));
- len += sprintf(buf+len, "Tx max collisions : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_max_collisions));
- len += sprintf(buf+len, "Tx carrier lost : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_carrier_lost));
- len += sprintf(buf+len, "Tx excessive deferrals : " FMT_U64_HEX "\n",
- U64_VAL(&stats.tx_excessive_deferrals));
-
- /* Optional Ethernet statistics follows */
- /* Get 0x0280 to see which optional fields are supported */


-
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0280, -1, &supp_fields, sizeof(supp_fields));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0280 LAN Supported Optional Ethernet Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- if (supp_fields) /* 0x0281 */


- {
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0281, -1, &stats, sizeof(stats));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0281 LAN Optional Ethernet Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "==== Optional ETHERNET statistics (group 0x0281)\n");
-
- len += i2o_report_opt_field(buf+len, "Rx Overrun",
- 0, supp_fields, &hist_stats.rx_overrun);
- len += i2o_report_opt_field(buf+len, "Tx Underrun",
- 1, supp_fields, &hist_stats.tx_underrun);
- len += i2o_report_opt_field(buf+len, "Tx HeartbeatFailure",
- 2, supp_fields, &hist_stats.tx_heartbeat_failure);


- }
-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0300h - Required Token Ring Statistics (scalar) */
-/* LAN group 0380h, 0381h - Optional Statistics not yet defined (TODO) */
-int i2o_proc_read_lan_tr_stats(char *buf, char **start, off_t offset,


- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;

- static u64 work64[13];
- int token;
-
- static char *ring_status[] =
- {


- "",
- "",
- "",

- "",
- "",
- "Ring Recovery",
- "Single Station",
- "Counter Overflow",
- "Remove Received",
- "",
- "Auto-Removal Error 1",
- "Lobe Wire Fault",
- "Transmit Beacon",
- "Soft Error",
- "Hard Error",
- "Signal Loss"
- };


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0300, -1, &work64, sizeof(work64));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0300 Token Ring Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf, "LineErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[0]));
- len += sprintf(buf+len, "LostFrames : " FMT_U64_HEX "\n",
- U64_VAL(&work64[1]));
- len += sprintf(buf+len, "ACError : " FMT_U64_HEX "\n",
- U64_VAL(&work64[2]));
- len += sprintf(buf+len, "TxAbortDelimiter : " FMT_U64_HEX "\n",
- U64_VAL(&work64[3]));
- len += sprintf(buf+len, "BursErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[4]));
- len += sprintf(buf+len, "FrameCopiedErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[5]));
- len += sprintf(buf+len, "FrequencyErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[6]));
- len += sprintf(buf+len, "InternalErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[7]));
- len += sprintf(buf+len, "LastRingStatus : %s\n", ring_status[work64[8]]);
- len += sprintf(buf+len, "TokenError : " FMT_U64_HEX "\n",
- U64_VAL(&work64[9]));
- len += sprintf(buf+len, "UpstreamNodeAddress : " FMT_U64_HEX "\n",
- U64_VAL(&work64[10]));
- len += sprintf(buf+len, "LastRingID : " FMT_U64_HEX "\n",
- U64_VAL(&work64[11]));
- len += sprintf(buf+len, "LastBeaconType : " FMT_U64_HEX "\n",
- U64_VAL(&work64[12]));


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-/* LAN group 0400h - Required FDDI Statistics (scalar) */
-/* LAN group 0480h, 0481h - Optional Statistics, not yet defined (TODO) */
-int i2o_proc_read_lan_fddi_stats(char *buf, char **start, off_t offset,


- int len, int *eof, void *data)
-{
- struct i2o_device *d = (struct i2o_device*)data;

- static u64 work64[11];
- int token;
-
- static char *conf_state[] =
- {
- "Isolated",
- "Local a",
- "Local b",
- "Local ab",
- "Local s",
- "Wrap a",
- "Wrap b",
- "Wrap ab",
- "Wrap s",
- "C-Wrap a",
- "C-Wrap b",
- "C-Wrap s",
- "Through",
- };
-
- static char *ring_state[] =
- {
- "Isolated",
- "Non-op",
- "Rind-op",
- "Detect",
- "Non-op-Dup",
- "Ring-op-Dup",
- "Directed",
- "Trace"
- };
-
- static char *link_state[] =
- {
- "Off",
- "Break",
- "Trace",
- "Connect",
- "Next",
- "Signal",
- "Join",
- "Verify",
- "Active",
- "Maintenance"
- };


-
- spin_lock(&i2o_proc_lock);
- len = 0;
-
- token = i2o_query_scalar(d->controller, d->lct_data.tid,

- 0x0400, -1, &work64, sizeof(work64));


-
- if (token < 0) {

- len += i2o_report_query_status(buf+len, token,"0x0400 FDDI Required Statistics");


- spin_unlock(&i2o_proc_lock);
- return len;
- }
-

- len += sprintf(buf+len, "ConfigurationState : %s\n", conf_state[work64[0]]);
- len += sprintf(buf+len, "UpstreamNode : " FMT_U64_HEX "\n",
- U64_VAL(&work64[1]));
- len += sprintf(buf+len, "DownStreamNode : " FMT_U64_HEX "\n",
- U64_VAL(&work64[2]));
- len += sprintf(buf+len, "FrameErrors : " FMT_U64_HEX "\n",
- U64_VAL(&work64[3]));
- len += sprintf(buf+len, "FramesLost : " FMT_U64_HEX "\n",
- U64_VAL(&work64[4]));
- len += sprintf(buf+len, "RingMgmtState : %s\n", ring_state[work64[5]]);
- len += sprintf(buf+len, "LCTFailures : " FMT_U64_HEX "\n",
- U64_VAL(&work64[6]));
- len += sprintf(buf+len, "LEMRejects : " FMT_U64_HEX "\n",
- U64_VAL(&work64[7]));
- len += sprintf(buf+len, "LEMCount : " FMT_U64_HEX "\n",
- U64_VAL(&work64[8]));
- len += sprintf(buf+len, "LConnectionState : %s\n",
- link_state[work64[9]]);


-
- spin_unlock(&i2o_proc_lock);
- return len;
-}
-

-static int i2o_proc_create_entries(void *data, i2o_proc_entry *pentry,
- struct proc_dir_entry *parent)
-{
- struct proc_dir_entry *ent;
-
- while(pentry->name != NULL)
- {
- ent = create_proc_entry(pentry->name, pentry->mode, parent);
- if(!ent) return -1;
-
- ent->data = data;
- ent->read_proc = pentry->read_proc;
- ent->write_proc = pentry->write_proc;
- ent->nlink = 1;
-
- pentry++;
- }
-


- return 0;
-}
-

-static void i2o_proc_remove_entries(i2o_proc_entry *pentry,
- struct proc_dir_entry *parent)
-{
- while(pentry->name != NULL)
- {
- remove_proc_entry(pentry->name, parent);
- pentry++;
- }
-}
-
-static int i2o_proc_add_controller(struct i2o_controller *pctrl,
- struct proc_dir_entry *root )
-{
- struct proc_dir_entry *dir, *dir1;
- struct i2o_device *dev;
- char buff[10];
-
- sprintf(buff, "iop%d", pctrl->unit);
-
- dir = proc_mkdir(buff, root);
- if(!dir)
- return -1;
-
- pctrl->proc_entry = dir;
-
- i2o_proc_create_entries(pctrl, generic_iop_entries, dir);
-
- for(dev = pctrl->devices; dev; dev = dev->next)
- {
- sprintf(buff, "%0#5x", dev->lct_data.tid);
-
- dir1 = proc_mkdir(buff, dir);
- dev->proc_entry = dir1;
-
- if(!dir1)
- printk(KERN_INFO "i2o_proc: Could not allocate proc dir\n");
-
- i2o_proc_add_device(dev, dir1);
- }
-


- return 0;
-}
-

-void i2o_proc_new_dev(struct i2o_controller *c, struct i2o_device *d)
-{
- char buff[10];
-
-#ifdef DRIVERDEBUG
- printk(KERN_INFO "Adding new device to /proc/i2o/iop%d\n", c->unit);
-#endif
- sprintf(buff, "%0#5x", d->lct_data.tid);
-
- d->proc_entry = proc_mkdir(buff, c->proc_entry);
-
- if(!d->proc_entry)
- {
- printk(KERN_WARNING "i2o: Could not allocate procdir!\n");
- return;
- }
-
- i2o_proc_add_device(d, d->proc_entry);
-}
-
-void i2o_proc_add_device(struct i2o_device *dev, struct proc_dir_entry *dir)
-{
- i2o_proc_create_entries(dev, generic_dev_entries, dir);
-
- /* Inform core that we want updates about this device's status */
- i2o_device_notify_on(dev, &i2o_proc_handler);
- switch(dev->lct_data.class_id)
- {
- case I2O_CLASS_SCSI_PERIPHERAL:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- i2o_proc_create_entries(dev, rbs_dev_entries, dir);
- break;
- case I2O_CLASS_LAN:
- i2o_proc_create_entries(dev, lan_entries, dir);
- switch(dev->lct_data.sub_class)
- {
- case I2O_LAN_ETHERNET:
- i2o_proc_create_entries(dev, lan_eth_entries, dir);
- break;
- case I2O_LAN_FDDI:
- i2o_proc_create_entries(dev, lan_fddi_entries, dir);
- break;
- case I2O_LAN_TR:
- i2o_proc_create_entries(dev, lan_tr_entries, dir);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static void i2o_proc_remove_controller(struct i2o_controller *pctrl,
- struct proc_dir_entry *parent)
-{
- char buff[10];
- struct i2o_device *dev;
-
- /* Remove unused device entries */
- for(dev=pctrl->devices; dev; dev=dev->next)
- i2o_proc_remove_device(dev);
-
- if(!atomic_read(&pctrl->proc_entry->count))
- {
- sprintf(buff, "iop%d", pctrl->unit);
-
- i2o_proc_remove_entries(generic_iop_entries, pctrl->proc_entry);
-
- remove_proc_entry(buff, parent);
- pctrl->proc_entry = NULL;
- }
-}
-
-void i2o_proc_remove_device(struct i2o_device *dev)
-{
- struct proc_dir_entry *de=dev->proc_entry;
- char dev_id[10];
-
- sprintf(dev_id, "%0#5x", dev->lct_data.tid);
-
- i2o_device_notify_off(dev, &i2o_proc_handler);
- /* Would it be safe to remove _files_ even if they are in use? */
- if((de) && (!atomic_read(&de->count)))
- {
- i2o_proc_remove_entries(generic_dev_entries, de);
- switch(dev->lct_data.class_id)
- {
- case I2O_CLASS_SCSI_PERIPHERAL:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- i2o_proc_remove_entries(rbs_dev_entries, de);
- break;
- case I2O_CLASS_LAN:
- {
- i2o_proc_remove_entries(lan_entries, de);
- switch(dev->lct_data.sub_class)
- {
- case I2O_LAN_ETHERNET:
- i2o_proc_remove_entries(lan_eth_entries, de);
- break;
- case I2O_LAN_FDDI:
- i2o_proc_remove_entries(lan_fddi_entries, de);
- break;
- case I2O_LAN_TR:
- i2o_proc_remove_entries(lan_tr_entries, de);
- break;
- }
- }
- remove_proc_entry(dev_id, dev->controller->proc_entry);
- }
- }
-}
-
-void i2o_proc_dev_del(struct i2o_controller *c, struct i2o_device *d)
-{
-#ifdef DRIVERDEBUG
- printk(KERN_INFO, "Deleting device %d from iop%d\n",
- d->lct_data.tid, c->unit);
-#endif
-
- i2o_proc_remove_device(d);
-}
-
-static int create_i2o_procfs(void)
-{
- struct i2o_controller *pctrl = NULL;
- int i;
-
- i2o_proc_dir_root = proc_mkdir("i2o", 0);
- if(!i2o_proc_dir_root)
- return -1;
-
- for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
- {
- pctrl = i2o_find_controller(i);
- if(pctrl)
- {
- i2o_proc_add_controller(pctrl, i2o_proc_dir_root);
- i2o_unlock_controller(pctrl);
- }
- };
-


- return 0;
-}
-

-static int __exit destroy_i2o_procfs(void)
-{
- struct i2o_controller *pctrl = NULL;
- int i;
-
- for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
- {
- pctrl = i2o_find_controller(i);
- if(pctrl)
- {
- i2o_proc_remove_controller(pctrl, i2o_proc_dir_root);
- i2o_unlock_controller(pctrl);
- }
- }
-
- if(!atomic_read(&i2o_proc_dir_root->count))
- remove_proc_entry("i2o", 0);
- else
- return -1;
-


- return 0;
-}
-

-int __init i2o_proc_init(void)
-{
- if (i2o_install_handler(&i2o_proc_handler) < 0)
- {
- printk(KERN_ERR "i2o_proc: Unable to install PROC handler.\n");


- return 0;
- }
-

- if(create_i2o_procfs())
- return -EBUSY;
-


- return 0;
-}
-

-MODULE_AUTHOR("Deepak Saxena");
-MODULE_DESCRIPTION("I2O procfs Handler");
-
-static void __exit i2o_proc_exit(void)
-{
- destroy_i2o_procfs();
- i2o_remove_handler(&i2o_proc_handler);
-}
-
-#ifdef MODULE
-module_init(i2o_proc_init);
-#endif
-module_exit(i2o_proc_exit);
-
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_scsi.c linux/drivers/i2o/i2o_scsi.c
--- v2.4.12/linux/drivers/i2o/i2o_scsi.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2o/i2o_scsi.c Wed Dec 31 16:00:00 1969
@@ -1,912 +0,0 @@
-/*
- * 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.
- *
- * Complications for I2O scsi
- *
- * o Each (bus,lun) is a logical device in I2O. We keep a map
- * table. We spoof failed selection for unmapped units
- * o Request sense buffers can come back for free.
- * o Scatter gather is a bit dynamic. We have to investigate at
- * setup time.
- * o Some of our resources are dynamically shared. The i2o core
- * needs a message reservation protocol to avoid swap v net
- * deadlocking. We need to back off queue requests.
- *
- * In general the firmware wants to help. Where its help isn't performance
- * useful we just ignore the aid. Its not worth the code in truth.
- *
- * Fixes:
- * Steve Ralston : Scatter gather now works
- *
- * To Do
- * 64bit cleanups
- * Fix the resource management problems.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <linux/blk.h>
-#include <linux/version.h>
-#include <linux/i2o.h>
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
-#include "i2o_scsi.h"
-
-#define VERSION_STRING "Version 0.0.1"
-
-#define dprintk(x)
-
-#define MAXHOSTS 32
-
-struct i2o_scsi_host


-{
- struct i2o_controller *controller;

- s16 task[16][8]; /* Allow 16 devices for now */
- unsigned long tagclock[16][8]; /* Tag clock for queueing */
- s16 bus_task; /* The adapter TID */
-};
-
-static int scsi_context;
-static int lun_done;
-static int i2o_scsi_hosts;
-
-static u32 *retry[32];
-static struct i2o_controller *retry_ctrl[32];
-static struct timer_list retry_timer;
-static int retry_ct = 0;
-
-static atomic_t queue_depth;
-
-/*
- * SG Chain buffer support...
- */
-
-#define SG_MAX_FRAGS 64
-
-/*
- * FIXME: we should allocate one of these per bus we find as we
- * locate them not in a lump at boot.
- */
-
-typedef struct _chain_buf
-{
- u32 sg_flags_cnt[SG_MAX_FRAGS];
- u32 sg_buf[SG_MAX_FRAGS];
-} chain_buf;
-
-#define SG_CHAIN_BUF_SZ sizeof(chain_buf)
-
-#define SG_MAX_BUFS (i2o_num_controllers * I2O_SCSI_CAN_QUEUE)
-#define SG_CHAIN_POOL_SZ (SG_MAX_BUFS * SG_CHAIN_BUF_SZ)
-
-static int max_sg_len = 0;
-static chain_buf *sg_chain_pool = NULL;
-static int sg_chain_tag = 0;
-static int sg_max_frags = SG_MAX_FRAGS;
-
-/*
- * Retry congested frames. This actually needs pushing down into
- * i2o core. We should only bother the OSM with this when we can't
- * queue and retry the frame. Or perhaps we should call the OSM
- * and its default handler should be this in the core, and this
- * call a 2nd "I give up" handler in the OSM ?
- */
-
-static void i2o_retry_run(unsigned long f)
-{
- int i;


- unsigned long flags;
-

- save_flags(flags);
- cli();
-
- for(i=0;i<retry_ct;i++)
- i2o_post_message(retry_ctrl[i], virt_to_bus(retry[i]));
- retry_ct=0;
-
- restore_flags(flags);
-}
-
-static void flush_pending(void)
-{
- int i;


- unsigned long flags;
-

- save_flags(flags);
- cli();
-
- for(i=0;i<retry_ct;i++)
- {
- retry[i][0]&=~0xFFFFFF;
- retry[i][0]|=I2O_CMD_UTIL_NOP<<24;
- i2o_post_message(retry_ctrl[i],virt_to_bus(retry[i]));
- }
- retry_ct=0;
-
- restore_flags(flags);
-}
-
-static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
-{
- Scsi_Cmnd *current_command;


- u32 *m = (u32 *)msg;

- u8 as,ds,st;
-

- if(m[0] & (1<<13))
- {

- printk("IOP fail.\n");
- printk("From %d To %d Cmd %d.\n",
- (m[1]>>12)&0xFFF,
- m[1]&0xFFF,
- m[1]>>24);
- printk("Failure Code %d.\n", m[4]>>24);
- if(m[4]&(1<<16))
- printk("Format error.\n");
- if(m[4]&(1<<17))
- printk("Path error.\n");
- if(m[4]&(1<<18))
- printk("Path State.\n");
- if(m[4]&(1<<18))
- printk("Congestion.\n");
-
- m=(u32 *)bus_to_virt(m[7]);
- printk("Failing message is %p.\n", m);
-
- if((m[4]&(1<<18)) && retry_ct < 32)
- {
- retry_ctrl[retry_ct]=c;
- retry[retry_ct]=m;
- if(!retry_ct++)
- {
- retry_timer.expires=jiffies+1;
- add_timer(&retry_timer);
- }
- }
- else
- {
- /* Create a scsi error for this */
- current_command = (Scsi_Cmnd *)m[3];
- printk("Aborted %ld\n", current_command->serial_number);
-
- spin_lock_irq(&io_request_lock);
- current_command->result = DID_ERROR << 16;
- current_command->scsi_done(current_command);
- spin_unlock_irq(&io_request_lock);

-
- /* Now flush the message by making it a NOP */
- m[0]&=0x00FFFFFF;
- m[0]|=(I2O_CMD_UTIL_NOP)<<24;
- i2o_post_message(c,virt_to_bus(m));
- }
- return;
- }

-
-
- /*
- * Low byte is device status, next is adapter status,
- * (then one byte reserved), then request status.
- */
- ds=(u8)m[4];
- as=(u8)(m[4]>>8);
- st=(u8)(m[4]>>24);
-
- dprintk(("i2o got a scsi reply %08X: ", m[0]));
- dprintk(("m[2]=%08X: ", m[2]));
- dprintk(("m[4]=%08X\n", m[4]));
-
- if(m[2]&0x80000000)
- {
- if(m[2]&0x40000000)
- {
- dprintk(("Event.\n"));
- lun_done=1;
- return;
- }
- printk(KERN_ERR "i2o_scsi: bus reset reply.\n");
- return;
- }
-
- current_command = (Scsi_Cmnd *)m[3];
-
- /*
- * Is this a control request coming back - eg an abort ?
- */
-
- if(current_command==NULL)
- {
- if(st)
- dprintk(("SCSI abort: %08X", m[4]));
- dprintk(("SCSI abort completed.\n"));
- return;
- }
-
- dprintk(("Completed %ld\n", current_command->serial_number));
-
- atomic_dec(&queue_depth);
-
- if(st == 0x06)
- {
- if(m[5] < current_command->underflow)
- {
- int i;
- printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X\n",
- m[5], current_command->underflow);
- printk("Cmd: ");
- for(i=0;i<15;i++)
- printk("%02X ", current_command->cmnd[i]);


- printk(".\n");
- }

- else st=0;
- }
-
- if(st)
- {
- /* An error has occurred */
-
- dprintk((KERN_DEBUG "SCSI error %08X", m[4]));
-
- if (as == 0x0E)
- /* SCSI Reset */
- current_command->result = DID_RESET << 16;
- else if (as == 0x0F)
- current_command->result = DID_PARITY << 16;
- else
- current_command->result = DID_ERROR << 16;
- }
- else
- /*
- * It worked maybe ?
- */
- current_command->result = DID_OK << 16 | ds;
- spin_lock(&io_request_lock);
- current_command->scsi_done(current_command);
- spin_unlock(&io_request_lock);
- return;
-}
-
-struct i2o_handler i2o_scsi_handler=
-{
- i2o_scsi_reply,


- NULL,
- NULL,
- NULL,

- "I2O SCSI OSM",
- 0,
- I2O_CLASS_SCSI_PERIPHERAL
-};
-
-static int i2o_find_lun(struct i2o_controller *c, struct i2o_device *d, int *target, int *lun)
-{
- u8 reply[8];
-
- if(i2o_query_scalar(c, d->lct_data.tid, 0, 3, reply, 4)<0)
- return -1;
-
- *target=reply[0];
-
- if(i2o_query_scalar(c, d->lct_data.tid, 0, 4, reply, 8)<0)
- return -1;
-
- *lun=reply[1];
-
- dprintk(("SCSI (%d,%d)\n", *target, *lun));


- return 0;
-}
-

-void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
-{
- struct i2o_device *unit;
- struct i2o_scsi_host *h =(struct i2o_scsi_host *)shpnt->hostdata;
- int lun;
- int target;
-
- h->controller=c;
- h->bus_task=d->lct_data.tid;
-
- for(target=0;target<16;target++)
- for(lun=0;lun<8;lun++)
- h->task[target][lun] = -1;
-
- for(unit=c->devices;unit!=NULL;unit=unit->next)
- {
- dprintk(("Class %03X, parent %d, want %d.\n",
- unit->lct_data.class_id, unit->lct_data.parent_tid, d->lct_data.tid));
-
- /* Only look at scsi and fc devices */
- if ( (unit->lct_data.class_id != I2O_CLASS_SCSI_PERIPHERAL)
- && (unit->lct_data.class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL)
- )
- continue;
-
- /* On our bus ? */
- dprintk(("Found a disk (%d).\n", unit->lct_data.tid));
- if ((unit->lct_data.parent_tid == d->lct_data.tid)
- || (unit->lct_data.parent_tid == d->lct_data.parent_tid)
- )
- {
- u16 limit;
- dprintk(("Its ours.\n"));
- if(i2o_find_lun(c, unit, &target, &lun)==-1)
- {
- printk(KERN_ERR "i2o_scsi: Unable to get lun for tid %d.\n", unit->lct_data.tid);
- continue;
- }
- dprintk(("Found disk %d %d.\n", target, lun));
- h->task[target][lun]=unit->lct_data.tid;
- h->tagclock[target][lun]=jiffies;
-
- /* Get the max fragments/request */
- i2o_query_scalar(c, d->lct_data.tid, 0xF103, 3, &limit, 2);


-
- /* sanity */

- if ( limit == 0 )
- {
- printk(KERN_WARNING "i2o_scsi: Ignoring unreasonable SG limit of 0 from IOP!\n");
- limit = 1;
- }
-
- shpnt->sg_tablesize = limit;
-
- dprintk(("i2o_scsi: set scatter-gather to %d.\n",
- shpnt->sg_tablesize));
- }
- }
-}
-
-int i2o_scsi_detect(Scsi_Host_Template * tpnt)
-{
- unsigned long flags;
- struct Scsi_Host *shpnt = NULL;
- int i;
- int count;
-
- printk("i2o_scsi.c: %s\n", VERSION_STRING);
-
- if(i2o_install_handler(&i2o_scsi_handler)<0)
- {
- printk(KERN_ERR "i2o_scsi: Unable to install OSM handler.\n");
- return 0;
- }
- scsi_context = i2o_scsi_handler.context;
-
- if((sg_chain_pool = kmalloc(SG_CHAIN_POOL_SZ, GFP_KERNEL)) == NULL)
- {
- printk("i2o_scsi: Unable to alloc %d byte SG chain buffer pool.\n", SG_CHAIN_POOL_SZ);
- printk("i2o_scsi: SG chaining DISABLED!\n");
- sg_max_frags = 11;
- }
- else
- {
- printk(" chain_pool: %d bytes @ %p\n", SG_CHAIN_POOL_SZ, sg_chain_pool);
- printk(" (%d byte buffers X %d can_queue X %d i2o controllers)\n",
- SG_CHAIN_BUF_SZ, I2O_SCSI_CAN_QUEUE, i2o_num_controllers);
- sg_max_frags = SG_MAX_FRAGS; // 64
- }
-
- init_timer(&retry_timer);
- retry_timer.data = 0UL;
- retry_timer.function = i2o_retry_run;
-
-// printk("SCSI OSM at %d.\n", scsi_context);
-
- for (count = 0, i = 0; i < MAX_I2O_CONTROLLERS; i++)
- {
- struct i2o_controller *c=i2o_find_controller(i);
- struct i2o_device *d;
- /*
- * This controller doesn't exist.
- */
-
- if(c==NULL)


- continue;
-
- /*

- * Fixme - we need some altered device locking. This
- * is racing with device addition in theory. Easy to fix.
- */
-
- for(d=c->devices;d!=NULL;d=d->next)
- {
- /*
- * bus_adapter, SCSI (obsolete), or FibreChannel busses only
- */
- if( (d->lct_data.class_id!=I2O_CLASS_BUS_ADAPTER_PORT) // bus_adapter
-// && (d->lct_data.class_id!=I2O_CLASS_FIBRE_CHANNEL_PORT) // FC_PORT
- )
- continue;
-
- shpnt = scsi_register(tpnt, sizeof(struct i2o_scsi_host));
- if(shpnt==NULL)
- continue;
- save_flags(flags);
- cli();
- shpnt->unique_id = (u32)d;
- shpnt->io_port = 0;
- shpnt->n_io_port = 0;
- shpnt->irq = 0;
- shpnt->this_id = /* Good question */15;
- restore_flags(flags);
- i2o_scsi_init(c, d, shpnt);
- count++;
- }
- }
- i2o_scsi_hosts = count;
-
- if(count==0)
- {
- if(sg_chain_pool!=NULL)
- {
- kfree(sg_chain_pool);
- sg_chain_pool = NULL;
- }
- flush_pending();
- del_timer(&retry_timer);
- i2o_remove_handler(&i2o_scsi_handler);
- }
-
- return count;
-}
-
-int i2o_scsi_release(struct Scsi_Host *host)
-{
- if(--i2o_scsi_hosts==0)
- {
- if(sg_chain_pool!=NULL)
- {
- kfree(sg_chain_pool);
- sg_chain_pool = NULL;
- }
- flush_pending();
- del_timer(&retry_timer);
- i2o_remove_handler(&i2o_scsi_handler);
- }


- return 0;
-}
-

-
-const char *i2o_scsi_info(struct Scsi_Host *SChost)
-{
- struct i2o_scsi_host *hostdata;
-
- hostdata = (struct i2o_scsi_host *)SChost->hostdata;
-
- return(&hostdata->controller->name[0]);
-}
-
-
-/*
- * From the wd93 driver:
- * Returns true if there will be a DATA_OUT phase with this command,
- * false otherwise.
- * (Thanks to Joerg Dorchain for the research and suggestion.)
- *
- */
-static int is_dir_out(Scsi_Cmnd *cmd)
-{
- switch (cmd->cmnd[0])
- {
- case WRITE_6: case WRITE_10: case WRITE_12:
- case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER:
- case WRITE_VERIFY: case WRITE_VERIFY_12:
- case COMPARE: case COPY: case COPY_VERIFY:
- case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
- case SEARCH_EQUAL_12: case SEARCH_HIGH_12: case SEARCH_LOW_12:
- case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
- case MODE_SELECT: case MODE_SELECT_10: case LOG_SELECT:
- case SEND_DIAGNOSTIC: case CHANGE_DEFINITION: case UPDATE_BLOCK:
- case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG:
- case 0xea:
- return 1;
- default:


- return 0;
- }
-}

-
-int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
-{
- int i;
- int tid;
- struct i2o_controller *c;
- Scsi_Cmnd *current_command;
- struct Scsi_Host *host;
- struct i2o_scsi_host *hostdata;
- u32 *msg, *mptr;
- u32 m;
- u32 *lenptr;
- int direction;
- int scsidir;
- u32 len;
- u32 reqlen;
- u32 tag;
-
- static int max_qd = 1;
-
- /*
- * Do the incoming paperwork
- */
-
- host = SCpnt->host;
- hostdata = (struct i2o_scsi_host *)host->hostdata;
- SCpnt->scsi_done = done;
-
- if(SCpnt->target > 15)
- {
- printk(KERN_ERR "i2o_scsi: Wild target %d.\n", SCpnt->target);


- return -1;
- }
-

- tid = hostdata->task[SCpnt->target][SCpnt->lun];
-
- dprintk(("qcmd: Tid = %d\n", tid));
-
- current_command = SCpnt; /* set current command */
- current_command->scsi_done = done; /* set ptr to done function */
-
- /* We don't have such a device. Pretend we did the command
- and that selection timed out */
-
- if(tid == -1)
- {
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);


- return 0;
- }
-

- dprintk(("Real scsi messages.\n"));
-
- c = hostdata->controller;
-
- /*
- * Obtain an I2O message. Right now we _have_ to obtain one
- * until the scsi layer stuff is cleaned up.
- */

-
- do
- {
- mb();
- m = I2O_POST_READ32(c);
- }

- while(m==0xFFFFFFFF);


- msg = (u32 *)(c->mem_offset + m);

-
- /*
- * Put together a scsi execscb message
- */
-
- len = SCpnt->request_bufflen;
- direction = 0x00000000; // SGL IN (osm<--iop)
-
- /*
- * The scsi layer should be handling this stuff
- */
-
- scsidir = 0x00000000; // DATA NO XFER
- if(len)
- {
- if(is_dir_out(SCpnt))
- {
- direction=0x04000000; // SGL OUT (osm-->iop)
- scsidir =0x80000000; // DATA OUT (iop-->dev)
- }
- else
- {
- scsidir =0x40000000; // DATA IN (iop<--dev)
- }
- }
-
- __raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
- __raw_writel(scsi_context, &msg[2]); /* So the I2O layer passes to us */
- /* Sorry 64bit folks. FIXME */
- __raw_writel((u32)SCpnt, &msg[3]); /* We want the SCSI control block back */
-
- /* LSI_920_PCI_QUIRK
- *
- * Intermittant observations of msg frame word data corruption
- * observed on msg[4] after:
- * WRITE, READ-MODIFY-WRITE
- * operations. 19990606 -sralston
- *
- * (Hence we build this word via tag. Its good practice anyway
- * we don't want fetches over PCI needlessly)
- */
-
- tag=0;
-
- /*
- * Attach tags to the devices
- */
- if(SCpnt->device->tagged_supported)
- {
- /*
- * Some drives are too stupid to handle fairness issues
- * with tagged queueing. We throw in the odd ordered
- * tag to stop them starving themselves.
- */
- if((jiffies - hostdata->tagclock[SCpnt->target][SCpnt->lun]) > (5*HZ))
- {
- tag=0x01800000; /* ORDERED! */
- hostdata->tagclock[SCpnt->target][SCpnt->lun]=jiffies;
- }
- else
- {
- /* Hmmm... I always see value of 0 here,
- * of which {HEAD_OF, ORDERED, SIMPLE} are NOT! -sralston
- */
- if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
- tag=0x01000000;
- else if(SCpnt->tag == ORDERED_QUEUE_TAG)
- tag=0x01800000;
- }
- }
-
- /* Direction, disconnect ok, tag, CDBLen */
- __raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
-
- mptr=msg+5;
-
- /*
- * Write SCSI command into the message - always 16 byte block
- */
-
- memcpy_toio(mptr, SCpnt->cmnd, 16);
- mptr+=4;
- lenptr=mptr++; /* Remember me - fill in when we know */
-
- reqlen = 12; // SINGLE SGE
-
- /*
- * Now fill in the SGList and command
- *
- * FIXME: we need to set the sglist limits according to the
- * message size of the I2O controller. We might only have room
- * for 6 or so worst case
- */
-
- if(SCpnt->use_sg)
- {
- struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
- int chain = 0;
-
- len = 0;
-
- if((sg_max_frags > 11) && (SCpnt->use_sg > 11))
- {
- chain = 1;
- /*
- * Need to chain!
- */
- __raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
- __raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
- mptr = (u32*)(sg_chain_pool + sg_chain_tag);
- if (SCpnt->use_sg > max_sg_len)
- {
- max_sg_len = SCpnt->use_sg;
- printk("i2o_scsi: Chain SG! SCpnt=%p, SG_FragCnt=%d, SG_idx=%d\n",
- SCpnt, SCpnt->use_sg, sg_chain_tag);
- }
- if ( ++sg_chain_tag == SG_MAX_BUFS )
- sg_chain_tag = 0;
- for(i = 0 ; i < SCpnt->use_sg; i++)
- {
- *mptr++=direction|0x10000000|sg->length;
- len+=sg->length;
- *mptr++=virt_to_bus(sg->address);
- sg++;
- }
- mptr[-2]=direction|0xD0000000|(sg-1)->length;
- }
- else
- {
- for(i = 0 ; i < SCpnt->use_sg; i++)
- {
- __raw_writel(direction|0x10000000|sg->length, mptr++);
- len+=sg->length;
- __raw_writel(virt_to_bus(sg->address), mptr++);
- sg++;
- }
-
- /* Make this an end of list. Again evade the 920 bug and
- unwanted PCI read traffic */
-
- __raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
- }
-
- if(!chain)
- reqlen = mptr - msg;
-
- __raw_writel(len, lenptr);
-
- if(len != SCpnt->underflow)
- printk("Cmd len %08X Cmd underflow %08X\n",
- len, SCpnt->underflow);
- }
- else
- {
- dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
- SCpnt->request_bufflen));
- __raw_writel(len = SCpnt->request_bufflen, lenptr);
- if(len == 0)
- {
- reqlen = 9;
- }
- else
- {
- __raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
- __raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
- }
- }
-
- /*
- * Stick the headers on
- */
-
- __raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
-
- /* Queue the message */
- i2o_post_message(c,m);
-
- atomic_inc(&queue_depth);
-
- if(atomic_read(&queue_depth)> max_qd)
- {
- max_qd=atomic_read(&queue_depth);
- printk("Queue depth now %d.\n", max_qd);
- }
-
- mb();
- dprintk(("Issued %ld\n", current_command->serial_number));
-

- return 0;
-}
-

-static void internal_done(Scsi_Cmnd * SCpnt)
-{
- SCpnt->SCp.Status++;
-}
-
-int i2o_scsi_command(Scsi_Cmnd * SCpnt)
-{
- i2o_scsi_queuecommand(SCpnt, internal_done);
- SCpnt->SCp.Status = 0;
- while (!SCpnt->SCp.Status)
- barrier();
- return SCpnt->result;
-}
-
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
-{
- struct i2o_controller *c;
- struct Scsi_Host *host;
- struct i2o_scsi_host *hostdata;
- u32 *msg;
- u32 m;
- int tid;
-
- printk("i2o_scsi: Aborting command block.\n");
-
- host = SCpnt->host;
- hostdata = (struct i2o_scsi_host *)host->hostdata;
- tid = hostdata->task[SCpnt->target][SCpnt->lun];
- if(tid==-1)
- {
- printk(KERN_ERR "impossible command to abort.\n");
- return SCSI_ABORT_NOT_RUNNING;
- }
- c = hostdata->controller;
-
- /*
- * Obtain an I2O message. Right now we _have_ to obtain one
- * until the scsi layer stuff is cleaned up.
- */

-
- do
- {
- mb();
- m = I2O_POST_READ32(c);
- }

- while(m==0xFFFFFFFF);


- msg = (u32 *)(c->mem_offset + m);
-

- __raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]);
- __raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]);
- __raw_writel(scsi_context, &msg[2]);
- __raw_writel(0, &msg[3]); /* Not needed for an abort */
- __raw_writel((u32)SCpnt, &msg[4]);
- wmb();
- i2o_post_message(c,m);
- wmb();
- return SCSI_ABORT_PENDING;
-}
-
-int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
-{
- int tid;
- struct i2o_controller *c;
- struct Scsi_Host *host;
- struct i2o_scsi_host *hostdata;


- u32 m;
- u32 *msg;

-
- /*
- * Find the TID for the bus
- */
-
- printk("i2o_scsi: Attempting to reset the bus.\n");
-
- host = SCpnt->host;
- hostdata = (struct i2o_scsi_host *)host->hostdata;
- tid = hostdata->bus_task;
- c = hostdata->controller;
-
- /*
- * Now send a SCSI reset request. Any remaining commands
- * will be aborted by the IOP. We need to catch the reply
- * possibly ?
- */
-
- m = I2O_POST_READ32(c);
-
- /*
- * No free messages, try again next time - no big deal
- */
-
- if(m == 0xFFFFFFFF)
- return SCSI_RESET_PUNT;
-

- msg = (u32 *)(c->mem_offset + m);

- __raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
- __raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]);
- __raw_writel(scsi_context|0x80000000, &msg[2]);
- /* We use the top bit to split controller and unit transactions */
- /* Now store unit,tid so we can tie the completion back to a specific device */
- __raw_writel(c->unit << 16 | tid, &msg[3]);
- wmb();
- i2o_post_message(c,m);
- return SCSI_RESET_PENDING;
-}
-
-/*
- * This is anyones guess quite frankly.
- */
-
-int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
-{
- int size;
-
- size = disk->capacity;
- ip[0] = 64; /* heads */
- ip[1] = 32; /* sectors */
- if ((ip[2] = size >> 11) > 1024) { /* cylinders, test for big disk */
- ip[0] = 255; /* heads */
- ip[1] = 63; /* sectors */
- ip[2] = size / (255 * 63); /* cylinders */
- }


- return 0;
-}
-

-MODULE_AUTHOR("Red Hat Software");
-

-static Scsi_Host_Template driver_template = I2OSCSI;
-
-#include "../scsi/scsi_module.c"
diff -u --recursive --new-file v2.4.12/linux/drivers/i2o/i2o_scsi.h linux/drivers/i2o/i2o_scsi.h
--- v2.4.12/linux/drivers/i2o/i2o_scsi.h Mon Dec 11 13:20:04 2000
+++ linux/drivers/i2o/i2o_scsi.h Wed Dec 31 16:00:00 1969
@@ -1,47 +0,0 @@
-#ifndef _I2O_SCSI_H
-#define _I2O_SCSI_H
-
-#if !defined(LINUX_VERSION_CODE)
-#include <linux/version.h>
-#endif
-
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
-#define I2O_SCSI_ID 15
-#define I2O_SCSI_CAN_QUEUE 4
-#define I2O_SCSI_CMD_PER_LUN 6
-
-extern int i2o_scsi_detect(Scsi_Host_Template *);
-extern const char *i2o_scsi_info(struct Scsi_Host *);
-extern int i2o_scsi_command(Scsi_Cmnd *);
-extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int i2o_scsi_abort(Scsi_Cmnd *);
-extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
-extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
-extern void i2o_scsi_setup(char *str, int *ints);
-extern int i2o_scsi_release(struct Scsi_Host *host);
-
-#define I2OSCSI { \
- next: NULL, \
- proc_name: "i2o_scsi", \
- name: "I2O SCSI Layer", \
- detect: i2o_scsi_detect, \
- release: i2o_scsi_release, \
- info: i2o_scsi_info, \
- command: i2o_scsi_command, \
- queuecommand: i2o_scsi_queuecommand, \
- abort: i2o_scsi_abort, \
- reset: i2o_scsi_reset, \
- bios_param: i2o_scsi_bios_param, \
- can_queue: I2O_SCSI_CAN_QUEUE, \
- this_id: I2O_SCSI_ID, \
- sg_tablesize: 8, \
- cmd_per_lun: I2O_SCSI_CMD_PER_LUN, \
- unchecked_isa_dma: 0, \
- use_clustering: ENABLE_CLUSTERING \
- }
-
-#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/hd.c linux/drivers/ide/hd.c
--- v2.4.12/linux/drivers/ide/hd.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/hd.c Mon Oct 15 13:27:42 2001
@@ -640,7 +640,7 @@


X
X case BLKGETSIZE: /* Return device size */

X return put_user(hd[MINOR(inode->i_rdev)].nr_sects,

- (long *) arg);
+ (unsigned long *) arg);

X case BLKGETSIZE64:
X return put_user((u64)hd[MINOR(inode->i_rdev)].nr_sects << 9,
X (u64 *) arg);
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c
--- v2.4.12/linux/drivers/ide/hptraid.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ide/hptraid.c Mon Oct 15 13:27:42 2001
@@ -15,6 +15,8 @@
X Based on work
X Copyleft (C) 2001 by Wilfried Weissmann <wweis...@gmx.at>
X Copyright (C) 1994-96 Marc ZYNGIER <zyn...@ufr-info-p7.ibp.fr>
+ Based on work done by Søren Schmidt for FreeBSD
+
X
X */
X
@@ -83,8 +85,8 @@


X if (!arg) return -EINVAL;

X sectors = ataraid_gendisk.part[MINOR(inode->i_rdev)].nr_sects;
X if (MINOR(inode->i_rdev)&15)
- return put_user(sectors, (long *) arg);
- return put_user(raid[minor].sectors , (long *) arg);
+ return put_user(sectors, (unsigned long *) arg);
+ return put_user(raid[minor].sectors , (unsigned long *) arg);
X break;
X
X
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/hptraid.h linux/drivers/ide/hptraid.h
--- v2.4.12/linux/drivers/ide/hptraid.h Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/hptraid.h Thu Oct 11 09:43:29 2001
@@ -1,4 +1,32 @@
-
+/*-
+ * Copyright (c) 2000,2001 Søren Schmidt <s...@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


+ *
+ */
+

X struct highpoint_raid_conf
X {
X int8_t filler1[32];
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- v2.4.12/linux/drivers/ide/ide-cd.c Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-cd.c Thu Oct 18 13:18:22 2001
@@ -2409,7 +2409,7 @@
X * any other way to detect this...
X */
X if (sense.sense_key == NOT_READY) {
- if (sense.asc == 0x3a && (!sense.ascq||sense.ascq == 1))
+ if (sense.asc == 0x3a && sense.ascq == 1)
X return CDS_NO_DISC;
X else
X return CDS_TRAY_OPEN;
@@ -3059,3 +3059,4 @@
X
X module_init(ide_cdrom_init);
X module_exit(ide_cdrom_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- v2.4.12/linux/drivers/ide/ide-disk.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ide/ide-disk.c Thu Oct 11 09:14:32 2001
@@ -890,3 +890,4 @@
X
X module_init(idedisk_init);
X module_exit(idedisk_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- v2.4.12/linux/drivers/ide/ide-floppy.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ide/ide-floppy.c Thu Oct 11 09:14:32 2001
@@ -2116,3 +2116,4 @@
X
X module_init(idefloppy_init);
X module_exit(idefloppy_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- v2.4.12/linux/drivers/ide/ide-probe.c Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ide-probe.c Thu Oct 11 09:14:32 2001
@@ -928,4 +928,5 @@
X {
X ide_probe = NULL;
X }
+MODULE_LICENSE("GPL");
X #endif /* MODULE */
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.12/linux/drivers/ide/ide.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ide/ide.c Mon Oct 15 13:27:42 2001
@@ -2661,7 +2661,7 @@
X }


X
X case BLKGETSIZE: /* Return device size */

- return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (long *) arg);
+ return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects << 9, (u64 *) arg);
X
@@ -3749,6 +3749,7 @@
X #ifdef MODULE
X char *options = NULL;
X MODULE_PARM(options,"s");
+MODULE_LICENSE("GPL");
X
X static void __init parse_options (char *line)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/pdcraid.c linux/drivers/ide/pdcraid.c
--- v2.4.12/linux/drivers/ide/pdcraid.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ide/pdcraid.c Mon Oct 15 13:27:42 2001
@@ -111,8 +111,8 @@


X if (!arg) return -EINVAL;

X sectors = ataraid_gendisk.part[MINOR(inode->i_rdev)].nr_sects;
X if (MINOR(inode->i_rdev)&15)
- return put_user(sectors, (long *) arg);
- return put_user(raid[minor].sectors , (long *) arg);
+ return put_user(sectors, (unsigned long *) arg);
+ return put_user(raid[minor].sectors , (unsigned long *) arg);
X break;
X
X
diff -u --recursive --new-file v2.4.12/linux/drivers/ide/rapide.c linux/drivers/ide/rapide.c
--- v2.4.12/linux/drivers/ide/rapide.c Tue Jul 3 17:08:19 2001
+++ linux/drivers/ide/rapide.c Thu Oct 11 09:14:32 2001
@@ -69,6 +69,7 @@
X }
X
X #ifdef MODULE
+MODULE_LICENSE("GPL");
X
X int init_module (void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/Makefile linux/drivers/ieee1394/Makefile
--- v2.4.12/linux/drivers/ieee1394/Makefile Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/Makefile Wed Oct 17 14:19:20 2001
@@ -4,11 +4,11 @@
X
X O_TARGET := ieee1394drv.o
X
-export-objs := ieee1394_syms.o ohci1394.o
+export-objs := ieee1394_core.o ohci1394.o
X
X list-multi := ieee1394.o
X ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
- highlevel.o csr.o nodemgr.o ieee1394_syms.o
+ highlevel.o csr.o nodemgr.o
X
X obj-$(CONFIG_IEEE1394) += ieee1394.o
X obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/ieee1394.h linux/drivers/ieee1394/ieee1394.h
--- v2.4.12/linux/drivers/ieee1394/ieee1394.h Mon Dec 11 13:20:17 2000
+++ linux/drivers/ieee1394/ieee1394.h Wed Oct 17 14:19:20 2001
@@ -47,7 +47,10 @@
X
X #define SPEED_100 0x0
X #define SPEED_200 0x1
-#define SPEED_400 0x2
+#define SPEED_400 0x2
+
+/* Maps speed values above to a string representation */
+extern const char *hpsb_speedto_str[];
X
X #define SELFID_PWRCL_NO_POWER 0x0
X #define SELFID_PWRCL_PROVIDE_15W 0x1
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- v2.4.12/linux/drivers/ieee1394/ieee1394_core.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/ieee1394_core.c Wed Oct 17 14:19:20 2001
@@ -30,6 +30,7 @@
X #include "ieee1394_transactions.h"
X #include "csr.h"
X #include "nodemgr.h"
+#include "ieee1394_hotplug.h"
X
X /*
X * Disable the nodemgr detection and config rom reading functionality.
@@ -38,8 +39,13 @@
X MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
X static int disable_nodemgr = 0;
X
+/* We are GPL, so treat us special */
+MODULE_LICENSE("GPL");
+
X static kmem_cache_t *hpsb_packet_cache;
X
+/* Some globals used */
+const char *hpsb_speedto_str[] = { "S100", "S200", "S400" };
X
X static void dump_packet(const char *text, quadlet_t *data, int size)


X {
@@ -805,3 +811,68 @@
X

X module_init(ieee1394_init);
X module_exit(ieee1394_cleanup);
+
+/* Exported symbols */
+EXPORT_SYMBOL(hpsb_register_lowlevel);
+EXPORT_SYMBOL(hpsb_unregister_lowlevel);
+EXPORT_SYMBOL(hpsb_get_host);
+EXPORT_SYMBOL(hpsb_inc_host_usage);
+EXPORT_SYMBOL(hpsb_dec_host_usage);
+EXPORT_SYMBOL(hpsb_speedto_str);
+
+EXPORT_SYMBOL(alloc_hpsb_packet);
+EXPORT_SYMBOL(free_hpsb_packet);
+EXPORT_SYMBOL(hpsb_send_packet);
+EXPORT_SYMBOL(hpsb_reset_bus);
+EXPORT_SYMBOL(hpsb_bus_reset);
+EXPORT_SYMBOL(hpsb_selfid_received);
+EXPORT_SYMBOL(hpsb_selfid_complete);
+EXPORT_SYMBOL(hpsb_packet_sent);
+EXPORT_SYMBOL(hpsb_packet_received);
+
+EXPORT_SYMBOL(get_tlabel);
+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);
+EXPORT_SYMBOL(fill_phy_packet);
+EXPORT_SYMBOL(hpsb_make_readqpacket);
+EXPORT_SYMBOL(hpsb_make_readbpacket);
+EXPORT_SYMBOL(hpsb_make_writeqpacket);
+EXPORT_SYMBOL(hpsb_make_writebpacket);
+EXPORT_SYMBOL(hpsb_make_lockpacket);
+EXPORT_SYMBOL(hpsb_make_phypacket);
+EXPORT_SYMBOL(hpsb_packet_success);
+EXPORT_SYMBOL(hpsb_make_packet);
+EXPORT_SYMBOL(hpsb_read);
+EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
+
+EXPORT_SYMBOL(hpsb_register_highlevel);
+EXPORT_SYMBOL(hpsb_unregister_highlevel);
+EXPORT_SYMBOL(hpsb_register_addrspace);
+EXPORT_SYMBOL(hpsb_listen_channel);
+EXPORT_SYMBOL(hpsb_unlisten_channel);
+EXPORT_SYMBOL(highlevel_read);
+EXPORT_SYMBOL(highlevel_write);
+EXPORT_SYMBOL(highlevel_lock);
+EXPORT_SYMBOL(highlevel_lock64);
+EXPORT_SYMBOL(highlevel_add_host);
+EXPORT_SYMBOL(highlevel_remove_host);
+EXPORT_SYMBOL(highlevel_host_reset);
+EXPORT_SYMBOL(highlevel_add_one_host);
+
+EXPORT_SYMBOL(hpsb_guid_get_entry);
+EXPORT_SYMBOL(hpsb_nodeid_get_entry);
+EXPORT_SYMBOL(hpsb_get_host_by_ne);
+EXPORT_SYMBOL(hpsb_guid_fill_packet);
+EXPORT_SYMBOL(hpsb_register_protocol);
+EXPORT_SYMBOL(hpsb_unregister_protocol);
+EXPORT_SYMBOL(hpsb_release_unit_directory);
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/ieee1394_types.h linux/drivers/ieee1394/ieee1394_types.h
--- v2.4.12/linux/drivers/ieee1394/ieee1394_types.h Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/ieee1394_types.h Wed Oct 17 14:19:20 2001
@@ -20,6 +20,23 @@
X #define INIT_TQ_HEAD(tq) INIT_LIST_HEAD(&(tq))
X #endif
X
+/* This showed up around this time */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12)
+
+# ifndef MODULE_LICENSE
+# define MODULE_LICENSE(x)
+# endif
+
+# ifndef min
+# define min(x,y) ({ \
+ const typeof(x) _x = (x); \
+ const typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+# endif
+
+#endif /* Linux version < 2.4.12 */
+
X #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
X #include <asm/spinlock.h>
X #else
@@ -49,6 +66,10 @@
X #define NODE_MASK 0x003f
X #define LOCAL_BUS 0xffc0
X #define ALL_NODES 0x003f
+
+#define NODE_BUS_FMT "%d:%d"
+#define NODE_BUS_ARGS(nodeid) \
+ (nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
X
X #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
X
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/nodemgr.c linux/drivers/ieee1394/nodemgr.c
--- v2.4.12/linux/drivers/ieee1394/nodemgr.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/nodemgr.c Wed Oct 17 14:19:20 2001
@@ -27,11 +27,8 @@
X #include "nodemgr.h"
X
X
-#define NODE_BUS_FMT "%d:%d"
-#define NODE_BUS_ARGS(nodeid) \
- (nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
-
-/* Basically what we do here is start off retrieving the bus_info block.
+/*
+ * Basically what we do here is start off retrieving the bus_info block.
X * From there will fill in some info about the node, verify it is of IEEE
X * 1394 type, and that the crc checks out ok. After that we start off with
X * the root directory, and subdirectories. To do this, we retrieve the
@@ -42,9 +39,7 @@
X * We verify CRC's along the way for each directory/block/leaf. The
X * entire node structure is generic, and simply stores the information in
X * a way that's easy to parse by the protocol interface.
- *
- * XXX: Most of this isn't done yet :) */
-
+ */
X
X static LIST_HEAD(node_list);
X static rwlock_t node_lock = RW_LOCK_UNLOCKED;
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/sbp2.c linux/drivers/ieee1394/sbp2.c
--- v2.4.12/linux/drivers/ieee1394/sbp2.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/sbp2.c Wed Oct 17 14:19:20 2001
@@ -130,6 +130,10 @@
X * add some init code to the kernel to support this... and modules are much
X * more flexible anyway. ;-)
X *
+ * - The scsi stack in recent kernels pass down the data transfer
+ * direction as scsicmd->sc_data_direction, which we should use
+ * instead of the sbp2scsi_direction_table.
+ *


X *
X * History:
X *

@@ -355,23 +359,23 @@
X
X
X #if CONFIG_IEEE1394_SBP2_DEBUG >= 2
-#define SBP2_DEBUG(fmt, args...) HPSB_ERR(fmt, ## args)
-#define SBP2_INFO(fmt, args...) HPSB_ERR(fmt, ## args)
-#define SBP2_NOTICE(fmt, args...) HPSB_ERR(fmt, ## args)
-#define SBP2_WARN(fmt, args...) HPSB_ERR(fmt, ## args)
+#define SBP2_DEBUG(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_INFO(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_NOTICE(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_WARN(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
X #elif CONFIG_IEEE1394_SBP2_DEBUG == 1
-#define SBP2_DEBUG(fmt, args...) HPSB_DEBUG(fmt, ## args)
-#define SBP2_INFO(fmt, args...) HPSB_INFO(fmt, ## args)
-#define SBP2_NOTICE(fmt, args...) HPSB_NOTICE(fmt, ## args)
-#define SBP2_WARN(fmt, args...) HPSB_WARN(fmt, ## args)
+#define SBP2_DEBUG(fmt, args...) HPSB_DEBUG("sbp2: "fmt, ## args)
+#define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args)
+#define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args)
+#define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args)
X #else
-#define SBP2_DEBUG(fmt, args...)
-#define SBP2_INFO(fmt, args...)
-#define SBP2_NOTICE(fmt, args...)
-#define SBP2_WARN(fmt, args...)
+#define SBP2_DEBUG(fmt, args...)
+#define SBP2_INFO(fmt, args...)
+#define SBP2_NOTICE(fmt, args...)
+#define SBP2_WARN(fmt, args...)
X #endif
X
-#define SBP2_ERR(fmt, args...) HPSB_ERR(fmt, ## args)
+#define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
X
X /*
X * Spinlock debugging stuff. I'm playing it safe until the driver has been
@@ -393,6 +397,8 @@
X
X Scsi_Host_Template *global_scsi_tpnt = NULL;
X
+static u8 sbp2_speedto_maxrec[] = { 0x7, 0x8, 0x9 };
+
X static LIST_HEAD(sbp2_host_info_list);
X static int sbp2_host_count = 0;
X
@@ -477,7 +483,7 @@
X packet = alloc_hpsb_packet(8);
X
X if (!packet) {
- SBP2_ERR("sbp2: sbp2util_create_request_packet_pool - packet allocation failed!");
+ SBP2_ERR("sbp2util_create_request_packet_pool - packet allocation failed!");
X return(-ENOMEM);
X }
X
@@ -593,7 +599,7 @@
X list_add_tail(&request_packet->list, &hi->sbp2_req_inuse);
X
X } else {
- SBP2_ERR("sbp2: sbp2util_allocate_request_packet - no packets available!");
+ SBP2_ERR("sbp2util_allocate_request_packet - no packets available!");
X }
X sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags);
X
@@ -766,7 +772,7 @@
X command->linked = 0;
X list_add_tail(&command->list, &scsi_id->sbp2_command_orb_inuse);
X } else {
- SBP2_ERR("sbp2: sbp2util_allocate_command_orb - No orbs available!");
+ SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!");
X }
X sbp2_spin_unlock(&scsi_id->sbp2_command_orb_lock, flags);
X return (command);
@@ -825,7 +831,7 @@
X */
X int sbp2_init(void)
X {
- SBP2_DEBUG("sbp2: sbp2_init");
+ SBP2_DEBUG("sbp2_init");
X
X /*
X * Register our high level driver with 1394 stack
@@ -833,7 +839,7 @@
X sbp2_hl_handle = hpsb_register_highlevel(SBP2_DEVICE_NAME, &sbp2_hl_ops);
X
X if (sbp2_hl_handle == NULL) {
- SBP2_ERR("sbp2: sbp2 failed to register with ieee1394 highlevel");
+ SBP2_ERR("sbp2 failed to register with ieee1394 highlevel");
X return(-ENOMEM);
X }
X
@@ -854,7 +860,7 @@
X */
X void sbp2_cleanup(void)
X {
- SBP2_DEBUG("sbp2: sbp2_cleanup");
+ SBP2_DEBUG("sbp2_cleanup");
X
X hpsb_unregister_protocol(&sbp2_driver);
X
@@ -869,7 +875,7 @@
X {
X struct sbp2scsi_host_info *hi;
X
- SBP2_DEBUG("sbp2: sbp2_probe");
+ SBP2_DEBUG("sbp2_probe");
X hi = sbp2_find_host_info(ud->ne->host);
X
X return sbp2_start_device(hi, ud);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 21'
echo 'File patch-2.4.13 is continued in part 22'
echo "22" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:52 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part22

#!/bin/sh -x
# this is part 22 of a 53 - part archive


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

if test "$Scheck" != 22; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

@@ -880,7 +886,7 @@
X struct sbp2scsi_host_info *hi;
X struct scsi_id_instance_data *scsi_id = ud->driver_data;
X
- SBP2_DEBUG("sbp2: sbp2_disconnect");
+ SBP2_DEBUG("sbp2_disconnect");


X hi = sbp2_find_host_info(ud->ne->host);
X

X if (hi != NULL)
@@ -893,7 +899,7 @@
X struct scsi_id_instance_data *scsi_id = ud->driver_data;


X unsigned long flags;
X

- SBP2_DEBUG("sbp2: sbp2_update");
+ SBP2_DEBUG("sbp2_update");


X hi = sbp2_find_host_info(ud->ne->host);
X

X if (sbp2_reconnect_device(hi, scsi_id)) {
@@ -907,7 +913,7 @@
X * unvalidated, so that he gets cleaned up
X * later.
X */
- SBP2_ERR("sbp2: sbp2_reconnect_device failed!");
+ SBP2_ERR("sbp2_reconnect_device failed!");
X sbp2_remove_device(hi, scsi_id);
X return;
X }
@@ -940,14 +946,14 @@
X struct sbp2scsi_host_info *hi;
X unsigned long flags;
X
- SBP2_DEBUG("sbp2: sbp2_add_host");
+ SBP2_DEBUG("sbp2_add_host");
X
X /* Allocate some memory for our host info structure */
X hi = (struct sbp2scsi_host_info *)kmalloc(sizeof(struct sbp2scsi_host_info),
X GFP_KERNEL);
X
X if (hi == NULL) {
- SBP2_ERR("sbp2: out of memory in sbp2_add_host");
+ SBP2_ERR("out of memory in sbp2_add_host");
X return;
X }
X
@@ -962,7 +968,7 @@
X
X /* Create our request packet pool (pool of packets for use in I/O) */
X if (sbp2util_create_request_packet_pool(hi)) {
- SBP2_ERR("sbp2: sbp2util_create_request_packet_pool failed!");
+ SBP2_ERR("sbp2util_create_request_packet_pool failed!");
X return;
X }
X
@@ -1005,7 +1011,7 @@
X unsigned long flags;
X int i;
X
- SBP2_DEBUG("sbp2: sbp2_remove_host");
+ SBP2_DEBUG("sbp2_remove_host");
X
X sbp2_spin_lock(&sbp2_host_info_lock, flags);
X
@@ -1030,7 +1036,7 @@
X kfree(hi);
X }
X else
- SBP2_ERR("sbp2: attempt to remove unknown host %p", host);
+ SBP2_ERR("attempt to remove unknown host %p", host);
X
X sbp2_spin_unlock(&sbp2_host_info_lock, flags);
X }
@@ -1045,7 +1051,7 @@
X struct node_entry *ne;
X int i;
X
- SBP2_DEBUG("sbp2: sbp2_start_device");
+ SBP2_DEBUG("sbp2_start_device");
X ne = ud->ne;
X
X /*
@@ -1114,7 +1120,7 @@
X
X kfree(scsi_id);
X alloc_fail_first:
- SBP2_ERR ("sbp2: Could not allocate memory for scsi_id");
+ SBP2_ERR ("Could not allocate memory for scsi_id");
X return(-ENOMEM);
X }
X SBP2_DMA_ALLOC("consistent DMA region for login ORB");
@@ -1125,7 +1131,7 @@
X scsi_id->ne = ne;
X scsi_id->ud = ud;
X scsi_id->speed_code = SPEED_100;
- scsi_id->max_payload_size = MAX_PAYLOAD_S100;
+ scsi_id->max_payload_size = sbp2_speedto_maxrec[SPEED_100];
X ud->driver_data = scsi_id;
X
X init_waitqueue_head(&scsi_id->sbp2_login_wait);
@@ -1169,7 +1175,7 @@
X if (!hi->scsi_id[i]) {
X hi->scsi_id[i] = scsi_id;
X scsi_id->id = i;
- SBP2_DEBUG("sbp2: New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
+ SBP2_DEBUG("New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
X break;
X }
X }
@@ -1178,7 +1184,7 @@
X * Create our command orb pool
X */
X if (sbp2util_create_command_orb_pool(scsi_id, hi)) {
- SBP2_ERR("sbp2: sbp2util_create_command_orb_pool failed!");
+ SBP2_ERR("sbp2util_create_command_orb_pool failed!");
X sbp2_remove_device(hi, scsi_id);
X return -ENOMEM;
X }
@@ -1187,7 +1193,7 @@
X * Make sure we are not out of space
X */
X if (i == SBP2SCSI_MAX_SCSI_IDS) {
- SBP2_ERR("sbp2: No slots left for SBP-2 device");
+ SBP2_ERR("No slots left for SBP-2 device");
X sbp2_remove_device(hi, scsi_id);
X return -EBUSY;
X }
@@ -1201,7 +1207,7 @@
X * Login failed... so, just mark him as unvalidated, so
X * that he gets cleaned up later.
X */
- SBP2_ERR("sbp2: sbp2_login_device failed");
+ SBP2_ERR("sbp2_login_device failed");
X sbp2_remove_device(hi, scsi_id);
X return -EBUSY;
X }
@@ -1270,7 +1276,7 @@
X SBP2_DMA_FREE("single logout orb");
X }
X
- SBP2_DEBUG("sbp2: Unvalidated SBP-2 device removed, SCSI ID = %d",
+ SBP2_DEBUG("Unvalidated SBP-2 device removed, SCSI ID = %d",
X scsi_id->id);
X hi->scsi_id[scsi_id->id] = NULL;
X kfree(scsi_id);
@@ -1291,43 +1297,43 @@
X quadlet_t data[2];


X unsigned long flags;
X

- SBP2_DEBUG("sbp2: sbp2_login_device");
+ SBP2_DEBUG("sbp2_login_device");
X
X if (!scsi_id->login_orb) {
- SBP2_DEBUG("sbp2: sbp2_login_device: login_orb not alloc'd!");
+ SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!");
X return(-EIO);
X }
X
X /* Set-up login ORB, assume no password */
X scsi_id->login_orb->password_hi = 0;
X scsi_id->login_orb->password_lo = 0;
- SBP2_DEBUG("sbp2: sbp2_login_device: password_hi/lo initialized");
+ SBP2_DEBUG("sbp2_login_device: password_hi/lo initialized");
X
X scsi_id->login_orb->login_response_lo = scsi_id->login_response_dma;
X scsi_id->login_orb->login_response_hi = ORB_SET_NODE_ID(hi->host->node_id);
- SBP2_DEBUG("sbp2: sbp2_login_device: login_response_hi/lo initialized");
+ SBP2_DEBUG("sbp2_login_device: login_response_hi/lo initialized");
X
X scsi_id->login_orb->lun_misc = ORB_SET_FUNCTION(LOGIN_REQUEST);
X scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0); /* One second reconnect time */
X scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(1); /* Exclusive access to device */
X scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1); /* Notify us of login complete */
- SBP2_DEBUG("sbp2: sbp2_login_device: lun_misc initialized");
+ SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
X
X scsi_id->login_orb->passwd_resp_lengths =
X ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
- SBP2_DEBUG("sbp2: sbp2_login_device: passwd_resp_lengths initialized");
+ SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized");
X
X scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
X scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
X SBP2_STATUS_FIFO_ADDRESS_HI);
- SBP2_DEBUG("sbp2: sbp2_login_device: status FIFO initialized");
+ SBP2_DEBUG("sbp2_login_device: status FIFO initialized");
X
X /*
X * Byte swap ORB if necessary
X */
X sbp2util_cpu_to_be32_buffer(scsi_id->login_orb, sizeof(struct sbp2_login_orb));
X
- SBP2_DEBUG("sbp2: sbp2_login_device: orb byte-swapped");
+ SBP2_DEBUG("sbp2_login_device: orb byte-swapped");
X
X /*
X * Initialize login response and status fifo
@@ -1335,7 +1341,7 @@
X memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response));
X memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
X
- SBP2_DEBUG("sbp2: sbp2_login_device: login_response/status FIFO memset");
+ SBP2_DEBUG("sbp2_login_device: login_response/status FIFO memset");
X
X /*
X * Ok, let's write to the target's management agent register
@@ -1344,9 +1350,9 @@
X data[1] = scsi_id->login_orb_dma;
X sbp2util_cpu_to_be32_buffer(data, 8);
X
- SBP2_DEBUG("sbp2: sbp2_login_device: prepared to write");
+ SBP2_DEBUG("sbp2_login_device: prepared to write");
X hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
- SBP2_DEBUG("sbp2: sbp2_login_device: written");
+ SBP2_DEBUG("sbp2_login_device: written");
X
X /*
X * Wait for login status... but, only if the device has not
@@ -1360,18 +1366,18 @@
X sleep_on_timeout(&scsi_id->sbp2_login_wait, 10*HZ);
X restore_flags(flags);
X
- SBP2_DEBUG("sbp2: sbp2_login_device: initial check");
+ SBP2_DEBUG("sbp2_login_device: initial check");
X
X /*
X * Match status to the login orb. If they do not match, it's
X * probably because the login timed-out.
X */
X if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
- SBP2_ERR("sbp2: Error logging into SBP-2 device - login timed-out");
+ SBP2_ERR("Error logging into SBP-2 device - login timed-out");
X return(-EIO);
X }
X
- SBP2_DEBUG("sbp2: sbp2_login_device: second check");
+ SBP2_DEBUG("sbp2_login_device: second check");
X
X /*
X * Check status
@@ -1380,7 +1386,7 @@
X STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
X STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
X
- SBP2_ERR("sbp2: Error logging into SBP-2 device - login failed");
+ SBP2_ERR("Error logging into SBP-2 device - login failed");
X return(-EIO);
X }
X
@@ -1393,9 +1399,9 @@
X /*
X * Grab our command block agent address from the login response.
X */
- SBP2_DEBUG("sbp2: command_block_agent_hi = %x",
+ SBP2_DEBUG("command_block_agent_hi = %x",
X (unsigned int)scsi_id->login_response->command_block_agent_hi);
- SBP2_DEBUG("sbp2: command_block_agent_lo = %x",
+ SBP2_DEBUG("command_block_agent_lo = %x",
X (unsigned int)scsi_id->login_response->command_block_agent_lo);
X
X scsi_id->sbp2_command_block_agent_addr =
@@ -1403,7 +1409,7 @@
X scsi_id->sbp2_command_block_agent_addr |= ((u64)scsi_id->login_response->command_block_agent_lo);
X scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL;
X
- SBP2_INFO("sbp2: Logged into SBP-2 device");
+ SBP2_INFO("Logged into SBP-2 device");
X
X return(0);
X
@@ -1417,7 +1423,7 @@
X {
X quadlet_t data[2];
X
- SBP2_DEBUG("sbp2: sbp2_logout_device");
+ SBP2_DEBUG("sbp2_logout_device");
X
X /*
X * Set-up logout ORB
@@ -1455,7 +1461,7 @@
X /* Wait for device to logout...1 second. */
X sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
X
- SBP2_INFO("sbp2: Logged out of SBP-2 device");
+ SBP2_INFO("Logged out of SBP-2 device");
X
X return(0);
X
@@ -1470,7 +1476,7 @@
X quadlet_t data[2];


X unsigned long flags;
X

- SBP2_DEBUG("sbp2: sbp2_reconnect_device");
+ SBP2_DEBUG("sbp2_reconnect_device");
X
X /*
X * Set-up reconnect ORB
@@ -1527,7 +1533,7 @@
X * probably because the reconnect timed-out.
X */
X if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
- SBP2_ERR("sbp2: Error reconnecting to SBP-2 device - reconnect timed-out");
+ SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
X return(-EIO);
X }
X
@@ -1538,11 +1544,11 @@
X STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
X STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
X
- SBP2_ERR("sbp2: Error reconnecting to SBP-2 device - reconnect failed");
+ SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed");
X return(-EIO);
X }
X
- SBP2_INFO("sbp2: Reconnected to SBP-2 device");
+ SBP2_INFO("Reconnected to SBP-2 device");
X
X return(0);
X
@@ -1556,7 +1562,7 @@
X {
X quadlet_t data;
X
- SBP2_DEBUG("sbp2: sbp2_set_busy_timeout");
+ SBP2_DEBUG("sbp2_set_busy_timeout");
X
X /*
X * Ok, let's write to the target's busy timeout register
@@ -1564,7 +1570,7 @@
X data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE);
X
X if (hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
- SBP2_ERR("sbp2: sbp2_set_busy_timeout error");
+ SBP2_ERR("sbp2_set_busy_timeout error");
X }
X
X return(0);
@@ -1580,7 +1586,7 @@
X struct unit_directory *ud;
X int i;
X
- SBP2_DEBUG("sbp2: sbp2_parse_unit_directory");
+ SBP2_DEBUG("sbp2_parse_unit_directory");
X
X ud = scsi_id->ud;
X
@@ -1593,21 +1599,21 @@
X CONFIG_ROM_INITIAL_MEMORY_SPACE +
X (ud->arb_values[i] << 2);
X
- SBP2_DEBUG("sbp2: sbp2_management_agent_addr = %x",
+ SBP2_DEBUG("sbp2_management_agent_addr = %x",
X (unsigned int) scsi_id->sbp2_management_agent_addr);
X break;
X
X case SBP2_COMMAND_SET_SPEC_ID_KEY:
X /* Command spec organization */
X scsi_id->sbp2_command_set_spec_id = ud->arb_values[i];
- SBP2_DEBUG("sbp2: sbp2_command_set_spec_id = %x",
+ SBP2_DEBUG("sbp2_command_set_spec_id = %x",
X (unsigned int) scsi_id->sbp2_command_set_spec_id);
X break;
X
X case SBP2_COMMAND_SET_KEY:
X /* Command set used by sbp2 device */
X scsi_id->sbp2_command_set = ud->arb_values[i];
- SBP2_DEBUG("sbp2: sbp2_command_set = %x",
+ SBP2_DEBUG("sbp2_command_set = %x",
X (unsigned int) scsi_id->sbp2_command_set);
X break;
X
@@ -1617,7 +1623,7 @@
X * that I'm not yet paying attention to)
X */
X scsi_id->sbp2_unit_characteristics = ud->arb_values[i];
- SBP2_DEBUG("sbp2: sbp2_unit_characteristics = %x",
+ SBP2_DEBUG("sbp2_unit_characteristics = %x",
X (unsigned int) scsi_id->sbp2_unit_characteristics);
X break;
X
@@ -1627,7 +1633,7 @@
X * detemining type of sbp2 device)
X */
X scsi_id->sbp2_device_type_and_lun = ud->arb_values[i];
- SBP2_DEBUG("sbp2: sbp2_device_type_and_lun = %x",
+ SBP2_DEBUG("sbp2_device_type_and_lun = %x",
X (unsigned int) scsi_id->sbp2_device_type_and_lun);
X break;
X
@@ -1642,7 +1648,7 @@
X scsi_id->sbp2_firmware_revision = ud->arb_values[i];
X if (scsi_id->sbp2_firmware_revision ==
X SBP2_128KB_BROKEN_FIRMWARE) {
- SBP2_WARN("sbp2: warning: Bridge chipset supports 128KB max transfer size");
+ SBP2_WARN("warning: Bridge chipset supports 128KB max transfer size");
X }
X break;
X
@@ -1654,39 +1660,36 @@
X
X /*
X * This function is called in order to determine the max speed and packet
- * size we can use in our ORBs.
+ * size we can use in our ORBs. Note, that we (the driver and host) only
+ * initiate the transaction. The SBP-2 device actually transfers the data
+ * (by reading from the DMA area we tell it). This means that the SBP-2
+ * device decides the actual maximum data it can transfer. We just tell it
+ * the speed that it needs to use, and the max_rec the host supports, and
+ * it takes care of the rest.
X */
X static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
X {
- u8 speed_code;
- unsigned int max_rec;
-
- SBP2_DEBUG("sbp2: sbp2_max_speed_and_size");
+ SBP2_DEBUG("sbp2_max_speed_and_size");
X
- speed_code = scsi_id->ne->busopt.lnkspd;
- max_rec = scsi_id->ne->busopt.max_rec;
-
- /* Bump down our speed if there is a module parameter forcing us slower */
- if (speed_code > max_speed) {
- speed_code = max_speed;
- SBP2_ERR("sbp2: Reducing SBP-2 max speed allowed (%x)", max_speed);
- }
-
- /* Support the devices max_rec and max speed. We choose a setting
- * that fits both values, since they may differ. */
- if (speed_code >= SPEED_400 && max_rec >= MAX_REC_S400) {
- HPSB_INFO("sbp2: SBP-2 device max speed S400 and payload 2KB");
- scsi_id->speed_code = SPEED_400;
- scsi_id->max_payload_size = MAX_PAYLOAD_S400;
- } else if (speed_code >= SPEED_200 && max_rec >= MAX_REC_S200) {
- HPSB_INFO("sbp2: SBP-2 device max speed S200 and payload 1KB");
- scsi_id->speed_code = SPEED_200;
- scsi_id->max_payload_size = MAX_PAYLOAD_S200;
- } else {
- HPSB_INFO("sbp2: SBP-2 device max speed S100 and payload 512 bytes");
- scsi_id->speed_code = SPEED_100;
- scsi_id->max_payload_size = MAX_PAYLOAD_S100;
- }
+ /* Initial setting comes from the hosts speed map */
+ scsi_id->speed_code = hi->host->speed_map[(hi->host->node_id & NODE_MASK) * 64
+ + (scsi_id->ne->nodeid & NODE_MASK)];
+
+ /* Bump down our speed if the user requested it */
+ if (scsi_id->speed_code > max_speed) {
+ scsi_id->speed_code = max_speed;
+ SBP2_ERR("Forcing SBP-2 max speed down to %s",
+ hpsb_speedto_str[scsi_id->speed_code]);
+ }
+
+ /* Payload size is the lesser of what our speed supports and what
+ * our host supports. */
+ scsi_id->max_payload_size = min(sbp2_speedto_maxrec[scsi_id->speed_code],
+ (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
+
+ SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [0x%02x/%u]",
+ NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code],
+ scsi_id->max_payload_size, 1 << ((u32)scsi_id->max_payload_size + 2));
X
X return(0);
X }
@@ -1698,7 +1701,7 @@
X {
X struct sbp2_request_packet *agent_reset_request_packet;
X
- SBP2_DEBUG("sbp2: sbp2_agent_reset");
+ SBP2_DEBUG("sbp2_agent_reset");
X
X /*
X * Ok, let's write to the target's management agent register
@@ -1710,12 +1713,12 @@
X 0, ntohl(SBP2_AGENT_RESET_DATA));
X
X if (!agent_reset_request_packet) {
- SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+ SBP2_ERR("sbp2util_allocate_write_request_packet failed");
X return(-EIO);
X }
X
X if (!hpsb_send_packet(agent_reset_request_packet->packet)) {
- SBP2_ERR("sbp2: hpsb_send_packet failed");
+ SBP2_ERR("hpsb_send_packet failed");
X sbp2util_free_request_packet(agent_reset_request_packet);
X return(-EIO);
X }
@@ -1774,7 +1777,7 @@
X */
X if (sbp2scsi_direction_table[*scsi_cmd] == ORB_DIRECTION_NO_DATA_TRANSFER) {
X
- SBP2_DEBUG("sbp2: No data transfer");
+ SBP2_DEBUG("No data transfer");
X
X /*
X * Handle no data transfer
@@ -1785,14 +1788,14 @@
X
X } else if (scsi_use_sg) {
X
- SBP2_DEBUG("sbp2: Use scatter/gather");
+ SBP2_DEBUG("Use scatter/gather");
X
X /*
X * Special case if only one element (and less than 64KB in size)
X */
X if ((scsi_use_sg == 1) && (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
X
- SBP2_DEBUG("sbp2: Only one s/g element");
+ SBP2_DEBUG("Only one s/g element");
X command->dma_dir = dma_dir;
X command->dma_size = sgpnt[0].length;
X command->cmd_dma = pci_map_single (hi->host->pdev, sgpnt[0].address,
@@ -1856,7 +1859,7 @@
X
X } else {
X
- SBP2_DEBUG("sbp2: No scatter/gather");
+ SBP2_DEBUG("No scatter/gather");
X
X command->dma_dir = dma_dir;
X command->dma_size = scsi_request_bufflen;
@@ -1977,7 +1980,7 @@
X SBP2_ORB_POINTER_OFFSET, 8, 0);
X
X if (!command_request_packet) {
- SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+ SBP2_ERR("sbp2util_allocate_write_request_packet failed");
X return(-EIO);
X }
X
@@ -1988,7 +1991,7 @@
X SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);
X
X if (!hpsb_send_packet(command_request_packet->packet)) {
- SBP2_ERR("sbp2: hpsb_send_packet failed");
+ SBP2_ERR("hpsb_send_packet failed");
X sbp2util_free_request_packet(command_request_packet);
X return(-EIO);
X }
@@ -2024,14 +2027,14 @@
X 0, cpu_to_be32(command->command_orb_dma));
X
X if (!command_request_packet) {
- SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+ SBP2_ERR("sbp2util_allocate_write_request_packet failed");
X return(-EIO);
X }
X
X SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);
X
X if (!hpsb_send_packet(command_request_packet->packet)) {
- SBP2_ERR("sbp2: hpsb_send_packet failed");
+ SBP2_ERR("hpsb_send_packet failed");
X sbp2util_free_request_packet(command_request_packet);
X return(-EIO);
X }
@@ -2053,10 +2056,10 @@
X u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
X struct sbp2_command_info *command;
X
- SBP2_DEBUG("sbp2: sbp2_send_command");
- SBP2_DEBUG("sbp2: SCSI command = %02x", *cmd);
- SBP2_DEBUG("sbp2: SCSI transfer size = %x", SCpnt->request_bufflen);
- SBP2_DEBUG("sbp2: SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
+ SBP2_DEBUG("sbp2_send_command");
+ SBP2_DEBUG("SCSI command = %02x", *cmd);
+ SBP2_DEBUG("SCSI transfer size = %x", SCpnt->request_bufflen);
+ SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
X
X /*
X * Check for broken devices that can't handle greater than 128K
@@ -2236,13 +2239,13 @@
X {
X unchar new_cmd[16];
X
- SBP2_DEBUG("sbp2: sbp2_check_sbp2_command");
+ SBP2_DEBUG("sbp2_check_sbp2_command");
X
X switch (*cmd) {
X
X case READ_6:
X
- SBP2_DEBUG("sbp2: Convert READ_6 to READ_10");
+ SBP2_DEBUG("Convert READ_6 to READ_10");
X
X /*
X * Need to turn read_6 into read_10
@@ -2264,7 +2267,7 @@
X
X case WRITE_6:
X
- SBP2_DEBUG("sbp2: Convert WRITE_6 to WRITE_10");
+ SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
X
X /*
X * Need to turn write_6 into write_10
@@ -2286,7 +2289,7 @@
X
X case MODE_SENSE:
X
- SBP2_DEBUG("sbp2: Convert MODE_SENSE_6 to MOSE_SENSE_10");
+ SBP2_DEBUG("Convert MODE_SENSE_6 to MOSE_SENSE_10");
X
X /*
X * Need to turn mode_sense_6 into mode_sense_10
@@ -2324,7 +2327,7 @@
X */
X static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data)
X {
- SBP2_DEBUG("sbp2: sbp2_status_to_sense_data");
+ SBP2_DEBUG("sbp2_status_to_sense_data");
X
X /*
X * Ok, it's pretty ugly... ;-)
@@ -2360,19 +2363,19 @@
X u8 *scsi_buf = SCpnt->request_buffer;
X u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
X
- SBP2_DEBUG("sbp2: sbp2_check_sbp2_response");
+ SBP2_DEBUG("sbp2_check_sbp2_response");
X
X switch (SCpnt->cmnd[0]) {
X
X case INQUIRY:
X
- SBP2_DEBUG("sbp2: Check Inquiry data");
+ SBP2_DEBUG("Check Inquiry data");
X
X /*
X * Check for Simple Direct Access Device and change it to TYPE_DISK
X */
X if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
- SBP2_DEBUG("sbp2: Changing TYPE_SDAD to TYPE_DISK");
+ SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
X scsi_buf[0] &= 0xe0;
X }
X
@@ -2390,7 +2393,7 @@
X (device_type == TYPE_SDAD) ||
X (device_type == TYPE_ROM)) {
X
- SBP2_DEBUG("sbp2: Modify mode sense response (10 byte version)");
+ SBP2_DEBUG("Modify mode sense response (10 byte version)");
X
X scsi_buf[0] = scsi_buf[1]; /* Mode data length */
X scsi_buf[1] = scsi_buf[2]; /* Medium type */
@@ -2428,10 +2431,10 @@
X u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
X struct sbp2_command_info *command;
X
- SBP2_DEBUG("sbp2: sbp2_handle_status_write");
+ SBP2_DEBUG("sbp2_handle_status_write");
X
X if (!host) {
- SBP2_ERR("sbp2: host is NULL - this is bad!");
+ SBP2_ERR("host is NULL - this is bad!");
X return(RCODE_ADDRESS_ERROR);
X }
X
@@ -2440,7 +2443,7 @@
X sbp2_spin_unlock(&sbp2_host_info_lock, flags);
X
X if (!hi) {
- SBP2_ERR("sbp2: host info is NULL - this is bad!");
+ SBP2_ERR("host info is NULL - this is bad!");
X return(RCODE_ADDRESS_ERROR);
X }
X
@@ -2453,14 +2456,14 @@
X if (hi->scsi_id[i]) {
X if ((hi->scsi_id[i]->ne->nodeid & NODE_MASK) == (nodeid & NODE_MASK)) {
X scsi_id = hi->scsi_id[i];
- SBP2_DEBUG("sbp2: SBP-2 status write from node %x", scsi_id->ne->nodeid);
+ SBP2_DEBUG("SBP-2 status write from node %x", scsi_id->ne->nodeid);
X break;
X }
X }
X }
X
X if (!scsi_id) {
- SBP2_ERR("sbp2: scsi_id is NULL - device is gone?");
+ SBP2_ERR("scsi_id is NULL - device is gone?");
X sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
X return(RCODE_ADDRESS_ERROR);
X }
@@ -2481,7 +2484,7 @@
X command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo);
X if (command) {
X
- SBP2_DEBUG("sbp2: Found status for command ORB");
+ SBP2_DEBUG("Found status for command ORB");
X
X SBP2_ORB_DEBUG("matched command orb %p", &command->command_orb);
X outstanding_orb_decr;
@@ -2499,7 +2502,7 @@
X */
X if (STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
X
- SBP2_DEBUG("sbp2: CHECK CONDITION");
+ SBP2_DEBUG("CHECK CONDITION");
X
X /*
X * Translate SBP-2 status to SCSI sense data
@@ -2518,7 +2521,7 @@
X /*
X * Complete the SCSI command
X */
- SBP2_DEBUG("sbp2: Completing SCSI command");
+ SBP2_DEBUG("Completing SCSI command");
X sbp2scsi_complete_command(hi, scsi_id, scsi_status, SCpnt, command->Current_done);
X SBP2_ORB_DEBUG("command orb completed");
X }
@@ -2555,7 +2558,7 @@
X struct scsi_id_instance_data *scsi_id = NULL;


X unsigned long flags;
X

- SBP2_DEBUG("sbp2: sbp2scsi_queuecommand");
+ SBP2_DEBUG("sbp2scsi_queuecommand");
X
X /*
X * Pull our host info and scsi id instance data from the scsi command
@@ -2563,7 +2566,7 @@
X hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
X
X if (!hi) {
- SBP2_ERR("sbp2: sbp2scsi_host_info is NULL - this is bad!");
+ SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
X SCpnt->result = DID_NO_CONNECT << 16;
X done (SCpnt);
X return(0);
@@ -2596,7 +2599,7 @@
X * (autorequest sense)
X */
X if (SCpnt->cmnd[0] == REQUEST_SENSE) {
- SBP2_DEBUG("sbp2: REQUEST_SENSE");
+ SBP2_DEBUG("REQUEST_SENSE");
X memcpy(SCpnt->request_buffer, SCpnt->sense_buffer, SCpnt->request_bufflen);
X memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
X sbp2scsi_complete_command(hi, scsi_id, SBP2_SCSI_STATUS_GOOD, SCpnt, done);
@@ -2608,7 +2611,7 @@
X * busy (to be queued later)
X */
X if (!hpsb_node_entry_valid(scsi_id->ne)) {
- SBP2_ERR("sbp2: Bus reset in progress - rejecting command");
+ SBP2_ERR("Bus reset in progress - rejecting command");
X SCpnt->result = DID_BUS_BUSY << 16;
X done (SCpnt);
X return(0);
@@ -2619,7 +2622,7 @@
X */
X sbp2_spin_lock(&hi->sbp2_command_lock, flags);
X if (sbp2_send_command(hi, scsi_id, SCpnt, done)) {
- SBP2_ERR("sbp2: Error sending SCSI command");
+ SBP2_ERR("Error sending SCSI command");
X sbp2scsi_complete_command(hi, scsi_id, SBP2_SCSI_STATUS_SELECTION_TIMEOUT, SCpnt, done);
X }
X sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
@@ -2638,10 +2641,10 @@
X struct list_head *lh;
X struct sbp2_command_info *command;
X
- SBP2_DEBUG("sbp2: sbp2_complete_all_commands");
+ SBP2_DEBUG("sbp2_complete_all_commands");
X
X while (!list_empty(&scsi_id->sbp2_command_orb_inuse)) {
- SBP2_DEBUG("sbp2: Found pending command to complete");
+ SBP2_DEBUG("Found pending command to complete");
X lh = scsi_id->sbp2_command_orb_inuse.next;
X command = list_entry(lh, struct sbp2_command_info, list);
X sbp2util_mark_command_completed(scsi_id, command);
@@ -2661,13 +2664,13 @@
X static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, u32 scsi_status,
X Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
X {
- SBP2_DEBUG("sbp2: sbp2scsi_complete_command");
+ SBP2_DEBUG("sbp2scsi_complete_command");
X
X /*
X * Sanity
X */
X if (!SCpnt) {
- SBP2_ERR("sbp2: SCpnt is NULL");
+ SBP2_ERR("SCpnt is NULL");
X return;
X }
X
@@ -2677,7 +2680,7 @@
X * bus reset.
X */
X if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
- SBP2_ERR("sbp2: Bus reset in progress - retry command later");
+ SBP2_ERR("Bus reset in progress - retry command later");
X return;
X }
X
@@ -2690,12 +2693,12 @@
X break;
X
X case SBP2_SCSI_STATUS_BUSY:
- SBP2_ERR("sbp2: SBP2_SCSI_STATUS_BUSY");
+ SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
X SCpnt->result = DID_BUS_BUSY << 16;
X break;
X
X case SBP2_SCSI_STATUS_CHECK_CONDITION:
- SBP2_DEBUG("sbp2: SBP2_SCSI_STATUS_CHECK_CONDITION");
+ SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
X SCpnt->result = CHECK_CONDITION << 1;
X
X /*
@@ -2706,19 +2709,19 @@
X break;
X
X case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
- SBP2_ERR("sbp2: SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
+ SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
X SCpnt->result = DID_NO_CONNECT << 16;
X break;
X
X case SBP2_SCSI_STATUS_CONDITION_MET:
X case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
X case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
- SBP2_ERR("sbp2: Bad SCSI status = %x", scsi_status);
+ SBP2_ERR("Bad SCSI status = %x", scsi_status);
X SCpnt->result = DID_ERROR << 16;


X break;
X
X default:

- SBP2_ERR("sbp2: Unsupported SCSI status = %x", scsi_status);
+ SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
X SCpnt->result = DID_ERROR << 16;
X }
X
@@ -2736,7 +2739,7 @@
X * can mount the device rw).
X */
X if (mode_sense_hack && SCpnt->result != DID_OK && SCpnt->cmnd[0] == MODE_SENSE) {
- SBP2_INFO("sbp2: Returning success to mode sense command");
+ SBP2_INFO("Returning success to mode sense command");
X SCpnt->result = DID_OK;
X SCpnt->sense_buffer[0] = 0;
X memset (SCpnt->request_buffer, 0, 8);
@@ -2747,7 +2750,7 @@
X * the command as busy so that it will get retried.
X */
X if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
- SBP2_ERR("sbp2: Completing command with busy (bus reset)");
+ SBP2_ERR("Completing command with busy (bus reset)");
X SCpnt->result = DID_BUS_BUSY << 16;
X }
X
@@ -2757,7 +2760,7 @@
X * or hot-plug...
X */
X if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) {
- SBP2_INFO("sbp2: UNIT ATTENTION - return busy");
+ SBP2_INFO("UNIT ATTENTION - return busy");
X SCpnt->result = DID_BUS_BUSY << 16;
X }
X
@@ -2780,7 +2783,7 @@
X struct sbp2_command_info *command;


X unsigned long flags;
X

- SBP2_ERR("sbp2: aborting sbp2 command");
+ SBP2_ERR("aborting sbp2 command");
X
X if (scsi_id) {
X
@@ -2793,7 +2796,7 @@
X do {
X command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
X if (command) {
- SBP2_DEBUG("sbp2: Found command to abort");
+ SBP2_DEBUG("Found command to abort");
X sbp2util_mark_command_completed(scsi_id, command);
X if (command->Current_SCpnt && !command->linked) {
X void (*done)(Scsi_Cmnd *) = command->Current_done;
@@ -2821,10 +2824,10 @@
X {
X struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
X
- SBP2_ERR("sbp2: reset requested");
+ SBP2_ERR("reset requested");
X
X if (hi) {
- SBP2_ERR("sbp2: generating IEEE-1394 bus reset");
+ SBP2_ERR("Generating IEEE-1394 bus reset");
X hpsb_reset_bus(hi->host, LONG_RESET);
X }
X
@@ -2838,7 +2841,7 @@
X {
X int heads, sectors, cylinders;
X
- SBP2_DEBUG("sbp2: request for bios parameters");
+ SBP2_DEBUG("Request for bios parameters");
X
X heads = 64;
X sectors = 32;
@@ -2862,7 +2865,7 @@
X */
X void sbp2scsi_setup( char *str, int *ints)
X {
- SBP2_DEBUG("sbp2: sbp2scsi_setup");
+ SBP2_DEBUG("sbp2scsi_setup");
X return;
X }
X
@@ -2871,7 +2874,7 @@
X */
X static int sbp2scsi_detect (Scsi_Host_Template *tpnt)
X {
- SBP2_DEBUG("sbp2: sbp2scsi_detect");
+ SBP2_DEBUG("sbp2scsi_detect");
X
X global_scsi_tpnt = tpnt;
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,26)
@@ -2881,7 +2884,7 @@
X * Module load option for force one command at a time
X */
X if (serialize_io) {
- SBP2_ERR("sbp2: Driver forced to serialize I/O (serialize_io = 1)");
+ SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
X global_scsi_tpnt->can_queue = 1;
X global_scsi_tpnt->cmd_per_lun = 1;
X }
@@ -2890,19 +2893,19 @@
X * Module load option to limit max size of requests from the scsi drivers
X */
X if (no_large_packets) {
- SBP2_ERR("sbp2: Driver forced to limit max transfer size (no_large_packets = 1)");
+ SBP2_ERR("Driver forced to limit max transfer size (no_large_packets = 1)");
X global_scsi_tpnt->sg_tablesize = 0x1f;
X global_scsi_tpnt->use_clustering = DISABLE_CLUSTERING;
X }
X
X if (mode_sense_hack) {
- SBP2_ERR("sbp2: Mode sense emulation enabled (mode_sense_hack = 1)");
+ SBP2_ERR("Mode sense emulation enabled (mode_sense_hack = 1)");
X }
X
X sbp2_init();
X
X if (!sbp2_host_count) {
- SBP2_ERR("sbp2: Please load the lower level IEEE-1394 driver (e.g. ohci1394) before sbp2...");
+ SBP2_ERR("Please load the lower level IEEE-1394 driver (e.g. ohci1394) before sbp2...");
X sbp2_cleanup();
X }
X
@@ -2921,8 +2924,8 @@
X {
X struct Scsi_Host *shpnt = NULL;
X
- SBP2_DEBUG("sbp2: sbp2scsi_register_scsi_host");
- SBP2_DEBUG("sbp2: sbp2scsi_host_info = %p", hi);
+ SBP2_DEBUG("sbp2scsi_register_scsi_host");
+ SBP2_DEBUG("sbp2scsi_host_info = %p", hi);
X
X /*
X * Let's register with the scsi stack
@@ -2946,7 +2949,7 @@
X /* Called when our module is released */
X static int sbp2scsi_release(struct Scsi_Host *host)
X {
- SBP2_DEBUG("sbp2: sbp2scsi_release");
+ SBP2_DEBUG("sbp2scsi_release");
X sbp2_cleanup();
X return(0);
X }
@@ -2960,6 +2963,7 @@
X MODULE_AUTHOR("James Goodwin <jam...@filanet.com>");
X MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
X MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
+MODULE_LICENSE("GPL");
X
X /* SCSI host template */
X static Scsi_Host_Template driver_template = {
diff -u --recursive --new-file v2.4.12/linux/drivers/ieee1394/sbp2.h linux/drivers/ieee1394/sbp2.h
--- v2.4.12/linux/drivers/ieee1394/sbp2.h Tue Oct 9 17:06:51 2001
+++ linux/drivers/ieee1394/sbp2.h Wed Oct 17 14:19:20 2001
@@ -36,16 +36,6 @@
X #define ORB_DIRECTION_READ_FROM_MEDIA 0x1
X #define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
X
-/* 2^(MAX_PAYLOAD+1) = Maximum data transfer length */
-#define MAX_PAYLOAD_S100 0x7
-#define MAX_PAYLOAD_S200 0x8
-#define MAX_PAYLOAD_S400 0x9
-
-/* Max rec matches node_entry values */
-#define MAX_REC_S100 512
-#define MAX_REC_S200 1024
-#define MAX_REC_S400 2048
-
X #define ORB_SET_NOTIFY(value) ((value & 0x1) << 31)
X #define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29)
X #define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16)
@@ -268,6 +258,9 @@
X * DOU = OUT data direction
X * DNO = No data transfer
X * DUN = Unknown data direction
+ *
+ * Opcode 0xec (Teac specific "opc execute") possibly should be DNO,
+ * but we'll change it when somebody reports a problem with this.
X */
X #define DIN ORB_DIRECTION_READ_FROM_MEDIA
X #define DOU ORB_DIRECTION_WRITE_TO_MEDIA
@@ -280,7 +273,7 @@
X DIN,DUN,DIN,DIN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
X DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU,
X DOU,DOU,DIN,DIN,DIN,DNO,DIN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DNO,DUN,
- DUN,DIN,DIN,DNO,DOU,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
+ DUN,DIN,DIN,DNO,DNO,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
X DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
X DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
X DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
diff -u --recursive --new-file v2.4.12/linux/drivers/input/keybdev.c linux/drivers/input/keybdev.c
--- v2.4.12/linux/drivers/input/keybdev.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/input/keybdev.c Thu Oct 11 09:14:32 2001
@@ -246,3 +246,4 @@
X MODULE_AUTHOR("Vojtech Pavlik <voj...@suse.cz>");
X MODULE_DESCRIPTION("Input driver to keyboard driver binding");
X MODULE_PARM(jp_kbd_109, "i");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.4.12/linux/drivers/macintosh/macserial.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/macintosh/macserial.c Mon Oct 15 13:43:24 2001
@@ -2730,6 +2730,8 @@
X
X module_init(macserial_init);
X module_exit(macserial_cleanup);
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
X
X #if 0
X /*
diff -u --recursive --new-file v2.4.12/linux/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c
--- v2.4.12/linux/drivers/macintosh/nvram.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/macintosh/nvram.c Mon Oct 15 13:43:24 2001
@@ -124,3 +124,4 @@
X
X module_init(nvram_init);
X module_exit(nvram_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/macintosh/rtc.c linux/drivers/macintosh/rtc.c
--- v2.4.12/linux/drivers/macintosh/rtc.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/macintosh/rtc.c Mon Oct 15 13:43:24 2001


@@ -146,3 +146,4 @@
X

X module_init(rtc_init);
X module_exit(rtc_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/md/lvm.c linux/drivers/md/lvm.c
--- v2.4.12/linux/drivers/md/lvm.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/md/lvm.c Mon Oct 15 13:27:52 2001
@@ -877,7 +877,7 @@
X /* return device size */
X P_IOCTL("%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
X lvm_name, lv_ptr->lv_size);
- if (put_user(lv_ptr->lv_size, (long *)arg))
+ if (put_user(lv_ptr->lv_size, (unsigned long *)arg))


X return -EFAULT;
X break;

X
diff -u --recursive --new-file v2.4.12/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.12/linux/drivers/md/md.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/md/md.c Wed Oct 17 14:21:00 2001
@@ -542,8 +542,10 @@
X goto abort;
X }
X
- if (calc_sb_csum(sb) != sb->sb_csum)
+ if (calc_sb_csum(sb) != sb->sb_csum) {
X printk(BAD_CSUM, partition_name(rdev->dev));
+ goto abort;
+ }
X ret = 0;
X abort:
X return ret;
@@ -2609,7 +2611,7 @@
X goto abort;
X }
X err = md_put_user(md_hd_struct[minor].nr_sects,


- (long *) arg);
+ (unsigned long *) arg);

X goto done;
X
X case BLKGETSIZE64: /* Return device size */
diff -u --recursive --new-file v2.4.12/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.12/linux/drivers/md/raid1.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/md/raid1.c Wed Oct 17 14:21:00 2001


@@ -1690,7 +1690,8 @@
X }

X }
X
- if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+ if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN)) &&
+ (conf->working_disks > 1)) {
X const char * name = "raid1syncd";
X
X conf->resync_thread = md_register_thread(raid1syncd, conf,name);
diff -u --recursive --new-file v2.4.12/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.12/linux/drivers/md/raid5.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/md/raid5.c Wed Oct 17 14:21:00 2001
@@ -487,22 +487,24 @@
X PRINTK("raid5_error called\n");
X
X 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);
+ if (disk->dev == dev) {
+ if (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);
+ }
X return 0;
X }
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bttv-cards.c linux/drivers/media/video/bttv-cards.c
--- v2.4.12/linux/drivers/media/video/bttv-cards.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/bttv-cards.c Wed Oct 17 14:19:20 2001
@@ -40,6 +40,8 @@
X
X /* fwd decl */
X static void hauppauge_eeprom(struct bttv *btv);
+static void avermedia_eeprom(struct bttv *btv);
+
X static void init_PXC200(struct bttv *btv);
X #if 0
X static void init_tea5757(struct bttv *btv);
@@ -52,6 +54,7 @@
X static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
X static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
X static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
+static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
X
X /* config variables */
X static int triton1=0;
@@ -71,6 +74,10 @@
X
X /* insmod options */
X MODULE_PARM(triton1,"i");
+MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
+ "[enable bug compatibility for triton1 + others]");
+MODULE_PARM(vsfx,"i");
+MODULE_PARM_DESC(vsfx,"set VSFX pci config bit [yet another chipset flaw workaround]");
X MODULE_PARM(no_overlay,"i");
X MODULE_PARM(card,"1-4i");
X MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
@@ -83,7 +90,6 @@
X MODULE_PARM(gpiomask,"i");
X MODULE_PARM(audioall,"i");
X MODULE_PARM(audiomux,"1-5i");
-MODULE_LICENSE("GPL");
X
X /* kernel args */
X #ifndef MODULE
@@ -127,13 +133,18 @@
X { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
X { 0x263610b4, BTTV_STB2, "STB TV PCI FM, P/N 6000704" },
X { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCV3/PCI" },
- { 0x405010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCV4/PCI" },
- { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
- { 0x3000121a, 0/* no entry yet */,"VoodooTV 200" },
+ { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCV4/PCI" },
X
- { 0x3000144f, BTTV_MAGICTVIEW063, "TView 99 (CPH063)" },
- { 0x3002144f, BTTV_MAGICTVIEW061, "Askey Magic TView" },
+ { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV" },
+ { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
+ { 0x001c11bd, BTTV_PINNACLE, "Pinnacle PCTV Sat" },
X
+ { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
+
+ { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
+ { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
+ { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
+
X { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
X { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" },
X { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
@@ -154,15 +165,15 @@
X { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
X { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
X { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
+ { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
X
X { 0x010115cb, BTTV_GMV1, "AG GMV1" },
- { 0x010114c7, 16 /* FIXME */, "Modular Technology PCTV" },
- { 0x18501851, BTTV_CHRONOS_VS2, "Chronos Video Shuttle II" },
- { 0x18511851, 0 /* FIXME */, "CyberMail AV" },
- { 0x18521852, BTTV_TYPHOON_TVIEW, "Typhoon TView TV/FM Tuner" },
+ { 0x010114c7, BTTV_MODTEC_205, "Modular Technology PCTV" },
+ { 0x18501851, BTTV_CHRONOS_VS2, "Flyvideo 98 (LR50)/ Chronos Video Shuttle II" },
+ { 0x18511851, BTTV_FLYVIDEO98EZ, "Flyvideo 98EZ (LR51)/ CyberMail AV" },
+ { 0x18521852, BTTV_TYPHOON_TVIEW, "Flyvideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
X { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
X { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV" },
X
X { 0, -1, NULL }
X };
@@ -173,7 +184,7 @@
X struct tvcard bttv_tvcards[] = {
X {
X /* ---- card 0x00 ---------------------------------- */
- name: " *** UNKNOWN *** ",
+ name: " *** UNKNOWN/GENERIC *** ",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
@@ -192,7 +203,7 @@
X needs_tvaudio: 1,
X tuner_type: -1,
X },{
- name: "Hauppauge old",
+ name: "Hauppauge (bt848)",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
@@ -265,7 +276,7 @@
X },{
X
X /* ---- card 0x08 ---------------------------------- */
- name: "Fly Video II",
+ name: "Fly Video II (Bt848)",
X video_inputs: 3,
X audio_inputs: 1,
X tuner: 0,
@@ -287,12 +298,12 @@
X needs_tvaudio: 1,
X tuner_type: -1,
X },{
- name: "Hauppauge new (bt878)",
+ name: "Hauppauge (bt878)",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
X svhs: 2,
- gpiomask: 7,
+ gpiomask: 0x0f, /* old: 7 */
X muxsel: { 2, 0, 1, 1},
X audiomux: { 0, 1, 2, 3, 4},
X needs_tvaudio: 1,
@@ -333,7 +344,7 @@
X audiomux: { 13, 14, 11, 7, 0, 0},
X needs_tvaudio: 1,
X pll: PLL_28,
- tuner_type: 5,
+ tuner_type: -1,
X },{
X name: "Aimslab VHX",
X video_inputs: 3,
@@ -452,14 +463,14 @@
X },{
X
X /* ---- card 0x18 ---------------------------------- */
- name: "Askey/Typhoon/Anubis Magic TView CPH051/061 (bt878)",
+ name: "[many vendors] CPH05X/06X (bt878)",
X video_inputs: 3,
X audio_inputs: 1,
X tuner: 0,
X svhs: 2,
X gpiomask: 0xe00,
X muxsel: { 2, 3, 1, 1},
- audiomux: {0x400, 0x400, 0x400, 0x400, 0},
+ audiomux: {0x400, 0x400, 0x400, 0x400, 0xc00},
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: -1,
@@ -528,9 +539,9 @@
X audio_inputs: 1,
X tuner: 0,
X svhs: 2,
- gpiomask: 0x8dfe00,
+ gpiomask: 0x1800, //0x8dfe00
X muxsel: {2, 3, 1, 1},
- audiomux: { 0, 0x8dff00, 0x8df700, 0x8de700, 0x8dff00, 0 },
+ audiomux: { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
X needs_tvaudio: 1,
X tuner_type: -1,
X },{
@@ -582,31 +593,32 @@
X tuner_type: -1,
X audio_hook: winfast2000_audio,
X },{
- name: "Chronos Video Shuttle II",
+ name: "Flyvideo 98 (LR50Q) / Chronos Video Shuttle II",
X video_inputs: 3,
X audio_inputs: 3,
X tuner: 0,
X svhs: 2,
X gpiomask: 0x1800,
X muxsel: { 2, 3, 1, 1},
- audiomux: { 0, 0, 0x1000, 0x1000, 0x0800},
+ audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800},
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: -1,
X },{
X
X /* ---- card 0x24 ---------------------------------- */
- name: "Typhoon TView TV/FM Tuner",
+ name: "Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner",
X video_inputs: 3,
X audio_inputs: 3,
X tuner: 0,
X svhs: 2,
X gpiomask: 0x1800,
X muxsel: { 2, 3, 1, 1},
- audiomux: { 0, 0x800, 0, 0, 0x1800, 0 },
+ audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: -1,
+ has_radio: 1,
X },{
X name: "PixelView PlayTV pro",
X video_inputs: 3,
@@ -620,14 +632,14 @@
X pll: PLL_28,
X tuner_type: -1,
X },{
- name: "TView99 CPH063",
+ name: "TView99 CPH06X",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
X svhs: 2,
X gpiomask: 0x551e00,
X muxsel: { 2, 3, 1, 0},
- audiomux: { 0x551400, 0x551200, 0, 0, 0, 0x551200 },
+ audiomux: { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: -1,
@@ -668,7 +680,8 @@
X audiomux: { 13, 4, 11, 7, 0, 0},
X needs_tvaudio: 1,
X pll: PLL_28,
- tuner_type: 5,
+ tuner_type: -1,
+ has_radio: 1,
X },{
X name: "ProVideo PV951", /* pic16c54 */
X video_inputs: 3,
@@ -742,6 +755,7 @@
X no_msp34xx: 1,
X pll: PLL_35,
X tuner_type: 1,
+ has_radio: 1,
X },{
X
X /* ---- card 0x30 ---------------------------------- */
@@ -770,7 +784,7 @@
X tuner_type: TUNER_ALPS_TSHC6_NTSC,
X audio_hook: gvbctv3pci_audio,
X },{
- name: "Prolink PV-BT878P+4E (PixelView PlayTV PAK)",
+ name: "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
@@ -810,7 +824,7 @@
X },{
X /* Claas Langbehn <cl...@bigfoot.com>,
X Sven Grothklags <sv...@upb.de> */
- name: "Typhoon TView RDS / FM Stereo",
+ name: "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
X video_inputs: 3,
X audio_inputs: 3,
X tuner: 0,
@@ -821,13 +835,14 @@
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: TUNER_PHILIPS_PAL_I,
+ has_radio: 1,
X },{
X /* Tim Röstermundt <ros...@uni-muenster.de>
X in de.comp.os.unix.linux.hardware:
X options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
X audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
X options tuner type=5 */
- name: "Lifetec LT 9415 TV",
+ name: "Lifetec LT 9415 TV (LR90 Rev.F)",
X video_inputs: 4,
X audio_inputs: 1,
X tuner: 0,
@@ -841,6 +856,7 @@
X pll: PLL_28,
X tuner_type: TUNER_PHILIPS_PAL,
X audio_hook: lt9415_audio,
+ has_radio: 1,
X },{
X /* Miguel Angel Alvarez <maa...@navegalia.com>
X old Easy TV BT848 version (model CPH031) */
@@ -866,7 +882,7 @@
X svhs: 2,
X gpiomask: 0x1800,
X muxsel: { 2, 3, 0, 1},
- audiomux: { 0, 0x800, 0, 0, 0x1800, 0 },
+ audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: 5,
@@ -893,7 +909,7 @@
X audio_inputs: 1,
X tuner: 0,
X svhs: 2,
- gpiomask: 0x0e00,
+ gpiomask: 0xe00,
X muxsel: { 2, 3, 1, 1},
X audiomux: { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
X needs_tvaudio: 1,
@@ -1005,7 +1021,93 @@
X needs_tvaudio: 1,
X pll: PLL_28,
X tuner_type: TUNER_PHILIPS_PAL,
-}};
+ has_radio: 1,
+},{
+ /* TANAKA Kei <peg0...@nifty.com> */
+ name: "GV-BCTV4/PCI",
+ video_inputs: 3,
+ audio_inputs: 1,
+ tuner: 0,
+ svhs: 2,
+ gpiomask: 0x010f00,
+ muxsel: {2, 3, 0, 0},
+ audiomux: {0x10000, 0, 0x10000, 0, 0, 0},
+ no_msp34xx: 1,
+ pll: PLL_28,
+ tuner_type: TUNER_SHARP_2U5JF5540_NTSC,
+ audio_hook: gvbctv3pci_audio,
+},{
+
+/* ---- card 0x44 ---------------------------------- */
+ name: "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
+ // try "insmod msp3400 simple=0" if you have
+ // sound problems with this card.
+ video_inputs: 4,
+ audio_inputs: 1,
+ tuner: 0,
+ svhs: -1,
+ gpiomask: 0x4f8a00,
+ // 0x100000: 1=MSP enabled (0=disable again)
+ // 0x010000: somehow influences tuner picture quality (?)
+ audiomux: {0x947fff, 0x987fff,0x947fff,0x947fff},
+ //tvtuner, radio, external,internal,mute,stereo
+ muxsel: { 2, 3 ,0 ,1}, /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
+ tuner_type: TUNER_MT2032,
+ pll: PLL_28,
+ has_radio: 1,
+},{
+ /* Philip Blundell <p...@nexus.co.uk> */
+ name: "Active Imaging AIMMS",
+ video_inputs: 1,
+ audio_inputs: 0,
+ tuner: -1,
+ tuner_type: -1,
+ pll: PLL_28,
+ muxsel: { 2 },
+ gpiomask: 0
+},{
+ /* Tomasz Pyra <hell...@sedez.iq.pl> */
+ name: "PV-BT878P+",
+ video_inputs: 3,
+ audio_inputs: 4,
+ tuner: 0,
+ svhs: 2,
+ gpiomask: 15,
+ muxsel: { 2, 3, 1, 1},
+ audiomux: { 0, 0, 11, 7, 13, 0},
+ needs_tvaudio: 1,
+ pll: PLL_28,
+ tuner_type: 25,
+},{
+ name: "Flyvideo 98EZ (capture only)",
+ video_inputs: 4,
+ audio_inputs: 0,
+ tuner: -1,
+ svhs: 2,
+ muxsel: { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
+ pll: PLL_28,
+ no_msp34xx: 1,
+},{
+
+/* ---- card 0x48 ---------------------------------- */
+ /* Dariusz Kowalewski <dar...@automex.pl> */
+ name: "Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
+ video_inputs: 3,
+ audio_inputs: 1,
+ tuner: 0,
+ svhs: 2,
+ gpiomask: 0x3f,
+ muxsel: { 2, 3, 0, 1 },
+ audiomux: { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
+ needs_tvaudio: 1,
+ no_msp34xx: 1,
+ no_tda9875: 1,
+ pll: PLL_28,
+ tuner_type: -1,
+ audio_hook: pvbt878p9b_audio,
+ has_radio: 1,
+}
+};
X
X const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
X
@@ -1036,17 +1138,17 @@
X
X if (type != -1) {
X /* found it */
- printk(KERN_INFO "bttv%d: subsystem: %04x:%04x => %s => card=%d\n",
- btv->nr, btv->cardid & 0xffff, btv->cardid >> 16,
- cards[type].name,cards[type].cardnr);
+ printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
+ "PCI subsystem ID is %04x:%04x\n",
+ btv->nr,cards[type].name,cards[type].cardnr,
+ btv->cardid & 0xffff, btv->cardid >> 16);
X btv->type = cards[type].cardnr;
X } else {
X /* 404 */
X printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
X btv->nr, btv->cardid&0xffff, btv->cardid>>16);
X printk(KERN_DEBUG "please mail id, board name and "
- "the correct card= insmod option to "
- "kra...@goldbach.in-berlin.de\n");
+ "the correct card= insmod option to kra...@bytesex.org\n");
X }
X }
X
@@ -1059,7 +1161,8 @@
X btv->id,
X (btv->id==848 && btv->revision==0x12) ? "A" : "",
X bttv_tvcards[btv->type].name);
- printk(KERN_INFO "bttv%d: model: %s [%s]\n",btv->nr,btv->video_dev.name,
+ printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr,
+ btv->video_dev.name,btv->type,
X (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards) ?
X "insmod option" : "autodetected");
X
@@ -1128,7 +1231,8 @@
X btv->type = BTTV_PINNACLEPRO;
X }
X if (bttv_verbose)
- printk("bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
+ printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d "
+ "radio=%s stereo=%s\n",
X btv->nr, id+1, btv->tuner_type,
X !btv->has_radio ? "no" :
X (btv->has_matchbox ? "matchbox" : "fmtuner"),
@@ -1148,6 +1252,11 @@
X hauppauge_eeprom(btv);
X }
X
+ if (btv->type == BTTV_AVERMEDIA98 || btv->type == BTTV_AVPHONE98) {
+ bttv_readee(btv,eeprom_data,0xa0);
+ avermedia_eeprom(btv);
+ }
+
X if (btv->type == BTTV_PXC200)
X init_PXC200(btv);
X
@@ -1166,7 +1275,13 @@
X printk("bttv%d: lifetec: tv mono/fm stereo card\n", btv->nr);
X else
X printk("bttv%d: lifetec: stereo(TDA9821) card\n",btv->nr);
- btv->has_radio=1;
+ }
+
+ if (btv->type == BTTV_MAGICTVIEW061) {
+ if(btv->cardid == 0x4002144f) {
+ btv->has_radio=1;
+ printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr);
+ }
X }
X
X /* pll configuration */
@@ -1210,6 +1325,9 @@
X if (btv->tuner_type != -1)
X bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
X
+ if (bttv_tvcards[btv->type].has_radio)
+ btv->has_radio=1;
+
X /* try to detect audio/fader chips */
X if (!bttv_tvcards[btv->type].no_msp34xx &&
X bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) {
@@ -1217,7 +1335,8 @@
X request_module("msp3400");
X }
X
- if (bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
+ if (!bttv_tvcards[btv->type].no_tda9875 &&
+ bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
X if (autoload)
X request_module("tda9875");
X }
@@ -1307,7 +1426,8 @@
X int blk2,tuner,radio,model;
X
X if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0)
- printk("bttv%d: Hauppauge eeprom: invalid\n",btv->nr);
+ printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n",
+ btv->nr);
X
X /* Block 2 starts after len+3 bytes header */
X blk2 = eeprom_data[1] + 3;
@@ -1323,24 +1443,83 @@
X btv->has_radio = 1;
X
X if (bttv_verbose)
- printk("bttv%d: Hauppauge eeprom: model=%d, tuner=%s (%d), radio=%s\n",
+ printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, "
+ "tuner=%s (%d), radio=%s\n",
X btv->nr, model, hauppauge_tuner[tuner].name,
X btv->tuner_type, radio ? "yes" : "no");
X }
X
-void __devinit bttv_hauppauge_boot_msp34xx(struct bttv *btv)
+// AVermedia specific stuff...
+// from bktr_card.c
+int tuner_0_table[] = {
+ TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL,
+ TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
+ TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
+ TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
+ TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL};
+/*
+int tuner_0_fm_table[] = {
+ PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL,
+ PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
+ PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
+ PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
+ PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
+*/
+
+int tuner_1_table[] = {
+ TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
+ TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
+ TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
+ TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM
+ TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
+
+static void __devinit avermedia_eeprom(struct bttv *btv)
X {
- /* reset/enable the MSP on some Hauppauge cards */
- /* Thanks to Kyösti Mälkki (kma...@cc.hut.fi)! */
- btaor(32, ~32, BT848_GPIO_OUT_EN);
- btaor(0, ~32, BT848_GPIO_DATA);
+ int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
+
+ tuner_make = (eeprom_data[0x41] & 0x7);
+ tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
+ tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
+
+ if (tuner_make == 0 || tuner_make == 2)
+ if(tuner_format <=9)
+ tuner = tuner_0_table[tuner_format];
+ if (tuner_make == 1)
+ if(tuner_format <=9)
+ tuner = tuner_1_table[tuner_format];
+
+ printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
+ btv->nr,eeprom_data[0x41],eeprom_data[0x42]);
+ if(tuner) {
+ btv->tuner_type=tuner;
+ printk("%d\n",tuner);
+ } else
+ printk("Unknown type\n");
+}
+
+
+
+/*
+ * reset/enable the MSP on some Hauppauge cards
+ * Thanks to Kyösti Mälkki (kma...@cc.hut.fi)!
+ *
+ * Hauppauge: pin 5
+ * Voodoo: pin 20
+ */
+void __devinit bttv_boot_msp34xx(struct bttv *btv, int pin)
+{
+ int mask = (1 << pin);
+
+ btaor(mask, ~mask, BT848_GPIO_OUT_EN);
+ btaor(0, ~mask, BT848_GPIO_DATA);
X udelay(2500);
- btaor(32, ~32, BT848_GPIO_DATA);
+ btaor(mask, ~mask, BT848_GPIO_DATA);
X if (bttv_gpio)
X bttv_gpio_tracking(btv,"msp34xx");
X
X if (bttv_verbose)
- printk("bttv%d: Hauppauge msp34xx: reset line init\n",btv->nr);
+ printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line "
+ "init [%d]\n", btv->nr, pin);
X }
X
X
@@ -1352,9 +1531,9 @@
X
X static void __devinit init_PXC200(struct bttv *btv)
X {
- static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x00 };
+ static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x00 };
X int i,tmp;
X
X /* Initialise GPIO-connevted stuff */
@@ -1465,7 +1644,7 @@
X BUS_IN(btv->mbox_data) && time_before(jiffies, timeout);
X schedule()); /* 10 s */
X if (BUS_IN(btv->mbox_data)) {
- printk("bttv%d: tea5757: read timeout\n",btv->nr);
+ printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->nr);
X return -1;
X }
X for(timeout = jiffies + HZ/5;
@@ -1706,6 +1885,43 @@
X }
X }
X
+/*
+ * Dariusz Kowalewski <dar...@automex.pl>
+ * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
+ * revision 9B has on-board TDA9874A sound decoder).
+ */
+static void
+pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
+{
+ unsigned int val = 0;
+
+#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
+ if (btv->radio_user)
+ return;
+#else
+ if (btv->radio)
+ return;
+#endif
+
+ if (set) {
+ if (v->mode & VIDEO_SOUND_MONO) {
+ val = 0x01;
+ }
+ if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
+ || (v->mode & VIDEO_SOUND_STEREO)) {
+ val = 0x02;
+ }
+ if (val) {
+ btaor(val, ~0x03, BT848_GPIO_DATA);
+ if (bttv_gpio)
+ bttv_gpio_tracking(btv,"pvbt878p9b");


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 22'
echo 'File patch-2.4.13 is continued in part 23'
echo "23" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:53 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part23

#!/bin/sh -x
# this is part 23 of a 53 - part archive


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

if test "$Scheck" != 23; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ }
+ } else {
+ v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+ VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ }
+}
+
X /* ----------------------------------------------------------------------- */
X /* motherboard chipset specific stuff */
X
@@ -1717,13 +1933,16 @@
X /* for 2.4.x we'll use the pci quirks (drivers/pci/quirks.c) */
X if (pci_pci_problems & PCIPCI_FAIL)
X pcipci_fail = 1;
-
X if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
X triton1 = 1;
- while ((dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, dev)))
+ if (pci_pci_problems & PCIPCI_VSFX)
X vsfx = 1;
X
- /* print warnings about quirks found */
+ /* print which chipset we have */
+ while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
+ printk(KERN_INFO "bttv: Host bridge is %s\n",dev->name);
+
+ /* print warnings about any quirks found */
X if (triton1)
X printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n");
X if (vsfx)
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- v2.4.12/linux/drivers/media/video/bttv-driver.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/bttv-driver.c Wed Oct 17 14:19:20 2001
@@ -104,7 +104,7 @@
X MODULE_PARM(vbi_nr,"i");
X
X MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards");
-MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
+MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
X MODULE_LICENSE("GPL");


X
X /* kernel args */

@@ -209,9 +209,11 @@
X unsigned long adr, page;
X
X mem=vmalloc_32(size);
- if (mem)
- {
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ if (NULL == mem)
+ printk(KERN_INFO "bttv: vmalloc_32(%ld) failed\n",size);
+ else {
+ /* Clear the ram out, no junk to the user */
+ memset(mem, 0, size);
X adr=(unsigned long) mem;
X while (size > 0)
X {
@@ -475,7 +477,13 @@
X /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
X { 35468950,
X 924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
- 1135, 186, 924, 0x20, 255},
+ 1135, 186, 924,
+#ifdef VIDEODAT_HACK
+ VBI_MAXLINES*2,
+#else
+ 0x20,
+#endif
+ 255},
X
X /* NTSC */
X { 28636363,
@@ -526,7 +534,7 @@
X btv->nr,virt_to_bus(po), virt_to_bus(pe));
X
X *(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
- for (i=0; i<16; i++)
+ for (i=0; i<VBI_MAXLINES; i++)
X {
X *(po++)=cpu_to_le32(VBI_RISC);
X *(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
@@ -535,7 +543,7 @@
X *(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
X
X *(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;
- for (i=16; i<32; i++)
+ for (i=VBI_MAXLINES; i<VBI_MAXLINES*2; i++)
X {
X *(pe++)=cpu_to_le32(VBI_RISC);
X *(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
@@ -553,23 +561,23 @@
X };
X
X static int palette2fmt[] = {
- 0,
- BT848_COLOR_FMT_Y8,
- BT848_COLOR_FMT_RGB8,
- BT848_COLOR_FMT_RGB16,
- BT848_COLOR_FMT_RGB24,
- BT848_COLOR_FMT_RGB32,
- BT848_COLOR_FMT_RGB15,
- BT848_COLOR_FMT_YUY2,
- BT848_COLOR_FMT_BtYUV,
- -1,
- -1,
- -1,
- BT848_COLOR_FMT_RAW,
- BT848_COLOR_FMT_YCrCb422,
- BT848_COLOR_FMT_YCrCb411,
- BT848_COLOR_FMT_YCrCb422,
- BT848_COLOR_FMT_YCrCb411,
+ 0,
+ BT848_COLOR_FMT_Y8,
+ BT848_COLOR_FMT_RGB8,
+ BT848_COLOR_FMT_RGB16,
+ BT848_COLOR_FMT_RGB24,
+ BT848_COLOR_FMT_RGB32,
+ BT848_COLOR_FMT_RGB15,
+ BT848_COLOR_FMT_YUY2,
+ BT848_COLOR_FMT_YUY2,
+ -1,
+ -1,
+ -1,
+ BT848_COLOR_FMT_RAW,
+ BT848_COLOR_FMT_YCrCb422,
+ BT848_COLOR_FMT_YCrCb411,
+ BT848_COLOR_FMT_YCrCb422,
+ BT848_COLOR_FMT_YCrCb411,
X };
X #define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))


X
@@ -2626,7 +2634,9 @@
X

X /* needs to be done before i2c is registered */
X if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
- bttv_hauppauge_boot_msp34xx(btv);
+ bttv_boot_msp34xx(btv,5);
+ if (btv->type == BTTV_VOODOOTV_FM)
+ bttv_boot_msp34xx(btv,20);
X
X /* register i2c */
X btv->tuner_type=-1;
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bttv-if.c linux/drivers/media/video/bttv-if.c
--- v2.4.12/linux/drivers/media/video/bttv-if.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/bttv-if.c Wed Oct 17 14:19:20 2001
@@ -209,7 +209,8 @@


X if (btv->tuner_type != -1)
X bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);

X if (bttv_verbose)
- printk("bttv%d: i2c attach [%s]\n",btv->nr,client->name);
+ printk("bttv%d: i2c attach [client=%s,%s]\n",btv->nr,
+ client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");


X return 0;
X }
X

@@ -218,14 +219,15 @@
X struct bttv *btv = (struct bttv*)client->adapter->data;
X int i;
X
- if (bttv_verbose)
- printk("bttv%d: i2c detach [%s]\n",btv->nr,client->name);
X for (i = 0; i < I2C_CLIENTS_MAX; i++) {
X if (btv->i2c_clients[i] == client) {
X btv->i2c_clients[i] = NULL;
X break;
X }
X }
+ if (bttv_verbose)
+ printk("bttv%d: i2c detach [client=%s,%s]\n",btv->nr,
+ client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");


X return 0;
X }
X

@@ -351,7 +353,6 @@
X btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap);
X return btv->i2c_rc;
X }


-MODULE_LICENSE("GPL");
X
X /*

X * Local variables:
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bttv.h linux/drivers/media/video/bttv.h
--- v2.4.12/linux/drivers/media/video/bttv.h Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bttv.h Wed Oct 17 14:19:20 2001
@@ -81,6 +81,13 @@
X #define BTTV_ATI_TVWONDERVE 0x40
X #define BTTV_FLYVIDEO2000 0x41
X #define BTTV_TERRATVALUER 0x42
+#define BTTV_GVBCTV4PCI 0x43
+#define BTTV_VOODOOTV_FM 0x44
+#define BTTV_AIMMS 0x45
+#define BTTV_PV_BT878P_PLUS 0x46
+#define BTTV_FLYVIDEO98EZ 0x47
+#define BTTV_PV_BT878P_9B 0x48
+
X
X /* i2c address list */
X #define I2C_TSA5522 0xc2
@@ -88,6 +95,7 @@
X #define I2C_TDA8425 0x82
X #define I2C_TDA9840 0x84
X #define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
+#define I2C_TDA9874A 0xb0 /* also used by 9875 */
X #define I2C_TDA9875 0xb0
X #define I2C_HAUPEE 0xa0
X #define I2C_STBEE 0xae
@@ -121,6 +129,7 @@
X
X /* i2c audio flags */
X int no_msp34xx:1;
+ int no_tda9875:1;
X int needs_tvaudio:1;
X
X /* other settings */
@@ -130,6 +139,7 @@
X #define PLL_35 2
X
X int tuner_type;
+ int has_radio;
X void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
X };
X
@@ -142,7 +152,7 @@
X
X /* card-specific funtions */
X extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_hauppauge_boot_msp34xx(struct bttv *btv);
+extern void bttv_boot_msp34xx(struct bttv *btv, int pin);
X
X /* kernel cmd line parse helper */
X extern int bttv_parse(char *str, int max, int *vals);
@@ -195,7 +205,7 @@
X extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
X
X /* i2c */
-#define I2C_CLIENTS_MAX 8
+#define I2C_CLIENTS_MAX 16
X extern void bttv_bit_setscl(void *data, int state);
X extern void bttv_bit_setsda(void *data, int state);
X extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
@@ -205,3 +215,8 @@
X extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
X
X #endif /* _BTTV_H_ */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bttvp.h linux/drivers/media/video/bttvp.h
--- v2.4.12/linux/drivers/media/video/bttvp.h Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bttvp.h Wed Oct 17 14:19:20 2001
@@ -25,7 +25,7 @@
X #ifndef _BTTVP_H_
X #define _BTTVP_H_
X
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,72)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,83)
X
X
X #include <linux/types.h>
@@ -62,10 +62,14 @@
X #define O_NONCAP O_TRUNC
X #endif
X
+#ifdef VIDEODAT_HACK
+# define VBI_MAXLINES 19
+#else
+# define VBI_MAXLINES 16
+#endif
+#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
X #define MAX_GBUFFERS 64
X #define RISCMEM_LEN (32744*2)
-#define VBI_MAXLINES 16
-#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
X
X #define BTTV_MAX_FBUF 0x208000
X
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- v2.4.12/linux/drivers/media/video/bw-qcam.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/bw-qcam.c Thu Oct 11 09:14:32 2001
@@ -1,8 +1,6 @@
X /*
X * QuickCam Driver For Video4Linux.
X *
- * This version only works as a module.
- *
X * Video4Linux conversion work by Alan Cox.
X * Parport compatibility by Phil Blundell.
X * Busy loop avoidance by Mark Cooke.
@@ -991,11 +989,20 @@
X MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
X #endif
X
-#ifdef MODULE
-int init_module(void)
+static void __exit exit_bw_qcams(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_cams; i++)
+ close_bwqcam(qcams[i]);
+}
+
+static int __init init_bw_qcams(void)
X {
X struct parport *port;
+#ifdef MODULE
X int n;
+
X if(parport[0] && strncmp(parport[0], "auto", 4)){
X /* user gave parport parameters */
X for(n=0; parport[n] && n<MAX_CAMS; n++){
@@ -1033,22 +1040,14 @@
X }
X
X return (num_cams)?0:-ENODEV;


-}
-
-void cleanup_module(void)
-{

- unsigned int i;
- for (i = 0; i < num_cams; i++)
- close_bwqcam(qcams[i]);
-}
X #else
-int __init init_bw_qcams(struct video_init *unused)
-{
- struct parport *port;
-
X for (port = parport_enumerate(); port; port=port->next)
X init_bwqcam(port);
X return 0;
-}
X #endif
+}
+
+module_init(init_bw_qcams);
+module_exit(exit_bw_qcams);
+
X MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/id.h linux/drivers/media/video/id.h
--- v2.4.12/linux/drivers/media/video/id.h Sun Nov 12 20:47:19 2000
+++ linux/drivers/media/video/id.h Wed Oct 17 14:19:20 2001
@@ -24,3 +24,6 @@
X #ifndef I2C_DRIVERID_TDA7432
X # define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
X #endif
+#ifndef I2C_DRIVERID_TDA9874A
+# define I2C_DRIVERID_TDA9874A I2C_DRIVERID_EXP0+7
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/msp3400.c linux/drivers/media/video/msp3400.c
--- v2.4.12/linux/drivers/media/video/msp3400.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/msp3400.c Wed Oct 17 14:19:20 2001
@@ -1,7 +1,7 @@
X /*
X * programming the msp34* sound processor family
X *
- * (c) 1997-2000 Gerd Knorr <kra...@goldbach.in-berlin.de>
+ * (c) 1997-2001 Gerd Knorr <kra...@bytesex.org>
X *
X * what works and what doesn't:
X *
@@ -97,7 +97,6 @@
X int nicam_on;
X int acb;
X int main, second; /* sound carrier */
- int scart; /* input is scart (extern) */
X
X int muted;
X int left, right; /* volume */
@@ -131,8 +130,10 @@
X MODULE_PARM(simple,"i");
X MODULE_PARM(amsound,"i");
X MODULE_PARM(dolby,"i");
-MODULE_LICENSE("GPL");
X
+MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
X
X /* ---------------------------------------------------------------------- */
X
@@ -231,6 +232,7 @@
X #define MSP_MODE_FM_NICAM2 6
X #define MSP_MODE_AM_NICAM 7
X #define MSP_MODE_BTSC 8
+#define MSP_MODE_EXTERN 9
X
X static struct MSP_INIT_DATA_DEM {
X int fir1[6];
@@ -443,6 +445,8 @@
X msp_init_data[type].dfp_src);
X msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
X msp_init_data[type].dfp_src);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
+ msp_init_data[type].dfp_src);
X }
X msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
X msp_init_data[type].dfp_src);
@@ -507,6 +511,13 @@
X dprintk("msp3400: BTSC setstereo: %d\n",mode);
X nicam=0x0300;
X break;
+ case MSP_MODE_EXTERN:
+ dprintk("msp3400: extern setstereo: %d\n", mode);
+ nicam = 0x0200;
+ break;
+ case MSP_MODE_FM_RADIO:
+ dprintk("msp3400: FM-Radio setstereo: %d\n", mode);
+ break;
X default:
X dprintk("msp3400: mono setstereo\n");
X return;
@@ -537,8 +548,8 @@
X src = 0x0010 | nicam;
X break;
X }
- if (msp->scart)
- src |= 0x0200;
+ dprintk("msp3400: setstereo final source/matrix = 0x%x\n", src);
+
X if (dolby) {
X msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
X msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
@@ -727,14 +738,14 @@
X {
X struct i2c_client *client = data;
X struct msp3400c *msp = client->data;
-
+
X struct CARRIER_DETECT *cd;
- int count, max1,max2,val1,val2, val,this;
-
+ int count, max1,max2,val1,val2, val,this;
+
X #ifdef CONFIG_SMP
X lock_kernel();
X #endif
-
+
X daemonize();
X sigfillset(&current->blocked);
X strcpy(current->comm,"msp3400");
@@ -748,7 +759,7 @@
X printk("msp3400: daemon started\n");
X if(msp->notify != NULL)
X up(msp->notify);
-
+
X for (;;) {
X if (msp->rmmod)
X goto done;
@@ -760,9 +771,8 @@
X if (msp->rmmod || signal_pending(current))
X goto done;
X
- if (VIDEO_MODE_RADIO == msp->norm)
- continue; /* nothing to do */
- if (msp->scart)
+ if (VIDEO_MODE_RADIO == msp->norm ||
+ MSP_MODE_EXTERN == msp->mode)
X continue; /* nothing to do */
X
X msp->active = 1;
@@ -780,10 +790,9 @@
X goto done;
X
X restart:
- if (msp->scart)
- continue;
- if (VIDEO_MODE_RADIO == msp->norm)
- continue;
+ if (VIDEO_MODE_RADIO == msp->norm ||
+ MSP_MODE_EXTERN == msp->mode)
+ continue; /* nothing to do */
X msp->restart = 0;
X msp3400c_setvolume(client, msp->muted, 0, 0);
X msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
@@ -1018,7 +1027,7 @@
X if (msp->rmmod || signal_pending(current))
X goto done;
X
- if (msp->scart)
+ if (msp->mode == MSP_MODE_EXTERN)
X continue;
X
X msp->active = 1;
@@ -1036,7 +1045,7 @@
X goto done;
X
X restart:
- if (msp->scart)
+ if (msp->mode == MSP_MODE_EXTERN)
X continue;
X msp->restart = 0;
X del_timer(&msp->wake_stereo);
@@ -1159,6 +1168,8 @@
X /* scart routing */
X msp3400c_set_scart(client,SCART_IN2,0);
X msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
X break;
X case 0x0003:
X msp->mode = MSP_MODE_FM_TERRA;
@@ -1353,7 +1364,19 @@


X return 0;
X }
X

-static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
+static void msp_wake_thread(struct i2c_client *client)
+{
+ struct msp3400c *msp = (struct msp3400c*)client->data;
+
+ msp3400c_setvolume(client,msp->muted,0,0);
+ msp->watch_stereo=0;
+ del_timer(&msp->wake_stereo);
+ if (msp->active)
+ msp->restart = 1;
+ wake_up_interruptible(&msp->wq);
+}
+
+static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
X {
X struct msp3400c *msp = (struct msp3400c*)client->data;
X __u16 *sarg = arg;
@@ -1368,21 +1391,24 @@
X - IN1 is often used for external input
X - Hauppauge uses IN2 for the radio */
X dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
- msp->scart = 0;
X switch (*sarg) {
X case AUDIO_RADIO:
+ msp->mode = MSP_MODE_FM_RADIO;
+ msp->stereo = VIDEO_SOUND_STEREO;
X msp3400c_set_scart(client,SCART_IN2,0);
X msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
X msp3400c_setstereo(client,msp->stereo);
X break;
X case AUDIO_EXTERN:
- msp->scart = 1;
+ msp->mode = MSP_MODE_EXTERN;
+ msp->stereo = VIDEO_SOUND_STEREO;
X msp3400c_set_scart(client,SCART_IN1,0);
X msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
X msp3400c_setstereo(client,msp->stereo);
X break;
X case AUDIO_TUNER:
- msp3400c_setstereo(client,msp->stereo);
+ msp->mode = -1;
+ msp_wake_thread(client);
X break;
X default:
X if (*sarg & AUDIO_MUTE)
@@ -1400,8 +1426,7 @@
X dprintk("msp34xx: switching to radio mode\n");
X if (msp->simple) {
X /* the thread will do for us */
- msp3400c_setvolume(client,msp->muted,0,0);
- wake_up_interruptible(&msp->wq);
+ msp_wake_thread(client);
X } else {
X /* set msp3400 to FM radio mode */
X msp3400c_setmode(client,MSP_MODE_FM_RADIO);
@@ -1457,6 +1482,8 @@
X (va->volume ? va->volume : 1);
X va->balance=(msp->left<msp->right)?
X (65535-va->balance) : va->balance;
+ if (0 == va->volume)
+ va->balance = 32768;
X va->bass = msp->bass;
X va->treble = msp->treble;
X
@@ -1500,12 +1527,7 @@
X case VIDIOCSFREQ:
X {
X /* new channel -- kick audio carrier scan */
- msp3400c_setvolume(client,msp->muted,0,0);
- msp->watch_stereo=0;
- del_timer(&msp->wake_stereo);
- if (msp->active)
- msp->restart = 1;
- wake_up_interruptible(&msp->wq);
+ msp_wake_thread(client);
X break;
X }
X
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- v2.4.12/linux/drivers/media/video/planb.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/planb.c Thu Oct 11 09:14:32 2001
@@ -55,12 +55,18 @@
X #include "planb.h"
X #include "saa7196.h"
X
-
X /* Would you mind for some ugly debugging? */
-//#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#define DEBUG(x...) /* Don't debug driver */
-//#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#if 0
+#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
+#else
+#define DEBUG(x...) /* Don't debug driver */
+#endif
+
+#if 0
+#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
+#endif
X #define IDEBUG(x...) /* Don't debug interrupt part */
+#endif
X
X /* Ever seen a Mac with more than 1 of these? */
X #define PLANB_MAX 1
@@ -2271,14 +2277,8 @@
X }
X }
X
-#ifdef MODULE
-
-int init_module(void)
-{
-#else
-int __init init_planbs(struct video_init *unused)
+static int __init init_planbs(void)
X {
-#endif
X int i;
X
X if (find_planb()<=0)
@@ -2296,11 +2296,10 @@


X return 0;
X }
X

-#ifdef MODULE
-
-void cleanup_module(void)

+static void __exit exit_planbs(void)
X {
X release_planb();
X }
X
-#endif
+module_init(init_planbs);
+module_exit(exit_planbs);
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/saa7110.c linux/drivers/media/video/saa7110.c
--- v2.4.12/linux/drivers/media/video/saa7110.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/saa7110.c Thu Oct 11 09:14:32 2001
@@ -306,7 +306,7 @@
X saa7110_write(decoder, 0x0D, 0x06);
X saa7110_write(decoder, 0x11, 0x2C);
X saa7110_write(decoder, 0x30, 0x81);
-saa7110_write(decoder, 0x2A, 0xDF);
+ saa7110_write(decoder, 0x2A, 0xDF);
X break;
X case VIDEO_MODE_PAL:
X saa7110_write(decoder, 0x0D, 0x06);
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tda7432.c linux/drivers/media/video/tda7432.c
--- v2.4.12/linux/drivers/media/video/tda7432.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/tda7432.c Wed Oct 17 14:19:20 2001
@@ -52,7 +52,6 @@
X MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");


X MODULE_LICENSE("GPL");
X
-

X MODULE_PARM(debug,"i");
X MODULE_PARM(loudness,"i");
X static int loudness = 0; /* disable loudness by default */
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tda9875.c linux/drivers/media/video/tda9875.c
--- v2.4.12/linux/drivers/media/video/tda9875.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/tda9875.c Wed Oct 17 14:19:20 2001
@@ -36,7 +36,6 @@
X MODULE_PARM(debug,"i");


X MODULE_LICENSE("GPL");
X
-

X static int debug = 0; /* insmod parameter */
X
X /* Addresses to scan */
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tuner.c linux/drivers/media/video/tuner.c
--- v2.4.12/linux/drivers/media/video/tuner.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/tuner.c Wed Oct 17 14:19:20 2001
@@ -30,25 +30,29 @@
X force
X };
X
-static int debug = 0; /* insmod parameter */
-static int type = -1; /* insmod parameter */
-
+/* insmod options */
+static int debug = 0;
+static int type = -1;
X static int addr = 0;
X static char *pal = "b";
-static int this_adap;
X static int tv_range[2] = { 44, 958 };
X static int radio_range[2] = { 65, 108 };
-
-#define dprintk if (debug) printk
-
X MODULE_PARM(debug,"i");
X MODULE_PARM(type,"i");
X MODULE_PARM(addr,"i");
X MODULE_PARM(tv_range,"2i");
X MODULE_PARM(radio_range,"2i");
X MODULE_PARM(pal,"s");
+
+#define optimize_vco 1
+
+MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");


X MODULE_LICENSE("GPL");
X

+static int this_adap;
+#define dprintk if (debug) printk
+
X struct tuner
X {
X int type; /* chip type */
@@ -56,12 +60,15 @@
X int std;
X
X int radio;
- int mode; /* PAL(0)/SECAM(1) mode (PHILIPS_SECAM only) */
+ int mode; /* current norm for multi-norm tuners */
+ int xogc; // only for MT2032
X };
X
X static struct i2c_driver driver;
X static struct i2c_client client_template;
X
+/* ---------------------------------------------------------------------- */
+
X /* tv standard selection for Temic 4046 FM5
X this value takes the low bits of control byte 2
X from datasheet Rev.01, Feb.00
@@ -154,13 +161,13 @@
X 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
X { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
X 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
- { "Temic PAL_I (4006FH5)", TEMIC, PAL_I,
+ { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
X 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
X { "Alps TSCH6",Alps,NTSC,
X 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
X
X { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
- 16*136.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
+ 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
X { "Philips NTSC_M (MK2)",Philips,NTSC,
X 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
X { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
@@ -191,7 +198,24 @@
X { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
X 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
X { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
- 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}
+ 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+ { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
+ 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940},
+
+ { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
+ 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
+ { "MT2032 universal", Microtune,PAL|NTSC,
+ 0,0,0,0,0,0,0},
+ { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
+ 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+ { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
+ 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
+
+ { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
+ 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
+ { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
+ 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
+
X };
X #define TUNERS (sizeof(tuners)/sizeof(struct tunertype))
X
@@ -201,6 +225,11 @@
X {
X unsigned char byte;
X
+ struct tuner *t = (struct tuner*)c->data;
+
+ if (t->type == TUNER_MT2032)
+ return 0;
+
X if (1 != i2c_master_recv(c,&byte,1))
X return 0;
X return byte;
@@ -241,6 +270,315 @@
X return (tuner_getstatus (c) & TUNER_MODE) >> 3;
X }
X #endif
+// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
+int mt2032_init(struct i2c_client *c)
+{
+ unsigned char buf[21];
+ int ret,xogc,xok=0;
+ struct tuner *t = (struct tuner*)c->data;
+
+ buf[0]=0;
+ ret=i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,21);
+
+ printk("MT2032: Companycode=%02x%02x Part=%02x Revision=%02x\n",
+ buf[0x11],buf[0x12],buf[0x13],buf[0x14]);
+
+ if(debug) {
+ int i;
+ printk("MT2032 hexdump:\n");
+ for(i=0;i<21;i++) {
+ printk(" %02x",buf[i]);
+ if(((i+1)%8)==0) printk(" ");
+ if(((i+1)%16)==0) printk("\n ");
+ }
+ printk("\n ");
+ }
+
+ // Initialize Registers per spec.
+ buf[1]=2; // Index to register 2
+ buf[2]=0xff;
+ buf[3]=0x0f;
+ buf[4]=0x1f;
+ ret=i2c_master_send(c,buf+1,4);
+
+ buf[5]=6; // Index register 6
+ buf[6]=0xe4;
+ buf[7]=0x8f;
+ buf[8]=0xc3;
+ buf[9]=0x4e;
+ buf[10]=0xec;
+ ret=i2c_master_send(c,buf+5,6);
+
+ buf[12]=13; // Index register 13
+ buf[13]=0x32;
+ ret=i2c_master_send(c,buf+12,2);
+
+ // Adjust XOGC (register 7), wait for XOK
+ xogc=7;
+ do {
+ dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+ mdelay(10);
+ buf[0]=0x0e;
+ i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,1);
+ xok=buf[0]&0x01;
+ dprintk("mt2032: xok = 0x%02x\n",xok);
+ if (xok == 1) break;
+
+ xogc--;
+ dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+ if (xogc == 3) {
+ xogc=4; // min. 4 per spec
+ break;
+ }
+ buf[0]=0x07;
+ buf[1]=0x88 + xogc;
+ ret=i2c_master_send(c,buf,2);
+ if (ret!=2)
+ printk("mt2032_init failed with %d\n",ret);
+ } while (xok != 1 );
+ t->xogc=xogc;
+
+ return(1);
+}
+
+
+// IsSpurInBand()?
+int mt2032_spurcheck(int f1, int f2, int spectrum_from,int spectrum_to)
+{
+ int n1=1,n2,f;
+
+ f1=f1/1000; //scale to kHz to avoid 32bit overflows
+ f2=f2/1000;
+ spectrum_from/=1000;
+ spectrum_to/=1000;
+
+ dprintk("spurcheck f1=%d f2=%d from=%d to=%d\n",f1,f2,spectrum_from,spectrum_to);
+
+ do {
+ n2=-n1;
+ f=n1*(f1-f2);
+ do {
+ n2--;
+ f=f-f2;
+ dprintk(" spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
+
+ if( (f>spectrum_from) && (f<spectrum_to))
+ printk("mt2032 spurcheck triggered: %d\n",n1);
+ } while ( (f>(f2-spectrum_to)) || (n2>-5));
+ n1++;
+ } while (n1<5);
+


+ return 1;
+}
+

+int mt2032_compute_freq(int rfin, int if1, int if2, int spectrum_from,
+ int spectrum_to, unsigned char *buf, int *ret_sel, int xogc) //all in Hz
+{
+ int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
+ desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
+
+ fref= 5250 *1000; //5.25MHz
+ desired_lo1=rfin+if1;
+
+ lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
+ lo1n=lo1/8;
+ lo1a=lo1-(lo1n*8);
+
+ s=rfin/1000/1000+1090;
+
+ if(optimize_vco) {
+ if(s>1890) sel=0;
+ else if(s>1720) sel=1;
+ else if(s>1530) sel=2;
+ else if(s>1370) sel=3;
+ else sel=4; // >1090
+ }
+ else {
+ if(s>1790) sel=0; // <1958
+ else if(s>1617) sel=1;
+ else if(s>1449) sel=2;
+ else if(s>1291) sel=3;
+ else sel=4; // >1090
+ }
+ *ret_sel=sel;
+
+ lo1freq=(lo1a+8*lo1n)*fref;
+
+ dprintk("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
+ rfin,lo1,lo1n,lo1a,sel,lo1freq);
+
+ desired_lo2=lo1freq-rfin-if2;
+ lo2=(desired_lo2)/fref;
+ lo2n=lo2/8;
+ lo2a=lo2-(lo2n*8);
+ lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
+ lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
+
+ dprintk("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
+ rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
+
+ if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
+ printk("mt2032: frequency parameters out of range: %d %d %d %d\n",
+ lo1a, lo1n, lo2a,lo2n);
+ return(-1);
+ }
+
+ mt2032_spurcheck(lo1freq, desired_lo2, spectrum_from, spectrum_to);
+ // should recalculate lo1 (one step up/down)
+
+ // set up MT2032 register map for transfer over i2c
+ buf[0]=lo1n-1;
+ buf[1]=lo1a | (sel<<4);
+ buf[2]=0x86; // LOGC
+ buf[3]=0x0f; //reserved
+ buf[4]=0x1f;
+ buf[5]=(lo2n-1) | (lo2a<<5);
+ if(rfin >400*1000*1000)
+ buf[6]=0xe4;
+ else
+ buf[6]=0xf4; // set PKEN per rev 1.2
+ buf[7]=8+xogc;
+ buf[8]=0xc3; //reserved
+ buf[9]=0x4e; //reserved
+ buf[10]=0xec; //reserved
+ buf[11]=(lo2num&0xff);
+ buf[12]=(lo2num>>8) |0x80; // Lo2RST


+
+ return 0;
+}
+

+int mt2032_check_lo_lock(struct i2c_client *c)
+{
+ int try,lock=0;
+ unsigned char buf[2];
+ for(try=0;try<10;try++) {
+ buf[0]=0x0e;
+ i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,1);
+ dprintk("mt2032 Reg.E=0x%02x\n",buf[0]);
+ lock=buf[0] &0x06;
+
+ if (lock==6)
+ break;
+
+ dprintk("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
+ udelay(1000);
+ }
+ return lock;
+}
+
+int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
+{
+ unsigned char buf[2];
+ int tad1;
+
+ buf[0]=0x0f;
+ i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,1);
+ dprintk("mt2032 Reg.F=0x%02x\n",buf[0]);
+ tad1=buf[0]&0x07;
+
+ if(tad1 ==0) return lock;
+ if(tad1 ==1) return lock;
+
+ if(tad1==2) {
+ if(sel==0)
+ return lock;
+ else sel--;
+ }
+ else {
+ if(sel<4)
+ sel++;
+ else
+ return lock;
+ }
+
+ dprintk("mt2032 optimize_vco: sel=%d\n",sel);
+
+ buf[0]=0x0f;
+ buf[1]=sel;
+ i2c_master_send(c,buf,2);
+ lock=mt2032_check_lo_lock(c);
+ return lock;
+}
+
+
+void mt2032_set_if_freq(struct i2c_client *c,int rfin, int if1, int if2, int from, int to)
+{
+ unsigned char buf[21];
+ int lint_try,ret,sel,lock=0;
+ struct tuner *t = (struct tuner*)c->data;
+
+ dprintk("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",rfin,if1,if2,from,to);
+
+ buf[0]=0;
+ ret=i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,21);
+
+ buf[0]=0;
+ ret=mt2032_compute_freq(rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
+ if (ret<0)
+ return;
+
+ // send only the relevant registers per Rev. 1.2
+ buf[0]=0;
+ ret=i2c_master_send(c,buf,4);
+ buf[5]=5;
+ ret=i2c_master_send(c,buf+5,4);
+ buf[11]=11;
+ ret=i2c_master_send(c,buf+11,3);
+ if(ret!=3)
+ printk("mt2032_set_if_freq failed with %d\n",ret);
+
+ // wait for PLLs to lock (per manual), retry LINT if not.
+ for(lint_try=0; lint_try<2; lint_try++) {
+ lock=mt2032_check_lo_lock(c);
+
+ if(optimize_vco)
+ lock=mt2032_optimize_vco(c,sel,lock);
+ if(lock==6) break;
+
+ printk("mt2032: re-init PLLs by LINT\n");
+ buf[0]=7;
+ buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs
+ i2c_master_send(c,buf,2);
+ mdelay(10);
+ buf[1]=8+t->xogc;
+ i2c_master_send(c,buf,2);
+ }
+
+ if (lock!=6)
+ printk("MT2032 Fatal Error: PLLs didn't lock.\n");
+
+ buf[0]=2;
+ buf[1]=0x20; // LOGC for optimal phase noise
+ ret=i2c_master_send(c,buf,2);
+ if (ret!=2)
+ printk("mt2032_set_if_freq2 failed with %d\n",ret);
+}
+
+
+void mt2032_set_tv_freq(struct i2c_client *c, int freq, int norm)
+{
+ int if2,from,to;
+
+ // signal bandwidth and picture carrier
+ if(norm==VIDEO_MODE_NTSC) {
+ from=40750*1000;
+ to=46750*1000;
+ if2=45750*1000;
+ }
+ else { // Pal
+ from=32900*1000;
+ to=39900*1000;
+ if2=38900*1000;
+ }
+
+ mt2032_set_if_freq(c,freq* 1000*1000/16, 1090*1000*1000, if2, from, to);
+}
+
X
X // Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
X static void set_tv_freq(struct i2c_client *c, int freq)
@@ -252,6 +590,15 @@
X unsigned char buffer[4];
X int rc;
X
+ if (t->type == -1) {
+ printk("tuner: tuner type not set\n");
+ return;
+ }
+ if (t->type == TUNER_MT2032) {
+ mt2032_set_tv_freq(c,freq,t->mode);
+ return;
+ }
+
X if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
X /* FIXME: better do that chip-specific, but
X right now we don't have that in the config
@@ -259,10 +606,6 @@
X check at all */
X printk("tuner: TV freq (%d.%02d) out of range (%d-%d)\n",
X freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
- }
-
- if (t->type == -1) {
- printk("tuner: tuner type not set\n");
X return;
X }
X
@@ -282,7 +625,7 @@
X /* 0x02 -> PAL BDGHI / SECAM L */
X /* 0x04 -> ??? PAL others / SECAM others ??? */
X config &= ~0x02;
- if (t->mode)
+ if (t->mode == VIDEO_MODE_SECAM)
X config |= 0x02;
X break;
X
@@ -366,6 +709,15 @@
X
X }
X
+static void mt2032_set_radio_freq(struct i2c_client *c,int freq)
+{
+ int if2;
+
+ if2=10700*1000; // 10.7MHz FM intermediate frequency
+
+ mt2032_set_if_freq(c,freq* 1000*1000/16, 1085*1000*1000,if2,if2,if2);
+}
+
X static void set_radio_freq(struct i2c_client *c, int freq)
X {
X u8 config;
@@ -386,6 +738,11 @@
X return;
X }
X
+ if (t->type == TUNER_MT2032) {
+ mt2032_set_radio_freq(c,freq);
+ return;
+ }
+
X tun=&tuners[t->type];
X config = 0xa4 /* 0xa5 */; /* bit 0 is AFC (set) vs. RF-Signal (clear) */
X div=freq + (int)(16*10.7);
@@ -448,6 +805,9 @@
X t->type = -1;
X }
X i2c_attach_client(client);
+ if (t->type == TUNER_MT2032)
+ mt2032_init(client);
+
X MOD_INC_USE_COUNT;
X
X return 0;
@@ -497,6 +857,8 @@
X dprintk("tuner: type set to %d (%s)\n",
X t->type,tuners[t->type].name);
X strncpy(client->name, tuners[t->type].name, sizeof(client->name));
+ if (t->type == TUNER_MT2032)
+ mt2032_init(client);
X break;
X case AUDC_SET_RADIO:
X t->radio = 1;
@@ -508,12 +870,11 @@
X case VIDIOCSCHAN:
X {
X struct video_channel *vc = arg;
-
+
X t->radio = 0;
- if (t->type == TUNER_PHILIPS_SECAM) {
- t->mode = (vc->norm == VIDEO_MODE_SECAM) ? 1 : 0;
+ t->mode = vc->norm;
+ if (t->freq)
X set_tv_freq(client,t->freq);
- }
X return 0;
X }
X case VIDIOCSFREQ:
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tuner.h linux/drivers/media/video/tuner.h
--- v2.4.12/linux/drivers/media/video/tuner.h Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/tuner.h Wed Oct 17 14:19:20 2001
@@ -22,29 +22,29 @@
X #ifndef _TUNER_H
X #define _TUNER_H
X
-#define TUNER_TEMIC_PAL 0 /* 4002 FH5_9483 */
+#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
X #define TUNER_PHILIPS_PAL_I 1
X #define TUNER_PHILIPS_NTSC 2
X #define TUNER_PHILIPS_SECAM 3 /* you must actively select B/G, L, L` */
X #define TUNER_ABSENT 4
X #define TUNER_PHILIPS_PAL 5
-#define TUNER_TEMIC_NTSC 6 /* 4032 FY5_7004 */
-#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5_9957 */
-#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 */
+#define TUNER_TEMIC_NTSC 6 /* 4032 FY5 (3X 7004, 9498, 9789) */
+#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5 (3X 8501, 9957) */
+#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 (3X 1223, 1981, 7686) */
X #define TUNER_ALPS_TSBH1_NTSC 9
X #define TUNER_ALPS_TSBE1_PAL 10
X #define TUNER_ALPS_TSBB5_PAL_I 11
X #define TUNER_ALPS_TSBE5_PAL 12
X #define TUNER_ALPS_TSBC5_PAL 13
-#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 */
+#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 (3X 9500, 9501, 7291) */
X #define TUNER_ALPS_TSHC6_NTSC 15
-#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 */
+#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 (3X 1392, 1393) */
X #define TUNER_PHILIPS_NTSC_M 17
-#define TUNER_TEMIC_4066FY5_PAL_I 18
-#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected */
-#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio */
-#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio */
-#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! */
+#define TUNER_TEMIC_4066FY5_PAL_I 18 /* 4066 FY5 (3X 7032, 7035) */
+#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected (3X 7595, 7606, 7657)*/
+#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio (3X 7607, 7488, 7711)*/
+#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio (3X 7246, 7578, 7732)*/
+#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! (3X 7804, 7806, 8103, 8104)*/
X #define TUNER_PHILIPS_PAL_DK 23
X #define TUNER_PHILIPS_FQ1216ME 24 /* you must actively select B/G/D/K, I, L, L` */
X #define TUNER_LG_PAL_I_FM 25
@@ -52,7 +52,15 @@
X #define TUNER_LG_NTSC_FM 27
X #define TUNER_LG_PAL_FM 28
X #define TUNER_LG_PAL 29
-#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected */
+#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected (3X 8155, 8160, 8163)*/
+#define TUNER_SHARP_2U5JF5540_NTSC 31
+#define TUNER_Samsung_PAL_TCPM9091PD27 32
+#define TUNER_MT2032 33
+#define TUNER_TEMIC_4106FH5 34 /* 4106 FH5 (3X 7808, 7865)*/
+#define TUNER_TEMIC_4012FY5 35 /* 4012 FY5 (3X 0971, 1099)*/
+#define TUNER_TEMIC_4136FY5 36 /* 4136 FY5 (3X 7708, 7746)*/
+#define TUNER_LG_PAL_NEW_TAPC 37
+
X
X
X #define NOTUNER 0
@@ -67,6 +75,9 @@
X #define Sony 3
X #define Alps 4
X #define LGINNOTEK 5
+#define SHARP 6
+#define Samsung 7
+#define Microtune 8
X
X #define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */
X #define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
--- v2.4.12/linux/drivers/media/video/tvaudio.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/tvaudio.c Wed Oct 17 14:19:20 2001
@@ -42,6 +42,9 @@
X
X #define dprintk if (debug) printk
X
+MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
+MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
+MODULE_LICENSE("GPL");
X
X /* ---------------------------------------------------------------------- */
X /* our structs */
@@ -51,6 +54,7 @@
X struct CHIPSTATE;
X typedef int (*getvalue)(int);
X typedef int (*checkit)(struct CHIPSTATE*);
+typedef int (*initialize)(struct CHIPSTATE*);
X typedef int (*getmode)(struct CHIPSTATE*);
X typedef void (*setmode)(struct CHIPSTATE*, int mode);
X typedef void (*checkmode)(struct CHIPSTATE*);


@@ -70,6 +74,7 @@
X

X int *insmodopt;
X checkit checkit;
+ initialize initialize;
X int flags;
X #define CHIP_HAS_VOLUME 1
X #define CHIP_HAS_BASSTREBLE 2
@@ -134,6 +139,7 @@
X I2C_TDA9840 >> 1,
X I2C_TDA985x_L >> 1,
X I2C_TDA985x_H >> 1,
+ I2C_TDA9874A >> 1,
X I2C_PIC16C54 >> 1,
X I2C_CLIENT_END };
X static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
@@ -216,7 +222,7 @@
X { chip->c.addr, 0, 1, write },
X { chip->c.addr, I2C_M_RD, 1, read }
X };
- write[1] = subaddr;
+ write[0] = subaddr;
X
X if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
X printk(KERN_WARNING "%s: I/O error (read2)\n",
@@ -323,6 +329,8 @@
X
X if (mode & VIDEO_SOUND_LANG1)
X desc->setmode(chip,VIDEO_SOUND_LANG1);
+ else if (mode & VIDEO_SOUND_LANG2)
+ desc->setmode(chip,VIDEO_SOUND_LANG2);
X else if (mode & VIDEO_SOUND_STEREO)
X desc->setmode(chip,VIDEO_SOUND_STEREO);
X else
@@ -695,6 +703,7 @@
X return;
X }
X
+ chip_write(chip, TDA9873_SW, sw_data);
X dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
X mode, sw_data);
X }
@@ -710,6 +719,181 @@
X
X
X /* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9874a */
+/* Dariusz Kowalewski <dar...@automex.pl> */
+
+/* Subaddresses for TDA9874A (slave rx) */
+#define TDA9874A_AGCGR 0x00 /* AGC gain */
+#define TDA9874A_GCONR 0x01 /* general config */
+#define TDA9874A_MSR 0x02 /* monitor select */
+#define TDA9874A_C1FRA 0x03 /* carrier 1 freq. */
+#define TDA9874A_C1FRB 0x04 /* carrier 1 freq. */
+#define TDA9874A_C1FRC 0x05 /* carrier 1 freq. */
+#define TDA9874A_C2FRA 0x06 /* carrier 2 freq. */
+#define TDA9874A_C2FRB 0x07 /* carrier 2 freq. */
+#define TDA9874A_C2FRC 0x08 /* carrier 2 freq. */
+#define TDA9874A_DCR 0x09 /* demodulator config */
+#define TDA9874A_FMER 0x0a /* FM de-emphasis */
+#define TDA9874A_FMMR 0x0b /* FM dematrix */
+#define TDA9874A_C1OLAR 0x0c /* ch.1 output level adj. */
+#define TDA9874A_C2OLAR 0x0d /* ch.2 output level adj. */
+#define TDA9874A_NCONR 0x0e /* NICAM config */
+#define TDA9874A_NOLAR 0x0f /* NICAM output level adj. */
+#define TDA9874A_NLELR 0x10 /* NICAM lower error limit */
+#define TDA9874A_NUELR 0x11 /* NICAM upper error limit */
+#define TDA9874A_AMCONR 0x12 /* audio mute control */
+#define TDA9874A_SDACOSR 0x13 /* stereo DAC output select */
+#define TDA9874A_AOSR 0x14 /* analog output select */
+#define TDA9874A_DAICONR 0x15 /* digital audio interface config */
+#define TDA9874A_I2SOSR 0x16 /* I2S-bus output select */
+#define TDA9874A_I2SOLAR 0x17 /* I2S-bus output level adj. */
+#define TDA9874A_MDACOSR 0x18 /* mono DAC output select */
+#define TDA9874A_ESP 0xFF /* easy standard progr. */
+
+/* Subaddresses for TDA9874A (slave tx) */
+#define TDA9874A_DSR 0x00 /* device status */
+#define TDA9874A_NSR 0x01 /* NICAM status */
+#define TDA9874A_NECR 0x02 /* NICAM error count */
+#define TDA9874A_DR1 0x03 /* add. data LSB */
+#define TDA9874A_DR2 0x04 /* add. data MSB */
+#define TDA9874A_LLRA 0x05 /* monitor level read-out LSB */
+#define TDA9874A_LLRB 0x06 /* monitor level read-out MSB */
+#define TDA9874A_SIFLR 0x07 /* SIF level */
+#define TDA9874A_TR2 252 /* test reg. 2 */
+#define TDA9874A_TR1 253 /* test reg. 1 */
+#define TDA9874A_DIC 254 /* device id. code */
+#define TDA9874A_SIC 255 /* software id. code */
+
+
+static int tda9874a_mode = 1; /* 0: A2, 1: NICAM */
+static int tda9874a_GCONR = 0xc0; /* default config. input pin: SIFSEL=0 */
+static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */
+
+/* insmod options for tda9874a */
+static int tda9874a_SIF = -1;
+static int tda9874a_STD = -1;
+MODULE_PARM(tda9874a_SIF,"i");
+MODULE_PARM(tda9874a_STD,"i");
+
+
+static int tda9874a_setup(struct CHIPSTATE *chip)
+{
+ chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
+ chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
+ chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
+ chip_write(chip, TDA9874A_FMMR, 0x80);
+ chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
+ chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
+ chip_write(chip, TDA9874A_NCONR, 0x00); /* not 0x04 as doc. table 10 says! */
+ chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
+ chip_write(chip, TDA9874A_AMCONR, 0xf9);
+ chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); /* 0x81 */
+ chip_write(chip, TDA9874A_AOSR, 0x80);
+ chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
+ chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
+


+ return 1;
+}
+

+int tda9874a_getmode(struct CHIPSTATE *chip)
+{
+ int dsr,nsr,mode;
+
+ mode = VIDEO_SOUND_MONO;
+
+ if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))
+ return mode;
+ if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
+ return mode;
+
+ if(tda9874a_mode) {
+ /* check also DSR.RSSF and DSR.AMSTAT bits? */
+ if(nsr & 0x02) /* NSR.S/MB */
+ mode |= VIDEO_SOUND_STEREO;
+ if(nsr & 0x01) /* NSR.D/SB */
+ mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ } else {
+ if(dsr & 0x02) /* DSR.IDSTE */
+ mode |= VIDEO_SOUND_STEREO;
+ if(dsr & 0x04) /* DSR.IDDUA */
+ mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ }
+
+ dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, return: %d.\n",
+ dsr, nsr, mode);
+ return mode;
+}
+
+void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
+{
+ int aosr=0x80,mdacosr=0x82;
+
+ /* note: TDA9874A has auto-select function for audio output */
+ switch(mode) {
+ case VIDEO_SOUND_MONO:
+ case VIDEO_SOUND_STEREO:
+ break;
+ case VIDEO_SOUND_LANG1:
+ aosr = 0x80; /* dual A/A */
+ mdacosr = (tda9874a_mode) ? 0x82:0x80;
+ break;
+ case VIDEO_SOUND_LANG2:
+ aosr = 0xa0; /* dual B/B */
+ mdacosr = (tda9874a_mode) ? 0x83:0x81;
+ break;
+ default:
+ chip->mode = 0;
+ return;
+ }
+
+ chip_write(chip, TDA9874A_AOSR, aosr);
+ chip_write(chip, TDA9874A_MDACOSR, mdacosr);
+
+ dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
+ mode, aosr, mdacosr);
+}
+
+int tda9874a_checkit(struct CHIPSTATE *chip)
+{
+ int dic,sic; /* device id. and software id. codes */
+
+ if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
+ return 0;
+ if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
+ return 0;
+
+ dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
+
+ return((dic & 0xff) == 0x11);
+}
+
+int tda9874a_initialize(struct CHIPSTATE *chip)
+{
+ if(tda9874a_SIF != -1) {
+ if(tda9874a_SIF == 1)
+ tda9874a_GCONR = 0xc0; /* sound IF input 1 */
+ else if(tda9874a_SIF == 2)
+ tda9874a_GCONR = 0xc1; /* sound IF input 2 */
+ else
+ printk(KERN_WARNING "tda9874a: SIF parameter must be 1 or 2.\n");
+ }
+
+ if(tda9874a_STD != -1) {
+ if((tda9874a_STD >= 0)&&(tda9874a_STD <= 8)) {
+ tda9874a_ESP = tda9874a_STD;
+ tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
+ } else {
+ printk(KERN_WARNING "tda9874a: STD parameter must be between 0 and 8.\n");
+ }
+ }
+
+ tda9874a_setup(chip);


+
+ return 0;
+}
+
+

+/* ---------------------------------------------------------------------- */
X /* audio chip descriptions - defines+functions for tea6420 */
X
X #define TEA6300_VL 0x00 /* volume left */
@@ -779,6 +963,7 @@
X int tda9850 = 1;
X int tda9855 = 1;
X int tda9873 = 1;
+int tda9874a = 1;
X int tea6300 = 0;
X int tea6420 = 1;
X int pic16c54 = 1;
@@ -787,6 +972,7 @@
X MODULE_PARM(tda9850,"i");
X MODULE_PARM(tda9855,"i");
X MODULE_PARM(tda9873,"i");
+MODULE_PARM(tda9874a,"i");
X MODULE_PARM(tea6300,"i");
X MODULE_PARM(tea6420,"i");
X MODULE_PARM(pic16c54,"i");
@@ -829,6 +1015,19 @@
X
X },
X {
+ name: "tda9874a",
+ id: I2C_DRIVERID_TDA9874A,
+ checkit: tda9874a_checkit,
+ initialize: tda9874a_initialize,
+ insmodopt: &tda9874a,
+ addr_lo: I2C_TDA9874A >> 1,
+ addr_hi: I2C_TDA9874A >> 1,
+
+ getmode: tda9874a_getmode,
+ setmode: tda9874a_setmode,
+ checkmode: generic_checkmode,
+ },
+ {
X name: "tda9850",
X id: I2C_DRIVERID_TDA9850,
X insmodopt: &tda9850,
@@ -991,7 +1190,11 @@
X i2c_attach_client(&chip->c);
X
X /* initialization */
- chip_cmd(chip,"init",&desc->init);
+ if (desc->initialize != NULL)
+ desc->initialize(chip);
+ else
+ chip_cmd(chip,"init",&desc->init);
+
X if (desc->flags & CHIP_HAS_VOLUME) {
X chip->left = desc->leftinit ? desc->leftinit : 65536;
X chip->right = desc->rightinit ? desc->rightinit : 65536;
@@ -1168,7 +1371,6 @@
X
X module_init(audiochip_init_module);
X module_exit(audiochip_cleanup_module);


-MODULE_LICENSE("GPL");
X
X /*

X * Local variables:
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tvaudio.h linux/drivers/media/video/tvaudio.h
--- v2.4.12/linux/drivers/media/video/tvaudio.h Sun Nov 12 20:47:19 2000
+++ linux/drivers/media/video/tvaudio.h Wed Oct 17 14:19:20 2001
@@ -6,6 +6,7 @@
X #define I2C_TDA9840 0x84
X #define I2C_TDA985x_L 0xb4 /* also used by 9873 */
X #define I2C_TDA985x_H 0xb6
+#define I2C_TDA9874A 0xb0 /* also used by 9875 */
X
X #define I2C_TEA6300 0x80
X #define I2C_TEA6420 0x98
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/tvmixer.c linux/drivers/media/video/tvmixer.c
--- v2.4.12/linux/drivers/media/video/tvmixer.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/tvmixer.c Wed Oct 17 14:19:20 2001
@@ -26,6 +26,9 @@
X MODULE_PARM(debug,"i");
X MODULE_PARM(devnr,"i");
X
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
X /* ----------------------------------------------------------------------- */
X
X struct TVMIXER {
@@ -39,27 +42,6 @@
X static int tvmixer_adapters(struct i2c_adapter *adap);
X static int tvmixer_clients(struct i2c_client *client);
X
-static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static int tvmixer_open(struct inode *inode, struct file *file);
-static int tvmixer_release(struct inode *inode, struct file *file);
-
-
-static struct i2c_driver driver = {
- name: "tv card mixer driver",
- id: I2C_DRIVERID_TVMIXER,
- flags: I2C_DF_DUMMY,
- attach_adapter: tvmixer_adapters,
- detach_client: tvmixer_clients,
-};
-
-static struct file_operations tvmixer_fops = {


- owner: THIS_MODULE,
- llseek: no_llseek,

- ioctl: tvmixer_ioctl,
- open: tvmixer_open,
- release: tvmixer_release,
-};
-
X /* ----------------------------------------------------------------------- */
X
X static int mix_to_v4l(int i)
@@ -232,6 +214,23 @@


X return 0;
X }
X

+
+static struct i2c_driver driver = {
+ name: "tv card mixer driver",
+ id: I2C_DRIVERID_TVMIXER,
+ flags: I2C_DF_DUMMY,
+ attach_adapter: tvmixer_adapters,
+ detach_client: tvmixer_clients,
+};
+
+static struct file_operations tvmixer_fops = {
+ owner: THIS_MODULE,
+ llseek: no_llseek,
+ ioctl: tvmixer_ioctl,
+ open: tvmixer_open,
+ release: tvmixer_release,
+};
+
X /* ----------------------------------------------------------------------- */
X
X static int tvmixer_adapters(struct i2c_adapter *adap)
@@ -355,4 +354,3 @@
X * c-basic-offset: 8
X * End:
X */
-MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.12/linux/drivers/media/video/videodev.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/media/video/videodev.c Thu Oct 11 09:14:32 2001
@@ -63,29 +63,6 @@
X #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
X
X
-#ifdef CONFIG_VIDEO_BWQCAM
-extern int init_bw_qcams(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_CPIA
-extern int cpia_init(struct video_init *);
-#endif
-#ifdef CONFIG_VIDEO_PLANB
-extern int init_planbs(struct video_init *);
-#endif
-
-static struct video_init video_init_list[]={
-#ifdef CONFIG_VIDEO_BWQCAM
- {"bw-qcam", init_bw_qcams},
-#endif
-#ifdef CONFIG_VIDEO_CPIA
- {"cpia", cpia_init},
-#endif
-#ifdef CONFIG_VIDEO_PLANB
- {"planb", init_planbs},
-#endif
- {"end", NULL}
-};
-
X /*
X * Read will do some smarts later on. Buffer pin etc.
X */
@@ -118,7 +95,7 @@
X
X /*
X * Poll to see if we're readable, can probably be used for timing on incoming
- * frames, etc..
+ * frames, etc..
X */
X
X static unsigned int video_poll(struct file *file, poll_table * wait)
@@ -222,8 +199,7 @@
X /*
X * We need to do MMAP support
X */
-
-
+
X int video_mmap(struct file *file, struct vm_area_struct *vma)
X {
X int ret = -EINVAL;
@@ -548,8 +524,6 @@
X
X static int __init videodev_init(void)
X {
- struct video_init *vfli = video_init_list;
-
X printk(KERN_INFO "Linux video capture interface: v1.00\n");
X if(devfs_register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
X {
@@ -557,19 +531,10 @@
X return -EIO;
X }
X
- /*
- * Init kernel installed video drivers
- */
-
X #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
X videodev_proc_create ();
X #endif
X
- while(vfli->init!=NULL)
- {
- vfli->init(vfli);
- vfli++;
- }


X return 0;
X }
X

diff -u --recursive --new-file v2.4.12/linux/drivers/message/fusion/isense.c linux/drivers/message/fusion/isense.c
--- v2.4.12/linux/drivers/message/fusion/isense.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/isense.c Thu Oct 11 09:14:32 2001
@@ -87,6 +87,7 @@
X EXPORT_NO_SYMBOLS;
X MODULE_AUTHOR(MODULEAUTHOR);
X MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
X
X /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
X int __init isense_init(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/Config.in linux/drivers/message/i2o/Config.in
--- v2.4.12/linux/drivers/message/i2o/Config.in Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/Config.in Wed Apr 12 09:38:53 2000
@@ -0,0 +1,16 @@
+mainmenu_option next_comment
+comment 'I2O device support'
+
+tristate 'I2O support' CONFIG_I2O
+
+if [ "$CONFIG_PCI" = "y" ]; then
+ dep_tristate ' I2O PCI support' CONFIG_I2O_PCI $CONFIG_I2O
+fi
+dep_tristate ' I2O Block OSM' CONFIG_I2O_BLOCK $CONFIG_I2O
+if [ "$CONFIG_NET" = "y" ]; then
+ dep_tristate ' I2O LAN OSM' CONFIG_I2O_LAN $CONFIG_I2O
+fi
+dep_tristate ' I2O SCSI OSM' CONFIG_I2O_SCSI $CONFIG_I2O $CONFIG_SCSI
+dep_tristate ' I2O /proc support' CONFIG_I2O_PROC $CONFIG_I2O
+
+endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/Makefile linux/drivers/message/i2o/Makefile
--- v2.4.12/linux/drivers/message/i2o/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/Makefile Fri Dec 29 14:07:21 2000
@@ -0,0 +1,20 @@
+#
+# Makefile for the kernel I2O OSM.
+#
+# Note : at this point, these files are compiled on all systems.
+# In the future, some of these should be built conditionally.
+#
+
+O_TARGET := i2o.o
+
+export-objs := i2o_pci.o i2o_core.o i2o_config.o i2o_block.o i2o_lan.o i2o_scsi.o i2o_proc.o
+
+obj-$(CONFIG_I2O_PCI) += i2o_pci.o
+obj-$(CONFIG_I2O) += i2o_core.o i2o_config.o
+obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
+obj-$(CONFIG_I2O_LAN) += i2o_lan.o
+obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o
+obj-$(CONFIG_I2O_PROC) += i2o_proc.o
+
+include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/README linux/drivers/message/i2o/README
--- v2.4.12/linux/drivers/message/i2o/README Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/README Mon Jun 19 13:30:55 2000
@@ -0,0 +1,98 @@
+
+ Linux I2O Support (c) Copyright 1999 Red Hat Software
+ and others.
+
+ 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.
+
+AUTHORS (so far)
+
+Alan Cox, Building Number Three Ltd.
+ Core code, SCSI and Block OSMs
+
+Steve Ralston, LSI Logic Corp.
+ Debugging SCSI and Block OSM
+
+Deepak Saxena, Intel Corp.
+ Various core/block extensions
+ /proc interface, bug fixes
+ Ioctl interfaces for control
+ Debugging LAN OSM
+
+Philip Rumpf
+ Fixed assorted dumb SMP locking bugs
+
+Juha Sievanen, University of Helsinki Finland
+ LAN OSM code
+ /proc interface to LAN class
+ Bug fixes
+ Core code extensions
+
+Auvo Häkkinen, University of Helsinki Finland
+ LAN OSM code
+ /Proc interface to LAN class
+ Bug fixes
+ Core code extensions
+
+Taneli Vähäkangas, University of Helsinki Finland
+ Fixes to i2o_config
+
+CREDITS
+
+ This work was made possible by
+
+Red Hat Software
+ Funding for the Building #3 part of the project
+
+Symbios Logic (Now LSI)
+ Host adapters, hints, known to work platforms when I hit
+ compatibility problems
+
+BoxHill Corporation
+ Loan of initial FibreChannel disk array used for development work.
+
+European Comission
+ Funding the work done by the University of Helsinki
+
+SysKonnect
+ Loan of FDDI and Gigabit Ethernet cards
+
+ASUSTeK
+ Loan of I2O motherboard
+
+STATUS:
+
+o The core setup works within limits.
+o The scsi layer seems to almost work.
+ I'm still chasing down the hang bug.
+o The block OSM is mostly functional
+o LAN OSM works with FDDI and Ethernet cards.
+
+TO DO:
+
+General:
+o Provide hidden address space if asked
+o Long term message flow control
+o PCI IOP's without interrupts are not supported yet
+o Push FAIL handling into the core
+o DDM control interfaces for module load etc
+o Add I2O 2.0 support (Deffered to 2.5 kernel)
+
+Block:
+o Multiple major numbers
+o Read ahead and cache handling stuff. Talk to Ingo and people
+o Power management
+o Finish Media changers
+
+SCSI:
+o Find the right way to associate drives/luns/busses
+
+Lan:
+o Performance tuning
+o Test Fibre Channel code
+
+Tape:
+o Anyone seen anything implementing this ?
+ (D.S: Will attempt to do so if spare cycles permit)
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/README.ioctl linux/drivers/message/i2o/README.ioctl
--- v2.4.12/linux/drivers/message/i2o/README.ioctl Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/README.ioctl Mon Jun 19 13:30:55 2000
@@ -0,0 +1,394 @@
+
+Linux I2O User Space Interface
+rev 0.3 - 04/20/99
+
+=============================================================================
+Originally written by Deepak Saxena(dee...@plexity.net)
+Currently maintained by Deepak Saxena(dee...@plexity.net)
+=============================================================================
+
+I. Introduction
+
+The Linux I2O subsystem provides a set of ioctl() commands that can be
+utilized by user space applications to communicate with IOPs and devices
+on individual IOPs. This document defines the specific ioctl() commands
+that are available to the user and provides examples of their uses.
+
+This document assumes the reader is familiar with or has access to the
+I2O specification as no I2O message parameters are outlined. For information
+on the specification, see http://www.i2osig.org
+
+This document and the I2O user space interface are currently maintained
+by Deepak Saxena. Please send all comments, errata, and bug fixes to
+dee...@csociety.purdue.edu
+
+II. IOP Access
+
+Access to the I2O subsystem is provided through the device file named
+/dev/i2o/ctl. This file is a character file with major number 10 and minor


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 23'
echo 'File patch-2.4.13 is continued in part 24'
echo "24" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:54 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part24

#!/bin/sh -x
# this is part 24 of a 53 - part archive


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

if test "$Scheck" != 24; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+number 166. It can be created through the following command:
+
+ mknod /dev/i2o/ctl c 10 166
+
+III. Determining the IOP Count
+
+ SYNOPSIS
+
+ ioctl(fd, I2OGETIOPS, int *count);
+
+ u8 count[MAX_I2O_CONTROLLERS];
+
+ DESCRIPTION
+
+ This function returns the system's active IOP table. count should
+ point to a buffer containing MAX_I2O_CONTROLLERS entries. Upon
+ returning, each entry will contain a non-zero value if the given
+ IOP unit is active, and NULL if it is inactive or non-existent.
+
+ RETURN VALUE.
+
+ Returns 0 if no errors occur, and -1 otherwise. If an error occurs,
+ errno is set appropriately:
+
+ EFAULT Invalid user space pointer was passed
+
+IV. Getting Hardware Resource Table
+
+ SYNOPSIS
+
+ ioctl(fd, I2OHRTGET, struct i2o_cmd_hrt *hrt);
+
+ struct i2o_cmd_hrtlct
+ {
+ u32 iop; /* IOP unit number */
+ void *resbuf; /* Buffer for result */
+ u32 *reslen; /* Buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function returns the Hardware Resource Table of the IOP specified
+ by hrt->iop in the buffer pointed to by hrt->resbuf. The actual size of
+ the data is written into *(hrt->reslen).
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriately:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(hrt->reslen)
+
+V. Getting Logical Configuration Table
+
+ SYNOPSIS
+
+ ioctl(fd, I2OLCTGET, struct i2o_cmd_lct *lct);
+
+ struct i2o_cmd_hrtlct
+ {
+ u32 iop; /* IOP unit number */
+ void *resbuf; /* Buffer for result */
+ u32 *reslen; /* Buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function returns the Logical Configuration Table of the IOP specified
+ by lct->iop in the buffer pointed to by lct->resbuf. The actual size of
+ the data is written into *(lct->reslen).
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriately:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(lct->reslen)
+
+VI. Settting Parameters
+
+ SYNOPSIS
+
+ ioctl(fd, I2OPARMSET, struct i2o_parm_setget *ops);
+
+ struct i2o_cmd_psetget
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device TID */
+ void *opbuf; /* Operation List buffer */
+ u32 oplen; /* Operation List buffer length in bytes */
+ void *resbuf; /* Result List buffer */
+ u32 *reslen; /* Result List buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts a UtilParamsSet message to the device identified
+ by ops->iop and ops->tid. The operation list for the message is
+ sent through the ops->opbuf buffer, and the result list is written
+ into the buffer pointed to by ops->resbuf. The number of bytes
+ written is placed into *(ops->reslen).
+
+ RETURNS
+
+ The return value is the size in bytes of the data written into
+ ops->resbuf if no errors occur. If an error occurs, -1 is returned
+ and errno is set appropriatly:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+ A return value of 0 does not mean that the value was actually
+ changed properly on the IOP. The user should check the result
+ list to determine the specific status of the transaction.
+
+VII. Getting Parameters
+
+ SYNOPSIS
+
+ ioctl(fd, I2OPARMGET, struct i2o_parm_setget *ops);
+
+ struct i2o_parm_setget
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device TID */
+ void *opbuf; /* Operation List buffer */
+ u32 oplen; /* Operation List buffer length in bytes */
+ void *resbuf; /* Result List buffer */
+ u32 *reslen; /* Result List buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts a UtilParamsGet message to the device identified
+ by ops->iop and ops->tid. The operation list for the message is
+ sent through the ops->opbuf buffer, and the result list is written
+ into the buffer pointed to by ops->resbuf. The actual size of data
+ written is placed into *(ops->reslen).
+
+ RETURNS
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+ A return value of 0 does not mean that the value was actually
+ properly retreived. The user should check the result list
+ to determine the specific status of the transaction.
+
+VIII. Downloading Software
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWDL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 flags; /* DownloadFlags field */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Pointer to software buffer */
+ u32 *swlen; /* Length of software buffer */
+ u32 *maxfrag; /* Number of fragments */
+ u32 *curfrag; /* Current fragment number */
+ };
+
+ DESCRIPTION
+
+ This function downloads a software fragment pointed by sw->buf
+ to the iop identified by sw->iop. The DownloadFlags, SwID, SwType
+ and SwSize fields of the ExecSwDownload message are filled in with
+ the values of sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen).
+
+ The fragments _must_ be sent in order and be 8K in size. The last
+ fragment _may_ be shorter, however. The kernel will compute its
+ size based on information in the sw->swlen field.
+
+ Please note that SW transfers can take a long time.
+
+ RETURNS
+
+ This function returns 0 no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+IX. Uploading Software
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 flags; /* UploadFlags */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Pointer to software buffer */
+ u32 *swlen; /* Length of software buffer */
+ u32 *maxfrag; /* Number of fragments */
+ u32 *curfrag; /* Current fragment number */
+ };
+
+ DESCRIPTION
+
+ This function uploads a software fragment from the IOP identified
+ by sw->iop, sw->sw_type, sw->sw_id and optionally sw->swlen fields.
+ The UploadFlags, SwID, SwType and SwSize fields of the ExecSwUpload
+ message are filled in with the values of sw->flags, sw->sw_id,
+ sw->sw_type and *(sw->swlen).
+
+ The fragments _must_ be requested in order and be 8K in size. The
+ user is responsible for allocating memory pointed by sw->buf. The
+ last fragment _may_ be shorter.
+
+ Please note that SW transfers can take a long time.
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+X. Removing Software
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWDEL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 flags; /* RemoveFlags */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Unused */
+ u32 *swlen; /* Length of the software data */
+ u32 *maxfrag; /* Unused */
+ u32 *curfrag; /* Unused */
+ };
+
+ DESCRIPTION
+
+ This function removes software from the IOP identified by sw->iop.
+ The RemoveFlags, SwID, SwType and SwSize fields of the ExecSwRemove message
+ are filled in with the values of sw->flags, sw->sw_id, sw->sw_type and
+ *(sw->swlen). Give zero in *(sw->len) if the value is unknown. IOP uses
+ *(sw->swlen) value to verify correct identication of the module to remove.
+ The actual size of the module is written into *(sw->swlen).
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+X. Validating Configuration
+
+ SYNOPSIS
+
+ ioctl(fd, I2OVALIDATE, int *iop);
+ u32 iop;
+
+ DESCRIPTION
+
+ This function posts an ExecConfigValidate message to the controller
+ identified by iop. This message indicates that the the current
+ configuration is accepted. The iop changes the status of suspect drivers
+ to valid and may delete old drivers from its store.
+
+ RETURNS
+
+ This function returns 0 if no erro occur. If an error occurs, -1 is
+ returned and errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENXIO Invalid IOP number
+
+XI. Configuration Dialog
+
+ SYNOPSIS
+
+ ioctl(fd, I2OHTML, struct i2o_html *htquery);
+ struct i2o_html
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device ID */
+ u32 page; /* HTML page */
+ void *resbuf; /* Buffer for reply HTML page */
+ u32 *reslen; /* Length in bytes of reply buffer */
+ void *qbuf; /* Pointer to HTTP query string */
+ u32 qlen; /* Length in bytes of query string buffer */
+ };
+
+ DESCRIPTION
+
+ This function posts an UtilConfigDialog message to the device identified
+ by htquery->iop and htquery->tid. The requested HTML page number is
+ provided by the htquery->page field, and the resultant data is stored
+ in the buffer pointed to by htquery->resbuf. If there is an HTTP query
+ string that is to be sent to the device, it should be sent in the buffer
+ pointed to by htquery->qbuf. If there is no query string, this field
+ should be set to NULL. The actual size of the reply received is written
+ into *(htquery->reslen).
+
+ RETURNS
+
+ This function returns 0 if no error occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+
+XII. Events
+
+ In the process of determining this. Current idea is to have use
+ the select() interface to allow user apps to periodically poll
+ the /dev/i2o/ctl device for events. When select() notifies the user
+ that an event is available, the user would call read() to retrieve
+ a list of all the events that are pending for the specific device.
+
+=============================================================================
+Revision History
+=============================================================================
+
+Rev 0.1 - 04/01/99
+- Initial revision
+
+Rev 0.2 - 04/06/99
+- Changed return values to match UNIX ioctl() standard. Only return values
+ are 0 and -1. All errors are reported through errno.
+- Added summary of proposed possible event interfaces
+
+Rev 0.3 - 04/20/99
+- Changed all ioctls() to use pointers to user data instead of actual data
+- Updated error values to match the code
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c
--- v2.4.12/linux/drivers/message/i2o/i2o_block.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_block.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,2043 @@
+/*
+ * I2O Random Block Storage Class OSM
+ *
+ * (C) Copyright 1999 Red Hat Software
+ *
+ * Written by Alan Cox, Building Number Three 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 is a beta test release. Most of the good code was taken
+ * from the nbd driver by Pavel Machek, who in turn took some of it
+ * from loop.c. Isn't free software great for reusability 8)
+ *
+ * Fixes/additions:
+ * Steve Ralston:
+ * Multiple device handling error fixes,
+ * Added a queue depth.
+ * Alan Cox:
+ * FC920 has an rmw bug. Dont or in the end marker.
+ * Removed queue walk, fixed for 64bitness.
+ * Deepak Saxena:
+ * Independent queues per IOP
+ * Support for dynamic device creation/deletion
+ * Code cleanup
+ * Support for larger I/Os through merge* functions
+ * (taken from DAC960 driver)
+ * Boji T Kannanthanam:
+ * Set the I2O Block devices to be detected in increasing
+ * order of TIDs during boot.
+ * Search and set the I2O block device that we boot off from as
+ * the first device to be claimed (as /dev/i2o/hda)
+ * Properly attach/detach I2O gendisk structure from the system
+ * gendisk list. The I2O block devices now appear in
+ * /proc/partitions.
+ *
+ * To do:
+ * Serial number scanning to find duplicates for FC multipathing
+ */
+
+#include <linux/major.h>
+
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/ioctl.h>
+#include <linux/i2o.h>
+#include <linux/blkdev.h>
+#include <linux/blkpg.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/spinlock.h>
+
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <linux/completion.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <linux/smp_lock.h>
+#include <linux/wait.h>
+
+#define MAJOR_NR I2O_MAJOR
+
+#include <linux/blk.h>
+
+#define MAX_I2OB 16
+
+#define MAX_I2OB_DEPTH 128
+#define MAX_I2OB_RETRIES 4
+
+//#define DRIVERDEBUG
+#ifdef DRIVERDEBUG
+#define DEBUG( s ) printk( s )
+#else
+#define DEBUG( s )
+#endif
+
+/*
+ * Events that this OSM is interested in
+ */
+#define I2OB_EVENT_MASK (I2O_EVT_IND_BSA_VOLUME_LOAD | \
+ I2O_EVT_IND_BSA_VOLUME_UNLOAD | \
+ I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ | \
+ I2O_EVT_IND_BSA_CAPACITY_CHANGE | \
+ I2O_EVT_IND_BSA_SCSI_SMART )
+
+
+/*
+ * I2O Block Error Codes - should be in a header file really...
+ */
+#define I2O_BSA_DSC_SUCCESS 0x0000
+#define I2O_BSA_DSC_MEDIA_ERROR 0x0001
+#define I2O_BSA_DSC_ACCESS_ERROR 0x0002
+#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003
+#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004
+#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005
+#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006
+#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007
+#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008
+#define I2O_BSA_DSC_BUS_FAILURE 0x0009
+#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A
+#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B
+#define I2O_BSA_DSC_DEVICE_RESET 0x000C
+#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D
+#define I2O_BSA_DSC_TIMEOUT 0x000E
+
+/*
+ * Some of these can be made smaller later
+ */
+
+static int i2ob_blksizes[MAX_I2OB<<4];
+static int i2ob_hardsizes[MAX_I2OB<<4];
+static int i2ob_sizes[MAX_I2OB<<4];
+static int i2ob_media_change_flag[MAX_I2OB];
+static u32 i2ob_max_sectors[MAX_I2OB<<4];
+
+static int i2ob_context;
+
+/*
+ * I2O Block device descriptor
+ */
+struct i2ob_device
+{
+ struct i2o_controller *controller;
+ struct i2o_device *i2odev;
+ int unit;
+ int tid;
+ int flags;
+ int refcnt;
+ struct request *head, *tail;
+ request_queue_t *req_queue;
+ int max_segments;
+ int done_flag;
+ int constipated;
+ int depth;
+};
+
+/*
+ * FIXME:
+ * We should cache align these to avoid ping-ponging lines on SMP
+ * boxes under heavy I/O load...
+ */
+struct i2ob_request
+{
+ struct i2ob_request *next;
+ struct request *req;
+ int num;
+};
+
+/*
+ * Per IOP requst queue information
+ *
+ * We have a separate requeust_queue_t per IOP so that a heavilly
+ * loaded I2O block device on an IOP does not starve block devices
+ * across all I2O controllers.
+ *
+ */
+struct i2ob_iop_queue
+{
+ atomic_t queue_depth;
+ struct i2ob_request request_queue[MAX_I2OB_DEPTH];
+ struct i2ob_request *i2ob_qhead;
+ request_queue_t req_queue;
+};
+static struct i2ob_iop_queue *i2ob_queues[MAX_I2O_CONTROLLERS];
+static struct i2ob_request *i2ob_backlog[MAX_I2O_CONTROLLERS];
+static struct i2ob_request *i2ob_backlog_tail[MAX_I2O_CONTROLLERS];
+
+/*
+ * Each I2O disk is one of these.
+ */
+
+static struct i2ob_device i2ob_dev[MAX_I2OB<<4];
+static int i2ob_dev_count = 0;
+static struct hd_struct i2ob[MAX_I2OB<<4];
+static struct gendisk i2ob_gendisk; /* Declared later */
+
+/*
+ * Mutex and spin lock for event handling synchronization
+ * evt_msg contains the last event.
+ */
+static DECLARE_MUTEX_LOCKED(i2ob_evt_sem);
+static DECLARE_COMPLETION(i2ob_thread_dead);
+static spinlock_t i2ob_evt_lock = SPIN_LOCK_UNLOCKED;
+static u32 evt_msg[MSG_FRAME_SIZE>>2];
+
+static struct timer_list i2ob_timer;
+static int i2ob_timer_started = 0;
+
+static void i2o_block_reply(struct i2o_handler *, struct i2o_controller *,
+ struct i2o_message *);
+static void i2ob_new_device(struct i2o_controller *, struct i2o_device *);
+static void i2ob_del_device(struct i2o_controller *, struct i2o_device *);
+static void i2ob_reboot_event(void);
+static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
+static void i2ob_end_request(struct request *);
+static void i2ob_request(request_queue_t *);
+static int i2ob_backlog_request(struct i2o_controller *, struct i2ob_device *);
+static int i2ob_init_iop(unsigned int);
+static request_queue_t* i2ob_get_queue(kdev_t);
+static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
+static int do_i2ob_revalidate(kdev_t, int);
+static int i2ob_evt(void *);
+
+static int evt_pid = 0;
+static int evt_running = 0;
+static int scan_unit = 0;
+
+/*
+ * I2O OSM registration structure...keeps getting bigger and bigger :)
+ */
+static struct i2o_handler i2o_block_handler =
+{
+ i2o_block_reply,
+ i2ob_new_device,
+ i2ob_del_device,
+ i2ob_reboot_event,
+ "I2O Block OSM",
+ 0,
+ I2O_CLASS_RANDOM_BLOCK_STORAGE
+};
+
+/*
+ * Get a message
+ */
+
+static u32 i2ob_get(struct i2ob_device *dev)
+{
+ struct i2o_controller *c=dev->controller;
+ return I2O_POST_READ32(c);
+}
+
+/*
+ * Turn a Linux block request into an I2O block read/write.
+ */
+
+static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq, u32 base, int unit)
+{
+ struct i2o_controller *c = dev->controller;
+ int tid = dev->tid;
+ unsigned long msg;
+ unsigned long mptr;
+ u64 offset;
+ struct request *req = ireq->req;
+ struct buffer_head *bh = req->bh;
+ int count = req->nr_sectors<<9;
+ char *last = NULL;
+ unsigned short size = 0;
+
+ // printk(KERN_INFO "i2ob_send called\n");
+ /* Map the message to a virtual address */
+ msg = c->mem_offset + m;
+
+ /*
+ * Build the message based on the request.
+ */
+ __raw_writel(i2ob_context|(unit<<8), msg+8);
+ __raw_writel(ireq->num, msg+12);
+ __raw_writel(req->nr_sectors << 9, msg+20);
+
+ /*
+ * Mask out partitions from now on
+ */
+ unit &= 0xF0;
+
+ /* This can be optimised later - just want to be sure its right for
+ starters */
+ offset = ((u64)(req->sector+base)) << 9;
+ __raw_writel( offset & 0xFFFFFFFF, msg+24);
+ __raw_writel(offset>>32, msg+28);
+ mptr=msg+32;
+
+ if(req->cmd == READ)
+ {
+ __raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
+ while(bh!=NULL)
+ {
+ if(bh->b_data == last) {
+ size += bh->b_size;
+ last += bh->b_size;
+ if(bh->b_reqnext)
+ __raw_writel(0x14000000|(size), mptr-8);
+ else
+ __raw_writel(0xD4000000|(size), mptr-8);
+ }
+ else
+ {
+ if(bh->b_reqnext)
+ __raw_writel(0x10000000|(bh->b_size), mptr);
+ else
+ __raw_writel(0xD0000000|(bh->b_size), mptr);
+ __raw_writel(virt_to_bus(bh->b_data), mptr+4);
+ mptr += 8;
+ size = bh->b_size;
+ last = bh->b_data + size;
+ }
+
+ count -= bh->b_size;
+ bh = bh->b_reqnext;
+ }
+ /*
+ * Heuristic for now since the block layer doesnt give
+ * us enough info. If its a big write assume sequential
+ * readahead on controller. If its small then don't read
+ * ahead but do use the controller cache.
+ */
+ if(size >= 8192)
+ __raw_writel((8<<24)|(1<<16)|8, msg+16);
+ else
+ __raw_writel((8<<24)|(1<<16)|4, msg+16);
+ }
+ else if(req->cmd == WRITE)
+ {
+ __raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
+ while(bh!=NULL)
+ {
+ if(bh->b_data == last) {
+ size += bh->b_size;
+ last += bh->b_size;
+ if(bh->b_reqnext)
+ __raw_writel(0x14000000|(size), mptr-8);
+ else
+ __raw_writel(0xD4000000|(size), mptr-8);
+ }
+ else
+ {
+ if(bh->b_reqnext)
+ __raw_writel(0x14000000|(bh->b_size), mptr);
+ else
+ __raw_writel(0xD4000000|(bh->b_size), mptr);
+ __raw_writel(virt_to_bus(bh->b_data), mptr+4);
+ mptr += 8;
+ size = bh->b_size;
+ last = bh->b_data + size;
+ }
+
+ count -= bh->b_size;
+ bh = bh->b_reqnext;
+ }
+
+ if(c->battery)
+ {
+
+ if(size>16384)
+ __raw_writel(4, msg+16);
+ else
+ /*
+ * Allow replies to come back once data is cached in the controller
+ * This allows us to handle writes quickly thus giving more of the
+ * queue to reads.
+ */
+ __raw_writel(16, msg+16);
+ }
+ else
+ {
+ /* Large write, don't cache */
+ if(size>8192)
+ __raw_writel(4, msg+16);
+ else
+ /* write through */
+ __raw_writel(8, msg+16);
+ }
+ }
+ __raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
+
+ if(count != 0)
+ {
+ printk(KERN_ERR "Request count botched by %d.\n", count);
+ }
+
+ i2o_post_message(c,m);
+ atomic_inc(&i2ob_queues[c->unit]->queue_depth);


+
+ return 0;
+}
+

+/*
+ * Remove a request from the _locked_ request list. We update both the
+ * list chain and if this is the last item the tail pointer. Caller
+ * must hold the lock.
+ */
+
+static inline void i2ob_unhook_request(struct i2ob_request *ireq,
+ unsigned int iop)
+{
+ ireq->next = i2ob_queues[iop]->i2ob_qhead;
+ i2ob_queues[iop]->i2ob_qhead = ireq;
+}
+
+/*
+ * Request completion handler
+ */
+
+static inline void i2ob_end_request(struct request *req)
+{
+ /*
+ * Loop until all of the buffers that are linked
+ * to this request have been marked updated and
+ * unlocked.
+ */
+
+ while (end_that_request_first( req, !req->errors, "i2o block" ));
+
+ /*
+ * It is now ok to complete the request.
+ */
+ end_that_request_last( req );
+}
+
+/*
+ * Request merging functions
+ */
+static inline int i2ob_new_segment(request_queue_t *q, struct request *req,
+ int __max_segments)
+{
+ int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
+
+ if (__max_segments < max_segments)
+ max_segments = __max_segments;
+
+ if (req->nr_segments < max_segments) {
+ req->nr_segments++;
+ return 1;
+ }


+ return 0;
+}
+

+static int i2ob_back_merge(request_queue_t *q, struct request *req,
+ struct buffer_head *bh, int __max_segments)
+{
+ if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
+ return 1;
+ return i2ob_new_segment(q, req, __max_segments);
+}
+
+static int i2ob_front_merge(request_queue_t *q, struct request *req,
+ struct buffer_head *bh, int __max_segments)
+{
+ if (bh->b_data + bh->b_size == req->bh->b_data)
+ return 1;
+ return i2ob_new_segment(q, req, __max_segments);
+}
+
+static int i2ob_merge_requests(request_queue_t *q,
+ struct request *req,
+ struct request *next,
+ int __max_segments)
+{
+ int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
+ int total_segments = req->nr_segments + next->nr_segments;
+
+ if (__max_segments < max_segments)
+ max_segments = __max_segments;
+
+ if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ total_segments--;
+
+ if (total_segments > max_segments)
+ return 0;
+
+ req->nr_segments = total_segments;


+ return 1;
+}
+

+static int i2ob_flush(struct i2o_controller *c, struct i2ob_device *d, int unit)
+{
+ unsigned long msg;
+ u32 m = i2ob_get(d);
+
+ if(m == 0xFFFFFFFF)
+ return -1;
+
+ msg = c->mem_offset + m;
+
+ /*
+ * Ask the controller to write the cache back. This sorts out
+ * the supertrak firmware flaw and also does roughly the right
+ * thing for other cases too.
+ */
+
+ __raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+ __raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
+ __raw_writel(i2ob_context|(unit<<8), msg+8);
+ __raw_writel(0, msg+12);
+ __raw_writel(60<<16, msg+16);
+
+ i2o_post_message(c,m);


+ return 0;
+}
+

+/*
+ * OSM reply handler. This gets all the message replies
+ */
+
+static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)


+{
+ unsigned long flags;

+ struct i2ob_request *ireq = NULL;
+ u8 st;
+ u32 *m = (u32 *)msg;
+ u8 unit = (m[2]>>8)&0xF0; /* low 4 bits are partition */
+ struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)];
+
+ /*
+ * Pull the lock over ready
+ */
+
+ spin_lock_prefetch(&io_request_lock);
+
+ /*
+ * FAILed message
+ */
+ if(m[0] & (1<<13))
+ {
+ /*
+ * FAILed message from controller
+ * We increment the error count and abort it
+ *
+ * In theory this will never happen. The I2O block class
+ * speficiation states that block devices never return
+ * FAILs but instead use the REQ status field...but
+ * better be on the safe side since no one really follows
+ * the spec to the book :)
+ */
+ ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
+ ireq->req->errors++;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ i2ob_unhook_request(ireq, c->unit);
+ i2ob_end_request(ireq->req);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ /* Now flush the message by making it a NOP */
+ m[0]&=0x00FFFFFF;
+ m[0]|=(I2O_CMD_UTIL_NOP)<<24;
+ i2o_post_message(c,virt_to_bus(m));
+
+ return;
+ }
+
+ if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
+ {
+ spin_lock(&i2ob_evt_lock);
+ memcpy(evt_msg, msg, (m[0]>>16)<<2);
+ spin_unlock(&i2ob_evt_lock);
+ up(&i2ob_evt_sem);
+ return;
+ }
+
+ if(msg->function == I2O_CMD_BLOCK_CFLUSH)
+ {
+ spin_lock_irqsave(&io_request_lock, flags);
+ dev->constipated=0;
+ DEBUG(("unconstipated\n"));
+ if(i2ob_backlog_request(c, dev)==0)
+ i2ob_request(dev->req_queue);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return;
+ }
+
+ if(!dev->i2odev)
+ {
+ /*
+ * This is HACK, but Intel Integrated RAID allows user
+ * to delete a volume that is claimed, locked, and in use
+ * by the OS. We have to check for a reply from a
+ * non-existent device and flag it as an error or the system
+ * goes kaput...
+ */
+ ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
+ ireq->req->errors++;
+ printk(KERN_WARNING "I2O Block: Data transfer to deleted device!\n");
+ spin_lock_irqsave(&io_request_lock, flags);
+ i2ob_unhook_request(ireq, c->unit);
+ i2ob_end_request(ireq->req);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return;
+ }
+
+ /*
+ * Lets see what is cooking. We stuffed the
+ * request in the context.
+ */
+
+ ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
+ st=m[4]>>24;
+
+ if(st!=0)
+ {
+ int err;
+ char *bsa_errors[] =
+ {
+ "Success",
+ "Media Error",
+ "Failure communicating to device",
+ "Device Failure",
+ "Device is not ready",
+ "Media not present",
+ "Media is locked by another user",
+ "Media has failed",
+ "Failure communicating to device",
+ "Device bus failure",
+ "Device is locked by another user",
+ "Device is write protected",
+ "Device has reset",
+ "Volume has changed, waiting for acknowledgement"
+ };
+
+ err = m[4]&0xFFFF;
+
+ /*
+ * Device not ready means two things. One is that the
+ * the thing went offline (but not a removal media)
+ *
+ * The second is that you have a SuperTrak 100 and the
+ * firmware got constipated. Unlike standard i2o card
+ * setups the supertrak returns an error rather than
+ * blocking for the timeout in these cases.
+ */
+
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if(err==4)
+ {
+ /*
+ * Time to uncork stuff
+ */
+
+ if(!dev->constipated)
+ {
+ dev->constipated = 1;
+ DEBUG(("constipated\n"));
+ /* Now pull the chain */
+ if(i2ob_flush(c, dev, unit)<0)
+ {
+ DEBUG(("i2ob: Unable to queue flush. Retrying I/O immediately.\n"));
+ dev->constipated=0;
+ }
+ DEBUG(("flushing\n"));
+ }
+
+ /*
+ * Recycle the request
+ */
+
+// i2ob_unhook_request(ireq, c->unit);
+
+ /*
+ * Place it on the recycle queue
+ */
+
+ ireq->next = NULL;
+ if(i2ob_backlog_tail[c->unit]!=NULL)
+ i2ob_backlog_tail[c->unit]->next = ireq;
+ else
+ i2ob_backlog[c->unit] = ireq;
+ i2ob_backlog_tail[c->unit] = ireq;
+
+ atomic_dec(&i2ob_queues[c->unit]->queue_depth);
+
+ /*
+ * If the constipator flush failed we want to
+ * poke the queue again.
+ */
+
+ i2ob_request(dev->req_queue);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ /*
+ * and out
+ */
+
+ return;
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name,
+ bsa_errors[m[4]&0XFFFF]);
+ if(m[4]&0x00FF0000)
+ printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF );
+ printk(".\n");
+ ireq->req->errors++;
+ }
+ else
+ ireq->req->errors = 0;
+
+ /*
+ * Dequeue the request. We use irqsave locks as one day we
+ * may be running polled controllers from a BH...
+ */
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ i2ob_unhook_request(ireq, c->unit);
+ i2ob_end_request(ireq->req);
+ atomic_dec(&i2ob_queues[c->unit]->queue_depth);
+
+ /*
+ * We may be able to do more I/O
+ */
+
+ if(i2ob_backlog_request(c, dev)==0)
+ i2ob_request(dev->req_queue);
+
+ spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+/*
+ * Event handler. Needs to be a separate thread b/c we may have
+ * to do things like scan a partition table, or query parameters
+ * which cannot be done from an interrupt or from a bottom half.
+ */
+static int i2ob_evt(void *dummy)
+{
+ unsigned int evt;
+ unsigned long flags;
+ int unit;
+ int i;
+ //The only event that has data is the SCSI_SMART event.
+ struct i2o_reply {
+ u32 header[4];
+ u32 evt_indicator;
+ u8 ASC;
+ u8 ASCQ;
+ u8 data[16];
+ } *evt_local;
+
+ lock_kernel();
+ daemonize();
+ unlock_kernel();
+
+ strcpy(current->comm, "i2oblock");
+ evt_running = 1;
+
+ while(1)
+ {
+ if(down_interruptible(&i2ob_evt_sem))
+ {
+ evt_running = 0;
+ printk("exiting...");
+ break;
+ }
+
+ /*
+ * Keep another CPU/interrupt from overwriting the
+ * message while we're reading it
+ *
+ * We stuffed the unit in the TxContext and grab the event mask
+ * None of the BSA we care about events have EventData
+ */
+ spin_lock_irqsave(&i2ob_evt_lock, flags);
+ evt_local = (struct i2o_reply *)evt_msg;
+ spin_unlock_irqrestore(&i2ob_evt_lock, flags);
+
+ unit = evt_local->header[3];
+ evt = evt_local->evt_indicator;
+
+ switch(evt)
+ {
+ /*
+ * New volume loaded on same TID, so we just re-install.
+ * The TID/controller don't change as it is the same
+ * I2O device. It's just new media that we have to
+ * rescan.
+ */
+ case I2O_EVT_IND_BSA_VOLUME_LOAD:
+ {
+ i2ob_install_device(i2ob_dev[unit].i2odev->controller,
+ i2ob_dev[unit].i2odev, unit);
+ break;
+ }
+
+ /*
+ * No media, so set all parameters to 0 and set the media
+ * change flag. The I2O device is still valid, just doesn't
+ * have media, so we don't want to clear the controller or
+ * device pointer.
+ */
+ case I2O_EVT_IND_BSA_VOLUME_UNLOAD:
+ {
+ for(i = unit; i <= unit+15; i++)
+ {
+ i2ob_sizes[i] = 0;
+ i2ob_hardsizes[i] = 0;
+ i2ob_max_sectors[i] = 0;
+ i2ob[i].nr_sects = 0;
+ i2ob_gendisk.part[i].nr_sects = 0;
+ }
+ i2ob_media_change_flag[unit] = 1;
+ break;
+ }
+
+ case I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ:
+ printk(KERN_WARNING "%s: Attempt to eject locked media\n",
+ i2ob_dev[unit].i2odev->dev_name);
+ break;
+
+ /*
+ * The capacity has changed and we are going to be
+ * updating the max_sectors and other information
+ * about this disk. We try a revalidate first. If
+ * the block device is in use, we don't want to
+ * do that as there may be I/Os bound for the disk
+ * at the moment. In that case we read the size
+ * from the device and update the information ourselves
+ * and the user can later force a partition table
+ * update through an ioctl.
+ */
+ case I2O_EVT_IND_BSA_CAPACITY_CHANGE:
+ {
+ u64 size;
+
+ if(do_i2ob_revalidate(MKDEV(MAJOR_NR, unit),0) != -EBUSY)
+ continue;
+
+ if(i2ob_query_device(&i2ob_dev[unit], 0x0004, 0, &size, 8) !=0 )
+ i2ob_query_device(&i2ob_dev[unit], 0x0000, 4, &size, 8);
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ i2ob_sizes[unit] = (int)(size>>10);
+ i2ob_gendisk.part[unit].nr_sects = size>>9;
+ i2ob[unit].nr_sects = (int)(size>>9);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ break;
+ }
+
+ /*
+ * We got a SCSI SMART event, we just log the relevant
+ * information and let the user decide what they want
+ * to do with the information.
+ */
+ case I2O_EVT_IND_BSA_SCSI_SMART:
+ {
+ char buf[16];
+ printk(KERN_INFO "I2O Block: %s received a SCSI SMART Event\n",i2ob_dev[unit].i2odev->dev_name);
+ evt_local->data[16]='\0';
+ sprintf(buf,"%s",&evt_local->data[0]);
+ printk(KERN_INFO " Disk Serial#:%s\n",buf);
+ printk(KERN_INFO " ASC 0x%02x \n",evt_local->ASC);
+ printk(KERN_INFO " ASCQ 0x%02x \n",evt_local->ASCQ);
+ break;
+ }
+
+ /*
+ * Non event
+ */
+
+ case 0:
+ break;
+
+ /*
+ * An event we didn't ask for. Call the card manufacturer
+ * and tell them to fix their firmware :)
+ */
+ default:
+ printk(KERN_INFO "%s: Received event %d we didn't register for\n"
+ KERN_INFO " Blame the I2O card manufacturer 8)\n",
+ i2ob_dev[unit].i2odev->dev_name, evt);


+ break;
+ }
+ };
+

+ complete_and_exit(&i2ob_thread_dead,0);


+ return 0;
+}
+

+/*
+ * The timer handler will attempt to restart requests
+ * that are queued to the driver. This handler
+ * currently only gets called if the controller
+ * had no more room in its inbound fifo.
+ */
+
+static void i2ob_timer_handler(unsigned long q)


+{
+ unsigned long flags;
+

+ /*
+ * We cannot touch the request queue or the timer
+ * flag without holding the io_request_lock.
+ */
+ spin_lock_irqsave(&io_request_lock,flags);
+
+ /*
+ * Clear the timer started flag so that
+ * the timer can be queued again.
+ */
+ i2ob_timer_started = 0;
+
+ /*
+ * Restart any requests.
+ */
+ i2ob_request((request_queue_t*)q);
+
+ /*
+ * Free the lock.
+ */
+ spin_unlock_irqrestore(&io_request_lock,flags);
+}
+
+static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev)
+{
+ u32 m;
+ struct i2ob_request *ireq;
+
+ while((ireq=i2ob_backlog[c->unit])!=NULL)
+ {
+ int unit;
+
+ if(atomic_read(&i2ob_queues[c->unit]->queue_depth) > dev->depth/4)
+ break;
+
+ m = i2ob_get(dev);
+ if(m == 0xFFFFFFFF)
+ break;
+
+ i2ob_backlog[c->unit] = ireq->next;
+ if(i2ob_backlog[c->unit] == NULL)
+ i2ob_backlog_tail[c->unit] = NULL;
+
+ unit = MINOR(ireq->req->rq_dev);
+ i2ob_send(m, dev, ireq, i2ob[unit].start_sect, unit);
+ }
+ if(i2ob_backlog[c->unit])
+ return 1;


+ return 0;
+}
+

+/*
+ * The I2O block driver is listed as one of those that pulls the
+ * front entry off the queue before processing it. This is important
+ * to remember here. If we drop the io lock then CURRENT will change
+ * on us. We must unlink CURRENT in this routine before we return, if
+ * we use it.
+ */
+
+static void i2ob_request(request_queue_t *q)
+{
+ struct request *req;
+ struct i2ob_request *ireq;
+ int unit;
+ struct i2ob_device *dev;
+ u32 m;
+
+
+ while (!list_empty(&q->queue_head)) {
+ /*
+ * On an IRQ completion if there is an inactive
+ * request on the queue head it means it isnt yet
+ * ready to dispatch.
+ */
+ req = blkdev_entry_next_request(&q->queue_head);
+
+ if(req->rq_status == RQ_INACTIVE)
+ return;
+
+ unit = MINOR(req->rq_dev);
+ dev = &i2ob_dev[(unit&0xF0)];
+
+ /*
+ * Queue depths probably belong with some kind of
+ * generic IOP commit control. Certainly its not right
+ * its global!
+ */
+ if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) >= dev->depth)
+ break;
+
+ /*
+ * Is the channel constipated ?
+ */
+
+ if(i2ob_backlog[dev->unit]!=NULL)
+ break;
+
+ /* Get a message */
+ m = i2ob_get(dev);
+
+ if(m==0xFFFFFFFF)
+ {
+ /*
+ * See if the timer has already been queued.
+ */
+ if (!i2ob_timer_started)
+ {
+ DEBUG((KERN_ERR "i2ob: starting timer\n"));
+
+ /*
+ * Set the timer_started flag to insure
+ * that the timer is only queued once.
+ * Queing it more than once will corrupt
+ * the timer queue.
+ */
+ i2ob_timer_started = 1;
+
+ /*
+ * Set up the timer to expire in
+ * 500ms.
+ */
+ i2ob_timer.expires = jiffies + (HZ >> 1);
+ i2ob_timer.data = (unsigned int)q;
+
+ /*
+ * Start it.
+ */
+
+ add_timer(&i2ob_timer);


+ return;
+ }
+ }
+

+ /*
+ * Everything ok, so pull from kernel queue onto our queue
+ */
+ req->errors = 0;
+ blkdev_dequeue_request(req);
+ req->waiting = NULL;
+
+ ireq = i2ob_queues[dev->unit]->i2ob_qhead;
+ i2ob_queues[dev->unit]->i2ob_qhead = ireq->next;
+ ireq->req = req;
+
+ i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));


+ }
+}
+
+
+/*

+ * SCSI-CAM for ioctl geometry mapping
+ * Duplicated with SCSI - this should be moved into somewhere common
+ * perhaps genhd ?
+ *
+ * LBA -> CHS mapping table taken from:
+ *
+ * "Incorporating the I2O Architecture into BIOS for Intel Architecture
+ * Platforms"
+ *
+ * This is an I2O document that is only available to I2O members,
+ * not developers.
+ *
+ * From my understanding, this is how all the I2O cards do this
+ *
+ * Disk Size | Sectors | Heads | Cylinders
+ * ---------------+---------+-------+-------------------
+ * 1 < X <= 528M | 63 | 16 | X/(63 * 16 * 512)
+ * 528M < X <= 1G | 63 | 32 | X/(63 * 32 * 512)
+ * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
+ * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
+ *
+ */
+#define BLOCK_SIZE_528M 1081344
+#define BLOCK_SIZE_1G 2097152
+#define BLOCK_SIZE_21G 4403200
+#define BLOCK_SIZE_42G 8806400
+#define BLOCK_SIZE_84G 17612800
+
+static void i2o_block_biosparam(
+ unsigned long capacity,
+ unsigned short *cyls,
+ unsigned char *hds,
+ unsigned char *secs)
+{
+ unsigned long heads, sectors, cylinders;
+
+ sectors = 63L; /* Maximize sectors per track */
+ if(capacity <= BLOCK_SIZE_528M)
+ heads = 16;
+ else if(capacity <= BLOCK_SIZE_1G)
+ heads = 32;
+ else if(capacity <= BLOCK_SIZE_21G)
+ heads = 64;
+ else if(capacity <= BLOCK_SIZE_42G)
+ heads = 128;
+ else
+ heads = 255;
+
+ cylinders = capacity / (heads * sectors);
+
+ *cyls = (unsigned short) cylinders; /* Stuff return values */
+ *secs = (unsigned char) sectors;
+ *hds = (unsigned char) heads;
+}
+
+
+/*
+ * Rescan the partition tables
+ */
+
+static int do_i2ob_revalidate(kdev_t dev, int maxu)
+{
+ int minor=MINOR(dev);
+ int i;
+
+ minor&=0xF0;
+
+ i2ob_dev[minor].refcnt++;
+ if(i2ob_dev[minor].refcnt>maxu+1)
+ {
+ i2ob_dev[minor].refcnt--;
+ return -EBUSY;
+ }
+
+ for( i = 15; i>=0 ; i--)
+ {
+ int m = minor+i;
+ invalidate_device(MKDEV(MAJOR_NR, m), 1);
+ i2ob_gendisk.part[m].start_sect = 0;
+ i2ob_gendisk.part[m].nr_sects = 0;
+ }
+
+ /*
+ * Do a physical check and then reconfigure
+ */
+
+ i2ob_install_device(i2ob_dev[minor].controller, i2ob_dev[minor].i2odev,
+ minor);
+ i2ob_dev[minor].refcnt--;


+ return 0;
+}
+

+/*
+ * Issue device specific ioctl calls.
+ */
+
+static int i2ob_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct i2ob_device *dev;
+ int minor;
+
+ /* Anyone capable of this syscall can do *real bad* things */
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!inode)
+ return -EINVAL;
+ minor = MINOR(inode->i_rdev);
+ if (minor >= (MAX_I2OB<<4))
+ return -ENODEV;
+
+ dev = &i2ob_dev[minor];
+ switch (cmd) {
+ case BLKGETSIZE:
+ return put_user(i2ob[minor].nr_sects, (long *) arg);
+ case BLKGETSIZE64:
+ return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg);
+
+ case HDIO_GETGEO:
+ {
+ struct hd_geometry g;
+ int u=minor&0xF0;
+ i2o_block_biosparam(i2ob_sizes[u]<<1,
+ &g.cylinders, &g.heads, &g.sectors);
+ g.start = i2ob[minor].start_sect;
+ return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
+ }
+
+ case BLKRRPART:
+ if(!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ return do_i2ob_revalidate(inode->i_rdev,1);
+
+ case BLKFLSBUF:
+ case BLKROSET:
+ case BLKROGET:
+ case BLKRASET:
+ case BLKRAGET:
+ case BLKPG:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Close the block device down
+ */
+
+static int i2ob_release(struct inode *inode, struct file *file)
+{
+ struct i2ob_device *dev;
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor >= (MAX_I2OB<<4))
+ return -ENODEV;
+ dev = &i2ob_dev[(minor&0xF0)];
+
+ /*
+ * This is to deail with the case of an application
+ * opening a device and then the device dissapears while
+ * it's in use, and then the application tries to release
+ * it. ex: Unmounting a deleted RAID volume at reboot.
+ * If we send messages, it will just cause FAILs since
+ * the TID no longer exists.
+ */
+ if(!dev->i2odev)
+ return 0;
+
+ /* Sync the device so we don't get errors */
+ fsync_dev(inode->i_rdev);
+
+ if (dev->refcnt <= 0)
+ printk(KERN_ALERT "i2ob_release: refcount(%d) <= 0\n", dev->refcnt);
+ dev->refcnt--;
+ if(dev->refcnt==0)
+ {
+ /*
+ * Flush the onboard cache on unmount
+ */
+ u32 msg[5];
+ int *query_done = &dev->done_flag;
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x40000000;
+ msg[3] = (u32)query_done;
+ msg[4] = 60<<16;
+ DEBUG("Flushing...");
+ i2o_post_wait(dev->controller, msg, 20, 60);
+
+ /*
+ * Unlock the media
+ */
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x40000000;
+ msg[3] = (u32)query_done;
+ msg[4] = -1;
+ DEBUG("Unlocking...");
+ i2o_post_wait(dev->controller, msg, 20, 2);
+ DEBUG("Unlocked.\n");
+
+ /*
+ * Now unclaim the device.
+ */
+
+ if (i2o_release_device(dev->i2odev, &i2o_block_handler))
+ printk(KERN_ERR "i2ob_release: controller rejected unclaim.\n");
+
+ DEBUG("Unclaim\n");
+ }
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+

+/*
+ * Open the block device.
+ */
+
+static int i2ob_open(struct inode *inode, struct file *file)
+{
+ int minor;
+ struct i2ob_device *dev;
+
+ if (!inode)
+ return -EINVAL;
+ minor = MINOR(inode->i_rdev);
+ if (minor >= MAX_I2OB<<4)
+ return -ENODEV;
+ dev=&i2ob_dev[(minor&0xF0)];
+
+ if(!dev->i2odev)
+ return -ENODEV;
+
+ if(dev->refcnt++==0)
+ {
+ u32 msg[6];
+
+ DEBUG("Claim ");
+ if(i2o_claim_device(dev->i2odev, &i2o_block_handler))
+ {
+ dev->refcnt--;
+ printk(KERN_INFO "I2O Block: Could not open device\n");
+ return -EBUSY;
+ }
+ DEBUG("Claimed ");
+
+ /*
+ * Mount the media if needed. Note that we don't use
+ * the lock bit. Since we have to issue a lock if it
+ * refuses a mount (quite possible) then we might as
+ * well just send two messages out.
+ */
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_MMOUNT<<24|HOST_TID<<12|dev->tid;
+ msg[4] = -1;
+ msg[5] = 0;
+ DEBUG("Mount ");
+ i2o_post_wait(dev->controller, msg, 24, 2);
+
+ /*
+ * Lock the media
+ */
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_MLOCK<<24|HOST_TID<<12|dev->tid;
+ msg[4] = -1;
+ DEBUG("Lock ");
+ i2o_post_wait(dev->controller, msg, 20, 2);
+ DEBUG("Ready.\n");
+ }
+ MOD_INC_USE_COUNT;


+ return 0;
+}
+

+/*
+ * Issue a device query
+ */
+
+static int i2ob_query_device(struct i2ob_device *dev, int table,
+ int field, void *buf, int buflen)
+{
+ return i2o_query_scalar(dev->controller, dev->tid,
+ table, field, buf, buflen);
+}
+
+
+/*
+ * Install the I2O block device we found.
+ */
+
+static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, int unit)
+{
+ u64 size;
+ u32 blocksize;
+ u32 limit;
+ u8 type;
+ u32 flags, status;
+ struct i2ob_device *dev=&i2ob_dev[unit];
+ int i;
+
+ /*
+ * For logging purposes...
+ */
+ printk(KERN_INFO "i2ob: Installing tid %d device at unit %d\n",
+ d->lct_data.tid, unit);
+
+ /*
+ * Ask for the current media data. If that isn't supported
+ * then we ask for the device capacity data
+ */
+ if(i2ob_query_device(dev, 0x0004, 1, &blocksize, 4) != 0
+ || i2ob_query_device(dev, 0x0004, 0, &size, 8) !=0 )
+ {
+ i2ob_query_device(dev, 0x0000, 3, &blocksize, 4);
+ i2ob_query_device(dev, 0x0000, 4, &size, 8);
+ }
+
+ i2ob_query_device(dev, 0x0000, 5, &flags, 4);
+ i2ob_query_device(dev, 0x0000, 6, &status, 4);
+ i2ob_sizes[unit] = (int)(size>>10);
+ for(i=unit; i <= unit+15 ; i++)
+ i2ob_hardsizes[i] = blocksize;
+ i2ob_gendisk.part[unit].nr_sects = size>>9;
+ i2ob[unit].nr_sects = (int)(size>>9);
+
+ /* Set limit based on inbound frame size */
+ limit = (d->controller->status_block->inbound_frame_size - 8)/2;
+ limit = limit<<9;
+
+ /*
+ * Max number of Scatter-Gather Elements
+ */
+
+ for(i=unit;i<=unit+15;i++)
+ {
+ if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy)
+ {
+ i2ob_max_sectors[i] = 32;
+ i2ob_dev[i].max_segments = 8;
+ i2ob_dev[i].depth = 4;
+ }
+ else if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
+ {
+ i2ob_max_sectors[i] = 8;
+ i2ob_dev[i].max_segments = 8;
+ }
+ else
+ {
+ /* MAX_SECTORS was used but 255 is a dumb number for
+ striped RAID */
+ i2ob_max_sectors[i]=256;
+ i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
+ }
+ }
+
+ printk(KERN_INFO "Max segments set to %d\n",
+ i2ob_dev[unit].max_segments);
+ printk(KERN_INFO "Byte limit is %d.\n", limit);
+
+ i2ob_query_device(dev, 0x0000, 0, &type, 1);
+
+ sprintf(d->dev_name, "%s%c", i2ob_gendisk.major_name, 'a' + (unit>>4));
+
+ printk(KERN_INFO "%s: ", d->dev_name);
+ switch(type)
+ {
+ case 0: printk("Disk Storage");break;
+ case 4: printk("WORM");break;
+ case 5: printk("CD-ROM");break;
+ case 7: printk("Optical device");break;
+ default:
+ printk("Type %d", type);
+ }
+ if(status&(1<<10))
+ printk("(RAID)");
+ if(((flags & (1<<3)) && !(status & (1<<3))) ||
+ ((flags & (1<<4)) && !(status & (1<<4))))
+ {
+ printk(KERN_INFO " Not loaded.\n");
+ return 1;
+ }
+ printk("- %dMb, %d byte sectors",
+ (int)(size>>20), blocksize);
+ if(status&(1<<0))
+ {
+ u32 cachesize;
+ i2ob_query_device(dev, 0x0003, 0, &cachesize, 4);
+ cachesize>>=10;
+ if(cachesize>4095)
+ printk(", %dMb cache", cachesize>>10);
+ else
+ printk(", %dKb cache", cachesize);
+
+ }
+ printk(".\n");
+ printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n",
+ d->dev_name, i2ob_max_sectors[unit]);
+
+ /*
+ * If this is the first I2O block device found on this IOP,
+ * we need to initialize all the queue data structures
+ * before any I/O can be performed. If it fails, this
+ * device is useless.
+ */
+ if(!i2ob_queues[c->unit]) {
+ if(i2ob_init_iop(c->unit))


+ return 1;
+ }
+

+ /*
+ * This will save one level of lookup/indirection in critical
+ * code so that we can directly get the queue ptr from the
+ * device instead of having to go the IOP data structure.
+ */
+ dev->req_queue = &i2ob_queues[c->unit]->req_queue;
+
+ grok_partitions(&i2ob_gendisk, unit>>4, 1<<4, (long)(size>>9));
+
+ /*
+ * Register for the events we're interested in and that the
+ * device actually supports.
+ */
+ i2o_event_register(c, d->lct_data.tid, i2ob_context, unit,
+ (I2OB_EVENT_MASK & d->lct_data.event_capabilities));


+
+ return 0;
+}
+

+/*
+ * Initialize IOP specific queue structures. This is called
+ * once for each IOP that has a block device sitting behind it.
+ */
+static int i2ob_init_iop(unsigned int unit)


+{
+ int i;
+

+ i2ob_queues[unit] = (struct i2ob_iop_queue*)
+ kmalloc(sizeof(struct i2ob_iop_queue), GFP_ATOMIC);
+ if(!i2ob_queues[unit])
+ {
+ printk(KERN_WARNING
+ "Could not allocate request queue for I2O block device!\n");


+ return -1;
+ }
+

+ for(i = 0; i< MAX_I2OB_DEPTH; i++)
+ {
+ i2ob_queues[unit]->request_queue[i].next =
+ &i2ob_queues[unit]->request_queue[i+1];
+ i2ob_queues[unit]->request_queue[i].num = i;
+ }
+
+ /* Queue is MAX_I2OB + 1... */
+ i2ob_queues[unit]->request_queue[i].next = NULL;
+ i2ob_queues[unit]->i2ob_qhead = &i2ob_queues[unit]->request_queue[0];
+ atomic_set(&i2ob_queues[unit]->queue_depth, 0);
+
+ blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request);
+ blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0);
+ i2ob_queues[unit]->req_queue.back_merge_fn = i2ob_back_merge;
+ i2ob_queues[unit]->req_queue.front_merge_fn = i2ob_front_merge;
+ i2ob_queues[unit]->req_queue.merge_requests_fn = i2ob_merge_requests;
+ i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit];


+
+ return 0;
+}
+

+/*
+ * Get the request queue for the given device.
+ */
+static request_queue_t* i2ob_get_queue(kdev_t dev)
+{
+ int unit = MINOR(dev)&0xF0;
+
+ return i2ob_dev[unit].req_queue;
+}
+
+/*
+ * Probe the I2O subsytem for block class devices
+ */
+static void i2ob_scan(int bios)
+{
+ int i;
+ int warned = 0;
+
+ struct i2o_device *d, *b=NULL;
+ struct i2o_controller *c;
+ struct i2ob_device *dev;
+
+ for(i=0; i< MAX_I2O_CONTROLLERS; i++)
+ {
+ c=i2o_find_controller(i);
+
+ if(c==NULL)
+ continue;
+
+ /*
+ * The device list connected to the I2O Controller is doubly linked
+ * Here we traverse the end of the list , and start claiming devices
+ * from that end. This assures that within an I2O controller atleast
+ * the newly created volumes get claimed after the older ones, thus
+ * mapping to same major/minor (and hence device file name) after
+ * every reboot.
+ * The exception being:
+ * 1. If there was a TID reuse.
+ * 2. There was more than one I2O controller.
+ */
+
+ if(!bios)
+ {
+ for (d=c->devices;d!=NULL;d=d->next)
+ if(d->next == NULL)
+ b = d;
+ }
+ else
+ b = c->devices;
+
+ while(b != NULL)
+ {
+ d=b;
+ if(bios)
+ b = b->next;
+ else
+ b = b->prev;
+
+ if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)
+ continue;
+
+ if(d->lct_data.user_tid != 0xFFF)
+ continue;
+
+ if(bios)
+ {
+ if(d->lct_data.bios_info != 0x80)
+ continue;
+ printk(KERN_INFO "Claiming as Boot device: Controller %d, TID %d\n", c->unit, d->lct_data.tid);
+ }
+ else
+ {
+ if(d->lct_data.bios_info == 0x80)
+ continue; /*Already claimed on pass 1 */
+ }
+
+ if(i2o_claim_device(d, &i2o_block_handler))
+ {
+ printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit,
+ d->lct_data.tid);
+ printk(KERN_WARNING "\t%sevice refused claim! Skipping installation\n", bios?"Boot d":"D");
+ continue;
+ }
+
+ if(scan_unit<MAX_I2OB<<4)
+ {
+ /*
+ * Get the device and fill in the
+ * Tid and controller.
+ */
+ dev=&i2ob_dev[scan_unit];
+ dev->i2odev = d;
+ dev->controller = c;
+ dev->unit = c->unit;
+ dev->tid = d->lct_data.tid;
+
+ if(i2ob_install_device(c,d,scan_unit))
+ printk(KERN_WARNING "Could not install I2O block device\n");
+ else
+ {
+ scan_unit+=16;
+ i2ob_dev_count++;
+
+ /* We want to know when device goes away */
+ i2o_device_notify_on(d, &i2o_block_handler);
+ }
+ }
+ else
+ {
+ if(!warned++)
+ printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
+ }
+ i2o_release_device(d, &i2o_block_handler);
+ }
+ i2o_unlock_controller(c);
+ }
+}
+
+static void i2ob_probe(void)
+{
+ /*
+ * Some overhead/redundancy involved here, while trying to
+ * claim the first boot volume encountered as /dev/i2o/hda
+ * everytime. All the i2o_controllers are searched and the
+ * first i2o block device marked as bootable is claimed
+ * If an I2O block device was booted off , the bios sets
+ * its bios_info field to 0x80, this what we search for.
+ * Assuming that the bootable volume is /dev/i2o/hda
+ * everytime will prevent any kernel panic while mounting
+ * root partition
+ */
+
+ printk(KERN_INFO "i2o_block: Checking for Boot device...\n");
+ i2ob_scan(1);
+
+ /*
+ * Now the remainder.
+ */
+ printk(KERN_INFO "i2o_block: Checking for I2O Block devices...\n");
+ i2ob_scan(0);
+}
+
+
+/*
+ * New device notification handler. Called whenever a new
+ * I2O block storage device is added to the system.
+ *
+ * Should we spin lock around this to keep multiple devs from
+ * getting updated at the same time?
+ *
+ */
+void i2ob_new_device(struct i2o_controller *c, struct i2o_device *d)
+{
+ struct i2ob_device *dev;
+ int unit = 0;
+
+ printk(KERN_INFO "i2o_block: New device detected\n");
+ printk(KERN_INFO " Controller %d Tid %d\n",c->unit, d->lct_data.tid);
+
+ /* Check for available space */
+ if(i2ob_dev_count>=MAX_I2OB<<4)
+ {
+ printk(KERN_ERR "i2o_block: No more devices allowed!\n");
+ return;
+ }
+ for(unit = 0; unit < (MAX_I2OB<<4); unit += 16)
+ {
+ if(!i2ob_dev[unit].i2odev)
+ break;
+ }
+
+ if(i2o_claim_device(d, &i2o_block_handler))
+ {
+ printk(KERN_INFO
+ "i2o_block: Unable to claim device. Installation aborted\n");
+ return;
+ }
+
+ dev = &i2ob_dev[unit];
+ dev->i2odev = d;
+ dev->controller = c;
+ dev->tid = d->lct_data.tid;
+
+ if(i2ob_install_device(c,d,unit))
+ printk(KERN_ERR "i2o_block: Could not install new device\n");
+ else
+ {
+ i2ob_dev_count++;
+ i2o_device_notify_on(d, &i2o_block_handler);
+ }
+
+ i2o_release_device(d, &i2o_block_handler);
+
+ return;
+}
+
+/*
+ * Deleted device notification handler. Called when a device we
+ * are talking to has been deleted by the user or some other
+ * mysterious fource outside the kernel.
+ */
+void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
+{
+ int unit = 0;
+ int i = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+
+ /*
+ * Need to do this...we somtimes get two events from the IRTOS
+ * in a row and that causes lots of problems.
+ */
+ i2o_device_notify_off(d, &i2o_block_handler);
+
+ printk(KERN_INFO "I2O Block Device Deleted\n");
+
+ for(unit = 0; unit < MAX_I2OB<<4; unit += 16)
+ {
+ if(i2ob_dev[unit].i2odev == d)
+ {
+ printk(KERN_INFO " /dev/%s: Controller %d Tid %d\n",
+ d->dev_name, c->unit, d->lct_data.tid);
+ break;
+ }
+ }
+ if(unit >= MAX_I2OB<<4)
+ {
+ printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n");
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return;
+ }
+
+ /*
+ * This will force errors when i2ob_get_queue() is called
+ * by the kenrel.
+ */
+ i2ob_dev[unit].req_queue = NULL;
+ for(i = unit; i <= unit+15; i++)
+ {
+ i2ob_dev[i].i2odev = NULL;
+ i2ob_sizes[i] = 0;
+ i2ob_hardsizes[i] = 0;
+ i2ob_max_sectors[i] = 0;
+ i2ob[i].nr_sects = 0;
+ i2ob_gendisk.part[i].nr_sects = 0;
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ /*
+ * Decrease usage count for module
+ */
+
+ while(i2ob_dev[unit].refcnt--)
+ MOD_DEC_USE_COUNT;
+
+ i2ob_dev[unit].refcnt = 0;
+
+ i2ob_dev[i].tid = 0;
+
+ /*
+ * Do we need this?
+ * The media didn't really change...the device is just gone
+ */
+ i2ob_media_change_flag[unit] = 1;
+
+ i2ob_dev_count--;
+}
+
+/*
+ * Have we seen a media change ?
+ */
+static int i2ob_media_change(kdev_t dev)
+{
+ int i=MINOR(dev);
+ i>>=4;
+ if(i2ob_media_change_flag[i])
+ {
+ i2ob_media_change_flag[i]=0;
+ return 1;
+ }


+ return 0;
+}
+

+static int i2ob_revalidate(kdev_t dev)


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 24'
echo 'File patch-2.4.13 is continued in part 25'
echo "25" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:55 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part25

#!/bin/sh -x
# this is part 25 of a 53 - part archive


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

if test "$Scheck" != 25; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+{
+ return do_i2ob_revalidate(dev, 0);
+}
+
+/*
+ * Reboot notifier. This is called by i2o_core when the system
+ * shuts down.
+ */
+static void i2ob_reboot_event(void)


+{
+ int i;
+

+ for(i=0;i<MAX_I2OB;i++)
+ {
+ struct i2ob_device *dev=&i2ob_dev[(i<<4)];
+
+ if(dev->refcnt!=0)


+ {
+ /*
+ * Flush the onboard cache

+ */
+ u32 msg[5];
+ int *query_done = &dev->done_flag;
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x40000000;
+ msg[3] = (u32)query_done;
+ msg[4] = 60<<16;
+
+ DEBUG("Flushing...");
+ i2o_post_wait(dev->controller, msg, 20, 60);
+

+ DEBUG("Unlocking...");


+ /*
+ * Unlock the media
+ */
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x40000000;
+ msg[3] = (u32)query_done;
+ msg[4] = -1;

+ i2o_post_wait(dev->controller, msg, 20, 2);
+
+ DEBUG("Unlocked.\n");
+ }
+ }

+}
+
+static struct block_device_operations i2ob_fops =
+{
+ open: i2ob_open,
+ release: i2ob_release,
+ ioctl: i2ob_ioctl,
+ check_media_change: i2ob_media_change,
+ revalidate: i2ob_revalidate,
+};
+
+static struct gendisk i2ob_gendisk =
+{
+ major: MAJOR_NR,
+ major_name: "i2o/hd",
+ minor_shift: 4,
+ max_p: 1<<4,
+ part: i2ob,
+ sizes: i2ob_sizes,
+ nr_real: MAX_I2OB,
+ fops: &i2ob_fops,
+};
+
+
+/*
+ * And here should be modules and kernel interface
+ * (Just smiley confuses emacs :-)
+ */
+
+#ifdef MODULE
+#define i2o_block_init init_module
+#endif
+
+int i2o_block_init(void)


+{
+ int i;
+

+ printk(KERN_INFO "I2O Block Storage OSM v0.9\n");
+ printk(KERN_INFO " (c) Copyright 1999-2001 Red Hat Software.\n");
+
+ /*
+ * Register the block device interfaces
+ */
+
+ if (register_blkdev(MAJOR_NR, "i2o_block", &i2ob_fops)) {
+ printk(KERN_ERR "Unable to get major number %d for i2o_block\n",
+ MAJOR_NR);
+ return -EIO;
+ }
+#ifdef MODULE
+ printk(KERN_INFO "i2o_block: registered device at major %d\n", MAJOR_NR);
+#endif
+
+ /*
+ * Now fill in the boiler plate
+ */
+
+ blksize_size[MAJOR_NR] = i2ob_blksizes;
+ hardsect_size[MAJOR_NR] = i2ob_hardsizes;
+ blk_size[MAJOR_NR] = i2ob_sizes;
+ max_sectors[MAJOR_NR] = i2ob_max_sectors;
+ blk_dev[MAJOR_NR].queue = i2ob_get_queue;
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
+
+ for (i = 0; i < MAX_I2OB << 4; i++) {
+ i2ob_dev[i].refcnt = 0;
+ i2ob_dev[i].flags = 0;
+ i2ob_dev[i].controller = NULL;


+ i2ob_dev[i].i2odev = NULL;

+ i2ob_dev[i].tid = 0;

+ i2ob_dev[i].head = NULL;
+ i2ob_dev[i].tail = NULL;
+ i2ob_dev[i].depth = MAX_I2OB_DEPTH;
+ i2ob_blksizes[i] = 1024;
+ i2ob_max_sectors[i] = 2;
+ }
+
+ /*
+ * Set up the queue
+ */
+ for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
+ {
+ i2ob_queues[i] = NULL;
+ }
+
+ /*
+ * Timers
+ */
+
+ init_timer(&i2ob_timer);
+ i2ob_timer.function = i2ob_timer_handler;
+ i2ob_timer.data = 0;
+
+ /*
+ * Register the OSM handler as we will need this to probe for
+ * drives, geometry and other goodies.
+ */
+
+ if(i2o_install_handler(&i2o_block_handler)<0)
+ {
+ unregister_blkdev(MAJOR_NR, "i2o_block");
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ printk(KERN_ERR "i2o_block: unable to register OSM.\n");
+ return -EINVAL;
+ }
+ i2ob_context = i2o_block_handler.context;
+
+ /*
+ * Initialize event handling thread
+ */
+ init_MUTEX_LOCKED(&i2ob_evt_sem);
+ evt_pid = kernel_thread(i2ob_evt, NULL, CLONE_SIGHAND);
+ if(evt_pid < 0)
+ {
+ printk(KERN_ERR
+ "i2o_block: Could not initialize event thread. Aborting\n");
+ i2o_remove_handler(&i2o_block_handler);


+ return 0;
+ }
+
+ /*

+ * Finally see what is actually plugged in to our controllers
+ */
+ for (i = 0; i < MAX_I2OB; i++)
+ register_disk(&i2ob_gendisk, MKDEV(MAJOR_NR,i<<4), 1<<4,
+ &i2ob_fops, 0);
+ i2ob_probe();
+
+ /*
+ * Adding i2ob_gendisk into the gendisk list.
+ */
+ add_gendisk(&i2ob_gendisk);


+
+ return 0;
+}
+

+#ifdef MODULE
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Red Hat Software");
+MODULE_DESCRIPTION("I2O Block Device OSM");
+MODULE_LICENSE("GPL");
+
+
+void cleanup_module(void)


+{
+ int i;
+

+ if(evt_running) {
+ printk(KERN_INFO "Killing I2O block threads...");
+ i = kill_proc(evt_pid, SIGTERM, 1);
+ if(!i) {
+ printk("waiting...");
+ }
+ /* Be sure it died */
+ wait_for_completion(&i2ob_thread_dead);
+ printk("done.\n");
+ }
+
+ /*
+ * Unregister for updates from any devices..otherwise we still
+ * get them and the core jumps to random memory :O
+ */
+ if(i2ob_dev_count) {
+ struct i2o_device *d;
+ for(i = 0; i < MAX_I2OB; i++)
+ if((d=i2ob_dev[i<<4].i2odev)) {
+ i2o_device_notify_off(d, &i2o_block_handler);
+ i2o_event_register(d->controller, d->lct_data.tid,
+ i2ob_context, i<<4, 0);


+ }
+ }
+
+ /*

+ * We may get further callbacks for ourself. The i2o_core
+ * code handles this case reasonably sanely. The problem here
+ * is we shouldn't get them .. but a couple of cards feel
+ * obliged to tell us stuff we dont care about.
+ *
+ * This isnt ideal at all but will do for now.
+ */
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ);
+
+ /*
+ * Flush the OSM
+ */
+
+ i2o_remove_handler(&i2o_block_handler);
+
+ /*
+ * Return the block device
+ */
+ if (unregister_blkdev(MAJOR_NR, "i2o_block") != 0)
+ printk("i2o_block: cleanup_module failed\n");
+
+ /*
+ * free request queue
+ */
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
+ del_gendisk(&i2ob_gendisk);
+}
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_config.c linux/drivers/message/i2o/i2o_config.c
--- v2.4.12/linux/drivers/message/i2o/i2o_config.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_config.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,966 @@
+/*
+ * I2O Configuration Interface Driver


+ *
+ * (C) Copyright 1999 Red Hat Software
+ *
+ * Written by Alan Cox, Building Number Three Ltd
+ *

+ * Modified 04/20/1999 by Deepak Saxena
+ * - Added basic ioctl() support
+ * Modified 06/07/1999 by Deepak Saxena
+ * - Added software download ioctl (still testing)
+ * Modified 09/10/1999 by Auvo Häkkinen
+ * - Changes to i2o_cfg_reply(), ioctl_parms()
+ * - Added ioct_validate()
+ * Modified 09/30/1999 by Taneli Vähäkangas
+ * - Fixed ioctl_swdl()
+ * Modified 10/04/1999 by Taneli Vähäkangas
+ * - Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
+ * Modified 11/18/199 by Deepak Saxena
+ * - Added event managmenet support


+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/i2o.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>


+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+

+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+static int i2o_cfg_context = -1;
+static void *page_buf;
+static spinlock_t i2o_config_lock = SPIN_LOCK_UNLOCKED;
+struct wait_queue *i2o_wait_queue;
+
+#define MODINC(x,y) (x = x++ % y)
+
+struct i2o_cfg_info
+{
+ struct file* fp;
+ struct fasync_struct *fasync;
+ struct i2o_evt_info event_q[I2O_EVT_Q_LEN];
+ u16 q_in; // Queue head index
+ u16 q_out; // Queue tail index
+ u16 q_len; // Queue length
+ u16 q_lost; // Number of lost events
+ u32 q_id; // Event queue ID...used as tx_context
+ struct i2o_cfg_info *next;
+};
+static struct i2o_cfg_info *open_files = NULL;
+static int i2o_cfg_info_id = 0;
+
+static int ioctl_getiops(unsigned long);
+static int ioctl_gethrt(unsigned long);
+static int ioctl_getlct(unsigned long);
+static int ioctl_parms(unsigned long, unsigned int);
+static int ioctl_html(unsigned long);
+static int ioctl_swdl(unsigned long);
+static int ioctl_swul(unsigned long);
+static int ioctl_swdel(unsigned long);
+static int ioctl_validate(unsigned long);
+static int ioctl_evt_reg(unsigned long, struct file *);
+static int ioctl_evt_get(unsigned long, struct file *);
+static int cfg_fasync(int, struct file*, int);
+
+/*
+ * This is the callback for any message we have posted. The message itself
+ * will be returned to the message pool when we return from the IRQ
+ *
+ * This runs in irq context so be short and sweet.
+ */
+static void i2o_cfg_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *m)
+{
+ u32 *msg = (u32 *)m;
+
+ if (msg[0] & MSG_FAIL) {
+ u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+
+ printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n");
+
+ /* Release the preserved msg frame by resubmitting it as a NOP */
+
+ preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
+ preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
+ preserved_msg[2] = 0;
+ i2o_post_message(c, msg[7]);
+ }
+
+ if (msg[4] >> 24) // ReqStatus != SUCCESS
+ i2o_report_status(KERN_INFO,"i2o_config", msg);
+
+ if(m->function == I2O_CMD_UTIL_EVT_REGISTER)
+ {
+ struct i2o_cfg_info *inf;
+
+ for(inf = open_files; inf; inf = inf->next)
+ if(inf->q_id == msg[3])
+ break;
+
+ //
+ // If this is the case, it means that we're getting
+ // events for a file descriptor that's been close()'d
+ // w/o the user unregistering for events first.
+ // The code currently assumes that the user will
+ // take care of unregistering for events before closing
+ // a file.
+ //
+ // TODO:
+ // Should we track event registartion and deregister
+ // for events when a file is close()'d so this doesn't
+ // happen? That would get rid of the search through
+ // the linked list since file->private_data could point
+ // directly to the i2o_config_info data structure...but
+ // it would mean having all sorts of tables to track
+ // what each file is registered for...I think the
+ // current method is simpler. - DS
+ //
+ if(!inf)
+ return;
+
+ inf->event_q[inf->q_in].id.iop = c->unit;
+ inf->event_q[inf->q_in].id.tid = m->target_tid;
+ inf->event_q[inf->q_in].id.evt_mask = msg[4];
+
+ //
+ // Data size = msg size - reply header
+ //
+ inf->event_q[inf->q_in].data_size = (m->size - 5) * 4;
+ if(inf->event_q[inf->q_in].data_size)
+ memcpy(inf->event_q[inf->q_in].evt_data,
+ (unsigned char *)(msg + 5),
+ inf->event_q[inf->q_in].data_size);
+
+ spin_lock(&i2o_config_lock);
+ MODINC(inf->q_in, I2O_EVT_Q_LEN);
+ if(inf->q_len == I2O_EVT_Q_LEN)
+ {
+ MODINC(inf->q_out, I2O_EVT_Q_LEN);
+ inf->q_lost++;
+ }
+ else
+ {
+ // Keep I2OEVTGET on another CPU from touching this
+ inf->q_len++;
+ }
+ spin_unlock(&i2o_config_lock);
+
+
+// printk(KERN_INFO "File %p w/id %d has %d events\n",
+// inf->fp, inf->q_id, inf->q_len);
+
+ kill_fasync(&inf->fasync, SIGIO, POLL_IN);
+ }


+
+ return;
+}
+
+/*

+ * Each of these describes an i2o message handler. They are
+ * multiplexed by the i2o_core code
+ */
+
+struct i2o_handler cfg_handler=
+{
+ i2o_cfg_reply,


+ NULL,
+ NULL,
+ NULL,

+ "Configuration",
+ 0,
+ 0xffffffff // All classes
+};
+
+static ssize_t cfg_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ printk(KERN_INFO "i2o_config write not yet supported\n");


+
+ return 0;
+}
+
+

+static ssize_t cfg_read(struct file *file, char *buf, size_t count, loff_t *ptr)


+{
+ return 0;
+}
+
+/*

+ * IOCTL Handler
+ */
+static int cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+
+ switch(cmd)
+ {
+ case I2OGETIOPS:
+ ret = ioctl_getiops(arg);
+ break;
+
+ case I2OHRTGET:
+ ret = ioctl_gethrt(arg);
+ break;
+
+ case I2OLCTGET:
+ ret = ioctl_getlct(arg);
+ break;
+
+ case I2OPARMSET:
+ ret = ioctl_parms(arg, I2OPARMSET);
+ break;
+
+ case I2OPARMGET:
+ ret = ioctl_parms(arg, I2OPARMGET);
+ break;
+
+ case I2OSWDL:
+ ret = ioctl_swdl(arg);
+ break;
+
+ case I2OSWUL:
+ ret = ioctl_swul(arg);
+ break;
+
+ case I2OSWDEL:
+ ret = ioctl_swdel(arg);
+ break;
+
+ case I2OVALIDATE:
+ ret = ioctl_validate(arg);
+ break;
+
+ case I2OHTML:
+ ret = ioctl_html(arg);
+ break;
+
+ case I2OEVTREG:
+ ret = ioctl_evt_reg(arg, fp);
+ break;
+
+ case I2OEVTGET:
+ ret = ioctl_evt_get(arg, fp);


+ break;
+
+ default:

+ ret = -EINVAL;
+ }


+
+ return ret;
+}
+

+int ioctl_getiops(unsigned long arg)
+{
+ u8 *user_iop_table = (u8*)arg;
+ struct i2o_controller *c = NULL;
+ int i;
+ u8 foo[MAX_I2O_CONTROLLERS];
+
+ if(!access_ok(VERIFY_WRITE, user_iop_table, MAX_I2O_CONTROLLERS))
+ return -EFAULT;
+
+ for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
+ {
+ c = i2o_find_controller(i);
+ if(c)
+ {
+ foo[i] = 1;
+ i2o_unlock_controller(c);
+ }
+ else
+ {
+ foo[i] = 0;
+ }
+ }
+
+ __copy_to_user(user_iop_table, foo, MAX_I2O_CONTROLLERS);


+ return 0;
+}
+

+int ioctl_gethrt(unsigned long arg)
+{
+ struct i2o_controller *c;
+ struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg;
+ struct i2o_cmd_hrtlct kcmd;
+ i2o_hrt *hrt;
+ int len;
+ u32 reslen;


+ int ret = 0;
+

+ if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
+ return -EFAULT;
+
+ if(get_user(reslen, kcmd.reslen) < 0)
+ return -EFAULT;
+
+ if(kcmd.resbuf == NULL)
+ return -EFAULT;
+
+ c = i2o_find_controller(kcmd.iop);
+ if(!c)
+ return -ENXIO;
+
+ hrt = (i2o_hrt *)c->hrt;
+
+ i2o_unlock_controller(c);
+
+ len = 8 + ((hrt->entry_len * hrt->num_entries) << 2);
+
+ /* We did a get user...so assuming mem is ok...is this bad? */
+ put_user(len, kcmd.reslen);
+ if(len > reslen)
+ ret = -ENOBUFS;
+ if(copy_to_user(kcmd.resbuf, (void*)hrt, len))
+ ret = -EFAULT;


+
+ return ret;
+}
+

+int ioctl_getlct(unsigned long arg)
+{
+ struct i2o_controller *c;
+ struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg;
+ struct i2o_cmd_hrtlct kcmd;
+ i2o_lct *lct;
+ int len;


+ int ret = 0;

+ u32 reslen;
+
+ if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
+ return -EFAULT;
+
+ if(get_user(reslen, kcmd.reslen) < 0)
+ return -EFAULT;
+
+ if(kcmd.resbuf == NULL)
+ return -EFAULT;
+
+ c = i2o_find_controller(kcmd.iop);
+ if(!c)
+ return -ENXIO;
+
+ lct = (i2o_lct *)c->lct;
+ i2o_unlock_controller(c);
+
+ len = (unsigned int)lct->table_size << 2;
+ put_user(len, kcmd.reslen);
+ if(len > reslen)
+ ret = -ENOBUFS;
+ else if(copy_to_user(kcmd.resbuf, (void*)lct, len))
+ ret = -EFAULT;


+
+ return ret;
+}
+

+static int ioctl_parms(unsigned long arg, unsigned int type)


+{
+ int ret = 0;

+ struct i2o_controller *c;
+ struct i2o_cmd_psetget *cmd = (struct i2o_cmd_psetget*)arg;
+ struct i2o_cmd_psetget kcmd;
+ u32 reslen;
+ u8 *ops;
+ u8 *res;
+ int len;
+
+ u32 i2o_cmd = (type == I2OPARMGET ?
+ I2O_CMD_UTIL_PARAMS_GET :
+ I2O_CMD_UTIL_PARAMS_SET);
+
+ if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_psetget)))
+ return -EFAULT;
+
+ if(get_user(reslen, kcmd.reslen))
+ return -EFAULT;
+
+ c = i2o_find_controller(kcmd.iop);
+ if(!c)
+ return -ENXIO;
+
+ ops = (u8*)kmalloc(kcmd.oplen, GFP_KERNEL);
+ if(!ops)
+ {
+ i2o_unlock_controller(c);


+ return -ENOMEM;
+ }
+

+ if(copy_from_user(ops, kcmd.opbuf, kcmd.oplen))
+ {
+ i2o_unlock_controller(c);
+ kfree(ops);
+ return -EFAULT;
+ }
+
+ /*
+ * It's possible to have a _very_ large table
+ * and that the user asks for all of it at once...
+ */
+ res = (u8*)kmalloc(65536, GFP_KERNEL);
+ if(!res)
+ {
+ i2o_unlock_controller(c);
+ kfree(ops);


+ return -ENOMEM;
+ }
+

+ len = i2o_issue_params(i2o_cmd, c, kcmd.tid,
+ ops, kcmd.oplen, res, 65536);
+ i2o_unlock_controller(c);
+ kfree(ops);
+
+ if (len < 0) {
+ kfree(res);
+ return -EAGAIN;
+ }
+
+ put_user(len, kcmd.reslen);
+ if(len > reslen)
+ ret = -ENOBUFS;
+ else if(copy_to_user(cmd->resbuf, res, len))
+ ret = -EFAULT;
+
+ kfree(res);


+
+ return ret;
+}
+

+int ioctl_html(unsigned long arg)
+{
+ struct i2o_html *cmd = (struct i2o_html*)arg;
+ struct i2o_html kcmd;
+ struct i2o_controller *c;
+ u8 *res = NULL;
+ void *query = NULL;


+ int ret = 0;

+ int token;
+ u32 len;
+ u32 reslen;
+ u32 msg[MSG_FRAME_SIZE/4];
+
+ if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_html)))
+ {
+ printk(KERN_INFO "i2o_config: can't copy html cmd\n");


+ return -EFAULT;
+ }
+

+ if(get_user(reslen, kcmd.reslen) < 0)
+ {
+ printk(KERN_INFO "i2o_config: can't copy html reslen\n");


+ return -EFAULT;
+ }
+

+ if(!kcmd.resbuf)
+ {
+ printk(KERN_INFO "i2o_config: NULL html buffer\n");


+ return -EFAULT;
+ }
+

+ c = i2o_find_controller(kcmd.iop);
+ if(!c)
+ return -ENXIO;
+
+ if(kcmd.qlen) /* Check for post data */
+ {
+ query = kmalloc(kcmd.qlen, GFP_KERNEL);
+ if(!query)
+ {
+ i2o_unlock_controller(c);
+ return -ENOMEM;
+ }
+ if(copy_from_user(query, kcmd.qbuf, kcmd.qlen))
+ {
+ i2o_unlock_controller(c);
+ printk(KERN_INFO "i2o_config: could not get query\n");
+ kfree(query);


+ return -EFAULT;
+ }
+ }
+

+ res = kmalloc(65536, GFP_KERNEL);
+ if(!res)
+ {
+ i2o_unlock_controller(c);
+ kfree(query);


+ return -ENOMEM;
+ }
+

+ msg[1] = (I2O_CMD_UTIL_CONFIG_DIALOG << 24)|HOST_TID<<12|kcmd.tid;
+ msg[2] = i2o_cfg_context;
+ msg[3] = 0;
+ msg[4] = kcmd.page;
+ msg[5] = 0xD0000000|65536;
+ msg[6] = virt_to_bus(res);
+ if(!kcmd.qlen) /* Check for post data */
+ msg[0] = SEVEN_WORD_MSG_SIZE|SGL_OFFSET_5;
+ else
+ {
+ msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
+ msg[5] = 0x50000000|65536;
+ msg[7] = 0xD4000000|(kcmd.qlen);
+ msg[8] = virt_to_bus(query);
+ }
+ /*
+ Wait for a considerable time till the Controller
+ does its job before timing out. The controller might
+ take more time to process this request if there are
+ many devices connected to it.
+ */
+ token = i2o_post_wait_mem(c, msg, 9*4, 400, query, res);
+ if(token < 0)
+ {
+ printk(KERN_DEBUG "token = %#10x\n", token);
+ i2o_unlock_controller(c);
+
+ if(token != -ETIMEDOUT)
+ {
+ kfree(res);
+ if(kcmd.qlen) kfree(query);
+ }
+
+ return token;
+ }
+ i2o_unlock_controller(c);
+
+ len = strnlen(res, 65536);
+ put_user(len, kcmd.reslen);
+ if(len > reslen)
+ ret = -ENOMEM;
+ if(copy_to_user(kcmd.resbuf, res, len))
+ ret = -EFAULT;
+
+ kfree(res);
+ if(kcmd.qlen)
+ kfree(query);


+
+ return ret;
+}
+

+int ioctl_swdl(unsigned long arg)
+{
+ struct i2o_sw_xfer kxfer;
+ struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg;
+ unsigned char maxfrag = 0, curfrag = 1;
+ unsigned char *buffer;
+ u32 msg[9];
+ unsigned int status = 0, swlen = 0, fragsize = 8192;


+ struct i2o_controller *c;
+

+ if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
+ return -EFAULT;
+
+ if(get_user(swlen, kxfer.swlen) < 0)
+ return -EFAULT;
+
+ if(get_user(maxfrag, kxfer.maxfrag) < 0)
+ return -EFAULT;
+
+ if(get_user(curfrag, kxfer.curfrag) < 0)
+ return -EFAULT;
+
+ if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192;
+
+ if(!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize))
+ return -EFAULT;
+
+ c = i2o_find_controller(kxfer.iop);
+ if(!c)
+ return -ENXIO;
+
+ buffer=kmalloc(fragsize, GFP_KERNEL);
+ if (buffer==NULL)
+ {
+ i2o_unlock_controller(c);
+ return -ENOMEM;
+ }
+ __copy_from_user(buffer, kxfer.buf, fragsize);
+
+ msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7;
+ msg[1]= I2O_CMD_SW_DOWNLOAD<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2]= (u32)cfg_handler.context;
+ msg[3]= 0;
+ msg[4]= (((u32)kxfer.flags)<<24) | (((u32)kxfer.sw_type)<<16) |
+ (((u32)maxfrag)<<8) | (((u32)curfrag));
+ msg[5]= swlen;
+ msg[6]= kxfer.sw_id;
+ msg[7]= (0xD0000000 | fragsize);
+ msg[8]= virt_to_bus(buffer);
+
+// printk("i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+ status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
+
+ i2o_unlock_controller(c);
+ if(status != -ETIMEDOUT)
+ kfree(buffer);
+
+ if (status != I2O_POST_WAIT_OK)
+ {
+ // it fails if you try and send frags out of order
+ // and for some yet unknown reasons too
+ printk(KERN_INFO "i2o_config: swdl failed, DetailedStatus = %d\n", status);
+ return status;
+ }


+
+ return 0;
+}
+

+int ioctl_swul(unsigned long arg)
+{
+ struct i2o_sw_xfer kxfer;
+ struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg;
+ unsigned char maxfrag = 0, curfrag = 1;
+ unsigned char *buffer;
+ u32 msg[9];
+ unsigned int status = 0, swlen = 0, fragsize = 8192;


+ struct i2o_controller *c;
+

+ if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
+ return -EFAULT;
+
+ if(get_user(swlen, kxfer.swlen) < 0)
+ return -EFAULT;
+
+ if(get_user(maxfrag, kxfer.maxfrag) < 0)
+ return -EFAULT;
+
+ if(get_user(curfrag, kxfer.curfrag) < 0)
+ return -EFAULT;
+
+ if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192;
+
+ if(!kxfer.buf || !access_ok(VERIFY_WRITE, kxfer.buf, fragsize))
+ return -EFAULT;
+
+ c = i2o_find_controller(kxfer.iop);
+ if(!c)
+ return -ENXIO;
+
+ buffer=kmalloc(fragsize, GFP_KERNEL);
+ if (buffer==NULL)
+ {
+ i2o_unlock_controller(c);


+ return -ENOMEM;
+ }
+

+ msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7;
+ msg[1]= I2O_CMD_SW_UPLOAD<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2]= (u32)cfg_handler.context;
+ msg[3]= 0;
+ msg[4]= (u32)kxfer.flags<<24|(u32)kxfer.sw_type<<16|(u32)maxfrag<<8|(u32)curfrag;
+ msg[5]= swlen;
+ msg[6]= kxfer.sw_id;
+ msg[7]= (0xD0000000 | fragsize);
+ msg[8]= virt_to_bus(buffer);
+
+// printk("i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+ status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
+ i2o_unlock_controller(c);
+
+ if (status != I2O_POST_WAIT_OK)
+ {
+ if(status != -ETIMEDOUT)
+ kfree(buffer);
+ printk(KERN_INFO "i2o_config: swul failed, DetailedStatus = %d\n", status);
+ return status;
+ }
+
+ __copy_to_user(kxfer.buf, buffer, fragsize);
+ kfree(buffer);


+
+ return 0;
+}
+

+int ioctl_swdel(unsigned long arg)
+{
+ struct i2o_controller *c;
+ struct i2o_sw_xfer kxfer, *pxfer = (struct i2o_sw_xfer *)arg;
+ u32 msg[7];
+ unsigned int swlen;
+ int token;
+
+ if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
+ return -EFAULT;
+
+ if (get_user(swlen, kxfer.swlen) < 0)
+ return -EFAULT;
+
+ c = i2o_find_controller(kxfer.iop);
+ if (!c)
+ return -ENXIO;
+
+ msg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
+ msg[1] = I2O_CMD_SW_REMOVE<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2] = (u32)i2o_cfg_context;
+ msg[3] = 0;
+ msg[4] = (u32)kxfer.flags<<24 | (u32)kxfer.sw_type<<16;
+ msg[5] = swlen;
+ msg[6] = kxfer.sw_id;
+
+ token = i2o_post_wait(c, msg, sizeof(msg), 10);
+ i2o_unlock_controller(c);
+
+ if (token != I2O_POST_WAIT_OK)
+ {
+ printk(KERN_INFO "i2o_config: swdel failed, DetailedStatus = %d\n", token);
+ return -ETIMEDOUT;
+ }


+
+ return 0;
+}
+

+int ioctl_validate(unsigned long arg)
+{
+ int token;
+ int iop = (int)arg;
+ u32 msg[4];


+ struct i2o_controller *c;
+

+ c=i2o_find_controller(iop);
+ if (!c)
+ return -ENXIO;
+
+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_CONFIG_VALIDATE<<24 | HOST_TID<<12 | iop;
+ msg[2] = (u32)i2o_cfg_context;
+ msg[3] = 0;
+
+ token = i2o_post_wait(c, msg, sizeof(msg), 10);
+ i2o_unlock_controller(c);
+
+ if (token != I2O_POST_WAIT_OK)
+ {
+ printk(KERN_INFO "Can't validate configuration, ErrorStatus = %d\n",
+ token);
+ return -ETIMEDOUT;
+ }


+
+ return 0;
+}
+

+static int ioctl_evt_reg(unsigned long arg, struct file *fp)
+{
+ u32 msg[5];
+ struct i2o_evt_id *pdesc = (struct i2o_evt_id *)arg;
+ struct i2o_evt_id kdesc;
+ struct i2o_controller *iop;
+ struct i2o_device *d;
+
+ if (copy_from_user(&kdesc, pdesc, sizeof(struct i2o_evt_id)))
+ return -EFAULT;
+
+ /* IOP exists? */
+ iop = i2o_find_controller(kdesc.iop);
+ if(!iop)
+ return -ENXIO;
+ i2o_unlock_controller(iop);
+
+ /* Device exists? */
+ for(d = iop->devices; d; d = d->next)
+ if(d->lct_data.tid == kdesc.tid)
+ break;
+
+ if(!d)
+ return -ENODEV;
+
+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_UTIL_EVT_REGISTER<<24 | HOST_TID<<12 | kdesc.tid;
+ msg[2] = (u32)i2o_cfg_context;
+ msg[3] = (u32)fp->private_data;
+ msg[4] = kdesc.evt_mask;
+
+ i2o_post_this(iop, msg, 20);


+
+ return 0;
+}
+

+static int ioctl_evt_get(unsigned long arg, struct file *fp)
+{
+ u32 id = (u32)fp->private_data;
+ struct i2o_cfg_info *p = NULL;
+ struct i2o_evt_get *uget = (struct i2o_evt_get*)arg;
+ struct i2o_evt_get kget;


+ unsigned long flags;
+

+ for(p = open_files; p; p = p->next)
+ if(p->q_id == id)
+ break;
+
+ if(!p->q_len)
+ {
+ return -ENOENT;


+ return 0;
+ }
+

+ memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info));
+ MODINC(p->q_out, I2O_EVT_Q_LEN);
+ spin_lock_irqsave(&i2o_config_lock, flags);
+ p->q_len--;
+ kget.pending = p->q_len;
+ kget.lost = p->q_lost;
+ spin_unlock_irqrestore(&i2o_config_lock, flags);
+
+ if(copy_to_user(uget, &kget, sizeof(struct i2o_evt_get)))
+ return -EFAULT;


+ return 0;
+}
+

+static int cfg_open(struct inode *inode, struct file *file)
+{
+ struct i2o_cfg_info *tmp =
+ (struct i2o_cfg_info *)kmalloc(sizeof(struct i2o_cfg_info), GFP_KERNEL);


+ unsigned long flags;
+

+ if(!tmp)
+ return -ENOMEM;
+
+ file->private_data = (void*)(i2o_cfg_info_id++);
+ tmp->fp = file;
+ tmp->fasync = NULL;
+ tmp->q_id = (u32)file->private_data;
+ tmp->q_len = 0;
+ tmp->q_in = 0;
+ tmp->q_out = 0;
+ tmp->q_lost = 0;
+ tmp->next = open_files;
+
+ spin_lock_irqsave(&i2o_config_lock, flags);
+ open_files = tmp;
+ spin_unlock_irqrestore(&i2o_config_lock, flags);


+
+ return 0;
+}
+

+static int cfg_release(struct inode *inode, struct file *file)
+{
+ u32 id = (u32)file->private_data;
+ struct i2o_cfg_info *p1, *p2;


+ unsigned long flags;
+

+ lock_kernel();
+ p1 = p2 = NULL;
+
+ spin_lock_irqsave(&i2o_config_lock, flags);
+ for(p1 = open_files; p1; )
+ {
+ if(p1->q_id == id)
+ {
+
+ if(p1->fasync)
+ cfg_fasync(-1, file, 0);
+ if(p2)
+ p2->next = p1->next;
+ else
+ open_files = p1->next;
+
+ kfree(p1);
+ break;
+ }
+ p2 = p1;
+ p1 = p1->next;
+ }
+ spin_unlock_irqrestore(&i2o_config_lock, flags);
+ unlock_kernel();


+
+ return 0;
+}
+

+static int cfg_fasync(int fd, struct file *fp, int on)
+{
+ u32 id = (u32)fp->private_data;
+ struct i2o_cfg_info *p;
+
+ for(p = open_files; p; p = p->next)
+ if(p->q_id == id)
+ break;
+
+ if(!p)
+ return -EBADF;
+
+ return fasync_helper(fd, fp, on, &p->fasync);
+}
+
+static struct file_operations config_fops =
+{


+ owner: THIS_MODULE,
+ llseek: no_llseek,

+ read: cfg_read,
+ write: cfg_write,
+ ioctl: cfg_ioctl,
+ open: cfg_open,
+ release: cfg_release,
+ fasync: cfg_fasync,
+};
+
+static struct miscdevice i2o_miscdev = {
+ I2O_MINOR,
+ "i2octl",
+ &config_fops
+};
+
+#ifdef MODULE
+int init_module(void)
+#else
+int __init i2o_config_init(void)
+#endif
+{
+ printk(KERN_INFO "I2O configuration manager v 0.04.\n");
+ printk(KERN_INFO " (C) Copyright 1999 Red Hat Software\n");
+
+ if((page_buf = kmalloc(4096, GFP_KERNEL))==NULL)
+ {
+ printk(KERN_ERR "i2o_config: no memory for page buffer.\n");
+ return -ENOBUFS;
+ }
+ if(misc_register(&i2o_miscdev)==-1)
+ {
+ printk(KERN_ERR "i2o_config: can't register device.\n");
+ kfree(page_buf);
+ return -EBUSY;
+ }
+ /*
+ * Install our handler
+ */
+ if(i2o_install_handler(&cfg_handler)<0)
+ {
+ kfree(page_buf);
+ printk(KERN_ERR "i2o_config: handler register failed.\n");
+ misc_deregister(&i2o_miscdev);
+ return -EBUSY;
+ }
+ /*
+ * The low 16bits of the transaction context must match this
+ * for everything we post. Otherwise someone else gets our mail
+ */
+ i2o_cfg_context = cfg_handler.context;


+ return 0;
+}
+

+#ifdef MODULE
+
+void cleanup_module(void)
+{
+ misc_deregister(&i2o_miscdev);
+
+ if(page_buf)
+ kfree(page_buf);
+ if(i2o_cfg_context != -1)
+ i2o_remove_handler(&cfg_handler);
+}
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Red Hat Software");
+MODULE_DESCRIPTION("I2O Configuration");
+MODULE_LICENSE("GPL");
+
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_core.c linux/drivers/message/i2o/i2o_core.c
--- v2.4.12/linux/drivers/message/i2o/i2o_core.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_core.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,3591 @@
+/*
+ * Core I2O structure management

+ *
+ * (C) Copyright 1999 Red Hat Software
+ *
+ * Written by Alan Cox, Building Number Three 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.
+ *

+ * A lot of the I2O message side code from this is taken from the
+ * Red Creek RCPCI45 adapter driver by Red Creek Communications
+ *
+ * Fixes by:
+ * Philipp Rumpf
+ * Juha Sievänen <Juha.S...@cs.Helsinki.FI>
+ * Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
+ * Deepak Saxena <dee...@plexity.net>
+ * Boji T Kannanthanam <boji.t.ka...@intel.com>


+ *
+ */
+

+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include <linux/i2o.h>
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>


+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+

+#include <linux/bitops.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/semaphore.h>
+#include <linux/completion.h>
+
+#include <asm/io.h>
+#include <linux/reboot.h>
+
+#include "i2o_lan.h"
+
+//#define DRIVERDEBUG
+
+#ifdef DRIVERDEBUG
+#define dprintk(s, args...) printk(s, ## args)
+#else
+#define dprintk(s, args...)
+#endif
+
+/* OSM table */
+static struct i2o_handler *i2o_handlers[MAX_I2O_MODULES];
+
+/* Controller list */
+static struct i2o_controller *i2o_controllers[MAX_I2O_CONTROLLERS];
+struct i2o_controller *i2o_controller_chain;
+int i2o_num_controllers;
+
+/* Initiator Context for Core message */
+static int core_context;
+
+/* Initialization && shutdown functions */
+static void i2o_sys_init(void);
+static void i2o_sys_shutdown(void);
+static int i2o_reset_controller(struct i2o_controller *);
+static int i2o_reboot_event(struct notifier_block *, unsigned long , void *);
+static int i2o_online_controller(struct i2o_controller *);
+static int i2o_init_outbound_q(struct i2o_controller *);
+static int i2o_post_outbound_messages(struct i2o_controller *);
+
+/* Reply handler */
+static void i2o_core_reply(struct i2o_handler *, struct i2o_controller *,


+ struct i2o_message *);
+

+/* Various helper functions */
+static int i2o_lct_get(struct i2o_controller *);
+static int i2o_lct_notify(struct i2o_controller *);
+static int i2o_hrt_get(struct i2o_controller *);
+
+static int i2o_build_sys_table(void);
+static int i2o_systab_send(struct i2o_controller *c);
+
+/* I2O core event handler */
+static int i2o_core_evt(void *);
+static int evt_pid;
+static int evt_running;
+
+/* Dynamic LCT update handler */
+static int i2o_dyn_lct(void *);
+
+void i2o_report_controller_unit(struct i2o_controller *, struct i2o_device *);
+
+/*
+ * I2O System Table. Contains information about
+ * all the IOPs in the system. Used to inform IOPs
+ * about each other's existence.
+ *
+ * sys_tbl_ver is the CurrentChangeIndicator that is
+ * used by IOPs to track changes.
+ */
+static struct i2o_sys_tbl *sys_tbl;
+static int sys_tbl_ind;
+static int sys_tbl_len;
+
+/*
+ * This spin lock is used to keep a device from being
+ * added and deleted concurrently across CPUs or interrupts.
+ * This can occur when a user creates a device and immediatelly
+ * deletes it before the new_dev_notify() handler is called.
+ */
+static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
+
+#ifdef MODULE
+/*
+ * Function table to send to bus specific layers
+ * See <include/linux/i2o.h> for explanation of this
+ */
+static struct i2o_core_func_table i2o_core_functions =
+{
+ i2o_install_controller,
+ i2o_activate_controller,
+ i2o_find_controller,
+ i2o_unlock_controller,
+ i2o_run_queue,
+ i2o_delete_controller
+};
+
+#ifdef CONFIG_I2O_PCI_MODULE
+extern int i2o_pci_core_attach(struct i2o_core_func_table *);
+extern void i2o_pci_core_detach(void);
+#endif /* CONFIG_I2O_PCI_MODULE */
+
+#endif /* MODULE */
+
+/*
+ * Structures and definitions for synchronous message posting.
+ * See i2o_post_wait() for description.
+ */
+struct i2o_post_wait_data
+{
+ int *status; /* Pointer to status block on caller stack */
+ int *complete; /* Pointer to completion flag on caller stack */
+ u32 id; /* Unique identifier */
+ wait_queue_head_t *wq; /* Wake up for caller (NULL for dead) */
+ struct i2o_post_wait_data *next; /* Chain */
+ void *mem[2]; /* Memory blocks to recover on failure path */
+};
+static struct i2o_post_wait_data *post_wait_queue;
+static u32 post_wait_id; // Unique ID for each post_wait
+static spinlock_t post_wait_lock = SPIN_LOCK_UNLOCKED;
+static void i2o_post_wait_complete(u32, int);
+
+/* OSM descriptor handler */
+static struct i2o_handler i2o_core_handler =
+{
+ (void *)i2o_core_reply,
+ NULL,
+ NULL,
+ NULL,
+ "I2O core layer",
+ 0,
+ I2O_CLASS_EXECUTIVE
+};
+
+/*
+ * Used when queueing a reply to be handled later
+ */
+
+struct reply_info
+{
+ struct i2o_controller *iop;
+ u32 msg[MSG_FRAME_SIZE];
+};
+static struct reply_info evt_reply;
+static struct reply_info events[I2O_EVT_Q_LEN];
+static int evt_in;
+static int evt_out;
+static int evt_q_len;
+#define MODINC(x,y) ((x) = ((x) + 1) % (y))
+
+/*
+ * I2O configuration spinlock. This isnt a big deal for contention
+ * so we have one only
+ */
+
+static DECLARE_MUTEX(i2o_configuration_lock);
+
+/*
+ * Event spinlock. Used to keep event queue sane and from
+ * handling multiple events simultaneously.
+ */
+static spinlock_t i2o_evt_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Semaphore used to synchronize event handling thread with
+ * interrupt handler.
+ */
+
+static DECLARE_MUTEX(evt_sem);
+static DECLARE_COMPLETION(evt_dead);
+DECLARE_WAIT_QUEUE_HEAD(evt_wait);
+
+static struct notifier_block i2o_reboot_notifier =
+{
+ i2o_reboot_event,
+ NULL,
+ 0
+};
+
+/*
+ * Config options
+ */
+
+static int verbose;
+MODULE_PARM(verbose, "i");
+
+/*
+ * I2O Core reply handler
+ */
+static void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c,
+ struct i2o_message *m)
+{
+ u32 *msg=(u32 *)m;
+ u32 status;
+ u32 context = msg[2];
+
+ if (msg[0] & MSG_FAIL) // Fail bit is set
+ {
+ u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+
+ i2o_report_status(KERN_INFO, "i2o_core", msg);
+ i2o_dump_message(preserved_msg);
+
+ /* If the failed request needs special treatment,
+ * it should be done here. */
+
+ /* Release the preserved msg by resubmitting it as a NOP */
+
+ preserved_msg[0] = cpu_to_le32(THREE_WORD_MSG_SIZE | SGL_OFFSET_0);
+ preserved_msg[1] = cpu_to_le32(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0);
+ preserved_msg[2] = 0;
+ i2o_post_message(c, msg[7]);
+
+ /* If reply to i2o_post_wait failed, return causes a timeout */


+
+ return;
+ }
+

+#ifdef DRIVERDEBUG
+ i2o_report_status(KERN_INFO, "i2o_core", msg);
+#endif
+
+ if(msg[2]&0x80000000) // Post wait message
+ {
+ if (msg[4] >> 24)
+ status = (msg[4] & 0xFFFF);
+ else
+ status = I2O_POST_WAIT_OK;
+
+ i2o_post_wait_complete(context, status);
+ return;
+ }
+
+ if(m->function == I2O_CMD_UTIL_EVT_REGISTER)
+ {
+ memcpy(events[evt_in].msg, msg, (msg[0]>>16)<<2);
+ events[evt_in].iop = c;
+
+ spin_lock(&i2o_evt_lock);
+ MODINC(evt_in, I2O_EVT_Q_LEN);
+ if(evt_q_len == I2O_EVT_Q_LEN)
+ MODINC(evt_out, I2O_EVT_Q_LEN);
+ else
+ evt_q_len++;
+ spin_unlock(&i2o_evt_lock);
+
+ up(&evt_sem);
+ wake_up_interruptible(&evt_wait);
+ return;
+ }
+
+ if(m->function == I2O_CMD_LCT_NOTIFY)
+ {
+ up(&c->lct_sem);


+ return;
+ }
+
+ /*

+ * If this happens, we want to dump the message to the syslog so
+ * it can be sent back to the card manufacturer by the end user
+ * to aid in debugging.
+ *
+ */
+ printk(KERN_WARNING "%s: Unsolicited message reply sent to core!"
+ "Message dumped to syslog\n",
+ c->name);
+ i2o_dump_message(msg);


+
+ return;
+}
+

+/**
+ * i2o_install_handler - install a message handler
+ * @h: Handler structure
+ *
+ * Install an I2O handler - these handle the asynchronous messaging
+ * from the card once it has initialised. If the table of handlers is
+ * full then -ENOSPC is returned. On a success 0 is returned and the
+ * context field is set by the function. The structure is part of the
+ * system from this time onwards. It must not be freed until it has
+ * been uninstalled
+ */
+
+int i2o_install_handler(struct i2o_handler *h)
+{
+ int i;
+ down(&i2o_configuration_lock);
+ for(i=0;i<MAX_I2O_MODULES;i++)
+ {
+ if(i2o_handlers[i]==NULL)
+ {
+ h->context = i;
+ i2o_handlers[i]=h;
+ up(&i2o_configuration_lock);


+ return 0;
+ }
+ }

+ up(&i2o_configuration_lock);
+ return -ENOSPC;
+}
+
+/**
+ * i2o_remove_handler - remove an i2o message handler
+ * @h: handler
+ *
+ * Remove a message handler previously installed with i2o_install_handler.
+ * After this function returns the handler object can be freed or re-used
+ */
+
+int i2o_remove_handler(struct i2o_handler *h)
+{
+ i2o_handlers[h->context]=NULL;


+ return 0;
+}
+

+
+/*
+ * Each I2O controller has a chain of devices on it.
+ * Each device has a pointer to it's LCT entry to be used
+ * for fun purposes.
+ */
+
+/**
+ * i2o_install_device - attach a device to a controller
+ * @c: controller
+ * @d: device
+ *
+ * Add a new device to an i2o controller. This can be called from
+ * non interrupt contexts only. It adds the device and marks it as
+ * unclaimed. The device memory becomes part of the kernel and must
+ * be uninstalled before being freed or reused. Zero is returned
+ * on success.
+ */
+
+int i2o_install_device(struct i2o_controller *c, struct i2o_device *d)
+{
+ int i;
+
+ down(&i2o_configuration_lock);
+ d->controller=c;
+ d->owner=NULL;
+ d->next=c->devices;
+ d->prev=NULL;
+ if (c->devices != NULL)
+ c->devices->prev=d;
+ c->devices=d;
+ *d->dev_name = 0;
+
+ for(i = 0; i < I2O_MAX_MANAGERS; i++)
+ d->managers[i] = NULL;
+
+ up(&i2o_configuration_lock);


+ return 0;
+}
+

+/* we need this version to call out of i2o_delete_controller */
+
+int __i2o_delete_device(struct i2o_device *d)
+{
+ struct i2o_device **p;
+ int i;
+
+ p=&(d->controller->devices);
+
+ /*
+ * Hey we have a driver!
+ * Check to see if the driver wants us to notify it of
+ * device deletion. If it doesn't we assume that it
+ * is unsafe to delete a device with an owner and
+ * fail.
+ */
+ if(d->owner)
+ {
+ if(d->owner->dev_del_notify)
+ {
+ dprintk(KERN_INFO "Device has owner, notifying\n");
+ d->owner->dev_del_notify(d->controller, d);
+ if(d->owner)
+ {
+ printk(KERN_WARNING
+ "Driver \"%s\" did not release device!\n", d->owner->name);


+ return -EBUSY;
+ }
+ }

+ else


+ return -EBUSY;
+ }
+

+ /*
+ * Tell any other users who are talking to this device
+ * that it's going away. We assume that everything works.
+ */
+ for(i=0; i < I2O_MAX_MANAGERS; i++)
+ {
+ if(d->managers[i] && d->managers[i]->dev_del_notify)
+ d->managers[i]->dev_del_notify(d->controller, d);
+ }
+
+ while(*p!=NULL)
+ {
+ if(*p==d)
+ {
+ /*
+ * Destroy
+ */
+ *p=d->next;
+ kfree(d);
+ return 0;
+ }
+ p=&((*p)->next);
+ }
+ printk(KERN_ERR "i2o_delete_device: passed invalid device.\n");


+ return -EINVAL;
+}
+

+/**
+ * i2o_delete_device - remove an i2o device
+ * @d: device to remove
+ *
+ * This function unhooks a device from a controller. The device
+ * will not be unhooked if it has an owner who does not wish to free
+ * it, or if the owner lacks a dev_del_notify function. In that case
+ * -EBUSY is returned. On success 0 is returned. Other errors cause
+ * negative errno values to be returned
+ */
+
+int i2o_delete_device(struct i2o_device *d)
+{
+ int ret;
+
+ down(&i2o_configuration_lock);
+
+ /*
+ * Seek, locate
+ */
+
+ ret = __i2o_delete_device(d);
+
+ up(&i2o_configuration_lock);


+
+ return ret;
+}
+

+/**
+ * i2o_install_controller - attach a controller
+ * @c: controller
+ *
+ * Add a new controller to the i2o layer. This can be called from
+ * non interrupt contexts only. It adds the controller and marks it as
+ * unused with no devices. If the tables are full or memory allocations
+ * fail then a negative errno code is returned. On success zero is
+ * returned and the controller is bound to the system. The structure
+ * must not be freed or reused until being uninstalled.
+ */
+
+int i2o_install_controller(struct i2o_controller *c)
+{
+ int i;
+ down(&i2o_configuration_lock);


+ for(i=0;i<MAX_I2O_CONTROLLERS;i++)
+ {

+ if(i2o_controllers[i]==NULL)
+ {
+ c->dlct = (i2o_lct*)kmalloc(8192, GFP_KERNEL);
+ if(c->dlct==NULL)
+ {
+ up(&i2o_configuration_lock);
+ return -ENOMEM;
+ }
+ i2o_controllers[i]=c;
+ c->devices = NULL;
+ c->next=i2o_controller_chain;
+ i2o_controller_chain=c;
+ c->unit = i;
+ c->page_frame = NULL;
+ c->hrt = NULL;
+ c->lct = NULL;
+ c->status_block = NULL;
+ sprintf(c->name, "i2o/iop%d", i);
+ i2o_num_controllers++;
+ init_MUTEX_LOCKED(&c->lct_sem);
+ up(&i2o_configuration_lock);


+ return 0;
+ }
+ }

+ printk(KERN_ERR "No free i2o controller slots.\n");
+ up(&i2o_configuration_lock);


+ return -EBUSY;
+}
+

+/**
+ * i2o_delete_controller - delete a controller
+ * @c: controller
+ *
+ * Remove an i2o controller from the system. If the controller or its
+ * devices are busy then -EBUSY is returned. On a failure a negative
+ * errno code is returned. On success zero is returned.
+ */
+
+int i2o_delete_controller(struct i2o_controller *c)
+{
+ struct i2o_controller **p;
+ int users;
+ char name[16];
+ int stat;
+
+ dprintk(KERN_INFO "Deleting controller %s\n", c->name);
+
+ /*
+ * Clear event registration as this can cause weird behavior
+ */
+ if(c->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
+ i2o_event_register(c, core_context, 0, 0, 0);
+
+ down(&i2o_configuration_lock);
+ if((users=atomic_read(&c->users)))
+ {
+ dprintk(KERN_INFO "I2O: %d users for controller %s\n", users,
+ c->name);
+ up(&i2o_configuration_lock);
+ return -EBUSY;
+ }
+ while(c->devices)
+ {
+ if(__i2o_delete_device(c->devices)<0)
+ {
+ /* Shouldnt happen */
+ c->bus_disable(c);
+ up(&i2o_configuration_lock);


+ return -EBUSY;
+ }
+ }
+

+ /*
+ * If this is shutdown time, the thread's already been killed
+ */
+ if(c->lct_running) {
+ stat = kill_proc(c->lct_pid, SIGTERM, 1);
+ if(!stat) {
+ int count = 10 * 100;
+ while(c->lct_running && --count) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+
+ if(!count)
+ printk(KERN_ERR
+ "%s: LCT thread still running!\n",
+ c->name);
+ }
+ }
+
+ p=&i2o_controller_chain;
+
+ while(*p)
+ {
+ if(*p==c)
+ {
+ /* Ask the IOP to switch to RESET state */
+ i2o_reset_controller(c);
+
+ /* Release IRQ */
+ c->destructor(c);
+
+ *p=c->next;
+ up(&i2o_configuration_lock);
+
+ if(c->page_frame)
+ {
+ pci_unmap_single(c->pdev, c->page_frame_map, MSG_POOL_SIZE, PCI_DMA_FROMDEVICE);
+ kfree(c->page_frame);
+ }
+ if(c->hrt)
+ kfree(c->hrt);
+ if(c->lct)
+ kfree(c->lct);
+ if(c->status_block)
+ kfree(c->status_block);
+ if(c->dlct)
+ kfree(c->dlct);
+
+ i2o_controllers[c->unit]=NULL;
+ memcpy(name, c->name, strlen(c->name)+1);
+ kfree(c);
+ dprintk(KERN_INFO "%s: Deleted from controller chain.\n", name);
+
+ i2o_num_controllers--;
+ return 0;
+ }
+ p=&((*p)->next);
+ }
+ up(&i2o_configuration_lock);
+ printk(KERN_ERR "i2o_delete_controller: bad pointer!\n");
+ return -ENOENT;
+}
+
+/**
+ * i2o_unlock_controller - unlock a controller
+ * @c: controller to unlock
+ *
+ * Take a lock on an i2o controller. This prevents it being deleted.
+ * i2o controllers are not refcounted so a deletion of an in use device
+ * will fail, not take affect on the last dereference.
+ */
+
+void i2o_unlock_controller(struct i2o_controller *c)
+{
+ atomic_dec(&c->users);
+}
+
+/**
+ * i2o_find_controller - return a locked controller
+ * @n: controller number
+ *
+ * Returns a pointer to the controller object. The controller is locked
+ * on return. NULL is returned if the controller is not found.
+ */
+
+struct i2o_controller *i2o_find_controller(int n)
+{
+ struct i2o_controller *c;
+
+ if(n<0 || n>=MAX_I2O_CONTROLLERS)
+ return NULL;
+
+ down(&i2o_configuration_lock);
+ c=i2o_controllers[n];
+ if(c!=NULL)
+ atomic_inc(&c->users);
+ up(&i2o_configuration_lock);
+ return c;
+}
+
+/**
+ * i2o_issue_claim - claim or release a device
+ * @cmd: command
+ * @c: controller to claim for
+ * @tid: i2o task id
+ * @type: type of claim
+ *
+ * Issue I2O UTIL_CLAIM and UTIL_RELEASE messages. The message to be sent
+ * is set by cmd. The tid is the task id of the object to claim and the
+ * type is the claim type (see the i2o standard)
+ *
+ * Zero is returned on success.
+ */
+
+static int i2o_issue_claim(u32 cmd, struct i2o_controller *c, int tid, u32 type)
+{


+ u32 msg[5];
+

+ msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;

+ msg[1] = cmd << 24 | HOST_TID<<12 | tid;
+ msg[3] = 0;
+ msg[4] = type;
+
+ return i2o_post_wait(c, msg, sizeof(msg), 60);
+}
+
+/*
+ * i2o_claim_device - claim a device for use by an OSM
+ * @d: device to claim
+ * @h: handler for this device
+ *
+ * Do the leg work to assign a device to a given OSM on Linux. The
+ * kernel updates the internal handler data for the device and then
+ * performs an I2O claim for the device, attempting to claim the
+ * device as primary. If the attempt fails a negative errno code
+ * is returned. On success zero is returned.
+ */
+
+int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h)
+{
+ down(&i2o_configuration_lock);
+ if (d->owner) {
+ printk(KERN_INFO "Device claim called, but dev already owned by %s!",
+ h->name);
+ up(&i2o_configuration_lock);
+ return -EBUSY;
+ }
+ d->owner=h;
+
+ if(i2o_issue_claim(I2O_CMD_UTIL_CLAIM ,d->controller,d->lct_data.tid,
+ I2O_CLAIM_PRIMARY))
+ {
+ d->owner = NULL;
+ return -EBUSY;
+ }
+ up(&i2o_configuration_lock);


+ return 0;
+}
+

+/**
+ * i2o_release_device - release a device that the OSM is using
+ * @d: device to claim
+ * @h: handler for this device
+ *
+ * Drop a claim by an OSM on a given I2O device. The handler is cleared
+ * and 0 is returned on success.
+ *
+ * AC - some devices seem to want to refuse an unclaim until they have
+ * finished internal processing. It makes sense since you don't want a
+ * new device to go reconfiguring the entire system until you are done.
+ * Thus we are prepared to wait briefly.
+ */
+
+int i2o_release_device(struct i2o_device *d, struct i2o_handler *h)
+{
+ int err = 0;
+ int tries;
+
+ down(&i2o_configuration_lock);
+ if (d->owner != h) {
+ printk(KERN_INFO "Claim release called, but not owned by %s!\n",
+ h->name);
+ up(&i2o_configuration_lock);
+ return -ENOENT;
+ }
+
+ for(tries=0;tries<10;tries++)
+ {
+ d->owner = NULL;
+
+ /*
+ * If the controller takes a nonblocking approach to
+ * releases we have to sleep/poll for a few times.
+ */
+
+ if((err=i2o_issue_claim(I2O_CMD_UTIL_RELEASE, d->controller, d->lct_data.tid, I2O_CLAIM_PRIMARY)) )
+ {
+ err = -ENXIO;
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(HZ);
+ }
+ else
+ {
+ err=0;
+ break;
+ }
+ }
+ up(&i2o_configuration_lock);


+ return err;
+}
+

+/**
+ * i2o_device_notify_on - Enable deletion notifiers
+ * @d: device for notification
+ * @h: handler to install
+ *
+ * Called by OSMs to let the core know that they want to be
+ * notified if the given device is deleted from the system.
+ */
+
+int i2o_device_notify_on(struct i2o_device *d, struct i2o_handler *h)


+{
+ int i;
+

+ if(d->num_managers == I2O_MAX_MANAGERS)
+ return -ENOSPC;
+
+ for(i = 0; i < I2O_MAX_MANAGERS; i++)
+ {
+ if(!d->managers[i])
+ {
+ d->managers[i] = h;


+ break;
+ }
+ }
+

+ d->num_managers++;


+
+ return 0;
+}
+

+/**
+ * i2o_device_notify_off - Remove deletion notifiers
+ * @d: device for notification
+ * @h: handler to remove
+ *
+ * Called by OSMs to let the core know that they no longer
+ * are interested in the fate of the given device.
+ */
+int i2o_device_notify_off(struct i2o_device *d, struct i2o_handler *h)


+{
+ int i;
+

+ for(i=0; i < I2O_MAX_MANAGERS; i++)
+ {
+ if(d->managers[i] == h)
+ {
+ d->managers[i] = NULL;
+ d->num_managers--;


+ return 0;
+ }
+ }
+

+ return -ENOENT;
+}
+
+/**
+ * i2o_event_register - register interest in an event
+ * @c: Controller to register interest with
+ * @tid: I2O task id
+ * @init_context: initiator context to use with this notifier
+ * @tr_context: transaction context to use with this notifier
+ * @evt_mask: mask of events
+ *
+ * Create and posts an event registration message to the task. No reply
+ * is waited for, or expected. Errors in posting will be reported.
+ */
+
+int i2o_event_register(struct i2o_controller *c, u32 tid,
+ u32 init_context, u32 tr_context, u32 evt_mask)
+{
+ u32 msg[5]; // Not performance critical, so we just
+ // i2o_post_this it instead of building it
+ // in IOP memory
+

+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;

+ msg[1] = I2O_CMD_UTIL_EVT_REGISTER<<24 | HOST_TID<<12 | tid;
+ msg[2] = init_context;
+ msg[3] = tr_context;
+ msg[4] = evt_mask;
+
+ return i2o_post_this(c, msg, sizeof(msg));
+}
+
+/*
+ * i2o_event_ack - acknowledge an event
+ * @c: controller
+ * @msg: pointer to the UTIL_EVENT_REGISTER reply we received
+ *
+ * We just take a pointer to the original UTIL_EVENT_REGISTER reply
+ * message and change the function code since that's what spec
+ * describes an EventAck message looking like.
+ */
+
+int i2o_event_ack(struct i2o_controller *c, u32 *msg)
+{
+ struct i2o_message *m = (struct i2o_message *)msg;
+
+ m->function = I2O_CMD_UTIL_EVT_ACK;
+
+ return i2o_post_wait(c, msg, m->size * 4, 2);
+}
+
+/*
+ * Core event handler. Runs as a separate thread and is woken
+ * up whenever there is an Executive class event.
+ */
+static int i2o_core_evt(void *reply_data)
+{
+ struct reply_info *reply = (struct reply_info *) reply_data;
+ u32 *msg = reply->msg;
+ struct i2o_controller *c = NULL;


+ unsigned long flags;
+

+ lock_kernel();
+ daemonize();
+ unlock_kernel();
+

+ strcpy(current->comm, "i2oevtd");


+ evt_running = 1;
+
+ while(1)
+ {

+ if(down_interruptible(&evt_sem))
+ {
+ dprintk(KERN_INFO "I2O event thread dead\n");
+ printk("exiting...");
+ evt_running = 0;
+ complete_and_exit(&evt_dead, 0);
+ }
+
+ /*
+ * Copy the data out of the queue so that we don't have to lock
+ * around the whole function and just around the qlen update
+ */
+ spin_lock_irqsave(&i2o_evt_lock, flags);
+ memcpy(reply, &events[evt_out], sizeof(struct reply_info));
+ MODINC(evt_out, I2O_EVT_Q_LEN);
+ evt_q_len--;
+ spin_unlock_irqrestore(&i2o_evt_lock, flags);
+
+ c = reply->iop;
+ dprintk(KERN_INFO "I2O IRTOS EVENT: iop%d, event %#10x\n", c->unit, msg[4]);
+
+ /*
+ * We do not attempt to delete/quiesce/etc. the controller if
+ * some sort of error indidication occurs. We may want to do
+ * so in the future, but for now we just let the user deal with
+ * it. One reason for this is that what to do with an error
+ * or when to send what ærror is not really agreed on, so
+ * we get errors that may not be fatal but just look like they
+ * are...so let the user deal with it.
+ */
+ switch(msg[4])
+ {
+ case I2O_EVT_IND_EXEC_RESOURCE_LIMITS:
+ printk(KERN_ERR "%s: Out of resources\n", c->name);
+ break;
+
+ case I2O_EVT_IND_EXEC_POWER_FAIL:
+ printk(KERN_ERR "%s: Power failure\n", c->name);
+ break;
+
+ case I2O_EVT_IND_EXEC_HW_FAIL:
+ {
+ char *fail[] =
+ {
+ "Unknown Error",
+ "Power Lost",
+ "Code Violation",
+ "Parity Error",
+ "Code Execution Exception",
+ "Watchdog Timer Expired"
+ };
+
+ if(msg[5] <= 6)
+ printk(KERN_ERR "%s: Hardware Failure: %s\n",
+ c->name, fail[msg[5]]);
+ else
+ printk(KERN_ERR "%s: Unknown Hardware Failure\n", c->name);
+


+ break;
+ }
+
+ /*

+ * New device created
+ * - Create a new i2o_device entry
+ * - Inform all interested drivers about this device's existence
+ */
+ case I2O_EVT_IND_EXEC_NEW_LCT_ENTRY:
+ {
+ struct i2o_device *d = (struct i2o_device *)
+ kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ int i;
+
+ if (d == NULL) {
+ printk(KERN_EMERG "i2oevtd: out of memory\n");
+ break;
+ }
+ memcpy(&d->lct_data, &msg[5], sizeof(i2o_lct_entry));
+
+ d->next = NULL;
+ d->controller = c;
+ d->flags = 0;
+
+ i2o_report_controller_unit(c, d);
+ i2o_install_device(c,d);
+
+ for(i = 0; i < MAX_I2O_MODULES; i++)
+ {
+ if(i2o_handlers[i] &&
+ i2o_handlers[i]->new_dev_notify &&
+ (i2o_handlers[i]->class&d->lct_data.class_id))
+ {
+ spin_lock(&i2o_dev_lock);
+ i2o_handlers[i]->new_dev_notify(c,d);
+ spin_unlock(&i2o_dev_lock);
+ }
+ }
+

+ break;
+ }
+
+ /*

+ * LCT entry for a device has been modified, so update it
+ * internally.
+ */
+ case I2O_EVT_IND_EXEC_MODIFIED_LCT:
+ {
+ struct i2o_device *d;
+ i2o_lct_entry *new_lct = (i2o_lct_entry *)&msg[5];
+
+ for(d = c->devices; d; d = d->next)
+ {
+ if(d->lct_data.tid == new_lct->tid)
+ {
+ memcpy(&d->lct_data, new_lct, sizeof(i2o_lct_entry));
+ break;
+ }
+ }
+ break;
+ }
+
+ case I2O_EVT_IND_CONFIGURATION_FLAG:
+ printk(KERN_WARNING "%s requires user configuration\n", c->name);
+ break;
+
+ case I2O_EVT_IND_GENERAL_WARNING:
+ printk(KERN_WARNING "%s: Warning notification received!"
+ "Check configuration for errors!\n", c->name);
+ break;
+
+ case I2O_EVT_IND_EVT_MASK_MODIFIED:
+ /* Well I guess that was us hey .. */


+ break;
+
+ default:

+ printk(KERN_WARNING "%s: No handler for event (0x%08x)\n", c->name, msg[4]);


+ break;
+ }
+ }
+

+ return 0;
+}
+
+/*

+ * Dynamic LCT update. This compares the LCT with the currently
+ * installed devices to check for device deletions..this needed b/c there
+ * is no DELETED_LCT_ENTRY EventIndicator for the Executive class so
+ * we can't just have the event handler do this...annoying
+ *
+ * This is a hole in the spec that will hopefully be fixed someday.
+ */
+static int i2o_dyn_lct(void *foo)
+{
+ struct i2o_controller *c = (struct i2o_controller *)foo;
+ struct i2o_device *d = NULL;
+ struct i2o_device *d1 = NULL;


+ int i = 0;

+ int found = 0;
+ int entries;
+ void *tmp;
+ char name[16];


+
+ lock_kernel();
+ daemonize();
+ unlock_kernel();
+

+ sprintf(name, "iop%d_lctd", c->unit);
+ strcpy(current->comm, name);
+
+ c->lct_running = 1;
+
+ while(1)
+ {
+ down_interruptible(&c->lct_sem);
+ if(signal_pending(current))
+ {
+ dprintk(KERN_ERR "%s: LCT thread dead\n", c->name);
+ c->lct_running = 0;


+ return 0;
+ }
+

+ entries = c->dlct->table_size;
+ entries -= 3;
+ entries /= 9;
+
+ dprintk(KERN_INFO "%s: Dynamic LCT Update\n",c->name);
+ dprintk(KERN_INFO "%s: Dynamic LCT contains %d entries\n", c->name, entries);
+
+ if(!entries)
+ {
+ printk(KERN_INFO "%s: Empty LCT???\n", c->name);
+ continue;
+ }
+
+ /*
+ * Loop through all the devices on the IOP looking for their
+ * LCT data in the LCT. We assume that TIDs are not repeated.
+ * as that is the only way to really tell. It's been confirmed
+ * by the IRTOS vendor(s?) that TIDs are not reused until they
+ * wrap arround(4096), and I doubt a system will up long enough
+ * to create/delete that many devices.
+ */
+ for(d = c->devices; d; )
+ {
+ found = 0;
+ d1 = d->next;
+
+ for(i = 0; i < entries; i++)
+ {
+ if(d->lct_data.tid == c->dlct->lct_entry[i].tid)
+ {
+ found = 1;
+ break;
+ }
+ }
+ if(!found)
+ {
+ dprintk(KERN_INFO "i2o_core: Deleted device!\n");
+ spin_lock(&i2o_dev_lock);
+ i2o_delete_device(d);
+ spin_unlock(&i2o_dev_lock);
+ }
+ d = d1;
+ }
+
+ /*
+ * Tell LCT to renotify us next time there is a change
+ */
+ i2o_lct_notify(c);
+
+ /*
+ * Copy new LCT into public LCT
+ *
+ * Possible race if someone is reading LCT while we are copying
+ * over it. If this happens, we'll fix it then. but I doubt that
+ * the LCT will get updated often enough or will get read by
+ * a user often enough to worry.
+ */
+ if(c->lct->table_size < c->dlct->table_size)
+ {
+ tmp = c->lct;
+ c->lct = kmalloc(c->dlct->table_size<<2, GFP_KERNEL);
+ if(!c->lct)
+ {
+ printk(KERN_ERR "%s: No memory for LCT!\n", c->name);
+ c->lct = tmp;
+ continue;
+ }
+ kfree(tmp);
+ }
+ memcpy(c->lct, c->dlct, c->dlct->table_size<<2);
+ }


+
+ return 0;
+}
+

+/**
+ * i2o_run_queue - process pending events on a controller
+ * @c: controller to process
+ *
+ * This is called by the bus specific driver layer when an interrupt
+ * or poll of this card interface is desired.
+ */
+
+void i2o_run_queue(struct i2o_controller *c)
+{
+ struct i2o_message *m;
+ u32 mv;
+ u32 *msg;
+
+ /*
+ * Old 960 steppings had a bug in the I2O unit that caused
+ * the queue to appear empty when it wasn't.
+ */
+ if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF)
+ mv=I2O_REPLY_READ32(c);
+
+ while(mv!=0xFFFFFFFF)
+ {
+ struct i2o_handler *i;
+ /* Map the message from the page frame map to kernel virtual */
+ m=(struct i2o_message *)(mv - (unsigned long)c->page_frame_map + (unsigned long)c->page_frame);
+ msg=(u32*)m;
+
+ /*
+ * Ensure this message is seen coherently but cachably by


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 25'
echo 'File patch-2.4.13 is continued in part 26'
echo "26" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:56 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part26

#!/bin/sh -x
# this is part 26 of a 53 - part archive


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

if test "$Scheck" != 26; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ * the processor
+ */
+
+ pci_dma_sync_single(c->pdev, c->page_frame_map, MSG_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+
+ /*
+ * Despatch it
+ */
+
+ i=i2o_handlers[m->initiator_context&(MAX_I2O_MODULES-1)];
+ if(i && i->reply)
+ i->reply(i,c,m);
+ else
+ {
+ printk(KERN_WARNING "I2O: Spurious reply to handler %d\n",
+ m->initiator_context&(MAX_I2O_MODULES-1));
+ }
+ i2o_flush_reply(c,mv);
+ mb();
+
+ /* That 960 bug again... */

+ if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF)
+ mv=I2O_REPLY_READ32(c);
+ }
+}

+
+
+/**
+ * i2o_get_class_name - do i2o class name lookup
+ * @class: class number
+ *
+ * Return a descriptive string for an i2o class
+ */
+
+const char *i2o_get_class_name(int class)
+{
+ int idx = 16;
+ static char *i2o_class_name[] = {
+ "Executive",
+ "Device Driver Module",
+ "Block Device",
+ "Tape Device",
+ "LAN Interface",
+ "WAN Interface",
+ "Fibre Channel Port",
+ "Fibre Channel Device",
+ "SCSI Device",
+ "ATE Port",
+ "ATE Device",
+ "Floppy Controller",
+ "Floppy Device",
+ "Secondary Bus Port",
+ "Peer Transport Agent",
+ "Peer Transport",
+ "Unknown"
+ };
+
+ switch(class&0xFFF)
+ {
+ case I2O_CLASS_EXECUTIVE:
+ idx = 0; break;
+ case I2O_CLASS_DDM:
+ idx = 1; break;
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ idx = 2; break;
+ case I2O_CLASS_SEQUENTIAL_STORAGE:
+ idx = 3; break;
+ case I2O_CLASS_LAN:
+ idx = 4; break;
+ case I2O_CLASS_WAN:
+ idx = 5; break;
+ case I2O_CLASS_FIBRE_CHANNEL_PORT:
+ idx = 6; break;
+ case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
+ idx = 7; break;
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ idx = 8; break;
+ case I2O_CLASS_ATE_PORT:
+ idx = 9; break;
+ case I2O_CLASS_ATE_PERIPHERAL:
+ idx = 10; break;
+ case I2O_CLASS_FLOPPY_CONTROLLER:
+ idx = 11; break;
+ case I2O_CLASS_FLOPPY_DEVICE:
+ idx = 12; break;
+ case I2O_CLASS_BUS_ADAPTER_PORT:
+ idx = 13; break;
+ case I2O_CLASS_PEER_TRANSPORT_AGENT:
+ idx = 14; break;
+ case I2O_CLASS_PEER_TRANSPORT:
+ idx = 15; break;
+ }
+
+ return i2o_class_name[idx];
+}
+
+
+/**
+ * i2o_wait_message - obtain an i2o message from the IOP
+ * @c: controller
+ * @why: explanation
+ *
+ * This function waits up to 5 seconds for a message slot to be
+ * available. If no message is available it prints an error message
+ * that is expected to be what the message will be used for (eg
+ * "get_status"). 0xFFFFFFFF is returned on a failure.
+ *
+ * On a success the message is returned. This is the physical page
+ * frame offset address from the read port. (See the i2o spec)
+ */
+
+u32 i2o_wait_message(struct i2o_controller *c, char *why)
+{
+ long time=jiffies;
+ u32 m;
+ while((m=I2O_POST_READ32(c))==0xFFFFFFFF)
+ {
+ if((jiffies-time)>=5*HZ)
+ {
+ dprintk(KERN_ERR "%s: Timeout waiting for message frame to send %s.\n",
+ c->name, why);
+ return 0xFFFFFFFF;
+ }
+ schedule();
+ barrier();
+ }
+ return m;
+}
+
+/**
+ * i2o_report_controller_unit - print information about a tid


+ * @c: controller
+ * @d: device
+ *

+ * Dump an information block associated with a given unit (TID). The
+ * tables are read and a block of text is output to printk that is
+ * formatted intended for the user.
+ */
+
+void i2o_report_controller_unit(struct i2o_controller *c, struct i2o_device *d)
+{
+ char buf[64];
+ char str[22];
+ int ret;
+ int unit = d->lct_data.tid;
+
+ if(verbose==0)
+ return;
+
+ printk(KERN_INFO "Target ID %d.\n", unit);
+ if((ret=i2o_query_scalar(c, unit, 0xF100, 3, buf, 16))>=0)
+ {
+ buf[16]=0;
+ printk(KERN_INFO " Vendor: %s\n", buf);
+ }
+ if((ret=i2o_query_scalar(c, unit, 0xF100, 4, buf, 16))>=0)
+ {
+ buf[16]=0;
+ printk(KERN_INFO " Device: %s\n", buf);
+ }
+ if(i2o_query_scalar(c, unit, 0xF100, 5, buf, 16)>=0)
+ {
+ buf[16]=0;
+ printk(KERN_INFO " Description: %s\n", buf);
+ }
+ if((ret=i2o_query_scalar(c, unit, 0xF100, 6, buf, 8))>=0)
+ {
+ buf[8]=0;
+ printk(KERN_INFO " Rev: %s\n", buf);
+ }
+
+ printk(KERN_INFO " Class: ");
+ sprintf(str, "%-21s", i2o_get_class_name(d->lct_data.class_id));
+ printk("%s\n", str);
+
+ printk(KERN_INFO " Subclass: 0x%04X\n", d->lct_data.sub_class);
+ printk(KERN_INFO " Flags: ");
+
+ if(d->lct_data.device_flags&(1<<0))
+ printk("C"); // ConfigDialog requested
+ if(d->lct_data.device_flags&(1<<1))
+ printk("U"); // Multi-user capable
+ if(!(d->lct_data.device_flags&(1<<4)))
+ printk("P"); // Peer service enabled!
+ if(!(d->lct_data.device_flags&(1<<5)))
+ printk("M"); // Mgmt service enabled!
+ printk("\n");
+
+}
+
+
+/*
+ * Parse the hardware resource table. Right now we print it out
+ * and don't do a lot with it. We should collate these and then
+ * interact with the Linux resource allocation block.
+ *
+ * Lets prove we can read it first eh ?
+ *
+ * This is full of endianisms!
+ */
+
+static int i2o_parse_hrt(struct i2o_controller *c)
+{
+#ifdef DRIVERDEBUG
+ u32 *rows=(u32*)c->hrt;
+ u8 *p=(u8 *)c->hrt;
+ u8 *d;
+ int count;
+ int length;
+ int i;
+ int state;
+
+ if(p[3]!=0)
+ {
+ printk(KERN_ERR "%s: HRT table for controller is too new a version.\n",
+ c->name);


+ return -1;
+ }
+

+ count=p[0]|(p[1]<<8);
+ length = p[2];
+
+ printk(KERN_INFO "%s: HRT has %d entries of %d bytes each.\n",
+ c->name, count, length<<2);
+
+ rows+=2;
+
+ for(i=0;i<count;i++)
+ {
+ printk(KERN_INFO "Adapter %08X: ", rows[0]);
+ p=(u8 *)(rows+1);
+ d=(u8 *)(rows+2);
+ state=p[1]<<8|p[0];
+
+ printk("TID %04X:[", state&0xFFF);
+ state>>=12;
+ if(state&(1<<0))
+ printk("H"); /* Hidden */
+ if(state&(1<<2))
+ {
+ printk("P"); /* Present */
+ if(state&(1<<1))
+ printk("C"); /* Controlled */
+ }
+ if(state>9)
+ printk("*"); /* Hard */
+
+ printk("]:");
+
+ switch(p[3]&0xFFFF)
+ {
+ case 0:
+ /* Adapter private bus - easy */
+ printk("Local bus %d: I/O at 0x%04X Mem 0x%08X",
+ p[2], d[1]<<8|d[0], *(u32 *)(d+4));
+ break;
+ case 1:
+ /* ISA bus */
+ printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X",
+ p[2], d[2], d[1]<<8|d[0], *(u32 *)(d+4));
+ break;
+
+ case 2: /* EISA bus */
+ printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X",
+ p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4));
+ break;
+
+ case 3: /* MCA bus */
+ printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X",
+ p[2], d[3], d[1]<<8|d[0], *(u32 *)(d+4));
+ break;
+
+ case 4: /* PCI bus */
+ printk("PCI %d: Bus %d Device %d Function %d",
+ p[2], d[2], d[1], d[0]);
+ break;
+
+ case 0x80: /* Other */
+ default:
+ printk("Unsupported bus type.");
+ break;
+ }
+ printk("\n");
+ rows+=length;
+ }
+#endif


+ return 0;
+}
+
+/*

+ * The logical configuration table tells us what we can talk to
+ * on the board. Most of the stuff isn't interesting to us.
+ */
+
+static int i2o_parse_lct(struct i2o_controller *c)
+{
+ int i;
+ int max;
+ int tid;
+ struct i2o_device *d;
+ i2o_lct *lct = c->lct;
+
+ if (lct == NULL) {
+ printk(KERN_ERR "%s: LCT is empty???\n", c->name);


+ return -1;
+ }
+

+ max = lct->table_size;
+ max -= 3;
+ max /= 9;
+
+ printk(KERN_INFO "%s: LCT has %d entries.\n", c->name, max);
+
+ if(lct->iop_flags&(1<<0))
+ printk(KERN_WARNING "%s: Configuration dialog desired.\n", c->name);
+
+ for(i=0;i<max;i++)
+ {
+ d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ if(d==NULL)
+ {
+ printk(KERN_CRIT "i2o_core: Out of memory for I2O device data.\n");


+ return -ENOMEM;
+ }
+

+ d->controller = c;

+ d->next = NULL;
+
+ memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+ d->flags = 0;
+ tid = d->lct_data.tid;


+
+ i2o_report_controller_unit(c, d);
+

+ i2o_install_device(c, d);


+ }
+ return 0;
+}
+
+

+/**
+ * i2o_quiesce_controller - quiesce controller


+ * @c: controller
+ *

+ * Quiesce an IOP. Causes IOP to make external operation quiescent
+ * (i2o 'READY' state). Internal operation of the IOP continues normally.
+ */
+
+int i2o_quiesce_controller(struct i2o_controller *c)
+{
+ u32 msg[4];
+ int ret;
+
+ i2o_status_get(c);
+
+ /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
+
+ if ((c->status_block->iop_state != ADAPTER_STATE_READY) &&
+ (c->status_block->iop_state != ADAPTER_STATE_OPERATIONAL))


+ {
+ return 0;
+ }
+

+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;

+ msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;


+ msg[3] = 0;
+

+ /* Long timeout needed for quiesce if lots of devices */
+
+ if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240)))
+ printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n",
+ c->name, -ret);
+ else
+ dprintk(KERN_INFO "%s: Quiesced.\n", c->name);
+
+ i2o_status_get(c); // Entered READY state


+ return ret;
+}
+
+/**

+ * i2o_enable_controller - move controller from ready to operational


+ * @c: controller
+ *

+ * Enable IOP. This allows the IOP to resume external operations and
+ * reverses the effect of a quiesce. In the event of an error a negative


+ * errno code is returned.

+ */
+
+int i2o_enable_controller(struct i2o_controller *c)
+{
+ u32 msg[4];
+ int ret;
+
+ i2o_status_get(c);
+
+ /* Enable only allowed on READY state */
+ if(c->status_block->iop_state != ADAPTER_STATE_READY)
+ return -EINVAL;
+
+ msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
+
+ /* How long of a timeout do we need? */
+
+ if ((ret = i2o_post_wait(c, msg, sizeof(msg), 240)))
+ printk(KERN_ERR "%s: Could not enable (status=%#x).\n",
+ c->name, -ret);
+ else
+ dprintk(KERN_INFO "%s: Enabled.\n", c->name);
+
+ i2o_status_get(c); // entered OPERATIONAL state


+
+ return ret;
+}
+
+/**

+ * i2o_clear_controller - clear a controller


+ * @c: controller
+ *

+ * Clear an IOP to HOLD state, ie. terminate external operations, clear all
+ * input queues and prepare for a system restart. IOP's internal operation
+ * continues normally and the outbound queue is alive.
+ * The IOP is not expected to rebuild its LCT.
+ */
+
+int i2o_clear_controller(struct i2o_controller *c)
+{
+ struct i2o_controller *iop;
+ u32 msg[4];
+ int ret;
+
+ /* Quiesce all IOPs first */
+
+ for (iop = i2o_controller_chain; iop; iop = iop->next)
+ i2o_quiesce_controller(iop);
+
+ msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_ADAPTER_CLEAR<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[3]=0;
+
+ if ((ret=i2o_post_wait(c, msg, sizeof(msg), 30)))
+ printk(KERN_INFO "%s: Unable to clear (status=%#x).\n",
+ c->name, -ret);
+ else
+ dprintk(KERN_INFO "%s: Cleared.\n",c->name);
+
+ i2o_status_get(c);
+
+ /* Enable other IOPs */
+
+ for (iop = i2o_controller_chain; iop; iop = iop->next)
+ if (iop != c)
+ i2o_enable_controller(iop);


+
+ return ret;
+}
+
+

+/**
+ * i2o_reset_controller - reset an IOP
+ * @c: controller to reset
+ *
+ * Reset the IOP into INIT state and wait until IOP gets into RESET state.
+ * Terminate all external operations, clear IOP's inbound and outbound
+ * queues, terminate all DDMs, and reload the IOP's operating environment
+ * and all local DDMs. The IOP rebuilds its LCT.
+ */
+
+static int i2o_reset_controller(struct i2o_controller *c)
+{
+ struct i2o_controller *iop;
+ u32 m;
+ u8 *status;
+ u32 *msg;
+ long time;
+
+ /* Quiesce all IOPs first */
+
+ for (iop = i2o_controller_chain; iop; iop = iop->next)
+ {
+ if(iop->type != I2O_TYPE_PCI || !iop->bus.pci.dpt)
+ i2o_quiesce_controller(iop);
+ }
+
+ m=i2o_wait_message(c, "AdapterReset");
+ if(m==0xFFFFFFFF)
+ return -ETIMEDOUT;
+ msg=(u32 *)(c->mem_offset+m);
+
+ status=(void *)kmalloc(4, GFP_KERNEL);
+ if(status==NULL) {
+ printk(KERN_ERR "IOP reset failed - no free memory.\n");
+ return -ENOMEM;
+ }
+ memset(status, 0, 4);
+
+ msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[2]=core_context;
+ msg[3]=0;
+ msg[4]=0;
+ msg[5]=0;
+ msg[6]=virt_to_bus(status);
+ msg[7]=0; /* 64bit host FIXME */
+
+ i2o_post_message(c,m);
+
+ /* Wait for a reply */
+ time=jiffies;
+ while(*status==0)
+ {
+ if((jiffies-time)>=20*HZ)
+ {
+ printk(KERN_ERR "IOP reset timeout.\n");
+ // Better to leak this for safety: kfree(status);
+ return -ETIMEDOUT;
+ }
+ schedule();
+ barrier();
+ }
+
+ if (*status==I2O_CMD_IN_PROGRESS)
+ {
+ /*
+ * Once the reset is sent, the IOP goes into the INIT state
+ * which is indeterminate. We need to wait until the IOP
+ * has rebooted before we can let the system talk to
+ * it. We read the inbound Free_List until a message is
+ * available. If we can't read one in the given ammount of
+ * time, we assume the IOP could not reboot properly.
+ */
+
+ dprintk(KERN_INFO "%s: Reset in progress, waiting for reboot...\n",
+ c->name);
+
+ time = jiffies;
+ m = I2O_POST_READ32(c);
+ while(m == 0XFFFFFFFF)
+ {
+ if((jiffies-time) >= 30*HZ)
+ {
+ printk(KERN_ERR "%s: Timeout waiting for IOP reset.\n",
+ c->name);
+ return -ETIMEDOUT;
+ }
+ schedule();
+ barrier();
+ m = I2O_POST_READ32(c);
+ }
+ i2o_flush_reply(c,m);
+ }
+
+ /* If IopReset was rejected or didn't perform reset, try IopClear */
+
+ i2o_status_get(c);
+ if (status[0] == I2O_CMD_REJECTED ||
+ c->status_block->iop_state != ADAPTER_STATE_RESET)
+ {
+ printk(KERN_WARNING "%s: Reset rejected, trying to clear\n",c->name);
+ i2o_clear_controller(c);
+ }
+ else
+ dprintk(KERN_INFO "%s: Reset completed.\n", c->name);
+
+ /* Enable other IOPs */
+
+ for (iop = i2o_controller_chain; iop; iop = iop->next)
+ if (iop != c)
+ i2o_enable_controller(iop);
+
+ kfree(status);


+ return 0;
+}
+
+

+/**
+ * i2o_status_get - get the status block for the IOP


+ * @c: controller
+ *

+ * Issue a status query on the controller. This updates the
+ * attached status_block. If the controller fails to reply or an
+ * error occurs then a negative errno code is returned. On success
+ * zero is returned and the status_blok is updated.
+ */
+
+int i2o_status_get(struct i2o_controller *c)
+{
+ long time;
+ u32 m;
+ u32 *msg;
+ u8 *status_block;
+
+ if (c->status_block == NULL)
+ {
+ c->status_block = (i2o_status_block *)
+ kmalloc(sizeof(i2o_status_block),GFP_KERNEL);
+ if (c->status_block == NULL)
+ {
+ printk(KERN_CRIT "%s: Get Status Block failed; Out of memory.\n",
+ c->name);


+ return -ENOMEM;
+ }
+ }
+

+ status_block = (u8*)c->status_block;
+ memset(c->status_block,0,sizeof(i2o_status_block));
+
+ m=i2o_wait_message(c, "StatusGet");
+ if(m==0xFFFFFFFF)
+ return -ETIMEDOUT;
+ msg=(u32 *)(c->mem_offset+m);
+
+ msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[2]=core_context;
+ msg[3]=0;
+ msg[4]=0;
+ msg[5]=0;
+ msg[6]=virt_to_bus(c->status_block);
+ msg[7]=0; /* 64bit host FIXME */
+ msg[8]=sizeof(i2o_status_block); /* always 88 bytes */
+
+ i2o_post_message(c,m);
+
+ /* Wait for a reply */
+
+ time=jiffies;
+ while(status_block[87]!=0xFF)
+ {
+ if((jiffies-time)>=5*HZ)
+ {
+ printk(KERN_ERR "%s: Get status timeout.\n",c->name);
+ return -ETIMEDOUT;
+ }
+ schedule();
+ barrier();
+ }
+
+#ifdef DRIVERDEBUG
+ printk(KERN_INFO "%s: State = ", c->name);
+ switch (c->status_block->iop_state) {
+ case 0x01:
+ printk("INIT\n");
+ break;
+ case 0x02:
+ printk("RESET\n");
+ break;
+ case 0x04:
+ printk("HOLD\n");
+ break;
+ case 0x05:
+ printk("READY\n");
+ break;
+ case 0x08:
+ printk("OPERATIONAL\n");
+ break;
+ case 0x10:
+ printk("FAILED\n");
+ break;
+ case 0x11:
+ printk("FAULTED\n");
+ break;
+ default:
+ printk("%x (unknown !!)\n",c->status_block->iop_state);
+}
+#endif

+
+ return 0;
+}
+
+/*

+ * Get the Hardware Resource Table for the device.
+ * The HRT contains information about possible hidden devices
+ * but is mostly useless to us
+ */
+int i2o_hrt_get(struct i2o_controller *c)


+{
+ u32 msg[6];

+ int ret, size = sizeof(i2o_hrt);
+
+ /* First read just the header to figure out the real size */
+
+ do {
+ if (c->hrt == NULL) {
+ c->hrt=kmalloc(size, GFP_KERNEL);
+ if (c->hrt == NULL) {
+ printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", c->name);


+ return -ENOMEM;
+ }
+ }
+

+ msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
+ msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;


+ msg[3]= 0;

+ msg[4]= (0xD0000000 | size); /* Simple transaction */
+ msg[5]= virt_to_bus(c->hrt); /* Dump it here */
+
+ ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL);
+
+ if(ret == -ETIMEDOUT)
+ {
+ /* The HRT block we used is in limbo somewhere. When the iop wakes up
+ we will recover it */


+ c->hrt = NULL;

+ return ret;
+ }
+

+ if(ret<0)
+ {
+ printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n",
+ c->name, -ret);

+ return ret;
+ }
+

+ if (c->hrt->num_entries * c->hrt->entry_len << 2 > size) {
+ size = c->hrt->num_entries * c->hrt->entry_len << 2;
+ kfree(c->hrt);


+ c->hrt = NULL;
+ }

+ } while (c->hrt == NULL);
+
+ i2o_parse_hrt(c); // just for debugging


+
+ return 0;
+}
+
+/*

+ * Send the I2O System Table to the specified IOP
+ *
+ * The system table contains information about all the IOPs in the
+ * system. It is build and then sent to each IOP so that IOPs can
+ * establish connections between each other.
+ *
+ */
+static int i2o_systab_send(struct i2o_controller *iop)
+{
+ u32 msg[12];
+ int ret;
+ u32 *privbuf = kmalloc(16, GFP_KERNEL);
+ if(privbuf == NULL)
+ return -ENOMEM;
+
+ if(iop->type == I2O_TYPE_PCI)
+ {
+ struct resource *root;
+
+ if(iop->status_block->current_mem_size < iop->status_block->desired_mem_size)
+ {
+ struct resource *res = &iop->mem_resource;
+ res->name = iop->pdev->bus->name;
+ res->flags = IORESOURCE_MEM;
+ res->start = 0;
+ res->end = 0;
+ printk("%s: requires private memory resources.\n", iop->name);
+ root = pci_find_parent_resource(iop->pdev, res);
+ if(root==NULL)
+ printk("Can't find parent resource!\n");
+ if(root && allocate_resource(root, res,
+ iop->status_block->desired_mem_size,
+ iop->status_block->desired_mem_size,
+ iop->status_block->desired_mem_size,
+ 1<<20, /* Unspecified, so use 1Mb and play safe */
+ NULL,
+ NULL)>=0)
+ {
+ iop->mem_alloc = 1;
+ iop->status_block->current_mem_size = 1 + res->end - res->start;
+ iop->status_block->current_mem_base = res->start;
+ printk(KERN_INFO "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n",
+ iop->name, 1+res->end-res->start, res->start);
+ }
+ }
+ if(iop->status_block->current_io_size < iop->status_block->desired_io_size)
+ {
+ struct resource *res = &iop->io_resource;
+ res->name = iop->pdev->bus->name;
+ res->flags = IORESOURCE_IO;
+ res->start = 0;
+ res->end = 0;
+ printk("%s: requires private memory resources.\n", iop->name);
+ root = pci_find_parent_resource(iop->pdev, res);
+ if(root==NULL)
+ printk("Can't find parent resource!\n");
+ if(root && allocate_resource(root, res,
+ iop->status_block->desired_io_size,
+ iop->status_block->desired_io_size,
+ iop->status_block->desired_io_size,
+ 1<<20, /* Unspecified, so use 1Mb and play safe */
+ NULL,
+ NULL)>=0)
+ {
+ iop->io_alloc = 1;
+ iop->status_block->current_io_size = 1 + res->end - res->start;
+ iop->status_block->current_mem_base = res->start;
+ printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n",
+ iop->name, 1+res->end-res->start, res->start);
+ }
+ }
+ }
+ else
+ {
+ privbuf[0] = iop->status_block->current_mem_base;
+ privbuf[1] = iop->status_block->current_mem_size;
+ privbuf[2] = iop->status_block->current_io_base;
+ privbuf[3] = iop->status_block->current_io_size;
+ }
+
+ msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
+ msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;


+ msg[3] = 0;

+ msg[4] = (0<<16) | ((iop->unit+2) ); /* Host 0 IOP ID (unit + 2) */
+ msg[5] = 0; /* Segment 0 */
+
+ /*
+ * Provide three SGL-elements:
+ * System table (SysTab), Private memory space declaration and
+ * Private i/o space declaration
+ *
+ * FIXME: provide these for controllers needing them
+ */
+ msg[6] = 0x54000000 | sys_tbl_len;
+ msg[7] = virt_to_bus(sys_tbl);
+ msg[8] = 0x54000000 | 8;
+ msg[9] = virt_to_bus(privbuf);
+ msg[10] = 0xD4000000 | 8;
+ msg[11] = virt_to_bus(privbuf+2);
+
+ ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
+
+ if(ret==-ETIMEDOUT)
+ {
+ printk(KERN_ERR "%s: SysTab setup timed out.\n", iop->name);
+ }
+ else if(ret<0)
+ {
+ printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n",
+ iop->name, -ret);
+ kfree(privbuf);
+ }
+ else
+ {
+ dprintk(KERN_INFO "%s: SysTab set.\n", iop->name);
+ kfree(privbuf);
+ }
+ i2o_status_get(iop); // Entered READY state


+
+ return ret;
+
+ }

+
+/*
+ * Initialize I2O subsystem.
+ */
+static void __init i2o_sys_init(void)
+{
+ struct i2o_controller *iop, *niop = NULL;
+
+ printk(KERN_INFO "Activating I2O controllers...\n");
+ printk(KERN_INFO "This may take a few minutes if there are many devices\n");
+
+ /* In INIT state, Activate IOPs */
+ for (iop = i2o_controller_chain; iop; iop = niop) {
+ dprintk(KERN_INFO "Calling i2o_activate_controller for %s...\n",
+ iop->name);
+ niop = iop->next;
+ if (i2o_activate_controller(iop) < 0)
+ i2o_delete_controller(iop);
+ }
+
+ /* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+ if (i2o_controller_chain == NULL)
+ return;
+
+ /*
+ * If build_sys_table fails, we kill everything and bail
+ * as we can't init the IOPs w/o a system table
+ */
+ dprintk(KERN_INFO "i2o_core: Calling i2o_build_sys_table...\n");
+ if (i2o_build_sys_table() < 0) {
+ i2o_sys_shutdown();
+ return;
+ }
+
+ /* If IOP don't get online, we need to rebuild the System table */
+ for (iop = i2o_controller_chain; iop; iop = niop) {
+ niop = iop->next;
+ dprintk(KERN_INFO "Calling i2o_online_controller for %s...\n", iop->name);
+ if (i2o_online_controller(iop) < 0) {
+ i2o_delete_controller(iop);
+ goto rebuild_sys_tab;
+ }
+ }
+
+ /* Active IOPs now in OPERATIONAL state */
+
+ /*
+ * Register for status updates from all IOPs
+ */
+ for(iop = i2o_controller_chain; iop; iop=iop->next) {
+
+ /* Create a kernel thread to deal with dynamic LCT updates */
+ iop->lct_pid = kernel_thread(i2o_dyn_lct, iop, CLONE_SIGHAND);
+
+ /* Update change ind on DLCT */
+ iop->dlct->change_ind = iop->lct->change_ind;
+
+ /* Start dynamic LCT updates */
+ i2o_lct_notify(iop);
+
+ /* Register for all events from IRTOS */
+ i2o_event_register(iop, core_context, 0, 0, 0xFFFFFFFF);
+ }
+}
+
+/**
+ * i2o_sys_shutdown - shutdown I2O system
+ *
+ * Bring down each i2o controller and then return. Each controller
+ * is taken through an orderly shutdown
+ */
+
+static void i2o_sys_shutdown(void)
+{
+ struct i2o_controller *iop, *niop;
+
+ /* Delete all IOPs from the controller chain */
+ /* that will reset all IOPs too */
+
+ for (iop = i2o_controller_chain; iop; iop = niop) {
+ niop = iop->next;
+ i2o_delete_controller(iop);
+ }
+}
+
+/**
+ * i2o_activate_controller - bring controller up to HOLD
+ * @iop: controller
+ *
+ * This function brings an I2O controller into HOLD state. The adapter
+ * is reset if neccessary and then the queues and resource table
+ * are read. -1 is returned on a failure, 0 on success.
+ *
+ */
+
+int i2o_activate_controller(struct i2o_controller *iop)
+{
+ /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
+ /* In READY state, Get status */
+
+ if (i2o_status_get(iop) < 0) {
+ printk(KERN_INFO "Unable to obtain status of %s, "
+ "attempting a reset.\n", iop->name);
+ if (i2o_reset_controller(iop) < 0)


+ return -1;
+ }
+

+ if(iop->status_block->iop_state == ADAPTER_STATE_FAULTED) {
+ printk(KERN_CRIT "%s: hardware fault\n", iop->name);


+ return -1;
+ }
+

+ if (iop->status_block->i2o_version > I2OVER15) {
+ printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O Specification.\n",
+ iop->name);


+ return -1;
+ }
+

+ if (iop->status_block->iop_state == ADAPTER_STATE_READY ||
+ iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
+ iop->status_block->iop_state == ADAPTER_STATE_HOLD ||
+ iop->status_block->iop_state == ADAPTER_STATE_FAILED)
+ {
+ dprintk(KERN_INFO "%s: Already running, trying to reset...\n",
+ iop->name);
+ if (i2o_reset_controller(iop) < 0)


+ return -1;
+ }
+

+ if (i2o_init_outbound_q(iop) < 0)
+ return -1;
+
+ if (i2o_post_outbound_messages(iop))
+ return -1;
+
+ /* In HOLD state */
+
+ if (i2o_hrt_get(iop) < 0)
+ return -1;


+
+ return 0;
+}
+
+

+/**
+ * i2o_init_outbound_queue - setup the outbound queue


+ * @c: controller
+ *

+ * Clear and (re)initialize IOP's outbound queue. Returns 0 on
+ * success or a negative errno code on a failure.
+ */
+
+int i2o_init_outbound_q(struct i2o_controller *c)
+{
+ u8 *status;
+ u32 m;
+ u32 *msg;
+ u32 time;
+
+ dprintk(KERN_INFO "%s: Initializing Outbound Queue...\n", c->name);
+ m=i2o_wait_message(c, "OutboundInit");
+ if(m==0xFFFFFFFF)
+ return -ETIMEDOUT;
+ msg=(u32 *)(c->mem_offset+m);
+
+ status = kmalloc(4,GFP_KERNEL);
+ if (status==NULL) {
+ printk(KERN_ERR "%s: Outbound Queue initialization failed - no free memory.\n",
+ c->name);
+ return -ENOMEM;
+ }
+ memset(status, 0, 4);
+
+ msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6;
+ msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2]= core_context;
+ msg[3]= 0x0106; /* Transaction context */
+ msg[4]= 4096; /* Host page frame size */
+ /* Frame size is in words. Pick 128, its what everyone elses uses and
+ other sizes break some adapters. */
+ msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */
+ msg[6]= 0xD0000004; /* Simple SG LE, EOB */
+ msg[7]= virt_to_bus(status);
+
+ i2o_post_message(c,m);
+
+ barrier();
+ time=jiffies;
+ while(status[0] < I2O_CMD_REJECTED)
+ {
+ if((jiffies-time)>=30*HZ)
+ {
+ if(status[0]==0x00)
+ printk(KERN_ERR "%s: Ignored queue initialize request.\n",
+ c->name);
+ else
+ printk(KERN_ERR "%s: Outbound queue initialize timeout.\n",
+ c->name);
+ kfree(status);
+ return -ETIMEDOUT;
+ }
+ schedule();
+ barrier();
+ }
+
+ if(status[0] != I2O_CMD_COMPLETED)
+ {
+ printk(KERN_ERR "%s: IOP outbound initialise failed.\n", c->name);
+ kfree(status);


+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+

+/**
+ * i2o_post_outbound_messages - fill message queue


+ * @c: controller
+ *

+ * Allocate a message frame and load the messages into the IOP. The
+ * function returns zero on success or a negative errno code on
+ * failure.
+ */
+
+int i2o_post_outbound_messages(struct i2o_controller *c)
+{
+ int i;
+ u32 m;
+ /* Alloc space for IOP's outbound queue message frames */
+
+ c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL);
+ if(c->page_frame==NULL) {
+ printk(KERN_ERR "%s: Outbound Q initialize failed; out of memory.\n",
+ c->name);


+ return -ENOMEM;
+ }
+

+ c->page_frame_map = pci_map_single(c->pdev, c->page_frame, MSG_POOL_SIZE, PCI_DMA_FROMDEVICE);
+
+ if(c->page_frame_map == 0)
+ {
+ kfree(c->page_frame);
+ printk(KERN_ERR "%s: Unable to map outbound queue.\n", c->name);


+ return -ENOMEM;
+ }
+

+ m = c->page_frame_map;
+
+ /* Post frames */
+
+ for(i=0; i< NMBR_MSG_FRAMES; i++) {
+ I2O_REPLY_WRITE32(c,m);
+ mb();
+ m += MSG_FRAME_SIZE;


+ }
+
+ return 0;
+}
+
+/*

+ * Get the IOP's Logical Configuration Table
+ */
+int i2o_lct_get(struct i2o_controller *c)
+{
+ u32 msg[8];
+ int ret, size = c->status_block->expected_lct_size;
+
+ do {
+ if (c->lct == NULL) {
+ c->lct = kmalloc(size, GFP_KERNEL);
+ if(c->lct == NULL) {
+ printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
+ c->name);


+ return -ENOMEM;
+ }
+ }

+ memset(c->lct, 0, size);
+
+ msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+ msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+ /* msg[2] filled in i2o_post_wait */


+ msg[3] = 0;

+ msg[4] = 0xFFFFFFFF; /* All devices */
+ msg[5] = 0x00000000; /* Report now */
+ msg[6] = 0xD0000000|size;
+ msg[7] = virt_to_bus(c->lct);
+
+ ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL);
+
+ if(ret == -ETIMEDOUT)
+ {


+ c->lct = NULL;

+ return ret;
+ }
+

+ if(ret<0)
+ {
+ printk(KERN_ERR "%s: LCT Get failed (status=%#x.\n",
+ c->name, -ret);

+ return ret;
+ }
+

+ if (c->lct->table_size << 2 > size) {
+ size = c->lct->table_size << 2;
+ kfree(c->lct);


+ c->lct = NULL;
+ }

+ } while (c->lct == NULL);
+
+ if ((ret=i2o_parse_lct(c)) < 0)
+ return ret;
+


+ return 0;
+}
+
+/*

+ * Like above, but used for async notification. The main
+ * difference is that we keep track of the CurrentChangeIndiicator
+ * so that we only get updates when it actually changes.
+ *
+ */
+int i2o_lct_notify(struct i2o_controller *c)
+{
+ u32 msg[8];
+
+ msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+ msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2] = core_context;
+ msg[3] = 0xDEADBEEF;
+ msg[4] = 0xFFFFFFFF; /* All devices */
+ msg[5] = c->dlct->change_ind+1; /* Next change */
+ msg[6] = 0xD0000000|8192;
+ msg[7] = virt_to_bus(c->dlct);


+
+ return i2o_post_this(c, msg, sizeof(msg));
+}
+
+/*

+ * Bring a controller online into OPERATIONAL state.
+ */
+
+int i2o_online_controller(struct i2o_controller *iop)
+{
+ u32 v;
+
+ if (i2o_systab_send(iop) < 0)
+ return -1;
+
+ /* In READY state */
+
+ dprintk(KERN_INFO "%s: Attempting to enable...\n", iop->name);
+ if (i2o_enable_controller(iop) < 0)
+ return -1;
+
+ /* In OPERATIONAL state */
+
+ dprintk(KERN_INFO "%s: Attempting to get/parse lct...\n", iop->name);
+ if (i2o_lct_get(iop) < 0)
+ return -1;
+
+ /* Check battery status */
+
+ iop->battery = 0;
+ if(i2o_query_scalar(iop, ADAPTER_TID, 0x0000, 4, &v, 4)>=0)
+ {
+ if(v&16)
+ iop->battery = 1;


+ }
+
+ return 0;
+}
+
+/*

+ * Build system table
+ *
+ * The system table contains information about all the IOPs in the
+ * system (duh) and is used by the Executives on the IOPs to establish
+ * peer2peer connections. We're not supporting peer2peer at the moment,
+ * but this will be needed down the road for things like lan2lan forwarding.
+ */
+static int i2o_build_sys_table(void)
+{
+ struct i2o_controller *iop = NULL;
+ struct i2o_controller *niop = NULL;
+ int count = 0;
+
+ sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
+ (i2o_num_controllers) *
+ sizeof(struct i2o_sys_tbl_entry);
+
+ if(sys_tbl)
+ kfree(sys_tbl);
+
+ sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL);
+ if(!sys_tbl) {
+ printk(KERN_CRIT "SysTab Set failed. Out of memory.\n");
+ return -ENOMEM;
+ }
+ memset((void*)sys_tbl, 0, sys_tbl_len);
+
+ sys_tbl->num_entries = i2o_num_controllers;
+ sys_tbl->version = I2OVERSION; /* TODO: Version 2.0 */
+ sys_tbl->change_ind = sys_tbl_ind++;
+
+ for(iop = i2o_controller_chain; iop; iop = niop)
+ {
+ niop = iop->next;
+
+ /*
+ * Get updated IOP state so we have the latest information
+ *
+ * We should delete the controller at this point if it
+ * doesn't respond since if it's not on the system table
+ * it is techninically not part of the I2O subsyßtem...
+ */
+ if(i2o_status_get(iop)) {
+ printk(KERN_ERR "%s: Deleting b/c could not get status while"
+ "attempting to build system table\n", iop->name);
+ i2o_delete_controller(iop);
+ sys_tbl->num_entries--;
+ continue; // try the next one
+ }
+
+ sys_tbl->iops[count].org_id = iop->status_block->org_id;
+ sys_tbl->iops[count].iop_id = iop->unit + 2;
+ sys_tbl->iops[count].seg_num = 0;
+ sys_tbl->iops[count].i2o_version =
+ iop->status_block->i2o_version;
+ sys_tbl->iops[count].iop_state =
+ iop->status_block->iop_state;
+ sys_tbl->iops[count].msg_type =
+ iop->status_block->msg_type;
+ sys_tbl->iops[count].frame_size =
+ iop->status_block->inbound_frame_size;
+ sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
+ sys_tbl->iops[count].iop_capabilities =
+ iop->status_block->iop_capabilities;
+ sys_tbl->iops[count].inbound_low =
+ (u32)virt_to_bus(iop->post_port);
+ sys_tbl->iops[count].inbound_high = 0; // TODO: 64-bit support
+
+ count++;
+ }
+
+#ifdef DRIVERDEBUG
+{
+ u32 *table;
+ table = (u32*)sys_tbl;
+ for(count = 0; count < (sys_tbl_len >>2); count++)
+ printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", count, table[count]);
+}
+#endif


+
+ return 0;
+}
+
+

+/*
+ * Run time support routines
+ */
+
+/*
+ * Generic "post and forget" helpers. This is less efficient - we do
+ * a memcpy for example that isnt strictly needed, but for most uses
+ * this is simply not worth optimising
+ */
+
+int i2o_post_this(struct i2o_controller *c, u32 *data, int len)
+{
+ u32 m;
+ u32 *msg;
+ unsigned long t=jiffies;
+
+ do
+ {
+ mb();
+ m = I2O_POST_READ32(c);
+ }
+ while(m==0xFFFFFFFF && (jiffies-t)<HZ);
+
+ if(m==0xFFFFFFFF)
+ {
+ printk(KERN_ERR "%s: Timeout waiting for message frame!\n",
+ c->name);
+ return -ETIMEDOUT;
+ }
+ msg = (u32 *)(c->mem_offset + m);
+ memcpy_toio(msg, data, len);
+ i2o_post_message(c,m);


+ return 0;
+}
+
+/**

+ * i2o_post_wait_mem - I2O query/reply with DMA buffers
+ * @c: controller
+ * @msg: message to send
+ * @len: length of message
+ * @timeout: time in seconds to wait
+ * @mem1: attached memory buffer 1
+ * @mem2: attached memory buffer 2
+ *
+ * This core API allows an OSM to post a message and then be told whether
+ * or not the system received a successful reply.
+ *
+ * If the message times out then the value '-ETIMEDOUT' is returned. This
+ * is a special case. In this situation the message may (should) complete
+ * at an indefinite time in the future. When it completes it will use the
+ * memory buffers attached to the request. If -ETIMEDOUT is returned then
+ * the memory buffers must not be freed. Instead the event completion will
+ * free them for you. In all other cases the buffers are your problem.
+ *
+ * Pass NULL for unneeded buffers.
+ */
+
+int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2)
+{
+ DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post);
+ int complete = 0;
+ int status;
+ unsigned long flags = 0;
+ struct i2o_post_wait_data *wait_data =
+ kmalloc(sizeof(struct i2o_post_wait_data), GFP_KERNEL);
+
+ if(!wait_data)
+ return -ENOMEM;
+
+ /*
+ * Create a new notification object
+ */
+ wait_data->status = &status;
+ wait_data->complete = &complete;
+ wait_data->mem[0] = mem1;
+ wait_data->mem[1] = mem2;
+ /*
+ * Queue the event with its unique id
+ */
+ spin_lock_irqsave(&post_wait_lock, flags);
+
+ wait_data->next = post_wait_queue;
+ post_wait_queue = wait_data;
+ wait_data->id = (++post_wait_id) & 0x7fff;
+ wait_data->wq = &wq_i2o_post;
+
+ spin_unlock_irqrestore(&post_wait_lock, flags);
+
+ /*
+ * Fill in the message id
+ */
+
+ msg[2] = 0x80000000|(u32)core_context|((u32)wait_data->id<<16);
+
+ /*
+ * Post the message to the controller. At some point later it
+ * will return. If we time out before it returns then
+ * complete will be zero. From the point post_this returns
+ * the wait_data may have been deleted.
+ */
+ if ((status = i2o_post_this(c, msg, len))==0) {
+ sleep_on_timeout(&wq_i2o_post, HZ * timeout);
+ }
+ else
+ return -EIO;
+
+ if(signal_pending(current))
+ status = -EINTR;
+
+ spin_lock_irqsave(&post_wait_lock, flags);
+ barrier(); /* Be sure we see complete as it is locked */
+ if(!complete)
+ {
+ /*
+ * Mark the entry dead. We cannot remove it. This is important.
+ * When it does terminate (which it must do if the controller hasnt
+ * died..) then it will otherwise scribble on stuff.
+ * !complete lets us safely check if the entry is still
+ * allocated and thus we can write into it
+ */
+ wait_data->wq = NULL;
+ status = -ETIMEDOUT;
+ }
+ else
+ {
+ /* Debugging check - remove me soon */
+ if(status == -ETIMEDOUT)
+ {
+ printk("TIMEDOUT BUG!\n");
+ status = -EIO;
+ }
+ }
+ /* And the wait_data is not leaked either! */
+ spin_unlock_irqrestore(&post_wait_lock, flags);


+ return status;
+}
+

+/**
+ * i2o_post_wait - I2O query/reply
+ * @c: controller
+ * @msg: message to send
+ * @len: length of message
+ * @timeout: time in seconds to wait
+ *
+ * This core API allows an OSM to post a message and then be told whether
+ * or not the system received a successful reply.
+ */
+
+int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout)
+{
+ return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL);
+}
+
+/*
+ * i2o_post_wait is completed and we want to wake up the
+ * sleeping proccess. Called by core's reply handler.
+ */
+
+static void i2o_post_wait_complete(u32 context, int status)
+{
+ struct i2o_post_wait_data **p1, *q;


+ unsigned long flags;
+

+ /*
+ * We need to search through the post_wait
+ * queue to see if the given message is still
+ * outstanding. If not, it means that the IOP
+ * took longer to respond to the message than we
+ * had allowed and timer has already expired.
+ * Not much we can do about that except log
+ * it for debug purposes, increase timeout, and recompile
+ *
+ * Lock needed to keep anyone from moving queue pointers
+ * around while we're looking through them.
+ */
+
+ spin_lock_irqsave(&post_wait_lock, flags);
+
+ for(p1 = &post_wait_queue; *p1!=NULL; p1 = &((*p1)->next))
+ {
+ q = (*p1);
+ if(q->id == ((context >> 16) & 0x7fff)) {
+ /*
+ * Delete it
+ */
+
+ *p1 = q->next;
+
+ /*
+ * Live or dead ?
+ */
+
+ if(q->wq)
+ {
+ /* Live entry - wakeup and set status */
+ *q->status = status;
+ *q->complete = 1;
+ wake_up(q->wq);
+ }
+ else
+ {
+ /*
+ * Free resources. Caller is dead
+ */
+ if(q->mem[0])
+ kfree(q->mem[0]);
+ if(q->mem[1])
+ kfree(q->mem[1]);
+ printk(KERN_WARNING "i2o_post_wait event completed after timeout.\n");
+ }
+ kfree(q);
+ spin_unlock(&post_wait_lock);
+ return;
+ }
+ }
+ spin_unlock(&post_wait_lock);
+
+ printk(KERN_DEBUG "i2o_post_wait: Bogus reply!\n");
+}
+
+/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
+ *
+ * This function can be used for all UtilParamsGet/Set operations.
+ * The OperationList is given in oplist-buffer,
+ * and results are returned in reslist-buffer.
+ * Note that the minimum sized reslist is 8 bytes and contains
+ * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
+ */
+int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid,
+ void *oplist, int oplen, void *reslist, int reslen)
+{
+ u32 msg[9];
+ u32 *res32 = (u32*)reslist;
+ u32 *restmp = (u32*)reslist;
+ int len = 0;


+ int i = 0;

+ int wait_status;
+ u32 *opmem, *resmem;
+
+ /* Get DMAable memory */
+ opmem = kmalloc(oplen, GFP_KERNEL);
+ if(opmem == NULL)
+ return -ENOMEM;
+ memcpy(opmem, oplist, oplen);
+
+ resmem = kmalloc(reslen, GFP_KERNEL);
+ if(resmem == NULL)
+ {
+ kfree(opmem);


+ return -ENOMEM;
+ }
+

+ msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;


+ msg[1] = cmd << 24 | HOST_TID << 12 | tid;
+ msg[3] = 0;

+ msg[4] = 0;
+ msg[5] = 0x54000000 | oplen; /* OperationList */
+ msg[6] = virt_to_bus(opmem);
+ msg[7] = 0xD0000000 | reslen; /* ResultList */
+ msg[8] = virt_to_bus(resmem);
+
+ wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem);
+
+ /*
+ * This only looks like a memory leak - don't "fix" it.
+ */
+ if(wait_status == -ETIMEDOUT)
+ return wait_status;
+
+ /* Query failed */
+ if(wait_status != 0)
+ {
+ kfree(resmem);
+ kfree(opmem);
+ return wait_status;
+ }
+
+ memcpy(reslist, resmem, reslen);
+ /*
+ * Calculate number of bytes of Result LIST
+ * We need to loop through each Result BLOCK and grab the length
+ */
+ restmp = res32 + 1;
+ len = 1;
+ for(i = 0; i < (res32[0]&0X0000FFFF); i++)
+ {
+ if(restmp[0]&0x00FF0000) /* BlockStatus != SUCCESS */
+ {
+ printk(KERN_WARNING "%s - Error:\n ErrorInfoSize = 0x%02x, "
+ "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
+ (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
+ : "PARAMS_GET",
+ res32[1]>>24, (res32[1]>>16)&0xFF, res32[1]&0xFFFF);
+
+ /*
+ * If this is the only request,than we return an error
+ */
+ if((res32[0]&0x0000FFFF) == 1)
+ {
+ return -((res32[1] >> 16) & 0xFF); /* -BlockStatus */
+ }
+ }
+ len += restmp[0] & 0x0000FFFF; /* Length of res BLOCK */
+ restmp += restmp[0] & 0x0000FFFF; /* Skip to next BLOCK */
+ }
+ return (len << 2); /* bytes used by result list */
+}
+
+/*
+ * Query one scalar group value or a whole scalar group.
+ */
+int i2o_query_scalar(struct i2o_controller *iop, int tid,
+ int group, int field, void *buf, int buflen)
+{
+ u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+ u8 resblk[8+buflen]; /* 8 bytes for header */
+ int size;
+
+ if (field == -1) /* whole group */
+ opblk[4] = -1;
+
+ size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid,
+ opblk, sizeof(opblk), resblk, sizeof(resblk));
+
+ memcpy(buf, resblk+8, buflen); /* cut off header */
+
+ if(size>buflen)
+ return buflen;
+ return size;
+}
+
+/*
+ * Set a scalar group value or a whole group.
+ */
+int i2o_set_scalar(struct i2o_controller *iop, int tid,
+ int group, int field, void *buf, int buflen)
+{
+ u16 *opblk;
+ u8 resblk[8+buflen]; /* 8 bytes for header */
+ int size;
+
+ opblk = kmalloc(buflen+64, GFP_KERNEL);
+ if (opblk == NULL)
+ {
+ printk(KERN_ERR "i2o: no memory for operation buffer.\n");
+ return -ENOMEM;
+ }
+
+ opblk[0] = 1; /* operation count */
+ opblk[1] = 0; /* pad */
+ opblk[2] = I2O_PARAMS_FIELD_SET;
+ opblk[3] = group;
+
+ if(field == -1) { /* whole group */
+ opblk[4] = -1;
+ memcpy(opblk+5, buf, buflen);
+ }
+ else /* single field */
+ {
+ opblk[4] = 1;
+ opblk[5] = field;
+ memcpy(opblk+6, buf, buflen);
+ }
+
+ size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
+ opblk, 12+buflen, resblk, sizeof(resblk));
+
+ kfree(opblk);
+ if(size>buflen)
+ return buflen;
+ return size;
+}
+
+/*
+ * if oper == I2O_PARAMS_TABLE_GET, get from all rows
+ * if fieldcount == -1 return all fields
+ * ibuf and ibuflen are unused (use NULL, 0)
+ * else return specific fields
+ * ibuf contains fieldindexes
+ *
+ * if oper == I2O_PARAMS_LIST_GET, get from specific rows
+ * if fieldcount == -1 return all fields
+ * ibuf contains rowcount, keyvalues
+ * else return specific fields
+ * fieldcount is # of fieldindexes
+ * ibuf contains fieldindexes, rowcount, keyvalues
+ *
+ * You could also use directly function i2o_issue_params().
+ */
+int i2o_query_table(int oper, struct i2o_controller *iop, int tid, int group,
+ int fieldcount, void *ibuf, int ibuflen,
+ void *resblk, int reslen)
+{
+ u16 *opblk;
+ int size;
+
+ opblk = kmalloc(10 + ibuflen, GFP_KERNEL);
+ if (opblk == NULL)
+ {
+ printk(KERN_ERR "i2o: no memory for query buffer.\n");
+ return -ENOMEM;
+ }
+
+ opblk[0] = 1; /* operation count */
+ opblk[1] = 0; /* pad */
+ opblk[2] = oper;
+ opblk[3] = group;
+ opblk[4] = fieldcount;
+ memcpy(opblk+5, ibuf, ibuflen); /* other params */
+
+ size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid,
+ opblk, 10+ibuflen, resblk, reslen);
+
+ kfree(opblk);
+ if(size>reslen)
+ return reslen;
+ return size;
+}
+
+/*
+ * Clear table group, i.e. delete all rows.
+ */
+int i2o_clear_table(struct i2o_controller *iop, int tid, int group)
+{
+ u16 opblk[] = { 1, 0, I2O_PARAMS_TABLE_CLEAR, group };
+ u8 resblk[32]; /* min 8 bytes for result header */
+
+ return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
+ opblk, sizeof(opblk), resblk, sizeof(resblk));
+}
+
+/*
+ * Add a new row into a table group.
+ *
+ * if fieldcount==-1 then we add whole rows
+ * buf contains rowcount, keyvalues
+ * else just specific fields are given, rest use defaults
+ * buf contains fieldindexes, rowcount, keyvalues
+ */
+int i2o_row_add_table(struct i2o_controller *iop, int tid,
+ int group, int fieldcount, void *buf, int buflen)
+{
+ u16 *opblk;
+ u8 resblk[32]; /* min 8 bytes for header */
+ int size;
+
+ opblk = kmalloc(buflen+64, GFP_KERNEL);
+ if (opblk == NULL)
+ {
+ printk(KERN_ERR "i2o: no memory for operation buffer.\n");
+ return -ENOMEM;
+ }
+
+ opblk[0] = 1; /* operation count */
+ opblk[1] = 0; /* pad */
+ opblk[2] = I2O_PARAMS_ROW_ADD;
+ opblk[3] = group;
+ opblk[4] = fieldcount;
+ memcpy(opblk+5, buf, buflen);
+
+ size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid,
+ opblk, 10+buflen, resblk, sizeof(resblk));
+
+ kfree(opblk);
+ if(size>buflen)
+ return buflen;
+ return size;
+}
+
+
+/*
+ * Used for error reporting/debugging purposes.
+ * Following fail status are common to all classes.
+ * The preserved message must be handled in the reply handler.
+ */
+void i2o_report_fail_status(u8 req_status, u32* msg)
+{
+ static char *FAIL_STATUS[] = {
+ "0x80", /* not used */
+ "SERVICE_SUSPENDED", /* 0x81 */
+ "SERVICE_TERMINATED", /* 0x82 */
+ "CONGESTION",
+ "FAILURE",
+ "STATE_ERROR",
+ "TIME_OUT",
+ "ROUTING_FAILURE",
+ "INVALID_VERSION",
+ "INVALID_OFFSET",
+ "INVALID_MSG_FLAGS",
+ "FRAME_TOO_SMALL",
+ "FRAME_TOO_LARGE",
+ "INVALID_TARGET_ID",
+ "INVALID_INITIATOR_ID",
+ "INVALID_INITIATOR_CONTEX", /* 0x8F */
+ "UNKNOWN_FAILURE" /* 0xFF */
+ };
+
+ if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
+ printk("TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.", req_status);
+ else
+ printk("TRANSPORT_%s.\n", FAIL_STATUS[req_status & 0x0F]);
+
+ /* Dump some details */
+
+ printk(KERN_ERR " InitiatorId = %d, TargetId = %d\n",
+ (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF);
+ printk(KERN_ERR " LowestVersion = 0x%02X, HighestVersion = 0x%02X\n",
+ (msg[4] >> 8) & 0xFF, msg[4] & 0xFF);
+ printk(KERN_ERR " FailingHostUnit = 0x%04X, FailingIOP = 0x%03X\n",
+ msg[5] >> 16, msg[5] & 0xFFF);
+
+ printk(KERN_ERR " Severity: 0x%02X ", (msg[4] >> 16) & 0xFF);
+ if (msg[4] & (1<<16))
+ printk("(FormatError), "
+ "this msg can never be delivered/processed.\n");
+ if (msg[4] & (1<<17))
+ printk("(PathError), "
+ "this msg can no longer be delivered/processed.\n");
+ if (msg[4] & (1<<18))
+ printk("(PathState), "
+ "the system state does not allow delivery.\n");
+ if (msg[4] & (1<<19))
+ printk("(Congestion), resources temporarily not available;"
+ "do not retry immediately.\n");
+}
+
+/*
+ * Used for error reporting/debugging purposes.
+ * Following reply status are common to all classes.
+ */
+void i2o_report_common_status(u8 req_status)
+{
+ static char *REPLY_STATUS[] = {
+ "SUCCESS",
+ "ABORT_DIRTY",
+ "ABORT_NO_DATA_TRANSFER",
+ "ABORT_PARTIAL_TRANSFER",
+ "ERROR_DIRTY",
+ "ERROR_NO_DATA_TRANSFER",
+ "ERROR_PARTIAL_TRANSFER",
+ "PROCESS_ABORT_DIRTY",
+ "PROCESS_ABORT_NO_DATA_TRANSFER",
+ "PROCESS_ABORT_PARTIAL_TRANSFER",
+ "TRANSACTION_ERROR",
+ "PROGRESS_REPORT"
+ };
+
+ if (req_status > I2O_REPLY_STATUS_PROGRESS_REPORT)
+ printk("RequestStatus = %0#2x", req_status);
+ else
+ printk("%s", REPLY_STATUS[req_status]);
+}
+
+/*
+ * Used for error reporting/debugging purposes.
+ * Following detailed status are valid for executive class,
+ * utility class, DDM class and for transaction error replies.
+ */
+static void i2o_report_common_dsc(u16 detailed_status)
+{
+ static char *COMMON_DSC[] = {
+ "SUCCESS",
+ "0x01", // not used
+ "BAD_KEY",
+ "TCL_ERROR",
+ "REPLY_BUFFER_FULL",
+ "NO_SUCH_PAGE",
+ "INSUFFICIENT_RESOURCE_SOFT",
+ "INSUFFICIENT_RESOURCE_HARD",
+ "0x08", // not used
+ "CHAIN_BUFFER_TOO_LARGE",
+ "UNSUPPORTED_FUNCTION",
+ "DEVICE_LOCKED",
+ "DEVICE_RESET",
+ "INAPPROPRIATE_FUNCTION",
+ "INVALID_INITIATOR_ADDRESS",
+ "INVALID_MESSAGE_FLAGS",
+ "INVALID_OFFSET",
+ "INVALID_PARAMETER",
+ "INVALID_REQUEST",
+ "INVALID_TARGET_ADDRESS",
+ "MESSAGE_TOO_LARGE",
+ "MESSAGE_TOO_SMALL",
+ "MISSING_PARAMETER",
+ "TIMEOUT",
+ "UNKNOWN_ERROR",
+ "UNKNOWN_FUNCTION",
+ "UNSUPPORTED_VERSION",
+ "DEVICE_BUSY",
+ "DEVICE_NOT_AVAILABLE"
+ };
+
+ if (detailed_status > I2O_DSC_DEVICE_NOT_AVAILABLE)
+ printk(" / DetailedStatus = %0#4x.\n", detailed_status);
+ else
+ printk(" / %s.\n", COMMON_DSC[detailed_status]);
+}
+
+/*
+ * Used for error reporting/debugging purposes
+ */
+static void i2o_report_lan_dsc(u16 detailed_status)
+{
+ static char *LAN_DSC[] = { // Lan detailed status code strings
+ "SUCCESS",
+ "DEVICE_FAILURE",
+ "DESTINATION_NOT_FOUND",
+ "TRANSMIT_ERROR",
+ "TRANSMIT_ABORTED",
+ "RECEIVE_ERROR",
+ "RECEIVE_ABORTED",
+ "DMA_ERROR",
+ "BAD_PACKET_DETECTED",
+ "OUT_OF_MEMORY",
+ "BUCKET_OVERRUN",
+ "IOP_INTERNAL_ERROR",
+ "CANCELED",
+ "INVALID_TRANSACTION_CONTEXT",
+ "DEST_ADDRESS_DETECTED",
+ "DEST_ADDRESS_OMITTED",
+ "PARTIAL_PACKET_RETURNED",
+ "TEMP_SUSPENDED_STATE", // last Lan detailed status code
+ "INVALID_REQUEST" // general detailed status code
+ };
+
+ if (detailed_status > I2O_DSC_INVALID_REQUEST)
+ printk(" / %0#4x.\n", detailed_status);
+ else
+ printk(" / %s.\n", LAN_DSC[detailed_status]);
+}
+
+/*
+ * Used for error reporting/debugging purposes
+ */
+static void i2o_report_util_cmd(u8 cmd)
+{
+ switch (cmd) {
+ case I2O_CMD_UTIL_NOP:
+ printk("UTIL_NOP, ");
+ break;
+ case I2O_CMD_UTIL_ABORT:
+ printk("UTIL_ABORT, ");
+ break;
+ case I2O_CMD_UTIL_CLAIM:
+ printk("UTIL_CLAIM, ");
+ break;
+ case I2O_CMD_UTIL_RELEASE:
+ printk("UTIL_CLAIM_RELEASE, ");
+ break;
+ case I2O_CMD_UTIL_CONFIG_DIALOG:
+ printk("UTIL_CONFIG_DIALOG, ");
+ break;
+ case I2O_CMD_UTIL_DEVICE_RESERVE:
+ printk("UTIL_DEVICE_RESERVE, ");
+ break;
+ case I2O_CMD_UTIL_DEVICE_RELEASE:
+ printk("UTIL_DEVICE_RELEASE, ");
+ break;
+ case I2O_CMD_UTIL_EVT_ACK:
+ printk("UTIL_EVENT_ACKNOWLEDGE, ");
+ break;
+ case I2O_CMD_UTIL_EVT_REGISTER:
+ printk("UTIL_EVENT_REGISTER, ");
+ break;
+ case I2O_CMD_UTIL_LOCK:
+ printk("UTIL_LOCK, ");
+ break;
+ case I2O_CMD_UTIL_LOCK_RELEASE:
+ printk("UTIL_LOCK_RELEASE, ");
+ break;
+ case I2O_CMD_UTIL_PARAMS_GET:
+ printk("UTIL_PARAMS_GET, ");
+ break;
+ case I2O_CMD_UTIL_PARAMS_SET:
+ printk("UTIL_PARAMS_SET, ");
+ break;
+ case I2O_CMD_UTIL_REPLY_FAULT_NOTIFY:
+ printk("UTIL_REPLY_FAULT_NOTIFY, ");
+ break;
+ default:
+ printk("Cmd = %0#2x, ",cmd);
+ }
+}
+
+/*
+ * Used for error reporting/debugging purposes
+ */
+static void i2o_report_exec_cmd(u8 cmd)
+{
+ switch (cmd) {
+ case I2O_CMD_ADAPTER_ASSIGN:
+ printk("EXEC_ADAPTER_ASSIGN, ");
+ break;
+ case I2O_CMD_ADAPTER_READ:
+ printk("EXEC_ADAPTER_READ, ");
+ break;
+ case I2O_CMD_ADAPTER_RELEASE:
+ printk("EXEC_ADAPTER_RELEASE, ");
+ break;
+ case I2O_CMD_BIOS_INFO_SET:
+ printk("EXEC_BIOS_INFO_SET, ");
+ break;
+ case I2O_CMD_BOOT_DEVICE_SET:
+ printk("EXEC_BOOT_DEVICE_SET, ");
+ break;
+ case I2O_CMD_CONFIG_VALIDATE:
+ printk("EXEC_CONFIG_VALIDATE, ");
+ break;
+ case I2O_CMD_CONN_SETUP:
+ printk("EXEC_CONN_SETUP, ");
+ break;
+ case I2O_CMD_DDM_DESTROY:
+ printk("EXEC_DDM_DESTROY, ");
+ break;
+ case I2O_CMD_DDM_ENABLE:
+ printk("EXEC_DDM_ENABLE, ");
+ break;
+ case I2O_CMD_DDM_QUIESCE:
+ printk("EXEC_DDM_QUIESCE, ");
+ break;
+ case I2O_CMD_DDM_RESET:
+ printk("EXEC_DDM_RESET, ");
+ break;
+ case I2O_CMD_DDM_SUSPEND:
+ printk("EXEC_DDM_SUSPEND, ");
+ break;
+ case I2O_CMD_DEVICE_ASSIGN:
+ printk("EXEC_DEVICE_ASSIGN, ");
+ break;
+ case I2O_CMD_DEVICE_RELEASE:
+ printk("EXEC_DEVICE_RELEASE, ");
+ break;
+ case I2O_CMD_HRT_GET:
+ printk("EXEC_HRT_GET, ");
+ break;
+ case I2O_CMD_ADAPTER_CLEAR:
+ printk("EXEC_IOP_CLEAR, ");
+ break;
+ case I2O_CMD_ADAPTER_CONNECT:
+ printk("EXEC_IOP_CONNECT, ");
+ break;
+ case I2O_CMD_ADAPTER_RESET:
+ printk("EXEC_IOP_RESET, ");
+ break;
+ case I2O_CMD_LCT_NOTIFY:
+ printk("EXEC_LCT_NOTIFY, ");
+ break;
+ case I2O_CMD_OUTBOUND_INIT:
+ printk("EXEC_OUTBOUND_INIT, ");
+ break;
+ case I2O_CMD_PATH_ENABLE:
+ printk("EXEC_PATH_ENABLE, ");
+ break;
+ case I2O_CMD_PATH_QUIESCE:
+ printk("EXEC_PATH_QUIESCE, ");
+ break;
+ case I2O_CMD_PATH_RESET:
+ printk("EXEC_PATH_RESET, ");
+ break;
+ case I2O_CMD_STATIC_MF_CREATE:
+ printk("EXEC_STATIC_MF_CREATE, ");
+ break;
+ case I2O_CMD_STATIC_MF_RELEASE:
+ printk("EXEC_STATIC_MF_RELEASE, ");
+ break;
+ case I2O_CMD_STATUS_GET:
+ printk("EXEC_STATUS_GET, ");
+ break;
+ case I2O_CMD_SW_DOWNLOAD:
+ printk("EXEC_SW_DOWNLOAD, ");
+ break;
+ case I2O_CMD_SW_UPLOAD:
+ printk("EXEC_SW_UPLOAD, ");
+ break;
+ case I2O_CMD_SW_REMOVE:
+ printk("EXEC_SW_REMOVE, ");
+ break;
+ case I2O_CMD_SYS_ENABLE:
+ printk("EXEC_SYS_ENABLE, ");
+ break;
+ case I2O_CMD_SYS_MODIFY:
+ printk("EXEC_SYS_MODIFY, ");
+ break;
+ case I2O_CMD_SYS_QUIESCE:
+ printk("EXEC_SYS_QUIESCE, ");
+ break;
+ case I2O_CMD_SYS_TAB_SET:
+ printk("EXEC_SYS_TAB_SET, ");
+ break;
+ default:
+ printk("Cmd = %#02x, ",cmd);
+ }
+}
+
+/*
+ * Used for error reporting/debugging purposes
+ */
+static void i2o_report_lan_cmd(u8 cmd)
+{
+ switch (cmd) {
+ case LAN_PACKET_SEND:
+ printk("LAN_PACKET_SEND, ");
+ break;
+ case LAN_SDU_SEND:
+ printk("LAN_SDU_SEND, ");
+ break;
+ case LAN_RECEIVE_POST:
+ printk("LAN_RECEIVE_POST, ");
+ break;
+ case LAN_RESET:
+ printk("LAN_RESET, ");
+ break;
+ case LAN_SUSPEND:
+ printk("LAN_SUSPEND, ");
+ break;
+ default:
+ printk("Cmd = %0#2x, ",cmd);
+ }
+}
+
+/*
+ * Used for error reporting/debugging purposes.
+ * Report Cmd name, Request status, Detailed Status.
+ */
+void i2o_report_status(const char *severity, const char *str, u32 *msg)
+{
+ u8 cmd = (msg[1]>>24)&0xFF;
+ u8 req_status = (msg[4]>>24)&0xFF;
+ u16 detailed_status = msg[4]&0xFFFF;
+ struct i2o_handler *h = i2o_handlers[msg[2] & (MAX_I2O_MODULES-1)];
+
+ printk("%s%s: ", severity, str);
+
+ if (cmd < 0x1F) // Utility cmd
+ i2o_report_util_cmd(cmd);
+
+ else if (cmd >= 0xA0 && cmd <= 0xEF) // Executive cmd
+ i2o_report_exec_cmd(cmd);
+
+ else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F)
+ i2o_report_lan_cmd(cmd); // LAN cmd
+ else
+ printk("Cmd = %0#2x, ", cmd); // Other cmds


+
+ if (msg[0] & MSG_FAIL) {

+ i2o_report_fail_status(req_status, msg);
+ return;
+ }
+
+ i2o_report_common_status(req_status);
+
+ if (cmd < 0x1F || (cmd >= 0xA0 && cmd <= 0xEF))
+ i2o_report_common_dsc(detailed_status);
+ else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F)
+ i2o_report_lan_dsc(detailed_status);
+ else
+ printk(" / DetailedStatus = %0#4x.\n", detailed_status);
+}
+
+/* Used to dump a message to syslog during debugging */
+void i2o_dump_message(u32 *msg)
+{
+#ifdef DRIVERDEBUG
+ int i;
+ printk(KERN_INFO "Dumping I2O message size %d @ %p\n",
+ msg[0]>>16&0xffff, msg);
+ for(i = 0; i < ((msg[0]>>16)&0xffff); i++)
+ printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]);
+#endif
+}
+
+/*
+ * I2O reboot/shutdown notification.
+ *
+ * - Call each OSM's reboot notifier (if one exists)
+ * - Quiesce each IOP in the system
+ *
+ * Each IOP has to be quiesced before we can ensure that the system
+ * can be properly shutdown as a transaction that has already been
+ * acknowledged still needs to be placed in permanent store on the IOP.
+ * The SysQuiesce causes the IOP to force all HDMs to complete their
+ * transactions before returning, so only at that point is it safe
+ *
+ */
+static int i2o_reboot_event(struct notifier_block *n, unsigned long code, void
+*p)
+{


+ int i = 0;

+ struct i2o_controller *c = NULL;
+

+ if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
+ return NOTIFY_DONE;
+
+ printk(KERN_INFO "Shutting down I2O system.\n");
+ printk(KERN_INFO
+ " This could take a few minutes if there are many devices attached\n");


+
+ for(i = 0; i < MAX_I2O_MODULES; i++)
+ {

+ if(i2o_handlers[i] && i2o_handlers[i]->reboot_notify)
+ i2o_handlers[i]->reboot_notify();
+ }
+
+ for(c = i2o_controller_chain; c; c = c->next)
+ {
+ if(i2o_quiesce_controller(c))
+ {
+ printk(KERN_WARNING "i2o: Could not quiesce %s." "
+ Verify setup on next system power up.\n", c->name);
+ }
+ }
+
+ printk(KERN_INFO "I2O system down.\n");


+ return NOTIFY_DONE;
+}
+
+

+EXPORT_SYMBOL(i2o_controller_chain);
+EXPORT_SYMBOL(i2o_num_controllers);
+EXPORT_SYMBOL(i2o_find_controller);
+EXPORT_SYMBOL(i2o_unlock_controller);
+EXPORT_SYMBOL(i2o_status_get);
+
+EXPORT_SYMBOL(i2o_install_handler);
+EXPORT_SYMBOL(i2o_remove_handler);
+
+EXPORT_SYMBOL(i2o_claim_device);
+EXPORT_SYMBOL(i2o_release_device);
+EXPORT_SYMBOL(i2o_device_notify_on);
+EXPORT_SYMBOL(i2o_device_notify_off);
+
+EXPORT_SYMBOL(i2o_post_this);
+EXPORT_SYMBOL(i2o_post_wait);
+EXPORT_SYMBOL(i2o_post_wait_mem);
+
+EXPORT_SYMBOL(i2o_query_scalar);
+EXPORT_SYMBOL(i2o_set_scalar);
+EXPORT_SYMBOL(i2o_query_table);
+EXPORT_SYMBOL(i2o_clear_table);
+EXPORT_SYMBOL(i2o_row_add_table);
+EXPORT_SYMBOL(i2o_issue_params);
+
+EXPORT_SYMBOL(i2o_event_register);
+EXPORT_SYMBOL(i2o_event_ack);
+
+EXPORT_SYMBOL(i2o_report_status);
+EXPORT_SYMBOL(i2o_dump_message);
+
+EXPORT_SYMBOL(i2o_get_class_name);
+
+#ifdef MODULE
+


+MODULE_AUTHOR("Red Hat Software");

+MODULE_DESCRIPTION("I2O Core");


+MODULE_LICENSE("GPL");
+
+

+
+int init_module(void)
+{
+ printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
+ if (i2o_install_handler(&i2o_core_handler) < 0)
+ {
+ printk(KERN_ERR
+ "i2o_core: Unable to install core handler.\nI2O stack not loaded!");


+ return 0;
+ }
+

+ core_context = i2o_core_handler.context;
+
+ /*
+ * Attach core to I2O PCI transport (and others as they are developed)
+ */
+#ifdef CONFIG_I2O_PCI_MODULE
+ if(i2o_pci_core_attach(&i2o_core_functions) < 0)
+ printk(KERN_INFO "i2o: No PCI I2O controllers found\n");
+#endif
+
+ /*


+ * Initialize event handling thread
+ */

+ init_MUTEX_LOCKED(&evt_sem);
+ evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND);
+ if(evt_pid < 0)
+ {
+ printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
+ i2o_remove_handler(&i2o_core_handler);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 26'
echo 'File patch-2.4.13 is continued in part 27'
echo "27" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:57 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part27

#!/bin/sh -x
# this is part 27 of a 53 - part archive


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

if test "$Scheck" != 27; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ return 0;
+ }
+ else
+ printk(KERN_INFO "I2O: Event thread created as pid %d\n", evt_pid);
+
+ if(i2o_num_controllers)
+ i2o_sys_init();
+
+ register_reboot_notifier(&i2o_reboot_notifier);


+
+ return 0;
+}
+

+void cleanup_module(void)
+{
+ int stat;
+
+ unregister_reboot_notifier(&i2o_reboot_notifier);
+
+ if(i2o_num_controllers)
+ i2o_sys_shutdown();
+
+ /*
+ * If this is shutdown time, the thread has already been killed
+ */
+ if(evt_running) {
+ printk("Terminating i2o threads...");
+ stat = kill_proc(evt_pid, SIGTERM, 1);
+ if(!stat) {
+ printk("waiting...");
+ wait_for_completion(&evt_dead);
+ }


+ printk("done.\n");
+ }
+

+#ifdef CONFIG_I2O_PCI_MODULE
+ i2o_pci_core_detach();
+#endif
+
+ i2o_remove_handler(&i2o_core_handler);
+
+ unregister_reboot_notifier(&i2o_reboot_notifier);
+}
+
+#else
+
+extern int i2o_block_init(void);
+extern int i2o_config_init(void);
+extern int i2o_lan_init(void);
+extern int i2o_pci_init(void);
+extern int i2o_proc_init(void);
+extern int i2o_scsi_init(void);
+
+int __init i2o_init(void)
+{
+ printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n");


+
+ if (i2o_install_handler(&i2o_core_handler) < 0)
+ {
+ printk(KERN_ERR
+ "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
+ return 0;
+ }
+
+ core_context = i2o_core_handler.context;
+
+ /*

+ * Initialize event handling thread

+ * We may not find any controllers, but still want this as
+ * down the road we may have hot pluggable controllers that
+ * need to be dealt with.
+ */
+ init_MUTEX_LOCKED(&evt_sem);
+ if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0)


+ {
+ printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
+ i2o_remove_handler(&i2o_core_handler);

+ return 0;
+ }
+
+

+#ifdef CONFIG_I2O_PCI
+ i2o_pci_init();
+#endif
+
+ if(i2o_num_controllers)
+ i2o_sys_init();
+
+ register_reboot_notifier(&i2o_reboot_notifier);
+
+ i2o_config_init();
+#ifdef CONFIG_I2O_BLOCK
+ i2o_block_init();
+#endif
+#ifdef CONFIG_I2O_LAN
+ i2o_lan_init();
+#endif
+#ifdef CONFIG_I2O_PROC
+ i2o_proc_init();


+#endif
+ return 0;
+}
+

+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_lan.c linux/drivers/message/i2o/i2o_lan.c
--- v2.4.12/linux/drivers/message/i2o/i2o_lan.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_lan.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,1579 @@
+/*
+ * drivers/i2o/i2o_lan.c
+ *
+ * I2O LAN CLASS OSM May 26th 2000
+ *
+ * (C) Copyright 1999, 2000 University of Helsinki,
+ * Department of Computer Science
+ *
+ * This code is still under development / test.
+ *


+ * 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.
+ *

+ * Authors: Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
+ * Fixes: Juha Sievänen <Juha.S...@cs.Helsinki.FI>
+ * Taneli Vähäkangas <Taneli.V...@cs.Helsinki.FI>


+ * Deepak Saxena <dee...@plexity.net>
+ *

+ * Tested: in FDDI environment (using SysKonnect's DDM)
+ * in Gigabit Eth environment (using SysKonnect's DDM)
+ * in Fast Ethernet environment (using Intel 82558 DDM)
+ *
+ * TODO: tests for other LAN classes (Token Ring, Fibre Channel)


+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+

+#include <linux/pci.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/fddidevice.h>
+#include <linux/trdevice.h>
+#include <linux/fcdevice.h>
+
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/tqueue.h>
+#include <asm/io.h>
+
+#include <linux/errno.h>
+
+#include <linux/i2o.h>


+#include "i2o_lan.h"
+
+//#define DRIVERDEBUG

+#ifdef DRIVERDEBUG
+#define dprintk(s, args...) printk(s, ## args)
+#else
+#define dprintk(s, args...)
+#endif
+

+/* The following module parameters are used as default values
+ * for per interface values located in the net_device private area.
+ * Private values are changed via /proc filesystem.
+ */
+static u32 max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
+static u32 bucket_thresh = I2O_LAN_BUCKET_THRESH;
+static u32 rx_copybreak = I2O_LAN_RX_COPYBREAK;
+static u8 tx_batch_mode = I2O_LAN_TX_BATCH_MODE;
+static u32 i2o_event_mask = I2O_LAN_EVENT_MASK;
+
+#define MAX_LAN_CARDS 16
+static struct net_device *i2o_landevs[MAX_LAN_CARDS+1];
+static int unit = -1; /* device unit number */
+
+static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
+static void i2o_lan_send_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
+static int i2o_lan_receive_post(struct net_device *dev);
+static void i2o_lan_receive_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
+static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg);
+
+static int i2o_lan_reset(struct net_device *dev);
+static void i2o_lan_handle_event(struct net_device *dev, u32 *msg);
+
+/* Structures to register handlers for the incoming replies. */
+
+static struct i2o_handler i2o_lan_send_handler = {
+ i2o_lan_send_post_reply, // For send replies


+ NULL,
+ NULL,
+ NULL,

+ "I2O LAN OSM send",
+ -1,
+ I2O_CLASS_LAN
+};
+static int lan_send_context;
+
+static struct i2o_handler i2o_lan_receive_handler = {
+ i2o_lan_receive_post_reply, // For receive replies


+ NULL,
+ NULL,
+ NULL,

+ "I2O LAN OSM receive",
+ -1,
+ I2O_CLASS_LAN
+};
+static int lan_receive_context;
+
+static struct i2o_handler i2o_lan_handler = {
+ i2o_lan_reply, // For other replies


+ NULL,
+ NULL,
+ NULL,

+ "I2O LAN OSM",
+ -1,
+ I2O_CLASS_LAN
+};
+static int lan_context;
+
+DECLARE_TASK_QUEUE(i2o_post_buckets_task);
+struct tq_struct run_i2o_post_buckets_task = {
+ routine: (void (*)(void *)) run_task_queue,
+ data: (void *) 0
+};
+
+/* Functions to handle message failures and transaction errors:
+==============================================================*/
+
+/*
+ * i2o_lan_handle_failure(): Fail bit has been set since IOP's message
+ * layer cannot deliver the request to the target, or the target cannot
+ * process the request.
+ */
+static void i2o_lan_handle_failure(struct net_device *dev, u32 *msg)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+
+ u32 *preserved_msg = (u32*)(iop->mem_offset + msg[7]);
+ u32 *sgl_elem = &preserved_msg[4];
+ struct sk_buff *skb = NULL;
+ u8 le_flag;
+
+ i2o_report_status(KERN_INFO, dev->name, msg);
+
+ /* If PacketSend failed, free sk_buffs reserved by upper layers */
+
+ if (msg[1] >> 24 == LAN_PACKET_SEND) {
+ do {
+ skb = (struct sk_buff *)(sgl_elem[1]);
+ dev_kfree_skb_irq(skb);
+
+ atomic_dec(&priv->tx_out);
+
+ le_flag = *sgl_elem >> 31;
+ sgl_elem +=3;
+ } while (le_flag == 0); /* Last element flag not set */
+
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ }
+
+ /* If ReceivePost failed, free sk_buffs we have reserved */
+
+ if (msg[1] >> 24 == LAN_RECEIVE_POST) {
+ do {
+ skb = (struct sk_buff *)(sgl_elem[1]);
+ dev_kfree_skb_irq(skb);
+
+ atomic_dec(&priv->buckets_out);
+
+ le_flag = *sgl_elem >> 31;
+ sgl_elem +=3;
+ } while (le_flag == 0); /* Last element flag not set */
+ }


+
+ /* Release the preserved msg frame by resubmitting it as a NOP */
+
+ preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
+ preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
+ preserved_msg[2] = 0;

+ i2o_post_message(iop, msg[7]);
+}
+/*
+ * i2o_lan_handle_transaction_error(): IOP or DDM has rejected the request
+ * for general cause (format error, bad function code, insufficient resources,
+ * etc.). We get one transaction_error for each failed transaction.
+ */
+static void i2o_lan_handle_transaction_error(struct net_device *dev, u32 *msg)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct sk_buff *skb;
+
+ i2o_report_status(KERN_INFO, dev->name, msg);
+
+ /* If PacketSend was rejected, free sk_buff reserved by upper layers */
+
+ if (msg[1] >> 24 == LAN_PACKET_SEND) {
+ skb = (struct sk_buff *)(msg[3]); // TransactionContext
+ dev_kfree_skb_irq(skb);
+ atomic_dec(&priv->tx_out);
+
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ }
+
+ /* If ReceivePost was rejected, free sk_buff we have reserved */
+
+ if (msg[1] >> 24 == LAN_RECEIVE_POST) {
+ skb = (struct sk_buff *)(msg[3]);
+ dev_kfree_skb_irq(skb);
+ atomic_dec(&priv->buckets_out);
+ }
+}
+
+/*
+ * i2o_lan_handle_status(): Common parts of handling a not succeeded request
+ * (status != SUCCESS).
+ */
+static int i2o_lan_handle_status(struct net_device *dev, u32 *msg)
+{
+ /* Fail bit set? */


+
+ if (msg[0] & MSG_FAIL) {

+ i2o_lan_handle_failure(dev, msg);


+ return -1;
+ }
+

+ /* Message rejected for general cause? */
+
+ if ((msg[4]>>24) == I2O_REPLY_STATUS_TRANSACTION_ERROR) {
+ i2o_lan_handle_transaction_error(dev, msg);


+ return -1;
+ }
+

+ /* Else have to handle it in the callback function */


+
+ return 0;
+}
+

+/* Callback functions called from the interrupt routine:
+=======================================================*/
+
+/*
+ * i2o_lan_send_post_reply(): Callback function to handle PostSend replies.
+ */
+static void i2o_lan_send_post_reply(struct i2o_handler *h,
+ struct i2o_controller *iop, struct i2o_message *m)


+{
+ u32 *msg = (u32 *)m;

+ u8 unit = (u8)(msg[2]>>16); // InitiatorContext
+ struct net_device *dev = i2o_landevs[unit];
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ u8 trl_count = msg[3] & 0x000000FF;
+
+ if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
+ if (i2o_lan_handle_status(dev, msg))
+ return;
+ }
+
+#ifdef DRIVERDEBUG
+ i2o_report_status(KERN_INFO, dev->name, msg);
+#endif
+
+ /* DDM has handled transmit request(s), free sk_buffs.
+ * We get similar single transaction reply also in error cases
+ * (except if msg failure or transaction error).
+ */
+ while (trl_count) {
+ dev_kfree_skb_irq((struct sk_buff *)msg[4 + trl_count]);
+ dprintk(KERN_INFO "%s: tx skb freed (trl_count=%d).\n",
+ dev->name, trl_count);
+ atomic_dec(&priv->tx_out);
+ trl_count--;
+ }
+
+ /* If priv->tx_out had reached tx_max_out, the queue was stopped */
+
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+}
+
+/*
+ * i2o_lan_receive_post_reply(): Callback function to process incoming packets.
+ */
+static void i2o_lan_receive_post_reply(struct i2o_handler *h,
+ struct i2o_controller *iop, struct i2o_message *m)


+{
+ u32 *msg = (u32 *)m;

+ u8 unit = (u8)(msg[2]>>16); // InitiatorContext
+ struct net_device *dev = i2o_landevs[unit];
+
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_bucket_descriptor *bucket = (struct i2o_bucket_descriptor *)&msg[6];
+ struct i2o_packet_info *packet;
+ u8 trl_count = msg[3] & 0x000000FF;
+ struct sk_buff *skb, *old_skb;


+ unsigned long flags = 0;
+

+ if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
+ if (i2o_lan_handle_status(dev, msg))
+ return;
+
+ i2o_lan_release_buckets(dev, msg);
+ return;
+ }
+
+#ifdef DRIVERDEBUG
+ i2o_report_status(KERN_INFO, dev->name, msg);
+#endif
+
+ /* Else we are receiving incoming post. */
+
+ while (trl_count--) {
+ skb = (struct sk_buff *)bucket->context;
+ packet = (struct i2o_packet_info *)bucket->packet_info;
+ atomic_dec(&priv->buckets_out);
+
+ /* Sanity checks: Any weird characteristics in bucket? */
+
+ if (packet->flags & 0x0f || ! packet->flags & 0x40) {
+ if (packet->flags & 0x01)
+ printk(KERN_WARNING "%s: packet with errors, error code=0x%02x.\n",
+ dev->name, packet->status & 0xff);
+
+ /* The following shouldn't happen, unless parameters in
+ * LAN_OPERATION group are changed during the run time.
+ */
+ if (packet->flags & 0x0c)
+ printk(KERN_DEBUG "%s: multi-bucket packets not supported!\n",
+ dev->name);
+
+ if (! packet->flags & 0x40)
+ printk(KERN_DEBUG "%s: multiple packets in a bucket not supported!\n",
+ dev->name);
+
+ dev_kfree_skb_irq(skb);
+
+ bucket++;
+ continue;
+ }
+
+ /* Copy short packet to a new skb */
+
+ if (packet->len < priv->rx_copybreak) {
+ old_skb = skb;
+ skb = (struct sk_buff *)dev_alloc_skb(packet->len+2);
+ if (skb == NULL) {
+ printk(KERN_ERR "%s: Can't allocate skb.\n", dev->name);
+ return;
+ }
+ skb_reserve(skb, 2);
+ memcpy(skb_put(skb, packet->len), old_skb->data, packet->len);
+
+ spin_lock_irqsave(&priv->fbl_lock, flags);
+ if (priv->i2o_fbl_tail < I2O_LAN_MAX_BUCKETS_OUT)
+ priv->i2o_fbl[++priv->i2o_fbl_tail] = old_skb;
+ else
+ dev_kfree_skb_irq(old_skb);
+
+ spin_unlock_irqrestore(&priv->fbl_lock, flags);
+ } else
+ skb_put(skb, packet->len);
+
+ /* Deliver to upper layers */
+
+ skb->dev = dev;
+ skb->protocol = priv->type_trans(skb, dev);
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+
+ dprintk(KERN_INFO "%s: Incoming packet (%d bytes) delivered "
+ "to upper level.\n", dev->name, packet->len);
+
+ bucket++; // to next Packet Descriptor Block
+ }
+
+#ifdef DRIVERDEBUG
+ if (msg[5] == 0)
+ printk(KERN_INFO "%s: DDM out of buckets (priv->count = %d)!\n",
+ dev->name, atomic_read(&priv->buckets_out));
+#endif
+
+ /* If DDM has already consumed bucket_thresh buckets, post new ones */
+
+ if (atomic_read(&priv->buckets_out) <= priv->max_buckets_out - priv->bucket_thresh) {
+ run_i2o_post_buckets_task.data = (void *)dev;
+ queue_task(&run_i2o_post_buckets_task, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ }
+
+ return;
+}
+
+/*
+ * i2o_lan_reply(): Callback function to handle other incoming messages
+ * except SendPost and ReceivePost.
+ */
+static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop,


+ struct i2o_message *m)
+{

+ u32 *msg = (u32 *)m;

+ u8 unit = (u8)(msg[2]>>16); // InitiatorContext
+ struct net_device *dev = i2o_landevs[unit];
+
+ if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
+ if (i2o_lan_handle_status(dev, msg))
+ return;
+
+ /* In other error cases just report and continue */
+
+ i2o_report_status(KERN_INFO, dev->name, msg);
+ }
+
+#ifdef DRIVERDEBUG
+ i2o_report_status(KERN_INFO, dev->name, msg);
+#endif
+ switch (msg[1] >> 24) {
+ case LAN_RESET:
+ case LAN_SUSPEND:
+ /* default reply without payload */
+ break;
+
+ case I2O_CMD_UTIL_EVT_REGISTER:
+ case I2O_CMD_UTIL_EVT_ACK:
+ i2o_lan_handle_event(dev, msg);
+ break;
+
+ case I2O_CMD_UTIL_PARAMS_SET:
+ /* default reply, results in ReplyPayload (not examined) */
+ switch (msg[3] >> 16) {
+ case 1: dprintk(KERN_INFO "%s: Reply to set MAC filter mask.\n",
+ dev->name);
+ break;
+ case 2: dprintk(KERN_INFO "%s: Reply to set MAC table.\n",
+ dev->name);
+ break;
+ default: printk(KERN_WARNING "%s: Bad group 0x%04X\n",
+ dev->name,msg[3] >> 16);
+ }
+ break;
+
+ default:
+ printk(KERN_ERR "%s: No handler for the reply.\n",
+ dev->name);
+ i2o_report_status(KERN_INFO, dev->name, msg);
+ }
+}
+
+/* Functions used by the above callback functions:
+=================================================*/
+/*
+ * i2o_lan_release_buckets(): Free unused buckets (sk_buffs).
+ */
+static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ u8 trl_elem_size = (u8)(msg[3]>>8 & 0x000000FF);
+ u8 trl_count = (u8)(msg[3] & 0x000000FF);
+ u32 *pskb = &msg[6];
+
+ while (trl_count--) {
+ dprintk(KERN_DEBUG "%s: Releasing unused rx skb %p (trl_count=%d).\n",
+ dev->name, (struct sk_buff*)(*pskb),trl_count+1);
+ dev_kfree_skb_irq((struct sk_buff *)(*pskb));
+ pskb += 1 + trl_elem_size;
+ atomic_dec(&priv->buckets_out);
+ }
+}
+
+/*
+ * i2o_lan_event_reply(): Handle events.
+ */
+static void i2o_lan_handle_event(struct net_device *dev, u32 *msg)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ u32 max_evt_data_size =iop->status_block->inbound_frame_size-5;


+ struct i2o_reply {
+ u32 header[4];
+ u32 evt_indicator;

+ u32 data[max_evt_data_size];
+ } *evt = (struct i2o_reply *)msg;
+ int evt_data_len = ((msg[0]>>16) - 5) * 4; /* real size*/
+
+ printk(KERN_INFO "%s: I2O event - ", dev->name);
+
+ if (msg[1]>>24 == I2O_CMD_UTIL_EVT_ACK) {
+ printk("Event acknowledgement reply.\n");
+ return;
+ }
+
+ /* Else evt->function == I2O_CMD_UTIL_EVT_REGISTER) */
+
+ switch (evt->evt_indicator) {
+ case I2O_EVT_IND_STATE_CHANGE: {
+ struct state_data {
+ u16 status;
+ u8 state;
+ u8 data;
+ } *evt_data = (struct state_data *)(evt->data[0]);
+
+ printk("State chance 0x%08x.\n", evt->data[0]);
+
+ /* If the DDM is in error state, recovery may be
+ * possible if status = Transmit or Receive Control
+ * Unit Inoperable.
+ */
+ if (evt_data->state==0x05 && evt_data->status==0x0003)
+ i2o_lan_reset(dev);
+ break;
+ }
+
+ case I2O_EVT_IND_FIELD_MODIFIED: {
+ u16 *work16 = (u16 *)evt->data;
+ printk("Group 0x%04x, field %d changed.\n", work16[0], work16[1]);
+ break;
+ }
+
+ case I2O_EVT_IND_VENDOR_EVT: {
+ int i;
+ printk("Vendor event:\n");
+ for (i = 0; i < evt_data_len / 4; i++)
+ printk(" 0x%08x\n", evt->data[i]);
+ break;
+ }
+
+ case I2O_EVT_IND_DEVICE_RESET:
+ /* Spec 2.0 p. 6-121:
+ * The event of _DEVICE_RESET should also be responded
+ */
+ printk("Device reset.\n");
+ if (i2o_event_ack(iop, msg) < 0)
+ printk("%s: Event Acknowledge timeout.\n", dev->name);
+ break;
+
+#if 0
+ case I2O_EVT_IND_EVT_MASK_MODIFIED:
+ printk("Event mask modified, 0x%08x.\n", evt->data[0]);
+ break;
+
+ case I2O_EVT_IND_GENERAL_WARNING:
+ printk("General warning 0x%04x.\n", evt->data[0]);
+ break;
+
+ case I2O_EVT_IND_CONFIGURATION_FLAG:
+ printk("Configuration requested.\n");
+ break;
+
+ case I2O_EVT_IND_CAPABILITY_CHANGE:
+ printk("Capability change 0x%04x.\n", evt->data[0]);
+ break;
+
+ case I2O_EVT_IND_DEVICE_STATE:
+ printk("Device state changed 0x%08x.\n", evt->data[0]);
+ break;
+#endif
+ case I2O_LAN_EVT_LINK_DOWN:
+ netif_carrier_off(dev);
+ printk("Link to the physical device is lost.\n");
+ break;
+
+ case I2O_LAN_EVT_LINK_UP:
+ netif_carrier_on(dev);
+ printk("Link to the physical device is (re)established.\n");
+ break;
+
+ case I2O_LAN_EVT_MEDIA_CHANGE:
+ printk("Media change.\n");
+ break;
+ default:
+ printk("0x%08x. No handler.\n", evt->evt_indicator);
+ }
+}
+
+/*
+ * i2o_lan_receive_post(): Post buckets to receive packets.
+ */
+static int i2o_lan_receive_post(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ struct sk_buff *skb;
+ u32 m, *msg;
+ u32 bucket_len = (dev->mtu + dev->hard_header_len);
+ u32 total = priv->max_buckets_out - atomic_read(&priv->buckets_out);
+ u32 bucket_count;
+ u32 *sgl_elem;


+ unsigned long flags;
+

+ /* Send (total/bucket_count) separate I2O requests */
+
+ while (total) {
+ m = I2O_POST_READ32(iop);
+ if (m == 0xFFFFFFFF)
+ return -ETIMEDOUT;
+ msg = (u32 *)(iop->mem_offset + m);
+
+ bucket_count = (total >= priv->sgl_max) ? priv->sgl_max : total;
+ total -= bucket_count;
+ atomic_add(bucket_count, &priv->buckets_out);
+
+ dprintk(KERN_INFO "%s: Sending %d buckets (size %d) to LAN DDM.\n",
+ dev->name, bucket_count, bucket_len);
+
+ /* Fill in the header */
+
+ __raw_writel(I2O_MESSAGE_SIZE(4 + 3 * bucket_count) | SGL_OFFSET_4, msg);
+ __raw_writel(LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
+ __raw_writel(priv->unit << 16 | lan_receive_context, msg+2);
+ __raw_writel(bucket_count, msg+3);
+ sgl_elem = &msg[4];
+
+ /* Fill in the payload - contains bucket_count SGL elements */
+
+ while (bucket_count--) {
+ spin_lock_irqsave(&priv->fbl_lock, flags);
+ if (priv->i2o_fbl_tail >= 0)
+ skb = priv->i2o_fbl[priv->i2o_fbl_tail--];
+ else {
+ skb = dev_alloc_skb(bucket_len + 2);
+ if (skb == NULL) {
+ spin_unlock_irqrestore(&priv->fbl_lock, flags);
+ return -ENOMEM;
+ }
+ skb_reserve(skb, 2);
+ }
+ spin_unlock_irqrestore(&priv->fbl_lock, flags);
+
+ __raw_writel(0x51000000 | bucket_len, sgl_elem);
+ __raw_writel((u32)skb, sgl_elem+1);
+ __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
+ sgl_elem += 3;
+ }
+
+ /* set LE flag and post */
+ __raw_writel(__raw_readl(sgl_elem-3) | 0x80000000, (sgl_elem-3));
+ i2o_post_message(iop, m);


+ }
+
+ return 0;
+}
+

+/* Functions called from the network stack, and functions called by them:
+========================================================================*/
+
+/*
+ * i2o_lan_reset(): Reset the LAN adapter into the operational state and
+ * restore it to full operation.
+ */
+static int i2o_lan_reset(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;


+ u32 msg[5];
+

+ dprintk(KERN_INFO "%s: LAN RESET MESSAGE.\n", dev->name);
+ msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
+ msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
+ msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
+ msg[3] = 0; // TransactionContext
+ msg[4] = 0; // Keep posted buckets
+
+ if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
+ return -ETIMEDOUT;
+


+ return 0;
+}
+
+/*

+ * i2o_lan_suspend(): Put LAN adapter into a safe, non-active state.
+ * IOP replies to any LAN class message with status error_no_data_transfer
+ * / suspended.
+ */
+static int i2o_lan_suspend(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;


+ u32 msg[5];
+

+ dprintk(KERN_INFO "%s: LAN SUSPEND MESSAGE.\n", dev->name);
+ msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
+ msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
+ msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
+ msg[3] = 0; // TransactionContext
+ msg[4] = 1 << 16; // return posted buckets
+
+ if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
+ return -ETIMEDOUT;
+


+ return 0;
+}
+
+/*

+ * i2o_set_ddm_parameters:
+ * These settings are done to ensure proper initial values for DDM.
+ * They can be changed via proc file system or vai configuration utility.
+ */
+static void i2o_set_ddm_parameters(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ u32 val;
+
+ /*
+ * When PacketOrphanlimit is set to the maximum packet length,
+ * the packets will never be split into two separate buckets
+ */
+ val = dev->mtu + dev->hard_header_len;
+ if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0004, 2, &val, sizeof(val)) < 0)
+ printk(KERN_WARNING "%s: Unable to set PacketOrphanLimit.\n",
+ dev->name);
+ else
+ dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d.\n",
+ dev->name, val);
+
+ /* When RxMaxPacketsBucket = 1, DDM puts only one packet into bucket */
+
+ val = 1;
+ if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0008, 4, &val, sizeof(val)) <0)
+ printk(KERN_WARNING "%s: Unable to set RxMaxPacketsBucket.\n",
+ dev->name);
+ else
+ dprintk(KERN_INFO "%s: RxMaxPacketsBucket set to %d.\n",
+ dev->name, val);
+ return;
+}
+
+/* Functions called from the network stack:
+==========================================*/
+
+/*
+ * i2o_lan_open(): Open the device to send/receive packets via
+ * the network device.
+ */
+static int i2o_lan_open(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ u32 mc_addr_group[64];
+
+ MOD_INC_USE_COUNT;
+
+ if (i2o_claim_device(i2o_dev, &i2o_lan_handler)) {
+ printk(KERN_WARNING "%s: Unable to claim the I2O LAN device.\n", dev->name);
+ MOD_DEC_USE_COUNT;
+ return -EAGAIN;
+ }
+ dprintk(KERN_INFO "%s: I2O LAN device (tid=%d) claimed by LAN OSM.\n",
+ dev->name, i2o_dev->lct_data.tid);
+
+ if (i2o_event_register(iop, i2o_dev->lct_data.tid,
+ priv->unit << 16 | lan_context, 0, priv->i2o_event_mask) < 0)
+ printk(KERN_WARNING "%s: Unable to set the event mask.\n", dev->name);
+
+ i2o_lan_reset(dev);
+
+ /* Get the max number of multicast addresses */
+
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0001, -1,
+ &mc_addr_group, sizeof(mc_addr_group)) < 0 ) {
+ printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name);
+ MOD_DEC_USE_COUNT;
+ return -EAGAIN;
+ }
+ priv->max_size_mc_table = mc_addr_group[8];
+
+ /* Malloc space for free bucket list to resuse reveive post buckets */
+
+ priv->i2o_fbl = kmalloc(priv->max_buckets_out * sizeof(struct sk_buff *),
+ GFP_KERNEL);
+ if (priv->i2o_fbl == NULL) {
+ MOD_DEC_USE_COUNT;
+ return -ENOMEM;
+ }
+ priv->i2o_fbl_tail = -1;
+ priv->send_active = 0;
+
+ i2o_set_ddm_parameters(dev);
+ i2o_lan_receive_post(dev);
+
+ netif_start_queue(dev);


+
+ return 0;
+}
+
+/*

+ * i2o_lan_close(): End the transfering.
+ */
+static int i2o_lan_close(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;


+ int ret = 0;
+

+ netif_stop_queue(dev);
+ i2o_lan_suspend(dev);
+
+ if (i2o_event_register(iop, i2o_dev->lct_data.tid,
+ priv->unit << 16 | lan_context, 0, 0) < 0)
+ printk(KERN_WARNING "%s: Unable to clear the event mask.\n",
+ dev->name);
+
+ while (priv->i2o_fbl_tail >= 0)
+ dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
+
+ kfree(priv->i2o_fbl);
+
+ if (i2o_release_device(i2o_dev, &i2o_lan_handler)) {
+ printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device "
+ "(tid=%d).\n", dev->name, i2o_dev->lct_data.tid);
+ ret = -EBUSY;
+ }
+
+ MOD_DEC_USE_COUNT;


+
+ return ret;
+}
+
+/*

+ * i2o_lan_tx_timeout(): Tx timeout handler.
+ */
+static void i2o_lan_tx_timeout(struct net_device *dev)
+{
+ if (!netif_queue_stopped(dev))
+ netif_start_queue(dev);
+}
+
+/*
+ * i2o_lan_batch_send(): Send packets in batch.
+ * Both i2o_lan_sdu_send and i2o_lan_packet_send use this.
+ */
+static void i2o_lan_batch_send(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_controller *iop = priv->i2o_dev->controller;
+
+ spin_lock_irq(&priv->tx_lock);
+ if (priv->tx_count != 0) {
+ dev->trans_start = jiffies;
+ i2o_post_message(iop, priv->m);
+ dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
+ priv->tx_count = 0;
+ }
+ priv->send_active = 0;
+ spin_unlock_irq(&priv->tx_lock);
+ MOD_DEC_USE_COUNT;
+}
+
+#ifdef CONFIG_NET_FC
+/*
+ * i2o_lan_sdu_send(): Send a packet, MAC header added by the DDM.
+ * Must be supported by Fibre Channel, optional for Ethernet/802.3,
+ * Token Ring, FDDI
+ */
+static int i2o_lan_sdu_send(struct sk_buff *skb, struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ int tickssofar = jiffies - dev->trans_start;
+ u32 m, *msg;
+ u32 *sgl_elem;
+
+ spin_lock_irq(&priv->tx_lock);
+
+ priv->tx_count++;
+ atomic_inc(&priv->tx_out);
+
+ /*
+ * If tx_batch_mode = 0x00 forced to immediate mode
+ * If tx_batch_mode = 0x01 forced to batch mode
+ * If tx_batch_mode = 0x10 switch automatically, current mode immediate
+ * If tx_batch_mode = 0x11 switch automatically, current mode batch
+ * If gap between two packets is > 0 ticks, switch to immediate
+ */
+ if (priv->tx_batch_mode >> 1) // switch automatically
+ priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
+
+ if (priv->tx_count == 1) {
+ m = I2O_POST_READ32(iop);
+ if (m == 0xFFFFFFFF) {
+ spin_unlock_irq(&priv->tx_lock);
+ return 1;
+ }
+ msg = (u32 *)(iop->mem_offset + m);
+ priv->m = m;
+
+ __raw_writel(NINE_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);
+ __raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
+ __raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
+ __raw_writel(1 << 30 | 1 << 3, msg+3); // TransmitControlWord
+
+ __raw_writel(0xD7000000 | skb->len, msg+4); // MAC hdr included
+ __raw_writel((u32)skb, msg+5); // TransactionContext
+ __raw_writel(virt_to_bus(skb->data), msg+6);
+ __raw_writel((u32)skb->mac.raw, msg+7);
+ __raw_writel((u32)skb->mac.raw+4, msg+8);
+
+ if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
+ priv->send_active = 1;
+ MOD_INC_USE_COUNT;
+ if (schedule_task(&priv->i2o_batch_send_task) == 0)
+ MOD_DEC_USE_COUNT;
+ }
+ } else { /* Add new SGL element to the previous message frame */
+
+ msg = (u32 *)(iop->mem_offset + priv->m);
+ sgl_elem = &msg[priv->tx_count * 5 + 1];
+
+ __raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 5) | 1<<12 | SGL_OFFSET_4, msg);
+ __raw_writel(__raw_readl(sgl_elem-5) & 0x7FFFFFFF, sgl_elem-5); /* clear LE flag */
+ __raw_writel(0xD5000000 | skb->len, sgl_elem);
+ __raw_writel((u32)skb, sgl_elem+1);
+ __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
+ __raw_writel((u32)(skb->mac.raw), sgl_elem+3);
+ __raw_writel((u32)(skb->mac.raw)+1, sgl_elem+4);
+ }
+
+ /* If tx not in batch mode or frame is full, send immediatelly */
+
+ if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
+ dev->trans_start = jiffies;
+ i2o_post_message(iop, priv->m);
+ dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
+ priv->tx_count = 0;
+ }
+
+ /* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
+
+ if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
+ netif_stop_queue(dev);
+
+ spin_unlock_irq(&priv->tx_lock);
+ return 0;
+}
+#endif /* CONFIG_NET_FC */
+
+/*
+ * i2o_lan_packet_send(): Send a packet as is, including the MAC header.
+ *
+ * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for
+ * Fibre Channel
+ */
+static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ int tickssofar = jiffies - dev->trans_start;
+ u32 m, *msg;
+ u32 *sgl_elem;
+
+ spin_lock_irq(&priv->tx_lock);
+
+ priv->tx_count++;
+ atomic_inc(&priv->tx_out);
+
+ /*
+ * If tx_batch_mode = 0x00 forced to immediate mode
+ * If tx_batch_mode = 0x01 forced to batch mode
+ * If tx_batch_mode = 0x10 switch automatically, current mode immediate
+ * If tx_batch_mode = 0x11 switch automatically, current mode batch
+ * If gap between two packets is > 0 ticks, switch to immediate
+ */
+ if (priv->tx_batch_mode >> 1) // switch automatically
+ priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
+
+ if (priv->tx_count == 1) {
+ m = I2O_POST_READ32(iop);
+ if (m == 0xFFFFFFFF) {
+ spin_unlock_irq(&priv->tx_lock);
+ return 1;
+ }
+ msg = (u32 *)(iop->mem_offset + m);
+ priv->m = m;
+
+ __raw_writel(SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);
+ __raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
+ __raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
+ __raw_writel(1 << 30 | 1 << 3, msg+3); // TransmitControlWord
+ // bit 30: reply as soon as transmission attempt is complete
+ // bit 3: Suppress CRC generation
+ __raw_writel(0xD5000000 | skb->len, msg+4); // MAC hdr included
+ __raw_writel((u32)skb, msg+5); // TransactionContext
+ __raw_writel(virt_to_bus(skb->data), msg+6);
+
+ if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
+ priv->send_active = 1;
+ MOD_INC_USE_COUNT;
+ if (schedule_task(&priv->i2o_batch_send_task) == 0)
+ MOD_DEC_USE_COUNT;
+ }
+ } else { /* Add new SGL element to the previous message frame */
+
+ msg = (u32 *)(iop->mem_offset + priv->m);
+ sgl_elem = &msg[priv->tx_count * 3 + 1];
+
+ __raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 3) | 1<<12 | SGL_OFFSET_4, msg);
+ __raw_writel(__raw_readl(sgl_elem-3) & 0x7FFFFFFF, sgl_elem-3); /* clear LE flag */
+ __raw_writel(0xD5000000 | skb->len, sgl_elem);
+ __raw_writel((u32)skb, sgl_elem+1);
+ __raw_writel(virt_to_bus(skb->data), sgl_elem+2);
+ }
+
+ /* If tx is in immediate mode or frame is full, send now */
+
+ if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
+ dev->trans_start = jiffies;
+ i2o_post_message(iop, priv->m);
+ dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
+ priv->tx_count = 0;
+ }
+
+ /* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
+
+ if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
+ netif_stop_queue(dev);
+
+ spin_unlock_irq(&priv->tx_lock);


+ return 0;
+}
+
+/*

+ * i2o_lan_get_stats(): Fill in the statistics.
+ */
+static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ u64 val64[16];
+ u64 supported_group[4] = { 0, 0, 0, 0 };
+
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0100, -1, val64,
+ sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_HISTORICAL_STATS.\n", dev->name);
+ else {
+ dprintk(KERN_DEBUG "%s: LAN_HISTORICAL_STATS queried.\n", dev->name);
+ priv->stats.tx_packets = val64[0];
+ priv->stats.tx_bytes = val64[1];
+ priv->stats.rx_packets = val64[2];
+ priv->stats.rx_bytes = val64[3];
+ priv->stats.tx_errors = val64[4];
+ priv->stats.rx_errors = val64[5];
+ priv->stats.rx_dropped = val64[6];
+ }
+
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0180, -1,
+ &supported_group, sizeof(supported_group)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_OPTIONAL_HISTORICAL_STATS.\n", dev->name);
+
+ if (supported_group[2]) {
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0183, -1,
+ val64, sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_RX_HISTORICAL_STATS.\n", dev->name);
+ else {
+ dprintk(KERN_DEBUG "%s: LAN_OPTIONAL_RX_HISTORICAL_STATS queried.\n", dev->name);
+ priv->stats.multicast = val64[4];
+ priv->stats.rx_length_errors = val64[10];
+ priv->stats.rx_crc_errors = val64[0];
+ }
+ }
+
+ if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET) {
+ u64 supported_stats = 0;
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0200, -1,
+ val64, sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_802_3_HISTORICAL_STATS.\n", dev->name);
+ else {
+ dprintk(KERN_DEBUG "%s: LAN_802_3_HISTORICAL_STATS queried.\n", dev->name);
+ priv->stats.transmit_collision = val64[1] + val64[2];
+ priv->stats.rx_frame_errors = val64[0];
+ priv->stats.tx_carrier_errors = val64[6];
+ }
+
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0280, -1,
+ &supported_stats, sizeof(supported_stats)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_802_3_HISTORICAL_STATS.\n", dev->name);
+
+ if (supported_stats != 0) {
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0281, -1,
+ val64, sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_802_3_HISTORICAL_STATS.\n", dev->name);
+ else {
+ dprintk(KERN_DEBUG "%s: LAN_OPTIONAL_802_3_HISTORICAL_STATS queried.\n", dev->name);
+ if (supported_stats & 0x1)
+ priv->stats.rx_over_errors = val64[0];
+ if (supported_stats & 0x4)
+ priv->stats.tx_heartbeat_errors = val64[2];
+ }
+ }
+ }
+
+#ifdef CONFIG_TR
+ if (i2o_dev->lct_data.sub_class == I2O_LAN_TR) {
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0300, -1,
+ val64, sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_802_5_HISTORICAL_STATS.\n", dev->name);
+ else {
+ struct tr_statistics *stats =
+ (struct tr_statistics *)&priv->stats;
+ dprintk(KERN_DEBUG "%s: LAN_802_5_HISTORICAL_STATS queried.\n", dev->name);
+
+ stats->line_errors = val64[0];
+ stats->internal_errors = val64[7];
+ stats->burst_errors = val64[4];
+ stats->A_C_errors = val64[2];
+ stats->abort_delimiters = val64[3];
+ stats->lost_frames = val64[1];
+ /* stats->recv_congest_count = ?; FIXME ??*/
+ stats->frame_copied_errors = val64[5];
+ stats->frequency_errors = val64[6];
+ stats->token_errors = val64[9];
+ }
+ /* Token Ring optional stats not yet defined */
+ }
+#endif
+
+#ifdef CONFIG_FDDI
+ if (i2o_dev->lct_data.sub_class == I2O_LAN_FDDI) {
+ if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0400, -1,
+ val64, sizeof(val64)) < 0)
+ printk(KERN_INFO "%s: Unable to query LAN_FDDI_HISTORICAL_STATS.\n", dev->name);
+ else {
+ dprintk(KERN_DEBUG "%s: LAN_FDDI_HISTORICAL_STATS queried.\n", dev->name);
+ priv->stats.smt_cf_state = val64[0];
+ memcpy(priv->stats.mac_upstream_nbr, &val64[1], FDDI_K_ALEN);
+ memcpy(priv->stats.mac_downstream_nbr, &val64[2], FDDI_K_ALEN);
+ priv->stats.mac_error_cts = val64[3];
+ priv->stats.mac_lost_cts = val64[4];
+ priv->stats.mac_rmt_state = val64[5];
+ memcpy(priv->stats.port_lct_fail_cts, &val64[6], 8);
+ memcpy(priv->stats.port_lem_reject_cts, &val64[7], 8);
+ memcpy(priv->stats.port_lem_cts, &val64[8], 8);
+ memcpy(priv->stats.port_pcm_state, &val64[9], 8);
+ }
+ /* FDDI optional stats not yet defined */
+ }
+#endif
+
+#ifdef CONFIG_NET_FC
+ /* Fibre Channel Statistics not yet defined in 1.53 nor 2.0 */
+#endif
+
+ return (struct net_device_stats *)&priv->stats;
+}
+
+/*
+ * i2o_lan_set_mc_filter(): Post a request to set multicast filter.
+ */
+int i2o_lan_set_mc_filter(struct net_device *dev, u32 filter_mask)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ u32 msg[10];
+
+ msg[0] = TEN_WORD_MSG_SIZE | SGL_OFFSET_5;
+ msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;
+ msg[2] = priv->unit << 16 | lan_context;
+ msg[3] = 0x0001 << 16 | 3 ; // TransactionContext: group&field


+ msg[4] = 0;

+ msg[5] = 0xCC000000 | 16; // Immediate data SGL
+ msg[6] = 1; // OperationCount
+ msg[7] = 0x0001<<16 | I2O_PARAMS_FIELD_SET; // Group, Operation
+ msg[8] = 3 << 16 | 1; // FieldIndex, FieldCount
+ msg[9] = filter_mask; // Value
+
+ return i2o_post_this(iop, msg, sizeof(msg));
+}
+
+/*
+ * i2o_lan_set_mc_table(): Post a request to set LAN_MULTICAST_MAC_ADDRESS table.
+ */
+int i2o_lan_set_mc_table(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ struct i2o_controller *iop = i2o_dev->controller;
+ struct dev_mc_list *mc;
+ u32 msg[10 + 2 * dev->mc_count];
+ u8 *work8 = (u8 *)(msg + 10);
+
+ msg[0] = I2O_MESSAGE_SIZE(10 + 2 * dev->mc_count) | SGL_OFFSET_5;
+ msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;
+ msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
+ msg[3] = 0x0002 << 16 | (u16)-1; // TransactionContext
+ msg[4] = 0; // OperationFlags
+ msg[5] = 0xCC000000 | (16 + 8 * dev->mc_count); // Immediate data SGL
+ msg[6] = 2; // OperationCount
+ msg[7] = 0x0002 << 16 | I2O_PARAMS_TABLE_CLEAR; // Group, Operation
+ msg[8] = 0x0002 << 16 | I2O_PARAMS_ROW_ADD; // Group, Operation
+ msg[9] = dev->mc_count << 16 | (u16)-1; // RowCount, FieldCount
+
+ for (mc = dev->mc_list; mc ; mc = mc->next, work8 += 8) {
+ memset(work8, 0, 8);
+ memcpy(work8, mc->dmi_addr, mc->dmi_addrlen); // Values
+ }
+
+ return i2o_post_this(iop, msg, sizeof(msg));
+}
+
+/*
+ * i2o_lan_set_multicast_list(): Enable a network device to receive packets
+ * not send to the protocol address.
+ */
+static void i2o_lan_set_multicast_list(struct net_device *dev)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ u32 filter_mask;
+
+ if (dev->flags & IFF_PROMISC) {
+ filter_mask = 0x00000002;
+ dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name);
+ } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > priv->max_size_mc_table) {
+ filter_mask = 0x00000004;
+ dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name);
+ } else if (dev->mc_count) {
+ filter_mask = 0x00000000;
+ dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name);
+ if (i2o_lan_set_mc_table(dev) < 0)
+ printk(KERN_WARNING "%s: Unable to send MAC table.\n", dev->name);
+ } else {
+ filter_mask = 0x00000300; // Broadcast, Multicast disabled
+ dprintk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name);
+ }
+
+ /* Finally copy new FilterMask to DDM */
+
+ if (i2o_lan_set_mc_filter(dev, filter_mask) < 0)
+ printk(KERN_WARNING "%s: Unable to send MAC FilterMask.\n", dev->name);
+}
+
+/*
+ * i2o_lan_change_mtu(): Change maximum transfer unit size.
+ */
+static int i2o_lan_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+ u32 max_pkt_size;
+
+ if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
+ 0x0000, 6, &max_pkt_size, 4) < 0)
+ return -EFAULT;
+
+ if (new_mtu < 68 || new_mtu > 9000 || new_mtu > max_pkt_size)
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ i2o_lan_suspend(dev); // to SUSPENDED state, return buckets
+
+ while (priv->i2o_fbl_tail >= 0) // free buffered buckets
+ dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
+
+ i2o_lan_reset(dev); // to OPERATIONAL state
+ i2o_set_ddm_parameters(dev); // reset some parameters
+ i2o_lan_receive_post(dev); // post new buckets (new size)


+
+ return 0;
+}
+

+/* Functions to initialize I2O LAN OSM:
+======================================*/
+
+/*
+ * i2o_lan_register_device(): Register LAN class device to kernel.
+ */
+struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev)
+{
+ struct net_device *dev = NULL;
+ struct i2o_lan_local *priv = NULL;
+ u8 hw_addr[8];
+ u32 tx_max_out = 0;
+ unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
+ void (*unregister_dev)(struct net_device *dev);
+
+ switch (i2o_dev->lct_data.sub_class) {
+ case I2O_LAN_ETHERNET:
+ dev = init_etherdev(NULL, sizeof(struct i2o_lan_local));
+ if (dev == NULL)
+ return NULL;
+ type_trans = eth_type_trans;
+ unregister_dev = unregister_netdev;
+ break;
+
+#ifdef CONFIG_ANYLAN
+ case I2O_LAN_100VG:
+ printk(KERN_ERR "i2o_lan: 100base VG not yet supported.\n");
+ return NULL;
+ break;
+#endif
+
+#ifdef CONFIG_TR
+ case I2O_LAN_TR:
+ dev = init_trdev(NULL, sizeof(struct i2o_lan_local));
+ if (dev==NULL)
+ return NULL;
+ type_trans = tr_type_trans;
+ unregister_dev = unregister_trdev;
+ break;
+#endif
+
+#ifdef CONFIG_FDDI
+ case I2O_LAN_FDDI:
+ {
+ int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local);
+
+ dev = (struct net_device *) kmalloc(size, GFP_KERNEL);
+ if (dev == NULL)
+ return NULL;
+ memset((char *)dev, 0, size);
+ dev->priv = (void *)(dev + 1);
+
+ if (dev_alloc_name(dev, "fddi%d") < 0) {
+ printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n");
+ kfree(dev);
+ return NULL;
+ }
+ type_trans = fddi_type_trans;
+ unregister_dev = (void *)unregister_netdevice;
+
+ fddi_setup(dev);
+ register_netdev(dev);
+ }
+ break;
+#endif
+
+#ifdef CONFIG_NET_FC
+ case I2O_LAN_FIBRE_CHANNEL:
+ dev = init_fcdev(NULL, sizeof(struct i2o_lan_local));
+ if (dev == NULL)
+ return NULL;
+ type_trans = NULL;
+/* FIXME: Move fc_type_trans() from drivers/net/fc/iph5526.c to net/802/fc.c
+ * and export it in include/linux/fcdevice.h
+ * type_trans = fc_type_trans;
+ */
+ unregister_dev = (void *)unregister_fcdev;
+ break;
+#endif
+
+ case I2O_LAN_UNKNOWN:
+ default:
+ printk(KERN_ERR "i2o_lan: LAN type 0x%04x not supported.\n",
+ i2o_dev->lct_data.sub_class);


+ return NULL;
+ }
+

+ priv = (struct i2o_lan_local *)dev->priv;
+ priv->i2o_dev = i2o_dev;
+ priv->type_trans = type_trans;
+ priv->sgl_max = (i2o_dev->controller->status_block->inbound_frame_size - 4) / 3;
+ atomic_set(&priv->buckets_out, 0);
+
+ /* Set default values for user configurable parameters */
+ /* Private values are changed via /proc file system */
+
+ priv->max_buckets_out = max_buckets_out;
+ priv->bucket_thresh = bucket_thresh;
+ priv->rx_copybreak = rx_copybreak;
+ priv->tx_batch_mode = tx_batch_mode & 0x03;
+ priv->i2o_event_mask = i2o_event_mask;
+
+ priv->tx_lock = SPIN_LOCK_UNLOCKED;
+ priv->fbl_lock = SPIN_LOCK_UNLOCKED;
+
+ unit++;
+ i2o_landevs[unit] = dev;
+ priv->unit = unit;
+
+ if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
+ 0x0001, 0, &hw_addr, sizeof(hw_addr)) < 0) {
+ printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name);
+ unit--;
+ unregister_dev(dev);
+ kfree(dev);
+ return NULL;
+ }
+ dprintk(KERN_DEBUG "%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+ dev->name, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3],
+ hw_addr[4], hw_addr[5]);
+
+ dev->addr_len = 6;
+ memcpy(dev->dev_addr, hw_addr, 6);
+
+ if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
+ 0x0007, 2, &tx_max_out, sizeof(tx_max_out)) < 0) {
+ printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name);
+ unit--;
+ unregister_dev(dev);
+ kfree(dev);
+ return NULL;
+ }
+ dprintk(KERN_INFO "%s: Max TX Outstanding = %d.\n", dev->name, tx_max_out);
+ priv->tx_max_out = tx_max_out;
+ atomic_set(&priv->tx_out, 0);
+ priv->tx_count = 0;
+
+ INIT_LIST_HEAD(&priv->i2o_batch_send_task.list);
+ priv->i2o_batch_send_task.sync = 0;
+ priv->i2o_batch_send_task.routine = (void *)i2o_lan_batch_send;
+ priv->i2o_batch_send_task.data = (void *)dev;
+
+ dev->open = i2o_lan_open;
+ dev->stop = i2o_lan_close;
+ dev->get_stats = i2o_lan_get_stats;
+ dev->set_multicast_list = i2o_lan_set_multicast_list;
+ dev->tx_timeout = i2o_lan_tx_timeout;
+ dev->watchdog_timeo = I2O_LAN_TX_TIMEOUT;
+
+#ifdef CONFIG_NET_FC
+ if (i2o_dev->lct_data.sub_class == I2O_LAN_FIBRE_CHANNEL)
+ dev->hard_start_xmit = i2o_lan_sdu_send;
+ else
+#endif
+ dev->hard_start_xmit = i2o_lan_packet_send;
+
+ if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET)
+ dev->change_mtu = i2o_lan_change_mtu;
+
+ return dev;
+}
+
+#ifdef MODULE
+#define i2o_lan_init init_module
+#endif
+
+int __init i2o_lan_init(void)
+{
+ struct net_device *dev;
+ int i;
+
+ printk(KERN_INFO "I2O LAN OSM (C) 1999 University of Helsinki.\n");
+
+ /* Module params are used as global defaults for private values */
+
+ if (max_buckets_out > I2O_LAN_MAX_BUCKETS_OUT)
+ max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
+ if (bucket_thresh > max_buckets_out)
+ bucket_thresh = max_buckets_out;
+
+ /* Install handlers for incoming replies */
+
+ if (i2o_install_handler(&i2o_lan_send_handler) < 0) {
+ printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
+ return -EINVAL;
+ }
+ lan_send_context = i2o_lan_send_handler.context;
+
+ if (i2o_install_handler(&i2o_lan_receive_handler) < 0) {
+ printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
+ return -EINVAL;
+ }
+ lan_receive_context = i2o_lan_receive_handler.context;
+
+ if (i2o_install_handler(&i2o_lan_handler) < 0) {
+ printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
+ return -EINVAL;
+ }
+ lan_context = i2o_lan_handler.context;
+
+ for(i=0; i <= MAX_LAN_CARDS; i++)
+ i2o_landevs[i] = NULL;
+
+ for (i=0; i < MAX_I2O_CONTROLLERS; i++) {
+ struct i2o_controller *iop = i2o_find_controller(i);
+ struct i2o_device *i2o_dev;
+
+ if (iop==NULL)
+ continue;
+
+ for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) {
+
+ if (i2o_dev->lct_data.class_id != I2O_CLASS_LAN)
+ continue;
+
+ /* Make sure device not already claimed by an ISM */
+ if (i2o_dev->lct_data.user_tid != 0xFFF)
+ continue;
+
+ if (unit == MAX_LAN_CARDS) {
+ i2o_unlock_controller(iop);
+ printk(KERN_WARNING "i2o_lan: Too many I2O LAN devices.\n");


+ return -EINVAL;
+ }
+

+ dev = i2o_lan_register_device(i2o_dev);
+ if (dev == NULL) {
+ printk(KERN_ERR "i2o_lan: Unable to register I2O LAN device 0x%04x.\n",
+ i2o_dev->lct_data.sub_class);
+ continue;
+ }
+
+ printk(KERN_INFO "%s: I2O LAN device registered, "
+ "subclass = 0x%04x, unit = %d, tid = %d.\n",
+ dev->name, i2o_dev->lct_data.sub_class,
+ ((struct i2o_lan_local *)dev->priv)->unit,
+ i2o_dev->lct_data.tid);
+ }
+
+ i2o_unlock_controller(iop);
+ }
+
+ dprintk(KERN_INFO "%d I2O LAN devices found and registered.\n", unit+1);


+
+ return 0;
+}
+

+#ifdef MODULE
+
+void cleanup_module(void)

+{
+ int i;
+

+ for (i = 0; i <= unit; i++) {
+ struct net_device *dev = i2o_landevs[i];
+ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
+ struct i2o_device *i2o_dev = priv->i2o_dev;
+
+ switch (i2o_dev->lct_data.sub_class) {
+ case I2O_LAN_ETHERNET:
+ unregister_netdev(dev);
+ break;
+#ifdef CONFIG_FDDI
+ case I2O_LAN_FDDI:
+ unregister_netdevice(dev);
+ break;
+#endif
+#ifdef CONFIG_TR
+ case I2O_LAN_TR:
+ unregister_trdev(dev);
+ break;
+#endif
+#ifdef CONFIG_NET_FC
+ case I2O_LAN_FIBRE_CHANNEL:
+ unregister_fcdev(dev);
+ break;
+#endif
+ default:
+ printk(KERN_WARNING "%s: Spurious I2O LAN subclass 0x%08x.\n",
+ dev->name, i2o_dev->lct_data.sub_class);
+ }
+
+ dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n",
+ dev->name);
+ kfree(dev);
+ }
+
+ i2o_remove_handler(&i2o_lan_handler);
+ i2o_remove_handler(&i2o_lan_send_handler);
+ i2o_remove_handler(&i2o_lan_receive_handler);
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("University of Helsinki, Department of Computer Science");
+MODULE_DESCRIPTION("I2O Lan OSM");


+MODULE_LICENSE("GPL");
+
+

+MODULE_PARM(max_buckets_out, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
+MODULE_PARM_DESC(max_buckets_out, "Total number of buckets to post (1-)");
+MODULE_PARM(bucket_thresh, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
+MODULE_PARM_DESC(bucket_thresh, "Bucket post threshold (1-)");
+MODULE_PARM(rx_copybreak, "1-" "i");
+MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy only small frames (1-)");
+MODULE_PARM(tx_batch_mode, "0-2" "i");
+MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");
+
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_lan.h linux/drivers/message/i2o/i2o_lan.h
--- v2.4.12/linux/drivers/message/i2o/i2o_lan.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_lan.h Mon Dec 11 13:20:00 2000
@@ -0,0 +1,159 @@
+/*
+ * i2o_lan.h I2O LAN Class definitions
+ *
+ * I2O LAN CLASS OSM May 26th 2000
+ *
+ * (C) Copyright 1999, 2000 University of Helsinki,
+ * Department of Computer Science
+ *
+ * This code is still under development / test.
+ *
+ * Author: Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>


+ * Juha Sievänen <Juha.S...@cs.Helsinki.FI>

+ * Taneli Vähäkangas <Taneli.V...@cs.Helsinki.FI>
+ */
+
+#ifndef _I2O_LAN_H
+#define _I2O_LAN_H
+
+/* Default values for tunable parameters first */
+
+#define I2O_LAN_MAX_BUCKETS_OUT 96
+#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
+#define I2O_LAN_RX_COPYBREAK 200
+#define I2O_LAN_TX_TIMEOUT (1*HZ)
+#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */
+#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */
+
+/* LAN types */
+#define I2O_LAN_ETHERNET 0x0030
+#define I2O_LAN_100VG 0x0040
+#define I2O_LAN_TR 0x0050
+#define I2O_LAN_FDDI 0x0060
+#define I2O_LAN_FIBRE_CHANNEL 0x0070
+#define I2O_LAN_UNKNOWN 0x00000000
+
+/* Connector types */
+
+/* Ethernet */
+#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001
+#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002
+#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003
+#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004
+#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005
+#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006
+#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007
+#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008
+#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009
+#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A
+#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B
+#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C
+#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D
+#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E
+#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F
+#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010
+
+/* AnyLAN */
+#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001
+#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002
+
+/* Token Ring */
+#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001
+#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002
+
+/* FDDI */
+#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001
+
+/* Fibre Channel */
+#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001
+#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002
+#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003
+#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004
+
+#define I2O_LAN_EMULATION 0x00000F00
+#define I2O_LAN_OTHER 0x00000F01
+#define I2O_LAN_DEFAULT 0xFFFFFFFF
+
+/* LAN class functions */
+
+#define LAN_PACKET_SEND 0x3B
+#define LAN_SDU_SEND 0x3D
+#define LAN_RECEIVE_POST 0x3E
+#define LAN_RESET 0x35
+#define LAN_SUSPEND 0x37
+
+/* LAN DetailedStatusCode defines */
+#define I2O_LAN_DSC_SUCCESS 0x00
+#define I2O_LAN_DSC_DEVICE_FAILURE 0x01
+#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02
+#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03
+#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04
+#define I2O_LAN_DSC_RECEIVE_ERROR 0x05
+#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06
+#define I2O_LAN_DSC_DMA_ERROR 0x07
+#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08
+#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09
+#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A
+#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B
+#define I2O_LAN_DSC_CANCELED 0x0C
+#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D
+#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E
+#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F
+#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10
+#define I2O_LAN_DSC_SUSPENDED 0x11
+
+struct i2o_packet_info {
+ u32 offset : 24;
+ u32 flags : 8;
+ u32 len : 24;
+ u32 status : 8;
+};
+
+struct i2o_bucket_descriptor {
+ u32 context; /* FIXME: 64bit support */
+ struct i2o_packet_info packet_info[1];
+};
+
+/* Event Indicator Mask Flags for LAN OSM */
+
+#define I2O_LAN_EVT_LINK_DOWN 0x01
+#define I2O_LAN_EVT_LINK_UP 0x02
+#define I2O_LAN_EVT_MEDIA_CHANGE 0x04
+
+#include <linux/netdevice.h>
+#include <linux/fddidevice.h>
+
+struct i2o_lan_local {
+ u8 unit;
+ struct i2o_device *i2o_dev;
+
+ struct fddi_statistics stats; /* see also struct net_device_stats */
+ unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
+ atomic_t buckets_out; /* nbr of unused buckets on DDM */
+ atomic_t tx_out; /* outstanding TXes */
+ u8 tx_count; /* packets in one TX message frame */
+ u16 tx_max_out; /* DDM's Tx queue len */
+ u8 sgl_max; /* max SGLs in one message frame */
+ u32 m; /* IOP address of the batch msg frame */
+
+ struct tq_struct i2o_batch_send_task;
+ int send_active;
+ struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */
+ int i2o_fbl_tail;
+ spinlock_t fbl_lock;
+
+ spinlock_t tx_lock;
+
+ u32 max_size_mc_table; /* max number of multicast addresses */
+
+ /* LAN OSM configurable parameters are here: */
+
+ u16 max_buckets_out; /* max nbr of buckets to send to DDM */
+ u16 bucket_thresh; /* send more when this many used */
+ u16 rx_copybreak;
+
+ u8 tx_batch_mode; /* Set when using batch mode sends */
+ u32 i2o_event_mask; /* To turn on interesting event flags */
+};
+
+#endif /* _I2O_LAN_H */
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_pci.c linux/drivers/message/i2o/i2o_pci.c
--- v2.4.12/linux/drivers/message/i2o/i2o_pci.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_pci.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,391 @@
+/*
+ * Find I2O capable controllers on the PCI bus, and register/install
+ * them with the I2O layer


+ *
+ * (C) Copyright 1999 Red Hat Software
+ *
+ * Written by Alan Cox, Building Number Three Ltd

+ * Modified by Deepak Saxena <dee...@plexity.net>
+ * Modified by Boji T Kannanthanam <boji.t.ka...@intel.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.
+ *

+ * TODO:
+ * Support polled I2O PCI controllers.

+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>

+#include <linux/i2o.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>

+#include <asm/io.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif // CONFIG_MTRR
+
+#ifdef MODULE
+/*
+ * Core function table


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 27'
echo 'File patch-2.4.13 is continued in part 28'
echo "28" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:58 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part28

#!/bin/sh -x
# this is part 28 of a 53 - part archive


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

if test "$Scheck" != 28; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ * See <include/linux/i2o.h> for an explanation
+ */
+static struct i2o_core_func_table *core;
+
+/* Core attach function */


+extern int i2o_pci_core_attach(struct i2o_core_func_table *);
+extern void i2o_pci_core_detach(void);

+#endif /* MODULE */
+
+/*
+ * Free bus specific resources
+ */
+static void i2o_pci_dispose(struct i2o_controller *c)
+{
+ I2O_IRQ_WRITE32(c,0xFFFFFFFF);
+ if(c->bus.pci.irq > 0)
+ free_irq(c->bus.pci.irq, c);
+ iounmap(((u8 *)c->post_port)-0x40);
+
+#ifdef CONFIG_MTRR
+ if(c->bus.pci.mtrr_reg0 > 0)
+ mtrr_del(c->bus.pci.mtrr_reg0, 0, 0);
+ if(c->bus.pci.mtrr_reg1 > 0)
+ mtrr_del(c->bus.pci.mtrr_reg1, 0, 0);
+#endif
+}
+
+/*
+ * No real bus specific handling yet (note that later we will
+ * need to 'steal' PCI devices on i960 mainboards)
+ */
+
+static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
+{
+ MOD_INC_USE_COUNT;


+ return 0;
+}
+

+static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev)
+{
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+
+/*

+ * Bus specific enable/disable functions
+ */
+static void i2o_pci_enable(struct i2o_controller *c)
+{
+ I2O_IRQ_WRITE32(c, 0);
+ c->enabled = 1;
+}
+
+static void i2o_pci_disable(struct i2o_controller *c)
+{
+ I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
+ c->enabled = 0;
+}
+
+/*
+ * Bus specific interrupt handler
+ */
+
+static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
+{
+ struct i2o_controller *c = dev_id;
+#ifdef MODULE
+ core->run_queue(c);
+#else
+ i2o_run_queue(c);
+#endif /* MODULE */
+}
+
+/*
+ * Install a PCI (or in theory AGP) i2o controller
+ *
+ * TODO: Add support for polled controllers
+ */
+int __init i2o_pci_install(struct pci_dev *dev)
+{
+ struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
+ GFP_KERNEL);
+ u8 *mem;
+ u32 memptr = 0;
+ u32 size;


+
+ int i;
+

+ if(c==NULL)
+ {
+ printk(KERN_ERR "i2o: Insufficient memory to add controller.\n");
+ return -ENOMEM;
+ }
+ memset(c, 0, sizeof(*c));
+
+ for(i=0; i<6; i++)
+ {
+ /* Skip I/O spaces */
+ if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+ {
+ memptr = pci_resource_start(dev, i);


+ break;
+ }
+ }
+

+ if(i==6)
+ {
+ printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+ kfree(c);


+ return -EINVAL;
+ }
+

+ size = dev->resource[i].end-dev->resource[i].start+1;
+ /* Map the I2O controller */
+
+ printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
+ mem = ioremap(memptr, size);
+ if(mem==NULL)
+ {
+ printk(KERN_ERR "i2o: Unable to map controller.\n");
+ kfree(c);


+ return -EINVAL;
+ }
+

+ c->bus.pci.irq = -1;
+ c->bus.pci.queue_buggy = 0;
+ c->bus.pci.dpt = 0;
+ c->bus.pci.short_req = 0;
+ c->pdev = dev;
+
+ c->irq_mask = (volatile u32 *)(mem+0x34);
+ c->post_port = (volatile u32 *)(mem+0x40);
+ c->reply_port = (volatile u32 *)(mem+0x44);
+
+ c->mem_phys = memptr;
+ c->mem_offset = (u32)mem;
+ c->destructor = i2o_pci_dispose;
+
+ c->bind = i2o_pci_bind;
+ c->unbind = i2o_pci_unbind;
+ c->bus_enable = i2o_pci_enable;
+ c->bus_disable = i2o_pci_disable;
+
+ c->type = I2O_TYPE_PCI;
+
+ /*
+ * Cards that fall apart if you hit them with large I/O
+ * loads...
+ */
+
+ if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
+ {
+ c->bus.pci.short_req=1;
+ printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
+ }
+ if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
+ {
+ c->bus.pci.queue_buggy=1;
+ printk(KERN_INFO "I2O: Promise workarounds activated.\n");
+ }
+
+ /*
+ * Cards that go bananas if you quiesce them before you reset
+ * them
+ */
+
+ if(dev->vendor == PCI_VENDOR_ID_DPT)
+ c->bus.pci.dpt=1;
+
+ /*
+ * Enable Write Combining MTRR for IOP's memory region
+ */
+#ifdef CONFIG_MTRR
+ c->bus.pci.mtrr_reg0 =
+ mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+/*
+* If it is an INTEL i960 I/O processor then set the first 64K to Uncacheable
+* since the region contains the Messaging unit which shouldn't be cached.
+*/
+ c->bus.pci.mtrr_reg1 = -1;
+ if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
+ {
+ printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n");
+ c->bus.pci.mtrr_reg1 = mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+ if(c->bus.pci.mtrr_reg1< 0)
+ {
+ printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
+ mtrr_del(c->bus.pci.mtrr_reg0, c->mem_phys, size);
+ c->bus.pci.mtrr_reg0 = -1;
+ }
+ }
+
+#endif
+
+ I2O_IRQ_WRITE32(c,0xFFFFFFFF);
+
+#ifdef MODULE
+ i = core->install(c);
+#else
+ i = i2o_install_controller(c);


+#endif /* MODULE */
+

+ if(i<0)
+ {
+ printk(KERN_ERR "i2o: Unable to install controller.\n");
+ kfree(c);
+ iounmap(mem);


+ return i;
+ }
+

+ c->bus.pci.irq = dev->irq;
+ if(c->bus.pci.irq)
+ {
+ i=request_irq(dev->irq, i2o_pci_interrupt, SA_SHIRQ,
+ c->name, c);
+ if(i<0)
+ {
+ printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
+ c->name, dev->irq);
+ c->bus.pci.irq = -1;
+#ifdef MODULE
+ core->delete(c);
+#else
+ i2o_delete_controller(c);
+#endif /* MODULE */
+ iounmap(mem);
+ return -EBUSY;
+ }
+ }
+
+ printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq);
+ I2O_IRQ_WRITE32(c,0x0);
+ c->enabled = 1;


+ return 0;
+}
+

+int __init i2o_pci_scan(void)
+{
+ struct pci_dev *dev;
+ int count=0;
+
+ printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
+
+ pci_for_each_dev(dev)
+ {
+ if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+ continue;
+ if(dev->vendor == PCI_VENDOR_ID_DPT)
+ {
+ if(dev->device == 0xA501 || dev->device == 0xA511)
+ {
+ printk(KERN_INFO "i2o: Skipping Adaptec/DPT I2O raid with preferred native driver.\n");
+ continue;
+ }
+ }
+ if((dev->class&0xFF)>1)
+ {
+ printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
+ continue;
+ }
+ if (pci_enable_device(dev))
+ continue;
+ printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n",
+ dev->bus->number, dev->devfn);
+ pci_set_master(dev);
+ if(i2o_pci_install(dev)==0)
+ count++;
+ }
+ if(count)
+ printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count,
+ count==1?"":"s");
+ return count?count:-ENODEV;
+}
+
+#ifdef I2O_HOTPLUG_SUPPORT
+/*
+ * Activate a newly found PCI I2O controller
+ * Not used now, but will be needed in future for
+ * hot plug PCI support
+ */
+static void i2o_pci_activate(i2o_controller * c)
+{
+ int i=0;


+ struct i2o_controller *c;
+

+ if(c->type == I2O_TYPE_PCI)
+ {
+ I2O_IRQ_WRITE32(c,0);
+#ifdef MODULE
+ if(core->activate(c))
+#else
+ if(i2o_activate_controller(c))
+#endif /* MODULE */
+ {
+ printk("%s: Failed to initialize.\n", c->name);
+#ifdef MODULE
+ core->unlock(c);
+ core->delete(c);
+#else
+ i2o_unlock_controller(c);
+ i2o_delete_controller(c);
+#endif


+ continue;
+ }
+ }
+}

+#endif // I2O_HOTPLUG_SUPPORT
+
+#ifdef MODULE
+
+int i2o_pci_core_attach(struct i2o_core_func_table *table)
+{
+ MOD_INC_USE_COUNT;
+
+ core = table;
+
+ return i2o_pci_scan();
+}
+
+void i2o_pci_core_detach(void)
+{
+ core = NULL;


+
+ MOD_DEC_USE_COUNT;
+}
+

+int init_module(void)
+{
+ printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
+
+ core = NULL;


+
+ return 0;
+
+}
+
+void cleanup_module(void)
+{
+}

+
+EXPORT_SYMBOL(i2o_pci_core_attach);
+EXPORT_SYMBOL(i2o_pci_core_detach);


+
+MODULE_AUTHOR("Red Hat Software");

+MODULE_DESCRIPTION("I2O PCI Interface");


+MODULE_LICENSE("GPL");
+
+

+#else
+void __init i2o_pci_init(void)
+{
+ printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
+ i2o_pci_scan();
+}
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_proc.c linux/drivers/message/i2o/i2o_proc.c
--- v2.4.12/linux/drivers/message/i2o/i2o_proc.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_proc.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,3377 @@
+/*
+ * procfs handler for Linux I2O subsystem
+ *
+ * (c) Copyright 1999 Deepak Saxena
+ *
+ * Originally written by Deepak Saxena(dee...@plexity.net)
+ *
+ * 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 is an initial test release. The code is based on the design
+ * of the ide procfs system (drivers/block/ide-proc.c). Some code
+ * taken from i2o-core module by Alan Cox.
+ *
+ * DISCLAIMER: This code is still under development/test and may cause
+ * your system to behave unpredictably. Use at your own discretion.
+ *
+ * LAN entries by Juha Sievänen (Juha.S...@cs.Helsinki.FI),
+ * Auvo Häkkinen (Auvo.H...@cs.Helsinki.FI)
+ * University of Helsinki, Department of Computer Science
+ */
+
+/*
+ * set tabstop=3
+ */
+
+/*
+ * TODO List
+ *
+ * - Add support for any version 2.0 spec changes once 2.0 IRTOS is
+ * is available to test with
+ * - Clean up code to use official structure definitions
+ */
+
+// FIXME!
+#define FMT_U64_HEX "0x%08x%08x"
+#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64))
+
+#include <linux/types.h>


+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/i2o.h>

+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>


+
+#include <asm/io.h>
+#include <asm/uaccess.h>

+#include <asm/byteorder.h>
+
+#include "i2o_lan.h"
+
+/*
+ * Structure used to define /proc entries
+ */
+typedef struct _i2o_proc_entry_t
+{
+ char *name; /* entry name */
+ mode_t mode; /* mode */
+ read_proc_t *read_proc; /* read func */
+ write_proc_t *write_proc; /* write func */
+} i2o_proc_entry;
+
+// #define DRIVERDEBUG
+
+static int i2o_proc_read_lct(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_hrt(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_status(char *, char **, off_t, int, int *, void *);
+
+static int i2o_proc_read_hw(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_ddm_table(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_driver_store(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_drivers_stored(char *, char **, off_t, int, int *, void *);
+
+static int i2o_proc_read_groups(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_phys_device(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_claimed(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_users(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_priv_msgs(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_authorized_users(char *, char **, off_t, int, int *, void *);
+
+static int i2o_proc_read_dev_name(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_dev_identity(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_ddm_identity(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_uinfo(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_sgl_limits(char *, char **, off_t, int, int *, void *);
+
+static int i2o_proc_read_sensors(char *, char **, off_t, int, int *, void *);
+
+static int print_serial_number(char *, int, u8 *, int);
+
+static int i2o_proc_create_entries(void *, i2o_proc_entry *,
+ struct proc_dir_entry *);
+static void i2o_proc_remove_entries(i2o_proc_entry *, struct proc_dir_entry *);
+static int i2o_proc_add_controller(struct i2o_controller *,
+ struct proc_dir_entry * );
+static void i2o_proc_remove_controller(struct i2o_controller *,
+ struct proc_dir_entry * );
+static void i2o_proc_add_device(struct i2o_device *, struct proc_dir_entry *);
+static void i2o_proc_remove_device(struct i2o_device *);
+static int create_i2o_procfs(void);
+static int destroy_i2o_procfs(void);
+static void i2o_proc_new_dev(struct i2o_controller *, struct i2o_device *);
+static void i2o_proc_dev_del(struct i2o_controller *, struct i2o_device *);
+
+static int i2o_proc_read_lan_dev_info(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_mac_addr(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_mcast_addr(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_batch_control(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_operation(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_media_operation(char *, char **, off_t, int,
+ int *, void *);
+static int i2o_proc_read_lan_alt_addr(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_tx_info(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_rx_info(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_hist_stats(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_eth_stats(char *, char **, off_t, int,
+ int *, void *);
+static int i2o_proc_read_lan_tr_stats(char *, char **, off_t, int, int *,
+ void *);
+static int i2o_proc_read_lan_fddi_stats(char *, char **, off_t, int, int *,
+ void *);
+
+static struct proc_dir_entry *i2o_proc_dir_root;
+
+/*
+ * I2O OSM descriptor
+ */
+static struct i2o_handler i2o_proc_handler =
+{
+ NULL,
+ i2o_proc_new_dev,
+ i2o_proc_dev_del,
+ NULL,
+ "I2O procfs Layer",


+ 0,
+ 0xffffffff // All classes

+};
+
+/*
+ * IOP specific entries...write field just in case someone
+ * ever wants one.
+ */
+static i2o_proc_entry generic_iop_entries[] =
+{
+ {"hrt", S_IFREG|S_IRUGO, i2o_proc_read_hrt, NULL},
+ {"lct", S_IFREG|S_IRUGO, i2o_proc_read_lct, NULL},
+ {"status", S_IFREG|S_IRUGO, i2o_proc_read_status, NULL},
+ {"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL},
+ {"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL},
+ {"driver_store", S_IFREG|S_IRUGO, i2o_proc_read_driver_store, NULL},
+ {"drivers_stored", S_IFREG|S_IRUGO, i2o_proc_read_drivers_stored, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+/*
+ * Device specific entries
+ */
+static i2o_proc_entry generic_dev_entries[] =
+{
+ {"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL},
+ {"phys_dev", S_IFREG|S_IRUGO, i2o_proc_read_phys_device, NULL},
+ {"claimed", S_IFREG|S_IRUGO, i2o_proc_read_claimed, NULL},
+ {"users", S_IFREG|S_IRUGO, i2o_proc_read_users, NULL},
+ {"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL},
+ {"authorized_users", S_IFREG|S_IRUGO, i2o_proc_read_authorized_users, NULL},
+ {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev_identity, NULL},
+ {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm_identity, NULL},
+ {"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL},
+ {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL},
+ {"sensors", S_IFREG|S_IRUGO, i2o_proc_read_sensors, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+/*
+ * Storage unit specific entries (SCSI Periph, BS) with device names
+ */
+static i2o_proc_entry rbs_dev_entries[] =
+{
+ {"dev_name", S_IFREG|S_IRUGO, i2o_proc_read_dev_name, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+#define SCSI_TABLE_SIZE 13
+static char *scsi_devices[] =
+{
+ "Direct-Access Read/Write",
+ "Sequential-Access Storage",
+ "Printer",
+ "Processor",
+ "WORM Device",
+ "CD-ROM Device",
+ "Scanner Device",
+ "Optical Memory Device",
+ "Medium Changer Device",
+ "Communications Device",
+ "Graphics Art Pre-Press Device",
+ "Graphics Art Pre-Press Device",
+ "Array Controller Device"
+};
+
+/* private */
+
+/*
+ * Generic LAN specific entries
+ *
+ * Should groups with r/w entries have their own subdirectory?
+ *
+ */
+static i2o_proc_entry lan_entries[] =
+{
+ {"lan_dev_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_dev_info, NULL},
+ {"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL},
+ {"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR,
+ i2o_proc_read_lan_mcast_addr, NULL},
+ {"lan_batch_ctrl", S_IFREG|S_IRUGO|S_IWUSR,
+ i2o_proc_read_lan_batch_control, NULL},
+ {"lan_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_operation, NULL},
+ {"lan_media_operation", S_IFREG|S_IRUGO,
+ i2o_proc_read_lan_media_operation, NULL},
+ {"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL},
+ {"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL},
+ {"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL},
+
+ {"lan_hist_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+/*
+ * Port specific LAN entries
+ *
+ */
+static i2o_proc_entry lan_eth_entries[] =
+{
+ {"lan_eth_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+static i2o_proc_entry lan_tr_entries[] =
+{
+ {"lan_tr_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_tr_stats, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+static i2o_proc_entry lan_fddi_entries[] =
+{
+ {"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL},
+ {NULL, 0, NULL, NULL}
+};
+
+
+static char *chtostr(u8 *chars, int n)
+{
+ char tmp[256];
+ tmp[0] = 0;
+ return strncat(tmp, (char *)chars, n);
+}
+
+static int i2o_report_query_status(char *buf, int block_status, char *group)
+{
+ switch (block_status)
+ {
+ case -ETIMEDOUT:
+ return sprintf(buf, "Timeout reading group %s.\n",group);
+ case -ENOMEM:
+ return sprintf(buf, "No free memory to read the table.\n");
+ case -I2O_PARAMS_STATUS_INVALID_GROUP_ID:
+ return sprintf(buf, "Group %s not supported.\n", group);
+ default:
+ return sprintf(buf, "Error reading group %s. BlockStatus 0x%02X\n",
+ group, -block_status);
+ }
+}
+
+static char* bus_strings[] =
+{
+ "Local Bus",
+ "ISA",
+ "EISA",
+ "MCA",
+ "PCI",
+ "PCMCIA",
+ "NUBUS",
+ "CARDBUS"
+};
+
+static spinlock_t i2o_proc_lock = SPIN_LOCK_UNLOCKED;
+
+int i2o_proc_read_hrt(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller *)data;
+ i2o_hrt *hrt = (i2o_hrt *)c->hrt;
+ u32 bus;
+ int len, i;
+
+ spin_lock(&i2o_proc_lock);


+
+ len = 0;
+

+ if(hrt->hrt_version)
+ {
+ len += sprintf(buf+len,
+ "HRT table for controller is too new a version.\n");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ if((hrt->num_entries * hrt->entry_len + 8) > 2048) {
+ printk(KERN_WARNING "i2o_proc: HRT does not fit into buffer\n");
+ len += sprintf(buf+len,
+ "HRT table too big to fit in buffer.\n");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "HRT has %d entries of %d bytes each.\n",
+ hrt->num_entries, hrt->entry_len << 2);
+
+ for(i = 0; i < hrt->num_entries && len < count; i++)
+ {
+ len += sprintf(buf+len, "Entry %d:\n", i);
+ len += sprintf(buf+len, " Adapter ID: %0#10x\n",
+ hrt->hrt_entry[i].adapter_id);
+ len += sprintf(buf+len, " Controlling tid: %0#6x\n",
+ hrt->hrt_entry[i].parent_tid);
+
+ if(hrt->hrt_entry[i].bus_type != 0x80)
+ {
+ bus = hrt->hrt_entry[i].bus_type;
+ len += sprintf(buf+len, " %s Information\n", bus_strings[bus]);
+
+ switch(bus)
+ {
+ case I2O_BUS_LOCAL:
+ len += sprintf(buf+len, " IOBase: %0#6x,",
+ hrt->hrt_entry[i].bus.local_bus.LbBaseIOPort);
+ len += sprintf(buf+len, " MemoryBase: %0#10x\n",
+ hrt->hrt_entry[i].bus.local_bus.LbBaseMemoryAddress);
+ break;
+
+ case I2O_BUS_ISA:
+ len += sprintf(buf+len, " IOBase: %0#6x,",
+ hrt->hrt_entry[i].bus.isa_bus.IsaBaseIOPort);
+ len += sprintf(buf+len, " MemoryBase: %0#10x,",
+ hrt->hrt_entry[i].bus.isa_bus.IsaBaseMemoryAddress);
+ len += sprintf(buf+len, " CSN: %0#4x,",
+ hrt->hrt_entry[i].bus.isa_bus.CSN);
+ break;
+
+ case I2O_BUS_EISA:
+ len += sprintf(buf+len, " IOBase: %0#6x,",
+ hrt->hrt_entry[i].bus.eisa_bus.EisaBaseIOPort);
+ len += sprintf(buf+len, " MemoryBase: %0#10x,",
+ hrt->hrt_entry[i].bus.eisa_bus.EisaBaseMemoryAddress);
+ len += sprintf(buf+len, " Slot: %0#4x,",
+ hrt->hrt_entry[i].bus.eisa_bus.EisaSlotNumber);
+ break;
+
+ case I2O_BUS_MCA:
+ len += sprintf(buf+len, " IOBase: %0#6x,",
+ hrt->hrt_entry[i].bus.mca_bus.McaBaseIOPort);
+ len += sprintf(buf+len, " MemoryBase: %0#10x,",
+ hrt->hrt_entry[i].bus.mca_bus.McaBaseMemoryAddress);
+ len += sprintf(buf+len, " Slot: %0#4x,",
+ hrt->hrt_entry[i].bus.mca_bus.McaSlotNumber);
+ break;
+
+ case I2O_BUS_PCI:
+ len += sprintf(buf+len, " Bus: %0#4x",
+ hrt->hrt_entry[i].bus.pci_bus.PciBusNumber);
+ len += sprintf(buf+len, " Dev: %0#4x",
+ hrt->hrt_entry[i].bus.pci_bus.PciDeviceNumber);
+ len += sprintf(buf+len, " Func: %0#4x",
+ hrt->hrt_entry[i].bus.pci_bus.PciFunctionNumber);
+ len += sprintf(buf+len, " Vendor: %0#6x",
+ hrt->hrt_entry[i].bus.pci_bus.PciVendorID);
+ len += sprintf(buf+len, " Device: %0#6x\n",
+ hrt->hrt_entry[i].bus.pci_bus.PciDeviceID);


+ break;
+
+ default:

+ len += sprintf(buf+len, " Unsupported Bus Type\n");
+ }
+ }
+ else
+ len += sprintf(buf+len, " Unknown Bus Type\n");
+ }
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+int i2o_proc_read_lct(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ i2o_lct *lct = (i2o_lct *)c->lct;
+ int entries;
+ int i;
+
+#define BUS_TABLE_SIZE 3
+ static char *bus_ports[] =
+ {
+ "Generic Bus",
+ "SCSI Bus",
+ "Fibre Channel Bus"
+ };
+
+ spin_lock(&i2o_proc_lock);


+ len = 0;
+

+ entries = (lct->table_size - 3)/9;
+
+ len += sprintf(buf, "LCT contains %d %s\n", entries,
+ entries == 1 ? "entry" : "entries");
+ if(lct->boot_tid)
+ len += sprintf(buf+len, "Boot Device @ ID %d\n", lct->boot_tid);
+
+ len +=
+ sprintf(buf+len, "Current Change Indicator: %#10x\n", lct->change_ind);
+
+ for(i = 0; i < entries; i++)
+ {
+ len += sprintf(buf+len, "Entry %d\n", i);
+ len += sprintf(buf+len, " Class, SubClass : %s", i2o_get_class_name(lct->lct_entry[i].class_id));
+
+ /*
+ * Classes which we'll print subclass info for
+ */
+ switch(lct->lct_entry[i].class_id & 0xFFF)
+ {
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ switch(lct->lct_entry[i].sub_class)
+ {
+ case 0x00:
+ len += sprintf(buf+len, ", Direct-Access Read/Write");
+ break;
+
+ case 0x04:
+ len += sprintf(buf+len, ", WORM Drive");
+ break;
+
+ case 0x05:
+ len += sprintf(buf+len, ", CD-ROM Drive");
+ break;
+
+ case 0x07:
+ len += sprintf(buf+len, ", Optical Memory Device");
+ break;
+
+ default:
+ len += sprintf(buf+len, ", Unknown (0x%02x)",
+ lct->lct_entry[i].sub_class);
+ break;
+ }
+ break;
+
+ case I2O_CLASS_LAN:
+ switch(lct->lct_entry[i].sub_class & 0xFF)
+ {
+ case 0x30:
+ len += sprintf(buf+len, ", Ethernet");
+ break;
+
+ case 0x40:
+ len += sprintf(buf+len, ", 100base VG");
+ break;
+
+ case 0x50:
+ len += sprintf(buf+len, ", IEEE 802.5/Token-Ring");
+ break;
+
+ case 0x60:
+ len += sprintf(buf+len, ", ANSI X3T9.5 FDDI");
+ break;
+
+ case 0x70:
+ len += sprintf(buf+len, ", Fibre Channel");
+ break;
+
+ default:
+ len += sprintf(buf+len, ", Unknown Sub-Class (0x%02x)",
+ lct->lct_entry[i].sub_class & 0xFF);
+ break;
+ }
+ break;
+
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ if(lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE)
+ len += sprintf(buf+len, ", %s",
+ scsi_devices[lct->lct_entry[i].sub_class]);
+ else
+ len += sprintf(buf+len, ", Unknown Device Type");
+ break;
+
+ case I2O_CLASS_BUS_ADAPTER_PORT:
+ if(lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
+ len += sprintf(buf+len, ", %s",
+ bus_ports[lct->lct_entry[i].sub_class]);
+ else
+ len += sprintf(buf+len, ", Unknown Bus Type");
+ break;
+ }
+ len += sprintf(buf+len, "\n");
+
+ len += sprintf(buf+len, " Local TID : 0x%03x\n", lct->lct_entry[i].tid);
+ len += sprintf(buf+len, " User TID : 0x%03x\n", lct->lct_entry[i].user_tid);
+ len += sprintf(buf+len, " Parent TID : 0x%03x\n",
+ lct->lct_entry[i].parent_tid);
+ len += sprintf(buf+len, " Identity Tag : 0x%x%x%x%x%x%x%x%x\n",
+ lct->lct_entry[i].identity_tag[0],
+ lct->lct_entry[i].identity_tag[1],
+ lct->lct_entry[i].identity_tag[2],
+ lct->lct_entry[i].identity_tag[3],
+ lct->lct_entry[i].identity_tag[4],
+ lct->lct_entry[i].identity_tag[5],
+ lct->lct_entry[i].identity_tag[6],
+ lct->lct_entry[i].identity_tag[7]);
+ len += sprintf(buf+len, " Change Indicator : %0#10x\n",
+ lct->lct_entry[i].change_ind);
+ len += sprintf(buf+len, " Event Capab Mask : %0#10x\n",
+ lct->lct_entry[i].device_flags);
+ }
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+int i2o_proc_read_status(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ char prodstr[25];
+ int version;
+
+ spin_lock(&i2o_proc_lock);


+ len = 0;
+

+ i2o_status_get(c); // reread the status block
+
+ len += sprintf(buf+len,"Organization ID : %0#6x\n",
+ c->status_block->org_id);
+
+ version = c->status_block->i2o_version;
+
+/* FIXME for Spec 2.0
+ if (version == 0x02) {
+ len += sprintf(buf+len,"Lowest I2O version supported: ");
+ switch(workspace[2]) {
+ case 0x00:
+ len += sprintf(buf+len,"1.0\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len,"1.5\n");
+ break;
+ case 0x02:
+ len += sprintf(buf+len,"2.0\n");
+ break;
+ }
+
+ len += sprintf(buf+len, "Highest I2O version supported: ");
+ switch(workspace[3]) {
+ case 0x00:
+ len += sprintf(buf+len,"1.0\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len,"1.5\n");
+ break;
+ case 0x02:
+ len += sprintf(buf+len,"2.0\n");
+ break;
+ }
+ }
+*/
+ len += sprintf(buf+len,"IOP ID : %0#5x\n",
+ c->status_block->iop_id);
+ len += sprintf(buf+len,"Host Unit ID : %0#6x\n",
+ c->status_block->host_unit_id);
+ len += sprintf(buf+len,"Segment Number : %0#5x\n",
+ c->status_block->segment_number);
+
+ len += sprintf(buf+len, "I2O version : ");
+ switch (version) {
+ case 0x00:
+ len += sprintf(buf+len,"1.0\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len,"1.5\n");
+ break;
+ case 0x02:
+ len += sprintf(buf+len,"2.0\n");
+ break;
+ default:
+ len += sprintf(buf+len,"Unknown version\n");
+ }
+
+ len += sprintf(buf+len, "IOP State : ");


+ switch (c->status_block->iop_state) {
+ case 0x01:

+ len += sprintf(buf+len,"INIT\n");
+ break;
+
+ case 0x02:
+ len += sprintf(buf+len,"RESET\n");
+ break;
+
+ case 0x04:
+ len += sprintf(buf+len,"HOLD\n");
+ break;
+
+ case 0x05:
+ len += sprintf(buf+len,"READY\n");
+ break;
+
+ case 0x08:
+ len += sprintf(buf+len,"OPERATIONAL\n");
+ break;
+
+ case 0x10:
+ len += sprintf(buf+len,"FAILED\n");
+ break;
+
+ case 0x11:
+ len += sprintf(buf+len,"FAULTED\n");
+ break;
+
+ default:
+ len += sprintf(buf+len,"Unknown\n");
+ break;
+ }
+
+ len += sprintf(buf+len,"Messenger Type : ");
+ switch (c->status_block->msg_type) {
+ case 0x00:
+ len += sprintf(buf+len,"Memory mapped\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len,"Memory mapped only\n");
+ break;
+ case 0x02:
+ len += sprintf(buf+len,"Remote only\n");
+ break;
+ case 0x03:
+ len += sprintf(buf+len,"Memory mapped and remote\n");
+ break;
+ default:
+ len += sprintf(buf+len,"Unknown\n");
+ }
+
+ len += sprintf(buf+len,"Inbound Frame Size : %d bytes\n",
+ c->status_block->inbound_frame_size<<2);
+ len += sprintf(buf+len,"Max Inbound Frames : %d\n",
+ c->status_block->max_inbound_frames);
+ len += sprintf(buf+len,"Current Inbound Frames : %d\n",
+ c->status_block->cur_inbound_frames);
+ len += sprintf(buf+len,"Max Outbound Frames : %d\n",
+ c->status_block->max_outbound_frames);
+
+ /* Spec doesn't say if NULL terminated or not... */
+ memcpy(prodstr, c->status_block->product_id, 24);
+ prodstr[24] = '\0';
+ len += sprintf(buf+len,"Product ID : %s\n", prodstr);
+ len += sprintf(buf+len,"Expected LCT Size : %d bytes\n",
+ c->status_block->expected_lct_size);
+
+ len += sprintf(buf+len,"IOP Capabilities\n");
+ len += sprintf(buf+len," Context Field Size Support : ");
+ switch (c->status_block->iop_capabilities & 0x0000003) {
+ case 0:
+ len += sprintf(buf+len,"Supports only 32-bit context fields\n");
+ break;
+ case 1:
+ len += sprintf(buf+len,"Supports only 64-bit context fields\n");
+ break;
+ case 2:
+ len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields, "
+ "but not concurrently\n");
+ break;
+ case 3:
+ len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields "
+ "concurrently\n");
+ break;
+ default:
+ len += sprintf(buf+len,"0x%08x\n",c->status_block->iop_capabilities);
+ }
+ len += sprintf(buf+len," Current Context Field Size : ");
+ switch (c->status_block->iop_capabilities & 0x0000000C) {
+ case 0:
+ len += sprintf(buf+len,"not configured\n");
+ break;
+ case 4:
+ len += sprintf(buf+len,"Supports only 32-bit context fields\n");
+ break;
+ case 8:
+ len += sprintf(buf+len,"Supports only 64-bit context fields\n");
+ break;
+ case 12:
+ len += sprintf(buf+len,"Supports both 32-bit or 64-bit context fields "
+ "concurrently\n");
+ break;
+ default:
+ len += sprintf(buf+len,"\n");
+ }
+ len += sprintf(buf+len," Inbound Peer Support : %s\n",
+ (c->status_block->iop_capabilities & 0x00000010) ? "Supported" : "Not supported");
+ len += sprintf(buf+len," Outbound Peer Support : %s\n",
+ (c->status_block->iop_capabilities & 0x00000020) ? "Supported" : "Not supported");
+ len += sprintf(buf+len," Peer to Peer Support : %s\n",
+ (c->status_block->iop_capabilities & 0x00000040) ? "Supported" : "Not supported");
+
+ len += sprintf(buf+len, "Desired private memory size : %d kB\n",
+ c->status_block->desired_mem_size>>10);
+ len += sprintf(buf+len, "Allocated private memory size : %d kB\n",
+ c->status_block->current_mem_size>>10);
+ len += sprintf(buf+len, "Private memory base address : %0#10x\n",
+ c->status_block->current_mem_base);
+ len += sprintf(buf+len, "Desired private I/O size : %d kB\n",
+ c->status_block->desired_io_size>>10);
+ len += sprintf(buf+len, "Allocated private I/O size : %d kB\n",
+ c->status_block->current_io_size>>10);
+ len += sprintf(buf+len, "Private I/O base address : %0#10x\n",
+ c->status_block->current_io_base);
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+int i2o_proc_read_hw(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ static u32 work32[5];
+ static u8 *work8 = (u8*)work32;
+ static u16 *work16 = (u16*)work32;
+ int token;
+ u32 hwcap;
+
+ static char *cpu_table[] =
+ {
+ "Intel 80960 series",
+ "AMD2900 series",
+ "Motorola 68000 series",
+ "ARM series",
+ "MIPS series",
+ "Sparc series",
+ "PowerPC series",
+ "Intel x86 series"
+ };
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_scalar(c, ADAPTER_TID, 0x0000, -1, &work32, sizeof(work32));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0000 IOP Hardware");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "I2O Vendor ID : %0#6x\n", work16[0]);
+ len += sprintf(buf+len, "Product ID : %0#6x\n", work16[1]);
+ len += sprintf(buf+len, "CPU : ");
+ if(work8[16] > 8)
+ len += sprintf(buf+len, "Unknown\n");
+ else
+ len += sprintf(buf+len, "%s\n", cpu_table[work8[16]]);
+ /* Anyone using ProcessorVersion? */
+
+ len += sprintf(buf+len, "RAM : %dkB\n", work32[1]>>10);
+ len += sprintf(buf+len, "Non-Volatile Mem : %dkB\n", work32[2]>>10);
+
+ hwcap = work32[3];
+ len += sprintf(buf+len, "Capabilities : 0x%08x\n", hwcap);
+ len += sprintf(buf+len, " [%s] Self booting\n",
+ (hwcap&0x00000001) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Upgradable IRTOS\n",
+ (hwcap&0x00000002) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Supports downloading DDMs\n",
+ (hwcap&0x00000004) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Supports installing DDMs\n",
+ (hwcap&0x00000008) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Battery-backed RAM\n",
+ (hwcap&0x00000010) ? "+" : "-");
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+/* Executive group 0003h - Executing DDM List (table) */
+int i2o_proc_read_ddm_table(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ int token;
+ int i;
+
+ typedef struct _i2o_exec_execute_ddm_table {
+ u16 ddm_tid;
+ u8 module_type;
+ u8 reserved;
+ u16 i2o_vendor_id;
+ u16 module_id;
+ u8 module_name_version[28];
+ u32 data_size;
+ u32 code_size;
+ } i2o_exec_execute_ddm_table;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ i2o_exec_execute_ddm_table ddm_table[MAX_I2O_MODULES];
+ } result;
+
+ i2o_exec_execute_ddm_table ddm_table;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ c, ADAPTER_TID,
+ 0x0003, -1,
+ NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0003 Executing DDM List");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "Tid Module_type Vendor Mod_id Module_name Vrs Data_size Code_size\n");
+ ddm_table=result.ddm_table[0];
+
+ for(i=0; i < result.row_count; ddm_table=result.ddm_table[++i])
+ {
+ len += sprintf(buf+len, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
+
+ switch(ddm_table.module_type)
+ {
+ case 0x01:
+ len += sprintf(buf+len, "Downloaded DDM ");
+ break;
+ case 0x22:
+ len += sprintf(buf+len, "Embedded DDM ");
+ break;
+ default:
+ len += sprintf(buf+len, " ");
+ }
+
+ len += sprintf(buf+len, "%-#7x", ddm_table.i2o_vendor_id);
+ len += sprintf(buf+len, "%-#8x", ddm_table.module_id);
+ len += sprintf(buf+len, "%-29s", chtostr(ddm_table.module_name_version, 28));
+ len += sprintf(buf+len, "%9d ", ddm_table.data_size);
+ len += sprintf(buf+len, "%8d", ddm_table.code_size);
+
+ len += sprintf(buf+len, "\n");
+ }
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+/* Executive group 0004h - Driver Store (scalar) */
+int i2o_proc_read_driver_store(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ u32 work32[8];
+ int token;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_scalar(c, ADAPTER_TID, 0x0004, -1, &work32, sizeof(work32));
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0004 Driver Store");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "Module limit : %d\n"
+ "Module count : %d\n"
+ "Current space : %d kB\n"
+ "Free space : %d kB\n",
+ work32[0], work32[1], work32[2]>>10, work32[3]>>10);
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+/* Executive group 0005h - Driver Store Table (table) */
+int i2o_proc_read_drivers_stored(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data)
+{
+ typedef struct _i2o_driver_store {
+ u16 stored_ddm_index;
+ u8 module_type;
+ u8 reserved;
+ u16 i2o_vendor_id;
+ u16 module_id;
+ u8 module_name_version[28];
+ u8 date[8];
+ u32 module_size;
+ u32 mpb_size;
+ u32 module_flags;
+ } i2o_driver_store_table;
+
+ struct i2o_controller *c = (struct i2o_controller*)data;
+ int token;
+ int i;
+
+ typedef struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ i2o_driver_store_table dst[MAX_I2O_MODULES];
+ } i2o_driver_result_table;
+
+ i2o_driver_result_table *result;
+ i2o_driver_store_table *dst;
+
+ spin_lock(&i2o_proc_lock);


+
+ len = 0;
+

+ result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL);
+ if(result == NULL)
+ return -ENOMEM;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ c, ADAPTER_TID, 0x0005, -1, NULL, 0,
+ result, sizeof(*result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0005 DRIVER STORE TABLE");
+ spin_unlock(&i2o_proc_lock);
+ kfree(result);
+ return len;
+ }
+
+ len += sprintf(buf+len, "# Module_type Vendor Mod_id Module_name Vrs"
+ "Date Mod_size Par_size Flags\n");
+ for(i=0, dst=&result->dst[0]; i < result->row_count; dst=&result->dst[++i])
+ {
+ len += sprintf(buf+len, "%-3d", dst->stored_ddm_index);
+ switch(dst->module_type)
+ {
+ case 0x01:
+ len += sprintf(buf+len, "Downloaded DDM ");
+ break;
+ case 0x22:
+ len += sprintf(buf+len, "Embedded DDM ");
+ break;
+ default:
+ len += sprintf(buf+len, " ");
+ }
+
+#if 0
+ if(c->i2oversion == 0x02)
+ len += sprintf(buf+len, "%-d", dst->module_state);
+#endif
+
+ len += sprintf(buf+len, "%-#7x", dst->i2o_vendor_id);
+ len += sprintf(buf+len, "%-#8x", dst->module_id);
+ len += sprintf(buf+len, "%-29s", chtostr(dst->module_name_version,28));
+ len += sprintf(buf+len, "%-9s", chtostr(dst->date,8));
+ len += sprintf(buf+len, "%8d ", dst->module_size);
+ len += sprintf(buf+len, "%8d ", dst->mpb_size);
+ len += sprintf(buf+len, "0x%04x", dst->module_flags);
+#if 0
+ if(c->i2oversion == 0x02)
+ len += sprintf(buf+len, "%d",
+ dst->notification_level);
+#endif
+ len += sprintf(buf+len, "\n");
+ }
+
+ spin_unlock(&i2o_proc_lock);
+ kfree(result);
+ return len;
+}
+
+
+/* Generic group F000h - Params Descriptor (table) */
+int i2o_proc_read_groups(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+ u8 properties;
+
+ typedef struct _i2o_group_info
+ {
+ u16 group_number;
+ u16 field_count;
+ u16 row_count;
+ u8 properties;
+ u8 reserved;
+ } i2o_group_info;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ i2o_group_info group[256];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid, 0xF000, -1, NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len = i2o_report_query_status(buf+len, token, "0xF000 Params Descriptor");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "# Group FieldCount RowCount Type Add Del Clear\n");
+
+ for (i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%-3d", i);
+ len += sprintf(buf+len, "0x%04X ", result.group[i].group_number);
+ len += sprintf(buf+len, "%10d ", result.group[i].field_count);
+ len += sprintf(buf+len, "%8d ", result.group[i].row_count);
+
+ properties = result.group[i].properties;
+ if (properties & 0x1) len += sprintf(buf+len, "Table ");
+ else len += sprintf(buf+len, "Scalar ");
+ if (properties & 0x2) len += sprintf(buf+len, " + ");
+ else len += sprintf(buf+len, " - ");
+ if (properties & 0x4) len += sprintf(buf+len, " + ");
+ else len += sprintf(buf+len, " - ");
+ if (properties & 0x8) len += sprintf(buf+len, " + ");
+ else len += sprintf(buf+len, " - ");
+
+ len += sprintf(buf+len, "\n");
+ }
+
+ if (result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+/* Generic group F001h - Physical Device Table (table) */
+int i2o_proc_read_phys_device(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ u32 adapter_id[64];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,
+ 0xF001, -1, NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF001 Physical Device Table");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ if (result.row_count)
+ len += sprintf(buf+len, "# AdapterId\n");
+
+ for (i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%-2d", i);
+ len += sprintf(buf+len, "%#7x\n", result.adapter_id[i]);
+ }
+
+ if (result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+/* Generic group F002h - Claimed Table (table) */
+int i2o_proc_read_claimed(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+
+ struct {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ u16 claimed_tid[64];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,
+ 0xF002, -1, NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF002 Claimed Table");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ if (result.row_count)
+ len += sprintf(buf+len, "# ClaimedTid\n");
+
+ for (i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%-2d", i);
+ len += sprintf(buf+len, "%#7x\n", result.claimed_tid[i]);
+ }
+
+ if (result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+/* Generic group F003h - User Table (table) */
+int i2o_proc_read_users(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+
+ typedef struct _i2o_user_table
+ {
+ u16 instance;
+ u16 user_tid;
+ u8 claim_type;
+ u8 reserved1;
+ u16 reserved2;
+ } i2o_user_table;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ i2o_user_table user[64];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,
+ 0xF003, -1, NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF003 User Table");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "# Instance UserTid ClaimType\n");
+
+ for(i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%-3d", i);
+ len += sprintf(buf+len, "%#8x ", result.user[i].instance);
+ len += sprintf(buf+len, "%#7x ", result.user[i].user_tid);
+ len += sprintf(buf+len, "%#9x\n", result.user[i].claim_type);
+ }
+
+ if (result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+/* Generic group F005h - Private message extensions (table) (optional) */
+int i2o_proc_read_priv_msgs(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+
+ typedef struct _i2o_private
+ {
+ u16 ext_instance;
+ u16 organization_id;
+ u16 x_function_code;
+ } i2o_private;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ i2o_private extension[64];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,
+ 0xF000, -1,
+ NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF005 Private Message Extensions (optional)");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "Instance# OrgId FunctionCode\n");
+
+ for(i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%0#9x ", result.extension[i].ext_instance);
+ len += sprintf(buf+len, "%0#6x ", result.extension[i].organization_id);
+ len += sprintf(buf+len, "%0#6x", result.extension[i].x_function_code);
+
+ len += sprintf(buf+len, "\n");
+ }
+
+ if(result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+/* Generic group F006h - Authorized User Table (table) */
+int i2o_proc_read_authorized_users(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;
+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;
+ u32 alternate_tid[64];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,
+ 0xF006, -1,
+ NULL, 0,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF006 Autohorized User Table");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ if (result.row_count)
+ len += sprintf(buf+len, "# AlternateTid\n");
+
+ for(i=0; i < result.row_count; i++)
+ {
+ len += sprintf(buf+len, "%-2d", i);
+ len += sprintf(buf+len, "%#7x ", result.alternate_tid[i]);
+ }
+
+ if (result.more_flag)
+ len += sprintf(buf+len, "There is more...\n");
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+
+/* Generic group F100h - Device Identity (scalar) */
+int i2o_proc_read_dev_identity(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number
+ // == (allow) 512d bytes (max)
+ static u16 *work16 = (u16*)work32;
+ int token;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,
+ 0xF100, -1,
+ &work32, sizeof(work32));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token ,"0xF100 Device Identity");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf, "Device Class : %s\n", i2o_get_class_name(work16[0]));
+ len += sprintf(buf+len, "Owner TID : %0#5x\n", work16[2]);
+ len += sprintf(buf+len, "Parent TID : %0#5x\n", work16[3]);
+ len += sprintf(buf+len, "Vendor info : %s\n", chtostr((u8 *)(work32+2), 16));
+ len += sprintf(buf+len, "Product info : %s\n", chtostr((u8 *)(work32+6), 16));
+ len += sprintf(buf+len, "Description : %s\n", chtostr((u8 *)(work32+10), 16));
+ len += sprintf(buf+len, "Product rev. : %s\n", chtostr((u8 *)(work32+14), 8));
+
+ len += sprintf(buf+len, "Serial number : ");
+ len = print_serial_number(buf, len,
+ (u8*)(work32+16),
+ /* allow for SNLen plus
+ * possible trailing '\0'
+ */
+ sizeof(work32)-(16*sizeof(u32))-2
+ );
+ len += sprintf(buf+len, "\n");
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+
+int i2o_proc_read_dev_name(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+
+ if ( d->dev_name[0] == '\0' )
+ return 0;
+
+ len = sprintf(buf, "%s\n", d->dev_name);
+
+ return len;
+}
+
+
+/* Generic group F101h - DDM Identity (scalar) */
+int i2o_proc_read_ddm_identity(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {
+ u16 ddm_tid;
+ u8 module_name[24];
+ u8 module_rev[8];
+ u8 sn_format;
+ u8 serial_number[12];
+ u8 pad[256]; // allow up to 256 byte (max) serial number
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,
+ 0xF101, -1,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF101 DDM Identity");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
+ len += sprintf(buf+len, "Module name : %s\n", chtostr(result.module_name, 24));
+ len += sprintf(buf+len, "Module revision : %s\n", chtostr(result.module_rev, 8));
+
+ len += sprintf(buf+len, "Serial number : ");
+ len = print_serial_number(buf, len, result.serial_number, sizeof(result)-36);
+ /* allow for SNLen plus possible trailing '\0' */
+
+ len += sprintf(buf+len, "\n");
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+/* Generic group F102h - User Information (scalar) */
+int i2o_proc_read_uinfo(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {
+ u8 device_name[64];
+ u8 service_name[64];
+ u8 physical_location[64];
+ u8 instance_number[4];
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,
+ 0xF102, -1,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF102 User Information");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf, "Device name : %s\n", chtostr(result.device_name, 64));
+ len += sprintf(buf+len, "Service name : %s\n", chtostr(result.service_name, 64));
+ len += sprintf(buf+len, "Physical name : %s\n", chtostr(result.physical_location, 64));
+ len += sprintf(buf+len, "Instance number : %s\n", chtostr(result.instance_number, 4));
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+/* Generic group F103h - SGL Operating Limits (scalar) */
+int i2o_proc_read_sgl_limits(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ static u32 work32[12];
+ static u16 *work16 = (u16 *)work32;
+ static u8 *work8 = (u8 *)work32;
+ int token;
+
+ spin_lock(&i2o_proc_lock);
+
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,
+ 0xF103, -1,
+ &work32, sizeof(work32));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF103 SGL Operating Limits");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf, "SGL chain size : %d\n", work32[0]);
+ len += sprintf(buf+len, "Max SGL chain size : %d\n", work32[1]);
+ len += sprintf(buf+len, "SGL chain size target : %d\n", work32[2]);
+ len += sprintf(buf+len, "SGL frag count : %d\n", work16[6]);
+ len += sprintf(buf+len, "Max SGL frag count : %d\n", work16[7]);
+ len += sprintf(buf+len, "SGL frag count target : %d\n", work16[8]);
+
+ if (d->i2oversion == 0x02)
+ {
+ len += sprintf(buf+len, "SGL data alignment : %d\n", work16[8]);
+ len += sprintf(buf+len, "SGL addr limit : %d\n", work8[20]);
+ len += sprintf(buf+len, "SGL addr sizes supported : ");
+ if (work8[21] & 0x01)
+ len += sprintf(buf+len, "32 bit ");
+ if (work8[21] & 0x02)
+ len += sprintf(buf+len, "64 bit ");
+ if (work8[21] & 0x04)
+ len += sprintf(buf+len, "96 bit ");
+ if (work8[21] & 0x08)
+ len += sprintf(buf+len, "128 bit ");
+ len += sprintf(buf+len, "\n");
+ }
+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+
+/* Generic group F200h - Sensors (scalar) */
+int i2o_proc_read_sensors(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {
+ u16 sensor_instance;
+ u8 component;
+ u16 component_instance;
+ u8 sensor_class;
+ u8 sensor_type;
+ u8 scaling_exponent;
+ u32 actual_reading;
+ u32 minimum_reading;
+ u32 low2lowcat_treshold;
+ u32 lowcat2low_treshold;
+ u32 lowwarn2low_treshold;
+ u32 low2lowwarn_treshold;
+ u32 norm2lowwarn_treshold;
+ u32 lowwarn2norm_treshold;
+ u32 nominal_reading;
+ u32 hiwarn2norm_treshold;
+ u32 norm2hiwarn_treshold;
+ u32 high2hiwarn_treshold;
+ u32 hiwarn2high_treshold;
+ u32 hicat2high_treshold;
+ u32 hi2hicat_treshold;
+ u32 maximum_reading;
+ u8 sensor_state;
+ u16 event_enable;
+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,
+ 0xF200, -1,
+ &result, sizeof(result));
+
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0xF200 Sensors (optional)");
+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+
+ len += sprintf(buf+len, "Sensor instance : %d\n", result.sensor_instance);
+
+ len += sprintf(buf+len, "Component : %d = ", result.component);
+ switch (result.component)
+ {
+ case 0: len += sprintf(buf+len, "Other");
+ break;
+ case 1: len += sprintf(buf+len, "Planar logic Board");
+ break;
+ case 2: len += sprintf(buf+len, "CPU");
+ break;
+ case 3: len += sprintf(buf+len, "Chassis");
+ break;
+ case 4: len += sprintf(buf+len, "Power Supply");
+ break;
+ case 5: len += sprintf(buf+len, "Storage");
+ break;
+ case 6: len += sprintf(buf+len, "External");
+ break;
+ }
+ len += sprintf(buf+len,"\n");
+
+ len += sprintf(buf+len, "Component instance : %d\n", result.component_instance);
+ len += sprintf(buf+len, "Sensor class : %s\n",
+ result.sensor_class ? "Analog" : "Digital");
+
+ len += sprintf(buf+len, "Sensor type : %d = ",result.sensor_type);
+ switch (result.sensor_type)
+ {
+ case 0: len += sprintf(buf+len, "Other\n");
+ break;
+ case 1: len += sprintf(buf+len, "Thermal\n");
+ break;
+ case 2: len += sprintf(buf+len, "DC voltage (DC volts)\n");
+ break;
+ case 3: len += sprintf(buf+len, "AC voltage (AC volts)\n");
+ break;
+ case 4: len += sprintf(buf+len, "DC current (DC amps)\n");
+ break;
+ case 5: len += sprintf(buf+len, "AC current (AC volts)\n");
+ break;
+ case 6: len += sprintf(buf+len, "Door open\n");
+ break;
+ case 7: len += sprintf(buf+len, "Fan operational\n");
+ break;
+ }
+
+ len += sprintf(buf+len, "Scaling exponent : %d\n", result.scaling_exponent);
+ len += sprintf(buf+len, "Actual reading : %d\n", result.actual_reading);
+ len += sprintf(buf+len, "Minimum reading : %d\n", result.minimum_reading);
+ len += sprintf(buf+len, "Low2LowCat treshold : %d\n", result.low2lowcat_treshold);
+ len += sprintf(buf+len, "LowCat2Low treshold : %d\n", result.lowcat2low_treshold);
+ len += sprintf(buf+len, "LowWarn2Low treshold : %d\n", result.lowwarn2low_treshold);
+ len += sprintf(buf+len, "Low2LowWarn treshold : %d\n", result.low2lowwarn_treshold);
+ len += sprintf(buf+len, "Norm2LowWarn treshold : %d\n", result.norm2lowwarn_treshold);
+ len += sprintf(buf+len, "LowWarn2Norm treshold : %d\n", result.lowwarn2norm_treshold);
+ len += sprintf(buf+len, "Nominal reading : %d\n", result.nominal_reading);
+ len += sprintf(buf+len, "HiWarn2Norm treshold : %d\n", result.hiwarn2norm_treshold);
+ len += sprintf(buf+len, "Norm2HiWarn treshold : %d\n", result.norm2hiwarn_treshold);
+ len += sprintf(buf+len, "High2HiWarn treshold : %d\n", result.high2hiwarn_treshold);
+ len += sprintf(buf+len, "HiWarn2High treshold : %d\n", result.hiwarn2high_treshold);
+ len += sprintf(buf+len, "HiCat2High treshold : %d\n", result.hicat2high_treshold);
+ len += sprintf(buf+len, "High2HiCat treshold : %d\n", result.hi2hicat_treshold);
+ len += sprintf(buf+len, "Maximum reading : %d\n", result.maximum_reading);
+
+ len += sprintf(buf+len, "Sensor state : %d = ", result.sensor_state);
+ switch (result.sensor_state)
+ {
+ case 0: len += sprintf(buf+len, "Normal\n");
+ break;
+ case 1: len += sprintf(buf+len, "Abnormal\n");
+ break;
+ case 2: len += sprintf(buf+len, "Unknown\n");
+ break;
+ case 3: len += sprintf(buf+len, "Low Catastrophic (LoCat)\n");
+ break;
+ case 4: len += sprintf(buf+len, "Low (Low)\n");
+ break;
+ case 5: len += sprintf(buf+len, "Low Warning (LoWarn)\n");
+ break;
+ case 6: len += sprintf(buf+len, "High Warning (HiWarn)\n");
+ break;
+ case 7: len += sprintf(buf+len, "High (High)\n");
+ break;
+ case 8: len += sprintf(buf+len, "High Catastrophic (HiCat)\n");
+ break;
+ }
+
+ len += sprintf(buf+len, "Event_enable : 0x%02X\n", result.event_enable);
+ len += sprintf(buf+len, " [%s] Operational state change. \n",
+ (result.event_enable & 0x01) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] Low catastrophic. \n",
+ (result.event_enable & 0x02) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] Low reading. \n",
+ (result.event_enable & 0x04) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] Low warning. \n",
+ (result.event_enable & 0x08) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] Change back to normal from out of range state. \n",
+ (result.event_enable & 0x10) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] High warning. \n",
+ (result.event_enable & 0x20) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] High reading. \n",
+ (result.event_enable & 0x40) ? "+" : "-" );
+ len += sprintf(buf+len, " [%s] High catastrophic. \n",
+ (result.event_enable & 0x80) ? "+" : "-" );
+
+ spin_unlock(&i2o_proc_lock);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 28'
echo 'File patch-2.4.13 is continued in part 29'
echo "29" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 7:59:59 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part29

#!/bin/sh -x
# this is part 29 of a 53 - part archive


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

if test "$Scheck" != 29; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ return len;
+}
+
+

+static int print_serial_number(char *buff, int pos, u8 *serialno, int max_len)


+{
+ int i;
+

+ /* 19990419 -sralston
+ * The I2O v1.5 (and v2.0 so far) "official specification"
+ * got serial numbers WRONG!
+ * Apparently, and despite what Section 3.4.4 says and
+ * Figure 3-35 shows (pg 3-39 in the pdf doc),
+ * the convention / consensus seems to be:
+ * + First byte is SNFormat
+ * + Second byte is SNLen (but only if SNFormat==7 (?))
+ * + (v2.0) SCSI+BS may use IEEE Registered (64 or 128 bit) format
+ */
+ switch(serialno[0])
+ {
+ case I2O_SNFORMAT_BINARY: /* Binary */
+ pos += sprintf(buff+pos, "0x");
+ for(i = 0; i < serialno[1]; i++)
+ {
+ pos += sprintf(buff+pos, "%02X", serialno[2+i]);
+ }
+ break;
+
+ case I2O_SNFORMAT_ASCII: /* ASCII */
+ if ( serialno[1] < ' ' ) /* printable or SNLen? */
+ {
+ /* sanity */
+ max_len = (max_len < serialno[1]) ? max_len : serialno[1];
+ serialno[1+max_len] = '\0';
+
+ /* just print it */
+ pos += sprintf(buff+pos, "%s", &serialno[2]);
+ }
+ else
+ {
+ /* print chars for specified length */
+ for(i = 0; i < serialno[1]; i++)
+ {
+ pos += sprintf(buff+pos, "%c", serialno[2+i]);
+ }
+ }
+ break;
+
+ case I2O_SNFORMAT_UNICODE: /* UNICODE */
+ pos += sprintf(buff+pos, "UNICODE Format. Can't Display\n");
+ break;
+
+ case I2O_SNFORMAT_LAN48_MAC: /* LAN-48 MAC Address */
+ pos += sprintf(buff+pos,
+ "LAN-48 MAC address @ %02X:%02X:%02X:%02X:%02X:%02X",
+ serialno[2], serialno[3],
+ serialno[4], serialno[5],
+ serialno[6], serialno[7]);
+ break;
+
+ case I2O_SNFORMAT_WAN: /* WAN MAC Address */
+ /* FIXME: Figure out what a WAN access address looks like?? */
+ pos += sprintf(buff+pos, "WAN Access Address");
+ break;
+
+/* plus new in v2.0 */
+ case I2O_SNFORMAT_LAN64_MAC: /* LAN-64 MAC Address */
+ /* FIXME: Figure out what a LAN-64 address really looks like?? */
+ pos += sprintf(buff+pos,
+ "LAN-64 MAC address @ [?:%02X:%02X:?] %02X:%02X:%02X:%02X:%02X:%02X",
+ serialno[8], serialno[9],
+ serialno[2], serialno[3],
+ serialno[4], serialno[5],
+ serialno[6], serialno[7]);
+ break;
+
+
+ case I2O_SNFORMAT_DDM: /* I2O DDM */
+ pos += sprintf(buff+pos,
+ "DDM: Tid=%03Xh, Rsvd=%04Xh, OrgId=%04Xh",
+ *(u16*)&serialno[2],
+ *(u16*)&serialno[4],
+ *(u16*)&serialno[6]);
+ break;
+
+ case I2O_SNFORMAT_IEEE_REG64: /* IEEE Registered (64-bit) */
+ case I2O_SNFORMAT_IEEE_REG128: /* IEEE Registered (128-bit) */
+ /* FIXME: Figure if this is even close?? */
+ pos += sprintf(buff+pos,
+ "IEEE NodeName(hi,lo)=(%08Xh:%08Xh), PortName(hi,lo)=(%08Xh:%08Xh)\n",
+ *(u32*)&serialno[2],
+ *(u32*)&serialno[6],
+ *(u32*)&serialno[10],
+ *(u32*)&serialno[14]);
+ break;
+
+
+ case I2O_SNFORMAT_UNKNOWN: /* Unknown 0 */
+ case I2O_SNFORMAT_UNKNOWN2: /* Unknown 0xff */
+ default:
+ pos += sprintf(buff+pos, "Unknown data format (0x%02x)",
+ serialno[0]);
+ break;
+ }
+
+ return pos;
+}
+
+const char * i2o_get_connector_type(int conn)


+{
+ int idx = 16;

+ static char *i2o_connector_type[] = {
+ "OTHER",
+ "UNKNOWN",
+ "AUI",
+ "UTP",
+ "BNC",
+ "RJ45",
+ "STP DB9",
+ "FIBER MIC",
+ "APPLE AUI",
+ "MII",
+ "DB9",
+ "HSSDC",
+ "DUPLEX SC FIBER",
+ "DUPLEX ST FIBER",
+ "TNC/BNC",
+ "HW DEFAULT"
+ };
+
+ switch(conn)
+ {
+ case 0x00000000:
+ idx = 0;
+ break;
+ case 0x00000001:
+ idx = 1;
+ break;
+ case 0x00000002:
+ idx = 2;
+ break;
+ case 0x00000003:
+ idx = 3;
+ break;
+ case 0x00000004:
+ idx = 4;
+ break;
+ case 0x00000005:
+ idx = 5;
+ break;
+ case 0x00000006:
+ idx = 6;
+ break;
+ case 0x00000007:
+ idx = 7;
+ break;
+ case 0x00000008:
+ idx = 8;
+ break;
+ case 0x00000009:
+ idx = 9;
+ break;
+ case 0x0000000A:
+ idx = 10;
+ break;
+ case 0x0000000B:
+ idx = 11;
+ break;
+ case 0x0000000C:
+ idx = 12;
+ break;
+ case 0x0000000D:
+ idx = 13;
+ break;
+ case 0x0000000E:
+ idx = 14;
+ break;
+ case 0xFFFFFFFF:
+ idx = 15;
+ break;
+ }
+
+ return i2o_connector_type[idx];
+}
+
+
+const char * i2o_get_connection_type(int conn)
+{
+ int idx = 0;
+ static char *i2o_connection_type[] = {
+ "Unknown",
+ "AUI",
+ "10BASE5",
+ "FIORL",
+ "10BASE2",
+ "10BROAD36",
+ "10BASE-T",
+ "10BASE-FP",
+ "10BASE-FB",
+ "10BASE-FL",
+ "100BASE-TX",
+ "100BASE-FX",
+ "100BASE-T4",
+ "1000BASE-SX",
+ "1000BASE-LX",
+ "1000BASE-CX",
+ "1000BASE-T",
+ "100VG-ETHERNET",
+ "100VG-TOKEN RING",
+ "4MBIT TOKEN RING",
+ "16 Mb Token Ring",
+ "125 MBAUD FDDI",
+ "Point-to-point",
+ "Arbitrated loop",
+ "Public loop",
+ "Fabric",
+ "Emulation",
+ "Other",
+ "HW default"
+ };
+
+ switch(conn)
+ {
+ case I2O_LAN_UNKNOWN:
+ idx = 0;
+ break;
+ case I2O_LAN_AUI:
+ idx = 1;
+ break;
+ case I2O_LAN_10BASE5:
+ idx = 2;
+ break;
+ case I2O_LAN_FIORL:
+ idx = 3;
+ break;
+ case I2O_LAN_10BASE2:
+ idx = 4;
+ break;
+ case I2O_LAN_10BROAD36:
+ idx = 5;
+ break;
+ case I2O_LAN_10BASE_T:
+ idx = 6;
+ break;
+ case I2O_LAN_10BASE_FP:
+ idx = 7;
+ break;
+ case I2O_LAN_10BASE_FB:
+ idx = 8;
+ break;
+ case I2O_LAN_10BASE_FL:
+ idx = 9;
+ break;
+ case I2O_LAN_100BASE_TX:
+ idx = 10;
+ break;
+ case I2O_LAN_100BASE_FX:
+ idx = 11;
+ break;
+ case I2O_LAN_100BASE_T4:
+ idx = 12;
+ break;
+ case I2O_LAN_1000BASE_SX:
+ idx = 13;
+ break;
+ case I2O_LAN_1000BASE_LX:
+ idx = 14;
+ break;
+ case I2O_LAN_1000BASE_CX:
+ idx = 15;
+ break;
+ case I2O_LAN_1000BASE_T:
+ idx = 16;
+ break;
+ case I2O_LAN_100VG_ETHERNET:
+ idx = 17;
+ break;
+ case I2O_LAN_100VG_TR:
+ idx = 18;
+ break;
+ case I2O_LAN_4MBIT:
+ idx = 19;
+ break;
+ case I2O_LAN_16MBIT:
+ idx = 20;
+ break;
+ case I2O_LAN_125MBAUD:
+ idx = 21;
+ break;
+ case I2O_LAN_POINT_POINT:
+ idx = 22;
+ break;
+ case I2O_LAN_ARB_LOOP:
+ idx = 23;
+ break;
+ case I2O_LAN_PUBLIC_LOOP:
+ idx = 24;
+ break;
+ case I2O_LAN_FABRIC:
+ idx = 25;
+ break;
+ case I2O_LAN_EMULATION:
+ idx = 26;
+ break;
+ case I2O_LAN_OTHER:
+ idx = 27;
+ break;
+ case I2O_LAN_DEFAULT:
+ idx = 28;
+ break;
+ }
+
+ return i2o_connection_type[idx];
+}
+
+
+/* LAN group 0000h - Device info (scalar) */
+int i2o_proc_read_lan_dev_info(char *buf, char **start, off_t offset, int len,

+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[56];


+ static u8 *work8 = (u8*)work32;
+ static u16 *work16 = (u16*)work32;

+ static u64 *work64 = (u64*)work32;


+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0000, -1, &work32, 56*4);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token, "0x0000 LAN Device Info");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "LAN Type : ");
+ switch (work16[0])
+ {
+ case 0x0030:
+ len += sprintf(buf+len, "Ethernet, ");
+ break;
+ case 0x0040:
+ len += sprintf(buf+len, "100Base VG, ");
+ break;
+ case 0x0050:
+ len += sprintf(buf+len, "Token Ring, ");
+ break;
+ case 0x0060:
+ len += sprintf(buf+len, "FDDI, ");
+ break;
+ case 0x0070:
+ len += sprintf(buf+len, "Fibre Channel, ");
+ break;
+ default:
+ len += sprintf(buf+len, "Unknown type (0x%04x), ", work16[0]);
+ break;
+ }
+
+ if (work16[1]&0x00000001)
+ len += sprintf(buf+len, "emulated LAN, ");
+ else
+ len += sprintf(buf+len, "physical LAN port, ");
+
+ if (work16[1]&0x00000002)
+ len += sprintf(buf+len, "full duplex\n");
+ else
+ len += sprintf(buf+len, "simplex\n");
+
+ len += sprintf(buf+len, "Address format : ");
+ switch(work8[4]) {
+ case 0x00:
+ len += sprintf(buf+len, "IEEE 48bit\n");


+ break;
+ case 0x01:

+ len += sprintf(buf+len, "FC IEEE\n");
+ break;
+ default:
+ len += sprintf(buf+len, "Unknown (0x%02x)\n", work8[4]);
+ break;
+ }
+
+ len += sprintf(buf+len, "State : ");
+ switch(work8[5])
+ {
+ case 0x00:
+ len += sprintf(buf+len, "Unknown\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len, "Unclaimed\n");


+ break;
+ case 0x02:

+ len += sprintf(buf+len, "Operational\n");


+ break;
+ case 0x03:

+ len += sprintf(buf+len, "Suspended\n");
+ break;
+ case 0x04:
+ len += sprintf(buf+len, "Resetting\n");
+ break;
+ case 0x05:
+ len += sprintf(buf+len, "ERROR: ");
+ if(work16[3]&0x0001)
+ len += sprintf(buf+len, "TxCU inoperative ");
+ if(work16[3]&0x0002)
+ len += sprintf(buf+len, "RxCU inoperative ");
+ if(work16[3]&0x0004)
+ len += sprintf(buf+len, "Local mem alloc ");


+ len += sprintf(buf+len, "\n");

+ break;
+ case 0x06:
+ len += sprintf(buf+len, "Operational no Rx\n");
+ break;
+ case 0x07:
+ len += sprintf(buf+len, "Suspended no Rx\n");
+ break;
+ default:
+ len += sprintf(buf+len, "Unspecified\n");
+ break;
+ }
+
+ len += sprintf(buf+len, "Min packet size : %d\n", work32[2]);
+ len += sprintf(buf+len, "Max packet size : %d\n", work32[3]);
+ len += sprintf(buf+len, "HW address : "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ work8[16],work8[17],work8[18],work8[19],
+ work8[20],work8[21],work8[22],work8[23]);
+
+ len += sprintf(buf+len, "Max Tx wire speed : %d bps\n", (int)work64[3]);
+ len += sprintf(buf+len, "Max Rx wire speed : %d bps\n", (int)work64[4]);
+
+ len += sprintf(buf+len, "Min SDU packet size : 0x%08x\n", work32[10]);
+ len += sprintf(buf+len, "Max SDU packet size : 0x%08x\n", work32[11]);


+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0001h - MAC address table (scalar) */
+int i2o_proc_read_lan_mac_addr(char *buf, char **start, off_t offset, int len,

+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[48];


+ static u8 *work8 = (u8*)work32;

+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0001, -1, &work32, 48*4);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0001 LAN MAC Address");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "Active address : "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ work8[0],work8[1],work8[2],work8[3],
+ work8[4],work8[5],work8[6],work8[7]);
+ len += sprintf(buf+len, "Current address : "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ work8[8],work8[9],work8[10],work8[11],
+ work8[12],work8[13],work8[14],work8[15]);
+ len += sprintf(buf+len, "Functional address mask : "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ work8[16],work8[17],work8[18],work8[19],
+ work8[20],work8[21],work8[22],work8[23]);
+
+ len += sprintf(buf+len,"HW/DDM capabilities : 0x%08x\n", work32[7]);
+ len += sprintf(buf+len," [%s] Unicast packets supported\n",
+ (work32[7]&0x00000001)?"+":"-");
+ len += sprintf(buf+len," [%s] Promiscuous mode supported\n",
+ (work32[7]&0x00000002)?"+":"-");
+ len += sprintf(buf+len," [%s] Promiscuous multicast mode supported\n",
+ (work32[7]&0x00000004)?"+":"-");
+ len += sprintf(buf+len," [%s] Broadcast reception disabling supported\n",
+ (work32[7]&0x00000100)?"+":"-");
+ len += sprintf(buf+len," [%s] Multicast reception disabling supported\n",
+ (work32[7]&0x00000200)?"+":"-");
+ len += sprintf(buf+len," [%s] Functional address disabling supported\n",
+ (work32[7]&0x00000400)?"+":"-");
+ len += sprintf(buf+len," [%s] MAC reporting supported\n",
+ (work32[7]&0x00000800)?"+":"-");
+
+ len += sprintf(buf+len,"Filter mask : 0x%08x\n", work32[6]);
+ len += sprintf(buf+len," [%s] Unicast packets disable\n",
+ (work32[6]&0x00000001)?"+":"-");
+ len += sprintf(buf+len," [%s] Promiscuous mode enable\n",
+ (work32[6]&0x00000002)?"+":"-");
+ len += sprintf(buf+len," [%s] Promiscuous multicast mode enable\n",
+ (work32[6]&0x00000004)?"+":"-");
+ len += sprintf(buf+len," [%s] Broadcast packets disable\n",
+ (work32[6]&0x00000100)?"+":"-");
+ len += sprintf(buf+len," [%s] Multicast packets disable\n",
+ (work32[6]&0x00000200)?"+":"-");
+ len += sprintf(buf+len," [%s] Functional address disable\n",
+ (work32[6]&0x00000400)?"+":"-");
+
+ if (work32[7]&0x00000800) {
+ len += sprintf(buf+len, " MAC reporting mode : ");
+ if (work32[6]&0x00000800)
+ len += sprintf(buf+len, "Pass only priority MAC packets to user\n");
+ else if (work32[6]&0x00001000)
+ len += sprintf(buf+len, "Pass all MAC packets to user\n");
+ else if (work32[6]&0x00001800)
+ len += sprintf(buf+len, "Pass all MAC packets (promiscuous) to user\n");
+ else
+ len += sprintf(buf+len, "Do not pass MAC packets to user\n");
+ }
+ len += sprintf(buf+len, "Number of multicast addresses : %d\n", work32[8]);
+ len += sprintf(buf+len, "Perfect filtering for max %d multicast addresses\n",
+ work32[9]);
+ len += sprintf(buf+len, "Imperfect filtering for max %d multicast addresses\n",
+ work32[10]);


+
+ spin_unlock(&i2o_proc_lock);
+
+ return len;
+}
+

+/* LAN group 0002h - Multicast MAC address table (table) */
+int i2o_proc_read_lan_mcast_addr(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;

+ u8 mc_addr[8];


+
+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;

+ u8 mc_addr[256][8];


+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,

+ d->controller, d->lct_data.tid, 0x0002, -1,
+ NULL, 0, &result, sizeof(result));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x002 LAN Multicast MAC Address");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ for (i = 0; i < result.row_count; i++)
+ {
+ memcpy(mc_addr, result.mc_addr[i], 8);
+
+ len += sprintf(buf+len, "MC MAC address[%d]: "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ i, mc_addr[0], mc_addr[1], mc_addr[2],
+ mc_addr[3], mc_addr[4], mc_addr[5],
+ mc_addr[6], mc_addr[7]);
+ }
+
+ spin_unlock(&i2o_proc_lock);


+ return len;
+}
+

+/* LAN group 0003h - Batch Control (scalar) */
+int i2o_proc_read_lan_batch_control(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[9];


+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0003, -1, &work32, 9*4);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0003 LAN Batch Control");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "Batch mode ");
+ if (work32[0]&0x00000001)
+ len += sprintf(buf+len, "disabled");
+ else
+ len += sprintf(buf+len, "enabled");
+ if (work32[0]&0x00000002)
+ len += sprintf(buf+len, " (current setting)");
+ if (work32[0]&0x00000004)
+ len += sprintf(buf+len, ", forced");
+ else
+ len += sprintf(buf+len, ", toggle");


+ len += sprintf(buf+len, "\n");
+

+ len += sprintf(buf+len, "Max Rx batch count : %d\n", work32[5]);
+ len += sprintf(buf+len, "Max Rx batch delay : %d\n", work32[6]);
+ len += sprintf(buf+len, "Max Tx batch delay : %d\n", work32[7]);
+ len += sprintf(buf+len, "Max Tx batch count : %d\n", work32[8]);
+


+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0004h - LAN Operation (scalar) */
+int i2o_proc_read_lan_operation(char *buf, char **start, off_t offset, int len,


+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[5];


+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0004, -1, &work32, 20);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0004 LAN Operation");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "Packet prepadding (32b words) : %d\n", work32[0]);
+ len += sprintf(buf+len, "Transmission error reporting : %s\n",
+ (work32[1]&1)?"on":"off");
+ len += sprintf(buf+len, "Bad packet handling : %s\n",
+ (work32[1]&0x2)?"by host":"by DDM");
+ len += sprintf(buf+len, "Packet orphan limit : %d\n", work32[2]);
+
+ len += sprintf(buf+len, "Tx modes : 0x%08x\n", work32[3]);
+ len += sprintf(buf+len, " [%s] HW CRC suppression\n",
+ (work32[3]&0x00000004) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW IPv4 checksum\n",
+ (work32[3]&0x00000100) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW TCP checksum\n",
+ (work32[3]&0x00000200) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW UDP checksum\n",
+ (work32[3]&0x00000400) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW RSVP checksum\n",
+ (work32[3]&0x00000800) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW ICMP checksum\n",
+ (work32[3]&0x00001000) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Loopback suppression enable\n",
+ (work32[3]&0x00002000) ? "+" : "-");
+
+ len += sprintf(buf+len, "Rx modes : 0x%08x\n", work32[4]);
+ len += sprintf(buf+len, " [%s] FCS in payload\n",
+ (work32[4]&0x00000004) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW IPv4 checksum validation\n",
+ (work32[4]&0x00000100) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW TCP checksum validation\n",
+ (work32[4]&0x00000200) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW UDP checksum validation\n",
+ (work32[4]&0x00000400) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW RSVP checksum validation\n",
+ (work32[4]&0x00000800) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] HW ICMP checksum validation\n",
+ (work32[4]&0x00001000) ? "+" : "-");
+
+ spin_unlock(&i2o_proc_lock);


+ return len;
+}
+

+/* LAN group 0005h - Media operation (scalar) */
+int i2o_proc_read_lan_media_operation(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {

+ u32 connector_type;
+ u32 connection_type;
+ u64 current_tx_wire_speed;
+ u64 current_rx_wire_speed;
+ u8 duplex_mode;
+ u8 link_status;
+ u8 reserved;
+ u8 duplex_mode_target;
+ u32 connector_type_target;
+ u32 connection_type_target;


+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0005, -1, &result, sizeof(result));
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token, "0x0005 LAN Media Operation");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "Connector type : %s\n",
+ i2o_get_connector_type(result.connector_type));
+ len += sprintf(buf+len, "Connection type : %s\n",
+ i2o_get_connection_type(result.connection_type));
+
+ len += sprintf(buf+len, "Current Tx wire speed : %d bps\n", (int)result.current_tx_wire_speed);
+ len += sprintf(buf+len, "Current Rx wire speed : %d bps\n", (int)result.current_rx_wire_speed);
+ len += sprintf(buf+len, "Duplex mode : %s duplex\n",
+ (result.duplex_mode)?"Full":"Half");
+
+ len += sprintf(buf+len, "Link status : ");
+ switch (result.link_status)
+ {
+ case 0x00:
+ len += sprintf(buf+len, "Unknown\n");
+ break;
+ case 0x01:
+ len += sprintf(buf+len, "Normal\n");
+ break;
+ case 0x02:
+ len += sprintf(buf+len, "Failure\n");


+ break;
+ case 0x03:

+ len += sprintf(buf+len, "Reset\n");
+ break;
+ default:
+ len += sprintf(buf+len, "Unspecified\n");
+ }
+
+ len += sprintf(buf+len, "Duplex mode target : ");
+ switch (result.duplex_mode_target){
+ case 0:
+ len += sprintf(buf+len, "Half duplex\n");


+ break;
+ case 1:

+ len += sprintf(buf+len, "Full duplex\n");


+ break;
+ default:
+ len += sprintf(buf+len, "\n");
+ }
+

+ len += sprintf(buf+len, "Connector type target : %s\n",
+ i2o_get_connector_type(result.connector_type_target));
+ len += sprintf(buf+len, "Connection type target : %s\n",
+ i2o_get_connection_type(result.connection_type_target));


+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0006h - Alternate address (table) (optional) */
+int i2o_proc_read_lan_alt_addr(char *buf, char **start, off_t offset, int len,


+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+ int i;

+ u8 alt_addr[8];


+ struct
+ {
+ u16 result_count;
+ u16 pad;
+ u16 block_size;
+ u8 block_status;
+ u8 error_info_size;
+ u16 row_count;
+ u16 more_flag;

+ u8 alt_addr[256][8];


+ } result;
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+ d->controller, d->lct_data.tid,

+ 0x0006, -1, NULL, 0, &result, sizeof(result));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token, "0x0006 LAN Alternate Address (optional)");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ for (i=0; i < result.row_count; i++)
+ {

+ memcpy(alt_addr,result.alt_addr[i],8);
+ len += sprintf(buf+len, "Alternate address[%d]: "
+ "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ i, alt_addr[0], alt_addr[1], alt_addr[2],
+ alt_addr[3], alt_addr[4], alt_addr[5],
+ alt_addr[6], alt_addr[7]);
+ }
+
+ spin_unlock(&i2o_proc_lock);


+ return len;
+}
+
+

+/* LAN group 0007h - Transmit info (scalar) */
+int i2o_proc_read_lan_tx_info(char *buf, char **start, off_t offset, int len,

+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[8];


+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0007, -1, &work32, 8*4);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0007 LAN Transmit Info");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "Tx Max SG elements per packet : %d\n", work32[0]);
+ len += sprintf(buf+len, "Tx Max SG elements per chain : %d\n", work32[1]);
+ len += sprintf(buf+len, "Tx Max outstanding packets : %d\n", work32[2]);
+ len += sprintf(buf+len, "Tx Max packets per request : %d\n", work32[3]);
+
+ len += sprintf(buf+len, "Tx modes : 0x%08x\n", work32[4]);
+ len += sprintf(buf+len, " [%s] No DA in SGL\n",
+ (work32[4]&0x00000002) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] CRC suppression\n",
+ (work32[4]&0x00000004) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] MAC insertion\n",
+ (work32[4]&0x00000010) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] RIF insertion\n",
+ (work32[4]&0x00000020) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] IPv4 checksum generation\n",
+ (work32[4]&0x00000100) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] TCP checksum generation\n",
+ (work32[4]&0x00000200) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] UDP checksum generation\n",
+ (work32[4]&0x00000400) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] RSVP checksum generation\n",
+ (work32[4]&0x00000800) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] ICMP checksum generation\n",
+ (work32[4]&0x00001000) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Loopback enabled\n",
+ (work32[4]&0x00010000) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] Loopback suppression enabled\n",
+ (work32[4]&0x00020000) ? "+" : "-");
+
+ spin_unlock(&i2o_proc_lock);


+ return len;
+}
+

+/* LAN group 0008h - Receive info (scalar) */
+int i2o_proc_read_lan_rx_info(char *buf, char **start, off_t offset, int len,

+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;

+ static u32 work32[8];


+ int token;
+
+ spin_lock(&i2o_proc_lock);

+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0008, -1, &work32, 8*4);
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x0008 LAN Receive Info");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf ,"Rx Max size of chain element : %d\n", work32[0]);
+ len += sprintf(buf+len, "Rx Max Buckets : %d\n", work32[1]);
+ len += sprintf(buf+len, "Rx Max Buckets in Reply : %d\n", work32[3]);
+ len += sprintf(buf+len, "Rx Max Packets in Bucket : %d\n", work32[4]);
+ len += sprintf(buf+len, "Rx Max Buckets in Post : %d\n", work32[5]);
+
+ len += sprintf(buf+len, "Rx Modes : 0x%08x\n", work32[2]);
+ len += sprintf(buf+len, " [%s] FCS reception\n",
+ (work32[2]&0x00000004) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] IPv4 checksum validation \n",
+ (work32[2]&0x00000100) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] TCP checksum validation \n",
+ (work32[2]&0x00000200) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] UDP checksum validation \n",
+ (work32[2]&0x00000400) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] RSVP checksum validation \n",
+ (work32[2]&0x00000800) ? "+" : "-");
+ len += sprintf(buf+len, " [%s] ICMP checksum validation \n",
+ (work32[2]&0x00001000) ? "+" : "-");
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+
+static int i2o_report_opt_field(char *buf, char *field_name,
+ int field_nbr, int supp_fields, u64 *value)
+{
+ if (supp_fields & (1 << field_nbr))
+ return sprintf(buf, "%-24s : " FMT_U64_HEX "\n", field_name, U64_VAL(value));
+ else
+ return sprintf(buf, "%-24s : Not supported\n", field_name);
+}
+
+/* LAN group 0100h - LAN Historical statistics (scalar) */
+/* LAN group 0180h - Supported Optional Historical Statistics (scalar) */
+/* LAN group 0182h - Optional Non Media Specific Transmit Historical Statistics (scalar) */
+/* LAN group 0183h - Optional Non Media Specific Receive Historical Statistics (scalar) */
+
+int i2o_proc_read_lan_hist_stats(char *buf, char **start, off_t offset, int len,


+ int *eof, void *data)
+{
+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {

+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_errors;
+ u64 rx_errors;
+ u64 rx_dropped;
+ u64 adapter_resets;
+ u64 adapter_suspends;
+ } stats; // 0x0100
+
+ static u64 supp_groups[4]; // 0x0180
+
+ struct
+ {
+ u64 tx_retries;
+ u64 tx_directed_bytes;
+ u64 tx_directed_packets;
+ u64 tx_multicast_bytes;
+ u64 tx_multicast_packets;
+ u64 tx_broadcast_bytes;
+ u64 tx_broadcast_packets;
+ u64 tx_group_addr_packets;
+ u64 tx_short_packets;
+ } tx_stats; // 0x0182
+
+ struct
+ {
+ u64 rx_crc_errors;
+ u64 rx_directed_bytes;
+ u64 rx_directed_packets;
+ u64 rx_multicast_bytes;
+ u64 rx_multicast_packets;
+ u64 rx_broadcast_bytes;
+ u64 rx_broadcast_packets;
+ u64 rx_group_addr_packets;
+ u64 rx_short_packets;
+ u64 rx_long_packets;
+ u64 rx_runt_packets;
+ } rx_stats; // 0x0183
+
+ struct
+ {
+ u64 ipv4_generate;
+ u64 ipv4_validate_success;
+ u64 ipv4_validate_errors;
+ u64 tcp_generate;
+ u64 tcp_validate_success;
+ u64 tcp_validate_errors;
+ u64 udp_generate;
+ u64 udp_validate_success;
+ u64 udp_validate_errors;
+ u64 rsvp_generate;
+ u64 rsvp_validate_success;
+ u64 rsvp_validate_errors;
+ u64 icmp_generate;
+ u64 icmp_validate_success;
+ u64 icmp_validate_errors;
+ } chksum_stats; // 0x0184


+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0100, -1, &stats, sizeof(stats));
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x100 LAN Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "Tx packets : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_packets));
+ len += sprintf(buf+len, "Tx bytes : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_bytes));
+ len += sprintf(buf+len, "Rx packets : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.rx_packets));
+ len += sprintf(buf+len, "Rx bytes : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.rx_bytes));
+ len += sprintf(buf+len, "Tx errors : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_errors));
+ len += sprintf(buf+len, "Rx errors : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.rx_errors));
+ len += sprintf(buf+len, "Rx dropped : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.rx_dropped));
+ len += sprintf(buf+len, "Adapter resets : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.adapter_resets));
+ len += sprintf(buf+len, "Adapter suspends : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.adapter_suspends));
+
+ /* Optional statistics follows */
+ /* Get 0x0180 to see which optional groups/fields are supported */


+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0180, -1, &supp_groups, sizeof(supp_groups));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token, "0x180 LAN Supported Optional Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ if (supp_groups[1]) /* 0x0182 */


+ {
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0182, -1, &tx_stats, sizeof(tx_stats));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x182 LAN Optional Tx Historical Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "==== Optional TX statistics (group 0182h)\n");
+
+ len += i2o_report_opt_field(buf+len, "Tx RetryCount",
+ 0, supp_groups[1], &tx_stats.tx_retries);
+ len += i2o_report_opt_field(buf+len, "Tx DirectedBytes",
+ 1, supp_groups[1], &tx_stats.tx_directed_bytes);
+ len += i2o_report_opt_field(buf+len, "Tx DirectedPackets",
+ 2, supp_groups[1], &tx_stats.tx_directed_packets);
+ len += i2o_report_opt_field(buf+len, "Tx MulticastBytes",
+ 3, supp_groups[1], &tx_stats.tx_multicast_bytes);
+ len += i2o_report_opt_field(buf+len, "Tx MulticastPackets",
+ 4, supp_groups[1], &tx_stats.tx_multicast_packets);
+ len += i2o_report_opt_field(buf+len, "Tx BroadcastBytes",
+ 5, supp_groups[1], &tx_stats.tx_broadcast_bytes);
+ len += i2o_report_opt_field(buf+len, "Tx BroadcastPackets",
+ 6, supp_groups[1], &tx_stats.tx_broadcast_packets);
+ len += i2o_report_opt_field(buf+len, "Tx TotalGroupAddrPackets",
+ 7, supp_groups[1], &tx_stats.tx_group_addr_packets);
+ len += i2o_report_opt_field(buf+len, "Tx TotalPacketsTooShort",
+ 8, supp_groups[1], &tx_stats.tx_short_packets);
+ }
+
+ if (supp_groups[2]) /* 0x0183 */


+ {
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0183, -1, &rx_stats, sizeof(rx_stats));
+ if (token < 0) {
+ len += i2o_report_query_status(buf+len, token,"0x183 LAN Optional Rx Historical Stats");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "==== Optional RX statistics (group 0183h)\n");
+
+ len += i2o_report_opt_field(buf+len, "Rx CRCErrorCount",
+ 0, supp_groups[2], &rx_stats.rx_crc_errors);
+ len += i2o_report_opt_field(buf+len, "Rx DirectedBytes",
+ 1, supp_groups[2], &rx_stats.rx_directed_bytes);
+ len += i2o_report_opt_field(buf+len, "Rx DirectedPackets",
+ 2, supp_groups[2], &rx_stats.rx_directed_packets);
+ len += i2o_report_opt_field(buf+len, "Rx MulticastBytes",
+ 3, supp_groups[2], &rx_stats.rx_multicast_bytes);
+ len += i2o_report_opt_field(buf+len, "Rx MulticastPackets",
+ 4, supp_groups[2], &rx_stats.rx_multicast_packets);
+ len += i2o_report_opt_field(buf+len, "Rx BroadcastBytes",
+ 5, supp_groups[2], &rx_stats.rx_broadcast_bytes);
+ len += i2o_report_opt_field(buf+len, "Rx BroadcastPackets",
+ 6, supp_groups[2], &rx_stats.rx_broadcast_packets);
+ len += i2o_report_opt_field(buf+len, "Rx TotalGroupAddrPackets",
+ 7, supp_groups[2], &rx_stats.rx_group_addr_packets);
+ len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooShort",
+ 8, supp_groups[2], &rx_stats.rx_short_packets);
+ len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooLong",
+ 9, supp_groups[2], &rx_stats.rx_long_packets);
+ len += i2o_report_opt_field(buf+len, "Rx TotalPacketsRunt",
+ 10, supp_groups[2], &rx_stats.rx_runt_packets);
+ }
+
+ if (supp_groups[3]) /* 0x0184 */


+ {
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0184, -1, &chksum_stats, sizeof(chksum_stats));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x184 LAN Optional Chksum Historical Stats");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "==== Optional CHKSUM statistics (group 0x0184)\n");
+
+ len += i2o_report_opt_field(buf+len, "IPv4 Generate",
+ 0, supp_groups[3], &chksum_stats.ipv4_generate);
+ len += i2o_report_opt_field(buf+len, "IPv4 ValidateSuccess",
+ 1, supp_groups[3], &chksum_stats.ipv4_validate_success);
+ len += i2o_report_opt_field(buf+len, "IPv4 ValidateError",
+ 2, supp_groups[3], &chksum_stats.ipv4_validate_errors);
+ len += i2o_report_opt_field(buf+len, "TCP Generate",
+ 3, supp_groups[3], &chksum_stats.tcp_generate);
+ len += i2o_report_opt_field(buf+len, "TCP ValidateSuccess",
+ 4, supp_groups[3], &chksum_stats.tcp_validate_success);
+ len += i2o_report_opt_field(buf+len, "TCP ValidateError",
+ 5, supp_groups[3], &chksum_stats.tcp_validate_errors);
+ len += i2o_report_opt_field(buf+len, "UDP Generate",
+ 6, supp_groups[3], &chksum_stats.udp_generate);
+ len += i2o_report_opt_field(buf+len, "UDP ValidateSuccess",
+ 7, supp_groups[3], &chksum_stats.udp_validate_success);
+ len += i2o_report_opt_field(buf+len, "UDP ValidateError",
+ 8, supp_groups[3], &chksum_stats.udp_validate_errors);
+ len += i2o_report_opt_field(buf+len, "RSVP Generate",
+ 9, supp_groups[3], &chksum_stats.rsvp_generate);
+ len += i2o_report_opt_field(buf+len, "RSVP ValidateSuccess",
+ 10, supp_groups[3], &chksum_stats.rsvp_validate_success);
+ len += i2o_report_opt_field(buf+len, "RSVP ValidateError",
+ 11, supp_groups[3], &chksum_stats.rsvp_validate_errors);
+ len += i2o_report_opt_field(buf+len, "ICMP Generate",
+ 12, supp_groups[3], &chksum_stats.icmp_generate);
+ len += i2o_report_opt_field(buf+len, "ICMP ValidateSuccess",
+ 13, supp_groups[3], &chksum_stats.icmp_validate_success);
+ len += i2o_report_opt_field(buf+len, "ICMP ValidateError",
+ 14, supp_groups[3], &chksum_stats.icmp_validate_errors);


+ }
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0200h - Required Ethernet Statistics (scalar) */
+/* LAN group 0280h - Optional Ethernet Statistics Supported (scalar) */
+/* LAN group 0281h - Optional Ethernet Historical Statistics (scalar) */
+int i2o_proc_read_lan_eth_stats(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;
+ int token;
+
+ struct
+ {

+ u64 rx_align_errors;
+ u64 tx_one_collisions;
+ u64 tx_multiple_collisions;
+ u64 tx_deferred;
+ u64 tx_late_collisions;
+ u64 tx_max_collisions;
+ u64 tx_carrier_lost;
+ u64 tx_excessive_deferrals;
+ } stats;
+
+ static u64 supp_fields;
+ struct
+ {
+ u64 rx_overrun;
+ u64 tx_underrun;
+ u64 tx_heartbeat_failure;
+ } hist_stats;


+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0200, -1, &stats, sizeof(stats));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x0200 LAN Ethernet Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "Rx alignment errors : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.rx_align_errors));
+ len += sprintf(buf+len, "Tx one collisions : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_one_collisions));
+ len += sprintf(buf+len, "Tx multicollisions : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_multiple_collisions));
+ len += sprintf(buf+len, "Tx deferred : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_deferred));
+ len += sprintf(buf+len, "Tx late collisions : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_late_collisions));
+ len += sprintf(buf+len, "Tx max collisions : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_max_collisions));
+ len += sprintf(buf+len, "Tx carrier lost : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_carrier_lost));
+ len += sprintf(buf+len, "Tx excessive deferrals : " FMT_U64_HEX "\n",
+ U64_VAL(&stats.tx_excessive_deferrals));
+
+ /* Optional Ethernet statistics follows */
+ /* Get 0x0280 to see which optional fields are supported */


+
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0280, -1, &supp_fields, sizeof(supp_fields));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x0280 LAN Supported Optional Ethernet Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ if (supp_fields) /* 0x0281 */


+ {
+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0281, -1, &stats, sizeof(stats));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x0281 LAN Optional Ethernet Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "==== Optional ETHERNET statistics (group 0x0281)\n");
+
+ len += i2o_report_opt_field(buf+len, "Rx Overrun",
+ 0, supp_fields, &hist_stats.rx_overrun);
+ len += i2o_report_opt_field(buf+len, "Tx Underrun",
+ 1, supp_fields, &hist_stats.tx_underrun);
+ len += i2o_report_opt_field(buf+len, "Tx HeartbeatFailure",
+ 2, supp_fields, &hist_stats.tx_heartbeat_failure);


+ }
+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0300h - Required Token Ring Statistics (scalar) */
+/* LAN group 0380h, 0381h - Optional Statistics not yet defined (TODO) */
+int i2o_proc_read_lan_tr_stats(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;

+ static u64 work64[13];
+ int token;
+
+ static char *ring_status[] =
+ {
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Ring Recovery",
+ "Single Station",
+ "Counter Overflow",
+ "Remove Received",
+ "",
+ "Auto-Removal Error 1",
+ "Lobe Wire Fault",
+ "Transmit Beacon",
+ "Soft Error",
+ "Hard Error",
+ "Signal Loss"


+ };
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+

+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0300, -1, &work64, sizeof(work64));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x0300 Token Ring Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf, "LineErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[0]));
+ len += sprintf(buf+len, "LostFrames : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[1]));
+ len += sprintf(buf+len, "ACError : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[2]));
+ len += sprintf(buf+len, "TxAbortDelimiter : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[3]));
+ len += sprintf(buf+len, "BursErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[4]));
+ len += sprintf(buf+len, "FrameCopiedErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[5]));
+ len += sprintf(buf+len, "FrequencyErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[6]));
+ len += sprintf(buf+len, "InternalErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[7]));
+ len += sprintf(buf+len, "LastRingStatus : %s\n", ring_status[work64[8]]);
+ len += sprintf(buf+len, "TokenError : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[9]));
+ len += sprintf(buf+len, "UpstreamNodeAddress : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[10]));
+ len += sprintf(buf+len, "LastRingID : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[11]));
+ len += sprintf(buf+len, "LastBeaconType : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[12]));


+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+/* LAN group 0400h - Required FDDI Statistics (scalar) */
+/* LAN group 0480h, 0481h - Optional Statistics, not yet defined (TODO) */
+int i2o_proc_read_lan_fddi_stats(char *buf, char **start, off_t offset,


+ int len, int *eof, void *data)
+{

+ struct i2o_device *d = (struct i2o_device*)data;

+ static u64 work64[11];
+ int token;
+
+ static char *conf_state[] =
+ {
+ "Isolated",
+ "Local a",
+ "Local b",
+ "Local ab",
+ "Local s",
+ "Wrap a",
+ "Wrap b",
+ "Wrap ab",
+ "Wrap s",
+ "C-Wrap a",
+ "C-Wrap b",
+ "C-Wrap s",
+ "Through",
+ };
+
+ static char *ring_state[] =
+ {
+ "Isolated",
+ "Non-op",
+ "Rind-op",
+ "Detect",
+ "Non-op-Dup",
+ "Ring-op-Dup",
+ "Directed",
+ "Trace"
+ };
+
+ static char *link_state[] =
+ {
+ "Off",
+ "Break",
+ "Trace",
+ "Connect",
+ "Next",
+ "Signal",
+ "Join",
+ "Verify",
+ "Active",
+ "Maintenance"


+ };
+
+ spin_lock(&i2o_proc_lock);
+ len = 0;
+

+ token = i2o_query_scalar(d->controller, d->lct_data.tid,

+ 0x0400, -1, &work64, sizeof(work64));


+
+ if (token < 0) {

+ len += i2o_report_query_status(buf+len, token,"0x0400 FDDI Required Statistics");


+ spin_unlock(&i2o_proc_lock);
+ return len;
+ }
+

+ len += sprintf(buf+len, "ConfigurationState : %s\n", conf_state[work64[0]]);
+ len += sprintf(buf+len, "UpstreamNode : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[1]));
+ len += sprintf(buf+len, "DownStreamNode : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[2]));
+ len += sprintf(buf+len, "FrameErrors : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[3]));
+ len += sprintf(buf+len, "FramesLost : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[4]));
+ len += sprintf(buf+len, "RingMgmtState : %s\n", ring_state[work64[5]]);
+ len += sprintf(buf+len, "LCTFailures : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[6]));
+ len += sprintf(buf+len, "LEMRejects : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[7]));
+ len += sprintf(buf+len, "LEMCount : " FMT_U64_HEX "\n",
+ U64_VAL(&work64[8]));
+ len += sprintf(buf+len, "LConnectionState : %s\n",
+ link_state[work64[9]]);


+
+ spin_unlock(&i2o_proc_lock);
+ return len;
+}
+

+static int i2o_proc_create_entries(void *data, i2o_proc_entry *pentry,
+ struct proc_dir_entry *parent)
+{
+ struct proc_dir_entry *ent;
+
+ while(pentry->name != NULL)
+ {
+ ent = create_proc_entry(pentry->name, pentry->mode, parent);
+ if(!ent) return -1;
+
+ ent->data = data;
+ ent->read_proc = pentry->read_proc;
+ ent->write_proc = pentry->write_proc;
+ ent->nlink = 1;
+
+ pentry++;
+ }


+
+ return 0;
+}
+

+static void i2o_proc_remove_entries(i2o_proc_entry *pentry,
+ struct proc_dir_entry *parent)
+{
+ while(pentry->name != NULL)
+ {
+ remove_proc_entry(pentry->name, parent);
+ pentry++;
+ }
+}
+
+static int i2o_proc_add_controller(struct i2o_controller *pctrl,
+ struct proc_dir_entry *root )
+{
+ struct proc_dir_entry *dir, *dir1;
+ struct i2o_device *dev;
+ char buff[10];
+
+ sprintf(buff, "iop%d", pctrl->unit);
+
+ dir = proc_mkdir(buff, root);
+ if(!dir)
+ return -1;
+
+ pctrl->proc_entry = dir;
+
+ i2o_proc_create_entries(pctrl, generic_iop_entries, dir);
+
+ for(dev = pctrl->devices; dev; dev = dev->next)
+ {
+ sprintf(buff, "%0#5x", dev->lct_data.tid);
+
+ dir1 = proc_mkdir(buff, dir);
+ dev->proc_entry = dir1;
+
+ if(!dir1)
+ printk(KERN_INFO "i2o_proc: Could not allocate proc dir\n");
+
+ i2o_proc_add_device(dev, dir1);
+ }


+
+ return 0;
+}
+

+void i2o_proc_new_dev(struct i2o_controller *c, struct i2o_device *d)
+{
+ char buff[10];
+
+#ifdef DRIVERDEBUG
+ printk(KERN_INFO "Adding new device to /proc/i2o/iop%d\n", c->unit);
+#endif
+ sprintf(buff, "%0#5x", d->lct_data.tid);
+
+ d->proc_entry = proc_mkdir(buff, c->proc_entry);
+
+ if(!d->proc_entry)
+ {
+ printk(KERN_WARNING "i2o: Could not allocate procdir!\n");
+ return;
+ }
+
+ i2o_proc_add_device(d, d->proc_entry);
+}
+
+void i2o_proc_add_device(struct i2o_device *dev, struct proc_dir_entry *dir)
+{
+ i2o_proc_create_entries(dev, generic_dev_entries, dir);
+
+ /* Inform core that we want updates about this device's status */
+ i2o_device_notify_on(dev, &i2o_proc_handler);
+ switch(dev->lct_data.class_id)
+ {
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ i2o_proc_create_entries(dev, rbs_dev_entries, dir);
+ break;
+ case I2O_CLASS_LAN:
+ i2o_proc_create_entries(dev, lan_entries, dir);
+ switch(dev->lct_data.sub_class)
+ {
+ case I2O_LAN_ETHERNET:
+ i2o_proc_create_entries(dev, lan_eth_entries, dir);
+ break;
+ case I2O_LAN_FDDI:
+ i2o_proc_create_entries(dev, lan_fddi_entries, dir);
+ break;
+ case I2O_LAN_TR:
+ i2o_proc_create_entries(dev, lan_tr_entries, dir);
+ break;
+ default:


+ break;
+ }
+ break;

+ default:


+ break;
+ }
+}
+

+static void i2o_proc_remove_controller(struct i2o_controller *pctrl,
+ struct proc_dir_entry *parent)
+{
+ char buff[10];
+ struct i2o_device *dev;
+
+ /* Remove unused device entries */
+ for(dev=pctrl->devices; dev; dev=dev->next)
+ i2o_proc_remove_device(dev);
+
+ if(!atomic_read(&pctrl->proc_entry->count))
+ {
+ sprintf(buff, "iop%d", pctrl->unit);
+
+ i2o_proc_remove_entries(generic_iop_entries, pctrl->proc_entry);
+
+ remove_proc_entry(buff, parent);
+ pctrl->proc_entry = NULL;
+ }
+}
+
+void i2o_proc_remove_device(struct i2o_device *dev)
+{
+ struct proc_dir_entry *de=dev->proc_entry;
+ char dev_id[10];
+
+ sprintf(dev_id, "%0#5x", dev->lct_data.tid);
+
+ i2o_device_notify_off(dev, &i2o_proc_handler);
+ /* Would it be safe to remove _files_ even if they are in use? */
+ if((de) && (!atomic_read(&de->count)))
+ {
+ i2o_proc_remove_entries(generic_dev_entries, de);
+ switch(dev->lct_data.class_id)
+ {
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ i2o_proc_remove_entries(rbs_dev_entries, de);
+ break;
+ case I2O_CLASS_LAN:
+ {
+ i2o_proc_remove_entries(lan_entries, de);
+ switch(dev->lct_data.sub_class)
+ {
+ case I2O_LAN_ETHERNET:
+ i2o_proc_remove_entries(lan_eth_entries, de);
+ break;
+ case I2O_LAN_FDDI:
+ i2o_proc_remove_entries(lan_fddi_entries, de);
+ break;
+ case I2O_LAN_TR:
+ i2o_proc_remove_entries(lan_tr_entries, de);
+ break;
+ }
+ }
+ remove_proc_entry(dev_id, dev->controller->proc_entry);
+ }
+ }
+}
+
+void i2o_proc_dev_del(struct i2o_controller *c, struct i2o_device *d)
+{
+#ifdef DRIVERDEBUG
+ printk(KERN_INFO "Deleting device %d from iop%d\n",
+ d->lct_data.tid, c->unit);
+#endif
+
+ i2o_proc_remove_device(d);
+}
+
+static int create_i2o_procfs(void)
+{
+ struct i2o_controller *pctrl = NULL;
+ int i;
+
+ i2o_proc_dir_root = proc_mkdir("i2o", 0);
+ if(!i2o_proc_dir_root)
+ return -1;
+
+ for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
+ {
+ pctrl = i2o_find_controller(i);
+ if(pctrl)
+ {
+ i2o_proc_add_controller(pctrl, i2o_proc_dir_root);
+ i2o_unlock_controller(pctrl);
+ }
+ };


+
+ return 0;
+}
+

+static int __exit destroy_i2o_procfs(void)
+{
+ struct i2o_controller *pctrl = NULL;
+ int i;
+


+ for(i = 0; i < MAX_I2O_CONTROLLERS; i++)
+ {

+ pctrl = i2o_find_controller(i);
+ if(pctrl)
+ {
+ i2o_proc_remove_controller(pctrl, i2o_proc_dir_root);
+ i2o_unlock_controller(pctrl);
+ }
+ }
+
+ if(!atomic_read(&i2o_proc_dir_root->count))
+ remove_proc_entry("i2o", 0);
+ else
+ return -1;


+
+ return 0;
+}
+

+int __init i2o_proc_init(void)
+{
+ if (i2o_install_handler(&i2o_proc_handler) < 0)
+ {
+ printk(KERN_ERR "i2o_proc: Unable to install PROC handler.\n");


+ return 0;
+ }
+

+ if(create_i2o_procfs())
+ return -EBUSY;
+
+ return 0;
+}
+
+MODULE_AUTHOR("Deepak Saxena");
+MODULE_DESCRIPTION("I2O procfs Handler");
+MODULE_LICENSE("GPL");
+
+static void __exit i2o_proc_exit(void)
+{
+ destroy_i2o_procfs();
+ i2o_remove_handler(&i2o_proc_handler);
+}
+
+#ifdef MODULE
+module_init(i2o_proc_init);
+#endif
+module_exit(i2o_proc_exit);
+
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_scsi.c linux/drivers/message/i2o/i2o_scsi.c
--- v2.4.12/linux/drivers/message/i2o/i2o_scsi.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_scsi.c Mon Oct 22 08:39:56 2001
@@ -0,0 +1,923 @@
+/*

+ * 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.
+ *
+ * Complications for I2O scsi
+ *
+ * o Each (bus,lun) is a logical device in I2O. We keep a map
+ * table. We spoof failed selection for unmapped units
+ * o Request sense buffers can come back for free.
+ * o Scatter gather is a bit dynamic. We have to investigate at
+ * setup time.
+ * o Some of our resources are dynamically shared. The i2o core
+ * needs a message reservation protocol to avoid swap v net
+ * deadlocking. We need to back off queue requests.
+ *
+ * In general the firmware wants to help. Where its help isn't performance
+ * useful we just ignore the aid. Its not worth the code in truth.
+ *
+ * Fixes:
+ * Steve Ralston : Scatter gather now works
+ *
+ * To Do
+ * 64bit cleanups
+ * Fix the resource management problems.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/prefetch.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <linux/blk.h>
+#include <linux/version.h>
+#include <linux/i2o.h>
+#include "../../scsi/scsi.h"
+#include "../../scsi/hosts.h"
+#include "../../scsi/sd.h"
+#include "i2o_scsi.h"
+
+#define VERSION_STRING "Version 0.0.1"
+
+#define dprintk(x)
+
+#define MAXHOSTS 32
+
+struct i2o_scsi_host


+{
+ struct i2o_controller *controller;

+ s16 task[16][8]; /* Allow 16 devices for now */
+ unsigned long tagclock[16][8]; /* Tag clock for queueing */
+ s16 bus_task; /* The adapter TID */
+};
+
+static int scsi_context;
+static int lun_done;
+static int i2o_scsi_hosts;
+
+static u32 *retry[32];
+static struct i2o_controller *retry_ctrl[32];
+static struct timer_list retry_timer;
+static int retry_ct = 0;
+
+static atomic_t queue_depth;
+
+/*
+ * SG Chain buffer support...
+ */
+
+#define SG_MAX_FRAGS 64
+
+/*
+ * FIXME: we should allocate one of these per bus we find as we
+ * locate them not in a lump at boot.
+ */
+
+typedef struct _chain_buf
+{
+ u32 sg_flags_cnt[SG_MAX_FRAGS];
+ u32 sg_buf[SG_MAX_FRAGS];
+} chain_buf;
+
+#define SG_CHAIN_BUF_SZ sizeof(chain_buf)
+
+#define SG_MAX_BUFS (i2o_num_controllers * I2O_SCSI_CAN_QUEUE)
+#define SG_CHAIN_POOL_SZ (SG_MAX_BUFS * SG_CHAIN_BUF_SZ)
+
+static int max_sg_len = 0;
+static chain_buf *sg_chain_pool = NULL;
+static int sg_chain_tag = 0;
+static int sg_max_frags = SG_MAX_FRAGS;
+
+/*
+ * Retry congested frames. This actually needs pushing down into
+ * i2o core. We should only bother the OSM with this when we can't
+ * queue and retry the frame. Or perhaps we should call the OSM
+ * and its default handler should be this in the core, and this
+ * call a 2nd "I give up" handler in the OSM ?
+ */
+
+static void i2o_retry_run(unsigned long f)
+{
+ int i;


+ unsigned long flags;
+

+ save_flags(flags);
+ cli();
+
+ for(i=0;i<retry_ct;i++)
+ i2o_post_message(retry_ctrl[i], virt_to_bus(retry[i]));
+ retry_ct=0;
+
+ restore_flags(flags);
+}
+
+static void flush_pending(void)
+{
+ int i;


+ unsigned long flags;
+

+ save_flags(flags);
+ cli();
+
+ for(i=0;i<retry_ct;i++)
+ {
+ retry[i][0]&=~0xFFFFFF;
+ retry[i][0]|=I2O_CMD_UTIL_NOP<<24;
+ i2o_post_message(retry_ctrl[i],virt_to_bus(retry[i]));
+ }
+ retry_ct=0;
+
+ restore_flags(flags);
+}
+
+static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
+{
+ Scsi_Cmnd *current_command;


+ u32 *m = (u32 *)msg;

+ u8 as,ds,st;
+
+ spin_lock_prefetch(&io_request_lock);
+


+ if(m[0] & (1<<13))
+ {

+ printk("IOP fail.\n");
+ printk("From %d To %d Cmd %d.\n",
+ (m[1]>>12)&0xFFF,
+ m[1]&0xFFF,
+ m[1]>>24);
+ printk("Failure Code %d.\n", m[4]>>24);
+ if(m[4]&(1<<16))
+ printk("Format error.\n");
+ if(m[4]&(1<<17))
+ printk("Path error.\n");
+ if(m[4]&(1<<18))
+ printk("Path State.\n");
+ if(m[4]&(1<<18))
+ printk("Congestion.\n");
+
+ m=(u32 *)bus_to_virt(m[7]);
+ printk("Failing message is %p.\n", m);
+
+ if((m[4]&(1<<18)) && retry_ct < 32)
+ {
+ retry_ctrl[retry_ct]=c;
+ retry[retry_ct]=m;
+ if(!retry_ct++)
+ {
+ retry_timer.expires=jiffies+1;
+ add_timer(&retry_timer);
+ }
+ }
+ else
+ {
+ /* Create a scsi error for this */
+ current_command = (Scsi_Cmnd *)m[3];
+ printk("Aborted %ld\n", current_command->serial_number);
+
+ spin_lock_irq(&io_request_lock);
+ current_command->result = DID_ERROR << 16;
+ current_command->scsi_done(current_command);
+ spin_unlock_irq(&io_request_lock);

+
+ /* Now flush the message by making it a NOP */
+ m[0]&=0x00FFFFFF;
+ m[0]|=(I2O_CMD_UTIL_NOP)<<24;
+ i2o_post_message(c,virt_to_bus(m));

+ }
+ return;
+ }
+

+ prefetchw(&queue_depth);
+
+
+ /*
+ * Low byte is device status, next is adapter status,
+ * (then one byte reserved), then request status.
+ */
+ ds=(u8)m[4];
+ as=(u8)(m[4]>>8);
+ st=(u8)(m[4]>>24);
+
+ dprintk(("i2o got a scsi reply %08X: ", m[0]));
+ dprintk(("m[2]=%08X: ", m[2]));
+ dprintk(("m[4]=%08X\n", m[4]));
+
+ if(m[2]&0x80000000)
+ {
+ if(m[2]&0x40000000)
+ {
+ dprintk(("Event.\n"));
+ lun_done=1;
+ return;
+ }
+ printk(KERN_ERR "i2o_scsi: bus reset reply.\n");
+ return;
+ }
+
+ current_command = (Scsi_Cmnd *)m[3];
+
+ /*
+ * Is this a control request coming back - eg an abort ?
+ */
+
+ if(current_command==NULL)
+ {
+ if(st)
+ dprintk(("SCSI abort: %08X", m[4]));
+ dprintk(("SCSI abort completed.\n"));
+ return;
+ }
+
+ dprintk(("Completed %ld\n", current_command->serial_number));
+
+ atomic_dec(&queue_depth);
+
+ if(st == 0x06)
+ {
+ if(m[5] < current_command->underflow)
+ {
+ int i;
+ printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X\n",
+ m[5], current_command->underflow);
+ printk("Cmd: ");
+ for(i=0;i<15;i++)
+ printk("%02X ", current_command->cmnd[i]);


+ printk(".\n");
+ }

+ else st=0;
+ }
+
+ if(st)
+ {
+ /* An error has occurred */
+
+ dprintk((KERN_DEBUG "SCSI error %08X", m[4]));
+
+ if (as == 0x0E)
+ /* SCSI Reset */
+ current_command->result = DID_RESET << 16;
+ else if (as == 0x0F)
+ current_command->result = DID_PARITY << 16;
+ else
+ current_command->result = DID_ERROR << 16;
+ }
+ else
+ /*
+ * It worked maybe ?
+ */
+ current_command->result = DID_OK << 16 | ds;
+ spin_lock(&io_request_lock);
+ current_command->scsi_done(current_command);
+ spin_unlock(&io_request_lock);
+ return;
+}
+
+struct i2o_handler i2o_scsi_handler=
+{
+ i2o_scsi_reply,


+ NULL,
+ NULL,
+ NULL,

+ "I2O SCSI OSM",
+ 0,
+ I2O_CLASS_SCSI_PERIPHERAL
+};
+
+static int i2o_find_lun(struct i2o_controller *c, struct i2o_device *d, int *target, int *lun)
+{
+ u8 reply[8];
+
+ if(i2o_query_scalar(c, d->lct_data.tid, 0, 3, reply, 4)<0)
+ return -1;
+
+ *target=reply[0];
+
+ if(i2o_query_scalar(c, d->lct_data.tid, 0, 4, reply, 8)<0)
+ return -1;
+
+ *lun=reply[1];
+
+ dprintk(("SCSI (%d,%d)\n", *target, *lun));


+ return 0;
+}
+

+void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
+{
+ struct i2o_device *unit;
+ struct i2o_scsi_host *h =(struct i2o_scsi_host *)shpnt->hostdata;
+ int lun;
+ int target;
+
+ h->controller=c;
+ h->bus_task=d->lct_data.tid;
+
+ for(target=0;target<16;target++)
+ for(lun=0;lun<8;lun++)
+ h->task[target][lun] = -1;
+
+ for(unit=c->devices;unit!=NULL;unit=unit->next)
+ {
+ dprintk(("Class %03X, parent %d, want %d.\n",
+ unit->lct_data.class_id, unit->lct_data.parent_tid, d->lct_data.tid));
+
+ /* Only look at scsi and fc devices */
+ if ( (unit->lct_data.class_id != I2O_CLASS_SCSI_PERIPHERAL)
+ && (unit->lct_data.class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL)
+ )
+ continue;
+
+ /* On our bus ? */
+ dprintk(("Found a disk (%d).\n", unit->lct_data.tid));
+ if ((unit->lct_data.parent_tid == d->lct_data.tid)
+ || (unit->lct_data.parent_tid == d->lct_data.parent_tid)
+ )
+ {
+ u16 limit;
+ dprintk(("Its ours.\n"));
+ if(i2o_find_lun(c, unit, &target, &lun)==-1)
+ {
+ printk(KERN_ERR "i2o_scsi: Unable to get lun for tid %d.\n", unit->lct_data.tid);
+ continue;
+ }
+ dprintk(("Found disk %d %d.\n", target, lun));
+ h->task[target][lun]=unit->lct_data.tid;
+ h->tagclock[target][lun]=jiffies;
+
+ /* Get the max fragments/request */
+ i2o_query_scalar(c, d->lct_data.tid, 0xF103, 3, &limit, 2);
+
+ /* sanity */
+ if ( limit == 0 )
+ {
+ printk(KERN_WARNING "i2o_scsi: Ignoring unreasonable SG limit of 0 from IOP!\n");
+ limit = 1;
+ }
+
+ shpnt->sg_tablesize = limit;
+
+ dprintk(("i2o_scsi: set scatter-gather to %d.\n",
+ shpnt->sg_tablesize));
+ }
+ }
+}
+
+int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+{
+ unsigned long flags;
+ struct Scsi_Host *shpnt = NULL;
+ int i;
+ int count;
+
+ printk("i2o_scsi.c: %s\n", VERSION_STRING);
+
+ if(i2o_install_handler(&i2o_scsi_handler)<0)
+ {
+ printk(KERN_ERR "i2o_scsi: Unable to install OSM handler.\n");
+ return 0;
+ }
+ scsi_context = i2o_scsi_handler.context;
+
+ if((sg_chain_pool = kmalloc(SG_CHAIN_POOL_SZ, GFP_KERNEL)) == NULL)
+ {
+ printk("i2o_scsi: Unable to alloc %d byte SG chain buffer pool.\n", SG_CHAIN_POOL_SZ);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 29'
echo 'File patch-2.4.13 is continued in part 30'
echo "30" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:00 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part30

#!/bin/sh -x
# this is part 30 of a 53 - part archive


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

if test "$Scheck" != 30; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ printk("i2o_scsi: SG chaining DISABLED!\n");
+ sg_max_frags = 11;
+ }
+ else
+ {
+ printk(" chain_pool: %d bytes @ %p\n", SG_CHAIN_POOL_SZ, sg_chain_pool);
+ printk(" (%d byte buffers X %d can_queue X %d i2o controllers)\n",
+ SG_CHAIN_BUF_SZ, I2O_SCSI_CAN_QUEUE, i2o_num_controllers);
+ sg_max_frags = SG_MAX_FRAGS; // 64
+ }
+
+ init_timer(&retry_timer);
+ retry_timer.data = 0UL;
+ retry_timer.function = i2o_retry_run;
+
+// printk("SCSI OSM at %d.\n", scsi_context);
+
+ for (count = 0, i = 0; i < MAX_I2O_CONTROLLERS; i++)
+ {
+ struct i2o_controller *c=i2o_find_controller(i);
+ struct i2o_device *d;
+ /*
+ * This controller doesn't exist.
+ */
+
+ if(c==NULL)


+ continue;
+
+ /*

+ * Fixme - we need some altered device locking. This
+ * is racing with device addition in theory. Easy to fix.
+ */
+
+ for(d=c->devices;d!=NULL;d=d->next)
+ {
+ /*
+ * bus_adapter, SCSI (obsolete), or FibreChannel busses only
+ */
+ if( (d->lct_data.class_id!=I2O_CLASS_BUS_ADAPTER_PORT) // bus_adapter
+// && (d->lct_data.class_id!=I2O_CLASS_FIBRE_CHANNEL_PORT) // FC_PORT


+ )
+ continue;
+

+ shpnt = scsi_register(tpnt, sizeof(struct i2o_scsi_host));
+ if(shpnt==NULL)
+ continue;
+ save_flags(flags);
+ cli();
+ shpnt->unique_id = (u32)d;
+ shpnt->io_port = 0;
+ shpnt->n_io_port = 0;
+ shpnt->irq = 0;
+ shpnt->this_id = /* Good question */15;
+ restore_flags(flags);
+ i2o_scsi_init(c, d, shpnt);
+ count++;
+ }
+ }
+ i2o_scsi_hosts = count;
+
+ if(count==0)
+ {
+ if(sg_chain_pool!=NULL)
+ {
+ kfree(sg_chain_pool);
+ sg_chain_pool = NULL;
+ }
+ flush_pending();
+ del_timer(&retry_timer);
+ i2o_remove_handler(&i2o_scsi_handler);
+ }
+
+ return count;
+}
+
+int i2o_scsi_release(struct Scsi_Host *host)
+{
+ if(--i2o_scsi_hosts==0)
+ {
+ if(sg_chain_pool!=NULL)
+ {
+ kfree(sg_chain_pool);
+ sg_chain_pool = NULL;
+ }
+ flush_pending();
+ del_timer(&retry_timer);
+ i2o_remove_handler(&i2o_scsi_handler);


+ }
+ return 0;
+}
+
+

+const char *i2o_scsi_info(struct Scsi_Host *SChost)
+{
+ struct i2o_scsi_host *hostdata;
+
+ hostdata = (struct i2o_scsi_host *)SChost->hostdata;
+
+ return(&hostdata->controller->name[0]);
+}
+
+
+/*
+ * From the wd93 driver:
+ * Returns true if there will be a DATA_OUT phase with this command,
+ * false otherwise.
+ * (Thanks to Joerg Dorchain for the research and suggestion.)
+ *
+ */
+static int is_dir_out(Scsi_Cmnd *cmd)
+{
+ switch (cmd->cmnd[0])
+ {
+ case WRITE_6: case WRITE_10: case WRITE_12:
+ case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER:
+ case WRITE_VERIFY: case WRITE_VERIFY_12:
+ case COMPARE: case COPY: case COPY_VERIFY:
+ case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
+ case SEARCH_EQUAL_12: case SEARCH_HIGH_12: case SEARCH_LOW_12:
+ case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
+ case MODE_SELECT: case MODE_SELECT_10: case LOG_SELECT:
+ case SEND_DIAGNOSTIC: case CHANGE_DEFINITION: case UPDATE_BLOCK:
+ case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG:
+ case 0xea:
+ return 1;
+ default:


+ return 0;
+ }
+}
+

+int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+{
+ int i;
+ int tid;
+ struct i2o_controller *c;
+ Scsi_Cmnd *current_command;
+ struct Scsi_Host *host;
+ struct i2o_scsi_host *hostdata;
+ u32 *msg, *mptr;
+ u32 m;
+ u32 *lenptr;
+ int direction;
+ int scsidir;
+ u32 len;
+ u32 reqlen;
+ u32 tag;
+
+ static int max_qd = 1;
+
+ /*
+ * Do the incoming paperwork
+ */
+
+ host = SCpnt->host;
+ hostdata = (struct i2o_scsi_host *)host->hostdata;
+
+ c = hostdata->controller;
+ prefetch(c);
+ prefetchw(&queue_depth);
+
+ SCpnt->scsi_done = done;
+
+ if(SCpnt->target > 15)
+ {
+ printk(KERN_ERR "i2o_scsi: Wild target %d.\n", SCpnt->target);


+ return -1;
+ }
+

+ tid = hostdata->task[SCpnt->target][SCpnt->lun];
+
+ dprintk(("qcmd: Tid = %d\n", tid));
+
+ current_command = SCpnt; /* set current command */
+ current_command->scsi_done = done; /* set ptr to done function */
+
+ /* We don't have such a device. Pretend we did the command
+ and that selection timed out */
+
+ if(tid == -1)
+ {
+ SCpnt->result = DID_NO_CONNECT << 16;
+ done(SCpnt);


+ return 0;
+ }
+

+ dprintk(("Real scsi messages.\n"));
+
+
+ /*
+ * Obtain an I2O message. Right now we _have_ to obtain one
+ * until the scsi layer stuff is cleaned up.
+ */
+
+ do


+ {
+ mb();
+ m = I2O_POST_READ32(c);
+ }

+ while(m==0xFFFFFFFF);


+ msg = (u32 *)(c->mem_offset + m);

+
+ /*
+ * Put together a scsi execscb message
+ */
+
+ len = SCpnt->request_bufflen;
+ direction = 0x00000000; // SGL IN (osm<--iop)
+
+ /*
+ * The scsi layer should be handling this stuff
+ */
+
+ scsidir = 0x00000000; // DATA NO XFER
+ if(len)
+ {
+ if(is_dir_out(SCpnt))
+ {
+ direction=0x04000000; // SGL OUT (osm-->iop)
+ scsidir =0x80000000; // DATA OUT (iop-->dev)
+ }
+ else
+ {
+ scsidir =0x40000000; // DATA IN (iop<--dev)
+ }
+ }
+
+ __raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
+ __raw_writel(scsi_context, &msg[2]); /* So the I2O layer passes to us */
+ /* Sorry 64bit folks. FIXME */
+ __raw_writel((u32)SCpnt, &msg[3]); /* We want the SCSI control block back */
+
+ /* LSI_920_PCI_QUIRK
+ *
+ * Intermittant observations of msg frame word data corruption
+ * observed on msg[4] after:
+ * WRITE, READ-MODIFY-WRITE
+ * operations. 19990606 -sralston
+ *
+ * (Hence we build this word via tag. Its good practice anyway
+ * we don't want fetches over PCI needlessly)
+ */
+
+ tag=0;
+
+ /*
+ * Attach tags to the devices
+ */
+ if(SCpnt->device->tagged_supported)
+ {
+ /*
+ * Some drives are too stupid to handle fairness issues
+ * with tagged queueing. We throw in the odd ordered
+ * tag to stop them starving themselves.
+ */
+ if((jiffies - hostdata->tagclock[SCpnt->target][SCpnt->lun]) > (5*HZ))
+ {
+ tag=0x01800000; /* ORDERED! */
+ hostdata->tagclock[SCpnt->target][SCpnt->lun]=jiffies;
+ }
+ else
+ {
+ /* Hmmm... I always see value of 0 here,
+ * of which {HEAD_OF, ORDERED, SIMPLE} are NOT! -sralston
+ */
+ if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
+ tag=0x01000000;
+ else if(SCpnt->tag == ORDERED_QUEUE_TAG)
+ tag=0x01800000;
+ }
+ }
+
+ /* Direction, disconnect ok, tag, CDBLen */
+ __raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
+
+ mptr=msg+5;
+
+ /*
+ * Write SCSI command into the message - always 16 byte block
+ */
+
+ memcpy_toio(mptr, SCpnt->cmnd, 16);
+ mptr+=4;
+ lenptr=mptr++; /* Remember me - fill in when we know */
+
+ reqlen = 12; // SINGLE SGE
+
+ /*
+ * Now fill in the SGList and command
+ *
+ * FIXME: we need to set the sglist limits according to the
+ * message size of the I2O controller. We might only have room
+ * for 6 or so worst case
+ */
+
+ if(SCpnt->use_sg)
+ {
+ struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
+ int chain = 0;
+

+ len = 0;
+

+ if((sg_max_frags > 11) && (SCpnt->use_sg > 11))
+ {
+ chain = 1;
+ /*
+ * Need to chain!
+ */
+ __raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
+ __raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
+ mptr = (u32*)(sg_chain_pool + sg_chain_tag);
+ if (SCpnt->use_sg > max_sg_len)
+ {
+ max_sg_len = SCpnt->use_sg;
+ printk("i2o_scsi: Chain SG! SCpnt=%p, SG_FragCnt=%d, SG_idx=%d\n",
+ SCpnt, SCpnt->use_sg, sg_chain_tag);
+ }
+ if ( ++sg_chain_tag == SG_MAX_BUFS )
+ sg_chain_tag = 0;
+ for(i = 0 ; i < SCpnt->use_sg; i++)
+ {
+ *mptr++=direction|0x10000000|sg->length;
+ len+=sg->length;
+ *mptr++=virt_to_bus(sg->address);
+ sg++;
+ }
+ mptr[-2]=direction|0xD0000000|(sg-1)->length;
+ }
+ else
+ {
+ for(i = 0 ; i < SCpnt->use_sg; i++)
+ {
+ __raw_writel(direction|0x10000000|sg->length, mptr++);
+ len+=sg->length;
+ __raw_writel(virt_to_bus(sg->address), mptr++);
+ sg++;
+ }
+
+ /* Make this an end of list. Again evade the 920 bug and
+ unwanted PCI read traffic */
+
+ __raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
+ }
+
+ if(!chain)
+ reqlen = mptr - msg;
+
+ __raw_writel(len, lenptr);
+
+ if(len != SCpnt->underflow)
+ printk("Cmd len %08X Cmd underflow %08X\n",
+ len, SCpnt->underflow);
+ }
+ else
+ {
+ dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
+ SCpnt->request_bufflen));
+ __raw_writel(len = SCpnt->request_bufflen, lenptr);
+ if(len == 0)
+ {
+ reqlen = 9;
+ }
+ else
+ {
+ __raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
+ __raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
+ }
+ }
+
+ /*
+ * Stick the headers on
+ */
+
+ __raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
+
+ /* Queue the message */
+ i2o_post_message(c,m);
+
+ atomic_inc(&queue_depth);
+
+ if(atomic_read(&queue_depth)> max_qd)
+ {
+ max_qd=atomic_read(&queue_depth);
+ printk("Queue depth now %d.\n", max_qd);
+ }
+
+ mb();
+ dprintk(("Issued %ld\n", current_command->serial_number));
+

+ return 0;
+}
+

+static void internal_done(Scsi_Cmnd * SCpnt)
+{
+ SCpnt->SCp.Status++;
+}
+
+int i2o_scsi_command(Scsi_Cmnd * SCpnt)
+{
+ i2o_scsi_queuecommand(SCpnt, internal_done);
+ SCpnt->SCp.Status = 0;
+ while (!SCpnt->SCp.Status)
+ barrier();
+ return SCpnt->result;
+}
+
+int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+{
+ struct i2o_controller *c;
+ struct Scsi_Host *host;
+ struct i2o_scsi_host *hostdata;
+ u32 *msg;
+ u32 m;
+ int tid;
+
+ printk("i2o_scsi: Aborting command block.\n");
+
+ host = SCpnt->host;
+ hostdata = (struct i2o_scsi_host *)host->hostdata;
+ tid = hostdata->task[SCpnt->target][SCpnt->lun];
+ if(tid==-1)
+ {
+ printk(KERN_ERR "impossible command to abort.\n");
+ return SCSI_ABORT_NOT_RUNNING;
+ }
+ c = hostdata->controller;
+
+ /*
+ * Obtain an I2O message. Right now we _have_ to obtain one
+ * until the scsi layer stuff is cleaned up.
+ */
+
+ do


+ {
+ mb();
+ m = I2O_POST_READ32(c);
+ }

+ while(m==0xFFFFFFFF);
+ msg = (u32 *)(c->mem_offset + m);
+
+ __raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]);
+ __raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]);
+ __raw_writel(scsi_context, &msg[2]);
+ __raw_writel(0, &msg[3]); /* Not needed for an abort */
+ __raw_writel((u32)SCpnt, &msg[4]);
+ wmb();
+ i2o_post_message(c,m);
+ wmb();
+ return SCSI_ABORT_PENDING;
+}
+
+int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+{
+ int tid;
+ struct i2o_controller *c;
+ struct Scsi_Host *host;
+ struct i2o_scsi_host *hostdata;


+ u32 m;
+ u32 *msg;

+
+ /*
+ * Find the TID for the bus
+ */
+
+ printk("i2o_scsi: Attempting to reset the bus.\n");
+
+ host = SCpnt->host;
+ hostdata = (struct i2o_scsi_host *)host->hostdata;
+ tid = hostdata->bus_task;
+ c = hostdata->controller;
+
+ /*
+ * Now send a SCSI reset request. Any remaining commands
+ * will be aborted by the IOP. We need to catch the reply
+ * possibly ?
+ */
+
+ m = I2O_POST_READ32(c);
+
+ /*
+ * No free messages, try again next time - no big deal
+ */


+
+ if(m == 0xFFFFFFFF)

+ return SCSI_RESET_PUNT;
+

+ msg = (u32 *)(c->mem_offset + m);

+ __raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
+ __raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]);
+ __raw_writel(scsi_context|0x80000000, &msg[2]);
+ /* We use the top bit to split controller and unit transactions */
+ /* Now store unit,tid so we can tie the completion back to a specific device */
+ __raw_writel(c->unit << 16 | tid, &msg[3]);
+ wmb();
+ i2o_post_message(c,m);
+ return SCSI_RESET_PENDING;
+}
+
+/*
+ * This is anyones guess quite frankly.
+ */
+
+int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
+{
+ int size;
+
+ size = disk->capacity;
+ ip[0] = 64; /* heads */
+ ip[1] = 32; /* sectors */
+ if ((ip[2] = size >> 11) > 1024) { /* cylinders, test for big disk */
+ ip[0] = 255; /* heads */
+ ip[1] = 63; /* sectors */
+ ip[2] = size / (255 * 63); /* cylinders */


+ }
+ return 0;
+}
+

+MODULE_AUTHOR("Red Hat Software");


+MODULE_LICENSE("GPL");
+
+

+static Scsi_Host_Template driver_template = I2OSCSI;
+
+#include "../../scsi/scsi_module.c"
diff -u --recursive --new-file v2.4.12/linux/drivers/message/i2o/i2o_scsi.h linux/drivers/message/i2o/i2o_scsi.h
--- v2.4.12/linux/drivers/message/i2o/i2o_scsi.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/message/i2o/i2o_scsi.h Mon Dec 11 13:20:04 2000
@@ -0,0 +1,47 @@
+#ifndef _I2O_SCSI_H
+#define _I2O_SCSI_H
+
+#if !defined(LINUX_VERSION_CODE)
+#include <linux/version.h>
+#endif
+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+
+#define I2O_SCSI_ID 15
+#define I2O_SCSI_CAN_QUEUE 4
+#define I2O_SCSI_CMD_PER_LUN 6
+
+extern int i2o_scsi_detect(Scsi_Host_Template *);
+extern const char *i2o_scsi_info(struct Scsi_Host *);
+extern int i2o_scsi_command(Scsi_Cmnd *);
+extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int i2o_scsi_abort(Scsi_Cmnd *);
+extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
+extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
+extern void i2o_scsi_setup(char *str, int *ints);
+extern int i2o_scsi_release(struct Scsi_Host *host);
+
+#define I2OSCSI { \
+ next: NULL, \
+ proc_name: "i2o_scsi", \
+ name: "I2O SCSI Layer", \
+ detect: i2o_scsi_detect, \
+ release: i2o_scsi_release, \
+ info: i2o_scsi_info, \
+ command: i2o_scsi_command, \
+ queuecommand: i2o_scsi_queuecommand, \
+ abort: i2o_scsi_abort, \
+ reset: i2o_scsi_reset, \
+ bios_param: i2o_scsi_bios_param, \
+ can_queue: I2O_SCSI_CAN_QUEUE, \
+ this_id: I2O_SCSI_ID, \
+ sg_tablesize: 8, \
+ cmd_per_lun: I2O_SCSI_CMD_PER_LUN, \
+ unchecked_isa_dma: 0, \
+ use_clustering: ENABLE_CLUSTERING \
+ }
+
+#endif
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/Config.in linux/drivers/mtd/Config.in
--- v2.4.12/linux/drivers/mtd/Config.in Tue Oct 9 17:06:51 2001
+++ linux/drivers/mtd/Config.in Thu Oct 11 09:14:32 2001
@@ -13,10 +13,10 @@
X fi
X dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
X dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
-if [ "$CONFIG_ARM" = "y" ]; then
- dep_tristate ' Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
- dep_tristate ' ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
-fi
+ if [ "$CONFIG_ARM" = "y" ]; then
+ dep_tristate ' Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
+ dep_tristate ' ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
+ fi
X
X comment 'User Modules And Translation Layers'
X dep_tristate ' Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- v2.4.12/linux/drivers/mtd/ftl.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/mtd/ftl.c Mon Oct 15 13:27:52 2001
@@ -1174,7 +1174,7 @@
X put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start);


X break;
X case BLKGETSIZE:

- ret = put_user(ftl_hd[minor].nr_sects, (long *)arg);
+ ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);


X break;
X case BLKGETSIZE64:

X ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg);
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
--- v2.4.12/linux/drivers/mtd/mtdblock.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/mtd/mtdblock.c Mon Oct 15 13:27:52 2001


@@ -539,7 +539,7 @@
X

X switch (cmd) {
X case BLKGETSIZE: /* Return device size */
- return put_user((mtdblk->mtd->size >> 9), (long *) arg);
+ return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
--- v2.4.12/linux/drivers/mtd/mtdblock_ro.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/mtd/mtdblock_ro.c Mon Oct 15 13:27:52 2001


@@ -213,7 +213,7 @@
X

X switch (cmd) {
X case BLKGETSIZE: /* Return device size */
- return put_user((mtd->size >> 9), (long *) arg);
+ return put_user((mtd->size >> 9), (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)mtd->size, (u64 *)arg);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- v2.4.12/linux/drivers/mtd/nftlcore.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/mtd/nftlcore.c Mon Oct 15 13:27:52 2001
@@ -804,7 +804,7 @@
X }
X case BLKGETSIZE: /* Return device size */
X return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,


- (long *) arg);
+ (unsigned long *) arg);

X case BLKGETSIZE64:
X return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
X (u64 *)arg);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/8139cp.c linux/drivers/net/8139cp.c
--- v2.4.12/linux/drivers/net/8139cp.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/8139cp.c Fri Oct 19 08:32:28 2001
@@ -0,0 +1,1325 @@
+/* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */
+/*
+ Copyright 2001 Jeff Garzik <jga...@mandrakesoft.com>
+
+ Copyright (C) 2000, 2001 David S. Miller (da...@redhat.com) [sungem.c]
+ Copyright 2001 Manfred Spraul [natsemi.c]
+ Copyright 1999-2001 by Donald Becker. [natsemi.c]
+ Written 1997-2001 by Donald Becker. [8139too.c]
+ Copyright 1998-2001 by Jes Sorensen, <j...@trained-monkey.org>. [acenic.c]
+
+ 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.
+
+ See the file COPYING in this distribution for more information.
+
+ TODO:
+ * dev->tx_timeout
+ * Constants (module parms?) for Rx work limit
+ * support 64-bit PCI DMA
+ * ETHTOOL_[GS]SET, ETHTOOL_GREGS, ETHTOOL_[GS]WOL,
+ ETHTOOL_[GS]MSGLVL, ETHTOOL_NWAY_RST
+ * Complete reset on PciErr
+ * LinkChg and LenChg interrupts
+ * Consider Rx interrupt mitigation using TimerIntr
+ * Implement 8139C+ statistics dump
+ * Support forcing media type with a module parameter,
+ like dl2k.c/sundance.c
+ * Rx checksumming
+ * Tx checksumming
+ * Jumbo frames / dev->change_mtu
+ * Tx abort stops Tx DMA?
+ * Investigate IntrStatus bit 10 purpose and use
+ * Investigate using skb->priority with h/w VLAN priority
+ * Investigate using High Priority Tx Queue with skb->priority
+ * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
+ * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
+
+ */
+
+#define DRV_NAME "8139cp"
+#define DRV_VERSION "0.0.5"
+#define DRV_RELDATE "Oct 19, 2001"
+


+
+#include <linux/module.h>
+#include <linux/kernel.h>

+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>


+#include <asm/io.h>
+#include <asm/uaccess.h>
+

+/* These identify the driver base version and may not be removed. */
+static char version[] __devinitdata =
+KERN_INFO DRV_NAME " 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
+
+MODULE_AUTHOR("Jeff Garzik <jga...@mandrakesoft.com>");
+MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
+MODULE_LICENSE("GPL");
+
+static int debug = -1;
+MODULE_PARM (debug, "i");
+MODULE_PARM_DESC (debug, "8139cp bitmapped message enable number");
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+ The RTL chips use a 64 element hash table based on the Ethernet CRC. */
+static int multicast_filter_limit = 32;
+MODULE_PARM (multicast_filter_limit, "i");
+MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered multicast addresses");
+
+/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
+ || defined(__sparc_) || defined(__ia64__) \
+ || defined(__sh__) || defined(__mips__)
+static int rx_copybreak = 1518;
+#else
+static int rx_copybreak = 100;
+#endif
+MODULE_PARM (rx_copybreak, "i");
+MODULE_PARM_DESC (rx_copybreak, "8139cp Breakpoint at which Rx packets are copied");
+
+#define PFX DRV_NAME ": "
+
+#define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK)
+#define CP_REGS_SIZE (0xff + 1)
+#define CP_RX_RING_SIZE 64
+#define CP_TX_RING_SIZE 64
+#define CP_RING_BYTES \
+ ((sizeof(struct cp_desc) * CP_RX_RING_SIZE) + \
+ (sizeof(struct cp_desc) * CP_TX_RING_SIZE))
+#define NEXT_TX(N) (((N) + 1) & (CP_TX_RING_SIZE - 1))
+#define NEXT_RX(N) (((N) + 1) & (CP_RX_RING_SIZE - 1))
+#define TX_BUFFS_AVAIL(CP) \
+ (((CP)->tx_tail <= (CP)->tx_head) ? \
+ (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head : \
+ (CP)->tx_tail - (CP)->tx_head - 1)
+#define CP_CHIP_VERSION 0x76
+
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+#define RX_OFFSET 2
+
+/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */
+#define RX_FIFO_THRESH 5 /* Rx buffer level before first PCI xfer. */
+#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 */
+#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
+#define TX_EARLY_THRESH 256 /* Early Tx threshold, in bytes */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT (6*HZ)
+
+
+enum {
+ /* NIC register offsets */
+ MAC0 = 0x00, /* Ethernet hardware address. */
+ MAR0 = 0x08, /* Multicast filter. */
+ TxRingAddr = 0x20, /* 64-bit start addr of Tx ring */
+ HiTxRingAddr = 0x28, /* 64-bit start addr of high priority Tx ring */
+ Cmd = 0x37, /* Command register */
+ IntrMask = 0x3C, /* Interrupt mask */
+ IntrStatus = 0x3E, /* Interrupt status */
+ TxConfig = 0x40, /* Tx configuration */
+ ChipVersion = 0x43, /* 8-bit chip version, inside TxConfig */
+ RxConfig = 0x44, /* Rx configuration */
+ Cfg9346 = 0x50, /* EEPROM select/control; Cfg reg [un]lock */
+ Config1 = 0x52, /* Config1 */
+ Config3 = 0x59, /* Config3 */
+ Config4 = 0x5A, /* Config4 */
+ MultiIntr = 0x5C, /* Multiple interrupt select */
+ Config5 = 0xD8, /* Config5 */
+ TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */
+ CpCmd = 0xE0, /* C+ Command register (C+ mode only) */
+ RxRingAddr = 0xE4, /* 64-bit start addr of Rx ring */
+ TxThresh = 0xEC, /* Early Tx threshold */
+ OldRxBufAddr = 0x30, /* DMA address of Rx ring buffer (C mode) */
+ OldTSD0 = 0x10, /* DMA address of first Tx desc (C mode) */
+
+ /* Tx and Rx status descriptors */
+ DescOwn = (1 << 31), /* Descriptor is owned by NIC */
+ RingEnd = (1 << 30), /* End of descriptor ring */
+ FirstFrag = (1 << 29), /* First segment of a packet */
+ LastFrag = (1 << 28), /* Final segment of a packet */
+ TxError = (1 << 23), /* Tx error summary */
+ RxError = (1 << 20), /* Rx error summary */
+ IPCS = (1 << 18), /* Calculate IP checksum */
+ UDPCS = (1 << 17), /* Calculate UDP/IP checksum */
+ TCPCS = (1 << 16), /* Calculate TCP/IP checksum */
+ IPFail = (1 << 15), /* IP checksum failed */
+ UDPFail = (1 << 14), /* UDP/IP checksum failed */
+ TCPFail = (1 << 13), /* TCP/IP checksum failed */
+ NormalTxPoll = (1 << 6), /* One or more normal Tx packets to send */
+ PID1 = (1 << 17), /* 2 protocol id bits: 0==non-IP, */
+ PID0 = (1 << 16), /* 1==UDP/IP, 2==TCP/IP, 3==IP */
+ TxFIFOUnder = (1 << 25), /* Tx FIFO underrun */
+ TxOWC = (1 << 22), /* Tx Out-of-window collision */
+ TxLinkFail = (1 << 21), /* Link failed during Tx of packet */
+ TxMaxCol = (1 << 20), /* Tx aborted due to excessive collisions */
+ TxColCntShift = 16, /* Shift, to get 4-bit Tx collision cnt */
+ TxColCntMask = 0x01 | 0x02 | 0x04 | 0x08, /* 4-bit collision count */
+ RxErrFrame = (1 << 27), /* Rx frame alignment error */
+ RxMcast = (1 << 26), /* Rx multicast packet rcv'd */
+ RxErrCRC = (1 << 18), /* Rx CRC error */
+ RxErrRunt = (1 << 19), /* Rx error, packet < 64 bytes */
+ RxErrLong = (1 << 21), /* Rx error, packet > 4096 bytes */
+ RxErrFIFO = (1 << 22), /* Rx error, FIFO overflowed, pkt bad */
+
+ /* RxConfig register */
+ RxCfgFIFOShift = 13, /* Shift, to get Rx FIFO thresh value */
+ RxCfgDMAShift = 8, /* Shift, to get Rx Max DMA value */
+ AcceptErr = 0x20, /* Accept packets with CRC errors */
+ AcceptRunt = 0x10, /* Accept runt (<64 bytes) packets */
+ AcceptBroadcast = 0x08, /* Accept broadcast packets */
+ AcceptMulticast = 0x04, /* Accept multicast packets */
+ AcceptMyPhys = 0x02, /* Accept pkts with our MAC as dest */
+ AcceptAllPhys = 0x01, /* Accept all pkts w/ physical dest */
+
+ /* IntrMask / IntrStatus registers */
+ PciErr = (1 << 15), /* System error on the PCI bus */
+ TimerIntr = (1 << 14), /* Asserted when TCTR reaches TimerInt value */
+ LenChg = (1 << 13), /* Cable length change */
+ SWInt = (1 << 8), /* Software-requested interrupt */
+ TxEmpty = (1 << 7), /* No Tx descriptors available */
+ RxFIFOOvr = (1 << 6), /* Rx FIFO Overflow */
+ LinkChg = (1 << 5), /* Packet underrun, or link change */
+ RxEmpty = (1 << 4), /* No Rx descriptors available */
+ TxErr = (1 << 3), /* Tx error */
+ TxOK = (1 << 2), /* Tx packet sent */
+ RxErr = (1 << 1), /* Rx error */
+ RxOK = (1 << 0), /* Rx packet received */
+ IntrResvd = (1 << 10), /* reserved, according to RealTek engineers,
+ but hardware likes to raise it */
+
+ IntrAll = PciErr | TimerIntr | LenChg | SWInt | TxEmpty |
+ RxFIFOOvr | LinkChg | RxEmpty | TxErr | TxOK |
+ RxErr | RxOK | IntrResvd,
+
+ /* C mode command register */
+ CmdReset = (1 << 4), /* Enable to reset; self-clearing */
+ RxOn = (1 << 3), /* Rx mode enable */
+ TxOn = (1 << 2), /* Tx mode enable */
+
+ /* C+ mode command register */
+ RxChkSum = (1 << 5), /* Rx checksum offload enable */
+ PCIMulRW = (1 << 3), /* Enable PCI read/write multiple */
+ CpRxOn = (1 << 1), /* Rx mode enable */
+ CpTxOn = (1 << 0), /* Tx mode enable */
+
+ /* Cfg9436 EEPROM control register */
+ Cfg9346_Lock = 0x00, /* Lock ConfigX/MII register access */
+ Cfg9346_Unlock = 0xC0, /* Unlock ConfigX/MII register access */
+
+ /* TxConfig register */
+ IFG = (1 << 25) | (1 << 24), /* standard IEEE interframe gap */
+ TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
+
+ /* Early Tx Threshold register */
+ TxThreshMask = 0x3f, /* Mask bits 5-0 */
+ TxThreshMax = 2048, /* Max early Tx threshold */
+
+ /* Config1 register */
+ DriverLoaded = (1 << 5), /* Software marker, driver is loaded */
+ PMEnable = (1 << 0), /* Enable various PM features of chip */
+
+ /* Config3 register */
+ PARMEnable = (1 << 6), /* Enable auto-loading of PHY parms */
+
+ /* Config5 register */
+ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
+};
+
+static const unsigned int cp_intr_mask =
+ PciErr | LinkChg |
+ RxOK | RxErr | RxEmpty | RxFIFOOvr |
+ TxOK | TxErr | TxEmpty;
+
+static const unsigned int cp_rx_config =
+ (RX_FIFO_THRESH << RxCfgFIFOShift) |
+ (RX_DMA_BURST << RxCfgDMAShift);
+
+struct cp_desc {
+ u32 opts1;
+ u32 opts2;
+ u32 addr_lo;
+ u32 addr_hi;
+};
+
+struct ring_info {
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+ unsigned frag;
+};
+
+struct cp_extra_stats {
+ unsigned long rx_frags;
+};
+
+struct cp_private {
+ unsigned tx_head;
+ unsigned tx_tail;
+ unsigned rx_tail;
+
+ void *regs;
+ struct net_device *dev;
+ spinlock_t lock;
+
+ struct cp_desc *rx_ring;
+ struct cp_desc *tx_ring;
+ struct ring_info tx_skb[CP_TX_RING_SIZE];
+ struct ring_info rx_skb[CP_RX_RING_SIZE];
+ unsigned rx_buf_sz;
+ dma_addr_t ring_dma;
+
+ u32 msg_enable;
+
+ struct net_device_stats net_stats;
+ struct cp_extra_stats cp_stats;
+
+ struct pci_dev *pdev;
+ u32 rx_config;
+
+ struct sk_buff *frag_skb;
+ unsigned dropping_frag : 1;
+};
+
+#define cpr8(reg) readb(cp->regs + (reg))
+#define cpr16(reg) readw(cp->regs + (reg))
+#define cpr32(reg) readl(cp->regs + (reg))
+#define cpw8(reg,val) writeb((val), cp->regs + (reg))
+#define cpw16(reg,val) writew((val), cp->regs + (reg))
+#define cpw32(reg,val) writel((val), cp->regs + (reg))
+#define cpw8_f(reg,val) do { \
+ writeb((val), cp->regs + (reg)); \
+ readb(cp->regs + (reg)); \
+ } while (0)
+#define cpw16_f(reg,val) do { \
+ writew((val), cp->regs + (reg)); \
+ readw(cp->regs + (reg)); \
+ } while (0)
+#define cpw32_f(reg,val) do { \
+ writel((val), cp->regs + (reg)); \
+ readl(cp->regs + (reg)); \
+ } while (0)
+
+
+static void __cp_set_rx_mode (struct net_device *dev);
+static void cp_tx (struct cp_private *cp);
+static void cp_clean_rings (struct cp_private *cp);
+
+
+static struct pci_device_id cp_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
+
+static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans (skb, cp->dev);
+
+ cp->net_stats.rx_packets++;
+ cp->net_stats.rx_bytes += skb->len;
+ cp->dev->last_rx = jiffies;
+ netif_rx (skb);
+}
+
+static inline void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
+ u32 status, u32 len)
+{
+ if (netif_msg_rx_err (cp))
+ printk (KERN_DEBUG
+ "%s: rx err, slot %d status 0x%x len %d\n",
+ cp->dev->name, rx_tail, status, len);
+ cp->net_stats.rx_errors++;
+ if (status & RxErrFrame)
+ cp->net_stats.rx_frame_errors++;
+ if (status & RxErrCRC)
+ cp->net_stats.rx_crc_errors++;
+ if (status & RxErrRunt)
+ cp->net_stats.rx_length_errors++;
+ if (status & RxErrLong)
+ cp->net_stats.rx_length_errors++;
+ if (status & RxErrFIFO)
+ cp->net_stats.rx_fifo_errors++;
+}
+
+static void cp_rx_frag (struct cp_private *cp, unsigned rx_tail,
+ struct sk_buff *skb, u32 status, u32 len)
+{
+ struct sk_buff *copy_skb, *frag_skb = cp->frag_skb;
+ unsigned orig_len = frag_skb ? frag_skb->len : 0;
+ unsigned target_len = orig_len + len;
+ unsigned first_frag = status & FirstFrag;
+ unsigned last_frag = status & LastFrag;
+
+ if (netif_msg_rx_status (cp))
+ printk (KERN_DEBUG "%s: rx %s%sfrag, slot %d status 0x%x len %d\n",
+ cp->dev->name,
+ cp->dropping_frag ? "dropping " : "",
+ first_frag ? "first " :
+ last_frag ? "last " : "",
+ rx_tail, status, len);
+
+ cp->cp_stats.rx_frags++;
+
+ if (!frag_skb && !first_frag)
+ cp->dropping_frag = 1;
+ if (cp->dropping_frag)
+ goto drop_frag;
+
+ copy_skb = dev_alloc_skb (target_len + RX_OFFSET);
+ if (!copy_skb) {
+ printk(KERN_WARNING "%s: rx slot %d alloc failed\n",
+ cp->dev->name, rx_tail);
+
+ cp->dropping_frag = 1;
+drop_frag:
+ if (frag_skb) {
+ dev_kfree_skb_irq(frag_skb);
+ cp->frag_skb = NULL;
+ }
+ if (last_frag) {
+ cp->net_stats.rx_dropped++;
+ cp->dropping_frag = 0;


+ }
+ return;
+ }
+

+ copy_skb->dev = cp->dev;
+ skb_reserve(copy_skb, RX_OFFSET);
+ skb_put(copy_skb, target_len);
+ if (frag_skb) {
+ memcpy(copy_skb->data, frag_skb->data, orig_len);
+ dev_kfree_skb_irq(frag_skb);
+ }
+ pci_dma_sync_single(cp->pdev, cp->rx_skb[rx_tail].mapping,
+ len, PCI_DMA_FROMDEVICE);
+ memcpy(copy_skb->data + orig_len, skb->data, len);
+
+ copy_skb->ip_summed = CHECKSUM_NONE;
+
+ if (last_frag) {
+ if (status & (RxError | RxErrFIFO)) {
+ cp_rx_err_acct(cp, rx_tail, status, len);
+ dev_kfree_skb_irq(copy_skb);
+ } else
+ cp_rx_skb(cp, copy_skb);
+ cp->frag_skb = NULL;
+ } else {
+ cp->frag_skb = copy_skb;
+ }
+}
+
+static void cp_rx (struct cp_private *cp)
+{
+ unsigned rx_tail = cp->rx_tail;
+ unsigned rx_work = 100;
+
+ while (rx_work--) {
+ u32 status, len;
+ dma_addr_t mapping;
+ struct sk_buff *skb, *copy_skb;
+ unsigned copying_skb, buflen;
+
+ skb = cp->rx_skb[rx_tail].skb;
+ if (!skb)
+ BUG();
+ rmb();
+ status = le32_to_cpu(cp->rx_ring[rx_tail].opts1);
+ if (status & DescOwn)
+ break;
+
+ len = (status & 0x1fff) - 4;
+ mapping = cp->rx_skb[rx_tail].mapping;
+
+ if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
+ cp_rx_frag(cp, rx_tail, skb, status, len);
+ goto rx_next;
+ }
+
+ if (status & (RxError | RxErrFIFO)) {
+ cp_rx_err_acct(cp, rx_tail, status, len);
+ goto rx_next;
+ }
+
+ copying_skb = (len <= rx_copybreak);
+
+ if (netif_msg_rx_status(cp))
+ printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d copying? %d\n",
+ cp->dev->name, rx_tail, status, len,
+ copying_skb);
+
+ buflen = copying_skb ? len : cp->rx_buf_sz;
+ copy_skb = dev_alloc_skb (buflen + RX_OFFSET);
+ if (!copy_skb) {
+ cp->net_stats.rx_dropped++;
+ goto rx_next;
+ }
+
+ skb_reserve(copy_skb, RX_OFFSET);
+ copy_skb->dev = cp->dev;
+
+ if (!copying_skb) {
+ pci_unmap_single(cp->pdev, mapping,
+ buflen, PCI_DMA_FROMDEVICE);
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_trim(skb, len);
+
+ mapping =
+ cp->rx_skb[rx_tail].mapping =
+ pci_map_single(cp->pdev, copy_skb->data,
+ buflen, PCI_DMA_FROMDEVICE);
+ cp->rx_skb[rx_tail].skb = copy_skb;
+ skb_put(copy_skb, buflen);
+ } else {
+ skb_put(copy_skb, len);
+ pci_dma_sync_single(cp->pdev, mapping, len, PCI_DMA_FROMDEVICE);
+ memcpy(copy_skb->data, skb->data, len);
+
+ /* We'll reuse the original ring buffer. */
+ skb = copy_skb;
+ }
+
+ cp_rx_skb(cp, skb);
+
+rx_next:
+ if (rx_tail == (CP_RX_RING_SIZE - 1))
+ cp->rx_ring[rx_tail].opts1 =
+ cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
+ else
+ cp->rx_ring[rx_tail].opts1 =
+ cpu_to_le32(DescOwn | cp->rx_buf_sz);
+ cp->rx_ring[rx_tail].opts2 = 0;
+ cp->rx_ring[rx_tail].addr_lo = cpu_to_le32(mapping);
+ rx_tail = NEXT_RX(rx_tail);
+ }
+
+ if (!rx_work)
+ printk(KERN_WARNING "%s: rx work limit reached\n", cp->dev->name);
+
+ cp->rx_tail = rx_tail;
+}
+
+static void cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_instance;
+ struct cp_private *cp = dev->priv;
+ u16 status;
+
+ status = cpr16(IntrStatus);
+ if (!status || (status == 0xFFFF))
+ return;
+
+ if (netif_msg_intr(cp))
+ printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
+ dev->name, status, cpr8(Cmd), cpr16(CpCmd));
+
+ spin_lock(&cp->lock);
+
+ if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
+ cp_rx(cp);
+ if (status & (TxOK | TxErr | TxEmpty | SWInt))
+ cp_tx(cp);
+
+ cpw16_f(IntrStatus, status);
+
+ if (status & PciErr) {
+ u16 pci_status;
+
+ pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
+ pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
+ printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
+ dev->name, status, pci_status);
+ }
+
+ spin_unlock(&cp->lock);
+}
+
+static void cp_tx (struct cp_private *cp)
+{
+ unsigned tx_head = cp->tx_head;
+ unsigned tx_tail = cp->tx_tail;
+
+ while (tx_tail != tx_head) {
+ struct sk_buff *skb;
+ u32 status;
+
+ rmb();
+ status = le32_to_cpu(cp->tx_ring[tx_tail].opts1);
+ if (status & DescOwn)
+ break;
+
+ skb = cp->tx_skb[tx_tail].skb;
+ if (!skb)
+ BUG();
+
+ pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
+ skb->len, PCI_DMA_TODEVICE);
+
+ if (status & LastFrag) {
+ if (status & (TxError | TxFIFOUnder)) {
+ if (netif_msg_tx_err(cp))
+ printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
+ cp->dev->name, status);
+ cp->net_stats.tx_errors++;
+ if (status & TxOWC)
+ cp->net_stats.tx_window_errors++;
+ if (status & TxMaxCol)
+ cp->net_stats.tx_aborted_errors++;
+ if (status & TxLinkFail)
+ cp->net_stats.tx_carrier_errors++;
+ if (status & TxFIFOUnder)
+ cp->net_stats.tx_fifo_errors++;
+ } else {
+ cp->net_stats.collisions +=
+ ((status >> TxColCntShift) & TxColCntMask);
+ cp->net_stats.tx_packets++;
+ cp->net_stats.tx_bytes += skb->len;
+ if (netif_msg_tx_done(cp))
+ printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);


+ }
+ dev_kfree_skb_irq(skb);
+ }
+

+ cp->tx_skb[tx_tail].skb = NULL;
+
+ tx_tail = NEXT_TX(tx_tail);
+ }
+
+ cp->tx_tail = tx_tail;
+
+ if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > 1))
+ netif_wake_queue(cp->dev);
+}
+
+static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
+{
+ struct cp_private *cp = dev->priv;
+ unsigned entry;
+ u32 eor;
+
+ spin_lock_irq(&cp->lock);
+
+ if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
+ netif_stop_queue(dev);
+ spin_unlock_irq(&cp->lock);


+ return 1;
+ }
+

+ entry = cp->tx_head;
+ eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+ if (skb_shinfo(skb)->nr_frags == 0) {
+ struct cp_desc *txd = &cp->tx_ring[entry];
+ u32 mapping, len;
+
+ len = skb->len;
+ mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+#ifdef CP_TX_CHECKSUM
+ txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag |
+ LastFrag | IPCS | UDPCS | TCPCS);
+#else
+ txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag |
+ LastFrag);
+#endif
+ txd->opts2 = 0;
+ txd->addr_lo = cpu_to_le32(mapping);
+
+ cp->tx_skb[entry].skb = skb;
+ cp->tx_skb[entry].mapping = mapping;
+ cp->tx_skb[entry].frag = 0;
+ wmb();
+ entry = NEXT_TX(entry);
+ } else {
+ struct cp_desc *txd;
+ u32 first_len, first_mapping;
+ int frag, first_entry = entry;
+
+ /* We must give this initial chunk to the device last.
+ * Otherwise we could race with the device.
+ */
+ first_len = skb->len - skb->data_len;
+ first_mapping = pci_map_single(cp->pdev, skb->data,
+ first_len, PCI_DMA_TODEVICE);
+ cp->tx_skb[entry].skb = skb;
+ cp->tx_skb[entry].mapping = first_mapping;
+ cp->tx_skb[entry].frag = 1;
+ entry = NEXT_TX(entry);
+
+ for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+ skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
+ u32 len, mapping;
+ u32 ctrl;
+
+ len = this_frag->size;
+ mapping = pci_map_single(cp->pdev,
+ ((void *) page_address(this_frag->page) +
+ this_frag->page_offset),
+ len, PCI_DMA_TODEVICE);
+ eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+#ifdef CP_TX_CHECKSUM
+ ctrl = eor | len | DescOwn | IPCS | UDPCS | TCPCS;
+#else
+ ctrl = eor | len | DescOwn;
+#endif
+ if (frag == skb_shinfo(skb)->nr_frags - 1)
+ ctrl |= LastFrag;
+
+ txd = &cp->tx_ring[entry];
+ txd->opts1 = cpu_to_le32(ctrl);
+ txd->opts2 = 0;
+ txd->addr_lo = cpu_to_le32(mapping);
+
+ cp->tx_skb[entry].skb = skb;
+ cp->tx_skb[entry].mapping = mapping;
+ cp->tx_skb[entry].frag = frag + 2;
+ wmb();
+ entry = NEXT_TX(entry);
+ }
+ txd = &cp->tx_ring[first_entry];
+#ifdef CP_TX_CHECKSUM
+ txd->opts1 = cpu_to_le32(first_len | FirstFrag | DescOwn | IPCS | UDPCS | TCPCS);
+#else
+ txd->opts1 = cpu_to_le32(first_len | FirstFrag | DescOwn);
+#endif
+ txd->opts2 = 0;
+ txd->addr_lo = cpu_to_le32(first_mapping);
+ wmb();
+ }
+ cp->tx_head = entry;
+ if (netif_msg_tx_queued(cp))
+ printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
+ dev->name, entry, skb->len);
+ if (TX_BUFFS_AVAIL(cp) < 0)
+ BUG();
+ if (TX_BUFFS_AVAIL(cp) == 0)
+ netif_stop_queue(dev);
+
+ spin_unlock_irq(&cp->lock);
+
+ cpw8(TxPoll, NormalTxPoll);


+ dev->trans_start = jiffies;

+
+ return 0;
+}
+

+/* Set or clear the multicast filter for this adaptor.
+ This routine is not state sensitive and need not be SMP locked. */
+
+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 __cp_set_rx_mode (struct net_device *dev)
+{
+ struct cp_private *cp = dev->priv;
+ u32 mc_filter[2]; /* Multicast hash filter */
+ int i, rx_mode;
+ u32 tmp;
+
+ /* Note: do not reorder, GCC is clever about common statements. */


+ if (dev->flags & IFF_PROMISC) {

+ /* Unconditionally log net taps. */
+ printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n",
+ dev->name);
+ rx_mode =
+ AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+ AcceptAllPhys;
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to filter perfectly -- accept all multicasts. */
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
+ } else {
+ struct dev_mc_list *mclist;
+ rx_mode = AcceptBroadcast | AcceptMyPhys;
+ mc_filter[1] = mc_filter[0] = 0;
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next) {
+ int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+
+ mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+ rx_mode |= AcceptMulticast;
+ }
+ }
+
+ /* We can safely update without stopping the chip. */
+ tmp = cp_rx_config | rx_mode;
+ if (cp->rx_config != tmp) {
+ cpw32_f (RxConfig, tmp);
+ cp->rx_config = tmp;
+ }
+ cpw32_f (MAR0 + 0, mc_filter[0]);
+ cpw32_f (MAR0 + 4, mc_filter[1]);
+}
+
+static void cp_set_rx_mode (struct net_device *dev)


+{
+ unsigned long flags;

+ struct cp_private *cp = dev->priv;
+
+ spin_lock_irqsave (&cp->lock, flags);
+ __cp_set_rx_mode(dev);
+ spin_unlock_irqrestore (&cp->lock, flags);
+}
+
+static void __cp_get_stats(struct cp_private *cp)
+{
+ /* XXX implement */
+}
+
+static struct net_device_stats *cp_get_stats(struct net_device *dev)
+{
+ struct cp_private *cp = dev->priv;
+
+ /* The chip only need report frame silently dropped. */
+ spin_lock_irq(&cp->lock);
+ if (netif_running(dev) && netif_device_present(dev))
+ __cp_get_stats(cp);
+ spin_unlock_irq(&cp->lock);
+
+ return &cp->net_stats;
+}
+
+static void cp_stop_hw (struct cp_private *cp)
+{
+ cpw16(IntrMask, 0);
+ cpr16(IntrMask);
+ cpw8(Cmd, 0);
+ cpw16(CpCmd, 0);
+ cpr16(CpCmd);
+ cpw16(IntrStatus, ~(cpr16(IntrStatus)));
+ synchronize_irq();
+ udelay(10);
+
+ cp->rx_tail = 0;
+ cp->tx_head = cp->tx_tail = 0;
+}
+
+static void cp_reset_hw (struct cp_private *cp)
+{
+ unsigned work = 1000;
+
+ cpw8(Cmd, CmdReset);
+
+ while (work--) {
+ if (!(cpr8(Cmd) & CmdReset))
+ return;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(10);
+ }
+
+ printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
+}
+
+static void cp_init_hw (struct cp_private *cp)
+{
+ struct net_device *dev = cp->dev;
+
+ cp_reset_hw(cp);
+
+ cpw8_f (Cfg9346, Cfg9346_Unlock);
+
+ /* Restore our idea of the MAC address. */
+ cpw32_f (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+ cpw32_f (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+
+ cpw8(Cmd, RxOn | TxOn);
+ cpw16(CpCmd, PCIMulRW | CpRxOn | CpTxOn);
+ cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
+
+ __cp_set_rx_mode(dev);
+ cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift));
+
+ cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
+ cpw8(Config3, PARMEnable); /* disables magic packet and WOL */
+ cpw8(Config5, cpr8(Config5) & PMEStatus); /* disables more WOL stuff */
+
+ cpw32_f(HiTxRingAddr, 0);
+ cpw32_f(HiTxRingAddr + 4, 0);
+ cpw32_f(OldRxBufAddr, 0);
+ cpw32_f(OldTSD0, 0);
+ cpw32_f(OldTSD0 + 4, 0);
+ cpw32_f(OldTSD0 + 8, 0);
+ cpw32_f(OldTSD0 + 12, 0);
+
+ cpw32_f(RxRingAddr, cp->ring_dma);
+ cpw32_f(RxRingAddr + 4, 0);
+ cpw32_f(TxRingAddr, cp->ring_dma + (sizeof(struct cp_desc) * CP_RX_RING_SIZE));
+ cpw32_f(TxRingAddr + 4, 0);
+
+ cpw16(MultiIntr, 0);
+
+ cpw16(IntrMask, cp_intr_mask);
+
+ cpw8_f (Cfg9346, Cfg9346_Lock);
+}
+
+static int cp_refill_rx (struct cp_private *cp)
+{
+ unsigned i;
+
+ for (i = 0; i < CP_RX_RING_SIZE; i++) {


+ struct sk_buff *skb;
+

+ skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET);
+ if (!skb)
+ goto err_out;
+
+ skb->dev = cp->dev;
+ skb_reserve(skb, RX_OFFSET);
+ skb_put(skb, cp->rx_buf_sz);
+
+ cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
+ skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ cp->rx_skb[i].skb = skb;
+ cp->rx_skb[i].frag = 0;
+
+ if (i == (CP_RX_RING_SIZE - 1))
+ cp->rx_ring[i].opts1 =
+ cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
+ else
+ cp->rx_ring[i].opts1 =
+ cpu_to_le32(DescOwn | cp->rx_buf_sz);
+ cp->rx_ring[i].opts2 = 0;
+ cp->rx_ring[i].addr_lo = cpu_to_le32(cp->rx_skb[i].mapping);
+ cp->rx_ring[i].addr_hi = 0;


+ }
+
+ return 0;
+

+err_out:
+ cp_clean_rings(cp);


+ return -ENOMEM;
+}
+

+static int cp_init_rings (struct cp_private *cp)
+{
+ memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
+ cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd);
+
+ cp->rx_tail = 0;
+ cp->tx_head = cp->tx_tail = 0;
+
+ return cp_refill_rx (cp);
+}
+
+static int cp_alloc_rings (struct cp_private *cp)
+{
+ cp->rx_ring = pci_alloc_consistent(cp->pdev, CP_RING_BYTES, &cp->ring_dma);
+ if (!cp->rx_ring)
+ return -ENOMEM;
+ cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
+ return cp_init_rings(cp);
+}
+
+static void cp_clean_rings (struct cp_private *cp)
+{
+ unsigned i;
+
+ memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
+ memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
+
+ for (i = 0; i < CP_RX_RING_SIZE; i++) {
+ if (cp->rx_skb[i].skb) {
+ pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,
+ cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(cp->rx_skb[i].skb);
+ }
+ }
+
+ for (i = 0; i < CP_TX_RING_SIZE; i++) {
+ if (cp->tx_skb[i].skb) {
+ struct sk_buff *skb = cp->tx_skb[i].skb;
+ pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
+ cp->net_stats.tx_dropped++;
+ }
+ }
+
+ memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE);
+ memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE);
+}
+
+static void cp_free_rings (struct cp_private *cp)
+{
+ cp_clean_rings(cp);
+ pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);
+ cp->rx_ring = NULL;
+ cp->tx_ring = NULL;
+}
+
+static int cp_open (struct net_device *dev)
+{
+ struct cp_private *cp = dev->priv;
+ int rc;
+
+ if (netif_msg_ifup(cp))
+ printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
+
+ cp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+
+ rc = cp_alloc_rings(cp);
+ if (rc)
+ return rc;
+
+ cp_init_hw(cp);
+
+ rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev);
+ if (rc)
+ goto err_out_hw;
+
+ netif_start_queue(dev);


+
+ return 0;
+

+err_out_hw:
+ cp_stop_hw(cp);
+ cp_free_rings(cp);
+ return rc;
+}
+
+static int cp_close (struct net_device *dev)
+{
+ struct cp_private *cp = dev->priv;
+
+ if (netif_msg_ifdown(cp))
+ printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
+
+ netif_stop_queue(dev);
+ cp_stop_hw(cp);
+ free_irq(dev->irq, dev);
+ cp_free_rings(cp);


+ return 0;
+}
+

+static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
+{
+ u32 ethcmd;
+
+ /* dev_ioctl() in ../../net/core/dev.c has already checked
+ capable(CAP_NET_ADMIN), so don't bother with that here. */
+
+ if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
+ return -EFAULT;
+
+ switch (ethcmd) {
+
+ case ETHTOOL_GDRVINFO:
+ {
+ struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+ strcpy (info.driver, DRV_NAME);
+ strcpy (info.version, DRV_VERSION);
+ strcpy (info.bus_info, cp->pdev->slot_name);
+ if (copy_to_user (useraddr, &info, sizeof (info)))
+ return -EFAULT;


+ return 0;
+ }
+

+ default:
+ break;
+ }
+

+ return -EOPNOTSUPP;
+}
+
+
+static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct cp_private *cp = dev->priv;
+ int rc = 0;
+
+ switch (cmd) {
+ case SIOCETHTOOL:
+ return cp_ethtool_ioctl(cp, (void *) rq->ifr_data);
+
+ default:
+ rc = -EOPNOTSUPP;
+ break;
+ }
+
+ return rc;
+}
+
+
+
+/* Serial EEPROM section. */
+
+/* EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
+#define EE_CS 0x08 /* EEPROM chip select. */
+#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
+#define EE_WRITE_0 0x00
+#define EE_WRITE_1 0x02
+#define EE_DATA_READ 0x01 /* EEPROM chip data out. */
+#define EE_ENB (0x80 | EE_CS)
+
+/* Delay between EEPROM clock transitions.
+ No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+ */
+
+#define eeprom_delay() readl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD (5)
+#define EE_READ_CMD (6)
+#define EE_ERASE_CMD (7)
+
+static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
+{
+ int i;
+ unsigned retval = 0;
+ void *ee_addr = ioaddr + Cfg9346;
+ int read_cmd = location | (EE_READ_CMD << addr_len);
+
+ writeb (EE_ENB & ~EE_CS, ee_addr);
+ writeb (EE_ENB, ee_addr);
+ eeprom_delay ();
+
+ /* Shift the read command bits out. */
+ for (i = 4 + addr_len; i >= 0; i--) {
+ int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ writeb (EE_ENB | dataval, ee_addr);
+ eeprom_delay ();
+ writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay ();
+ }
+ writeb (EE_ENB, ee_addr);
+ eeprom_delay ();
+
+ for (i = 16; i > 0; i--) {
+ writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay ();
+ retval =
+ (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
+ 0);
+ writeb (EE_ENB, ee_addr);
+ eeprom_delay ();
+ }
+
+ /* Terminate the EEPROM access. */
+ writeb (~EE_CS, ee_addr);
+ eeprom_delay ();
+
+ return retval;
+}
+
+static int __devinit cp_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)


+{
+ struct net_device *dev;

+ struct cp_private *cp;
+ int rc;
+ void *regs;
+ long pciaddr;
+ unsigned addr_len, i;
+ u8 pci_rev, cache_size;
+ u16 pci_command;
+
+#ifndef MODULE
+ static int version_printed;
+ if (version_printed++ == 0)
+ printk("%s", version);
+#endif
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+ if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
+ pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) {
+ printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n",
+ pdev->slot_name, pdev->vendor, pdev->device, pci_rev);
+ printk(KERN_ERR PFX "Try the \"8139too\" driver instead.\n");
+ return -ENODEV;
+ }
+
+ dev = alloc_etherdev(sizeof(struct cp_private));
+ if (!dev)
+ return -ENOMEM;
+ SET_MODULE_OWNER(dev);
+ cp = dev->priv;
+ cp->pdev = pdev;
+ cp->dev = dev;
+ cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
+ spin_lock_init (&cp->lock);
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ goto err_out_free;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out_disable;
+
+ if (pdev->irq < 2) {
+ rc = -EIO;
+ printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",
+ pdev->irq, pdev->slot_name);
+ goto err_out_res;
+ }
+ pciaddr = pci_resource_start(pdev, 1);
+ if (!pciaddr) {
+ rc = -EIO;
+ printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n",
+ pdev->slot_name);
+ goto err_out_res;
+ }
+ if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) {
+ rc = -EIO;
+ printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n",
+ pci_resource_len(pdev, 1), pdev->slot_name);
+ goto err_out_res;
+ }
+
+ regs = ioremap_nocache(pciaddr, CP_REGS_SIZE);
+ if (!regs) {
+ rc = -EIO;
+ printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n",
+ pci_resource_len(pdev, 1), pciaddr, pdev->slot_name);
+ goto err_out_res;
+ }
+ dev->base_addr = (unsigned long) regs;
+ cp->regs = regs;
+
+ cp_stop_hw(cp);
+
+ /* read MAC address from EEPROM */
+ addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6;
+ for (i = 0; i < 3; i++)
+ ((u16 *) (dev->dev_addr))[i] =
+ le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+
+ dev->open = cp_open;
+ dev->stop = cp_close;
+ dev->set_multicast_list = cp_set_rx_mode;
+ dev->hard_start_xmit = cp_start_xmit;
+ dev->get_stats = cp_get_stats;
+ dev->do_ioctl = cp_ioctl;
+#if 0
+ dev->tx_timeout = cp_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+#endif
+#ifdef CP_TX_CHECKSUM
+ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#endif
+
+ dev->irq = pdev->irq;
+
+ rc = register_netdev(dev);
+ if (rc)
+ goto err_out_iomap;
+
+ printk (KERN_INFO "%s: %s at 0x%lx, "
+ "%02x:%02x:%02x:%02x:%02x:%02x, "
+ "IRQ %d\n",
+ dev->name,
+ "RTL-8139C+",
+ dev->base_addr,
+ dev->dev_addr[0], dev->dev_addr[1],
+ dev->dev_addr[2], dev->dev_addr[3],
+ dev->dev_addr[4], dev->dev_addr[5],
+ dev->irq);
+
+ pci_set_drvdata(pdev, dev);
+
+ /*
+ * Looks like this is necessary to deal with on all architectures,
+ * even this %$#%$# N440BX Intel based thing doesn't get it right.
+ * Ie. having two NICs in the machine, one will have the cache
+ * line set at boot time, the other will not.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size);
+ cache_size <<= 2;
+ if (cache_size != SMP_CACHE_BYTES) {
+ printk(KERN_INFO "%s: PCI cache line size set incorrectly "
+ "(%i bytes) by BIOS/FW, ", dev->name, cache_size);
+ if (cache_size > SMP_CACHE_BYTES)
+ printk("expecting %i\n", SMP_CACHE_BYTES);
+ else {
+ printk("correcting to %i\n", SMP_CACHE_BYTES);
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ SMP_CACHE_BYTES >> 2);
+ }
+ }
+
+ /* enable busmastering and memory-write-invalidate */
+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+ if (!(pci_command & PCI_COMMAND_INVALIDATE)) {
+ pci_command |= PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+ }
+ pci_set_master(pdev);


+
+ return 0;
+

+err_out_iomap:
+ iounmap(regs);
+err_out_res:
+ pci_release_regions(pdev);
+err_out_disable:
+ pci_disable_device(pdev);
+err_out_free:
+ kfree(dev);
+ return rc;
+}
+
+static void __devexit cp_remove_one (struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct cp_private *cp = dev->priv;
+
+ if (!dev)
+ BUG();
+ unregister_netdev(dev);
+ iounmap(cp->regs);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ kfree(dev);
+}
+
+static struct pci_driver cp_driver = {
+ name: DRV_NAME,
+ id_table: cp_pci_tbl,
+ probe: cp_init_one,
+ remove: cp_remove_one,
+};
+
+static int __init cp_init (void)
+{
+#ifdef MODULE
+ printk("%s", version);
+#endif
+ return pci_module_init (&cp_driver);
+}
+
+static void __exit cp_exit (void)
+{
+ pci_unregister_driver (&cp_driver);
+}
+
+module_init(cp_init);
+module_exit(cp_exit);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.12/linux/drivers/net/8139too.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/net/8139too.c Fri Oct 19 08:32:28 2001
@@ -72,7 +72,7 @@
X features of the 8139 chips
X
X Jean-Jacques Michel - bug fix
-
+
X Tobias Ringström - Rx interrupt status checking suggestion
X
X Andrew Morton - Clear blocked signals, avoid
@@ -139,7 +139,7 @@
X */
X
X #define DRV_NAME "8139too"
-#define DRV_VERSION "0.9.19"
+#define DRV_VERSION "0.9.20"
X
X
X #include <linux/config.h>
@@ -258,6 +258,7 @@
X DELTA8139,
X ADDTRON8139,
X DFE538TX,
+ DFE690TXD,
X RTL8129,
X } board_t;
X
@@ -274,6 +275,7 @@
X { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS },
X { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS },
X { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS },
+ { "D-Link DFE-690TXD (RealTek RTL8139)", RTL8139_CAPS },
X { "RealTek RTL8129", RTL8129_CAPS },
X };
X
@@ -286,6 +288,7 @@
X {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
X {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
X {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX },
+ {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD },
X
X #ifdef CONFIG_8139TOO_8129
X {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
@@ -942,6 +945,7 @@
X int i, addr_len, option;
X void *ioaddr;
X static int board_idx = -1;
+ u8 pci_rev;
X
X DPRINTK ("ENTER\n");
X
@@ -961,6 +965,15 @@
X }
X #endif
X
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+ if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
+ pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev >= 0x20) {
+ printk(KERN_INFO PFX "pci dev %s (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n",
+ pdev->slot_name, pdev->vendor, pdev->device, pci_rev);
+ printk(KERN_INFO PFX "Use the \"8139cp\" driver for improved performance and stability.\n");
+ }
+
X i = rtl8139_init_board (pdev, &dev);
X if (i < 0) {
X DPRINTK ("EXIT, returning %d\n", i);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 30'
echo 'File patch-2.4.13 is continued in part 31'
echo "31" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:02 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part32

#!/bin/sh -x
# this is part 32 of a 53 - part archive


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

if test "$Scheck" != 32; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- new_skb->data,
- RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE));
+ rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev,
+ virt_to_page(new_skb->data),
+ ((unsigned long) new_skb->data &
+ ~PAGE_MASK),
+ RX_BUF_ALLOC_SIZE(gp),
+ PCI_DMA_FROMDEVICE));
X skb_reserve(new_skb, RX_OFFSET);
X
X /* Trim the original skb for the netif. */
@@ -661,37 +680,45 @@
X
X if (skb_shinfo(skb)->nr_frags == 0) {
X struct gem_txd *txd = &gp->init_block->txd[entry];
- u32 mapping, len;
+ dma_addr_t mapping;
+ u32 len;
X
X len = skb->len;
- mapping = pci_map_single(gp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ mapping = pci_map_page(gp->pdev,
+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),
+ len, PCI_DMA_TODEVICE);
X ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len;
X txd->buffer = cpu_to_le64(mapping);
X txd->control_word = cpu_to_le64(ctrl);
X entry = NEXT_TX(entry);
X } else {
X struct gem_txd *txd;
- u32 first_len, first_mapping;
+ u32 first_len;
+ dma_addr_t first_mapping;
X int frag, first_entry = entry;
X
X /* We must give this initial chunk to the device last.
X * Otherwise we could race with the device.
X */
X first_len = skb->len - skb->data_len;
- first_mapping = pci_map_single(gp->pdev, skb->data,
- first_len, PCI_DMA_TODEVICE);
+ first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data),
+ ((unsigned long) skb->data & ~PAGE_MASK),
+ first_len, PCI_DMA_TODEVICE);
X entry = NEXT_TX(entry);
X
X for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
X skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
- u32 len, mapping;
+ u32 len;
+ dma_addr_t mapping;
X u64 this_ctrl;
X
X len = this_frag->size;
- mapping = pci_map_single(gp->pdev,
- ((void *) page_address(this_frag->page) +
- this_frag->page_offset),
- len, PCI_DMA_TODEVICE);
+ mapping = pci_map_page(gp->pdev,
+ this_frag->page,
+ this_frag->page_offset,
+ len, PCI_DMA_TODEVICE);
X this_ctrl = ctrl;
X if (frag == skb_shinfo(skb)->nr_frags - 1)
X this_ctrl |= TXDCTRL_EOF;
@@ -750,6 +777,10 @@
X int limit;
X u32 val;
X
+ /* Make sure we won't get any more interrupts */
+ writel(0xffffffff, gp->regs + GREG_IMASK);
+
+ /* Reset the chip */
X writel(GREG_SWRST_TXRST | GREG_SWRST_RXRST, regs + GREG_SWRST);
X
X limit = STOP_TRIES;
@@ -765,24 +796,73 @@
X printk(KERN_ERR "gem: SW reset is ghetto.\n");
X }
X
+static void gem_start_dma(struct gem *gp)
+{
+ unsigned long val;
+
+ /* We are ready to rock, turn everything on. */
+ val = readl(gp->regs + TXDMA_CFG);
+ writel(val | TXDMA_CFG_ENABLE, gp->regs + TXDMA_CFG);
+ val = readl(gp->regs + RXDMA_CFG);
+ writel(val | RXDMA_CFG_ENABLE, gp->regs + RXDMA_CFG);
+ val = readl(gp->regs + MAC_TXCFG);
+ writel(val | MAC_TXCFG_ENAB, gp->regs + MAC_TXCFG);
+ val = readl(gp->regs + MAC_RXCFG);
+ writel(val | MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
+
+ writel(GREG_STAT_TXDONE, gp->regs + GREG_IMASK);
+
+ writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
+
+}
+
+/* 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 /* A link-up condition has occurred, initialize and enable the
X * rest of the chip.
X */
X static void gem_set_link_modes(struct gem *gp)
X {
X u32 val;
- int full_duplex, speed;
+ int full_duplex, speed, pause;
X
X full_duplex = 0;
X speed = 10;
+ pause = 0;
+
X if (gp->phy_type == phy_mii_mdio0 ||
X gp->phy_type == phy_mii_mdio1) {
X if (gp->lstate == aneg_wait) {
- val = phy_read(gp, PHY_LPA);
- if (val & (PHY_LPA_10FULL | PHY_LPA_100FULL))
- full_duplex = 1;
- if (val & (PHY_LPA_100FULL | PHY_LPA_100HALF))
- speed = 100;
+ if (gp->phy_mod == phymod_bcm5400 ||
+ gp->phy_mod == phymod_bcm5401 ||
+ gp->phy_mod == phymod_bcm5411) {
+ int link_mode;
+ val = phy_read(gp, PHY_BCM5400_AUXSTATUS);
+ link_mode = (val & PHY_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
+ PHY_BCM5400_AUXSTATUS_LINKMODE_SHIFT;
+ full_duplex = phy_BCM5400_link_table[link_mode][0];
+ speed = phy_BCM5400_link_table[link_mode][2] ? 1000
+ : (phy_BCM5400_link_table[link_mode][1] ? 100 : 10);
+ val = phy_read(gp, PHY_LPA);
+ if (val & PHY_LPA_PAUSE)
+ pause = 1;
+ } else {
+ val = phy_read(gp, PHY_LPA);
+ if (val & (PHY_LPA_10FULL | PHY_LPA_100FULL))
+ full_duplex = 1;
+ if (val & (PHY_LPA_100FULL | PHY_LPA_100HALF))
+ speed = 100;
+ }
X } else {
X val = phy_read(gp, PHY_CTRL);
X if (val & PHY_CTRL_FDPLX)
@@ -842,33 +922,24 @@
X
X if (gp->phy_type == phy_serialink ||
X gp->phy_type == phy_serdes) {
- u32 pcs_lpa = readl(gp->regs + PCS_MIILP);
+ u32 pcs_lpa = readl(gp->regs + PCS_MIILP);
X
- val = readl(gp->regs + MAC_MCCFG);
X if (pcs_lpa & (PCS_MIIADV_SP | PCS_MIIADV_AP))
- val |= (MAC_MCCFG_SPE | MAC_MCCFG_RPE);
- else
- val &= ~(MAC_MCCFG_SPE | MAC_MCCFG_RPE);
- writel(val, gp->regs + MAC_MCCFG);
+ pause = 1;
+ }
X
- if (!full_duplex)
- writel(512, gp->regs + MAC_STIME);
- else
- writel(64, gp->regs + MAC_STIME);
- } else {
- /* Set slot-time of 64. */
+ if (!full_duplex)
+ writel(512, gp->regs + MAC_STIME);
+ else
X writel(64, gp->regs + MAC_STIME);
- }
+ val = readl(gp->regs + MAC_MCCFG);
+ if (pause)
+ val |= (MAC_MCCFG_SPE | MAC_MCCFG_RPE);
+ else
+ val &= ~(MAC_MCCFG_SPE | MAC_MCCFG_RPE);
+ writel(val, gp->regs + MAC_MCCFG);
X
- /* We are ready to rock, turn everything on. */
- val = readl(gp->regs + TXDMA_CFG);
- writel(val | TXDMA_CFG_ENABLE, gp->regs + TXDMA_CFG);
- val = readl(gp->regs + RXDMA_CFG);
- writel(val | RXDMA_CFG_ENABLE, gp->regs + RXDMA_CFG);
- val = readl(gp->regs + MAC_TXCFG);
- writel(val | MAC_TXCFG_ENAB, gp->regs + MAC_TXCFG);
- val = readl(gp->regs + MAC_RXCFG);
- writel(val | MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
+ gem_start_dma(gp);
X }
X
X static int gem_mdio_link_not_up(struct gem *gp)
@@ -948,19 +1019,18 @@
X struct gem_init_block *gb = gp->init_block;
X struct sk_buff *skb;
X int i;
- u32 dma_addr;
+ dma_addr_t dma_addr;
X
X for (i = 0; i < RX_RING_SIZE; i++) {
X struct gem_rxd *rxd;
X
X rxd = &gb->rxd[i];
X if (gp->rx_skbs[i] != NULL) {
-
X skb = gp->rx_skbs[i];
- dma_addr = (u32) le64_to_cpu(rxd->buffer);
- pci_unmap_single(gp->pdev, dma_addr,
- RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE);
+ dma_addr = le64_to_cpu(rxd->buffer);
+ pci_unmap_page(gp->pdev, dma_addr,
+ RX_BUF_ALLOC_SIZE(gp),
+ PCI_DMA_FROMDEVICE);
X dev_kfree_skb_any(skb);
X gp->rx_skbs[i] = NULL;
X }
@@ -978,10 +1048,10 @@
X
X for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
X txd = &gb->txd[i];
- dma_addr = (u32) le64_to_cpu(txd->buffer);
- pci_unmap_single(gp->pdev, dma_addr,
- le64_to_cpu(txd->control_word) &
- TXDCTRL_BUFSZ, PCI_DMA_TODEVICE);
+ dma_addr = le64_to_cpu(txd->buffer);
+ pci_unmap_page(gp->pdev, dma_addr,
+ le64_to_cpu(txd->control_word) &
+ TXDCTRL_BUFSZ, PCI_DMA_TODEVICE);
X
X if (frag != skb_shinfo(skb)->nr_frags)
X i++;
@@ -996,7 +1066,7 @@
X struct gem_init_block *gb = gp->init_block;
X struct net_device *dev = gp->dev;
X int i, gfp_flags = GFP_KERNEL;
- u32 dma_addr;
+ dma_addr_t dma_addr;
X
X if (from_irq)
X gfp_flags = GFP_ATOMIC;
@@ -1019,9 +1089,12 @@
X gp->rx_skbs[i] = skb;
X skb->dev = dev;
X skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET));
- dma_addr = pci_map_single(gp->pdev, skb->data,
- RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE);
+ dma_addr = pci_map_page(gp->pdev,
+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),
+ RX_BUF_ALLOC_SIZE(gp),
+ PCI_DMA_FROMDEVICE);
X rxd->buffer = cpu_to_le64(dma_addr);
X rxd->status_word = cpu_to_le64(RXDCTRL_FRESH(gp));
X skb_reserve(skb, RX_OFFSET);
@@ -1035,8 +1108,150 @@
X }
X }
X
+static int
+gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
+{
+ u16 val;
+ int limit = 10000;
+
+ val = __phy_read(gp, PHY_CTRL, phy_addr);
+ val &= ~PHY_CTRL_ISO;
+ val |= PHY_CTRL_RST;
+ __phy_write(gp, PHY_CTRL, val, phy_addr);
+
+ udelay(100);
+
+ while (limit--) {
+ val = __phy_read(gp, PHY_CTRL, phy_addr);
+ if ((val & PHY_CTRL_RST) == 0)
+ break;
+ udelay(10);
+ }
+ if ((val & PHY_CTRL_ISO) && limit > 0)
+ __phy_write(gp, PHY_CTRL, val & ~PHY_CTRL_ISO, phy_addr);
+
+ return (limit <= 0);
+}
+
+static void
+gem_init_bcm5400_phy(struct gem *gp)
+{
+ u16 data;
+
+ /* Configure for gigabit full duplex */
+ data = phy_read(gp, PHY_BCM5400_AUXCONTROL);
+ data |= PHY_BCM5400_AUXCONTROL_PWR10BASET;
+ phy_write(gp, PHY_BCM5400_AUXCONTROL, data);
+
+ data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
+ data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+
+ mdelay(10);
+
+ /* Reset and configure cascaded 10/100 PHY */
+ gem_reset_one_mii_phy(gp, 0x1f);
+
+ data = __phy_read(gp, PHY_BCM5201_MULTIPHY, 0x1f);
+ data |= PHY_BCM5201_MULTIPHY_SERIALMODE;
+ __phy_write(gp, PHY_BCM5201_MULTIPHY, data, 0x1f);
+
+ data = phy_read(gp, PHY_BCM5400_AUXCONTROL);
+ data &= ~PHY_BCM5400_AUXCONTROL_PWR10BASET;
+ phy_write(gp, PHY_BCM5400_AUXCONTROL, data);
+}
+
+static void
+gem_init_bcm5401_phy(struct gem *gp)
+{
+ u16 data;
+ int rev;
+
+ rev = phy_read(gp, PHY_ID1) & 0x000f;
+ if (rev == 0 || rev == 3) {
+ /* Some revisions of 5401 appear to need this
+ * initialisation sequence to disable, according
+ * to OF, "tap power management"
+ *
+ * WARNING ! OF and Darwin don't agree on the
+ * register addresses. OF seem to interpret the
+ * register numbers below as decimal
+ */
+ phy_write(gp, 0x18, 0x0c20);
+ phy_write(gp, 0x17, 0x0012);
+ phy_write(gp, 0x15, 0x1804);
+ phy_write(gp, 0x17, 0x0013);
+ phy_write(gp, 0x15, 0x1204);
+ phy_write(gp, 0x17, 0x8006);
+ phy_write(gp, 0x15, 0x0132);
+ phy_write(gp, 0x17, 0x8006);
+ phy_write(gp, 0x15, 0x0232);
+ phy_write(gp, 0x17, 0x201f);
+ phy_write(gp, 0x15, 0x0a20);
+ }
+
+ /* Configure for gigabit full duplex */
+ data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
+ data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+
+ mdelay(1);
+
+ /* Reset and configure cascaded 10/100 PHY */
+ gem_reset_one_mii_phy(gp, 0x1f);
+
+ data = __phy_read(gp, PHY_BCM5201_MULTIPHY, 0x1f);
+ data |= PHY_BCM5201_MULTIPHY_SERIALMODE;
+ __phy_write(gp, PHY_BCM5201_MULTIPHY, data, 0x1f);
+}
+
+static void
+gem_init_bcm5411_phy(struct gem *gp)
+{
+ u16 data;
+
+ /* Here's some more Apple black magic to setup
+ * some voltage stuffs.
+ */
+ phy_write(gp, 0x1c, 0x8c23);
+ phy_write(gp, 0x1c, 0x8ca3);
+ phy_write(gp, 0x1c, 0x8c23);
+
+ /* Here, Apple seems to want to reset it, do
+ * it as well
+ */
+ phy_write(gp, PHY_CTRL, PHY_CTRL_RST);
+
+ /* Start autoneg */
+ phy_write(gp, PHY_CTRL,
+ (PHY_CTRL_ANENAB | PHY_CTRL_FDPLX |
+ PHY_CTRL_ANRES | PHY_CTRL_SPD2));
+
+ data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
+ data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+}
+
X static void gem_init_phy(struct gem *gp)
X {
+#ifdef CONFIG_ALL_PPC
+ if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
+ int i;
+
+ pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
+ for (i = 0; i < 32; i++) {
+ gp->mii_phy_addr = i;
+ if (phy_read(gp, PHY_CTRL) != 0xffff)
+ break;
+ }
+ if (i == 32) {
+ printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
+ gp->dev->name);
+ return;
+ }
+ }
+#endif /* CONFIG_ALL_PPC */
+
X if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
X gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
X u32 val;
@@ -1056,27 +1271,59 @@
X
X if (gp->phy_type == phy_mii_mdio0 ||
X gp->phy_type == phy_mii_mdio1) {
- u16 val = phy_read(gp, PHY_CTRL);
- int limit = 10000;
-
+ u32 phy_id;
+ u16 val;
+
X /* Take PHY out of isloate mode and reset it. */
- val &= ~PHY_CTRL_ISO;
- val |= PHY_CTRL_RST;
- phy_write(gp, PHY_CTRL, val);
+ gem_reset_one_mii_phy(gp, gp->mii_phy_addr);
X
- while (limit--) {
- val = phy_read(gp, PHY_CTRL);
- if ((val & PHY_CTRL_RST) == 0)
+ phy_id = (phy_read(gp, PHY_ID0) << 16 | phy_read(gp, PHY_ID1))
+ & 0xfffffff0;
+ printk(KERN_INFO "%s: MII PHY ID: %x ", gp->dev->name, phy_id);
+ switch(phy_id) {
+ case 0x406210:
+ gp->phy_mod = phymod_bcm5201;
+ printk("BCM 5201\n");
X break;
- udelay(10);
- }
+ case 0x4061e0:
+ printk("BCM 5221\n");
+ gp->phy_mod = phymod_bcm5221;
+ break;
+ case 0x206040:
+ printk("BCM 5400\n");
+ gp->phy_mod = phymod_bcm5400;
+ gem_init_bcm5400_phy(gp);
+ break;
+ case 0x206050:
+ printk("BCM 5401\n");
+ gp->phy_mod = phymod_bcm5401;
+ gem_init_bcm5401_phy(gp);
+ break;
+ case 0x206070:
+ printk("BCM 5411\n");
+ gp->phy_mod = phymod_bcm5411;
+ gem_init_bcm5411_phy(gp);
+ break;
+ default:
+ printk("Generic\n");
+ gp->phy_mod = phymod_generic;
+ };
X
X /* Init advertisement and enable autonegotiation. */
+ val = phy_read(gp, PHY_CTRL);
+ val &= ~PHY_CTRL_ANENAB;
+ phy_write(gp, PHY_CTRL, val);
+ udelay(10);
+
X phy_write(gp, PHY_ADV,
+ phy_read(gp, PHY_ADV) |
X (PHY_ADV_10HALF | PHY_ADV_10FULL |
X PHY_ADV_100HALF | PHY_ADV_100FULL));
X
- val |= (PHY_CTRL_ANRES | PHY_CTRL_ANENAB);
+ val = phy_read(gp, PHY_CTRL);
+ val |= PHY_CTRL_ANENAB;
+ phy_write(gp, PHY_CTRL, val);
+ val |= PHY_CTRL_ANRES;
X phy_write(gp, PHY_CTRL, val);
X } else {
X u32 val;
@@ -1137,13 +1384,15 @@
X
X static void gem_init_dma(struct gem *gp)
X {
+ u64 desc_dma = (u64) gp->gblock_dvma;
X u32 val;
X
X val = (TXDMA_CFG_BASE | (0x7ff << 10) | TXDMA_CFG_PMODE);
X writel(val, gp->regs + TXDMA_CFG);
X
- writel(0, gp->regs + TXDMA_DBHI);
- writel(gp->gblock_dvma, gp->regs + TXDMA_DBLOW);
+ writel(desc_dma >> 32, gp->regs + TXDMA_DBHI);
+ writel(desc_dma & 0xffffffff, gp->regs + TXDMA_DBLOW);
+ desc_dma += (TX_RING_SIZE * sizeof(struct gem_txd));
X
X writel(0, gp->regs + TXDMA_KICK);
X
@@ -1151,10 +1400,8 @@
X ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_512);
X writel(val, gp->regs + RXDMA_CFG);
X
- writel(0, gp->regs + RXDMA_DBHI);
- writel((gp->gblock_dvma +
- (TX_RING_SIZE * sizeof(struct gem_txd))),
- gp->regs + RXDMA_DBLOW);
+ writel(desc_dma >> 32, gp->regs + RXDMA_DBHI);
+ writel(desc_dma & 0xffffffff, gp->regs + RXDMA_DBLOW);
X
X writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
X
@@ -1314,20 +1561,186 @@
X writel(0, gp->regs + MAC_MCMASK);
X }
X
+static void
+gem_init_pause_thresholds(struct gem* gp)
+{
+ /* Calculate pause thresholds. Setting the OFF threshold to the
+ * full RX fifo size effectively disables PAUSE generation which
+ * is what we do for 10/100 only GEMs which have FIFOs too small
+ * to make real gains from PAUSE.
+ */
+ if (gp->rx_fifo_sz <= (2 * 1024)) {
+ gp->rx_pause_off = gp->rx_pause_on = gp->rx_fifo_sz;
+ } else {
+ int off = (gp->rx_fifo_sz - (5 * 1024));
+ int on = off - 1024;
+
+ gp->rx_pause_off = off;
+ gp->rx_pause_on = on;
+ }
+
+ {
+ u32 cfg = readl(gp->regs + GREG_BIFCFG);
+
+ /* XXX Why do I do this? -DaveM XXX */
+ cfg |= GREG_BIFCFG_B64DIS;
+ writel(cfg, gp->regs + GREG_BIFCFG);
+
+ cfg = GREG_CFG_IBURST;
+ cfg |= ((31 << 1) & GREG_CFG_TXDMALIM);
+ cfg |= ((31 << 6) & GREG_CFG_RXDMALIM);
+ writel(cfg, gp->regs + GREG_CFG);
+ }
+}
+
+static int gem_check_invariants(struct gem *gp)
+{
+ struct pci_dev *pdev = gp->pdev;
+ u32 mif_cfg;
+
+ /* On Apple's sungem, we can't realy on registers as the chip
+ * was been powered down by the firmware. We do the PHY lookup
+ * when the interface is opened and we configure the driver
+ * with known values.
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_APPLE) {
+ gp->phy_type = phy_mii_mdio0;
+ mif_cfg = readl(gp->regs + MIF_CFG);
+ mif_cfg &= ~MIF_CFG_PSELECT;
+ writel(mif_cfg, gp->regs + MIF_CFG);
+ writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
+ writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
+ gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
+ gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
+ gem_init_pause_thresholds(gp);


+ return 0;
+ }
+

+ mif_cfg = readl(gp->regs + MIF_CFG);
+
+ if (pdev->vendor == PCI_VENDOR_ID_SUN &&
+ pdev->device == PCI_DEVICE_ID_SUN_RIO_GEM) {
+ /* One of the MII PHYs _must_ be present
+ * as this chip has no gigabit PHY.
+ */
+ if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) {
+ printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n",
+ mif_cfg);


+ return -1;
+ }
+ }
+

+ /* Determine initial PHY interface type guess. MDIO1 is the
+ * external PHY and thus takes precedence over MDIO0.
+ */
+
+ if (mif_cfg & MIF_CFG_MDI1) {
+ gp->phy_type = phy_mii_mdio1;
+ mif_cfg |= MIF_CFG_PSELECT;
+ writel(mif_cfg, gp->regs + MIF_CFG);
+ } else if (mif_cfg & MIF_CFG_MDI0) {
+ gp->phy_type = phy_mii_mdio0;
+ mif_cfg &= ~MIF_CFG_PSELECT;
+ writel(mif_cfg, gp->regs + MIF_CFG);
+ } else {
+ gp->phy_type = phy_serialink;
+ }
+ if (gp->phy_type == phy_mii_mdio1 ||
+ gp->phy_type == phy_mii_mdio0) {
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ gp->mii_phy_addr = i;
+ if (phy_read(gp, PHY_CTRL) != 0xffff)
+ break;
+ }
+ if (i == 32) {
+ if (pdev->device != PCI_DEVICE_ID_SUN_GEM) {
+ printk(KERN_ERR PFX "RIO MII phy will not respond.\n");
+ return -1;
+ }
+ gp->phy_type = phy_serdes;
+ }
+ }
+
+ /* Fetch the FIFO configurations now too. */
+ gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
+ gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
+
+ if (pdev->vendor == PCI_VENDOR_ID_SUN) {
+ if (pdev->device == PCI_DEVICE_ID_SUN_GEM) {
+ if (gp->tx_fifo_sz != (9 * 1024) ||
+ gp->rx_fifo_sz != (20 * 1024)) {
+ printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ gp->tx_fifo_sz, gp->rx_fifo_sz);
+ return -1;
+ }
+ } else {
+ if (gp->tx_fifo_sz != (2 * 1024) ||
+ gp->rx_fifo_sz != (2 * 1024)) {
+ printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ gp->tx_fifo_sz, gp->rx_fifo_sz);


+ return -1;
+ }
+ }
+ }

+
+ gem_init_pause_thresholds(gp);


+
+ return 0;
+}
+

X static void gem_init_hw(struct gem *gp)
X {
+ /* On Apple's gmac, I initialize the PHY only after
+ * setting up the chip. It appears the gigabit PHYs
+ * don't quite like beeing talked to on the GII when
+ * the chip is not running, I suspect it might not
+ * be clocked at that point. --BenH
+ */
+ if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
+ gem_check_invariants(gp);
+ gp->hw_running = 1;
+ }
X gem_init_phy(gp);
X gem_init_dma(gp);
X gem_init_mac(gp);
X
- writel(GREG_STAT_TXDONE, gp->regs + GREG_IMASK);
-
X gp->timer_ticks = 0;
X gp->lstate = aneg_wait;
X gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
X add_timer(&gp->link_timer);
X }
X
+#ifdef CONFIG_ALL_PPC
+/* Enable the chip's clock and make sure it's config space is
+ * setup properly. There appear to be no need to restore the
+ * base addresses.
+ */
+static void
+gem_apple_powerup(struct gem* gp)
+{
+ u16 cmd;
+
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 1);
+
+ udelay(100);
+
+ pci_read_config_word(gp->pdev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(gp->pdev, PCI_COMMAND, cmd);
+ pci_write_config_byte(gp->pdev, PCI_LATENCY_TIMER, 6);
+ pci_write_config_byte(gp->pdev, PCI_CACHE_LINE_SIZE, 8);
+}
+
+/* Turn off the chip's clock */
+static void
+gem_apple_powerdown(struct gem* gp)
+{
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
+}
+#endif /* CONFIG_ALL_PPC */
+
X static int gem_open(struct net_device *dev)
X {
X struct gem *gp = dev->priv;
@@ -1335,12 +1748,31 @@
X
X del_timer(&gp->link_timer);
X
+#ifdef CONFIG_ALL_PPC
+ /* First, we need to bring up the chip */
+ if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+ gem_apple_powerup(gp);
+#endif /* CONFIG_ALL_PPC */
+
+ /* Reset the chip */
+ gem_stop(gp, regs);
+
+ /* We can now request the interrupt as we know it's masked
+ * on the controller
+ */
X if (request_irq(gp->pdev->irq, gem_interrupt,
- SA_SHIRQ, dev->name, (void *)dev))
+ SA_SHIRQ, dev->name, (void *)dev)) {
+#ifdef CONFIG_ALL_PPC
+ if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+ gem_apple_powerdown(gp);
+#endif /* CONFIG_ALL_PPC */
X return -EAGAIN;
+ }
X
- gem_stop(gp, regs);
+ /* Allocate & setup ring buffers */
X gem_init_rings(gp, 0);
+
+ /* Init & setup chip hardware */
X gem_init_hw(gp);
X
X return 0;
@@ -1353,6 +1785,11 @@
X del_timer(&gp->link_timer);
X gem_stop(gp, gp->regs);
X gem_clean_rings(gp);
+ gp->hw_running = 0;
+#ifdef CONFIG_ALL_PPC
+ if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+ gem_apple_powerdown(gp);
+#endif /* CONFIG_ALL_PPC */
X free_irq(gp->pdev->irq, (void *)dev);
X return 0;
X }
@@ -1362,22 +1799,23 @@
X struct gem *gp = dev->priv;
X struct net_device_stats *stats = &gp->net_stats;
X
- stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
- writel(0, gp->regs + MAC_FCSERR);
-
- stats->rx_frame_errors += readl(gp->regs + MAC_AERR);
- writel(0, gp->regs + MAC_AERR);
-
- stats->rx_length_errors += readl(gp->regs + MAC_LERR);
- writel(0, gp->regs + MAC_LERR);
-
- stats->tx_aborted_errors += readl(gp->regs + MAC_ECOLL);
- stats->collisions +=
- (readl(gp->regs + MAC_ECOLL) +
- readl(gp->regs + MAC_LCOLL));
- writel(0, gp->regs + MAC_ECOLL);
- writel(0, gp->regs + MAC_LCOLL);
-
+ if (gp->hw_running) {
+ stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
+ writel(0, gp->regs + MAC_FCSERR);
+
+ stats->rx_frame_errors += readl(gp->regs + MAC_AERR);
+ writel(0, gp->regs + MAC_AERR);
+
+ stats->rx_length_errors += readl(gp->regs + MAC_LERR);
+ writel(0, gp->regs + MAC_LERR);
+
+ stats->tx_aborted_errors += readl(gp->regs + MAC_ECOLL);
+ stats->collisions +=
+ (readl(gp->regs + MAC_ECOLL) +
+ readl(gp->regs + MAC_LCOLL));
+ writel(0, gp->regs + MAC_ECOLL);
+ writel(0, gp->regs + MAC_LCOLL);
+ }
X return &gp->net_stats;
X }
X
@@ -1385,6 +1823,9 @@
X {
X struct gem *gp = dev->priv;
X
+ if (!gp->hw_running)
+ return;
+
X netif_stop_queue(dev);
X
X if ((gp->dev->flags & IFF_ALLMULTI) ||
@@ -1475,115 +1916,14 @@


X return -EINVAL;
X }
X

-static int __devinit gem_check_invariants(struct gem *gp)
-{
- struct pci_dev *pdev = gp->pdev;
- u32 mif_cfg = readl(gp->regs + MIF_CFG);
-
- if (pdev->vendor == PCI_VENDOR_ID_SUN &&
- pdev->device == PCI_DEVICE_ID_SUN_RIO_GEM) {
- /* One of the MII PHYs _must_ be present
- * as this chip has no gigabit PHY.
- */
- if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) {
- printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n",
- mif_cfg);


- return -1;
- }
- }
-

- /* Determine initial PHY interface type guess. MDIO1 is the
- * external PHY and thus takes precedence over MDIO0.
- */
- if (mif_cfg & MIF_CFG_MDI1) {
- gp->phy_type = phy_mii_mdio1;
- mif_cfg |= MIF_CFG_PSELECT;
- writel(mif_cfg, gp->regs + MIF_CFG);
- } else if (mif_cfg & MIF_CFG_MDI0) {
- gp->phy_type = phy_mii_mdio0;
- mif_cfg &= ~MIF_CFG_PSELECT;
- writel(mif_cfg, gp->regs + MIF_CFG);
- } else {
- gp->phy_type = phy_serialink;
- }
- if (gp->phy_type == phy_mii_mdio1 ||
- gp->phy_type == phy_mii_mdio0) {
- int i;
-
- for (i = 0; i < 32; i++) {
- gp->mii_phy_addr = i;
- if (phy_read(gp, PHY_CTRL) != 0xffff)
- break;
- }
- if (i == 32) {
- if (pdev->device != PCI_DEVICE_ID_SUN_GEM) {
- printk(KERN_ERR PFX "RIO MII phy will not respond.\n");
- return -1;
- }
- gp->phy_type = phy_serdes;
- }
- }
-
- /* Fetch the FIFO configurations now too. */
- gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
- gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
-
- if (pdev->vendor == PCI_VENDOR_ID_SUN) {
- if (pdev->device == PCI_DEVICE_ID_SUN_GEM) {
- if (gp->tx_fifo_sz != (9 * 1024) ||
- gp->rx_fifo_sz != (20 * 1024)) {
- printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n",
- gp->tx_fifo_sz, gp->rx_fifo_sz);
- return -1;
- }
- } else {
- if (gp->tx_fifo_sz != (2 * 1024) ||
- gp->rx_fifo_sz != (2 * 1024)) {
- printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
- gp->tx_fifo_sz, gp->rx_fifo_sz);


- return -1;
- }
- }
- }

-
- /* Calculate pause thresholds. Setting the OFF threshold to the
- * full RX fifo size effectively disables PAUSE generation which
- * is what we do for 10/100 only GEMs which have FIFOs too small
- * to make real gains from PAUSE.
- */
- if (gp->rx_fifo_sz <= (2 * 1024)) {
- gp->rx_pause_off = gp->rx_pause_on = gp->rx_fifo_sz;
- } else {
- int off = (gp->rx_fifo_sz - (5 * 1024));
- int on = off - 1024;
-
- gp->rx_pause_off = off;
- gp->rx_pause_on = on;
- }
-
- {
- u32 cfg = readl(gp->regs + GREG_BIFCFG);
-
- cfg |= GREG_BIFCFG_B64DIS;
- writel(cfg, gp->regs + GREG_BIFCFG);
-
- cfg = GREG_CFG_IBURST;
- cfg |= ((31 << 1) & GREG_CFG_TXDMALIM);
- cfg |= ((31 << 6) & GREG_CFG_RXDMALIM);
- writel(cfg, gp->regs + GREG_CFG);


- }
-
- return 0;
-}
-

X static int __devinit gem_get_device_address(struct gem *gp)
X {
-#if defined(__sparc__) || defined(__powerpc__)
+#if defined(__sparc__) || defined(CONFIG_ALL_PPC)
X struct net_device *dev = gp->dev;
- struct pci_dev *pdev = gp->pdev;
X #endif
X
X #ifdef __sparc__
+ struct pci_dev *pdev = gp->pdev;


X struct pcidev_cookie *pcp = pdev->sysdata;

X int node = -1;
X
@@ -1598,12 +1938,10 @@
X if (node == -1)
X memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
X #endif
-#ifdef __powerpc__
- struct device_node *gem_node;
+#ifdef CONFIG_ALL_PPC
X unsigned char *addr;
X
- gem_node = pci_device_to_OF_node(pdev);
- addr = get_property(gem_node, "local-mac-address", NULL);
+ addr = get_property(gp->of_node, "local-mac-address", NULL);
X if (addr == NULL) {
X printk("\n");
X printk(KERN_ERR "%s: can't get mac-address\n", dev->name);
@@ -1621,11 +1959,17 @@
X unsigned long gemreg_base, gemreg_len;
X struct net_device *dev;
X struct gem *gp;
- int i, err;
+ int i, err, pci_using_dac;
X
X if (gem_version_printed++ == 0)
X printk(KERN_INFO "%s", version);
X
+ /* Apple gmac note: during probe, the chip is powered up by
+ * the arch code to allow the code below to work (and to let
+ * the chip be probed on the config space. It won't stay powered
+ * up until the interface is brought up however, so we can't rely
+ * on register configuration done at this point.
+ */
X err = pci_enable_device(pdev);
X if (err) {
X printk(KERN_ERR PFX "Cannot enable MMIO operation, "
@@ -1634,6 +1978,29 @@
X }
X pci_set_master(pdev);
X
+ /* Configure DMA attributes. */
+
+ /* All of the GEM documentation states that 64-bit DMA addressing
+ * is fully supported and should work just fine. However the
+ * front end for RIO based GEMs is different and only supports
+ * 32-bit addressing.
+ *
+ * For now we assume the various PPC GEMs are 32-bit only as well.
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_SUN &&
+ pdev->device == PCI_DEVICE_ID_SUN_GEM &&
+ !pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) {
+ pci_using_dac = 1;
+ } else {
+ err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+ if (err) {
+ printk(KERN_ERR PFX "No usable DMA configuration, "
+ "aborting.\n");
+ return err;
+ }
+ pci_using_dac = 0;
+ }
+
X gemreg_base = pci_resource_start(pdev, 0);
X gemreg_len = pci_resource_len(pdev, 0);
X
@@ -1671,8 +2038,13 @@
X goto err_out_free_mmio_res;
X }
X
- if (gem_check_invariants(gp))
- goto err_out_iounmap;
+ /* On Apple's, we might not access the hardware at that point */
+ if (pdev->vendor != PCI_VENDOR_ID_APPLE) {
+ gem_stop(gp, gp->regs);
+ if (gem_check_invariants(gp))
+ goto err_out_iounmap;
+ gp->hw_running = 1;
+ }
X
X /* It is guarenteed that the returned buffer will be at least
X * PAGE_SIZE aligned.
@@ -1691,6 +2063,9 @@
X printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ",
X dev->name);
X
+#ifdef CONFIG_ALL_PPC
+ gp->of_node = pci_device_to_OF_node(pdev);
+#endif
X if (gem_get_device_address(gp))
X goto err_out_iounmap;
X
@@ -1717,6 +2092,8 @@
X
X /* GEM can do it all... */
X dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ if (pci_using_dac)
+ dev->features |= NETIF_F_HIGHDMA;


X
X return 0;
X

@@ -1750,6 +2127,9 @@
X iounmap((void *) gp->regs);
X release_mem_region(pci_resource_start(pdev, 0),
X pci_resource_len(pdev, 0));
+#ifdef CONFIG_ALL_PPC
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
+#endif
X kfree(dev);
X
X pci_set_drvdata(pdev, NULL);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sungem.h linux/drivers/net/sungem.h
--- v2.4.12/linux/drivers/net/sungem.h Thu Apr 12 12:11:39 2001
+++ linux/drivers/net/sungem.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: sungem.h,v 1.7 2001/04/04 14:49:40 davem Exp $
+/* $Id: sungem.h,v 1.8 2001/10/17 05:55:39 davem Exp $
X * sungem.h: Definitions for Sun GEM ethernet driver.


X *
X * Copyright (C) 2000 David S. Miller (da...@redhat.com)

@@ -756,9 +756,12 @@
X /* MII phy registers */
X #define PHY_CTRL 0x00
X #define PHY_STAT 0x01
+#define PHY_ID0 0x02
+#define PHY_ID1 0x03
X #define PHY_ADV 0x04
X #define PHY_LPA 0x05
X
+#define PHY_CTRL_SPD2 0x0040 /* Gigabit enable? (bcm5411) */
X #define PHY_CTRL_FDPLX 0x0100 /* Full duplex */
X #define PHY_CTRL_ISO 0x0400 /* Isloate MII from PHY */
X #define PHY_CTRL_ANRES 0x0200 /* Auto-negotiation restart */
@@ -778,8 +781,37 @@
X #define PHY_LPA_10FULL 0x0040
X #define PHY_LPA_100HALF 0x0080
X #define PHY_LPA_100FULL 0x0100
+#define PHY_LPA_PAUSE 0x0400
X #define PHY_LPA_FAULT 0x2000
X
+/* More PHY registers (specific to Broadcom models) */
+
+/* MII BCM5201 MULTIPHY interrupt register */
+#define PHY_BCM5201_INTERRUPT 0x1A
+#define PHY_BCM5201_INTERRUPT_INTENABLE 0x4000
+
+#define PHY_BCM5201_AUXMODE2 0x1B
+#define PHY_BCM5201_AUXMODE2_LOWPOWER 0x0008
+
+#define PHY_BCM5201_MULTIPHY 0x1E
+
+/* MII BCM5201 MULTIPHY register bits */
+#define PHY_BCM5201_MULTIPHY_SERIALMODE 0x0002
+#define PHY_BCM5201_MULTIPHY_SUPERISOLATE 0x0008
+
+/* MII BCM5400 1000-BASET Control register */
+#define PHY_BCM5400_GB_CONTROL 0x09
+#define PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP 0x0200
+
+/* MII BCM5400 AUXCONTROL register */
+#define PHY_BCM5400_AUXCONTROL 0x18
+#define PHY_BCM5400_AUXCONTROL_PWR10BASET 0x0004
+
+/* MII BCM5400 AUXSTATUS register */
+#define PHY_BCM5400_AUXSTATUS 0x19
+#define PHY_BCM5400_AUXSTATUS_LINKMODE_MASK 0x0700
+#define PHY_BCM5400_AUXSTATUS_LINKMODE_SHIFT 8
+
X /* When it can, GEM internally caches 4 aligned TX descriptors
X * at a time, so that it can use full cacheline DMA reads.
X *
@@ -916,9 +948,19 @@
X phy_serdes,
X };
X
+enum gem_phy_model {
+ phymod_generic,
+ phymod_bcm5201,
+ phymod_bcm5221,
+ phymod_bcm5400,
+ phymod_bcm5401,
+ phymod_bcm5411,
+};
+
X enum link_state {
X aneg_wait,
X force_wait,
+ aneg_up,
X };
X
X struct gem {
@@ -927,6 +969,11 @@
X int rx_new, rx_old;
X int tx_new, tx_old;
X
+ /* Set when chip is actually in operational state
+ * (ie. not power managed)
+ */
+ int hw_running;
+
X struct gem_init_block *init_block;
X
X struct sk_buff *rx_skbs[RX_RING_SIZE];
@@ -935,6 +982,7 @@
X struct net_device_stats net_stats;
X
X enum gem_phy_type phy_type;
+ enum gem_phy_model phy_mod;
X int tx_fifo_sz;
X int rx_fifo_sz;
X int rx_pause_off;
@@ -952,6 +1000,9 @@
X dma_addr_t gblock_dvma;
X struct pci_dev *pdev;
X struct net_device *dev;
+#ifdef CONFIG_ALL_PPC
+ struct device_node *of_node;
+#endif
X };
X
X #define ALIGNED_RX_SKB_ADDR(addr) \
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- v2.4.12/linux/drivers/net/sunhme.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/sunhme.c Fri Oct 12 15:35:53 2001
@@ -1,4 +1,4 @@
-/* $Id: sunhme.c,v 1.122 2001/08/13 14:40:07 davem Exp $
+/* $Id: sunhme.c,v 1.123 2001/10/02 02:22:30 davem Exp $
X * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching,
X * auto carrier detecting ethernet driver. Also known as the
X * "Happy Meal Ethernet" found on SunSwift SBUS cards.
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- v2.4.12/linux/drivers/net/sunlance.c Thu Apr 26 22:17:26 2001
+++ linux/drivers/net/sunlance.c Fri Oct 19 08:32:28 2001
@@ -1603,3 +1603,4 @@
X
X module_init(sparc_lance_probe);
X module_exit(sparc_lance_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c
--- v2.4.12/linux/drivers/net/sunqe.c Thu Apr 26 22:17:26 2001
+++ linux/drivers/net/sunqe.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: sunqe.c,v 1.51 2001/04/19 22:32:42 davem Exp $
+/* $Id: sunqe.c,v 1.52 2001/10/18 08:18:08 davem Exp $
X * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver.
X * Once again I am out to prove that every ethernet
X * controller out there can be most efficiently programmed
@@ -1041,3 +1041,4 @@
X
X module_init(qec_probe);
X module_exit(qec_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
--- v2.4.12/linux/drivers/net/tulip/interrupt.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/tulip/interrupt.c Tue Oct 16 21:56:29 2001
@@ -301,7 +301,7 @@
X long ioaddr = dev->base_addr;
X int csr5;
X int entry;
- int csr8;
+ int missed;
X int rx = 0;
X int tx = 0;
X int oi = 0;


@@ -434,6 +434,7 @@
X }

X }
X if (csr5 & RxDied) { /* Missed a Rx frame. */
+ tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
X #ifdef CONFIG_NET_HW_FLOWCONTROL
X if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
X tp->stats.rx_errors++;
@@ -547,8 +548,9 @@
X }
X }
X
- csr8 = inl(ioaddr + CSR8);
- tp->stats.rx_dropped += (csr8 & 0x1ffff) + ((csr8 >> 17) & 0xfff);
+ if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
+ tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+ }
X
X if (tulip_debug > 4)
X printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
diff -u --recursive --new-file v2.4.12/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.12/linux/drivers/net/tulip/tulip_core.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/tulip/tulip_core.c Tue Oct 16 21:56:29 2001
@@ -15,8 +15,8 @@
X */
X
X #define DRV_NAME "tulip"
-#define DRV_VERSION "0.9.15-pre7"
-#define DRV_RELDATE "Oct 2, 2001"
+#define DRV_VERSION "0.9.15-pre8"
+#define DRV_RELDATE "Oct 11, 2001"
X
X #include <linux/config.h>
X #include <linux/module.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.4.12/linux/drivers/net/via-rhine.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/via-rhine.c Mon Oct 15 13:32:32 2001
@@ -764,6 +764,7 @@
X RX_RING_SIZE * sizeof(struct rx_desc) +
X TX_RING_SIZE * sizeof(struct tx_desc),
X np->rx_ring, np->rx_ring_dma);
+ np->tx_ring = NULL;
X
X if (np->tx_bufs)
X pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
@@ -1595,11 +1596,6 @@
X #ifndef USE_IO
X iounmap((char *)(dev->base_addr));
X #endif
-
- pci_free_consistent(pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- np->rx_ring, np->rx_ring_dma);
X
X kfree(dev);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.4.12/linux/drivers/net/wavelan.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/wavelan.c Fri Oct 12 14:21:18 2001
@@ -2059,6 +2059,10 @@
X range.max_qual.qual = MMR_SGNL_QUAL;
X range.max_qual.level = MMR_SIGNAL_LVL;
X range.max_qual.noise = MMR_SILENCE_LVL;
+ range.avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
+ /* Need to get better values for those two */
+ range.avg_qual.level = 30;
+ range.avg_qual.noise = 8;
X
X range.num_bitrates = 1;
X range.bitrate[0] = 2000000; /* 2 Mb/s */
diff -u --recursive --new-file v2.4.12/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h
--- v2.4.12/linux/drivers/net/wavelan.p.h Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/wavelan.p.h Fri Oct 12 14:21:18 2001
@@ -447,13 +447,13 @@
X
X /* ------------------------ PRIVATE IOCTL ------------------------ */
X
-#define SIOCSIPQTHR SIOCDEVPRIVATE /* Set quality threshold */
-#define SIOCGIPQTHR SIOCDEVPRIVATE + 1 /* Get quality threshold */
-#define SIOCSIPLTHR SIOCDEVPRIVATE + 2 /* Set level threshold */
-#define SIOCGIPLTHR SIOCDEVPRIVATE + 3 /* Get level threshold */
+#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
+#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */
+#define SIOCSIPLTHR SIOCIWFIRSTPRIV + 2 /* Set level threshold */
+#define SIOCGIPLTHR SIOCIWFIRSTPRIV + 3 /* Get level threshold */
X
-#define SIOCSIPHISTO SIOCDEVPRIVATE + 6 /* Set histogram ranges */
-#define SIOCGIPHISTO SIOCDEVPRIVATE + 7 /* Get histogram values */
+#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 6 /* Set histogram ranges */
+#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 7 /* Get histogram values */
X
X /****************************** TYPES ******************************/
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- v2.4.12/linux/drivers/net/wireless/airo.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/wireless/airo.c Fri Oct 19 08:32:28 2001
@@ -14,7 +14,7 @@
X Aironet. Major code contributions were received from Javier Achirica
X and Jean Tourrilhes <j...@hpl.hp.com>. Code was also integrated from
X the Cisco Aironet driver for Linux.
-
+
X ======================================================================*/
X
X #include <linux/config.h>
@@ -53,7 +53,7 @@
X { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
X { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
X { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
- { 0, }
+ { 0, }
X };
X MODULE_DEVICE_TABLE(pci, card_ids);
X

@@ -213,7 +213,7 @@
X

X static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
X static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
- the bap, needed on some older cards and buses. */
+ the bap, needed on some older cards and buses. */
X static int adhoc;
X
X static int proc_uid /* = 0 */;
@@ -341,6 +341,9 @@
X
X /* The RIDs */
X #define RID_CAPABILITIES 0xFF00
+#define RID_APINFO 0xFF01
+#define RID_RADIOINFO 0xFF02
+#define RID_UNKNOWN3 0xFF03
X #define RID_RSSI 0xFF04
X #define RID_CONFIG 0xFF10
X #define RID_SSID 0xFF11
@@ -350,13 +353,25 @@
X #define RID_WEP_TEMP 0xFF15
X #define RID_WEP_PERM 0xFF16
X #define RID_MODULATION 0xFF17
+#define RID_OPTIONS 0xFF18
X #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
+#define RID_FACTORYCONFIG 0xFF21
+#define RID_UNKNOWN22 0xFF22
X #define RID_LEAPUSERNAME 0xFF23
X #define RID_LEAPPASSWORD 0xFF24
X #define RID_STATUS 0xFF50
+#define RID_UNKNOWN52 0xFF52
+#define RID_UNKNOWN54 0xFF54
+#define RID_UNKNOWN55 0xFF55
+#define RID_UNKNOWN56 0xFF56
+#define RID_STATS16 0xFF60
+#define RID_STATS16DELTA 0xFF61
+#define RID_STATS16DELTACLEAR 0xFF62
X #define RID_STATS 0xFF68
X #define RID_STATSDELTA 0xFF69
X #define RID_STATSDELTACLEAR 0xFF6A
+#define RID_UNKNOWN70 0xFF70
+#define RID_UNKNOWN71 0xFF71
X #define RID_BSSLISTFIRST 0xFF72
X #define RID_BSSLISTNEXT 0xFF73
X
@@ -563,7 +578,7 @@
X u16 spacer;
X u32 vals[100];
X } StatsRid;
-
+
X
X typedef struct {
X u16 len;
@@ -604,7 +619,7 @@
X #define RADIO_FH 1 /* Frequency hopping radio type */
X #define RADIO_DS 2 /* Direct sequence radio type */
X #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
- u16 radioType;
+ u16 radioType;
X u8 bssid[6]; /* Mac address of the BSS */
X u8 zero;
X u8 ssidLen;


@@ -653,14 +668,23 @@
X

X #ifdef CISCO_EXT
X #define AIROMAGIC 0xa55a
-#define AIROIOCTL SIOCDEVPRIVATE
+/* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
+#ifdef SIOCIWFIRSTPRIV
+#ifdef SIOCDEVPRIVATE
+#define AIROOLDIOCTL SIOCDEVPRIVATE
+#define AIROOLDIDIFC AIROOLDIOCTL + 1
+#endif /* SIOCDEVPRIVATE */
+#else /* SIOCIWFIRSTPRIV */
+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */
+#define AIROIOCTL SIOCIWFIRSTPRIV
X #define AIROIDIFC AIROIOCTL + 1
X
X /* Ioctl constants to be used in airo_ioctl.command */
X
X #define AIROGCAP 0 // Capability rid
-#define AIROGCFG 1 // USED A LOT
-#define AIROGSLIST 2 // System ID list
+#define AIROGCFG 1 // USED A LOT
+#define AIROGSLIST 2 // System ID list
X #define AIROGVLIST 3 // List of specified AP's
X #define AIROGDRVNAM 4 // NOTUSED
X #define AIROGEHTENC 5 // NOTUSED
@@ -728,11 +752,12 @@
X static u16 setup_card(struct airo_info*, u8 *mac, ConfigRid *);
X static void enable_interrupts(struct airo_info*);
X static void disable_interrupts(struct airo_info*);
+static u16 lock_issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
X static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
X static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
-static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
+static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
X int whichbap);
-static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
+static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
X int whichbap);
X static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
X int whichbap);
@@ -740,7 +765,7 @@
X static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len);
X static int PC4500_writerid(struct airo_info*, u16 rid, const void
X *pBuf, int len);
-static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
+static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
X int len );
X static u16 transmit_allocate(struct airo_info*, int lenPayload);
X static int transmit_802_3_packet(struct airo_info*, u16 TxFid, char
@@ -768,20 +793,18 @@
X int fids[MAX_FIDS];
X int registered;
X ConfigRid config;
- u16 authtype; // Used with auto_wep
+ u16 authtype; // Used with auto_wep
X char keyindex; // Used with auto wep
X char defindex; // Used with auto wep
X struct timer_list timer;
X struct proc_dir_entry *proc_entry;
X struct airo_info *next;
- spinlock_t bap0_lock;
- spinlock_t bap1_lock;
X spinlock_t aux_lock;
- spinlock_t cmd_lock;
+ spinlock_t main_lock;
X int flags;
X #define FLAG_PROMISC IFF_PROMISC
X #define FLAG_RADIO_OFF 0x02
- int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
+ int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
X int whichbap);
X int (*header_parse)(struct sk_buff*, unsigned char *);
X unsigned short *flash;
@@ -797,7 +820,7 @@
X #endif /* WIRELESS_EXT */
X };
X
-static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
+static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
X int whichbap) {
X return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
X }
@@ -816,12 +839,12 @@
X if (first == 1) {
X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd=CMD_LISTBSS;
- issuecommand(ai, &cmd, &rsp);
+ lock_issuecommand(ai, &cmd, &rsp);
X /* Let the command take effect */
X set_current_state (TASK_INTERRUPTIBLE);
X schedule_timeout (3*HZ);
X }
- rc = PC4500_readrid(ai,
+ rc = PC4500_readrid(ai,
X first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
X list, sizeof(*list));
X
@@ -837,9 +860,9 @@
X }
X
X static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
- int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
+ int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
X wkr, sizeof(*wkr));
-
+
X wkr->len = le16_to_cpu(wkr->len);
X wkr->kindex = le16_to_cpu(wkr->kindex);
X wkr->klen = le16_to_cpu(wkr->klen);
@@ -855,7 +878,7 @@
X wkr.kindex = cpu_to_le16(wkr.kindex);
X wkr.klen = cpu_to_le16(wkr.klen);
X rc = do_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr));
- if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
+ if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
X if (perm) {
X rc = do_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr));
X if (rc!=SUCCESS) {
@@ -890,7 +913,7 @@
X static int readConfigRid(struct airo_info*ai, ConfigRid *cfgr) {
X int rc = PC4500_readrid(ai, RID_ACTUALCONFIG, cfgr, sizeof(*cfgr));
X u16 *s;
-
+
X for(s = &cfgr->len; s <= &cfgr->rtsThres; s++) *s = le16_to_cpu(*s);
X
X for(s = &cfgr->shortRetryLimit; s <= &cfgr->radioType; s++)
@@ -898,16 +921,16 @@
X
X for(s = &cfgr->txPower; s <= &cfgr->radioSpecific; s++)
X *s = le16_to_cpu(*s);
-
+
X for(s = &cfgr->arlThreshold; s <= &cfgr->autoWake; s++)
X *s = le16_to_cpu(*s);
-
+
X return rc;
X }
X static int writeConfigRid(struct airo_info*ai, ConfigRid *pcfgr) {
X u16 *s;
X ConfigRid cfgr = *pcfgr;
-
+
X for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
X
X for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
@@ -915,10 +938,10 @@
X
X for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
X *s = cpu_to_le16(*s);
-
+
X for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
X *s = cpu_to_le16(*s);
-
+
X return do_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr));
X }
X static int readStatusRid(struct airo_info*ai, StatusRid *statr) {
@@ -947,7 +970,7 @@
X static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
X int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr));
X u16 *s;
-
+
X capr->len = le16_to_cpu(capr->len);
X capr->prodNum = le16_to_cpu(capr->prodNum);
X capr->radioType = le16_to_cpu(capr->radioType);
@@ -976,21 +999,19 @@
X
X static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
X s16 len;
- s16 retval = 0;
X u16 status;
X u32 flags;
- s8 *buffer;
X int i,j;
X struct airo_info *priv = (struct airo_info*)dev->priv;
X u32 *fids = priv->fids;
-
+
X if ( skb == NULL ) {
X printk( KERN_ERR "airo: skb == NULL!!!\n" );
X return 0;
X }
-
+
X /* Find a vacant FID */
- spin_lock_irqsave(&priv->bap1_lock, flags);
+ spin_lock_irqsave(&priv->main_lock, flags);
X for( j = 0, i = -1; j < MAX_FIDS; j++ ) {
X if ( !( fids[j] & 0xffff0000 ) ) {
X if ( i == -1 ) i = j;
@@ -999,31 +1020,51 @@
X }
X if ( j == MAX_FIDS ) netif_stop_queue(dev);
X if ( i == -1 ) {
- retval = -EBUSY;
+ priv->stats.tx_fifo_errors++;
X goto tx_done;
X }
-
+
X len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* check min length*/
- buffer = skb->data;
- status = transmit_802_3_packet( priv,
- fids[i],
- skb->data, len );
-
+ status = transmit_802_3_packet( priv, fids[i], skb->data, len );
+
X if ( status == SUCCESS ) {
X /* Mark fid as used & save length for later */
- fids[i] |= (len << 16);
+ fids[i] |= (len << 16);
X dev->trans_start = jiffies;
X } else {
- priv->stats.tx_errors++;
+ priv->stats.tx_window_errors++;
X }
X tx_done:
- spin_unlock_irqrestore(&priv->bap1_lock, flags);
+ spin_unlock_irqrestore(&priv->main_lock, flags);
X dev_kfree_skb(skb);


X return 0;
X }
X

-static struct net_device_stats *airo_get_stats(struct net_device *dev) {
- return &(((struct airo_info*)dev->priv)->stats);
+struct net_device_stats *airo_get_stats(struct net_device *dev)
+{
+ struct airo_info *local = (struct airo_info*) dev->priv;
+ StatsRid stats_rid;
+ u32 *vals = stats_rid.vals;
+
+ /* Get stats out of the card */
+ readStatsRid(local, &stats_rid, RID_STATS);
+
+ local->stats.rx_packets = vals[43] + vals[44] + vals[45];
+ local->stats.tx_packets = vals[39] + vals[40] + vals[41];
+ local->stats.rx_bytes = vals[92];
+ local->stats.tx_bytes = vals[91];
+ local->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];
+ local->stats.tx_errors = vals[42] + local->stats.tx_fifo_errors;
+ local->stats.multicast = vals[43];
+ local->stats.collisions = vals[89];
+
+ /* detailed rx_errors: */
+ local->stats.rx_length_errors = vals[3];
+ local->stats.rx_crc_errors = vals[4];
+ local->stats.rx_frame_errors = vals[2];
+ local->stats.rx_fifo_errors = vals[0];
+
+ return (&local->stats);
X }
X
X static int enable_MAC( struct airo_info *ai, Resp *rsp );
@@ -1033,7 +1074,7 @@
X struct airo_info *ai = (struct airo_info*)dev->priv;
X Cmd cmd;
X Resp rsp;
-
+
X /* For some reason this command takes a lot of time (~20 ms) and it's
X * run in an interrupt handler, so we'd better be sure we needed it
X * before executing it.
@@ -1042,7 +1083,7 @@
X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd=CMD_SETMODE;
X cmd.parm0=(dev->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
- issuecommand(ai, &cmd, &rsp);
+ lock_issuecommand(ai, &cmd, &rsp);
X ai->flags^=IFF_PROMISC;
X }
X
@@ -1073,7 +1114,7 @@
X }
X
X
-static int airo_close(struct net_device *dev) {
+static int airo_close(struct net_device *dev) {
X struct airo_info *ai = (struct airo_info*)dev->priv;
X
X netif_stop_queue(dev);
@@ -1083,7 +1124,7 @@
X
X static void del_airo_dev( struct net_device *dev );
X
-void stop_airo_card( struct net_device *dev, int freeres )
+void stop_airo_card( struct net_device *dev, int freeres )
X {
X struct airo_info *ai = (struct airo_info*)dev->priv;
X if (ai->flash)
@@ -1106,32 +1147,35 @@
X kfree( dev );
X }
X
-static int add_airo_dev( struct net_device *dev );
+static int add_airo_dev( struct net_device *dev );
X
X struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
X {
X struct net_device *dev;
X struct airo_info *ai;
X int i, rc;
-
+
X /* Create the network device object. */
X dev = alloc_etherdev(sizeof(*ai));
X if (!dev) {
X printk(KERN_ERR "airo: Couldn't alloc_etherdev\n");
X return NULL;
X }
+ if (dev_alloc_name(dev, dev->name) < 0) {
+ printk(KERN_ERR "airo: Couldn't get name!\n");


+ goto err_out_free;
+ }
+

X ai = dev->priv;
- ai->registered = 1;
+ ai->registered = 0;
X ai->dev = dev;
- ai->bap0_lock = SPIN_LOCK_UNLOCKED;
- ai->bap1_lock = SPIN_LOCK_UNLOCKED;
X ai->aux_lock = SPIN_LOCK_UNLOCKED;
- ai->cmd_lock = SPIN_LOCK_UNLOCKED;
+ ai->main_lock = SPIN_LOCK_UNLOCKED;
X ai->header_parse = dev->hard_header_parse;
X rc = add_airo_dev( dev );
X if (rc)
X goto err_out_free;
-
+
X /* The Airo-specific entries in the device structure. */
X dev->hard_start_xmit = &airo_start_xmit;
X dev->get_stats = &airo_get_stats;
@@ -1146,16 +1190,11 @@
X dev->stop = &airo_close;
X dev->irq = irq;
X dev->base_addr = port;
-
- rc = register_netdev(dev);
- if (rc)
- goto err_out_unlink;
-
- rc = request_irq( dev->irq, airo_interrupt,
- SA_SHIRQ | SA_INTERRUPT, dev->name, dev );
+
+ rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
X if (rc) {
X printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
- goto err_out_unregister;
+ goto err_out_unlink;
X }
X if (!is_pcmcia) {
X if (!request_region( dev->base_addr, 64, dev->name )) {
@@ -1163,13 +1202,18 @@
X goto err_out_irq;
X }
X }
-
+
X if ( setup_card( ai, dev->dev_addr, &ai->config) != SUCCESS ) {
X printk( KERN_ERR "airo: MAC could not be enabled\n" );
X rc = -EIO;
X goto err_out_res;
X }
X

+ rc = register_netdev(dev);
+ if (rc)

+ goto err_out_res;
+
+ ai->registered = 1;
X printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
X dev->name,
X dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
@@ -1189,8 +1233,6 @@
X release_region( dev->base_addr, 64 );
X err_out_irq:
X free_irq(dev->irq, dev);
-err_out_unregister:
- unregister_netdev(dev);
X err_out_unlink:
X del_airo_dev(dev);
X err_out_free:
@@ -1204,7 +1246,7 @@
X udelay (10);
X if (++delay % 20)
X OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
- }
+ }
X return delay < 10000;
X }
X
@@ -1253,29 +1295,33 @@
X u16 status;
X u16 fid;
X struct airo_info *apriv = (struct airo_info *)dev->priv;
- u16 savedInterrupts;
-
+ u16 savedInterrupts = 0;
+
X if (!netif_device_present(dev))
X return;
-
- status = IN4500( apriv, EVSTAT );
- if ( !status || status == 0xffff ) return;
-
- if ( status & EV_AWAKE ) {
- OUT4500( apriv, EVACK, EV_AWAKE );
- OUT4500( apriv, EVACK, EV_AWAKE );
- }
-
- savedInterrupts = IN4500( apriv, EVINTEN );
- OUT4500( apriv, EVINTEN, 0 );
-
- if ( status & EV_LINK ) {
- /* The link status has changed, if you want to put a
- monitor hook in, do it here. (Remember that
- interrupts are still disabled!)
- */
- u16 newStatus = IN4500(apriv, LINKSTAT);
- /* Here is what newStatus means: */
+
+ for (;;) {
+ status = IN4500( apriv, EVSTAT );
+ if ( !status || status == 0xffff ) break;
+
+ if ( status & EV_AWAKE ) {
+ OUT4500( apriv, EVACK, EV_AWAKE );
+ OUT4500( apriv, EVACK, EV_AWAKE );
+ }
+
+ if (!savedInterrupts) {
+ savedInterrupts = IN4500( apriv, EVINTEN );
+ OUT4500( apriv, EVINTEN, 0 );
+ }
+
+ if ( status & EV_LINK ) {
+ /* The link status has changed, if you want to put a
+ monitor hook in, do it here. (Remember that
+ interrupts are still disabled!)
+ */
+ u16 newStatus = IN4500(apriv, LINKSTAT);
+ OUT4500( apriv, EVACK, EV_LINK);
+ /* Here is what newStatus means: */
X #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
X #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
X #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
@@ -1304,155 +1350,137 @@
X leaving BSS */
X #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
X Authenticated with the responding station */
- if (newStatus != ASSOCIATED) {
- if (auto_wep && !timer_pending(&apriv->timer)) {
- apriv->timer.expires = RUN_AT(HZ*3);
- add_timer(&apriv->timer);
- }
- }
- }
-
- /* Check to see if there is something to receive */
- if ( status & EV_RX ) {
- struct sk_buff *skb = NULL;
- long flags;
- u16 fc, len, hdrlen = 0;
- struct {
- u16 status, len;
- u8 rssi[2];
- } hdr;
-
- fid = IN4500( apriv, RXFID );
-
- /* Get the packet length */
- spin_lock_irqsave(&apriv->bap0_lock, flags);
- if (dev->type == ARPHRD_IEEE80211) {
- bap_setup (apriv, fid, 4, BAP0);
- bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
- /* Bad CRC. Ignore packet */
- if (le16_to_cpu(hdr.status) == 2) {
- apriv->stats.rx_crc_errors++;
- apriv->stats.rx_errors++;
- hdr.len = 0;
+ if (newStatus != ASSOCIATED) {
+ if (auto_wep && !timer_pending(&apriv->timer)) {
+ apriv->timer.expires = RUN_AT(HZ*3);
+ add_timer(&apriv->timer);
+ }
X }
- } else {
- bap_setup (apriv, fid, 6, BAP0);
- bap_read (apriv, (u16*)&hdr.len, 4, BAP0);
X }
- len = le16_to_cpu(hdr.len);
X
- if (len > 2312) {
- apriv->stats.rx_length_errors++;
- apriv->stats.rx_errors++;
- printk( KERN_ERR
- "airo: Bad size %d\n", len );


- len = 0;
- }

- if (len) {
+ /* Check to see if there is something to receive */
+ if ( status & EV_RX ) {
+ struct sk_buff *skb = NULL;
+ u16 fc, len, hdrlen = 0;
+ struct {
+ u16 status, len;
+ u8 rssi[2];
+ } hdr;
+
+ fid = IN4500( apriv, RXFID );
+
+ /* Get the packet length */
X if (dev->type == ARPHRD_IEEE80211) {
- bap_setup (apriv, fid, 0x14, BAP0);
- bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
- if ((le16_to_cpu(fc) & 0x300) == 0x300)
- hdrlen = 30;
- else
- hdrlen = 24;
- } else
- hdrlen = 12;
+ bap_setup (apriv, fid, 4, BAP0);
+ bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
+ /* Bad CRC. Ignore packet */
+ if (le16_to_cpu(hdr.status) & 2)
+ hdr.len = 0;
+ } else {
+ bap_setup (apriv, fid, 6, BAP0);
+ bap_read (apriv, (u16*)&hdr.len, 4, BAP0);
+ }
+ len = le16_to_cpu(hdr.len);
X
- skb = dev_alloc_skb( len + hdrlen + 2 );
- if ( !skb ) {
- apriv->stats.rx_dropped++;
+ if (len > 2312) {
+ printk( KERN_ERR "airo: Bad size %d\n", len );
X len = 0;
X }
- }
- if (len) {
- u16 *buffer;
- buffer = (u16*)skb_put (skb, len + hdrlen);
- if (dev->type == ARPHRD_IEEE80211) {
- u16 gap, tmpbuf[4];
- buffer[0] = fc;
- bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
- if (hdrlen == 24)
- bap_read (apriv, tmpbuf, 6, BAP0);
-
- bap_read (apriv, &gap, sizeof(gap), BAP0);
- gap = le16_to_cpu(gap);
- if (gap && gap <= 8)
- bap_read (apriv, tmpbuf, gap, BAP0);
+ if (len) {
+ if (dev->type == ARPHRD_IEEE80211) {
+ bap_setup (apriv, fid, 0x14, BAP0);
+ bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
+ if ((le16_to_cpu(fc) & 0x300) == 0x300)
+ hdrlen = 30;
+ else
+ hdrlen = 24;
+ } else
+ hdrlen = 12;
X
- bap_read (apriv, buffer + hdrlen/2, len, BAP0);
- } else {
- bap_setup (apriv, fid, 0x38, BAP0);
- bap_read (apriv, buffer,len + hdrlen,BAP0);
+ skb = dev_alloc_skb( len + hdrlen + 2 );
+ if ( !skb ) {
+ apriv->stats.rx_dropped++;


+ len = 0;
+ }

X }
+ if (len) {
+ u16 *buffer;
+ buffer = (u16*)skb_put (skb, len + hdrlen);
+ if (dev->type == ARPHRD_IEEE80211) {
+ u16 gap, tmpbuf[4];
+ buffer[0] = fc;
+ bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
+ if (hdrlen == 24)


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 32'
echo 'File patch-2.4.13 is continued in part 33'
echo "33" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:01 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part31

#!/bin/sh -x
# this is part 31 of a 53 - part archive


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

if test "$Scheck" != 31; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

@@ -1372,7 +1385,7 @@
X struct rtl8139_private *tp = dev->priv;
X
X DPRINTK("ENTER\n");
-
+
X if (tp->phys[0] >= 0) {
X u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
X if (mii_reg5 == 0xffff)
@@ -1421,7 +1434,7 @@
X RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
X
X tp->cur_rx = 0;
-
+
X rtl_check_media (dev);
X
X if (tp->chipset >= CH_8139B) {
@@ -1879,7 +1892,7 @@
X {
X u8 tmp8;
X int tmp_work;
-
+
X DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
X dev->name, rx_status);
X if (rx_status & RxTooLong) {
@@ -1967,7 +1980,7 @@


X struct sk_buff *skb;
X

X rmb();
-
+
X /* read size+status of next frame from DMA ring buffer */
X rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
X rx_size = rx_status >> 16;
@@ -2376,7 +2389,7 @@
X }
X
X /* TODO: ETHTOOL_SSET */
-
+
X case ETHTOOL_GDRVINFO:
X {
X struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
diff -u --recursive --new-file v2.4.12/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.4.12/linux/drivers/net/Config.in Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/Config.in Fri Oct 19 08:32:28 2001
@@ -176,6 +176,7 @@
X dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
X dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
X dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
+ dep_tristate ' RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_8139CP $CONFIG_PCI $CONFIG_EXPERIMENTAL
X dep_tristate ' RealTek RTL-8139 PCI Fast Ethernet Adapter support' CONFIG_8139TOO $CONFIG_PCI
X dep_mbool ' Use PIO instead of MMIO' CONFIG_8139TOO_PIO $CONFIG_8139TOO
X dep_mbool ' Support for automatic channel equalization (EXPERIMENTAL)' CONFIG_8139TOO_TUNE_TWISTER $CONFIG_8139TOO $CONFIG_EXPERIMENTAL
@@ -191,7 +192,7 @@
X if [ "$CONFIG_OBSOLETE" = "y" ]; then
X dep_bool ' Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET $CONFIG_ISA
X fi
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_MIPS" = "y" ]; then
X bool ' Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730
X fi
X fi
diff -u --recursive --new-file v2.4.12/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.4.12/linux/drivers/net/Makefile Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/Makefile Fri Oct 19 08:32:28 2001
@@ -164,6 +164,7 @@
X obj-$(CONFIG_3C515) += 3c515.o
X obj-$(CONFIG_EEXPRESS) += eexpress.o
X obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
+obj-$(CONFIG_8139CP) += 8139cp.o
X obj-$(CONFIG_8139TOO) += 8139too.o
X obj-$(CONFIG_WAVELAN) += wavelan.o
X obj-$(CONFIG_ARLAN) += arlan.o arlan-proc.o
diff -u --recursive --new-file v2.4.12/linux/drivers/net/a2065.c linux/drivers/net/a2065.c
--- v2.4.12/linux/drivers/net/a2065.c Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/a2065.c Tue Oct 16 21:56:29 2001
@@ -837,3 +837,4 @@
X
X module_init(a2065_probe);
X module_exit(a2065_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.4.12/linux/drivers/net/acenic.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/net/acenic.c Fri Oct 12 15:35:53 2001
@@ -165,10 +165,6 @@
X #define SMP_CACHE_BYTES L1_CACHE_BYTES
X #endif
X
-#if (BITS_PER_LONG == 64) || defined(CONFIG_HIGHMEM)
-#define ACE_64BIT_PTR 1
-#endif
-
X #ifndef SET_MODULE_OWNER
X #define SET_MODULE_OWNER(dev) {do{} while(0);}
X #define ACE_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
@@ -203,9 +199,15 @@
X *dma_handle = virt_to_bus(virt_ptr);
X return virt_ptr;
X }
+
X #define pci_free_consistent(cookie, size, ptr, dma_ptr) kfree(ptr)
-#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
-#define pci_unmap_single(cookie, address, size, dir)
+#define pci_map_page(cookie, page, off, size, dir) \
+ virt_to_bus(page_address(page)+(off))
+#define pci_unmap_page(cookie, address, size, dir)
+#define pci_set_dma_mask(dev, mask) \
+ (((u64)(mask) & 0xffffffff00000000) == 0 ? 0 : -EIO)
+#define pci_dma_supported(dev, mask) \
+ (((u64)(mask) & 0xffffffff00000000) == 0 ? 1 : 0)
X #endif
X
X #if (LINUX_VERSION_CODE < 0x02032b)
@@ -263,10 +265,6 @@
X #define ace_if_down(dev) {do{} while(0);}
X #endif
X
-#ifndef pci_set_dma_mask
-#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
-#endif
-
X #if (LINUX_VERSION_CODE >= 0x02031b)
X #define NEW_NETINIT
X #define ACE_PROBE_ARG void
@@ -598,7 +596,7 @@
X dev->irq = pdev->irq;
X dev->open = &ace_open;
X dev->hard_start_xmit = &ace_start_xmit;
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;


+ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;

X if (1) {
X static void ace_watchdog(struct net_device *dev);
X dev->tx_timeout = &ace_watchdog;
@@ -740,6 +738,8 @@
X kfree(dev);
X continue;
X }
+ if (ap->pci_using_dac)


+ dev->features |= NETIF_F_HIGHDMA;
X

X boards_found++;
X }
@@ -816,9 +816,9 @@
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_std_skbuff[i].mapping;
- pci_unmap_single(ap->pdev, mapping,
- ACE_STD_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(ap->pdev, mapping,
+ ACE_STD_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X
X ap->rx_std_ring[i].size = 0;
X ap->skb->rx_std_skbuff[i].skb = NULL;
@@ -833,9 +833,9 @@
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_mini_skbuff[i].mapping;
- pci_unmap_single(ap->pdev, mapping,
- ACE_MINI_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(ap->pdev, mapping,
+ ACE_MINI_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X
X ap->rx_mini_ring[i].size = 0;
X ap->skb->rx_mini_skbuff[i].skb = NULL;
@@ -849,9 +849,9 @@
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_jumbo_skbuff[i].mapping;
- pci_unmap_single(ap->pdev, mapping,
- ACE_JUMBO_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(ap->pdev, mapping,
+ ACE_JUMBO_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X
X ap->rx_jumbo_ring[i].size = 0;
X ap->skb->rx_jumbo_skbuff[i].skb = NULL;
@@ -1210,12 +1210,6 @@
X ap->pci_latency);
X
X /*
- * Make sure to enable the 64 bit DMA mask if we're in a 64bit slot
- */
- if (!(pci_state & PCI_32BIT))
- pci_set_dma_mask(ap->pdev, (dma_addr_t)~0ULL);
-
- /*
X * Set the max DMA transfer size. Seems that for most systems
X * the performance is better when no MAX parameter is
X * set. However for systems enabling PCI write and invalidate,
@@ -1309,12 +1303,24 @@


X #endif
X
X /*

+ * Configure DMA attributes.
+ */
+ if (!pci_set_dma_mask(ap->pdev, (u64) 0xffffffffffffffff)) {
+ ap->pci_using_dac = 1;
+ } else if (!pci_set_dma_mask(ap->pdev, (u64) 0xffffffff)) {
+ ap->pci_using_dac = 0;
+ } else {
+ ecode = -ENODEV;
+ goto init_error;
+ }
+
+ /*
X * Initialize the generic info block and the command+event rings
X * and the control blocks for the transmit and receive rings
X * as they need to be setup once and for all.
X */
X if (!(info = pci_alloc_consistent(ap->pdev, sizeof(struct ace_info),
- &ap->info_dma))) {
+ &ap->info_dma))) {
X ecode = -EAGAIN;
X goto init_error;
X }
@@ -1355,12 +1361,8 @@
X ace_load_firmware(dev);
X ap->fw_running = 0;
X
- tmp_ptr = (unsigned long) ap->info_dma;
-#ifdef ACE_64BIT_PTR
+ tmp_ptr = (u64) ap->info_dma;
X writel(tmp_ptr >> 32, &regs->InfoPtrHi);
-#else
- writel(0, &regs->InfoPtrHi);
-#endif
X writel(tmp_ptr & 0xffffffff, &regs->InfoPtrLo);
X
X memset(ap->evt_ring, 0, EVT_RING_ENTRIES * sizeof(struct event));
@@ -1796,9 +1798,12 @@
X * Make sure IP header starts on a fresh cache line.
X */
X skb_reserve(skb, 2 + 16);
- mapping = pci_map_single(ap->pdev, skb->data,
- ACE_STD_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ mapping = pci_map_page(ap->pdev,


+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),

+ ACE_STD_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X ap->skb->rx_std_skbuff[idx].skb = skb;
X ap->skb->rx_std_skbuff[idx].mapping = mapping;
X
@@ -1860,9 +1865,12 @@
X * Make sure the IP header ends up on a fresh cache line
X */
X skb_reserve(skb, 2 + 16);
- mapping = pci_map_single(ap->pdev, skb->data,
- ACE_MINI_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ mapping = pci_map_page(ap->pdev,


+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),

+ ACE_MINI_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X ap->skb->rx_mini_skbuff[idx].skb = skb;
X ap->skb->rx_mini_skbuff[idx].mapping = mapping;
X
@@ -1919,9 +1927,12 @@
X * Make sure the IP header ends up on a fresh cache line
X */
X skb_reserve(skb, 2 + 16);
- mapping = pci_map_single(ap->pdev, skb->data,
- ACE_JUMBO_BUFSIZE - (2 + 16),
- PCI_DMA_FROMDEVICE);
+ mapping = pci_map_page(ap->pdev,


+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),

+ ACE_JUMBO_BUFSIZE - (2 + 16),
+ PCI_DMA_FROMDEVICE);
X ap->skb->rx_jumbo_skbuff[idx].skb = skb;
X ap->skb->rx_jumbo_skbuff[idx].mapping = mapping;
X
@@ -2129,8 +2140,8 @@
X
X skb = rip->skb;
X rip->skb = NULL;
- pci_unmap_single(ap->pdev, rip->mapping, mapsize,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(ap->pdev, rip->mapping, mapsize,
+ PCI_DMA_FROMDEVICE);
X skb_put(skb, retdesc->size);
X
X /*
@@ -2198,8 +2209,8 @@
X mapping = info->mapping;
X
X if (mapping) {
- pci_unmap_single(ap->pdev, mapping, info->maplen,
- PCI_DMA_TODEVICE);
+ pci_unmap_page(ap->pdev, mapping, info->maplen,
+ PCI_DMA_TODEVICE);
X info->mapping = 0;
X }
X
@@ -2488,11 +2499,10 @@
X
X if (mapping) {
X memset(ap->tx_ring+i, 0, sizeof(struct tx_desc));
- pci_unmap_single(ap->pdev, mapping, info->maplen,
- PCI_DMA_TODEVICE);
+ pci_unmap_page(ap->pdev, mapping, info->maplen,
+ PCI_DMA_TODEVICE);
X info->mapping = 0;
X }
-
X if (skb) {
X dev_kfree_skb(skb);
X info->skb = NULL;
@@ -2512,75 +2522,35 @@


X return 0;
X }
X
-

-/*
- * Following below should be (in more clean form!) in arch/ARCH/kernel/pci_*.
- * For now, let it stay here.
- */
-#if defined(CONFIG_HIGHMEM) && MAX_SKB_FRAGS
-
-#if defined(CONFIG_X86)
-#define DMAADDR_OFFSET 0
-typedef unsigned long long dmaaddr_high_t;
-#elif defined(CONFIG_PPC)
-#define DMAADDR_OFFSET PCI_DRAM_OFFSET
-typedef unsigned long dmaaddr_high_t;
-#endif
-
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
- int offset, size_t size, int dir)
-{
- dmaaddr_high_t phys;
-
- phys = (page-mem_map) * (dmaaddr_high_t) PAGE_SIZE + offset;
-
- return (phys + DMAADDR_OFFSET);
-}
-
-#else
-
-typedef unsigned long dmaaddr_high_t;
-
-static inline dmaaddr_high_t
-pci_map_single_high(struct pci_dev *hwdev, struct page *page,
- int offset, size_t size, int dir)
-{
- return pci_map_single(hwdev, page_address(page) + offset, size, dir);


-}
-
-#endif
-
-

-static inline dmaaddr_high_t
+static inline dma_addr_t
X ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
X struct sk_buff *tail, u32 idx)
X {
X unsigned long addr;
X struct tx_ring_info *info;
X
- addr = pci_map_single(ap->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+ addr = pci_map_page(ap->pdev,


+ virt_to_page(skb->data),
+ ((unsigned long) skb->data &
+ ~PAGE_MASK),

+ skb->len, PCI_DMA_TODEVICE);
X
X info = ap->skb->tx_skbuff + idx;
X info->skb = tail;
X info->mapping = addr;
X info->maplen = skb->len;
-
X return addr;
X }
X
X
X static inline void
-ace_load_tx_bd(struct tx_desc *desc, dmaaddr_high_t addr, u32 flagsize)
+ace_load_tx_bd(struct tx_desc *desc, u64 addr, u32 flagsize)
X {
X #if !USE_TX_COAL_NOW
X flagsize &= ~BD_FLG_COAL_NOW;
X #endif
X
-#ifdef ACE_64BIT_PTR
X desc->addr.addrhi = addr >> 32;
-#endif
X desc->addr.addrlo = addr;
X desc->flagsize = flagsize;
X }
@@ -2642,16 +2612,16 @@
X for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
X skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
X struct tx_ring_info *info;
- dmaaddr_high_t phys;
+ dma_addr_t phys;
X
X len += frag->size;
X info = ap->skb->tx_skbuff + idx;
X desc = ap->tx_ring + idx;
X
- phys = pci_map_single_high(ap->pdev, frag->page,
- frag->page_offset,
- frag->size,
- PCI_DMA_TODEVICE);
+ phys = pci_map_page(ap->pdev, frag->page,
+ frag->page_offset,
+ frag->size,
+ PCI_DMA_TODEVICE);
X
X flagsize = (frag->size << 16);
X if (skb->ip_summed == CHECKSUM_HW)
@@ -2673,7 +2643,6 @@
X }
X info->mapping = phys;
X info->maplen = frag->size;
-
X ace_load_tx_bd(desc, phys, flagsize);
X }
X }
@@ -2995,7 +2964,7 @@
X
X while (size > 0) {
X tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
- min_t(u32, size, ACE_WINDOW_SIZE));
+ min_t(u32, size, ACE_WINDOW_SIZE));
X tdest = (unsigned long)&regs->Window +
X (dest & (ACE_WINDOW_SIZE - 1));
X writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
@@ -3026,7 +2995,7 @@
X
X while (size > 0) {
X tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
- min_t(u32, size, ACE_WINDOW_SIZE));
+ min_t(u32, size, ACE_WINDOW_SIZE));
X tdest = (unsigned long)&regs->Window +
X (dest & (ACE_WINDOW_SIZE - 1));
X writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/acenic.h linux/drivers/net/acenic.h
--- v2.4.12/linux/drivers/net/acenic.h Thu Oct 11 08:02:26 2001
+++ linux/drivers/net/acenic.h Fri Oct 12 15:35:53 2001
@@ -582,7 +582,6 @@
X aceaddr stats2_ptr;
X };
X
-
X struct ring_info {
X struct sk_buff *skb;
X dma_addr_t mapping;
@@ -684,6 +683,7 @@
X u32 last_tx, last_std_rx, last_mini_rx;
X #endif
X struct net_device_stats stats;
+ int pci_using_dac;
X };
X
X
@@ -705,31 +705,11 @@
X
X static inline void set_aceaddr(aceaddr *aa, dma_addr_t addr)
X {
- unsigned long baddr = (unsigned long) addr;
-#ifdef ACE_64BIT_PTR
+ u64 baddr = (u64) addr;
X aa->addrlo = baddr & 0xffffffff;
X aa->addrhi = baddr >> 32;
-#else
- /* Don't bother setting zero every time */
- aa->addrlo = baddr;
-#endif
X mb();
X }
-
-
-#if 0
-static inline void *get_aceaddr(aceaddr *aa)
-{
- unsigned long addr;
- mb();
-#ifdef ACE_64BIT_PTR
- addr = (u64)aa->addrhi << 32 | aa->addrlo;
-#else
- addr = aa->addrlo;
-#endif
- return (void *)addr;
-}
-#endif
X
X
X static inline void ace_set_txprd(struct ace_regs *regs,
diff -u --recursive --new-file v2.4.12/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- v2.4.12/linux/drivers/net/atari_bionet.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/atari_bionet.c Tue Oct 16 21:56:29 2001
@@ -128,6 +128,7 @@
X unsigned int bionet_debug = NET_DEBUG;
X MODULE_PARM(bionet_debug, "i");
X MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
+MODULE_LICENSE("GPL");
X
X static unsigned int bionet_min_poll_time = 2;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c
--- v2.4.12/linux/drivers/net/atari_pamsnet.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/atari_pamsnet.c Tue Oct 16 21:56:29 2001
@@ -124,6 +124,7 @@
X unsigned int pamsnet_debug = NET_DEBUG;
X MODULE_PARM(pamsnet_debug, "i");
X MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
+MODULE_LICENSE("GPL");
X
X static unsigned int pamsnet_min_poll_time = 2;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c
--- v2.4.12/linux/drivers/net/atarilance.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/atarilance.c Tue Oct 16 21:56:29 2001
@@ -84,6 +84,7 @@
X #endif
X MODULE_PARM(lance_debug, "i");
X MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
+MODULE_LICENSE("GPL");
X
X /* Print debug messages on probing? */
X #undef LANCE_DEBUG_PROBE
diff -u --recursive --new-file v2.4.12/linux/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c
--- v2.4.12/linux/drivers/net/bagetlance.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/bagetlance.c Tue Oct 16 21:56:29 2001
@@ -60,6 +60,7 @@
X #endif
X MODULE_PARM(lance_debug, "i");
X MODULE_PARM_DESC(lance_debug, "Lance debug level (0-3)");
+MODULE_LICENSE("GPL");
X
X /* Print debug messages on probing? */
X #undef LANCE_DEBUG_PROBE
diff -u --recursive --new-file v2.4.12/linux/drivers/net/bmac.c linux/drivers/net/bmac.c
--- v2.4.12/linux/drivers/net/bmac.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/bmac.c Tue Oct 16 21:56:29 2001
@@ -1658,6 +1658,7 @@
X
X MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
X MODULE_DESCRIPTION("PowerMac BMAC ethernet driver.");


+MODULE_LICENSE("GPL");
X
X

X static void __exit bmac_cleanup (void)
diff -u --recursive --new-file v2.4.12/linux/drivers/net/fealnx.c linux/drivers/net/fealnx.c
--- v2.4.12/linux/drivers/net/fealnx.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/fealnx.c Tue Oct 16 21:56:29 2001
@@ -109,6 +109,7 @@
X
X MODULE_AUTHOR("Myson or whoever");
X MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
+MODULE_LICENSE("GPL");
X MODULE_PARM(max_interrupt_work, "i");
X //MODULE_PARM(min_pci_latency, "i");
X MODULE_PARM(debug, "i");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.4.12/linux/drivers/net/fmv18x.c Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/fmv18x.c Tue Oct 16 21:56:29 2001
@@ -632,6 +632,7 @@
X MODULE_PARM_DESC(io, "FMV-18X I/O address");
X MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
X MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
+MODULE_LICENSE("GPL");
X
X int init_module(void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/gmac.c linux/drivers/net/gmac.c
--- v2.4.12/linux/drivers/net/gmac.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/gmac.c Tue Oct 16 21:56:29 2001
@@ -1676,6 +1676,7 @@
X
X MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt");
X MODULE_DESCRIPTION("PowerMac GMAC driver.");
+MODULE_LICENSE("GPL");
X
X static void __exit gmac_cleanup_module(void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/gt96100eth.c linux/drivers/net/gt96100eth.c
--- v2.4.12/linux/drivers/net/gt96100eth.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/gt96100eth.c Tue Oct 16 21:56:29 2001
@@ -1250,3 +1250,4 @@
X }
X
X module_init(gt96100_probe);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- v2.4.12/linux/drivers/net/hamradio/scc.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/hamradio/scc.c Fri Oct 12 14:22:49 2001
@@ -1,5 +1,3 @@
-#define RCS_ID "$Id: scc.c,v 1.75 1998/11/04 15:15:01 jreuter Exp jreuter $"
-
X #define VERSION "3.0"
X
X /*
@@ -18,7 +16,7 @@
X
X ********************************************************************
X
- Copyright (c) 1993, 2000 Joerg Reuter DL1BKE
+ Copyright (c) 1993, 2001 Joerg Reuter DL1BKE
X
X portions (c) 1993 Guido ten Dolle PE1NNZ
X
@@ -106,6 +104,10 @@
X 2000-02-13 Fixed for new network driver interface changes, still
X does TX timeouts itself since it uses its own queue
X scheme.
+ 2001-10-05 Set skb to NULL on Rx_OVR in scc_spint() (tnx everybody
+ who insisted that the skb gets in fact re-used by the
+ following code otherwise. I think we have another Z8530
+ bug here...)
X
X Thanks to all who contributed to this driver with ideas and bug
X reports!
@@ -583,6 +585,7 @@
X if (skb != NULL)
X dev_kfree_skb_irq(skb);
X scc->rx_buff = skb = NULL;
+ skb = NULL; /* avoid skb being reused */
X }
X
X if(status & END_FR && skb != NULL) /* end of frame */
diff -u --recursive --new-file v2.4.12/linux/drivers/net/hplance.c linux/drivers/net/hplance.c
--- v2.4.12/linux/drivers/net/hplance.c Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/hplance.c Tue Oct 16 21:56:29 2001
@@ -226,6 +226,7 @@


X }
X
X #ifdef MODULE
+MODULE_LICENSE("GPL");

X int init_module(void)
X {
X root_lance_dev = NULL;
diff -u --recursive --new-file v2.4.12/linux/drivers/net/hydra.c linux/drivers/net/hydra.c
--- v2.4.12/linux/drivers/net/hydra.c Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/hydra.c Tue Oct 16 21:56:29 2001
@@ -254,3 +254,4 @@
X
X module_init(hydra_probe);
X module_exit(hydra_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ibmlana.c linux/drivers/net/ibmlana.c
--- v2.4.12/linux/drivers/net/ibmlana.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/ibmlana.c Tue Oct 16 21:56:29 2001
@@ -1199,6 +1199,7 @@
X MODULE_PARM(io, "i");
X MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
X MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
+MODULE_LICENSE("GPL");
X
X int init_module(void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c
--- v2.4.12/linux/drivers/net/ioc3-eth.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/ioc3-eth.c Tue Oct 16 21:56:29 2001
@@ -1817,6 +1817,7 @@
X
X MODULE_AUTHOR("Ralf Baechle <ra...@oss.sgi.com>");
X MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
+MODULE_LICENSE("GPL");
X
X module_init(ioc3_init_module);
X module_exit(ioc3_cleanup_module);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/isa-skeleton.c linux/drivers/net/isa-skeleton.c
--- v2.4.12/linux/drivers/net/isa-skeleton.c Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/isa-skeleton.c Tue Oct 16 21:56:29 2001
@@ -636,6 +636,7 @@
X static int irq;
X static int dma;
X static int mem;
+MODULE_LICENSE("GPL");
X
X int init_module(void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/lasi_82596.c linux/drivers/net/lasi_82596.c
--- v2.4.12/linux/drivers/net/lasi_82596.c Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/lasi_82596.c Tue Oct 16 21:56:29 2001


@@ -180,6 +180,7 @@
X

X MODULE_AUTHOR("Richard Hirst");
X MODULE_DESCRIPTION("i82596 driver");
+MODULE_LICENSE("GPL");
X MODULE_PARM(i596_debug, "i");
X MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask");
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/mac89x0.c linux/drivers/net/mac89x0.c
--- v2.4.12/linux/drivers/net/mac89x0.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/mac89x0.c Tue Oct 16 21:56:29 2001
@@ -627,6 +627,7 @@
X
X MODULE_PARM(debug, "i");
X MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
+MODULE_LICENSE("GPL");
X
X EXPORT_NO_SYMBOLS;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/mace.c linux/drivers/net/mace.c
--- v2.4.12/linux/drivers/net/mace.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/mace.c Tue Oct 16 21:56:29 2001
@@ -913,6 +913,7 @@
X
X MODULE_AUTHOR("Paul Mackerras");
X MODULE_DESCRIPTION("PowerMac MACE driver.");
+MODULE_LICENSE("GPL");
X
X static void __exit mace_cleanup (void)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/macsonic.c linux/drivers/net/macsonic.c
--- v2.4.12/linux/drivers/net/macsonic.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/net/macsonic.c Tue Oct 16 21:56:29 2001
@@ -584,6 +584,7 @@
X
X MODULE_PARM(sonic_debug, "i");
X MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
+MODULE_LICENSE("GPL");
X
X EXPORT_NO_SYMBOLS;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/mvme147.c linux/drivers/net/mvme147.c
--- v2.4.12/linux/drivers/net/mvme147.c Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/mvme147.c Tue Oct 16 21:56:29 2001
@@ -188,6 +188,8 @@


X }
X
X #ifdef MODULE

+MODULE_LICENSE("GPL");
+
X int init_module(void)
X {
X root_lance_dev = NULL;
diff -u --recursive --new-file v2.4.12/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- v2.4.12/linux/drivers/net/myri_sbus.c Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/myri_sbus.c Fri Oct 19 08:32:28 2001
@@ -1153,3 +1153,4 @@
X
X module_init(myri_sbus_probe);
X module_exit(myri_sbus_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ne2.c linux/drivers/net/ne2.c
--- v2.4.12/linux/drivers/net/ne2.c Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/ne2.c Tue Oct 16 21:56:29 2001
@@ -744,6 +744,7 @@
X static int io[MAX_NE_CARDS];
X static int irq[MAX_NE_CARDS];
X static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
+MODULE_LICENSE("GPL");
X
X #ifdef MODULE_PARM
X MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/oaknet.c linux/drivers/net/oaknet.c
--- v2.4.12/linux/drivers/net/oaknet.c Sat Mar 3 10:55:47 2001
+++ linux/drivers/net/oaknet.c Tue Oct 16 21:56:29 2001
@@ -696,3 +696,4 @@
X
X module_init(oaknet_init_module);
X module_exit(oaknet_cleanup_module);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
--- v2.4.12/linux/drivers/net/pci-skeleton.c Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/pci-skeleton.c Tue Oct 16 21:56:29 2001
@@ -484,6 +484,7 @@
X
X MODULE_AUTHOR ("Jeff Garzik <jga...@mandrakesoft.com>");
X MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver");
+MODULE_LICENSE("GPL");
X MODULE_PARM (multicast_filter_limit, "i");
X MODULE_PARM (max_interrupt_work, "i");
X MODULE_PARM (debug, "i");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c
--- v2.4.12/linux/drivers/net/pcmcia/netwave_cs.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/pcmcia/netwave_cs.c Fri Oct 12 14:21:18 2001
@@ -269,8 +269,15 @@
X because they generally can't be allocated dynamically.
X */
X
-#define SIOCGIPSNAP SIOCDEVPRIVATE /* Site Survey Snapshot */
-/*#define SIOCGIPQTHR SIOCDEVPRIVATE + 1*/
+/* Wireless Extension Backward compatibility - Jean II
+ * If the new wireless device private ioctl range is not defined,
+ * default to standard device private ioctl range */
+#ifndef SIOCIWFIRSTPRIV


+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */
+

+#define SIOCGIPSNAP SIOCIWFIRSTPRIV /* Site Survey Snapshot */
+/*#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1*/
X
X #define MAX_ESA 10
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
--- v2.4.12/linux/drivers/net/pcmcia/ray_cs.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/pcmcia/ray_cs.c Fri Oct 12 14:21:18 2001
@@ -1451,9 +1451,12 @@
X #endif /* WIRELESS_SPY */
X
X /* ------------------ PRIVATE IOCTL ------------------ */
-#define SIOCSIPFRAMING SIOCDEVPRIVATE /* Set framing mode */
-#define SIOCGIPFRAMING SIOCDEVPRIVATE + 1 /* Get framing mode */
-#define SIOCGIPCOUNTRY SIOCDEVPRIVATE + 3 /* Get country code */
+#ifndef SIOCIWFIRSTPRIV


+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */

+#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
+#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */
+#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
X case SIOCSIPFRAMING:
X if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcmcia/wavelan_cs.c linux/drivers/net/pcmcia/wavelan_cs.c
--- v2.4.12/linux/drivers/net/pcmcia/wavelan_cs.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/pcmcia/wavelan_cs.c Fri Oct 12 14:21:18 2001
@@ -2269,6 +2269,12 @@


X range.max_qual.qual = MMR_SGNL_QUAL;
X range.max_qual.level = MMR_SIGNAL_LVL;
X range.max_qual.noise = MMR_SILENCE_LVL;

+#if WIRELESS_EXT > 11


+ range.avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
+ /* Need to get better values for those two */
+ range.avg_qual.level = 30;
+ range.avg_qual.noise = 8;

+#endif /* WIRELESS_EXT > 11 */
X
X #if WIRELESS_EXT > 7
X range.num_bitrates = 1;
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcmcia/wavelan_cs.h linux/drivers/net/pcmcia/wavelan_cs.h
--- v2.4.12/linux/drivers/net/pcmcia/wavelan_cs.h Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/pcmcia/wavelan_cs.h Fri Oct 12 14:21:18 2001
@@ -465,13 +465,20 @@


X
X /* ------------------------ PRIVATE IOCTL ------------------------ */
X
-#define SIOCSIPQTHR SIOCDEVPRIVATE /* Set quality threshold */
-#define SIOCGIPQTHR SIOCDEVPRIVATE + 1 /* Get quality threshold */

-#define SIOCSIPROAM SIOCDEVPRIVATE + 2 /* Set roaming state */
-#define SIOCGIPROAM SIOCDEVPRIVATE + 3 /* Get roaming state */
+/* Wireless Extension Backward compatibility - Jean II
+ * If the new wireless device private ioctl range is not defined,
+ * default to standard device private ioctl range */
+#ifndef SIOCIWFIRSTPRIV


+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */

X
-#define SIOCSIPHISTO SIOCDEVPRIVATE + 6 /* Set histogram ranges */
-#define SIOCGIPHISTO SIOCDEVPRIVATE + 7 /* Get histogram values */

+#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
+#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */

+#define SIOCSIPROAM SIOCIWFIRSTPRIV + 2 /* Set roaming state */
+#define SIOCGIPROAM SIOCIWFIRSTPRIV + 3 /* Get roaming state */
+


+#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 6 /* Set histogram ranges */
+#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 7 /* Get histogram values */
X

X /*************************** WaveLAN Roaming **************************/
X #ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- v2.4.12/linux/drivers/net/pcmcia/xircom_tulip_cb.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c Tue Oct 16 21:56:29 2001
@@ -9,11 +9,25 @@
X Scyld Computing Corporation
X 410 Severn Ave., Suite 210
X Annapolis MD 21403
+
+ -----------------------------------------------------------
+
+ Linux kernel-specific changes:
+
+ LK1.0 (Ion Badulescu)
+ - Major cleanup
+ - Use 2.4 PCI API
+ - Support ethtool
+ - Rewrite perfect filter/hash code
+ - Use interrupts for media changes
+
+ LK1.1 (Ion Badulescu)
+ - Disallow negotiation of unsupported full-duplex modes
X */
X
X #define DRV_NAME "xircom_tulip_cb"
-#define DRV_VERSION "0.91+LK"
-#define DRV_RELDATE "July 19, 2001"
+#define DRV_VERSION "0.91+LK1.1"
+#define DRV_RELDATE "October 11, 2001"
X
X #define CARDBUS 1
X
@@ -94,7 +108,6 @@
X /* These identify the driver base version and may not be removed. */
X static char version[] __devinitdata =
X KERN_INFO DRV_NAME ".c derived from tulip.c:v0.91 4/14/99 bec...@scyld.com\n"
-KERN_INFO " modified by dan...@cs.uni-magdeburg.de for XIRCOM CBE, fixed by Doug Ledford\n"
X KERN_INFO " unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "\n";
X
X MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");
@@ -238,7 +251,7 @@
X int valid_intrs; /* CSR7 interrupt enable settings */
X int flags;
X } xircom_tbl[] = {
- { "Xircom Cardbus Adapter (DEC 21143 compatible mode)",
+ { "Xircom Cardbus Adapter",
X LinkChange | NormalIntr | AbnormalIntr | BusErrorIntr |
X RxDied | RxNoBuf | RxIntr | TxFIFOUnderflow | TxNoBuf | TxDied | TxIntr,
X HAS_MII | HAS_ACPI, },
@@ -425,12 +438,22 @@
X
X /*
X * locate the MII interfaces and initialize them.
+ * we disable full-duplex modes here,
+ * because we don't know how to handle them.
X */
X static void find_mii_transceivers(struct net_device *dev)
X {
X struct xircom_private *tp = dev->priv;
X int phy, phy_idx;
X
+ if (media_cap[tp->default_port] & MediaIsMII) {
+ u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
+ tp->to_advertise = media2advert[tp->default_port - 9];
+ } else
+ tp->to_advertise =
+ /*ADVERTISE_100BASE4 | ADVERTISE_100FULL |*/ ADVERTISE_100HALF |
+ /*ADVERTISE_10FULL |*/ ADVERTISE_10HALF | ADVERTISE_CSMA;
+
X /* Find the connected MII xcvrs.
X Doing this in open() would allow detecting external xcvrs later,
X but takes much time. */
@@ -447,17 +470,6 @@
X printk(KERN_INFO "%s: MII transceiver #%d "
X "config %4.4x status %4.4x advertising %4.4x.\n",
X dev->name, phy, mii_reg0, mii_status, mii_advert);
- /* Fixup for DLink with miswired PHY. */
- if (mii_advert != reg4) {
- printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d,"
- " previously advertising %4.4x.\n",
- dev->name, reg4, phy, mii_advert);
- mdio_write(dev, phy, MII_ADVERTISE, reg4);
- }
- /* Enable autonegotiation: some boards default to off. */
- mdio_write(dev, phy, MII_BMCR, mii_reg0 | BMCR_ANENABLE |
- (tp->full_duplex ? BMCR_FULLDPLX : 0) |
- (media_cap[tp->default_port]&MediaIs100 ? BMCR_SPEED100 : 0));
X }
X }
X tp->mii_cnt = phy_idx;
@@ -529,7 +541,7 @@
X printk(version);
X #endif
X
- printk(KERN_INFO "xircom_init_one(%s)\n", pdev->slot_name);
+ //printk(KERN_INFO "xircom_init_one(%s)\n", pdev->slot_name);
X
X board_idx++;
X
@@ -1696,7 +1708,6 @@
X }
X
X
-/* XXX: resume isn't able to power up the MII/PHY! */
X static int xircom_resume(struct pci_dev *pdev)
X {
X struct net_device *dev = pdev->driver_data;
diff -u --recursive --new-file v2.4.12/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- v2.4.12/linux/drivers/net/pcnet32.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/pcnet32.c Fri Oct 19 08:32:28 2001
@@ -53,7 +53,13 @@
X static struct pci_device_id pcnet32_pci_tbl[] __devinitdata = {
X { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
X { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+/* this id is never reached as the match above occurs first.
+ * However it clearly has significance, so let's not remove it
+ * until we know what that significance is. -jgarzik
+ */
+#if 0
X { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0x1014, 0x2000, 0, 0, 0 },
+#endif
X { 0, }
X };
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- v2.4.12/linux/drivers/net/ppp_generic.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/ppp_generic.c Thu Oct 11 09:18:31 2001
@@ -2481,3 +2481,4 @@
X EXPORT_SYMBOL(ppp_unregister_compressor);
X EXPORT_SYMBOL(all_ppp_units); /* for debugging */
X EXPORT_SYMBOL(all_channels); /* for debugging */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/ppp_synctty.c linux/drivers/net/ppp_synctty.c
--- v2.4.12/linux/drivers/net/ppp_synctty.c Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ppp_synctty.c Thu Oct 11 11:17:22 2001
@@ -44,13 +44,6 @@


X #include <linux/init.h>
X #include <asm/uaccess.h>

X
-#ifndef spin_trylock_bh
-#define spin_trylock_bh(lock) ({ int __r; local_bh_disable(); \
- __r = spin_trylock(lock); \
- if (!__r) local_bh_enable(); \
- __r; })
-#endif
-
X #define PPP_VERSION "2.4.1"
X
X /* Structure for storing local state. */
@@ -708,3 +701,4 @@
X
X module_init(ppp_sync_init);
X module_exit(ppp_sync_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/saa9730.c linux/drivers/net/saa9730.c
--- v2.4.12/linux/drivers/net/saa9730.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/saa9730.c Tue Oct 16 21:56:29 2001
@@ -1080,3 +1080,4 @@
X }
X
X module_init(saa9730_probe);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- v2.4.12/linux/drivers/net/seeq8005.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/seeq8005.c Tue Oct 16 21:56:29 2001
@@ -711,6 +711,7 @@
X static struct net_device dev_seeq = { init: seeq8005_probe };
X static int io = 0x320;
X static int irq = 10;
+MODULE_LICENSE("GPL");
X MODULE_PARM(io, "i");
X MODULE_PARM(irq, "i");
X MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.4.12/linux/drivers/net/sk98lin/skge.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/net/sk98lin/skge.c Fri Oct 12 15:35:53 2001
@@ -443,6 +443,11 @@
X if (pci_enable_device(pdev))
X continue;


X
+ /* Configure DMA attributes. */

+ if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
+ pci_set_dma_mask(pdev, (u64) 0xffffffff))
+ continue;
+
X if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) {
X printk(KERN_ERR "Unable to allocate etherdev "
X "structure!\n");
@@ -1770,10 +1775,12 @@
X #endif
X
X /* set up descriptor and CONTROL dword */
- PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev,
- pMessage->data,
- pMessage->len,
- PCI_DMA_TODEVICE);
+ PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev,
+ virt_to_page(pMessage->data),
+ ((unsigned long) pMessage->data &
+ ~PAGE_MASK),
+ pMessage->len,
+ PCI_DMA_TODEVICE);
X pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
X pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
X pTxd->pMBuf = pMessage;
@@ -1865,9 +1872,9 @@
X /* release the DMA mapping */
X PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
X PhysAddr |= (SK_U64) pTxd->VDataLow;
- pci_unmap_single(&pAC->PciDev, PhysAddr,
- pTxd->pMBuf->len,
- PCI_DMA_TODEVICE);
+ pci_unmap_page(&pAC->PciDev, PhysAddr,
+ pTxd->pMBuf->len,
+ PCI_DMA_TODEVICE);
X
X /* free message */
X DEV_KFREE_SKB_ANY(pTxd->pMBuf);
@@ -1946,10 +1953,12 @@
X pRxPort->pRxdRingTail = pRxd->pNextRxd;
X pRxPort->RxdRingFree--;
X Length = pAC->RxBufSize;
- PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev,
- pMsgBlock->data,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
+ PhysAddr = (SK_U64) pci_map_page(&pAC->PciDev,
+ virt_to_page(pMsgBlock->data),
+ ((unsigned long) pMsgBlock->data &
+ ~PAGE_MASK),
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
X pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
X pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
X pRxd->pMBuf = pMsgBlock;
@@ -2093,9 +2102,9 @@
X PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
X PhysAddr |= (SK_U64) pRxd->VDataLow;
X pci_dma_sync_single(&pAC->PciDev,
- (dma_addr_t) PhysAddr,
- FrameLength,
- PCI_DMA_FROMDEVICE);
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
X ReQueueRxBuffer(pAC, pRxPort, pMsg,
X pRxd->VDataHigh, pRxd->VDataLow);
X
@@ -2117,9 +2126,9 @@
X skb_reserve(pNewMsg, 2);
X skb_put(pNewMsg, FrameLength);
X pci_dma_sync_single(&pAC->PciDev,
- (dma_addr_t) PhysAddr,
- FrameLength,
- PCI_DMA_FROMDEVICE);
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
X eth_copy_and_sum(pNewMsg, pMsg->data,
X FrameLength, 0);
X ReQueueRxBuffer(pAC, pRxPort, pMsg,
@@ -2137,10 +2146,10 @@
X PhysAddr |= (SK_U64) pRxd->VDataLow;
X
X /* release the DMA mapping */
- pci_unmap_single(&pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(&pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
X
X /* set length in message */
X skb_put(pMsg, FrameLength);
@@ -2262,10 +2271,10 @@
X /* release the DMA mapping */
X PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
X PhysAddr |= (SK_U64) pRxd->VDataLow;
- pci_unmap_single(&pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(&pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
X DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
X pRxd->pMBuf = NULL;
X pRxPort->RxdRingFree++;
@@ -2342,10 +2351,10 @@
X if (pRxd->pMBuf != NULL) {
X PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
X PhysAddr |= (SK_U64) pRxd->VDataLow;
- pci_unmap_single(&pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(&pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
X DEV_KFREE_SKB(pRxd->pMBuf);
X pRxd->pMBuf = NULL;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v2.4.12/linux/drivers/net/sk_g16.c Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/sk_g16.c Tue Oct 16 21:56:29 2001
@@ -616,6 +616,7 @@
X
X MODULE_AUTHOR("Patrick J.D. Weichmann");
X MODULE_DESCRIPTION("Schneider & Koch G16 Ethernet Device Driver");
+MODULE_LICENSE("GPL");
X MODULE_PARM(io, "i");
X MODULE_PARM_DESC(io, "0 to probe common ports (unsafe), or the I/O base of the board");
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c
--- v2.4.12/linux/drivers/net/sk_mca.c Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/sk_mca.c Tue Oct 16 21:56:29 2001
@@ -1229,6 +1229,7 @@
X * ------------------------------------------------------------------------ */
X
X #ifdef MODULE
+MODULE_LICENSE("GPL");
X
X #define DEVMAX 5
X
diff -u --recursive --new-file v2.4.12/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c
--- v2.4.12/linux/drivers/net/smc-mca.c Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/smc-mca.c Tue Oct 16 21:56:29 2001
@@ -437,6 +437,7 @@
X static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS];
X static int io[MAX_ULTRAMCA_CARDS];
X static int irq[MAX_ULTRAMCA_CARDS];
+MODULE_LICENSE("GPL");
X
X MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
X MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- v2.4.12/linux/drivers/net/smc9194.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/smc9194.c Tue Oct 16 21:56:29 2001
@@ -1558,6 +1558,7 @@
X static int io;
X static int irq;
X static int ifport;
+MODULE_LICENSE("GPL");
X
X MODULE_PARM(io, "i");
X MODULE_PARM(irq, "i");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/stnic.c linux/drivers/net/stnic.c
--- v2.4.12/linux/drivers/net/stnic.c Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/stnic.c Tue Oct 16 21:56:29 2001
@@ -316,3 +316,4 @@
X
X module_init(stnic_probe);
X /* No cleanup routine. */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sun3lance.c linux/drivers/net/sun3lance.c
--- v2.4.12/linux/drivers/net/sun3lance.c Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/sun3lance.c Tue Oct 16 21:56:29 2001
@@ -71,6 +71,7 @@
X #endif
X MODULE_PARM(lance_debug, "i");
X MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
+MODULE_LICENSE("GPL");
X
X #define DPRINTK(n,a) \
X do { \
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c
--- v2.4.12/linux/drivers/net/sunbmac.c Thu Apr 26 22:17:25 2001
+++ linux/drivers/net/sunbmac.c Fri Oct 19 08:32:28 2001
@@ -1301,3 +1301,4 @@
X
X module_init(bigmac_probe);
X module_exit(bigmac_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sundance.c linux/drivers/net/sundance.c
--- v2.4.12/linux/drivers/net/sundance.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/sundance.c Fri Oct 19 08:32:28 2001
@@ -25,10 +25,9 @@
X
X /* The user-configurable values.
X These may be modified when a driver module is loaded.*/
-
X static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
X /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
+static int max_interrupt_work = 30;
X static int mtu;
X /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
X Typical is a 64 element hash table based on the Ethernet CRC. */
@@ -40,15 +39,20 @@
X need a copy-align. */
X static int rx_copybreak;
X
-/* 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[]'.
+/* media[] specifies the media type the NIC operates at.
+ autosense Autosensing active media.
+ 10mbps_hd 10Mbps half duplex.
+ 10mbps_fd 10Mbps full duplex.
+ 100mbps_hd 100Mbps half duplex.
+ 100mbps_fd 100Mbps full duplex.
+ 0 Autosensing active media.
+ 1 10Mbps half duplex.
+ 2 10Mbps full duplex.
+ 3 100Mbps half duplex.
+ 4 100Mbps full duplex.
X */
-#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};
-
+#define MAX_UNITS 8
+static char *media[MAX_UNITS];
X /* Operational parameters that are set at compile time. */
X
X /* Keep the ring sizes a power of two for compile efficiency.
@@ -65,7 +69,7 @@
X
X /* Operational parameters that usually are not changed. */
X /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT (2*HZ)
+#define TX_TIMEOUT (4*HZ)
X
X #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
X
@@ -98,7 +102,7 @@
X #include <asm/processor.h> /* Processor type for cache alignment. */
X #include <asm/bitops.h>
X #include <asm/io.h>
-
+#include <linux/delay.h>
X #include <linux/spinlock.h>
X
X /* These identify the driver base version and may not be removed. */
@@ -114,15 +118,11 @@
X MODULE_PARM(mtu, "i");
X MODULE_PARM(debug, "i");
X MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "s");
X MODULE_PARM_DESC(max_interrupt_work, "Sundance Alta maximum events handled per interrupt");
X MODULE_PARM_DESC(mtu, "Sundance Alta MTU (all boards)");
X MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
X MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(options, "Sundance Alta: Bits 0-3: media type, bit 17: full duplex");
-MODULE_PARM_DESC(full_duplex, "Sundance Alta full duplex setting(s) (1)");
-
X /*
X Theory of Operation
X
@@ -214,9 +214,12 @@
X #endif
X
X 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, }
+ {0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0},
+ {0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1},
+ {0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2},
+ {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+ {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+ {0,}
X };
X MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
X
@@ -231,11 +234,19 @@
X int drv_flags; /* Driver use, intended as capability flags. */
X };
X static struct pci_id_info pci_id_tbl[] = {
- {"OEM Sundance Technology ST201", {0x10021186, 0xffffffff, },
+ {"D-Link DFE-550TX FAST Ethernet Adapter", {0x10021186, 0xffffffff,},
X PCI_IOTYPE, 128, CanHaveMII},
- {"Sundance Technology Alta", {0x020113F0, 0xffffffff, },
+ {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter",
+ {0x10031186, 0xffffffff,},
X PCI_IOTYPE, 128, CanHaveMII},
- {0,}, /* 0 terminated list. */
+ {"D-Link DFE-580TX 4 port Server Adapter", {0x10121186, 0xffffffff,},
+ PCI_IOTYPE, 128, CanHaveMII},
+ {"D-Link DL10050-based FAST Ethernet Adapter",
+ {0x10021186, 0xffffffff,},
+ PCI_IOTYPE, 128, CanHaveMII},
+ {"Sundance Technology Alta", {0x020113F0, 0xffffffff,},
+ PCI_IOTYPE, 128, CanHaveMII},
+ {0,}, /* 0 terminated list. */
X };
X
X /* This driver was written to use PCI memory space, however x86-oriented
@@ -384,9 +395,10 @@
X unsigned int tx_full:1; /* The Tx queue is full. */
X /* These values are keep track of the transceiver/media in use. */
X unsigned int full_duplex:1; /* Full-duplex operation requested. */
- unsigned int duplex_lock:1;
X unsigned int medialock:1; /* Do not sense media. */
X unsigned int default_port:4; /* Last dev->if_port value. */
+ unsigned int an_enable:1;
+ unsigned int speed;
X /* Multicast and receive mode. */
X spinlock_t mcastlock; /* SMP lock multicast updates. */
X u16 mcast_filter[4];
@@ -428,8 +440,9 @@
X static int card_idx;
X int chip_idx = ent->driver_data;
X int irq;
- int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+ int i;
X long ioaddr;
+ u16 mii_reg0;
X void *ring_space;
X dma_addr_t ring_dma;
X
@@ -489,23 +502,6 @@
X np->rx_ring = (struct netdev_desc *)ring_space;
X np->rx_ring_dma = ring_dma;
X
- 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;
-
X /* The chip-specific entries in the device structure. */
X dev->open = &netdev_open;
X dev->hard_start_xmit = &start_tx;
@@ -548,6 +544,56 @@
X printk(KERN_INFO "%s: No MII transceiver found!, ASIC status %x\n",
X dev->name, readl(ioaddr + ASICCtrl));
X }
+ /* Parse override configuration */
+ np->an_enable = 1;
+ if (card_idx < MAX_UNITS) {
+ if (media[card_idx] != NULL) {
+ np->an_enable = 0;
+ if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
+ strcmp (media[card_idx], "4") == 0) {
+ np->speed = 100;
+ np->full_duplex = 1;
+ } else if (strcmp (media[card_idx], "100mbps_hd") == 0
+ || strcmp (media[card_idx], "3") == 0) {
+ np->speed = 100;
+ np->full_duplex = 0;
+ } else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
+ strcmp (media[card_idx], "2") == 0) {
+ np->speed = 10;
+ np->full_duplex = 1;
+ } else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
+ strcmp (media[card_idx], "1") == 0) {
+ np->speed = 10;
+ np->full_duplex = 0;
+ } else {
+ np->an_enable = 1;
+ }
+ }
+ }
+
+ /* Fibre PHY? */
+ if (readl (ioaddr + ASICCtrl) & 0x80) {
+ /* Default 100Mbps Full */
+ if (np->an_enable) {
+ np->speed = 100;
+ np->full_duplex = 1;
+ np->an_enable = 0;
+ }
+ }
+ /* Reset PHY */
+ mdio_write (dev, np->phys[0], 0, 0x8000);
+ mdelay (300);
+ mdio_write (dev, np->phys[0], 0, 0x1200);
+ /* Force media type */
+ if (!np->an_enable) {
+ mii_reg0 = 0;
+ mii_reg0 |= (np->speed == 100) ? 0x2000 : 0;
+ mii_reg0 |= (np->full_duplex) ? 0x0100 : 0;
+ mdio_write (dev, np->phys[0], 0, mii_reg0);
+ printk (KERN_INFO "Override speed=%d, %s duplex\n",
+ np->speed, np->full_duplex ? "Full" : "Half");
+
+ }
X
X /* Perhaps move the reset here? */
X /* Reset the chip to erase previous misconfiguration. */
@@ -714,7 +760,6 @@
X if (dev->if_port == 0)
X dev->if_port = np->default_port;
X
- np->full_duplex = np->duplex_lock;
X np->mcastlock = (spinlock_t) SPIN_LOCK_UNLOCKED;
X
X set_rx_mode(dev);
@@ -755,9 +800,15 @@
X int mii_reg5 = mdio_read(dev, np->phys[0], 5);
X int negotiated = mii_reg5 & np->advertising;
X int duplex;
-
- if (np->duplex_lock || mii_reg5 == 0xffff)
+
+ /* Force media */
+ if (!np->an_enable || mii_reg5 == 0xffff) {
+ if (np->full_duplex)
+ writew (readw (ioaddr + MACCtrl0) | EnbFullDuplex,
+ ioaddr + MACCtrl0);
X return;
+ }
+ /* Autonegotiation */
X duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
X if (np->full_duplex != duplex) {
X np->full_duplex = duplex;
@@ -1003,10 +1054,10 @@
X /* Abnormal error summary/uncommon events handlers. */
X if (intr_status & (IntrDrvRqst | IntrPCIErr | LinkChange | StatsMax))
X netdev_error(dev, intr_status);
-
X if (--boguscnt < 0) {
X get_stats(dev);
- printk(KERN_WARNING "%s: Too much work at interrupt, "
+ if (debug > 1)
+ printk(KERN_WARNING "%s: Too much work at interrupt, "
X "status=0x%4.4x / 0x%4.4x.\n",
X dev->name, intr_status, readw(ioaddr + IntrClear));
X /* Re-enable us in 3.2msec. */
@@ -1132,21 +1183,46 @@
X {


X long ioaddr = dev->base_addr;

X struct netdev_private *np = dev->priv;
+ u16 mii_reg0, mii_reg4, mii_reg5;
+ int speed;
X
X if (intr_status & IntrDrvRqst) {
X /* Stop the down counter and turn interrupts back on. */
- printk("%s: Turning interrupts back on.\n", dev->name);
+ if (debug > 1)
+ printk("%s: Turning interrupts back on.\n", dev->name);
X writew(0, ioaddr + IntrEnable);
X writew(0, ioaddr + DownCounter);
X writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst |
X IntrTxDone | StatsMax | LinkChange, ioaddr + IntrEnable);
+ /* Ack buggy InRequest */
+ writew (IntrDrvRqst, ioaddr + IntrStatus);
X }
X 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 (np->an_enable) {
+ mii_reg4 = mdio_read (dev, np->phys[0], 4);
+ mii_reg5= mdio_read (dev, np->phys[0], 5);
+ mii_reg4 &= mii_reg5;
+ printk (KERN_INFO "%s: Link changed: ", dev->name);
+ if (mii_reg4 & 0x0100)
+ printk ("100Mbps, full duplex\n");
+ else if (mii_reg4 & 0x0080)
+ printk ("100Mbps, half duplex\n");
+ else if (mii_reg4 & 0x0040)
+ printk ("10Mbps, full duplex\n");
+ else if (mii_reg4 & 0x0020)
+ printk ("10Mbps, half duplex\n");
+ else
+ printk ("\n");
+
+ } else {
+ mii_reg0 = mdio_read (dev, np->phys[0], 0);
+ speed = (mii_reg0 & 0x2000) ? 100 : 10;
+ printk (KERN_INFO "%s: Link changed: %dMbps ,",
+ dev->name, speed);
+ printk ("%s duplex.\n", (mii_reg0 & 0x0100) ?
+ "full" : "half");
+ }
+ check_duplex (dev);
X }
X if (intr_status & StatsMax) {
X get_stats(dev);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/sungem.c linux/drivers/net/sungem.c
--- v2.4.12/linux/drivers/net/sungem.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/sungem.c Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: sungem.c,v 1.20 2001/09/19 00:04:32 davem Exp $
+/* $Id: sungem.c,v 1.30 2001/10/17 06:55:10 davem Exp $
X * sungem.c: Sun GEM ethernet driver.
X *
X * Copyright (C) 2000, 2001 David S. Miller (da...@redhat.com)
@@ -36,15 +36,17 @@
X #include <asm/pbm.h>
X #endif
X
-#ifdef __powerpc__
+#ifdef CONFIG_ALL_PPC
X #include <asm/pci-bridge.h>
X #include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
X #endif
X
X #include "sungem.h"
X
X static char version[] __devinitdata =
- "sungem.c:v0.75 21/Mar/01 David S. Miller (da...@redhat.com)\n";
+ "sungem.c:v0.95 16/Oct/01 David S. Miller (da...@redhat.com)\n";
X
X MODULE_AUTHOR("David S. Miller (da...@redhat.com)");
X MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
@@ -69,6 +71,9 @@
X /* These models only differ from the original GEM in
X * that their tx/rx fifos are of a different size and
X * they only support 10/100 speeds. -DaveM
+ *
+ * Apple's GMAC does support gigabit on machines with
+ * the BCM5400 or 5401 PHYs. -BenH
X */
X { PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_GEM,
X PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -79,14 +84,14 @@
X
X MODULE_DEVICE_TABLE(pci, gem_pci_tbl);
X
-static u16 phy_read(struct gem *gp, int reg)
+static u16 __phy_read(struct gem *gp, int reg, int phy_addr)
X {
X u32 cmd;
X int limit = 10000;
X
X cmd = (1 << 30);
X cmd |= (2 << 28);
- cmd |= (gp->mii_phy_addr << 23) & MIF_FRAME_PHYAD;
+ cmd |= (phy_addr << 23) & MIF_FRAME_PHYAD;
X cmd |= (reg << 18) & MIF_FRAME_REGAD;
X cmd |= (MIF_FRAME_TAMSB);
X writel(cmd, gp->regs + MIF_FRAME);
@@ -105,14 +110,19 @@
X return cmd & MIF_FRAME_DATA;
X }
X
-static void phy_write(struct gem *gp, int reg, u16 val)
+static inline u16 phy_read(struct gem *gp, int reg)
+{
+ return __phy_read(gp, reg, gp->mii_phy_addr);
+}
+
+static void __phy_write(struct gem *gp, int reg, u16 val, int phy_addr)
X {
X u32 cmd;
X int limit = 10000;
X
X cmd = (1 << 30);
X cmd |= (1 << 28);
- cmd |= (gp->mii_phy_addr << 23) & MIF_FRAME_PHYAD;
+ cmd |= (phy_addr << 23) & MIF_FRAME_PHYAD;
X cmd |= (reg << 18) & MIF_FRAME_REGAD;
X cmd |= (MIF_FRAME_TAMSB);
X cmd |= (val & MIF_FRAME_DATA);
@@ -127,6 +137,11 @@
X }
X }
X
+static inline void phy_write(struct gem *gp, int reg, u16 val)
+{
+ __phy_write(gp, reg, val, gp->mii_phy_addr);
+}
+
X static void gem_handle_mif_event(struct gem *gp, u32 reg_val, u32 changed_bits)
X {
X }
@@ -418,7 +433,8 @@
X while (entry != limit) {
X struct sk_buff *skb;
X struct gem_txd *txd;
- u32 dma_addr, dma_len;
+ dma_addr_t dma_addr;
+ u32 dma_len;
X int frag;
X
X skb = gp->tx_skbs[entry];
@@ -444,10 +460,10 @@


X for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {

X txd = &gp->init_block->txd[entry];
X

- dma_addr = (u32) le64_to_cpu(txd->buffer);

+ dma_addr = le64_to_cpu(txd->buffer);

X dma_len = le64_to_cpu(txd->control_word) & TXDCTRL_BUFSZ;
X
- pci_unmap_single(gp->pdev, dma_addr, dma_len, PCI_DMA_TODEVICE);
+ pci_unmap_page(gp->pdev, dma_addr, dma_len, PCI_DMA_TODEVICE);


X entry = NEXT_TX(entry);
X }
X

@@ -498,7 +514,7 @@
X struct gem_rxd *rxd = &gp->init_block->rxd[entry];
X struct sk_buff *skb;
X u64 status = cpu_to_le64(rxd->status_word);


- u32 dma_addr;
+ dma_addr_t dma_addr;

X int len;
X
X if ((status & RXDCTRL_OWN) != 0)
@@ -520,7 +536,7 @@
X goto next;
X }
X
- dma_addr = (u32) cpu_to_le64(rxd->buffer);
+ dma_addr = cpu_to_le64(rxd->buffer);
X if (len > RX_COPY_THRESHOLD) {
X struct sk_buff *new_skb;
X
@@ -529,15 +545,18 @@
X drops++;
X goto drop_it;
X }
- pci_unmap_single(gp->pdev, dma_addr,
- RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE);


+ pci_unmap_page(gp->pdev, dma_addr,
+ RX_BUF_ALLOC_SIZE(gp),
+ PCI_DMA_FROMDEVICE);

X gp->rx_skbs[entry] = new_skb;
X new_skb->dev = gp->dev;
X skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
- rxd->buffer = cpu_to_le64(pci_map_single(gp->pdev,


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 31'
echo 'File patch-2.4.13 is continued in part 32'
echo "32" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:03 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part33

#!/bin/sh -x
# this is part 33 of a 53 - part archive


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

if test "$Scheck" != 33; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ bap_read (apriv, tmpbuf, 6, BAP0);
+
+ bap_read (apriv, &gap, sizeof(gap), BAP0);
+ gap = le16_to_cpu(gap);
+ if (gap && gap <= 8)
+ bap_read (apriv, tmpbuf, gap, BAP0);
+
+ bap_read (apriv, buffer + hdrlen/2, len, BAP0);
+ } else {
+ bap_setup (apriv, fid, 0x38, BAP0);
+ bap_read (apriv, buffer,len + hdrlen,BAP0);
+ }
+ OUT4500( apriv, EVACK, EV_RX);
X #ifdef WIRELESS_SPY
- if (apriv->spy_number > 0) {
- int i;
- char *sa;
-
- sa = (char*)buffer + ((dev->type == ARPHRD_IEEE80211) ? 10 : 6);
-
- for (i=0; i<apriv->spy_number; i++)
- if (!memcmp(sa,apriv->spy_address[i],6))
- {
- apriv->spy_stat[i].qual = hdr.rssi[0];
- if (apriv->rssi)
- apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
- else
- apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
- apriv->spy_stat[i].noise = 0;
- apriv->spy_stat[i].updated = 3;
- break;
- }
- }
+ if (apriv->spy_number > 0) {
+ int i;
+ char *sa;
+
+ sa = (char*)buffer + ((dev->type == ARPHRD_IEEE80211) ? 10 : 6);
+
+ for (i=0; i<apriv->spy_number; i++)
+ if (!memcmp(sa,apriv->spy_address[i],6))
+ {
+ apriv->spy_stat[i].qual = hdr.rssi[0];
+ if (apriv->rssi)
+ apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
+ else
+ apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
+ apriv->spy_stat[i].noise = 0;
+ apriv->spy_stat[i].updated = 3;
+ break;
+ }
+ }


X #endif /* WIRELESS_SPY */

- apriv->stats.rx_packets++;
- apriv->stats.rx_bytes += len + hdrlen;


- dev->last_rx = jiffies;

- skb->dev = dev;

- skb->ip_summed = CHECKSUM_NONE;


- if (dev->type == ARPHRD_IEEE80211) {

- skb->mac.raw = skb->data;
- skb_pull (skb, hdrlen);
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = htons(ETH_P_802_2);
- } else
- skb->protocol = eth_type_trans( skb, dev );
+ dev->last_rx = jiffies;
+ skb->dev = dev;


+ skb->ip_summed = CHECKSUM_NONE;

+ if (dev->type == ARPHRD_IEEE80211) {

+ skb->mac.raw = skb->data;
+ skb_pull (skb, hdrlen);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ } else
+ skb->protocol = eth_type_trans(skb,dev);
X
- netif_rx( skb );
+ netif_rx( skb );
+ } else
+ OUT4500( apriv, EVACK, EV_RX);
X }
- spin_unlock_irqrestore(&apriv->bap0_lock, flags);
- }
X
- /* Check to see if a packet has been transmitted */
- if ( status & ( EV_TX|EV_TXEXC ) ) {
- int i;


- int len = 0;

- int full = 1;
- int index = -1;
-
- fid = IN4500(apriv, TXCOMPLFID);
-
- for( i = 0; i < MAX_FIDS; i++ ) {
- if (!(apriv->fids[i] & 0xffff0000)) full = 0;
- if ( ( apriv->fids[i] & 0xffff ) == fid ) {
- len = apriv->fids[i] >> 16;
- index = i;
- /* Set up to be used again */
- apriv->fids[i] &= 0xffff;
+ /* Check to see if a packet has been transmitted */
+ if ( status & ( EV_TX|EV_TXEXC ) ) {
+ int i;


+ int len = 0;

+ int index = -1;
+
+ fid = IN4500(apriv, TXCOMPLFID);
+
+ for( i = 0; i < MAX_FIDS; i++ ) {
+ if ( ( apriv->fids[i] & 0xffff ) == fid ) {
+ len = apriv->fids[i] >> 16;
+ index = i;
+ /* Set up to be used again */
+ apriv->fids[i] &= 0xffff;
+ }
X }
- }
- if (full) netif_wake_queue(dev);
- if (index==-1) {
- printk( KERN_ERR
- "airo: Unallocated FID was used to xmit\n" );
- }
- if ( status & EV_TX ) {
- apriv->stats.tx_packets++;
- if(index!=-1)
- apriv->stats.tx_bytes += len;
- } else {
- if (bap_setup(apriv, fid, 0x0004, BAP1) == SUCCESS) {
+ if (index != -1) netif_wake_queue(dev);
+ if ((status & EV_TXEXC) &&
+ (bap_setup(apriv, fid, 4, BAP1) == SUCCESS)) {
+
X u16 status;
X bap_read(apriv, &status, 2, BAP1);
X if (le16_to_cpu(status) & 2)
@@ -1462,18 +1490,24 @@
X if (le16_to_cpu(status) & 0x10)
X apriv->stats.tx_carrier_errors++;
X }
- apriv->stats.tx_errors++;
+ OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
+ if (index==-1) {
+ printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
+ }
X }
+ if ( status & ~STATUS_INTS )
+ OUT4500( apriv, EVACK, status & ~STATUS_INTS);
+
+ if ( status & ~STATUS_INTS & ~IGNORE_INTS )
+ printk( KERN_WARNING "airo: Got weird status %x\n",
+ status & ~STATUS_INTS & ~IGNORE_INTS );
X }
- if ( status & ~STATUS_INTS & ~IGNORE_INTS )
- printk( KERN_WARNING
- "airo: Got weird status %x\n",
- status & ~STATUS_INTS & ~IGNORE_INTS );
- OUT4500( apriv, EVACK, status & STATUS_INTS );
- OUT4500( apriv, EVINTEN, savedInterrupts );
-
+
+ if (savedInterrupts)
+ OUT4500( apriv, EVINTEN, savedInterrupts );
+
X /* done.. */
- return;
+ return;
X }
X
X /*
@@ -1496,7 +1530,7 @@
X
X static u16 IN4500( struct airo_info *ai, u16 reg ) {
X unsigned short rc;
-
+
X if ( !do8bitIO )
X rc = inw( ai->dev->base_addr + reg );
X else {
@@ -1512,7 +1546,7 @@
X if (ai->flags&FLAG_RADIO_OFF) return SUCCESS;
X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd = MAC_ENABLE;
- return issuecommand(ai, &cmd, rsp);
+ return lock_issuecommand(ai, &cmd, rsp);
X }
X
X static void disable_MAC( struct airo_info *ai ) {


@@ -1521,7 +1555,7 @@
X

X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd = MAC_DISABLE; // disable in case already enabled


- issuecommand(ai, &cmd, &rsp);
+ lock_issuecommand(ai, &cmd, &rsp);
X }

X
X static void enable_interrupts( struct airo_info *ai ) {
@@ -1538,10 +1572,10 @@
X OUT4500( ai, EVINTEN, 0 );
X }
X
-static u16 setup_card(struct airo_info *ai, u8 *mac,
+static u16 setup_card(struct airo_info *ai, u8 *mac,
X ConfigRid *config)
X {
- Cmd cmd;
+ Cmd cmd;
X Resp rsp;
X ConfigRid cfg;
X int status;
@@ -1560,18 +1594,18 @@
X /* The NOP is the first step in getting the card going */
X cmd.cmd = NOP;
X cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
- if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
+ if ( lock_issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
X return ERROR;
X }
X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd = MAC_DISABLE; // disable in case already enabled
- if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
+ if ( lock_issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
X return ERROR;
X }
-
+
X // Let's figure out if we need to use the AUX port
X cmd.cmd = CMD_ENABLEAUX;
- if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
+ if (lock_issuecommand(ai, &cmd, &rsp) != SUCCESS) {
X printk(KERN_ERR "airo: Error checking for AUX port\n");
X return ERROR;
X }
@@ -1586,7 +1620,7 @@
X cfg = *config;
X } else {
X tdsRssiRid rssi_rid;
-
+
X // general configuration (read/modify/write)
X status = readConfigRid(ai, &cfg);
X if ( status != SUCCESS ) return ERROR;
@@ -1606,23 +1640,23 @@
X if ((status == SUCCESS) && (cap_rid.softCap & 8))
X cfg.rmode |= RXMODE_NORMALIZED_RSSI;
X else
- printk(KERN_WARNING "airo: unknown received signal level\n");
+ printk(KERN_WARNING "airo: unknown received signal level scale\n");
X }
X cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
-
+
X /* Save off the MAC */
X for( i = 0; i < 6; i++ ) {
X mac[i] = cfg.macAddr[i];
X }
X
- /* Check to see if there are any insmod configured
+ /* Check to see if there are any insmod configured
X rates to add */
X if ( rates ) {
X int i = 0;
X if ( rates[0] ) memset(cfg.rates,0,sizeof(cfg.rates));
X for( i = 0; i < 8 && rates[i]; i++ ) {
X cfg.rates[i] = rates[i];
- }
+ }
X }
X if ( basic_rate > 0 ) {
X int i;
@@ -1637,27 +1671,27 @@
X cfg.authType = ai->authtype;
X *config = cfg;
X }
-
+
X /* Setup the SSIDs if present */
X if ( ssids[0] ) {
X int i = 0;
X for( i = 0; i < 3 && ssids[i]; i++ ) {
X mySsid.ssids[i].len = strlen(ssids[i]);
- if ( mySsid.ssids[i].len > 32 )
+ if ( mySsid.ssids[i].len > 32 )
X mySsid.ssids[i].len = 32;
X memcpy(mySsid.ssids[i].ssid, ssids[i],
X mySsid.ssids[i].len);
X mySsid.ssids[i].len = mySsid.ssids[i].len;
X }
X }
-
+
X status = writeConfigRid(ai, &cfg);
X if ( status != SUCCESS ) return ERROR;
-
+
X /* Set up the SSID list */
X status = writeSsidRid(ai, &mySsid);
X if ( status != SUCCESS ) return ERROR;
-
+
X /* Grab the initial wep key, we gotta save it for auto_wep */
X rc = readWepKeyRid(ai, &wkr, 1);
X if (rc == SUCCESS) do {
@@ -1667,7 +1701,7 @@
X }
X rc = readWepKeyRid(ai, &wkr, 0);
X } while(lastindex != wkr.kindex);
-
+
X if (auto_wep && !timer_pending(&ai->timer)) {
X ai->timer.expires = RUN_AT(HZ*3);
X add_timer(&ai->timer);
@@ -1675,49 +1709,49 @@
X return SUCCESS;
X }
X
+static u16 lock_issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
+ int rc;
+ long flags;
+
+ spin_lock_irqsave(&ai->main_lock, flags);
+ rc = issuecommand(ai, pCmd, pRsp);
+ spin_unlock_irqrestore(&ai->main_lock, flags);


+ return rc;
+}
+

X static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
X // Im really paranoid about letting it run forever!
- int max_tries = 600000;
- int rc = SUCCESS;
- long flags;
+ int max_tries = 600000;
X
- spin_lock_irqsave(&ai->cmd_lock, flags);
X OUT4500(ai, PARAM0, pCmd->parm0);
X OUT4500(ai, PARAM1, pCmd->parm1);
X OUT4500(ai, PARAM2, pCmd->parm2);
X OUT4500(ai, COMMAND, pCmd->cmd);
X while ( max_tries-- &&
X (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
- if ( IN4500(ai, COMMAND) == pCmd->cmd) {
+ if ( IN4500(ai, COMMAND) == pCmd->cmd) {
X // PC4500 didn't notice command, try again
X OUT4500(ai, COMMAND, pCmd->cmd);
X }
- if (!(max_tries & 255) && !in_interrupt()) {
- set_current_state(TASK_RUNNING);
- schedule();
- }
X }
X if ( max_tries == -1 ) {
- printk( KERN_ERR
+ printk( KERN_ERR
X "airo: Max tries exceeded when issueing command\n" );
- rc = ERROR;
- goto done;
+ return ERROR;
X }
X // command completed
X pRsp->status = IN4500(ai, STATUS);
X pRsp->rsp0 = IN4500(ai, RESP0);
X pRsp->rsp1 = IN4500(ai, RESP1);
X pRsp->rsp2 = IN4500(ai, RESP2);
-
+
X // clear stuck command busy if necessary
X if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
X OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
X }
X // acknowledge processing the status/response
X OUT4500(ai, EVACK, EV_CMD);
- done:
- spin_unlock_irqrestore(&ai->cmd_lock, flags);
- return rc;
+ return SUCCESS;
X }
X
X /* Sets up the bap to start exchange data. whichbap should
@@ -1727,7 +1761,7 @@
X {
X int timeout = 50;
X int max_tries = 3;
-
+
X OUT4500(ai, SELECT0+whichbap, rid);
X OUT4500(ai, OFFSET0+whichbap, offset);
X while (1) {
@@ -1735,19 +1769,19 @@
X if (status & BAP_BUSY) {
X /* This isn't really a timeout, but its kinda
X close */
- if (timeout--) {
+ if (timeout--) {
X continue;
X }
X } else if ( status & BAP_ERR ) {
X /* invalid rid or offset */
- printk( KERN_ERR "airo: BAP error %x %d\n",
+ printk( KERN_ERR "airo: BAP error %x %d\n",
X status, whichbap );
X return ERROR;
X } else if (status & BAP_DONE) { // success
X return SUCCESS;
X }
X if ( !(max_tries--) ) {
- printk( KERN_ERR
+ printk( KERN_ERR
X "airo: BAP setup error too many retries\n" );
X return ERROR;
X }
@@ -1776,7 +1810,7 @@
X
X /* requires call to bap_setup() first */
X static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
- int bytelen, int whichbap)
+ int bytelen, int whichbap)
X {
X u16 len;
X u16 page;
@@ -1795,11 +1829,11 @@
X for (i=0; i<words;) {
X int count;
X count = (len>>1) < (words-i) ? (len>>1) : (words-i);
- if ( !do8bitIO )
- insw( ai->dev->base_addr+DATA0+whichbap,
+ if ( !do8bitIO )
+ insw( ai->dev->base_addr+DATA0+whichbap,
X pu16Dst+i,count );
X else
- insb( ai->dev->base_addr+DATA0+whichbap,
+ insb( ai->dev->base_addr+DATA0+whichbap,
X pu16Dst+i, count << 1 );
X i += count;
X if (i<words) {
@@ -1812,11 +1846,11 @@
X
X
X /* requires call to bap_setup() first */
-static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
+static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
X int bytelen, int whichbap)
X {
X bytelen = (bytelen + 1) & (~1); // round up to even value
- if ( !do8bitIO )
+ if ( !do8bitIO )
X insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
X else
X insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
@@ -1824,12 +1858,12 @@
X }
X
X /* requires call to bap_setup() first */
-static int bap_write(struct airo_info *ai, const u16 *pu16Src,
+static int bap_write(struct airo_info *ai, const u16 *pu16Src,
X int bytelen, int whichbap)
X {
X bytelen = (bytelen + 1) & (~1); // round up to even value
- if ( !do8bitIO )
- outsw( ai->dev->base_addr+DATA0+whichbap,
+ if ( !do8bitIO )
+ outsw( ai->dev->base_addr+DATA0+whichbap,
X pu16Src, bytelen>>1 );
X else
X outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
@@ -1861,7 +1895,7 @@
X long flags;
X int rc = SUCCESS;
X
- spin_lock_irqsave(&ai->bap1_lock, flags);
+ spin_lock_irqsave(&ai->main_lock, flags);
X if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
X rc = status;
X goto done;
@@ -1873,10 +1907,10 @@
X // read the rid length field
X bap_read(ai, pBuf, 2, BAP1);
X // length for remaining part of rid
- len = min_t(unsigned int, len, le16_to_cpu(*(u16*)pBuf)) - 2;
-
+ len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
+
X if ( len <= 2 ) {
- printk( KERN_ERR
+ printk( KERN_ERR
X "airo: Rid %x has a length of %d which is too short\n",
X (int)rid,
X (int)len );
@@ -1884,26 +1918,22 @@
X goto done;
X }
X // read remainder of the rid
- if (bap_setup(ai, rid, 2, BAP1) != SUCCESS) {
- rc = ERROR;
- goto done;
- }
X rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
X done:
- spin_unlock_irqrestore(&ai->bap1_lock, flags);
+ spin_unlock_irqrestore(&ai->main_lock, flags);


X return rc;
X }
X

X /* Note, that we are using BAP1 which is also used by transmit, so
X * make sure this isnt called when a transmit is happening */
-static int PC4500_writerid(struct airo_info *ai, u16 rid,
+static int PC4500_writerid(struct airo_info *ai, u16 rid,
X const void *pBuf, int len)
X {
X u16 status;
X long flags;
X int rc = SUCCESS;
X
- spin_lock_irqsave(&ai->bap1_lock, flags);
+ spin_lock_irqsave(&ai->main_lock, flags);
X // --- first access so that we can write the rid data
X if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
X rc = status;
@@ -1918,7 +1948,7 @@
X // ---now commit the rid data
X rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
X done:
- spin_unlock_irqrestore(&ai->bap1_lock, flags);
+ spin_unlock_irqrestore(&ai->main_lock, flags);


X return rc;
X }
X

@@ -1934,7 +1964,7 @@
X
X cmd.cmd = CMD_ALLOCATETX;
X cmd.parm0 = lenPayload;
- if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return 0;
+ if (lock_issuecommand(ai, &cmd, &rsp) != SUCCESS) return 0;
X if ( (rsp.status & 0xFF00) != 0) return 0;
X /* wait for the allocate event/indication
X * It makes me kind of nervous that this can just sit here and spin,
@@ -1943,7 +1973,7 @@
X // get the allocated fid and acknowledge
X txFid = IN4500(ai, TXALLOCFID);
X OUT4500(ai, EVACK, EV_ALLOC);
-
+
X /* The CARD is pretty cool since it converts the ethernet packet
X * into 802.11. Also note that we don't release the FID since we
X * will be using the same one over and over again. */
@@ -1951,13 +1981,13 @@
X * releasing the fid. */
X txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
X | TXCTL_ETHERNET | TXCTL_NORELEASE);
- spin_lock_irqsave(&ai->bap1_lock, flags);
+ spin_lock_irqsave(&ai->main_lock, flags);
X if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS) {
- spin_unlock_irqrestore(&ai->bap1_lock, flags);
+ spin_unlock_irqrestore(&ai->main_lock, flags);
X return ERROR;
X }
X bap_write(ai, &txControl, sizeof(txControl), BAP1);
- spin_unlock_irqrestore(&ai->bap1_lock, flags);
+ spin_unlock_irqrestore(&ai->main_lock, flags);
X
X return txFid;
X }
@@ -1965,18 +1995,18 @@
X /* In general BAP1 is dedicated to transmiting packets. However,
X since we need a BAP when accessing RIDs, we also use BAP1 for that.
X Make sure the BAP1 spinlock is held when this is called. */
-static int transmit_802_3_packet(struct airo_info *ai, u16 txFid,
+static int transmit_802_3_packet(struct airo_info *ai, u16 txFid,
X char *pPacket, int len)
X {
X u16 payloadLen;


X Cmd cmd;
X Resp rsp;
-
+

X if (len < 12) {
X printk( KERN_WARNING "Short packet %d\n", len );
X return ERROR;
X }
-
+
X // packet is destination[6], source[6], payload[len-12]
X // write the payload length and dst/src/payload
X if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
@@ -2106,7 +2136,7 @@
X entry->gid = proc_gid;
X entry->data = dev;
X SETPROC_OPS(entry, proc_statsdelta_ops);
-
+
X /* Setup the Stats */
X entry = create_proc_entry("Stats",
X S_IFREG | (S_IRUGO&proc_perm),
@@ -2115,7 +2145,7 @@
X entry->gid = proc_gid;
X entry->data = dev;
X SETPROC_OPS(entry, proc_stats_ops);
-
+
X /* Setup the Status */
X entry = create_proc_entry("Status",
X S_IFREG | (S_IRUGO&proc_perm),
@@ -2124,7 +2154,7 @@
X entry->gid = proc_gid;
X entry->data = dev;
X SETPROC_OPS(entry, proc_status_ops);
-
+
X /* Setup the Config */
X entry = create_proc_entry("Config",
X S_IFREG | proc_perm,
@@ -2208,9 +2238,9 @@
X int i;
X int pos;
X struct proc_data *priv = (struct proc_data*)file->private_data;
-
+
X if( !priv->rbuffer ) return -EINVAL;
-
+
X pos = *offset;
X for( i = 0; i+pos < priv->readlen && i < len; i++ ) {
X if (put_user( priv->rbuffer[i+pos], buffer+i ))
@@ -2227,18 +2257,18 @@
X static ssize_t proc_write( struct file *file,
X const char *buffer,
X size_t len,
- loff_t *offset )
+ loff_t *offset )
X {
X int i;
X int pos;
X struct proc_data *priv = (struct proc_data*)file->private_data;
-
+
X if ( !priv->wbuffer ) {


X return -EINVAL;
X }
-

+
X pos = *offset;
-
+
X for( i = 0; i + pos < priv->maxwritelen &&
X i < len; i++ ) {
X if (get_user( priv->wbuffer[i+pos], buffer + i ))
@@ -2257,11 +2287,11 @@
X CapabilityRid cap_rid;
X StatusRid status_rid;
X int i;
-
+
X MOD_INC_USE_COUNT;
-
+
X dp = inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2270,10 +2300,10 @@
X kfree (file->private_data);


X return -ENOMEM;
X }
-

+
X readStatusRid(apriv, &status_rid);
X readCapabilityRid(apriv, &cap_rid);
-
+
X i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
X status_rid.mode & 1 ? "CFG ": "",
X status_rid.mode & 2 ? "ACT ": "",
@@ -2319,7 +2349,7 @@
X }
X
X static int proc_stats_rid_open(struct inode*, struct file*, u16);
-static int proc_statsdelta_open( struct inode *inode,
+static int proc_statsdelta_open( struct inode *inode,
X struct file *file ) {
X if (file->f_mode&FMODE_WRITE) {
X return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
@@ -2331,7 +2361,7 @@
X return proc_stats_rid_open(inode, file, RID_STATS);
X }
X
-static int proc_stats_rid_open( struct inode *inode,
+static int proc_stats_rid_open( struct inode *inode,
X struct file *file,
X u16 rid ) {
X struct proc_data *data;
@@ -2342,10 +2372,10 @@
X int i, j;
X int *vals = stats.vals;
X MOD_INC_USE_COUNT;
-
-
+
+
X dp = inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2354,11 +2384,11 @@
X kfree (file->private_data);


X return -ENOMEM;
X }
-

+
X readStatsRid(apriv, &stats, rid);
-
+
X j = 0;
- for(i=0; (int)statsLabels[i]!=-1 &&
+ for(i=0; (int)statsLabels[i]!=-1 &&
X i*4<stats.len; i++){
X if (!statsLabels[i]) continue;
X if (j+strlen(statsLabels[i])+16>4096) {
@@ -2411,10 +2441,10 @@
X Resp rsp;
X char *line;
X int need_reset = 0;
-
+
X if ( !data->writelen ) return;
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X disable_MAC(ai);
X readConfigRid(ai, &config);
X
@@ -2442,7 +2472,7 @@
X need_reset = 1;
X }
X }
-
+
X /*** Radio status */
X else if (!strncmp(line,"Radio: ", 7)) {
X line += 7;
@@ -2455,15 +2485,15 @@
X /*** NodeName processing */
X else if ( !strncmp( line, "NodeName: ", 10 ) ) {
X int j;
-
+
X line += 10;
X memset( config.nodeName, 0, 16 );
X /* Do the name, assume a space between the mode and node name */
X for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
X config.nodeName[j] = line[j];
X }
- }
-
+ }
+
X /*** PowerMode processing */
X else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
X line += 11;
@@ -2473,11 +2503,11 @@
X config.powerSaveMode = POWERSAVE_PSP;
X } else {
X config.powerSaveMode = POWERSAVE_CAM;
- }
+ }
X } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
- int v, i = 0, k = 0; /* i is index into line,
+ int v, i = 0, k = 0; /* i is index into line,
X k is index to rates */
-
+
X line += 11;
X while((v = get_dec_u16(line, &i, 3))!=-1) {
X config.rates[k++] = (u8)v;
@@ -2488,7 +2518,7 @@
X int v, i = 0;
X line += 9;
X v = get_dec_u16(line, &i, i+3);
- if ( v != -1 )
+ if ( v != -1 )
X config.channelSet = (u16)v;
X } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
X int v, i = 0;
@@ -2510,50 +2540,50 @@
X }
X } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
X int v, i = 0;
-
+
X line += 16;
X v = get_dec_u16(line, &i, 3);
X v = (v<0) ? 0 : ((v>255) ? 255 : v);
X config.longRetryLimit = (u16)v;
X } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
X int v, i = 0;
-
+
X line += 17;
X v = get_dec_u16(line, &i, 3);
X v = (v<0) ? 0 : ((v>255) ? 255 : v);
X config.shortRetryLimit = (u16)v;
X } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
X int v, i = 0;
-
+
X line += 14;
X v = get_dec_u16(line, &i, 4);
X v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
X config.rtsThres = (u16)v;
X } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
X int v, i = 0;
-
+
X line += 16;
X v = get_dec_u16(line, &i, 5);
X v = (v<0) ? 0 : v;
X config.txLifetime = (u16)v;
X } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
X int v, i = 0;
-
+
X line += 16;
X v = get_dec_u16(line, &i, 5);
X v = (v<0) ? 0 : v;
X config.rxLifetime = (u16)v;
X } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
- config.txDiversity =
+ config.txDiversity =
X (line[13]=='l') ? 1 :
X ((line[13]=='r')? 2: 3);
X } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
- config.rxDiversity =
+ config.rxDiversity =
X (line[13]=='l') ? 1 :
X ((line[13]=='r')? 2: 3);
X } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
X int v, i = 0;
-
+
X line += 15;
X v = get_dec_u16(line, &i, 4);
X v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
@@ -2605,11 +2635,11 @@


X struct airo_info *ai = (struct airo_info*)dev->priv;

X ConfigRid config;
X int i;
-
+
X MOD_INC_USE_COUNT;
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2626,10 +2656,10 @@
X memset( data->wbuffer, 0, 2048 );
X data->maxwritelen = 2048;
X data->on_close = proc_config_on_close;
-
+
X readConfigRid(ai, &config);
-
- i = sprintf( data->rbuffer,
+
+ i = sprintf( data->rbuffer,
X "Mode: %s\n"
X "Radio: %s\n"
X "NodeName: %-16s\n"
@@ -2637,9 +2667,9 @@
X "DataRates: %d %d %d %d %d %d %d %d\n"
X "Channel: %d\n"
X "XmitPower: %d\n",
- config.opmode == 0 ? "adhoc" :
+ config.opmode == 0 ? "adhoc" :
X config.opmode == 1 ? "ESS" :
- config.opmode == 2 ? "AP" :
+ config.opmode == 2 ? "AP" :
X config.opmode == 3 ? "AP RPTR" : "Error",
X ai->flags&FLAG_RADIO_OFF ? "off" : "on",
X config.nodeName,
@@ -2700,11 +2730,11 @@
X SsidRid SSID_rid;
X int i;
X int offset = 0;
-
+
X if ( !data->writelen ) return;
-
+
X memset( &SSID_rid, 0, sizeof( SSID_rid ) );
-
+
X for( i = 0; i < 3; i++ ) {
X int j;
X for( j = 0; j+offset < data->writelen && j < 32 &&
@@ -2714,7 +2744,7 @@
X if ( j == 0 ) break;
X SSID_rid.ssids[i].len = j;
X offset += j;
- while( data->wbuffer[offset] != '\n' &&
+ while( data->wbuffer[offset] != '\n' &&
X offset < data->writelen ) offset++;
X offset++;
X }
@@ -2735,12 +2765,12 @@


X struct airo_info *ai = (struct airo_info*)dev->priv;

X APListRid APList_rid;
X int i;
-
+
X if ( !data->writelen ) return;
-
+
X memset( &APList_rid, 0, sizeof(APList_rid) );
X APList_rid.len = sizeof(APList_rid);
-
+
X for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
X int j;
X for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
@@ -2764,7 +2794,7 @@
X int len ) {
X int rc;


X Resp rsp;
-
+

X disable_MAC(ai);
X rc = PC4500_writerid(ai, rid, rid_data, len);
X enable_MAC(ai, &rsp);
@@ -2816,7 +2846,7 @@
X memcpy( wkr.mac, macaddr, 6 );
X printk(KERN_INFO "Setting key %d\n", index);
X }
-
+
X writeWepKeyRid(ai, &wkr, perm);
X return 0;
X }
@@ -2832,11 +2862,11 @@
X int j = 0;
X
X memset(key, 0, sizeof(key));
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
X data = (struct proc_data *)file->private_data;
X if ( !data->writelen ) return;
-
+
X if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
X (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
X index = data->wbuffer[0] - '0';
@@ -2873,11 +2903,11 @@
X u16 lastindex;
X int j=0;
X int rc;
-
+
X MOD_INC_USE_COUNT;
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2897,7 +2927,7 @@
X }
X memset( data->wbuffer, 0, 80 );
X data->on_close = proc_wepkey_on_close;
-
+
X ptr = data->rbuffer;
X strcpy(ptr, "No wep keys\n");
X rc = readWepKeyRid(ai, &wkr, 1);
@@ -2927,9 +2957,9 @@
X SsidRid SSID_rid;
X
X MOD_INC_USE_COUNT;
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2947,16 +2977,16 @@
X }
X memset( data->wbuffer, 0, 33*3 );
X data->on_close = proc_SSID_on_close;
-
+
X readSsidRid(ai, &SSID_rid);
X ptr = data->rbuffer;
X for( i = 0; i < 3; i++ ) {
X int j;
X if ( !SSID_rid.ssids[i].len ) break;
- for( j = 0; j < 32 &&
- j < SSID_rid.ssids[i].len &&
+ for( j = 0; j < 32 &&
+ j < SSID_rid.ssids[i].len &&
X SSID_rid.ssids[i].ssid[j]; j++ ) {
- *ptr++ = SSID_rid.ssids[i].ssid[j];
+ *ptr++ = SSID_rid.ssids[i].ssid[j];
X }
X *ptr++ = '\n';
X }
@@ -2975,9 +3005,9 @@
X APListRid APList_rid;
X
X MOD_INC_USE_COUNT;
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2995,7 +3025,7 @@
X }
X memset( data->wbuffer, 0, data->maxwritelen );
X data->on_close = proc_APList_on_close;
-
+
X readAPListRid(ai, &APList_rid);
X ptr = data->rbuffer;
X for( i = 0; i < 4; i++ ) {
@@ -3027,11 +3057,11 @@
X int rc;
X /* If doLoseSync is not 1, we won't do a Lose Sync */
X int doLoseSync = -1;
-
+
X MOD_INC_USE_COUNT;
-
+
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
+
X if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
X return -ENOMEM;
X memset(file->private_data, 0, sizeof(struct proc_data));
@@ -3044,15 +3074,15 @@
X data->maxwritelen = 0;
X data->wbuffer = 0;
X data->on_close = 0;
-
+
X if (file->f_mode & FMODE_WRITE) {
X if (!(file->f_mode & FMODE_READ)) {


X Cmd cmd;
X Resp rsp;
-
+

X memset(&cmd, 0, sizeof(cmd));
X cmd.cmd=CMD_LISTBSS;
- issuecommand(ai, &cmd, &rsp);
+ lock_issuecommand(ai, &cmd, &rsp);

X data->readlen = 0;
X return 0;
X }
@@ -3087,7 +3117,7 @@


X return 0;
X }
X

-static int proc_close( struct inode *inode, struct file *file )
+static int proc_close( struct inode *inode, struct file *file )
X {
X struct proc_data *data = (struct proc_data *)file->private_data;
X if ( data->on_close != NULL ) data->on_close( inode, file );
@@ -3112,7 +3142,7 @@
X struct net_device *dev = (struct net_device*)data;


X struct airo_info *apriv = (struct airo_info *)dev->priv;

X u16 linkstat = IN4500(apriv, LINKSTAT);
-
+
X if (linkstat != 0x400 ) {
X /* We don't have a link so try changing the authtype */
X ConfigRid config = apriv->config;
@@ -3158,13 +3188,13 @@
X if ( auto_wep ) {
X struct airo_info *apriv=dev->priv;
X struct timer_list *timer = &apriv->timer;
-
+
X timer->function = timer_func;
X timer->data = (u_long)dev;
X init_timer(timer);
X apriv->authtype = AUTH_SHAREDKEY;
X }
-
+
X node->dev = dev;
X node->next = airo_devices;
X airo_devices = node;
@@ -3177,14 +3207,14 @@
X while( *p && ( (*p)->dev != dev ) )
X p = &(*p)->next;
X if ( *p && (*p)->dev == dev )
- *p = (*p)->next;
+ *p = (*p)->next;
X }
X
X #ifdef CONFIG_PCI
-static int __devinit airo_pci_probe(struct pci_dev *pdev,
+static int __devinit airo_pci_probe(struct pci_dev *pdev,
X const struct pci_device_id *pent)
X {
- pdev->driver_data = init_airo_card(pdev->irq,
+ pdev->driver_data = init_airo_card(pdev->irq,
X pdev->resource[2].start, 0);
X if (!pdev->driver_data) {
X return -ENODEV;
@@ -3201,21 +3231,21 @@
X static int __init airo_init_module( void )
X {
X int i, rc = 0, have_isa_dev = 0;
-
+
X airo_entry = create_proc_entry("aironet",
X S_IFDIR | airo_perm,
X proc_root_driver);
X airo_entry->uid = proc_uid;
X airo_entry->gid = proc_gid;
-
+
X for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
- printk( KERN_INFO
+ printk( KERN_INFO
X "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n",
X irq[i], io[i] );
X if (init_airo_card( irq[i], io[i], 0 ))
X have_isa_dev = 1;
X }
-
+
X #ifdef CONFIG_PCI
X printk( KERN_INFO "airo: Probing for PCI adapters\n" );
X rc = pci_module_init(&airo_driver);
@@ -3274,7 +3304,11 @@
X StatusRid status_rid; /* Card status info */
X
X #ifdef CISCO_EXT
- if (cmd != SIOCGIWPRIV && cmd != AIROIOCTL && cmd != AIROIDIFC)
+ if (cmd != SIOCGIWPRIV && cmd != AIROIOCTL && cmd != AIROIDIFC
+#ifdef AIROOLDIOCTL
+ && cmd != AIROOLDIOCTL && cmd != AIROOLDIDIFC
+#endif
+ )
X #endif /* CISCO_EXT */
X {
X /* If the command read some stuff, we better get it out of
@@ -3851,7 +3885,7 @@
X
X /* Hum... Should put the right values there */
X range.max_qual.qual = 10;
- range.max_qual.level = 0;
+ range.max_qual.level = 0x100 - 120; /* -120 dBm */
X range.max_qual.noise = 0;
X range.sensitivity = 65535;
X
@@ -3908,7 +3942,7 @@
X range.txpower_capa = IW_TXPOW_MWATT;
X #endif /* WIRELESS_EXT > 9 */
X #if WIRELESS_EXT > 10
- range.we_version_source = 11;
+ range.we_version_source = 12;
X range.we_version_compiled = WIRELESS_EXT;
X range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
X range.retry_flags = IW_RETRY_LIMIT;
@@ -3918,6 +3952,17 @@
X range.min_r_time = 1024;
X range.max_r_time = 65535 * 1024;
X #endif /* WIRELESS_EXT > 10 */
+#if WIRELESS_EXT > 11
+ /* Experimental measurements - boundary 11/5.5 Mb/s */
+ /* Note : with or without the (local->rssi), results
+ * are somewhat different. - Jean II */
+ range.avg_qual.qual = 6;
+ if (local->rssi)
+ range.avg_qual.level = 186; /* -70 dBm */
+ else
+ range.avg_qual.level = 176; /* -80 dBm */
+ range.avg_qual.noise = 0;


+#endif /* WIRELESS_EXT > 11 */
X

X if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
X rc = -EFAULT;
@@ -3943,7 +3988,7 @@
X }
X break;
X
- case SIOCSIWPOWER:
+ case SIOCSIWPOWER:
X if (wrq->u.power.disabled) {
X if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
X rc = -EINVAL;
@@ -4022,7 +4067,7 @@
X if (BSSList.index == 0xffff) break;
X }
X if (!i) {


- for (i = 0;

+ for (i = 0;

X i < min(IW_MAX_AP, 4) &&
X (status_rid.bssid[i][0]
X & status_rid.bssid[i][1]
@@ -4037,7 +4082,7 @@
X | status_rid.bssid[i][4]
X | status_rid.bssid[i][5]);
X i++) {
- memcpy(s[i].sa_data,
+ memcpy(s[i].sa_data,
X status_rid.bssid[i], 6);
X s[i].sa_family = ARPHRD_ETHER;
X }
@@ -4050,7 +4095,7 @@
X rc = -EFAULT;
X }
X wrq->u.data.length = i;
- if (copy_to_user(wrq->u.data.pointer, &s,
+ if (copy_to_user(wrq->u.data.pointer, &s,
X sizeof(struct sockaddr)*i))
X rc = -EFAULT;
X }
@@ -4134,6 +4179,9 @@
X
X #ifdef CISCO_EXT
X case AIROIDIFC:
+#ifdef AIROOLDIDIFC
+ case AIROOLDIDIFC:
+#endif
X {
X int val = AIROMAGIC;
X aironet_ioctl com;
@@ -4143,9 +4191,12 @@
X rc = -EFAULT;
X }
X break;
-
+
X case AIROIOCTL:
- /* Get the command struct and hand it off for evaluation by
+#ifdef AIROOLDIOCTL
+ case AIROOLDIOCTL:
+#endif
+ /* Get the command struct and hand it off for evaluation by
X * the proper subfunction
X */
X {
@@ -4209,8 +4260,6 @@
X * TODO :
X * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
X * o Find the noise level
- * o Convert values to dBm
- * o Fill out discard.misc with something interesting
X *
X * Jean
X */
@@ -4219,7 +4268,7 @@
X struct airo_info *local = (struct airo_info*) dev->priv;
X StatusRid status_rid;
X StatsRid stats_rid;
- int *vals = stats_rid.vals;


+ u32 *vals = stats_rid.vals;

X
X /* Get stats out of the card */
X readStatusRid(local, &status_rid);
@@ -4241,21 +4290,28 @@
X * specific problems */
X local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
X local->wstats.discard.code = vals[6];/* RxWepErr */
- local->wstats.discard.misc = vals[1] + vals[2] + vals[3] + vals[4] + vals[30] + vals[32];
+#if WIRELESS_EXT > 11
+ local->wstats.discard.fragment = vals[30];
+ local->wstats.discard.retries = vals[10];
+ local->wstats.discard.misc = vals[1] + vals[32];
+ local->wstats.miss.beacon = vals[34];
+#else /* WIRELESS_EXT > 11 */
+ local->wstats.discard.misc = vals[1] + vals[30] + vals[32];


+#endif /* WIRELESS_EXT > 11 */

X return (&local->wstats);
X }


X #endif /* WIRELESS_EXT */
X

X #ifdef CISCO_EXT
X /*
- * This just translates from driver IOCTL codes to the command codes to
- * feed to the radio's host interface. Things can be added/deleted
- * as needed. This represents the READ side of control I/O to
+ * This just translates from driver IOCTL codes to the command codes to
+ * feed to the radio's host interface. Things can be added/deleted
+ * as needed. This represents the READ side of control I/O to
X * the card
X */
X static int readrids(struct net_device *dev, aironet_ioctl *comp) {
X unsigned short ridcode;
- unsigned char iobuf[2048];
+ unsigned char iobuf[2048];
X
X switch(comp->command)
X {
@@ -4279,18 +4335,18 @@
X case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
X case AIROGSTATSC32: ridcode = RID_STATS; break;
X default:
- return -EINVAL;
+ return -EINVAL;
X break;
X }
X
X PC4500_readrid((struct airo_info *)dev->priv,ridcode,iobuf,sizeof(iobuf));
X /* get the count of bytes in the rid docs say 1st 2 bytes is it.
- * then return it to the user
+ * then return it to the user
X * 9/22/2000 Honor user given length
X */
X
X if (copy_to_user(comp->data, iobuf,
- min_t(unsigned int, comp->len, sizeof(iobuf))))
+ min((int)comp->len, (int)sizeof(iobuf))))
X return -EFAULT;
X return 0;
X }
@@ -4303,7 +4359,7 @@
X int ridcode;
X Resp rsp;
X static int (* writer)(struct airo_info *, u16 rid, const void *, int);
- unsigned char iobuf[2048];
+ unsigned char iobuf[2048];
X
X /* Only super-user can write RIDs */
X if (!capable(CAP_NET_ADMIN))
@@ -4324,7 +4380,7 @@
X case AIROPWEPKEY: ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
X break;
X
- /* this is not really a rid but a command given to the card
+ /* this is not really a rid but a command given to the card
X * same with MAC off
X */
X case AIROPMACON:
@@ -4332,7 +4388,7 @@
X return -EIO;
X return 0;
X
- /*
+ /*
X * Evidently this code in the airo driver does not get a symbol
X * as disable_MAC. it's probably so short the compiler does not gen one.
X */
@@ -4350,7 +4406,7 @@
X PC4500_readrid(dev->priv,ridcode,iobuf,sizeof(iobuf));
X
X if (copy_to_user(comp->data, iobuf,
- min_t(unsigned int, comp->len, sizeof(iobuf))))
+ min((int)comp->len, (int)sizeof(iobuf))))
X return -EFAULT;
X return 0;
X
@@ -4372,7 +4428,7 @@
X *****************************************************************************
X */
X
-/*
+/*
X * Flash command switch table
X */
X
@@ -4435,10 +4491,10 @@
X
X #define FLASH_COMMAND 0x7e7e
X
-/*
+/*
X * STEP 1)
- * Disable MAC and do soft reset on
- * card.
+ * Disable MAC and do soft reset on
+ * card.
X */
X
X int cmdreset(struct airo_info *ai) {
@@ -4448,7 +4504,7 @@
X printk(KERN_INFO "Waitbusy hang before RESET\n");
X return -EBUSY;
X }
-
+
X OUT4500(ai,COMMAND,CMD_SOFTRESET);
X
X set_current_state (TASK_UNINTERRUPTIBLE);
@@ -4462,7 +4518,7 @@
X }
X
X /* STEP 2)
- * Put the card in legendary flash
+ * Put the card in legendary flash
X * mode
X */
X
@@ -4473,7 +4529,7 @@
X OUT4500(ai, COMMAND,0x10);
X set_current_state (TASK_UNINTERRUPTIBLE);
X schedule_timeout (HZ/2); /* 500ms delay */
-
+
X if(!waitbusy(ai)) {
X printk(KERN_INFO "Waitbusy hang after setflash mode\n");
X return -EIO;
@@ -4481,8 +4537,8 @@


X return 0;
X }
X

-/* Put character to SWS0 wait for dwelltime
- * x 50us for echo .
+/* Put character to SWS0 wait for dwelltime
+ * x 50us for echo .
X */
X
X int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
@@ -4493,7 +4549,7 @@
X
X if(dwelltime == 0 )
X dwelltime = 200;
-
+
X waittime=dwelltime;
X
X /* Wait for busy bit d15 to go false indicating buffer empty */
@@ -4531,7 +4587,7 @@
X
X do {
X rchar = IN4500(ai,SWS1);
-
+
X if(dwelltime && !(0x8000 & rchar)){
X dwelltime -= 10;
X mdelay(10);
@@ -4551,9 +4607,9 @@


X return -EIO;
X }
X
-/*

- * Transfer 32k of firmware data from user buffer to our buffer and
- * send to the card
+/*
+ * Transfer 32k of firmware data from user buffer to our buffer and
+ * send to the card
X */
X
X int flashputbuf(struct airo_info *ai){
@@ -4566,7 +4622,7 @@
X for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
X OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
X }
-
+
X OUT4500(ai,SWS0,0x8000);
X
X return 0;
@@ -4628,7 +4684,7 @@
X HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
X STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
X IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
+ POSSIBILITY OF SUCH DAMAGE.
X */
X
X module_init(airo_init_module);
diff -u --recursive --new-file v2.4.12/linux/drivers/net/wireless/airport.c linux/drivers/net/wireless/airport.c
--- v2.4.12/linux/drivers/net/wireless/airport.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/airport.c Wed Oct 17 14:37:01 2001
@@ -43,6 +43,7 @@
X MODULE_AUTHOR("Benjamin Herrenschmidt <be...@kernel.crashing.org>");
X MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
X MODULE_LICENSE("Dual MPL/GPL");
+EXPORT_NO_SYMBOLS;
X
X typedef struct dldwd_card {
X struct device_node* node;
diff -u --recursive --new-file v2.4.12/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- v2.4.12/linux/drivers/net/yellowfin.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/yellowfin.c Fri Oct 19 08:32:28 2001
@@ -38,10 +38,13 @@
X * Fix three endian-ness bugs
X * Support dual function SYM53C885E ethernet chip
X
+ LK1.1.5 (v...@nmt.edu):
+ * Fix forced full-duplex bug I introduced
+
X */
X
X #define DRV_NAME "yellowfin"
-#define DRV_VERSION "1.05+LK1.1.3"
+#define DRV_VERSION "1.05+LK1.1.5"
X #define DRV_RELDATE "May 10, 2001"
X
X #define PFX DRV_NAME ": "
@@ -256,7 +259,7 @@
X };
X enum capability_flags {
X HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16,
- HasMACAddrBug=32, /* Only on early revs. */
+ HasMACAddrBug=32, DontUseEeprom=64, /* Only on early revs. */
X };
X /* The PCI I/O space extent. */
X #define YELLOWFIN_SIZE 0x100
@@ -282,7 +285,7 @@
X PCI_IOTYPE, YELLOWFIN_SIZE,
X FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug},
X {"Symbios SYM83C885", { 0x07011000, 0xffffffff},
- PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | IsGigabit | FullTxStatus },
+ PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom },
X {0,},
X };
X
@@ -453,7 +456,7 @@
X #endif
X irq = pdev->irq;
X
- if (drv_flags & IsGigabit)
+ if (drv_flags & DontUseEeprom)
X for (i = 0; i < 6; i++)
X dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
X else {
diff -u --recursive --new-file v2.4.12/linux/drivers/nubus/nubus_syms.c linux/drivers/nubus/nubus_syms.c
--- v2.4.12/linux/drivers/nubus/nubus_syms.c Sat Sep 4 13:08:32 1999
+++ linux/drivers/nubus/nubus_syms.c Thu Oct 11 09:18:31 2001
@@ -12,6 +12,8 @@
X EXPORT_SYMBOL(nubus_proc_detach_device);
X #endif
X
+MODULE_LICENSE("GPL");
+
X EXPORT_SYMBOL(nubus_find_device);
X EXPORT_SYMBOL(nubus_find_type);
X EXPORT_SYMBOL(nubus_find_slot);
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c
--- v2.4.12/linux/drivers/parport/ieee1284_ops.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/parport/ieee1284_ops.c Thu Oct 11 07:53:24 2001
@@ -362,7 +362,7 @@
X } else {
X DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n",
X port->name);
- port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+ port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
X }
X
X return retval;
@@ -394,7 +394,7 @@
X DPRINTK (KERN_DEBUG
X "%s: ECP direction: failed to switch forward\n",
X port->name);
- port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
+ port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
X }
X
X
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_amiga.c linux/drivers/parport/parport_amiga.c
--- v2.4.12/linux/drivers/parport/parport_amiga.c Tue May 22 19:54:04 2001
+++ linux/drivers/parport/parport_amiga.c Thu Oct 11 09:18:31 2001
@@ -298,6 +298,7 @@
X MODULE_AUTHOR("Joerg Dorchain <jo...@dorchain.net>");
X MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
X MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
+MODULE_LICENSE("GPL");
X
X module_init(parport_amiga_init)
X module_exit(parport_amiga_exit)
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_atari.c linux/drivers/parport/parport_atari.c
--- v2.4.12/linux/drivers/parport/parport_atari.c Mon Nov 27 17:11:26 2000
+++ linux/drivers/parport/parport_atari.c Thu Oct 11 09:18:31 2001
@@ -249,6 +249,7 @@
X MODULE_AUTHOR("Andreas Schwab");
X MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
X MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port");


+MODULE_LICENSE("GPL");
X
X int

X init_module(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.12/linux/drivers/parport/parport_pc.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/parport/parport_pc.c Thu Oct 11 09:18:31 2001
@@ -2884,6 +2884,8 @@
X
X MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
X MODULE_DESCRIPTION("PC-style parallel port driver");
+MODULE_LICENSE("GPL");
+
X MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
X MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i");
X MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
diff -u --recursive --new-file v2.4.12/linux/drivers/pci/gen-devlist.c linux/drivers/pci/gen-devlist.c
--- v2.4.12/linux/drivers/pci/gen-devlist.c Mon Oct 16 12:56:50 2000
+++ linux/drivers/pci/gen-devlist.c Thu Oct 11 09:18:31 2001
@@ -68,6 +68,7 @@
X bra[-1] = 0;
X if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
X fprintf(stderr, "Line %d: Device name too long\n", lino);
+ fprintf(stderr, "%s\n", c);
X return 1;
X }
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.4.12/linux/drivers/pci/pci.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/pci/pci.c Fri Oct 12 15:35:53 2001
@@ -834,17 +834,27 @@
X }
X
X int
-pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
+pci_set_dma_mask(struct pci_dev *dev, u64 mask)
X {
- if(! pci_dma_supported(dev, mask))
- return -EIO;
+ if (!pci_dma_supported(dev, mask))
+ return -EIO;
X
- dev->dma_mask = mask;
+ dev->dma_mask = mask;
X
- return 0;


+ return 0;
X }
X

+int
+pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ if (!pci_dac_dma_supported(dev, mask))
+ return -EIO;
+
+ dev->dma_mask = mask;
X

+ return 0;
+}
+

X /*
X * Translate the low bits of the PCI base
X * to the resource type
@@ -1678,7 +1688,8 @@
X if (!page)
X return 0;
X page->vaddr = pci_alloc_consistent (pool->dev,
- pool->allocation, &page->dma);
+ pool->allocation,
+ &page->dma);
X if (page->vaddr) {
X memset (page->bitmap, 0xff, mapsize); // bit set == free
X if (pool->flags & SLAB_POISON)
@@ -1864,14 +1875,14 @@
X if ((page = pool_find_page (pool, dma)) == 0) {
X printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
X pool->dev ? pool->dev->slot_name : NULL,
- pool->name, vaddr, dma);
+ pool->name, vaddr, (int) (dma & 0xffffffff));
X return;
X }
X #ifdef CONFIG_PCIPOOL_DEBUG
X if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
X printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
X pool->dev ? pool->dev->slot_name : NULL,
- pool->name, vaddr, dma);
+ pool->name, vaddr, (int) (dma & 0xffffffff));
X return;
X }
X #endif
@@ -1956,6 +1967,7 @@
X EXPORT_SYMBOL(pci_find_subsys);
X EXPORT_SYMBOL(pci_set_master);
X EXPORT_SYMBOL(pci_set_dma_mask);
+EXPORT_SYMBOL(pci_dac_set_dma_mask);
X EXPORT_SYMBOL(pci_assign_resource);
X EXPORT_SYMBOL(pci_register_driver);
X EXPORT_SYMBOL(pci_unregister_driver);
diff -u --recursive --new-file v2.4.12/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.12/linux/drivers/pci/pci.ids Tue Oct 9 17:06:52 2001
+++ linux/drivers/pci/pci.ids Fri Oct 19 08:32:28 2001
@@ -106,9 +106,16 @@
X 0012 53c895a
X 0020 53c1010 Ultra3 SCSI Adapter
X 0021 53c1010 66MHz Ultra3 SCSI Adapter
+ 0030 53c1030
+ 0040 53c1035
X 008f 53c875J
X 1092 8000 FirePort 40 SCSI Controller
X 1092 8760 FirePort 40 Dual SCSI Host Adapter
+ 0621 FC909
+ 0622 FC929
+ 0623 FC929 LAN
+ 0624 FC919
+ 0625 FC919 LAN
X 0701 83C885
X 0702 Yellowfin G-NIC gigabit ethernet
X 1318 0000 PEI100X
@@ -2085,6 +2092,7 @@
X 110a Siemens Nixdorf AG
X 0002 Pirahna 2-port
X 0005 Tulip controller, power management, switch extender
+ 2102 DSCC4 WAN adapter
X 4942 FPGA I-Bus Tracer for MBD
X 6120 SZB6120
X 110b Chromatic Research Inc.
@@ -2310,7 +2318,7 @@
X 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64)
X 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64)
X 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
- 4200 Token ring adaptor
+ 4200 Token Ring adapter
X 4300 Gigabit Ethernet
X 1148 9821 SK-9821 (1000Base-T single link)
X 1148 9822 SK-9822 (1000Base-T dual link)
@@ -3107,34 +3115,104 @@
X 0396 SDRAM controller
X 0397 BIOS scratchpad
X 127a Rockwell International
- 1002 HCF 56k V90 FaxModem
- 127a 1002 HCF 56k V90 Modem
- 1003 HCF 56k V90 FaxModem
- 127a 1003 PCI56RX Modem
- 13df 1003 PCI56RX Modem
- 1004 HCF 56k V90 FaxModem
- 1005 HCF 56k V90 FaxModem
- 122d 4008 MDP3858SP-A SVD Modem
- 127a 1005 PCI56RVP Modem
- 13df 1005 PCI56RVP Modem
- 1436 1005 WS-5614PS3G
- 1025 HCF 56k PCI Modem
- 127a 1025 HCF 56k PCI Modem
+ 1002 HCF 56k Data/Fax Modem
+ 122d 4002 HPG / MDP3858-U # Aztech
+ 122d 4005 MDP3858-E # Aztech
+ 122d 4007 MDP3858-A/-NZ # Aztech
+ 122d 4012 MDP3858-SA # Aztech
+ 122d 4017 MDP3858-W # Aztech
+ 122d 4018 MDP3858-W # Aztech
+ 1003 HCF 56k Data/Fax Modem
+ 0e11 b0bc 229-DF Zephyr # Compaq
+ 0e11 b114 229-DF Cheetah # Compaq
+ 1033 802b 229-DF # NEC
+ 13df 1003 PCI56RX Modem # E-Tech Inc
+ 13e0 0117 IBM # GVC
+ 13e0 0147 IBM # GVC
+ 13e0 0197 IBM # GVC
+ 13e0 01c7 IBM # GVC
+ 13e0 01f7 IBM # GVC
+ 1436 1003 IBM # CIS
+ 1436 1103 IBM # CIS
+ 1436 1602 Compaq 229-DF Ducati
+ 1004 HCF 56k Data/Fax/Voice Modem
+ 10cf 1059 Fujitsu 229-DFRT
+ 1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1033 8029 229-DFSV # NEC
+ 1033 8054 Modem # NEC
+ 10cf 103c Fujitsu
+ 10cf 1055 Fujitsu 229-DFSV
+ 10cf 1056 Fujitsu 229-DFSV
+ 122d 4003 MDP3858SP-U # Aztech
+ 122d 4006 Packard Bell MDP3858V-E # Aztech
+ 122d 4008 MDP3858SP-A/SP-NZ # Aztech
+ 122d 4009 MDP3858SP-E # Aztech
+ 122d 4010 MDP3858V-U # Aztech
+ 122d 4011 MDP3858SP-SA # Aztech
+ 122d 4013 MDP3858V-A/V-NZ # Aztech
+ 122d 4015 MDP3858SP-W # Aztech
+ 122d 4016 MDP3858V-W # Aztech
+ 122d 4019 MDP3858V-SA # Aztech
+ 13df 1005 PCI56RVP Modem # E-Tech Inc
+ 13e0 0187 IBM # GVC
+ 13e0 01a7 IBM # GVC
+ 13e0 01b7 IBM # GVC
+ 13e0 01d7 IBM # GVC
+ 1436 1005 IBM # CIS
+ 1436 1105 IBM # CIS
+ 1023 HCF 56k Data/Fax Modem
+ 122d 4020 Packard Bell MDP3858-WE # Aztech
+ 122d 4023 MDP3858-UE # Aztech
+ 13e0 0247 IBM # GVC
+ 13e0 0297 IBM # GVC
+ 13e0 02c7 IBM # GVC
+ 1436 1203 IBM # CIS
+ 1436 1303 IBM # CIS
+ 1024 HCF 56k Data/Fax/Voice Modem
+ 1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 106a Fujitsu 235-DFSV
+ 122d 4021 Packard Bell MDP3858V-WE # Aztech
+ 122d 4022 MDP3858SP-WE # Aztech
+ 122d 4024 MDP3858V-UE # Aztech
+ 122d 4025 MDP3858SP-UE # Aztech
X 1026 HCF 56k PCI Speakerphone Modem
- 127a 1026 HCF 56k PCI Speakerphone Modem
X 1035 HCF 56k PCI Speakerphone Modem
- 127a 1035 HCF 56k PCI Speakerphone Modem
- 1085 Volcano HCF 56k PCI Modem
- 127a 1085 Volcano HCF 56k PCI Modem
- 2005 HCF 56k V90 FaxModem
- 127a 2005 Conexant SoftK56 Speakerphone Modem
- 2015 Conexant SoftK56 Speakerphone Modem
- 127a 2015 Conexant SoftK56 Speakerphone Modem
- 14c8 2115 Conexant SoftK56 Speakerphone Modem
+ 1085 HCF 56k Volcano PCI Modem
+ 2005 HCF 56k Data/Fax Modem
+ 104d 8044 229-DFSV # Sony
+ 104d 8045 229-DFSV # Sony
+ 104d 8055 PBE/Aztech 235W-DFSV # Sony
+ 104d 8056 235-DFSV # Sony
+ 104d 805a Modem # Sony
+ 104d 805f Modem # Sony
+ 104d 8074 Modem # Sony
+ 2013 HSF 56k Data/Fax Modem
+ 1179 0001 Modem # Toshiba
+ 1179 ff00 Modem # Toshiba
+ 2014 HSF 56k Data/Fax/Voice Modem
+ 10cf 1057 Fujitsu Citicorp III
+ 122d 4050 MSP3880-U # Aztech
+ 122d 4055 MSP3880-W # Aztech
+ 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 1063 Fujitsu
+ 10cf 1064 Fujitsu
+ 1468 2015 Fujitsu
+ 2016 HSF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4051 MSP3880V-W # Aztech
+ 122d 4052 MSP3880SP-W # Aztech
+ 122d 4054 MSP3880V-U # Aztech
+ 122d 4056 MSP3880SP-U # Aztech
+ 122d 4057 MSP3880SP-A # Aztech
+ 4311 Riptide HSF 56k PCI Modem
+ 127a 4311 Ring Modular? Riptide HSF RT HP Dom
+ 13e0 0210 HP-GVC
X 4320 Riptide PCI Audio Controller
X 1235 4320 Riptide PCI Audio Controller
X 4321 Riptide HCF 56k PCI Modem
- 1235 4321 Riptide HCF 56k PCI Modem
+ 1235 4321 Hewlett Packard DF
+ 1235 4324 Hewlett Packard DF
+ 13e0 0210 Hewlett Packard DF
+ 144d 2321 Riptide # Samsung
X 4322 Riptide PCI Game Controller
X 1235 4322 Riptide PCI Game Controller
X 8234 RapidFire 616X ATM155 Adapter
@@ -3884,6 +3962,7 @@
X 148b INNOMEDIALOGIC Inc.
X 148c C.P. Technology Co. Ltd
X 148d DIGICOM Systems, Inc.
+ 1003 HCF 56k Data/Fax Modem
X 148e OSI Plus Corporation
X 148f Plant Equipment, Inc.
X 1490 Stone Microsystems PTY Ltd.
@@ -4009,6 +4088,7 @@
X 14e4 0007 NetXtreme BCM5701 1000BaseSX
X 14e4 0008 NetXtreme BCM5701 1000BaseTX
X 14e4 8008 NetXtreme BCM5701 1000BaseTX
+ 5820 BCM5820 Crypto Accelerator
X 14e5 Pixelfusion Ltd
X 14e6 SHINING Technology Inc
X 14e7 3CX
@@ -4021,30 +4101,123 @@
X 14ee MASPRO KENKOH Corp
X 14ef CARRY Computer ENG. CO Ltd
X 14f0 CANON RESEACH CENTRE FRANCE
-14f1 CONEXANT
- 1033 56K Winmodem
- 13e0 02b0 56K Winmodem
- 1035 PCI Modem Enumerator
- 2003 SoftK56 Winmodem
- 14f1 2003 SoftK56 Winmodem
- 2004 SoftK56 RemoteTAM Winmodem
- 14f1 2004 SoftK56 RemoteTAM Winmodem
- 2005 SoftK56 Speakerphone Winmodem
- 14f1 2005 SoftK56 Speakerphone Winmodem
- 2006 SoftK56 Speakerphone Winmodem
- 14f1 2006 SoftK56 Speakerphone Winmodem
- 2013 HSP MicroModem 56K
- 14f1 2013 SoftK56 Winmodem
- 2014 SoftK56 RemoteTAM Winmodem
- 144f 101c SoftK56 RemoteTAM Winmodem
- 144f 2014 SoftK56 RemoteTAM Winmodem
- 2015 SoftK56 Speakerphone Winmodem
- 14c8 2115 SoftK56 Speakerphone Winmodem
- 14f1 2015 SoftK56 Speakerphone Winmodem
- 2016 SoftK56 Speakerphone Winmodem
- 14f1 2016 SoftK56 Speakerphone Winmodem
- 2443 SoftK56 Speakerphone Winmodem
- 14f1 2443 SoftK56 Speakerphone Winmodem
+14f1 Conexant
+ 1033 HCF 56k Data/Fax Modem
+ 1033 8077 NEC
+ 122d 4027 Dell Zeus - MDP3880-W(B) Data Fax Modem # Aztech
+ 122d 4030 Dell Mercury - MDP3880-U(B) Data Fax Modem # Aztech
+ 122d 4034 Dell Thor - MDP3880-W(U) Data Fax Modem # Aztech
+ 13e0 020d Dell Copper
+ 13e0 020e Dell Silver
+ 13e0 0261 IBM # GVC
+ 13e0 0290 Compaq Goldwing
+ 13e0 02a0 IBM # GVC
+ 13e0 02b0 IBM # GVC
+ 13e0 02c0 Compaq Scooter
+ 13e0 02d0 IBM # GVC
+ 144f 1500 IBM P85-DF # Askey
+ 144f 1501 IBM P85-DF # Askey
+ 144f 150a IBM P85-DF # Askey
+ 144f 150b IBM P85-DF Low Profile # Askey
+ 144f 1510 IBM P85-DF Low Profile # Askey
+ 1034 HCF 56k Data/Fax/Voice Modem
+ 1035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 1098 Fujitsu P85-DFSV
+ 1036 HCF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4029 MDP3880SP-W # Aztech
+ 122d 4031 MDP3880SP-U # Aztech
+ 13e0 0209 Dell Titanium
+ 13e0 020a Dell Graphite
+ 13e0 0260 Gateway Red Owl
+ 13e0 0270 Gateway White Horse
+ 1052 HCF 56k Data/Fax Modem (Worldwide)
+ 1053 HCF 56k Data/Fax Modem (Worldwide)
+ 1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
+ 1055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
+ 1056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+ 1057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+ 1059 HCF 56k Data/Fax/Voice Modem (Worldwide)
+ 1063 HCF 56k Data/Fax Modem
+ 1064 HCF 56k Data/Fax/Voice Modem
+ 1065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1066 HCF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4033 Dell Athena - MDP3900V-U # Aztech
+ 1433 HCF 56k Data/Fax Modem
+ 1434 HCF 56k Data/Fax/Voice Modem
+ 1435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1436 HCF 56k Data/Fax Modem
+ 1453 HCF 56k Data/Fax Modem
+ 13e0 0240 IBM # GVC
+ 13e0 0250 IBM # GVC
+ 144f 1502 IBM P95-DF # Askey
+ 144f 1503 IBM P95-DF # Askey
+ 1454 HCF 56k Data/Fax/Voice Modem
+ 1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1456 HCF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4035 Dell Europa - MDP3900V-W # Aztech
+ 122d 4302 MP3930V-W(C) MiniPCI # Aztech
+ 1803 HCF 56k Modem
+ 0e11 0023 623-LAN Grizzly # Compaq
+ 0e11 0043 623-LAN Yogi # Compaq
+ 1815 HCF 56k Modem
+ 0e11 0022 Grizzly # Compaq
+ 0e11 0042 Yogi # Compaq
+ 2003 HSF 56k Data/Fax Modem
+ 2004 HSF 56k Data/Fax/Voice Modem
+ 2005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 2006 HSF 56k Data/Fax/Voice/Spkp Modem
+ 2013 HSF 56k Data/Fax Modem
+ 0e11 b195 Bear # Compaq
+ 0e11 b196 Seminole 1 # Compaq
+ 0e11 b1be Seminole 2 # Compaq
+ 1025 8013 Acer
+ 1033 809d NEC
+ 1033 80bc NEC
+ 155d 6793 HP
+ 155d 8850 E Machines
+ 2014 HSF 56k Data/Fax/Voice Modem
+ 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 2016 HSF 56k Data/Fax/Voice/Spkp Modem
+ 2043 HSF 56k Data/Fax Modem (Worldwide SmartDAA)
+ 2044 HSF 56k Data/Fax/Voice Modem (Worldwide SmartDAA)
+ 2045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide SmartDAA)
+ 2046 HSF 56k Data/Fax/Voice/Spkp Modem (Worldwide SmartDAA)
+ 2063 HSF 56k Data/Fax Modem (SmartDAA)
+ 2064 HSF 56k Data/Fax/Voice Modem (SmartDAA)
+ 2065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
+ 2066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
+ 2093 HSF 56k Modem
+ 155d 2f07 Legend
+ 2143 HSF 56k Data/Fax/Cell Modem (Mobile Worldwide SmartDAA)
+ 2144 HSF 56k Data/Fax/Voice/Cell Modem (Mobile Worldwide SmartDAA)
+ 2145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WW SmartDAA)
+ 2146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile Worldwide SmartDAA)
+ 2163 HSF 56k Data/Fax/Cell Modem (Mobile SmartDAA)
+ 2164 HSF 56k Data/Fax/Voice/Cell Modem (Mobile SmartDAA)
+ 2165 HSF 56k Data/Fax/Voice/Spkp (w/Handset)/Cell Modem (Mobile SmartDAA)
+ 2166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mobile SmartDAA)
+ 2343 HSF 56k Data/Fax CardBus Modem (Mobile Worldwide SmartDAA)
+ 2344 HSF 56k Data/Fax/Voice CardBus Modem (Mobile Worldwide SmartDAA)
+ 2345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WW SmartDAA)
+ 2346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile Worldwide SmartDAA)


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 33'
echo 'File patch-2.4.13 is continued in part 34'
echo "34" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:04 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part34

#!/bin/sh -x
# this is part 34 of a 53 - part archive


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

if test "$Scheck" != 34; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ 2363 HSF 56k Data/Fax CardBus Modem (Mobile SmartDAA)
+ 2364 HSF 56k Data/Fax/Voice CardBus Modem (Mobile SmartDAA)
+ 2365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
+ 2366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mobile SmartDAA)
+ 2443 HSF 56k Data/Fax Modem (Mobile Worldwide SmartDAA)
+ 104d 8075 Modem # Sony
+ 104d 8083 Modem # Sony
+ 104d 8097 Modem # Sony
+ 2444 HSF 56k Data/Fax/Voice Modem (Mobile Worldwide SmartDAA)
+ 2445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mobile WW SmartDAA)
+ 2446 HSF 56k Data/Fax/Voice/Spkp Modem (Mobile Worldwide SmartDAA)
+ 2463 HSF 56k Data/Fax Modem (Mobile SmartDAA)
+ 2464 HSF 56k Data/Fax/Voice Modem (Mobile SmartDAA)
+ 2465 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Mobile SmartDAA)
+ 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mobile SmartDAA)
+ 2f00 HSF 56k HSFi Modem
+ 13e0 8d84 IBM HSFi V.90
+ 13e0 8d85 Compaq Stinger
X 14f2 MOBILITY Electronics
X 14f3 BROADLOGIC
X 14f4 TOKYO Electronic Industry CO Ltd
@@ -4659,7 +4832,7 @@
X 0e11 b0c6 Embedded NC3120 with Wake on LAN
X 0e11 b0c7 Embedded NC3121
X 0e11 b0d7 NC3121 with Wake on LAN
- 0e11 b0dd NC3131
+ 0e11 b0dd NC3131 (82558B)
X 0e11 b0de NC3132
X 0e11 b0e1 NC3133
X 0e11 b144 NC3123 (82559)
@@ -4727,6 +4900,8 @@
X 1a21 82840 840 (Carmel) Chipset Host Bridge (Hub A)
X 1a23 82840 840 (Carmel) Chipset AGP Bridge
X 1a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B)
+ 1a30 82845 845 (Brookdale) Chipset Host Bridge
+ 1a31 82845 845 (Brookdale) Chipset AGP Bridge
X 2410 82801AA ISA Bridge (LPC)
X 2411 82801AA IDE
X 2412 82801AA USB
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/Makefile linux/drivers/pcmcia/Makefile
--- v2.4.12/linux/drivers/pcmcia/Makefile Mon Mar 26 15:36:30 2001
+++ linux/drivers/pcmcia/Makefile Thu Oct 11 09:43:29 2001
@@ -53,10 +53,33 @@
X endif
X endif
X
+obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
+
+sa1100_cs-objs-y := sa1100_generic.o
+sa1100_cs-objs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
+sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
+sa1100_cs-objs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
+sa1100_cs-objs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
+sa1100_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o
+sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o
+sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
+sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
+sa1100_cs-objs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o
+sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
+sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
+sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
+sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
+sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
+sa1100_cs-objs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
+
X include $(TOPDIR)/Rules.make
X
X pcmcia_core.o: $(pcmcia_core-objs)
X $(LD) $(LD_RFLAG) -r -o $@ $(pcmcia_core-objs)
+
+sa1100_cs.o: $(sa1100_cs-objs-y)
+ $(LD) -r -o $@ $(sa1100_cs-objs-y)
X
X yenta_socket.o: $(yenta_socket-objs)
X $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.4.12/linux/drivers/pcmcia/cs.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/pcmcia/cs.c Thu Oct 11 09:43:29 2001
@@ -789,6 +789,10 @@
X *base, align);
X align = 0;
X }
+ if ((s->cap.features & SS_CAP_STATIC_MAP) && s->cap.io_offset) {
+ *base = s->cap.io_offset | (*base & 0x0fff);
+ return 0;
+ }
X /* Check for an already-allocated window that must conflict with
X what was asked for. It is a hack because it does not catch all
X potential conflicts, just the most obvious ones. */
@@ -833,7 +837,8 @@
X ioaddr_t num)
X {
X int i;
- release_region(base, num);
+ if(!(s->cap.features & SS_CAP_STATIC_MAP))
+ release_region(base, num);
X for (i = 0; i < MAX_IO_WIN; i++) {
X if ((s->io[i].BasePort <= base) &&
X (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
@@ -1623,7 +1628,8 @@
X s->state &= ~SOCKET_WIN_REQ(win->index);
X
X /* Release system memory */
- release_mem_region(win->base, win->size);
+ if(!(s->cap.features & SS_CAP_STATIC_MAP))
+ release_mem_region(win->base, win->size);
X win->handle->state &= ~CLIENT_WIN_REQ(win->index);
X
X win->magic = 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100.h linux/drivers/pcmcia/sa1100.h
--- v2.4.12/linux/drivers/pcmcia/sa1100.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100.h Thu Oct 11 09:43:29 2001
@@ -0,0 +1,202 @@
+/*======================================================================
+
+ Device driver for the PCMCIA control functionality of StrongARM
+ SA-1100 microprocessors.
+
+ The contents of this file are subject to the Mozilla Public
+ License Version 1.1 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS
+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+ The initial developer of the original code is John G. Dorsey
+ <jo...@cs.cmu.edu>. Portions created by John G. Dorsey are
+ Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
+
+ Alternatively, the contents of this file may be used under the
+ terms of the GNU Public License version 2 (the "GPL"), in which
+ case the provisions of the GPL are applicable instead of the
+ above. If you wish to allow the use of your version of this file
+ only under the terms of the GPL and not to allow others to use
+ your version of this file under the MPL, indicate your decision
+ by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL. If you do not delete
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
+======================================================================*/
+
+#if !defined(_PCMCIA_SA1100_H)
+# define _PCMCIA_SA1100_H
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+#include <asm/arch/pcmcia.h>
+
+
+/* MECR: Expansion Memory Configuration Register
+ * (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
+ *
+ * MECR layout is:
+ *
+ * FAST1 BSM1<4:0> BSA1<4:0> BSIO1<4:0> FAST0 BSM0<4:0> BSA0<4:0> BSIO0<4:0>
+ *
+ * (This layout is actually true only for the SA-1110; the FASTn bits are
+ * reserved on the SA-1100.)
+ */
+
+#define MECR_SOCKET_0_SHIFT (0)
+#define MECR_SOCKET_1_SHIFT (16)
+
+#define MECR_BS_MASK (0x1f)
+#define MECR_FAST_MODE_MASK (0x01)
+
+#define MECR_BSIO_SHIFT (0)
+#define MECR_BSA_SHIFT (5)
+#define MECR_BSM_SHIFT (10)
+#define MECR_FAST_SHIFT (15)
+
+#define MECR_SET(mecr, sock, shift, mask, bs) \
+((mecr)=((mecr)&~(((mask)<<(shift))<<\
+ ((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))|\
+ (((bs)<<(shift))<<((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))
+
+#define MECR_GET(mecr, sock, shift, mask) \
+((((mecr)>>(((sock)==0)?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT))>>\
+ (shift))&(mask))
+
+#define MECR_BSIO_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSIO_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSA_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSA_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK)
+
+#define MECR_BSM_SET(mecr, sock, bs) \
+MECR_SET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK, (bs))
+
+#define MECR_BSM_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK)
+
+#define MECR_FAST_SET(mecr, sock, fast) \
+MECR_SET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK, (fast))
+
+#define MECR_FAST_GET(mecr, sock) \
+MECR_GET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK)
+
+
+/* This function implements the BS value calculation for setting the MECR
+ * using integer arithmetic:
+ */
+static inline unsigned int sa1100_pcmcia_mecr_bs(unsigned int pcmcia_cycle_ns,
+ unsigned int cpu_clock_khz){
+ unsigned int t = ((pcmcia_cycle_ns * cpu_clock_khz) / 6) - 1000000;
+ return (t / 1000000) + (((t % 1000000) == 0) ? 0 : 1);
+}
+
+/* This function returns the (approxmiate) command assertion period, in
+ * nanoseconds, for a given CPU clock frequency and MECR BS value:
+ */
+static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
+ unsigned int pcmcia_mecr_bs){
+ return (((10000000 * 2) / cpu_clock_khz) * (3 * (pcmcia_mecr_bs + 1))) / 10;
+}
+
+
+/* SA-1100 PCMCIA Memory and I/O timing
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * The SA-1110 Developer's Manual, section 10.2.5, says the following:
+ *
+ * "To calculate the recommended BS_xx value for each address space:
+ * divide the command width time (the greater of twIOWR and twIORD,
+ * or the greater of twWE and twOE) by processor cycle time; divide
+ * by 2; divide again by 3 (number of BCLK's per command assertion);
+ * round up to the next whole number; and subtract 1."
+ *
+ * The PC Card Standard, Release 7, section 4.13.4, says that twIORD
+ * has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
+ * a minimum value of 165ns, as well. Section 4.7.2 (describing
+ * common and attribute memory write timing) says that twWE has a
+ * minimum value of 150ns for a 250ns cycle time (for 5V operation;
+ * see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
+ * operation, also section 4.7.4). Section 4.7.3 says that taOE
+ * has a maximum value of 150ns for a 300ns cycle time (for 5V
+ * operation), or 300ns for a 600ns cycle time (for 3.3V operation).
+ *
+ * When configuring memory maps, Card Services appears to adopt the policy
+ * that a memory access time of "0" means "use the default." The default
+ * PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
+ * and memory command width time is 150ns; the PCMCIA 3.3V attribute and
+ * memory command width time is 300ns.
+ */
+#define SA1100_PCMCIA_IO_ACCESS (165)
+#define SA1100_PCMCIA_5V_MEM_ACCESS (150)
+#define SA1100_PCMCIA_3V_MEM_ACCESS (300)
+
+
+/* The socket driver actually works nicely in interrupt-driven form,
+ * so the (relatively infrequent) polling is "just to be sure."
+ */
+#define SA1100_PCMCIA_POLL_PERIOD (2*HZ)
+
+
+/* This structure encapsulates per-socket state which we might need to
+ * use when responding to a Card Services query of some kind.
+ */
+struct sa1100_pcmcia_socket {
+ socket_state_t cs_state;
+ struct pcmcia_state k_state;
+ unsigned int irq;
+ void (*handler)(void *, unsigned int);
+ void *handler_info;
+ pccard_io_map io_map[MAX_IO_WIN];
+ pccard_mem_map mem_map[MAX_WIN];
+ ioaddr_t virt_io, phys_attr, phys_mem;
+ unsigned short speed_io, speed_attr, speed_mem;
+};
+
+
+/* I/O pins replacing memory pins
+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
+ *
+ * These signals change meaning when going from memory-only to
+ * memory-or-I/O interface:
+ */
+#define iostschg bvd1
+#define iospkr bvd2
+
+
+/*
+ * Declaration for all implementation specific low_level operations.
+ */
+extern struct pcmcia_low_level assabet_pcmcia_ops;
+extern struct pcmcia_low_level neponset_pcmcia_ops;
+extern struct pcmcia_low_level h3600_pcmcia_ops;
+extern struct pcmcia_low_level cerf_pcmcia_ops;
+extern struct pcmcia_low_level gcplus_pcmcia_ops;
+extern struct pcmcia_low_level xp860_pcmcia_ops;
+extern struct pcmcia_low_level yopy_pcmcia_ops;
+extern struct pcmcia_low_level pangolin_pcmcia_ops;
+extern struct pcmcia_low_level freebird_pcmcia_ops;
+extern struct pcmcia_low_level pfs168_pcmcia_ops;
+extern struct pcmcia_low_level jornada720_pcmcia_ops;
+extern struct pcmcia_low_level flexanet_pcmcia_ops;
+extern struct pcmcia_low_level simpad_pcmcia_ops;
+extern struct pcmcia_low_level graphicsmaster_pcmcia_ops;
+extern struct pcmcia_low_level adsbitsy_pcmcia_ops;
+extern struct pcmcia_low_level stork_pcmcia_ops;
+
+#endif /* !defined(_PCMCIA_SA1100_H) */
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_adsbitsy.c linux/drivers/pcmcia/sa1100_adsbitsy.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_adsbitsy.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_adsbitsy.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,216 @@
+/*
+ * drivers/pcmcia/sa1100_adsbitsy.c
+ *
+ * PCMCIA implementation routines for ADS Bitsy
+ *
+ * 9/18/01 Woojung
+ * Fixed wrong PCMCIA voltage setting
+ *
+ * 7/5/01 Woojung Huh <wh...@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
+{
+ int return_val=0;
+
+ /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+ /* Disable Power 3.3V/5V for PCMCIA/CF */
+ PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+
+ INTPOL1 |= (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
+ "GC Master PCMCIA (0) CD", NULL);
+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
+ "GC Master CF (1) CD", NULL);
+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+ "GC Master PCMCIA (0) BVD1", NULL);
+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
+ "GC Master CF (1) BVD1", NULL);
+
+ MECR = 0x09430943;
+
+ return (return_val<0) ? -1 : 2;
+}
+
+static int adsbitsy_pcmcia_shutdown(void)
+{
+
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+


+ return 0;
+}
+

+static int adsbitsy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{
+ unsigned long status;
+ int return_val=1;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ status=PCSR;
+
+ state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+
+ state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+
+ state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+
+ state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+
+ state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+
+ state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+
+ state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+
+ state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+
+ state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+
+ state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+
+ state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+
+ state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+
+ state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+
+ state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+
+ return return_val;
+}
+
+static int adsbitsy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;


+ break;
+
+ default:

+ return -1;
+ }
+

+ return 0;
+}
+

+static int adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+ unsigned long pccr=PCCR, gpio=PA_DWR;
+
+ switch(configure->sock){
+ case 0:
+
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S0_FLT);
+ gpio |= GPIO_GPIO0 | GPIO_GPIO1;
+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+ gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+ gpio &= ~GPIO_GPIO0;
+ break;
+
+ case 50:
+ pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+ gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);
+ gpio |= GPIO_GPIO0;


+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);


+ return -1;
+ }
+

+ pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+ break;
+
+ case 1:
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S1_FLT);
+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+ gpio |= GPIO_GPIO2;
+ break;
+
+ case 50:
+ pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+ gpio |= GPIO_GPIO3;


+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);


+ return -1;
+ }
+

+ if(configure->vpp!=configure->vcc && configure->vpp!=0){
+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+ configure->vpp);


+ return -1;
+ }
+

+ pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+ break;
+
+ default:


+ return -1;
+ }
+

+ PCCR = pccr;
+ PA_DWR = gpio;
+


+ return 0;
+}
+

+struct pcmcia_low_level adsbitsy_pcmcia_ops = {
+ adsbitsy_pcmcia_init,
+ adsbitsy_pcmcia_shutdown,
+ adsbitsy_pcmcia_socket_state,
+ adsbitsy_pcmcia_get_irq_info,
+ adsbitsy_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_assabet.c linux/drivers/pcmcia/sa1100_assabet.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_assabet.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_assabet.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,149 @@
+/*
+ * drivers/pcmcia/sa1100_assabet.c
+ *
+ * PCMCIA implementation routines for Assabet
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int assabet_pcmcia_init(struct pcmcia_init *init){
+ int irq, res;
+
+ /* Enable CF bus: */
+ BCR_clear(BCR_CF_BUS_OFF);
+
+ /* All those are inputs */
+ GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+ /* Set transition detect */
+ set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+ /* Register interrupts */
+ irq = IRQ_GPIO_CF_CD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+ if( res < 0 ) goto irq_err;
+ irq = IRQ_GPIO_CF_BVD2;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+ if( res < 0 ) goto irq_err;
+ irq = IRQ_GPIO_CF_BVD1;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+ if( res < 0 ) goto irq_err;
+
+ /* There's only one slot, but it's "Slot 1": */
+ return 2;
+
+irq_err:
+ printk( KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__, irq );


+ return -1;
+}
+

+static int assabet_pcmcia_shutdown(void)
+{
+ /* disable IRQs */
+ free_irq( IRQ_GPIO_CF_CD, NULL );
+ free_irq( IRQ_GPIO_CF_BVD2, NULL );
+ free_irq( IRQ_GPIO_CF_BVD1, NULL );
+
+ /* Disable CF bus: */
+ BCR_set(BCR_CF_BUS_OFF);
+


+ return 0;
+}
+

+static int assabet_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){
+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;
+
+ state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+ state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+ state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+ state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+ state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+ state_array->state[1].vs_3v=1; /* Can only apply 3.3V on Assabet. */
+
+ state_array->state[1].vs_Xv=0;
+


+ return 1;
+}
+

+static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+ if(info->sock>1) return -1;
+
+ if(info->sock==1)
+ info->irq=IRQ_GPIO_CF_IRQ;
+


+ return 0;
+}
+

+static int assabet_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long value, flags;
+
+ if(configure->sock>1) return -1;
+
+ if(configure->sock==0) return 0;
+
+ save_flags_cli(flags);
+
+ value = BCR_value;
+
+ switch(configure->vcc){
+ case 0:
+ value &= ~BCR_CF_PWR;
+ break;
+
+ case 50:
+ printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+ __FUNCTION__);
+
+ case 33: /* Can only apply 3.3V to the CF slot. */
+ value |= BCR_CF_PWR;


+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);


+ return -1;
+ }
+

+ value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+ /* Silently ignore Vpp, output enable, speaker enable. */
+
+ BCR = BCR_value = value;
+
+ restore_flags(flags);
+


+ return 0;
+}
+

+struct pcmcia_low_level assabet_pcmcia_ops = {
+ assabet_pcmcia_init,
+ assabet_pcmcia_shutdown,
+ assabet_pcmcia_socket_state,
+ assabet_pcmcia_get_irq_info,
+ assabet_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_cerf.c linux/drivers/pcmcia/sa1100_cerf.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_cerf.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_cerf.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,150 @@
+/*
+ * drivers/pcmcia/sa1100_cerf.c
+ *
+ * PCMCIA implementation routines for CerfBoard
+ * Based off the Assabet.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int cerf_pcmcia_init(struct pcmcia_init *init){
+ int irq, res;
+
+ /* Enable CF bus: */
+// BCR_clear(BCR_CF_BUS_OFF);
+
+ /* All those are inputs */
+ GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+
+ /* Set transition detect */
+ set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+ /* Register interrupts */
+ irq = IRQ_GPIO_CF_CD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+ if( res < 0 ) goto irq_err;
+ irq = IRQ_GPIO_CF_BVD2;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL );
+ if( res < 0 ) goto irq_err;
+ irq = IRQ_GPIO_CF_BVD1;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+ if( res < 0 ) goto irq_err;
+
+ /* There's only one slot, but it's "Slot 1": */
+ return 2;
+
+irq_err:
+ printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );


+ return -1;
+}
+

+static int cerf_pcmcia_shutdown(void)
+{
+ /* disable IRQs */
+ free_irq( IRQ_GPIO_CF_CD, NULL );
+ free_irq( IRQ_GPIO_CF_BVD2, NULL );
+ free_irq( IRQ_GPIO_CF_BVD1, NULL );
+
+ /* Disable CF bus: */
+// BCR_set(BCR_CF_BUS_OFF);
+


+ return 0;
+}
+

+static int cerf_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){
+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;
+
+ state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+ state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+
+ state_array->state[1].bvd1=(levels & GPIO_CF_BVD1)?1:0;
+
+ state_array->state[1].bvd2=(levels & GPIO_CF_BVD2)?1:0;
+
+ state_array->state[1].wrprot=0; /* Not available on Assabet. */
+
+ state_array->state[1].vs_3v=1; /* Can only apply 3.3V on Assabet. */
+
+ state_array->state[1].vs_Xv=0;
+


+ return 1;
+}
+

+static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+ if(info->sock>1) return -1;
+
+ if(info->sock==1)
+ info->irq=IRQ_GPIO_CF_IRQ;
+


+ return 0;
+}
+

+static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long value, flags;
+
+ if(configure->sock>1) return -1;
+
+ if(configure->sock==0) return 0;
+
+ save_flags_cli(flags);
+
+// value = BCR_value;
+
+ switch(configure->vcc){
+ case 0:
+// value &= ~BCR_CF_PWR;
+ break;
+
+ case 50:
+ printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+ __FUNCTION__);
+
+ case 33: /* Can only apply 3.3V to the CF slot. */
+// value |= BCR_CF_PWR;


+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);


+ return -1;
+ }
+

+// value = (configure->reset) ? (value | BCR_CF_RST) : (value & ~BCR_CF_RST);
+
+ /* Silently ignore Vpp, output enable, speaker enable. */
+
+// BCR = BCR_value = value;
+
+ restore_flags(flags);
+


+ return 0;
+}
+

+struct pcmcia_low_level cerf_pcmcia_ops = {
+ cerf_pcmcia_init,
+ cerf_pcmcia_shutdown,
+ cerf_pcmcia_socket_state,
+ cerf_pcmcia_get_irq_info,
+ cerf_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_flexanet.c linux/drivers/pcmcia/sa1100_flexanet.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_flexanet.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_flexanet.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,84 @@
+/*
+ * drivers/pcmcia/sa1100_flexanet.c
+ *
+ * PCMCIA implementation routines for Flexanet.
+ * by Jordi Colomer, 09/05/2001
+ *
+ * Yet to be defined.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+/*
+ * Socket initialization.
+ *
+ * Called by sa1100_pcmcia_driver_init on startup.
+ * Must return the number of slots.
+ *
+ */
+static int flexanet_pcmcia_init(struct pcmcia_init *init){
+


+ return 0;
+}
+

+
+/*
+ * Socket shutdown
+ *
+ */
+static int flexanet_pcmcia_shutdown(void)
+{


+ return 0;
+}
+

+
+/*
+ * Get the state of the sockets.
+ *
+ * Sockets in Flexanet are 3.3V only, without BVD2.
+ *
+ */
+static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){


+ return -1;
+}
+
+
+/*

+ * Return the IRQ information for a given socket number (the IRQ number)
+ *
+ */
+static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+


+ return -1;
+}
+
+
+/*

+ *
+ */
+static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{


+ return -1;
+}
+
+
+/*

+ * The set of socket operations
+ *
+ */
+struct pcmcia_low_level flexanet_pcmcia_ops = {
+ flexanet_pcmcia_init,
+ flexanet_pcmcia_shutdown,
+ flexanet_pcmcia_socket_state,
+ flexanet_pcmcia_get_irq_info,
+ flexanet_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_freebird.c linux/drivers/pcmcia/sa1100_freebird.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_freebird.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_freebird.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,160 @@
+/*
+ * drivers/pcmcia/sa1100_freebird.c
+ *
+ * Created by Eric Peng <eric...@coventive.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+
+static int freebird_pcmcia_init(struct pcmcia_init *init){
+ int irq, res;
+
+ /* Enable Linkup CF card */
+ LINKUP_PRC = 0xc0;
+ mdelay(100);
+ LINKUP_PRC = 0xc1;
+ mdelay(100);
+ LINKUP_PRC = 0xd1;
+ mdelay(100);
+ LINKUP_PRC = 0xd1;
+ mdelay(100);
+ LINKUP_PRC = 0xc0;
+
+ /* All those are inputs */
+ ////GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IRQ);
+ GPDR &= ~(GPIO_FREEBIRD_CF_CD | GPIO_FREEBIRD_CF_IRQ | GPIO_FREEBIRD_CF_BVD);
+
+ /* Set transition detect */
+ //set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1, GPIO_BOTH_EDGES );
+ //set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+ set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_CD|GPIO_FREEBIRD_CF_BVD,GPIO_BOTH_EDGES);
+ set_GPIO_IRQ_edge(GPIO_FREEBIRD_CF_IRQ, GPIO_FALLING_EDGE);
+
+ /* Register interrupts */
+ irq = IRQ_GPIO_FREEBIRD_CF_CD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+ if( res < 0 ) goto irq_err;
+ irq = IRQ_GPIO_FREEBIRD_CF_BVD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL );
+ if( res < 0 ) goto irq_err;
+
+ /* There's only one slot, but it's "Slot 1": */
+ return 2;
+
+irq_err:
+ printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );


+ return -1;
+}
+

+static int freebird_pcmcia_shutdown(void)
+{
+ /* disable IRQs */
+ free_irq( IRQ_GPIO_FREEBIRD_CF_CD, NULL );
+ free_irq( IRQ_GPIO_FREEBIRD_CF_BVD, NULL );
+
+ /* Disable CF card */
+ LINKUP_PRC = 0x40; /* SSP=1 SOE=0 */
+ mdelay(100);
+


+ return 0;
+}
+

+static int freebird_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){
+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels = LINKUP_PRS;
+//printk("LINKUP_PRS=%x \n",levels);
+
+ state_array->state[0].detect=
+ ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
+
+ state_array->state[0].ready=(levels & LINKUP_RDY)?1:0;
+
+ state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0;
+
+ state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0;
+
+ state_array->state[0].wrprot=0; /* Not available on Assabet. */
+
+ state_array->state[0].vs_3v=1; /* Can only apply 3.3V on Assabet. */
+
+ state_array->state[0].vs_Xv=0;
+


+ return 1;
+}
+

+static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+ if(info->sock>1) return -1;
+
+ if(info->sock==0)
+ info->irq=IRQ_GPIO_FREEBIRD_CF_IRQ;
+


+ return 0;
+}
+

+static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long value, flags;
+
+ if(configure->sock>1) return -1;
+
+ if(configure->sock==1) return 0;
+
+ save_flags_cli(flags);
+
+ value = 0xc0; /* SSP=1 SOE=1 CFE=1 */
+
+ switch(configure->vcc){
+ case 0:
+
+ break;
+
+ case 50:
+ printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+ __FUNCTION__);
+
+ case 33: /* Can only apply 3.3V to the CF slot. */
+ value |= LINKUP_S1;


+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);


+ return -1;
+ }
+

+ if (configure->reset)
+ value = (configure->reset) ? (value | LINKUP_RESET) : (value & ~LINKUP_RESET);
+
+ /* Silently ignore Vpp, output enable, speaker enable. */
+
+ LINKUP_PRC = value;
+//printk("LINKUP_PRC=%x\n",value);
+ restore_flags(flags);
+


+ return 0;
+}
+

+struct pcmcia_low_level freebird_pcmcia_ops = {
+ freebird_pcmcia_init,
+ freebird_pcmcia_shutdown,
+ freebird_pcmcia_socket_state,
+ freebird_pcmcia_get_irq_info,
+ freebird_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_generic.c linux/drivers/pcmcia/sa1100_generic.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_generic.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_generic.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,1168 @@
+/*======================================================================
+
+ Device driver for the PCMCIA control functionality of StrongARM
+ SA-1100 microprocessors.
+
+ The contents of this file are subject to the Mozilla Public
+ License Version 1.1 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS
+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+ The initial developer of the original code is John G. Dorsey
+ <jo...@cs.cmu.edu>. Portions created by John G. Dorsey are
+ Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
+
+ Alternatively, the contents of this file may be used under the
+ terms of the GNU Public License version 2 (the "GPL"), in which
+ case the provisions of the GPL are applicable instead of the
+ above. If you wish to allow the use of your version of this file
+ only under the terms of the GPL and not to allow others to use
+ your version of this file under the MPL, indicate your decision
+ by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL. If you do not delete
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bus_ops.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "sa1100.h"
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug;
+#endif
+
+MODULE_AUTHOR("John Dorsey <jo...@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-1100 Socket Controller");
+
+/* This structure maintains housekeeping state for each socket, such
+ * as the last known values of the card detect pins, or the Card Services
+ * callback value associated with the socket:
+ */
+static struct sa1100_pcmcia_socket
+sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
+
+static int sa1100_pcmcia_socket_count;
+
+
+/* Returned by the low-level PCMCIA interface: */
+static struct pcmcia_low_level *pcmcia_low_level;
+
+/* Event poll timer structure */
+static struct timer_list poll_timer;
+
+
+/* Prototypes for routines which are used internally: */
+
+static int sa1100_pcmcia_driver_init(void);
+static void sa1100_pcmcia_driver_shutdown(void);
+static void sa1100_pcmcia_task_handler(void *data);
+static void sa1100_pcmcia_poll_event(unsigned long data);
+static void sa1100_pcmcia_interrupt(int irq, void *dev,
+ struct pt_regs *regs);
+static struct tq_struct sa1100_pcmcia_task;
+
+#ifdef CONFIG_PROC_FS
+static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data);
+#endif
+
+
+/* Prototypes for operations which are exported to the
+ * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
+ */
+
+static int sa1100_pcmcia_init(unsigned int sock);
+static int sa1100_pcmcia_suspend(unsigned int sock);
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+ void (*handler)(void *,
+ unsigned int),
+ void *info);
+static int sa1100_pcmcia_inquire_socket(unsigned int sock,
+ socket_cap_t *cap);
+static int sa1100_pcmcia_get_status(unsigned int sock, u_int *value);
+static int sa1100_pcmcia_get_socket(unsigned int sock,
+ socket_state_t *state);
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+ socket_state_t *state);
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+ struct pccard_io_map *io);
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+ struct pccard_io_map *io);
+static int sa1100_pcmcia_get_mem_map(unsigned int sock,
+ struct pccard_mem_map *mem);
+static int sa1100_pcmcia_set_mem_map(unsigned int sock,
+ struct pccard_mem_map *mem);
+#ifdef CONFIG_PROC_FS
+static void sa1100_pcmcia_proc_setup(unsigned int sock,
+ struct proc_dir_entry *base);
+#endif
+
+static struct pccard_operations sa1100_pcmcia_operations = {
+ sa1100_pcmcia_init,
+ sa1100_pcmcia_suspend,
+ sa1100_pcmcia_register_callback,
+ sa1100_pcmcia_inquire_socket,
+ sa1100_pcmcia_get_status,
+ sa1100_pcmcia_get_socket,
+ sa1100_pcmcia_set_socket,
+ sa1100_pcmcia_get_io_map,
+ sa1100_pcmcia_set_io_map,
+ sa1100_pcmcia_get_mem_map,
+ sa1100_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+ sa1100_pcmcia_proc_setup
+#endif
+};
+
+#ifdef CONFIG_CPU_FREQ
+/* forward declaration */
+static struct notifier_block sa1100_pcmcia_notifier_block;
+#endif
+
+
+/* sa1100_pcmcia_driver_init()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * This routine performs a basic sanity check to ensure that this
+ * kernel has been built with the appropriate board-specific low-level
+ * PCMCIA support, performs low-level PCMCIA initialization, registers
+ * this socket driver with Card Services, and then spawns the daemon
+ * thread which is the real workhorse of the socket driver.
+ *
+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
+ * on the low-level kernel interface.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int __init sa1100_pcmcia_driver_init(void){
+ servinfo_t info;
+ struct pcmcia_init pcmcia_init;
+ struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+ struct pcmcia_state_array state_array;
+ unsigned int i, clock;
+ unsigned long mecr;
+
+ printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
+
+ CardServices(GetCardServicesInfo, &info);
+
+ if(info.Revision!=CS_RELEASE_CODE){
+ printk(KERN_ERR "Card Services release codes do not match\n");


+ return -1;
+ }
+

+ if(machine_is_assabet()){
+#ifdef CONFIG_SA1100_ASSABET
+ if(machine_has_neponset()){
+#ifdef CONFIG_ASSABET_NEPONSET
+ pcmcia_low_level=&neponset_pcmcia_ops;
+#else
+ printk(KERN_ERR "Card Services disabled: missing Neponset support\n");
+ return -1;
+#endif
+ }else{
+ pcmcia_low_level=&assabet_pcmcia_ops;
+ }
+#endif
+ } else if (machine_is_freebird()) {
+#ifdef CONFIG_SA1100_FREEBIRD
+ pcmcia_low_level = &freebird_pcmcia_ops;
+#endif
+ } else if (machine_is_h3600()) {
+#ifdef CONFIG_SA1100_H3600
+ pcmcia_low_level = &h3600_pcmcia_ops;
+#endif
+ } else if (machine_is_cerf()) {
+#ifdef CONFIG_SA1100_CERF
+ pcmcia_low_level = &cerf_pcmcia_ops;
+#endif
+ } else if (machine_is_graphicsclient()) {
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+ pcmcia_low_level = &gcplus_pcmcia_ops;
+#endif
+ } else if (machine_is_xp860()) {
+#ifdef CONFIG_SA1100_XP860
+ pcmcia_low_level = &xp860_pcmcia_ops;
+#endif
+ } else if (machine_is_yopy()) {
+#ifdef CONFIG_SA1100_YOPY
+ pcmcia_low_level = &yopy_pcmcia_ops;
+#endif
+ } else if (machine_is_pangolin()) {
+#ifdef CONFIG_SA1100_PANGOLIN
+ pcmcia_low_level = &pangolin_pcmcia_ops;
+#endif
+ } else if (machine_is_jornada720()) {
+#ifdef CONFIG_SA1100_JORNADA720
+ pcmcia_low_level = &jornada720_pcmcia_ops;
+#endif
+ } else if(machine_is_pfs168()){
+#ifdef CONFIG_SA1100_PFS168
+ pcmcia_low_level=&pfs168_pcmcia_ops;
+#endif
+ } else if(machine_is_flexanet()){
+#ifdef CONFIG_SA1100_FLEXANET
+ pcmcia_low_level=&flexanet_pcmcia_ops;
+#endif
+ } else if(machine_is_simpad()){
+#ifdef CONFIG_SA1100_SIMPAD
+ pcmcia_low_level=&simpad_pcmcia_ops;
+#endif
+ } else if(machine_is_graphicsmaster()) {
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
+ pcmcia_low_level=&graphicsmaster_pcmcia_ops;
+#endif
+ } else if(machine_is_adsbitsy()) {
+#ifdef CONFIG_SA1100_ADSBITSY
+ pcmcia_low_level=&adsbitsy_pcmcia_ops;
+#endif
+ } else if(machine_is_stork()) {
+#ifdef CONFIG_SA1100_STORK
+ pcmcia_low_level=&stork_pcmcia_ops;
+#endif
+ }
+
+ if (!pcmcia_low_level) {
+ printk(KERN_ERR "This hardware is not supported by the SA1100 Card Service driver\n");


+ return -ENODEV;
+ }
+

+ pcmcia_init.handler=sa1100_pcmcia_interrupt;
+
+ if((sa1100_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
+ printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");


+ return -EIO;
+ }
+

+ state_array.size=sa1100_pcmcia_socket_count;
+ state_array.state=state;
+
+ if(pcmcia_low_level->socket_state(&state_array)<0){
+ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");


+ return -EIO;
+ }
+

+ /* We initialize the MECR to default values here, because we are
+ * not guaranteed to see a SetIOMap operation at runtime.
+ */
+ mecr=0;
+
+ clock = get_cclk_frequency() * 100;
+
+ for(i=0; i<sa1100_pcmcia_socket_count; ++i){
+ sa1100_pcmcia_socket[i].k_state=state[i];
+
+ /* This is an interim fix. Apparently, SetSocket is no longer
+ * called to initialize each socket (prior to the first detect
+ * event). For now, we'll just manually set up the mask.
+ */
+ sa1100_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
+
+ sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
+ sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
+ sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);
+
+ MECR_FAST_SET(mecr, i, 0);
+ MECR_BSIO_SET(mecr, i,
+ sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_IO_ACCESS, clock));
+ MECR_BSA_SET(mecr, i,
+ sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+ MECR_BSM_SET(mecr, i,
+ sa1100_pcmcia_mecr_bs(SA1100_PCMCIA_5V_MEM_ACCESS, clock));
+
+ sa1100_pcmcia_socket[i].speed_io=SA1100_PCMCIA_IO_ACCESS;
+ sa1100_pcmcia_socket[i].speed_attr=SA1100_PCMCIA_5V_MEM_ACCESS;
+ sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
+ }
+
+ MECR=mecr;
+
+#ifdef CONFIG_CPU_FREQ
+ if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
+ printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
+ return -ENXIO;
+ }
+#endif
+
+ /* Only advertise as many sockets as we can detect: */
+ if(register_ss_entry(sa1100_pcmcia_socket_count,
+ &sa1100_pcmcia_operations)<0){
+ printk(KERN_ERR "Unable to register socket service routine\n");


+ return -ENXIO;
+ }
+

+ /* Start the event poll timer. It will reschedule by itself afterwards. */
+ sa1100_pcmcia_poll_event(0);
+
+ DEBUG(1, "sa1100: initialization complete\n");
+
+ return 0;
+
+} /* sa1100_pcmcia_driver_init() */
+
+module_init(sa1100_pcmcia_driver_init);
+
+
+/* sa1100_pcmcia_driver_shutdown()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit sa1100_pcmcia_driver_shutdown(void){
+
+ del_timer_sync(&poll_timer);
+ unregister_ss_entry(&sa1100_pcmcia_operations);
+#ifdef CONFIG_CPU_FREQ
+ cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
+#endif
+ pcmcia_low_level->shutdown();
+ flush_scheduled_tasks();
+
+ DEBUG(1, "sa1100: shutdown complete\n");
+}
+
+module_exit(sa1100_pcmcia_driver_shutdown);
+
+
+/* sa1100_pcmcia_init()
+ * ^^^^^^^^^^^^^^^^^^^^
+ * We perform all of the interesting initialization tasks in
+ * sa1100_pcmcia_driver_init().
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_init(unsigned int sock){
+
+ DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
+


+ return 0;
+}
+

+
+/* sa1100_pcmcia_suspend()
+ * ^^^^^^^^^^^^^^^^^^^^^^^
+ * We don't currently perform any actions on a suspend.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_suspend(unsigned int sock){
+
+ DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+


+ return 0;
+}
+

+
+/* sa1100_pcmcia_events()
+ * ^^^^^^^^^^^^^^^^^^^^^^
+ * Helper routine to generate a Card Services event mask based on
+ * state information obtained from the kernel low-level PCMCIA layer
+ * in a recent (and previous) sampling. Updates `prev_state'.
+ *
+ * Returns: an event mask for the given socket state.
+ */
+static inline unsigned sa1100_pcmcia_events(struct pcmcia_state *state,
+ struct pcmcia_state *prev_state,
+ unsigned int mask,
+ unsigned int flags){
+ unsigned int events=0;
+
+ if(state->detect!=prev_state->detect){
+
+ DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
+
+ events|=mask&SS_DETECT;
+ }
+
+ if(state->ready!=prev_state->ready){
+
+ DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
+
+ events|=mask&((flags&SS_IOCARD)?0:SS_READY);
+ }
+
+ if(state->bvd1!=prev_state->bvd1){
+
+ DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
+
+ events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;
+ }
+
+ if(state->bvd2!=prev_state->bvd2){
+
+ DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
+
+ events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;
+ }
+
+ DEBUG(2, "events: %s%s%s%s%s%s\n",
+ (events==0)?"<NONE>":"",
+ (events&SS_DETECT)?"DETECT ":"",
+ (events&SS_READY)?"READY ":"",
+ (events&SS_BATDEAD)?"BATDEAD ":"",
+ (events&SS_BATWARN)?"BATWARN ":"",
+ (events&SS_STSCHG)?"STSCHG ":"");
+
+ *prev_state=*state;
+
+ return events;
+
+} /* sa1100_pcmcia_events() */
+
+
+/* sa1100_pcmcia_task_handler()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Processes serviceable socket events using the "eventd" thread context.
+ *
+ * Event processing (specifically, the invocation of the Card Services event
+ * callback) occurs in this thread rather than in the actual interrupt
+ * handler due to the use of scheduling operations in the PCMCIA core.
+ */
+static void sa1100_pcmcia_task_handler(void *data) {
+ struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+ struct pcmcia_state_array state_array;
+ int i, events, all_events, irq_status;
+
+ DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
+
+ state_array.size=sa1100_pcmcia_socket_count;
+ state_array.state=state;
+
+ do {
+
+ DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
+
+ if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)
+ printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
+
+ all_events=0;
+
+ if(irq_status>0){
+
+ for(i=0; i<state_array.size; ++i, all_events|=events)
+ if((events=
+ sa1100_pcmcia_events(&state[i],
+ &sa1100_pcmcia_socket[i].k_state,
+ sa1100_pcmcia_socket[i].cs_state.csc_mask,
+ sa1100_pcmcia_socket[i].cs_state.flags)))
+ if(sa1100_pcmcia_socket[i].handler!=NULL)
+ sa1100_pcmcia_socket[i].handler(sa1100_pcmcia_socket[i].handler_info,
+ events);
+ }
+
+ } while(all_events);
+} /* sa1100_pcmcia_task_handler() */
+
+static struct tq_struct sa1100_pcmcia_task = {
+ routine: sa1100_pcmcia_task_handler
+};
+
+
+/* sa1100_pcmcia_poll_event()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
+ */
+static void sa1100_pcmcia_poll_event(unsigned long dummy)
+{
+ DEBUG(3, "%s(): polling for events\n", __FUNCTION__);
+ poll_timer.function = sa1100_pcmcia_poll_event;
+ poll_timer.expires = jiffies + SA1100_PCMCIA_POLL_PERIOD;
+ add_timer(&poll_timer);
+ schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_interrupt()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Service routine for socket driver interrupts (requested by the
+ * low-level PCMCIA init() operation via sa1100_pcmcia_thread()).
+ * The actual interrupt-servicing work is performed by
+ * sa1100_pcmcia_thread(), largely because the Card Services event-
+ * handling code performs scheduling operations which cannot be
+ * executed from within an interrupt context.
+ */
+static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
+ DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
+ schedule_task(&sa1100_pcmcia_task);
+}
+
+
+/* sa1100_pcmcia_register_callback()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the register_callback() operation for the in-kernel
+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If
+ * the function pointer `handler' is not NULL, remember the callback
+ * location in the state for `sock', and increment the usage counter
+ * for the driver module. (The callback is invoked from the interrupt
+ * service routine, sa1100_pcmcia_interrupt(), to notify Card Services
+ * of interesting events.) Otherwise, clear the callback pointer in the
+ * socket state and decrement the module usage count.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_register_callback(unsigned int sock,
+ void (*handler)(void *,
+ unsigned int),
+ void *info){
+ if(handler==NULL){
+ sa1100_pcmcia_socket[sock].handler=NULL;
+ MOD_DEC_USE_COUNT;
+ } else {
+ MOD_INC_USE_COUNT;
+ sa1100_pcmcia_socket[sock].handler=handler;
+ sa1100_pcmcia_socket[sock].handler_info=info;
+ }
+


+ return 0;
+}
+

+
+/* sa1100_pcmcia_inquire_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_InquireSocket in Card Services). Of note is
+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
+ * `cap' to "trick" Card Services into tolerating large "I/O memory"
+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
+ * resource database check. (Mapped memory is set up within the socket
+ * driver itself.)
+ *
+ * In conjunction with the STATIC_MAP capability is a new field,
+ * `io_offset', recommended by David Hinds. Rather than go through
+ * the SetIOMap interface (which is not quite suited for communicating
+ * window locations up from the socket driver), we just pass up
+ * an offset which is applied to client-requested base I/O addresses
+ * in alloc_io_space().
+ *
+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ */
+static int sa1100_pcmcia_inquire_socket(unsigned int sock,
+ socket_cap_t *cap){
+ struct pcmcia_irq_info irq_info;
+
+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ if(sock>=sa1100_pcmcia_socket_count){
+ printk(KERN_ERR "sa1100: socket %u not configured\n", sock);


+ return -1;
+ }
+

+ /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+ * force_low argument to validate_mem() in rsrc_mgr.c -- since in
+ * general, the mapped * addresses of the PCMCIA memory regions
+ * will not be within 0xffff, setting force_low would be
+ * undesirable.
+ *
+ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+ * resource database; we instead pass up physical address ranges
+ * and allow other parts of Card Services to deal with remapping.
+ *
+ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+ * not 32-bit CardBus devices.
+ */
+ cap->features=(SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+
+ irq_info.sock=sock;
+ irq_info.irq=-1;
+
+ if(pcmcia_low_level->get_irq_info(&irq_info)<0){
+ printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",
+ sock);


+ return -1;
+ }
+

+ cap->irq_mask=0;
+ cap->map_size=PAGE_SIZE;
+ cap->pci_irq=irq_info.irq;
+ cap->io_offset=sa1100_pcmcia_socket[sock].virt_io;
+
+ return 0;
+
+} /* sa1100_pcmcia_inquire_socket() */
+
+
+/* sa1100_pcmcia_get_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_status() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetStatus in Card Services). Essentially just
+ * fills in bits in `status' according to internal driver state or
+ * the value of the voltage detect chipselect register.
+ *
+ * As a debugging note, during card startup, the PCMCIA core issues
+ * three set_socket() commands in a row the first with RESET deasserted,
+ * the second with RESET asserted, and the last with RESET deasserted
+ * again. Following the third set_socket(), a get_status() command will
+ * be issued. The kernel is looking for the SS_READY flag (see
+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_status(unsigned int sock,
+ unsigned int *status){
+ struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
+ struct pcmcia_state_array state_array;
+
+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ state_array.size=sa1100_pcmcia_socket_count;
+ state_array.state=state;
+
+ if((pcmcia_low_level->socket_state(&state_array))<0){
+ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");


+ return -1;
+ }
+

+ sa1100_pcmcia_socket[sock].k_state=state[sock];
+
+ *status=state[sock].detect?SS_DETECT:0;
+
+ *status|=state[sock].ready?SS_READY:0;
+
+ /* The power status of individual sockets is not available
+ * explicitly from the hardware, so we just remember the state
+ * and regurgitate it upon request:
+ */
+ *status|=sa1100_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+
+ if(sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
+ *status|=state[sock].bvd1?SS_STSCHG:0;
+ else {
+ if(state[sock].bvd1==0)
+ *status|=SS_BATDEAD;
+ else if(state[sock].bvd2==0)
+ *status|=SS_BATWARN;
+ }
+
+ *status|=state[sock].vs_3v?SS_3VCARD:0;
+
+ *status|=state[sock].vs_Xv?SS_XVCARD:0;
+
+ DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",
+ (*status&SS_DETECT)?"DETECT ":"",
+ (*status&SS_READY)?"READY ":"",
+ (*status&SS_BATDEAD)?"BATDEAD ":"",
+ (*status&SS_BATWARN)?"BATWARN ":"",
+ (*status&SS_POWERON)?"POWERON ":"",
+ (*status&SS_STSCHG)?"STSCHG ":"",
+ (*status&SS_3VCARD)?"3VCARD ":"",
+ (*status&SS_XVCARD)?"XVCARD ":"");
+
+ return 0;
+
+} /* sa1100_pcmcia_get_status() */
+
+
+/* sa1100_pcmcia_get_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetSocket in Card Services). Not a very
+ * exciting routine.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_get_socket(unsigned int sock,
+ socket_state_t *state){
+
+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ /* This information was given to us in an earlier call to set_socket(),
+ * so we're just regurgitating it here:
+ */
+ *state=sa1100_pcmcia_socket[sock].cs_state;
+


+ return 0;
+}
+

+
+/* sa1100_pcmcia_set_socket()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetSocket in Card Services). We more or
+ * less punt all of this work and let the kernel handle the details
+ * of power configuration, reset, &c. We also record the value of
+ * `state' in order to regurgitate it to the PCMCIA core later.
+ *
+ * Returns: 0
+ */
+static int sa1100_pcmcia_set_socket(unsigned int sock,
+ socket_state_t *state){
+ struct pcmcia_configure configure;
+
+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ DEBUG(3, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+ "\tVcc %d Vpp %d irq %d\n",
+ (state->csc_mask==0)?"<NONE>":"",
+ (state->csc_mask&SS_DETECT)?"DETECT ":"",
+ (state->csc_mask&SS_READY)?"READY ":"",
+ (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
+ (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
+ (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
+ (state->flags==0)?"<NONE>":"",
+ (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
+ (state->flags&SS_IOCARD)?"IOCARD ":"",
+ (state->flags&SS_RESET)?"RESET ":"",
+ (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
+ (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+ state->Vcc, state->Vpp, state->io_irq);
+
+ configure.sock=sock;
+ configure.vcc=state->Vcc;
+ configure.vpp=state->Vpp;
+ configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
+ configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
+ configure.reset=(state->flags&SS_RESET)?1:0;
+
+ if(pcmcia_low_level->configure_socket(&configure)<0){
+ printk(KERN_ERR "Unable to configure socket %u\n", sock);


+ return -1;
+ }
+

+ sa1100_pcmcia_socket[sock].cs_state=*state;
+
+ return 0;
+
+} /* sa1100_pcmcia_set_socket() */
+
+
+/* sa1100_pcmcia_get_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetIOMap in Card Services). Just returns an
+ * I/O map descriptor which was assigned earlier by a set_io_map().
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int sa1100_pcmcia_get_io_map(unsigned int sock,
+ struct pccard_io_map *map){
+
+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ if(map->map>=MAX_IO_WIN){
+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+ map->map);


+ return -1;
+ }
+

+ *map=sa1100_pcmcia_socket[sock].io_map[map->map];
+


+ return 0;
+}
+

+
+/* sa1100_pcmcia_set_io_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetIOMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int sa1100_pcmcia_set_io_map(unsigned int sock,
+ struct pccard_io_map *map){
+ unsigned int clock, speed;
+ unsigned long mecr, start;
+
+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+
+ DEBUG(4, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n"
+ "\tflags: %s%s%s%s%s%s%s%s\n",


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 34'
echo 'File patch-2.4.13 is continued in part 35'
echo "35" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:05 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part35

#!/bin/sh -x
# this is part 35 of a 53 - part archive


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

if test "$Scheck" != 35; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ map->map, map->speed, map->start, map->stop,
+ (map->flags==0)?"<NONE>":"",
+ (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+ (map->flags&MAP_16BIT)?"16BIT ":"",
+ (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+ (map->flags&MAP_0WS)?"0WS ":"",
+ (map->flags&MAP_WRPROT)?"WRPROT ":"",
+ (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
+ (map->flags&MAP_PREFETCH)?"PREFETCH ":"");


+
+ if(map->map>=MAX_IO_WIN){
+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+ map->map);
+ return -1;
+ }
+

+ if(map->flags&MAP_ACTIVE){
+
+ speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS;


+
+ clock = get_cclk_frequency() * 100;
+

+ mecr=MECR;
+
+ MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+
+ sa1100_pcmcia_socket[sock].speed_io=speed;
+
+ DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
+ __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+ MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
+ sock, MECR_BSIO_GET(mecr, sock));
+
+ MECR=mecr;
+
+ }
+
+ start=map->start;
+
+ if(map->stop==1)
+ map->stop=PAGE_SIZE-1;
+
+ map->start=sa1100_pcmcia_socket[sock].virt_io;
+ map->stop=map->start+(map->stop-start);
+
+ sa1100_pcmcia_socket[sock].io_map[map->map]=*map;


+
+ return 0;
+

+} /* sa1100_pcmcia_set_io_map() */
+
+
+/* sa1100_pcmcia_get_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the get_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetMemMap in Card Services). Just returns a
+ * memory map descriptor which was assigned earlier by a
+ * set_mem_map() request.


+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */

+static int sa1100_pcmcia_get_mem_map(unsigned int sock,

+ struct pccard_mem_map *map){


+
+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+

+ if(map->map>=MAX_WIN){


+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+ map->map);
+ return -1;
+ }
+

+ *map=sa1100_pcmcia_socket[sock].mem_map[map->map];


+
+ return 0;
+}
+
+

+/* sa1100_pcmcia_set_mem_map()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the set_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetMemMap in Card Services). We configure


+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */

+static int sa1100_pcmcia_set_mem_map(unsigned int sock,

+ struct pccard_mem_map *map){


+ unsigned int clock, speed;
+ unsigned long mecr, start;
+
+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+

+ DEBUG(4, "\tmap %u speed %u\n\tsys_start %#lx\n"
+ "\tsys_stop %#lx\n\tcard_start %#x\n"


+ "\tflags: %s%s%s%s%s%s%s%s\n",

+ map->map, map->speed, map->sys_start, map->sys_stop,
+ map->card_start, (map->flags==0)?"<NONE>":"",
+ (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
+ (map->flags&MAP_16BIT)?"16BIT ":"",
+ (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
+ (map->flags&MAP_0WS)?"0WS ":"",
+ (map->flags&MAP_WRPROT)?"WRPROT ":"",
+ (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
+ (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
+
+ if(map->map>=MAX_WIN){


+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+ map->map);
+ return -1;
+ }
+

+ if(map->flags&MAP_ACTIVE){
+
+ /* When clients issue RequestMap, the access speed is not always
+ * properly configured:
+ */
+ if(map->speed > 0)
+ speed = map->speed;
+ else
+ switch(sa1100_pcmcia_socket[sock].cs_state.Vcc){
+ case 33:
+ speed = SA1100_PCMCIA_3V_MEM_ACCESS;
+ break;
+ default:
+ speed = SA1100_PCMCIA_5V_MEM_ACCESS;
+ }


+
+ clock = get_cclk_frequency() * 100;
+

+ mecr=MECR;
+
+ if(map->flags&MAP_ATTRIB){
+
+ MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+ sa1100_pcmcia_socket[sock].speed_attr=speed;
+
+ } else {
+
+ MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
+ sa1100_pcmcia_socket[sock].speed_mem=speed;
+
+ }
+
+ DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
+ __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
+ MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
+ sock, MECR_BSIO_GET(mecr, sock));
+
+ MECR=mecr;
+
+ }
+
+ start=map->sys_start;
+
+ if(map->sys_stop==0)
+ map->sys_stop=PAGE_SIZE-1;
+
+ map->sys_start=(map->flags & MAP_ATTRIB)?\
+ sa1100_pcmcia_socket[sock].phys_attr:\
+ sa1100_pcmcia_socket[sock].phys_mem;
+
+ map->sys_stop=map->sys_start+(map->sys_stop-start);
+
+ sa1100_pcmcia_socket[sock].mem_map[map->map]=*map;


+
+ return 0;
+

+} /* sa1100_pcmcia_set_mem_map() */
+
+
+#if defined(CONFIG_PROC_FS)
+
+/* sa1100_pcmcia_proc_setup()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the proc_setup() operation for the in-kernel PCMCIA
+ * service (formerly SS_ProcSetup in Card Services).


+ *
+ * Returns: 0 on success, -1 on error
+ */

+static void sa1100_pcmcia_proc_setup(unsigned int sock,

+ struct proc_dir_entry *base){
+ struct proc_dir_entry *entry;


+
+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
+

+ if((entry=create_proc_entry("status", 0, base))==NULL){
+ printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+ return;
+ }
+
+ entry->read_proc=sa1100_pcmcia_proc_status;
+ entry->data=(void *)sock;
+}
+
+
+/* sa1100_pcmcia_proc_status()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Implements the /proc/bus/pccard/??/status file.
+ *
+ * Returns: the number of characters added to the buffer
+ */


+static int sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,

+ int count, int *eof, void *data){
+ char *p=buf;
+ unsigned int sock=(unsigned int)data;
+ unsigned int clock = get_cclk_frequency() * 100;
+ unsigned long mecr = MECR;
+
+ p+=sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
+ sa1100_pcmcia_socket[sock].k_state.detect?"detect ":"",
+ sa1100_pcmcia_socket[sock].k_state.ready?"ready ":"",
+ sa1100_pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
+ sa1100_pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
+ sa1100_pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
+ sa1100_pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
+ sa1100_pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+
+ p+=sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n",
+ sa1100_pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
+ sa1100_pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
+ sa1100_pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+ "SS_IOCARD ":"",
+ (sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
+ sa1100_pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
+ ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+ (sa1100_pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
+ ((sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+ (sa1100_pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
+ sa1100_pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
+ sa1100_pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+
+ p+=sprintf(p, "mask : %s%s%s%s%s\n",
+ sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
+ "SS_DETECT ":"",
+ sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
+ "SS_READY ":"",
+ sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
+ "SS_BATDEAD ":"",
+ sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
+ "SS_BATWARN ":"",
+ sa1100_pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
+ "SS_STSCHG ":"");
+
+ p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
+ "SS_PWR_AUTO ":"",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+ "SS_IOCARD ":"",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_RESET?\
+ "SS_RESET ":"",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
+ "SS_SPKR_ENA ":"",
+ sa1100_pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
+ "SS_OUTPUT_ENA ":"");
+
+ p+=sprintf(p, "Vcc : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vcc);
+
+ p+=sprintf(p, "Vpp : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vpp);
+
+ p+=sprintf(p, "irq : %d\n", sa1100_pcmcia_socket[sock].cs_state.io_irq);
+
+ p+=sprintf(p, "I/O : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_io,
+ sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
+
+ p+=sprintf(p, "attribute: %u (%u)\n", sa1100_pcmcia_socket[sock].speed_attr,
+ sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
+
+ p+=sprintf(p, "common : %u (%u)\n", sa1100_pcmcia_socket[sock].speed_mem,
+ sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
+
+ return p-buf;
+}
+
+#endif /* defined(CONFIG_PROC_FS) */
+
+
+#ifdef CONFIG_CPU_FREQ
+
+/* sa1100_pcmcia_update_mecr()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
+ * to a core clock frequency change) is needed, this routine establishes
+ * new BS_xx values consistent with the clock speed `clock'.
+ */
+static void sa1100_pcmcia_update_mecr(unsigned int clock){
+ unsigned int sock;
+ unsigned long mecr = MECR;
+
+ for(sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock){
+
+ MECR_BSIO_SET(mecr, sock,
+ sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_io,
+ clock));
+ MECR_BSA_SET(mecr, sock,
+ sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_attr,
+ clock));
+ MECR_BSM_SET(mecr, sock,
+ sa1100_pcmcia_mecr_bs(sa1100_pcmcia_socket[sock].speed_mem,
+ clock));
+ }
+
+ MECR = mecr;
+
+}
+
+/* sa1100_pcmcia_notifier()
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
+ * When changing the processor core clock frequency, it is necessary
+ * to adjust the MECR timings accordingly. We've recorded the timings
+ * requested by Card Services, so this is just a matter of finding
+ * out what our current speed is, and then recomputing the new MECR
+ * values.


+ *
+ * Returns: 0 on success, -1 on error
+ */

+static int sa1100_pcmcia_notifier(struct notifier_block *nb,
+ unsigned long val, void *data){
+ struct cpufreq_info *ci = data;
+
+ switch(val){
+ case CPUFREQ_MINMAX:
+
+ break;
+
+ case CPUFREQ_PRECHANGE:
+
+ if(ci->new_freq > ci->old_freq){
+ DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
+ __FUNCTION__,
+ ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+ ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+ sa1100_pcmcia_update_mecr(ci->new_freq);
+ }
+
+ break;
+
+ case CPUFREQ_POSTCHANGE:
+
+ if(ci->new_freq < ci->old_freq){
+ DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
+ __FUNCTION__,
+ ci->new_freq / 1000, (ci->new_freq / 100) % 10,
+ ci->old_freq / 1000, (ci->old_freq / 100) % 10);
+ sa1100_pcmcia_update_mecr(ci->new_freq);
+ }


+
+ break;
+
+ default:

+ printk(KERN_ERR "%s(): unknown CPU frequency event %lx\n", __FUNCTION__,
+ val);


+ return -1;
+
+ }
+

+ return 0;
+
+}
+

+static struct notifier_block sa1100_pcmcia_notifier_block = {
+ notifier_call: sa1100_pcmcia_notifier
+};
+
+#endif
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_graphicsclient.c linux/drivers/pcmcia/sa1100_graphicsclient.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_graphicsclient.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_graphicsclient.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,154 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsclient.c
+ *
+ * PCMCIA implementation routines for Graphics Client Plus
+ *
+ * 9/12/01 Woojung
+ * Turn power OFF at startup
+ * 1/31/2001 Woojung Huh
+ * Fix for GC Plus PCMCIA Reset Problem
+ * 2/27/2001 Woojung Huh [wh...@applieddata.net]
+ * Fix


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>

+#include <linux/delay.h>


+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+#define S0_CD_IRQ 60 // Socket 0 Card Detect IRQ
+#define S0_STS_IRQ 55 // Socket 0 PCMCIA IRQ
+
+static volatile unsigned long *PCMCIA_Status =
+ ((volatile unsigned long *) ADS_p2v(_ADS_CS_STATUS));
+
+static volatile unsigned long *PCMCIA_Power =
+ ((volatile unsigned long *) ADS_p2v(_ADS_CS_PR));
+
+static int gcplus_pcmcia_init(struct pcmcia_init *init)
+{
+ int irq, res;
+
+ // Reset PCMCIA
+ // Reset Timing for CPLD(U2) version 8001E or later
+ *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+ udelay(12); // 12 uSec
+
+ *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+ mdelay(30); // 30 mSec
+
+ // Turn off 5V
+ *PCMCIA_Power &= ~0x03;


+
+ /* Register interrupts */

+ irq = S0_CD_IRQ;
+ res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
+ if (res < 0) {
+ printk(KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq);


+ return -1;
+ }
+

+ return 1; // 1 PCMCIA Slot
+}
+
+static int gcplus_pcmcia_shutdown(void)


+{
+ /* disable IRQs */

+ free_irq( S0_CD_IRQ, NULL);
+
+ /* Shutdown PCMCIA power */
+ mdelay(2); // 2msec
+ *PCMCIA_Power &= ~0x03;


+
+ return 0;
+}
+

+static int gcplus_pcmcia_socket_state(struct pcmcia_state_array


+ *state_array){
+ unsigned long levels;
+

+ if(state_array->size<1) return -1;
+


+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+

+ levels=*PCMCIA_Status;
+
+ state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
+ state_array->state[0].ready=(levels & ADS_CS_ST_A_READY)?1:0;
+ state_array->state[0].bvd1= 0;
+ state_array->state[0].bvd2= 0;


+ state_array->state[0].wrprot=0;

+ state_array->state[0].vs_3v=0;


+ state_array->state[0].vs_Xv=0;
+
+ return 1;
+}
+

+static int gcplus_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+ if (info->sock > 1)
+ return -1;
+
+ if (info->sock == 0)
+ info->irq = S0_STS_IRQ;


+
+ return 0;
+}
+

+static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long flags;


+
+ if(configure->sock>1) return -1;
+

+ save_flags_cli(flags);
+
+ switch (configure->vcc) {
+ case 0:
+ *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);


+ break;
+
+ case 50:

+ *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+ *PCMCIA_Power |= ADS_CS_PR_A_5V_POWER;


+ break;
+
+ case 33:

+ *PCMCIA_Power &= ~(ADS_CS_PR_A_3V_POWER | ADS_CS_PR_A_5V_POWER);
+ *PCMCIA_Power |= ADS_CS_PR_A_3V_POWER;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);
+ return -1;
+ }
+

+ /* Silently ignore Vpp, output enable, speaker enable. */
+

+ // Reset PCMCIA
+ *PCMCIA_Power &= ~ ADS_CS_PR_A_RESET;
+ udelay(12);
+
+ *PCMCIA_Power |= ADS_CS_PR_A_RESET;
+ mdelay(30);


+
+ restore_flags(flags);
+
+ return 0;
+}
+

+struct pcmcia_low_level gcplus_pcmcia_ops = {
+ gcplus_pcmcia_init,
+ gcplus_pcmcia_shutdown,
+ gcplus_pcmcia_socket_state,
+ gcplus_pcmcia_get_irq_info,
+ gcplus_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_graphicsmaster.c linux/drivers/pcmcia/sa1100_graphicsmaster.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_graphicsmaster.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_graphicsmaster.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_graphicsmaster.c
+ *
+ * PCMCIA implementation routines for GraphicsMaster


+ *
+ * 9/18/01 Woojung
+ * Fixed wrong PCMCIA voltage setting
+ * 7/5/01 Woojung Huh <wh...@applieddata.net>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)

+static int graphicsmaster_pcmcia_shutdown(void)


+{
+
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &= ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+ return 0;
+}
+

+static int graphicsmaster_pcmcia_socket_state(struct pcmcia_state_array *state_array)

+static int graphicsmaster_pcmcia_get_irq_info(struct pcmcia_irq_info *info)


+{
+
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+

+static int graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *configure)

+ gpio |= GPIO_GPIO2 | GPIO_GPIO3;
+ break;
+


+ case 33:
+ pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);

+ gpio &= ~GPIO_GPIO2;


+ break;
+
+ case 50:
+ pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+ gpio |= GPIO_GPIO2;
+ break;
+

+struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
+ graphicsmaster_pcmcia_init,
+ graphicsmaster_pcmcia_shutdown,
+ graphicsmaster_pcmcia_socket_state,
+ graphicsmaster_pcmcia_get_irq_info,
+ graphicsmaster_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_h3600.c linux/drivers/pcmcia/sa1100_h3600.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_h3600.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_h3600.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,147 @@
+/*
+ * drivers/pcmcia/sa1100_h3600.c
+ *
+ * PCMCIA implementation routines for H3600


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+

+static int h3600_pcmcia_init(struct pcmcia_init *init){


+ int irq, res;
+
+ /* Enable CF bus: */

+ set_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON);
+ clr_h3600_egpio(EGPIO_H3600_OPT_RESET);


+
+ /* All those are inputs */

+ GPDR &= ~(GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1 | GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1);


+
+ /* Set transition detect */

+ set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1, GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_H3600_PCMCIA_IRQ0| GPIO_H3600_PCMCIA_IRQ1, GPIO_FALLING_EDGE );


+
+ /* Register interrupts */

+ irq = IRQ_GPIO_H3600_PCMCIA_CD0;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );


+ if( res < 0 ) goto irq_err;

+ irq = IRQ_GPIO_H3600_PCMCIA_CD1;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );


+ if( res < 0 ) goto irq_err;
+

+ return 2;
+
+irq_err:

+ printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );


+ return -1;
+}
+

+static int h3600_pcmcia_shutdown(void)


+{
+ /* disable IRQs */

+ free_irq( IRQ_GPIO_H3600_PCMCIA_CD0, NULL );
+ free_irq( IRQ_GPIO_H3600_PCMCIA_CD1, NULL );


+
+ /* Disable CF bus: */

+ clr_h3600_egpio(EGPIO_H3600_OPT_NVRAM_ON|EGPIO_H3600_OPT_ON);
+ set_h3600_egpio(EGPIO_H3600_OPT_RESET);


+
+ return 0;
+}
+

+static int h3600_pcmcia_socket_state(struct pcmcia_state_array


+ *state_array){
+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;
+

+ state_array->state[0].detect=((levels & GPIO_H3600_PCMCIA_CD0)==0)?1:0;
+ state_array->state[0].ready=(levels & GPIO_H3600_PCMCIA_IRQ0)?1:0;
+ state_array->state[0].bvd1= 0;
+ state_array->state[0].bvd2= 0;
+ state_array->state[0].wrprot=0; /* Not available on H3600. */
+ state_array->state[0].vs_3v=0;


+ state_array->state[0].vs_Xv=0;
+

+ state_array->state[1].detect=((levels & GPIO_H3600_PCMCIA_CD1)==0)?1:0;
+ state_array->state[1].ready=(levels & GPIO_H3600_PCMCIA_IRQ1)?1:0;
+ state_array->state[1].bvd1=0;
+ state_array->state[1].bvd2=0;
+ state_array->state[1].wrprot=0; /* Not available on H3600. */
+ state_array->state[1].vs_3v=0;


+ state_array->state[1].vs_Xv=0;
+
+ return 1;
+}
+

+static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+
+ switch (info->sock) {
+ case 0:
+ info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ0;
+ break;
+ case 1:
+ info->irq=IRQ_GPIO_H3600_PCMCIA_IRQ1;
+ break;


+ default:
+ return -1;
+ }

+ return 0;
+}
+

+static int h3600_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long flags;


+
+ if(configure->sock>1) return -1;
+

+ save_flags_cli(flags);
+
+ switch (configure->vcc) {
+ case 0:
+ clr_h3600_egpio(EGPIO_H3600_OPT_ON);


+ break;
+
+ case 33:

+ case 50:
+ set_h3600_egpio(EGPIO_H3600_OPT_ON);


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);
+ return -1;
+ }
+
+ if (configure->reset)

+ set_h3600_egpio(EGPIO_H3600_CARD_RESET);
+ else
+ clr_h3600_egpio(EGPIO_H3600_CARD_RESET);


+
+ /* Silently ignore Vpp, output enable, speaker enable. */
+

+ restore_flags(flags);
+
+ return 0;
+}
+

+struct pcmcia_low_level h3600_pcmcia_ops = {
+ h3600_pcmcia_init,
+ h3600_pcmcia_shutdown,
+ h3600_pcmcia_socket_state,
+ h3600_pcmcia_get_irq_info,
+ h3600_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_jornada720.c linux/drivers/pcmcia/sa1100_jornada720.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_jornada720.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_jornada720.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,215 @@
+/*
+ * drivers/pcmcia/sa1100_jornada720.c
+ *
+ * Jornada720 PCMCIA specific routines


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+#define SOCKET0_POWER GPIO_GPIO0
+#define SOCKET0_3V GPIO_GPIO2
+#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
+#define SOCKET1_3V GPIO_GPIO3
+
+static int jornada720_pcmcia_init(struct pcmcia_init *init)


+{
+ int return_val=0;
+

+ GRER |= 0x00000002;
+ /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+ PA_DDR = 0;
+ PA_DWR = 0;
+ PA_SDR = 0;
+ PA_SSR = 0;
+
+ PB_DDR = 0;
+ PB_DWR = 0x01;
+ PB_SDR = 0;
+ PB_SSR = 0;
+
+ PC_DDR = 0x88;
+ PC_DWR = 0x20;
+ PC_SDR = 0;
+ PC_SSR = 0;
+
+ INTPOL1 |=
+ (1 << (S0_READY_NINT - SA1111_IRQ(32))) |


+ (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,

+ "Jornada720 PCMCIA (0) CD", NULL);


+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,

+ "Jornada720 CF (1) CD", NULL);


+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "Jornada720 PCMCIA (0) BVD1", NULL);


+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "Jornada720 CF (1) BVD1", NULL);
+


+ return (return_val<0) ? -1 : 2;
+}
+

+static int jornada720_pcmcia_shutdown(void)


+{
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &=

+ ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |


+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+ return 0;
+}
+

+static int jornada720_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array)


+{
+ unsigned long status;
+ int return_val=1;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));

+ status=PCSR;


+ state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
+ state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
+ state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
+ state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
+ state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
+ state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
+ state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
+ state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
+ state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
+ state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
+ state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
+ state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
+ state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
+ state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
+ return return_val;
+}
+

+static int jornada720_pcmcia_get_irq_info(struct pcmcia_irq_info *info)


+{
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;
+ break;
+
+ default:
+ return -1;
+ }

+ return 0;
+}
+

+static int jornada720_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure)
+{
+ unsigned long pccr=PCCR, gpio=PA_DWR;
+
+printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
+ configure->sock, configure->vcc, configure->vpp);


+ switch(configure->sock){
+ case 0:
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S0_FLT);

+ gpio&=~(SOCKET0_POWER | SOCKET0_3V);


+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;

+ gpio |= SOCKET0_POWER | SOCKET0_3V;


+ break;
+
+ case 50:
+ pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);

+ gpio = (gpio & ~SOCKET0_3V) | SOCKET0_POWER;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }

+ switch(configure->vpp){
+ case 0:
+ break;
+ case 50:
+ printk(KERN_ERR "%s(): 5.0 Vpp %u\n", __FUNCTION__,
+ configure->vpp);
+ break;
+ case 120:
+ printk(KERN_ERR "%s(): 12 Vpp %u\n", __FUNCTION__,
+ configure->vpp);
+ break;
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,


+ configure->vpp);
+ return -1;
+ }

+ pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+ break;
+
+ case 1:
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S1_FLT);

+ gpio &= ~(SOCKET1_POWER);


+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;

+ gpio |= SOCKET1_POWER;


+ break;
+
+ case 50:
+ pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);

+ gpio = (gpio & ~(SOCKET1_POWER)) | SOCKET1_POWER;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }

+ if(configure->vpp!=configure->vcc && configure->vpp!=0){
+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+ configure->vpp);
+ return -1;
+ }
+ pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);

+ break;


+ default:
+ return -1;
+ }

+ PCCR = pccr;
+ PA_DWR = gpio;
+ return 0;
+}
+

+struct pcmcia_low_level jornada720_pcmcia_ops = {
+ jornada720_pcmcia_init,
+ jornada720_pcmcia_shutdown,
+ jornada720_pcmcia_socket_state,
+ jornada720_pcmcia_get_irq_info,
+ jornada720_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_neponset.c linux/drivers/pcmcia/sa1100_neponset.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_neponset.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_neponset.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,248 @@
+/*
+ * drivers/pcmcia/sa1100_neponset.c
+ *
+ * Neponset PCMCIA specific routines


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int neponset_pcmcia_init(struct pcmcia_init *init){


+ int return_val=0;
+
+ /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+

+ /* MAX1600 to standby mode: */
+ PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+ NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
+
+ INTPOL1 |=
+ (1 << (S0_READY_NINT - SA1111_IRQ(32))) |


+ (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,

+ "Neponset PCMCIA (0) CD", NULL);


+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,

+ "Neponset CF (1) CD", NULL);


+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "Neponset PCMCIA (0) BVD1", NULL);


+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "Neponset CF (1) BVD1", NULL);
+


+ return (return_val<0) ? -1 : 2;
+}
+

+static int neponset_pcmcia_shutdown(void){


+
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &=

+ ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |


+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+ return 0;
+}
+

+static int neponset_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){

+static int neponset_pcmcia_get_irq_info(struct pcmcia_irq_info *info){


+
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+

+static int neponset_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure){
+ unsigned long pccr=PCCR, ncr=NCR_0, gpio=PA_DWR;
+
+ /* Neponset uses the Maxim MAX1600, with the following connections:
+ *
+ * MAX1600 Neponset
+ *
+ * A0VCC SA-1111 GPIO A<1>
+ * A1VCC SA-1111 GPIO A<0>
+ * A0VPP CPLD NCR A0VPP
+ * A1VPP CPLD NCR A1VPP
+ * B0VCC SA-1111 GPIO A<2>
+ * B1VCC SA-1111 GPIO A<3>
+ * B0VPP ground (slot B is CF)
+ * B1VPP ground (slot B is CF)
+ *
+ * VX VCC (5V)
+ * VY VCC3_3 (3.3V)
+ * 12INA 12V
+ * 12INB ground (slot B is CF)
+ *
+ * The MAX1600 CODE pin is tied to ground, placing the device in
+ * "Standard Intel code" mode. Refer to the Maxim data sheet for
+ * the corresponding truth table.
+ */


+
+ switch(configure->sock){
+ case 0:
+
+ switch(configure->vcc){
+ case 0:
+ pccr=(pccr & ~PCCR_S0_FLT);

+ gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);


+ break;
+
+ case 33:

+ pccr=(pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
+ gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+ break;
+
+ case 50:
+ pccr=(pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
+ gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }
+

+ switch(configure->vpp){
+ case 0:
+ ncr&=~(NCR_A0VPP | NCR_A1VPP);
+ break;
+
+ case 120:
+ ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A1VPP;


+ break;
+
+ default:

+ if(configure->vpp == configure->vcc)
+ ncr=(ncr & ~(NCR_A0VPP | NCR_A1VPP)) | NCR_A0VPP;
+ else {
+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,


+ configure->vpp);
+ return -1;
+ }
+ }
+

+ pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+
+ break;
+
+ case 1:
+ switch(configure->vcc){
+ case 0:
+ pccr=(pccr & ~PCCR_S1_FLT);

+ gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);


+ break;
+
+ case 33:

+ pccr=(pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
+ gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;


+ break;
+
+ case 50:
+ pccr=(pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);

+ gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }
+
+ if(configure->vpp!=configure->vcc && configure->vpp!=0){
+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+ configure->vpp);
+ return -1;
+ }
+
+ pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);
+
+ break;
+
+ default:
+ return -1;
+ }
+
+ PCCR = pccr;

+ NCR_0 = ncr;


+ PA_DWR = gpio;
+
+ return 0;
+}
+

+struct pcmcia_low_level neponset_pcmcia_ops = {
+ neponset_pcmcia_init,
+ neponset_pcmcia_shutdown,
+ neponset_pcmcia_socket_state,
+ neponset_pcmcia_get_irq_info,
+ neponset_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_pangolin.c linux/drivers/pcmcia/sa1100_pangolin.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_pangolin.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_pangolin.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,157 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for Pangolin


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int pangolin_pcmcia_init(struct pcmcia_init *init){


+ int irq, res;
+

+ /* set GPIO_PCMCIA_CD & GPIO_PCMCIA_IRQ as inputs */
+ GPDR &= ~(GPIO_PCMCIA_CD|GPIO_PCMCIA_IRQ);
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+ /* set GPIO pins GPIO_PCMCIA_BUS_ON & GPIO_PCMCIA_RESET as output */
+ GPDR |= (GPIO_PCMCIA_BUS_ON|GPIO_PCMCIA_RESET);
+ /* Enable PCMCIA bus: */
+ GPCR = GPIO_PCMCIA_BUS_ON;
+#else
+ /* set GPIO pin GPIO_PCMCIA_RESET as output */
+ GPDR |= GPIO_PCMCIA_RESET;
+#endif


+ /* Set transition detect */

+ set_GPIO_IRQ_edge( GPIO_PCMCIA_CD, GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_PCMCIA_IRQ, GPIO_FALLING_EDGE );


+
+ /* Register interrupts */

+ irq = IRQ_PCMCIA_CD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD", NULL );


+ if( res < 0 ) goto irq_err;
+
+ /* There's only one slot, but it's "Slot 1": */
+ return 2;
+
+irq_err:
+ printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+ return -1;
+}
+

+static int pangolin_pcmcia_shutdown(void)


+{
+ /* disable IRQs */

+ free_irq( IRQ_PCMCIA_CD, NULL );
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+ /* Disable PCMCIA bus: */
+ GPSR = GPIO_PCMCIA_BUS_ON;
+#endif


+ return 0;
+}
+

+static int pangolin_pcmcia_socket_state(struct pcmcia_state_array


+ *state_array){
+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;

+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+ state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+ state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+ state_array->state[1].bvd1=1; /* Not available on Pangolin. */
+ state_array->state[1].bvd2=1; /* Not available on Pangolin. */
+ state_array->state[1].wrprot=0; /* Not available on Pangolin. */
+ state_array->state[1].vs_3v=1; /* Can only apply 3.3V on Pangolin. */


+ state_array->state[1].vs_Xv=0;

+#else
+ state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+ state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+ state_array->state[0].bvd1=1; /* Not available on Pangolin. */
+ state_array->state[0].bvd2=1; /* Not available on Pangolin. */
+ state_array->state[0].wrprot=0; /* Not available on Pangolin. */
+ state_array->state[0].vs_3v=0; /* voltage level is determined by jumper setting */


+ state_array->state[0].vs_Xv=0;

+#endif


+ return 1;
+}
+

+static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){


+
+ if(info->sock>1) return -1;

+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+ if(info->sock==1)
+ info->irq=IRQ_PCMCIA_IRQ;
+#else
+ if(info->sock==0)
+ info->irq=IRQ_PCMCIA_IRQ;
+#endif


+ return 0;
+}
+

+static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure


+ *configure)
+{
+ unsigned long value, flags;
+
+ if(configure->sock>1) return -1;

+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE


+ if(configure->sock==0) return 0;

+#endif
+ save_flags_cli(flags);
+
+ /* Murphy: BUS_ON different from POWER ? */


+
+ switch(configure->vcc){
+ case 0:

+ break;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE


+ case 50:
+ printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
+ __FUNCTION__);
+ case 33: /* Can only apply 3.3V to the CF slot. */

+ break;
+#else
+ case 50:
+ printk(KERN_WARNING "%s(): CS asked for 5V, determinded by jumper setting...\n", __FUNCTION__);
+ break;
+ case 33:
+ printk(KERN_WARNING "%s(): CS asked for 3.3V, determined by jumper setting...\n", __FUNCTION__);
+ break;
+#endif


+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);
+ return -1;
+ }

+#ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+ /* reset & unreset request */
+ if(configure->sock==0) {
+ if(configure->reset) {
+ GPSR |= GPIO_PCMCIA_RESET;
+ } else {
+ GPCR |= GPIO_PCMCIA_RESET;
+ }
+ }
+#endif


+ /* Silently ignore Vpp, output enable, speaker enable. */

+ restore_flags(flags);


+ return 0;
+}
+

+struct pcmcia_low_level pangolin_pcmcia_ops = {
+ pangolin_pcmcia_init,
+ pangolin_pcmcia_shutdown,
+ pangolin_pcmcia_socket_state,
+ pangolin_pcmcia_get_irq_info,
+ pangolin_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_pfs168.c linux/drivers/pcmcia/sa1100_pfs168.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_pfs168.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_pfs168.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,237 @@
+#warning "REVISIT_PFS168: Need to verify and test GPIO power encodings."
+/*
+ * drivers/pcmcia/sa1100_pfs168.c
+ *
+ * PFS168 PCMCIA specific routines


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int pfs168_pcmcia_init(struct pcmcia_init *init){
+ int return_val=0;
+
+ /* TPS2211 to standby mode: */
+ PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+ /* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller: */


+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+

+ INTPOL1 |=
+ (1 << (S0_READY_NINT - SA1111_IRQ(32))) |


+ (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,

+ "PFS168 PCMCIA (0) CD", NULL);


+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,

+ "PFS168 CF (1) CD", NULL);


+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "PFS168 PCMCIA (0) BVD1", NULL);


+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "PFS168 CF (1) BVD1", NULL);
+


+ return (return_val<0) ? -1 : 2;
+}
+

+static int pfs168_pcmcia_shutdown(void){


+
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &=

+ ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |


+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+ return 0;
+}
+

+static int pfs168_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array){

+static int pfs168_pcmcia_get_irq_info(struct pcmcia_irq_info *info){


+
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+

+static int pfs168_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure){


+ unsigned long pccr=PCCR, gpio=PA_DWR;
+

+ /* PFS168 uses the Texas Instruments TPS2211 for PCMCIA (socket 0) voltage control only,
+ * with the following connections:
+ *
+ * TPS2211 PFS168
+ *
+ * -VCCD0 SA-1111 GPIO A<0>
+ * -VCCD0 SA-1111 GPIO A<1>
+ * VPPD0 SA-1111 GPIO A<2>
+ * VPPD0 SA-1111 GPIO A<2>
+ *
+ */


+
+ switch(configure->sock){
+ case 0:
+
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S0_FLT);

+ gpio &= ~(GPIO_GPIO0 | GPIO_GPIO1);


+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;

+ gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0;
+ break;
+


+ case 50:
+ pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);

+ gpio = (gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+ break;
+


+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }
+

+ switch(configure->vpp){
+ case 0:


+ gpio &= ~(GPIO_GPIO2 | GPIO_GPIO3);
+ break;
+

+ case 120:
+ printk(KERN_ERR "%s(): PFS-168 does not support Vpp %uV\n", __FUNCTION__,
+ configure->vpp/10);
+ return -1;


+ break;
+
+ default:

+ if(configure->vpp == configure->vcc)
+ gpio = (gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+ else {
+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__,


+ configure->vpp);
+ return -1;
+ }
+ }
+

+ pccr = (configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST);
+


+ PA_DWR = gpio;
+

+ break;
+
+ case 1:
+ switch(configure->vcc){
+ case 0:
+ pccr = (pccr & ~PCCR_S1_FLT);

+ break;
+
+ case 33:
+ pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;

+ break;
+
+ case 50:

+ printk(KERN_ERR "%s(): PFS-168 CompactFlash socket does not support Vcc %uV\n", __FUNCTION__,
+ configure->vcc/10);
+ return -1;


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }
+
+ if(configure->vpp!=configure->vcc && configure->vpp!=0){

+ printk(KERN_ERR "%s(): CompactFlash socket does not support Vpp %uV\n", __FUNCTION__,
+ configure->vpp/10);


+ return -1;
+ }
+

+ pccr = (configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);


+
+ break;
+
+ default:
+ return -1;
+ }
+
+ PCCR = pccr;
+

+ return 0;
+}
+

+struct pcmcia_low_level pfs168_pcmcia_ops = {
+ pfs168_pcmcia_init,
+ pfs168_pcmcia_shutdown,
+ pfs168_pcmcia_socket_state,
+ pfs168_pcmcia_get_irq_info,
+ pfs168_pcmcia_configure_socket
+};
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_simpad.c linux/drivers/pcmcia/sa1100_simpad.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_simpad.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_simpad.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,136 @@
+/*
+ * drivers/pcmcia/sa1100_pangolin.c
+ *
+ * PCMCIA implementation routines for simpad


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int simpad_pcmcia_init(struct pcmcia_init *init){


+ int irq, res;
+

+ /* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
+ GPDR &= ~(GPIO_CF_CD|GPIO_CF_IRQ);
+ //init_simpad_cs3();
+ printk("\nCS3:%x\n",cs3_shadow);
+ PCMCIA_setbit(PCMCIA_RESET);
+ PCMCIA_clearbit(PCMCIA_BUFF_DIS);


+
+ /* Set transition detect */

+ set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_BOTH_EDGES );


+ set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
+
+ /* Register interrupts */
+ irq = IRQ_GPIO_CF_CD;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+ if( res < 0 ) goto irq_err;
+

+ /* There's only one slot, but it's "Slot 1": */
+ return 2;
+
+irq_err:
+ printk( KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq );
+ return -1;
+}
+

+static int simpad_pcmcia_shutdown(void)


+{
+ /* disable IRQs */
+ free_irq( IRQ_GPIO_CF_CD, NULL );
+

+ /* Disable CF bus: */
+

+ PCMCIA_setbit(PCMCIA_BUFF_DIS);
+ PCMCIA_clearbit(PCMCIA_RESET);


+ return 0;
+}
+

+static int simpad_pcmcia_socket_state(struct pcmcia_state_array
+ *state_array)
+{


+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;
+
+ state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
+
+ state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
+

+ state_array->state[1].bvd1=1; /* Not available on Simpad. */
+
+ state_array->state[1].bvd2=1; /* Not available on Simpad. */
+
+ state_array->state[1].wrprot=0; /* Not available on Simpad. */
+
+ state_array->state[1].vs_3v=1; /* Can only apply 3.3V on Simpad. */


+
+ state_array->state[1].vs_Xv=0;
+
+ return 1;
+}
+

+static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){


+
+ if(info->sock>1) return -1;
+
+ if(info->sock==1)
+ info->irq=IRQ_GPIO_CF_IRQ;
+
+ return 0;
+}
+

+static int simpad_pcmcia_configure_socket(const struct pcmcia_configure


+ *configure)
+{
+ unsigned long value, flags;
+
+ if(configure->sock>1) return -1;
+
+ if(configure->sock==0) return 0;
+
+ save_flags_cli(flags);
+

+ /* Murphy: BUS_ON different from POWER ? */


+
+ switch(configure->vcc){
+ case 0:

+ PCMCIA_setbit(PCMCIA_BUFF_DIS);


+ break;
+
+ case 33:

+ case 50:
+ PCMCIA_setbit(PCMCIA_BUFF_DIS);


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);
+ return -1;
+ }
+

+ /* Silently ignore Vpp, output enable, speaker enable. */
+

+ restore_flags(flags);
+
+ return 0;
+}
+

+struct pcmcia_low_level simpad_pcmcia_ops = {
+ simpad_pcmcia_init,
+ simpad_pcmcia_shutdown,
+ simpad_pcmcia_socket_state,
+ simpad_pcmcia_get_irq_info,
+ simpad_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_stork.c linux/drivers/pcmcia/sa1100_stork.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_stork.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_stork.c Thu Oct 11 09:43:29 2001


@@ -0,0 +1,202 @@
+/*

+ * drivers/pcmcia/sa1100_stork.c
+ *
+ Copyright 2001 (C) Ken Gordon
+
+ This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
+
+ 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.
+
+ 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.
+
+ *
+ * PCMCIA implementation routines for stork
+ *


+ */
+
+#include <linux/config.h>

+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>


+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+static int debug = 0;
+

+static struct pcmcia_init sa1100_stork_pcmcia_init;
+
+static int stork_pcmcia_init(struct pcmcia_init *init)
+{
+ int irq, res;
+ printk("in stork_pcmcia_init\n");
+
+ sa1100_stork_pcmcia_init = *init;


+
+ /* Enable CF bus: */

+ storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);


+
+ /* All those are inputs */

+ GPDR &= ~(GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT | GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY);


+
+ /* Set transition detect */

+ set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );


+
+ /* Register interrupts */

+ irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );


+ if( res < 0 ) goto irq_err;

+ irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
+ res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );


+ if( res < 0 ) goto irq_err;
+

+ return 2;
+
+ irq_err:
+ printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );


+ return -1;
+}
+

+static int stork_pcmcia_shutdown(void)
+{
+ printk(__FUNCTION__ "\n");


+ /* disable IRQs */

+ free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
+ free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );


+
+ /* Disable CF bus: */

+ storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+ storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
+ storkClearLatchA(STORK_PCMCIA_B_POWER_ON);


+ return 0;
+}
+

+static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+{


+ unsigned long levels;
+
+ if(state_array->size<2) return -1;
+
+ memset(state_array->state, 0,
+ (state_array->size)*sizeof(struct pcmcia_state));
+
+ levels=GPLR;
+

+ if (debug > 1)
+ printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
+ state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
+ state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
+ state_array->state[0].bvd1= 1;
+ state_array->state[0].bvd2= 1;


+ state_array->state[0].wrprot=0;

+ state_array->state[0].vs_3v=1;

+ state_array->state[0].vs_Xv=0;
+

+ state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
+ state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
+ state_array->state[1].bvd1=1;
+ state_array->state[1].bvd2=1;


+ state_array->state[1].wrprot=0;

+ state_array->state[1].vs_3v=1;

+ state_array->state[1].vs_Xv=0;
+
+ return 1;
+}
+

+static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+ switch (info->sock) {
+ case 0:
+ info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
+ break;
+ case 1:
+ info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
+ break;


+ default:
+ return -1;
+ }

+ return 0;
+}
+

+static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+ int card = configure->sock;


+ unsigned long flags;
+

+ int DETECT, RDY, POWER, RESET;
+
+ if (card > 1) return -1;
+
+ printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n",
+ card, configure->vcc, configure->vpp, configure->reset);
+
+ save_flags_cli(flags);
+
+ if (card == 0) {
+ DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
+ RDY = GPIO_STORK_PCMCIA_A_RDY;
+ POWER = STORK_PCMCIA_A_POWER_ON;
+ RESET = STORK_PCMCIA_A_RESET;
+ } else {
+ DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
+ RDY = GPIO_STORK_PCMCIA_B_RDY;
+ POWER = STORK_PCMCIA_B_POWER_ON;
+ RESET = STORK_PCMCIA_B_RESET;
+ }
+
+/*
+ if (storkTestGPIO(DETECT)) {
+ printk("no card detected - but resetting anyway\r\n");
+ }
+*/
+ switch (configure->vcc) {
+ case 0:
+ storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+ storkClearLatchA(POWER);


+ break;
+
+ case 50:

+ case 33:


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 35'
echo 'File patch-2.4.13 is continued in part 36'
echo "36" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:06 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part36

#!/bin/sh -x
# this is part 36 of a 53 - part archive


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

if test "$Scheck" != 36; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
+ storkSetLatchA(POWER);


+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ restore_flags(flags);
+ return -1;
+ }
+
+ if (configure->reset)

+ storkSetLatchB(RESET);
+ else
+ storkClearLatchB(RESET);
+
+ restore_flags(flags);
+
+ /* silently ignore vpp and speaker enables. */
+
+ printk(__FUNCTION__ ": finished\n");


+
+ return 0;
+}
+

+struct pcmcia_low_level stork_pcmcia_ops = {
+ stork_pcmcia_init,
+ stork_pcmcia_shutdown,
+ stork_pcmcia_socket_state,
+ stork_pcmcia_get_irq_info,
+ stork_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_xp860.c linux/drivers/pcmcia/sa1100_xp860.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_xp860.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_xp860.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,255 @@
+/*
+ * drivers/pcmcia/sa1100_xp860.c
+ *
+ * XP860 PCMCIA specific routines


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

+#include <linux/delay.h>


+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+

+#define NCR_A0VPP (1<<16)
+#define NCR_A1VPP (1<<17)
+
+static int xp860_pcmcia_init(struct pcmcia_init *init){


+ int return_val=0;
+
+ /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
+
+ /* MAX1600 to standby mode: */
+ PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);

+ GPDR |= (NCR_A0VPP | NCR_A1VPP);
+ GPCR &= ~(NCR_A0VPP | NCR_A1VPP);


+
+ INTPOL1 |=
+ (1 << (S0_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S1_READY_NINT - SA1111_IRQ(32))) |
+ (1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32)));
+
+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,

+ "XP860 PCMCIA (0) CD", NULL);


+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,

+ "XP860 CF (1) CD", NULL);


+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "XP860 PCMCIA (0) BVD1", NULL);


+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,

+ "XP860 CF (1) BVD1", NULL);


+
+ return (return_val<0) ? -1 : 2;
+}
+

+static int xp860_pcmcia_shutdown(void){


+
+ free_irq(S0_CD_VALID, NULL);
+ free_irq(S1_CD_VALID, NULL);
+ free_irq(S0_BVD1_STSCHG, NULL);
+ free_irq(S1_BVD1_STSCHG, NULL);
+
+ INTPOL1 &=
+ ~((1 << (S0_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S1_CD_VALID - SA1111_IRQ(32))) |
+ (1 << (S0_BVD1_STSCHG - SA1111_IRQ(32))) |
+ (1 << (S1_BVD1_STSCHG - SA1111_IRQ(32))));
+
+ return 0;
+}
+

+static int xp860_pcmcia_socket_state(struct pcmcia_state_array

+static int xp860_pcmcia_get_irq_info(struct pcmcia_irq_info *info){


+
+ switch(info->sock){
+ case 0:
+ info->irq=S0_READY_NINT;
+ break;
+
+ case 1:
+ info->irq=S1_READY_NINT;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+

+static int xp860_pcmcia_configure_socket(const struct pcmcia_configure
+ *configure){
+ unsigned long pccr=PCCR, ncr=GPLR, gpio=PA_DWR;
+

+ gpio&=~(GPIO_GPIO0 | GPIO_GPIO1);
+ break;
+
+ case 33:

+ pccr=(pccr & ~PCCR_S0_PSE);


+ gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1;
+ break;
+
+ case 50:

+ pccr=(pccr | PCCR_S0_PSE);

+ pccr=(configure->output)?(pccr | PCCR_S0_FLT):(pccr & ~PCCR_S0_FLT);


+
+ break;
+
+ case 1:
+ switch(configure->vcc){
+ case 0:

+ gpio&=~(GPIO_GPIO2 | GPIO_GPIO3);
+ break;
+
+ case 33:

+ pccr=(pccr & ~PCCR_S1_PSE);


+ gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2;
+ break;
+
+ case 50:

+ pccr=(pccr | PCCR_S1_PSE);


+ gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3;
+ break;
+
+ default:
+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+ configure->vcc);
+ return -1;
+ }
+
+ if(configure->vpp!=configure->vcc && configure->vpp!=0){
+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__,
+ configure->vpp);
+ return -1;
+ }
+
+ pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST);

+ pccr=(configure->output)?(pccr | PCCR_S1_FLT):(pccr & ~PCCR_S1_FLT);


+
+ break;
+
+ default:
+ return -1;
+ }
+
+ PCCR = pccr;

+ ncr &= NCR_A0VPP|NCR_A1VPP;
+ GPSR = ncr;
+ GPCR = (~ncr)&(NCR_A0VPP|NCR_A1VPP);


+ PA_DWR = gpio;
+
+ return 0;
+}
+

+struct pcmcia_low_level xp860_pcmcia_ops = {
+ xp860_pcmcia_init,
+ xp860_pcmcia_shutdown,
+ xp860_pcmcia_socket_state,
+ xp860_pcmcia_get_irq_info,
+ xp860_pcmcia_configure_socket
+};
+
diff -u --recursive --new-file v2.4.12/linux/drivers/pcmcia/sa1100_yopy.c linux/drivers/pcmcia/sa1100_yopy.c
--- v2.4.12/linux/drivers/pcmcia/sa1100_yopy.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/pcmcia/sa1100_yopy.c Thu Oct 11 09:43:29 2001
@@ -0,0 +1,139 @@
+/*
+ * drivers/pcmcia/sa1100_yopy.c
+ *
+ * PCMCIA implementation routines for Yopy


+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pcmcia.h>
+
+

+static inline void pcmcia_power(int on) {
+ /* high for power up */
+ yopy_gpio_set(GPIO_CF_POWER, on);
+}
+
+static inline void pcmcia_reset(int reset)
+{
+ /* high for reset */
+ yopy_gpio_set(GPIO_CF_RESET, reset);
+}
+
+static int yopy_pcmcia_init(struct pcmcia_init *init)


+{
+ int irq, res;
+

+ pcmcia_power(0);
+ pcmcia_reset(1);


+
+ /* All those are inputs */

+ GPDR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);
+ GAFR &= ~(GPIO_CF_CD | GPIO_CF_BVD2 | GPIO_CF_BVD1 | GPIO_CF_IREQ);


+
+ /* Set transition detect */

+ set_GPIO_IRQ_edge( GPIO_CF_CD|GPIO_CF_BVD2|GPIO_CF_BVD1,
+ GPIO_BOTH_EDGES );
+ set_GPIO_IRQ_edge( GPIO_CF_IREQ, GPIO_FALLING_EDGE );


+
+ /* Register interrupts */

+ irq = IRQ_CF_CD;
+ res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_CD", NULL);
+ if (res < 0) goto irq_err;
+ irq = IRQ_CF_BVD2;
+ res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD2", NULL);
+ if (res < 0) goto irq_err;
+ irq = IRQ_CF_BVD1;
+ res = request_irq(irq, init->handler, SA_INTERRUPT, "CF_BVD1", NULL);
+ if (res < 0) goto irq_err;
+
+ return 1;
+irq_err:
+ printk(KERN_ERR "%s: Request for IRQ %d failed\n", __FUNCTION__, irq);


+ return -1;
+}
+

+static int yopy_pcmcia_shutdown(void)


+{
+ /* disable IRQs */

+ free_irq( IRQ_CF_CD, NULL );
+ free_irq( IRQ_CF_BVD2, NULL );
+ free_irq( IRQ_CF_BVD1, NULL );
+
+ /* Disable CF */
+ pcmcia_reset(1);
+ pcmcia_power(0);


+
+ return 0;
+}
+

+static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)


+{
+ unsigned long levels;
+

+ if (state_array->size != 1)
+ return -1;
+
+ memset(state_array->state, 0,
+ state_array->size * sizeof(struct pcmcia_state));
+
+ levels = GPLR;
+
+ state_array->state[0].detect = (levels & GPIO_CF_CD) ? 0 : 1;
+ state_array->state[0].ready = (levels & GPIO_CF_READY) ? 1 : 0;
+ state_array->state[0].bvd1 = (levels & GPIO_CF_BVD1) ? 1 : 0;
+ state_array->state[0].bvd2 = (levels & GPIO_CF_BVD2) ? 1 : 0;
+ state_array->state[0].wrprot = 0; /* Not available on Yopy. */
+ state_array->state[0].vs_3v = 0; /* FIXME Can only apply 3.3V on Yopy. */
+ state_array->state[0].vs_Xv = 0;


+
+ return 1;
+}
+

+static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+ if (info->sock != 0)
+ return -1;
+
+ info->irq = IRQ_CF_IREQ;


+
+ return 0;
+}
+

+static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+ if (configure->sock != 0)
+ return -1;
+
+ switch (configure->vcc) {
+ case 0: /* power off */;
+ pcmcia_power(0);


+ break;
+ case 50:

+ printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..\n");
+ case 33:
+ pcmcia_power(1);
+ break;
+ default:
+ printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %u\n",


+ configure->vcc);
+ return -1;
+ }
+

+ pcmcia_reset(configure->reset);


+
+ /* Silently ignore Vpp, output enable, speaker enable. */
+

+ return 0;
+}
+

+struct pcmcia_low_level yopy_pcmcia_ops = {
+ yopy_pcmcia_init,
+ yopy_pcmcia_shutdown,
+ yopy_pcmcia_socket_state,
+ yopy_pcmcia_get_irq_info,
+ yopy_pcmcia_configure_socket
+};
diff -u --recursive --new-file v2.4.12/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- v2.4.12/linux/drivers/pnp/isapnp.c Wed Jul 25 17:10:22 2001
+++ linux/drivers/pnp/isapnp.c Thu Oct 11 09:43:29 2001
@@ -87,6 +87,7 @@
X MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
X MODULE_PARM(isapnp_reserve_mem, "1-16i");
X MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
+MODULE_LICENSE("GPL");
X
X #define _PIDXR 0x279
X #define _PNPWRP 0xa79
@@ -1673,8 +1674,8 @@
X }
X isapnp_for_each_dev(dev) {
X if (dev->active) {
- if (dev->irq_resource[0].start == irq ||
- dev->irq_resource[1].start == irq)
+ if ((dev->irq_resource[0].flags && dev->irq_resource[0].start == irq) ||
+ (dev->irq_resource[1].flags && dev->irq_resource[1].start == irq))


X return 1;
X }
X }

@@ -1763,7 +1764,8 @@
X }
X isapnp_for_each_dev(dev) {
X if (dev->active) {
- if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
+ if ((dev->dma_resource[0].flags && dev->dma_resource[0].start == dma) ||
+ (dev->dma_resource[1].flags && dev->dma_resource[1].start == dma))


X return 1;
X }
X }

@@ -1784,6 +1786,10 @@
X
X static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
X {
+ /* DMA priority: this table is good for i386 */
+ static unsigned short xtab[16] = {
+ 1, 3, 5, 6, 7, 0, 2, 4
+ };
X int err, i;
X unsigned long *value1, *value2;
X struct isapnp_dma *dma;
@@ -1799,15 +1805,16 @@
X value1 = &cfg->result.dma_resource[idx].start;
X value2 = &cfg->result.dma_resource[idx].end;
X if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
- for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
+ for (i = 0; i < 8 && !(dma->map & (1<<xtab[i])); i++);
X if (i >= 8)
X return -ENOENT;
X cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
- if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
+ if (!isapnp_check_dma(cfg, *value1 = *value2 = xtab[i], idx))
X return 0;
X }
X do {
- for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
+ for (i = 0; i < 8 && xtab[i] != *value1; i++);
+ for (i++; i < 8 && !(dma->map & (1<<xtab[i])); i++);
X if (i >= 8) {
X if (dma->res && dma->res->alt) {
X if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)


@@ -1816,7 +1823,7 @@
X }

X return -ENOENT;
X } else {
- *value1 = *value2 = i;
+ *value1 = *value2 = xtab[i];
X }
X } while (isapnp_check_dma(cfg, *value1, idx));
X return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- v2.4.12/linux/drivers/s390/block/dasd.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/block/dasd.c Mon Oct 15 13:30:13 2001
@@ -1092,9 +1092,11 @@
X BUG ();
X }
X if (device->lowmem_cqr==NULL) {
- DASD_MESSAGE (KERN_WARNING, device,
- "Low memory! Using emergency request %p",
- device->lowmem_ccws);
+ DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+ "(%04x) Low memory! Using emergency request %p.",
+ device->devinfo.devno,
+ device->lowmem_ccws);
+
X device->lowmem_cqr=device->lowmem_ccws;
X rv = device->lowmem_ccws;
X memset (rv, 0, PAGE_SIZE);
@@ -1105,10 +1107,11 @@
X rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
X rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
X } else {
- DASD_MESSAGE (KERN_WARNING, device,
- "Refusing emergency mem for request "
- "NULL, already in use at %p.",
- device->lowmem_ccws);
+ DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
+ "(%04x) Refusing emergency mem for request "
+ "NULL, already in use at %p.",
+ device->devinfo.devno,
+ device->lowmem_ccws);
X }
X return rv;
X }
@@ -1219,6 +1222,7 @@
X CQR_STATUS_QUEUED);
X
X
+#ifdef DASD_PROFILE
X /* save profile information for non erp cqr */
X if (cqr->refers == NULL) {
X unsigned int counter = 0;
@@ -1235,6 +1239,7 @@
X dasd_global_profile.dasd_io_nr_req[counter]++;
X device->profile.dasd_io_nr_req[counter]++;
X }
+#endif
X }
X
X /*
@@ -1671,9 +1676,12 @@
X chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
X ccw_req_t *cqr = NULL;
X if (is_read_only(device->kdev) && req->cmd == WRITE) {
- DASD_MESSAGE (KERN_WARNING, device,
- "rejecting write request %p\n",
- req);
+
+ DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+ "(%04x) Rejecting write request %p\n",
+ device->devinfo.devno,
+ req);
+
X dasd_end_request (req, 0);
X dasd_dequeue_request (queue,req);
X } else {
@@ -1683,9 +1691,12 @@
X part[MINOR (req->rq_dev)].start_sect;
X cqr = device->discipline->build_cp_from_req (device, req);
X if (cqr == NULL) {
- DASD_MESSAGE (KERN_WARNING, device,
- "CCW creation failed on request %p\n",
- req);
+
+ DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
+ "(%04x) CCW creation failed "
+ "on request %p\n",
+ device->devinfo.devno,
+ req);
X /* revert relocation of request */
X req->sector -=
X device->major_info->gendisk.
@@ -2032,7 +2043,7 @@
X }
X
X erp->cpaddr->cmd_code = CCW_CMD_TIC;
- erp->cpaddr->cda = (__u32) (void *) cqr->cpaddr;
+ erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
X erp->function = dasd_default_erp_action;
X erp->refers = cqr;
X erp->device = cqr->device;
@@ -2232,13 +2243,7 @@
X }
X for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
X int major = device->major_info->gendisk.major;
- int minor = start + i;
- kdev_t devi = MKDEV (major, minor);
- struct super_block *sb = get_super (devi);
- //sync_dev (devi);
- if (sb)
- invalidate_inodes (sb);
- invalidate_buffers (devi);
+ invalidate_device(MKDEV (major, start+i), 1);
X }
X dasd_destroy_partitions(device);
X dasd_setup_partitions(device);
@@ -2285,20 +2290,20 @@
X #endif
X switch (no) {
X case DASDAPIVER: {
- int ver = DASD_API_VERSION;
- rc = copy_to_user ((int *) data, &ver, sizeof (int));
- if (rc)
- rc = -EFAULT;
- break;
+ int ver = DASD_API_VERSION;
+ rc = put_user(ver, (int *) data);
+ break;


X }
X case BLKGETSIZE:{ /* Return device size */

- long blocks = major_info->gendisk.sizes
- [MINOR (inp->i_rdev)] << 1;
- rc =
- copy_to_user ((long *) data, &blocks,
- sizeof (long));
- if (rc)
- rc = -EFAULT;
+ unsigned long blocks = major_info->gendisk.sizes
+ [MINOR (inp->i_rdev)] << 1;
+ rc = put_user(blocks, (unsigned long *) data);
+ break;
+ }
+ case BLKGETSIZE64:{
+ u64 blocks = major_info->gendisk.sizes
+ [MINOR (inp->i_rdev)];
+ rc = put_user(blocks << 10, (u64 *) data);
X break;
X }
X case BLKRRPART:{
@@ -3253,10 +3258,6 @@
X int rc = 0;


X unsigned long flags;
X

- printk (KERN_ERR PRINTK_HEADER
- "called dasd_state_accept_to_init for device %02x\n",
- device->devinfo.devno);
-
X if ( device->discipline->init_analysis ) {
X device->init_cqr=device->discipline->init_analysis (device);
X if ( device->init_cqr != NULL ) {
@@ -3297,8 +3298,10 @@
X rc = -EMEDIUMTYPE;
X }
X if ( device->init_cqr ) {
+ /* This pointer is no longer needed, BUT dont't free the */
+ /* memory, because this is done in bh for finished request!!!! */
X atomic_dec(&dasd_init_pending);
- device->init_cqr = NULL; /* This one is no longer needed */
+ device->init_cqr = NULL;
X }
X device->level = DASD_STATE_READY;
X return rc;
@@ -3378,7 +3381,6 @@
X dasd_deactivate_queue (dasd_device_t *device)
X {
X int i;
- int major = MAJOR(device->kdev);
X int minor = MINOR(device->kdev);
X
X for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
@@ -3764,7 +3766,14 @@
X vfree (buffer);
X return -EFAULT;
X }
- buffer[user_len] = 0;
+
+ /* replace LF with '\0' */
+ if (buffer[user_len -1] == '\n') {
+ buffer[user_len -1] = '\0';
+ } else {
+ buffer[user_len] = '\0';
+ }
+
X printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer);
X if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) {
X printk (KERN_WARNING PRINTK_HEADER
@@ -3798,7 +3807,7 @@
X range.to == -EINVAL ) {
X
X printk (KERN_WARNING PRINTK_HEADER
- "/proc/dasd/devices: parse error in '%s'",
+ "/proc/dasd/devices: range parse error in '%s'\n",
X buffer);
X } else {
X off = (long) temp - (long) buffer;
@@ -3814,7 +3823,8 @@
X dasd_disable_ranges (&range, NULL, 0, 1);
X } else {
X printk (KERN_WARNING PRINTK_HEADER
- "/proc/dasd/devices: parse error in '%s'", buffer);
+ "/proc/dasd/devices: parse error in '%s'\n",
+ buffer);
X }
X }
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/block/dasd_3990_erp.c linux/drivers/s390/block/dasd_3990_erp.c
--- v2.4.12/linux/drivers/s390/block/dasd_3990_erp.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/block/dasd_3990_erp.c Thu Oct 11 09:43:29 2001
@@ -761,7 +761,7 @@
X * DASD_3990_HANDLE_ENV_DATA
X *
X * DESCRIPTION
- * Handles 24 byte 'Enviromental data present'.
+ * Handles 24 byte 'Environmental data present'.
X * Does a analysis of the sense data (message Format)
X * and prints the error messages.
X *
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c
--- v2.4.12/linux/drivers/s390/block/xpram.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/block/xpram.c Mon Oct 15 13:27:51 2001
@@ -171,7 +171,7 @@
X int xpram_devs, xpram_rahead;
X int xpram_blksize, xpram_hardsect;
X int xpram_mem_avail = 0;
-int xpram_sizes[XPRAM_MAX_DEVS];
+unsigned long xpram_sizes[XPRAM_MAX_DEVS];
X
X
X MODULE_PARM(devs,"i");
@@ -649,7 +649,7 @@
X /* Return the device size, expressed in sectors */
X return put_user( 1024* xpram_sizes[MINOR(inode->i_rdev)]
X / XPRAM_SOFTSECT,


- (long *) arg);
+ (unsigned long *) arg);
X

X case BLKGETSIZE64:
X return put_user( (u64)(1024* xpram_sizes[MINOR(inode->i_rdev)]
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/Makefile linux/drivers/s390/char/Makefile
--- v2.4.12/linux/drivers/s390/char/Makefile Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/Makefile Thu Oct 11 09:43:29 2001
@@ -5,6 +5,7 @@
X O_TARGET := s390-char.o
X
X list-multi := tub3270.o tape390.o
+export-objs := hwc_rw.o
X
X tub3270-objs := tuball.o tubfs.o tubtty.o \
X tubttyaid.o tubttybld.o tubttyscl.o \
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/hwc_cpi.c linux/drivers/s390/char/hwc_cpi.c
--- v2.4.12/linux/drivers/s390/char/hwc_cpi.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/char/hwc_cpi.c Thu Oct 11 09:43:29 2001
@@ -9,7 +9,7 @@
X #include <linux/module.h>
X #include <linux/init.h>
X #include <linux/errno.h>


-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/version.h>

X #include <asm/semaphore.h>
X #include <asm/ebcdic.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tape34xx.c linux/drivers/s390/char/tape34xx.c
--- v2.4.12/linux/drivers/s390/char/tape34xx.c Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tape34xx.c Thu Oct 11 09:43:29 2001
@@ -1670,7 +1670,7 @@
X tapestate_set (ti, TS_DONE);
X ti->rc = 0;
X ti->wanna_wakeup=1;
- wake_up_interruptible (&ti->wq);
+ wake_up (&ti->wq);
X }
X
X void
@@ -2274,6 +2274,8 @@
X ti->wanna_wakeup=1;
X switch (tapestate_get(ti)) {
X case TS_REW_RELEASE_INIT:
+ case TS_RFO_INIT:
+ case TS_RBA_INIT:
X tapestate_set(ti,TS_FAILED);
X wake_up (&ti->wq);
X break;
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tapechar.c linux/drivers/s390/char/tapechar.c
--- v2.4.12/linux/drivers/s390/char/tapechar.c Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/tapechar.c Thu Oct 11 09:43:29 2001
@@ -204,13 +204,9 @@
X return rc;
X }
X s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
- wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+ wait_event (ti->wq,ti->wanna_wakeup);
X ti->cqr = NULL;
X ti->discipline->free_read_block (cqr, ti);
- if (signal_pending (current)) {
- tapestate_set (ti, TS_IDLE);
- return -ERESTARTSYS;
- }
X s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
X if (tapestate_get (ti) == TS_FAILED) {
X tapestate_set (ti, TS_IDLE);
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tuball.c linux/drivers/s390/char/tuball.c
--- v2.4.12/linux/drivers/s390/char/tuball.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/char/tuball.c Thu Oct 11 09:43:29 2001
@@ -93,8 +93,8 @@
X NULL /* next */
X };
X
-bcb_t tub3270_con_bcb; /* Buffer that receives con writes */
-spinlock_t tub3270_con_bcblock; /* Lock for the buffer */
+static bcb_t tub3270_con_bcb; /* Buffer that receives con writes */
+static spinlock_t tub3270_con_bcblock; /* Lock for the buffer */
X int tub3270_con_irq = -1; /* set nonneg by _activate() */
X tub_t *tub3270_con_tubp; /* set nonzero by _activate() */
X struct tty_driver tty3270_con_driver; /* for /dev/console at 4, 64 */
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/char/tubtty.c linux/drivers/s390/char/tubtty.c
--- v2.4.12/linux/drivers/s390/char/tubtty.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/char/tubtty.c Thu Oct 11 09:43:29 2001
@@ -992,8 +992,8 @@
X
X if (tty)
X len += sprintf(buf+len,
- " write_wait=%.8x read_wait=%.8x\n",
- (int)&tty->write_wait, (int)&tty->read_wait);
+ " write_wait=%p read_wait=%p\n",
+ &tty->write_wait, &tty->read_wait);
X
X if (tty && ((mp = tty->termios)))
X len += sprintf(buf+len," iflag=%.8x oflag=%.8x "
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/ctcmain.c linux/drivers/s390/net/ctcmain.c
--- v2.4.12/linux/drivers/s390/net/ctcmain.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/net/ctcmain.c Thu Oct 11 09:43:29 2001
@@ -1,5 +1,5 @@
X /*
- * $Id: ctcmain.c,v 1.49 2001/08/31 14:50:05 felfert Exp $
+ * $Id: ctcmain.c,v 1.51 2001/09/24 10:38:02 mschwide Exp $
X *
X * CTC / ESCON network driver
X *
@@ -35,7 +35,7 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.49 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.51 $


X *
X */
X

@@ -43,7 +43,7 @@
X #include <linux/module.h>
X #include <linux/init.h>
X #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/errno.h>
X #include <linux/types.h>
X #include <linux/interrupt.h>
@@ -96,6 +96,7 @@
X #ifdef MODULE
X MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (fel...@millenux.com)");
X MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
+MODULE_LICENSE("GPL");
X #ifndef CTC_CHANDEV
X MODULE_PARM(ctc, "s");
X MODULE_PARM_DESC(ctc,
@@ -296,6 +297,8 @@
X net_device *netdev;
X
X ctc_profile prof;
+
+ unsigned char *trans_skb_data;
X } channel;
X
X #define CHANNEL_FLAGS_READ 0
@@ -382,7 +385,7 @@
X */
X static void print_banner(void) {
X static int printed = 0;
- char vbuf[] = "$Revision: 1.49 $";
+ char vbuf[] = "$Revision: 1.51 $";
X char *version = vbuf;
X
X if (printed)
@@ -951,6 +954,7 @@
X return -ENOMEM;
X }
X ch->ccw[1].count = 0;
+ ch->trans_skb_data = ch->trans_skb->data;
X ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
X }
X return 0;
@@ -1016,7 +1020,7 @@
X spin_unlock(&ch->collect_lock);
X return;
X }
- ch->trans_skb->tail = ch->trans_skb->data;
+ ch->trans_skb->tail = ch->trans_skb->data = ch->trans_skb_data;
X ch->trans_skb->len = 0;
X if (ch->prof.maxmulti < (ch->collect_len + 2))
X ch->prof.maxmulti = ch->collect_len + 2;
@@ -1089,7 +1093,6 @@
X int len = ch->max_bufsize - ch->devstat->rescnt;
X struct sk_buff *skb = ch->trans_skb;
X __u16 block_len = *((__u16*)skb->data);
- char *saved_data = skb->data;
X int check_len;
X int rc;
X
@@ -1138,7 +1141,7 @@
X ctc_unpack_skb(ch, skb);
X }
X again:
- skb->data = skb->tail = saved_data;
+ skb->data = skb->tail = ch->trans_skb_data;
X skb->len = 0;
X if (ctc_checkalloc_buffer(ch, 1))
X return;
@@ -1548,9 +1551,9 @@
X channel *ch = (channel *)arg;
X net_device *dev = ch->netdev;
X
+ fsm_deltimer(&ch->timer);
X printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
X (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
-
X fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
X oldstate = fsm_getstate(fi);
X fsm_newstate(fi, CH_STATE_STARTWAIT);
@@ -1716,8 +1719,7 @@
X #ifdef DEBUG
X printk(KERN_DEBUG "ccw[4].cda = %08x\n", ch->ccw[4].cda);
X #endif
- rc = do_IO(ch->irq, &ch->ccw[3],
- (intparm_t)ch, 0xff, 0);
+ rc = do_IO(ch->irq, &ch->ccw[3], (intparm_t)ch, 0xff, 0);
X if (event == CH_EVENT_TIMER)
X s390irq_spin_unlock_irqrestore(ch->irq,
X saveflags);
@@ -2539,7 +2541,8 @@
X if (rc != 0) {
X fsm_deltimer(&ch->timer);
X ccw_check_return_code(ch, rc);
- skb_dequeue_tail(&ch->io_queue);
+ if (ccw_idx == 3)
+ skb_dequeue_tail(&ch->io_queue);
X /**
X * Remove our header. It gets added
X * again on retransmit.
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
--- v2.4.12/linux/drivers/s390/net/iucv.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/net/iucv.c Thu Oct 11 09:43:29 2001
@@ -39,7 +39,7 @@
X #include <linux/version.h>
X #include <linux/spinlock.h>
X #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/init.h>
X #include <linux/tqueue.h>
X #include <linux/interrupt.h>
@@ -53,10 +53,6 @@
X
X #undef DEBUG
X
-#ifndef min
-#define min(a,b) (((a)<(b))?(a):(b))
-#endif
-
X /* FLAGS:
X * All flags are defined in the field IPFLAGS1 of each function
X * and can be found in CP Programming Services.
@@ -1163,7 +1159,7 @@
X
X parm = (iparml_db *)grab_param();
X
- parm->ipbfadr1 = (__u32) buffer;
+ parm->ipbfadr1 = (__u32) (addr_t) buffer;
X parm->ipbfln1f = (__u32) ((ulong) buflen);
X parm->ipmsgid = msgid;
X parm->ippathid = pathid;
@@ -1186,7 +1182,7 @@
X if (residual_buffer)
X *residual_buffer = parm->ipbfadr1;
X } else {
- moved = min (buflen, 8);
+ moved = min_t (unsigned long, buflen, 8);
X
X memcpy ((char *) buffer,
X (char *) &parm->ipbfadr1, moved);
@@ -1283,7 +1279,8 @@
X
X while ((moved < 8) && (moved < buflen)) {
X dyn_len =
- min ((buffer + i)->length, need_to_move);
+ min_t (unsigned int,
+ (buffer + i)->length, need_to_move);
X
X memcpy ((char *)((ulong)((buffer + i)->address)),
X ((char *) &parm->ipbfadr1) + moved,
diff -u --recursive --new-file v2.4.12/linux/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- v2.4.12/linux/drivers/s390/net/netiucv.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/s390/net/netiucv.c Thu Oct 11 09:43:29 2001
@@ -1,5 +1,5 @@
X /*
- * $Id: netiucv.c,v 1.11 2001/07/16 17:00:02 felfert Exp $
+ * $Id: netiucv.c,v 1.12 2001/09/24 10:38:02 mschwide Exp $
X *
X * IUCV network driver
X *
@@ -28,7 +28,7 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
- * RELEASE-TAG: IUCV network driver $Revision: 1.11 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.12 $


X *
X */
X

@@ -36,7 +36,7 @@
X #include <linux/module.h>
X #include <linux/init.h>
X #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/errno.h>
X #include <linux/types.h>
X #include <linux/interrupt.h>
@@ -2002,7 +2002,7 @@
X static void
X netiucv_banner(void)
X {
- char vbuf[] = "$Revision: 1.11 $";
+ char vbuf[] = "$Revision: 1.12 $";
X char *version = vbuf;
X
X if ((version = strchr(version, ':'))) {
@@ -2115,7 +2115,8 @@


X return 0;
X }
X

-module_init(netiucv_init);
X #ifdef MODULE
+module_init(netiucv_init);
X module_exit(netiucv_exit);


+MODULE_LICENSE("GPL");
X #endif

diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/audio/amd7930.c linux/drivers/sbus/audio/amd7930.c
--- v2.4.12/linux/drivers/sbus/audio/amd7930.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/audio/amd7930.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: amd7930.c,v 1.27 2001/05/21 01:25:22 davem Exp $
+/* $Id: amd7930.c,v 1.28 2001/10/13 01:47:29 davem Exp $
X * drivers/sbus/audio/amd7930.c
X *
X * Copyright (C) 1996,1997 Thomas K. Dyas (td...@eden.rutgers.edu)
@@ -1716,6 +1716,7 @@
X
X module_init(amd7930_init);
X module_exit(amd7930_exit);
+MODULE_LICENSE("GPL");
X
X /*************************************************************/
X /* Audio format conversion */
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/aurora.c linux/drivers/sbus/char/aurora.c
--- v2.4.12/linux/drivers/sbus/char/aurora.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/sbus/char/aurora.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: aurora.c,v 1.16 2001/10/08 22:19:51 davem Exp $
+/* $Id: aurora.c,v 1.17 2001/10/13 08:27:50 davem Exp $
X * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
X *
X * Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
@@ -33,6 +33,14 @@
X * read that file before reading this one.
X *
X * Several parts of the code do not have comments yet.
+ *
+ * n.b. The board can support 115.2 bit rates, but only on a few
+ * ports. The total badwidth of one chip (ports 0-7 or 8-15) is equal
+ * to OSC_FREQ div 16. In case of my board, each chip can take 6
+ * channels of 115.2 kbaud. This information is not well-tested.
+ *
+ * Fixed to use tty_get_baud_rate().
+ * Theodore Ts'o <ty...@mit.edu>, 2001-Oct-12
X */
X
X #include <linux/module.h>
@@ -100,16 +108,6 @@
X
X DECLARE_TASK_QUEUE(tq_aurora);
X
-/* Yes, the board can support 115.2 bit rates, but only on a few ports. The
- * total badwidth of one chip (ports 0-7 or 8-15) is equal to OSC_FREQ div
- * 16. In case of my board, each chip can take 6 channels of 115.2 kbaud.
- * This information is not well-tested.
- */
-static unsigned long baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 0,
-};
-
X static inline int aurora_paranoia_check(struct Aurora_port const * port,
X kdev_t device, const char *routine)
X {
@@ -1030,28 +1028,14 @@
X port->COR2 = 0;
X port->MSVR = MSVR_RTS|MSVR_DTR;
X
- baud = C_BAUD(tty);
-
- if (baud & CBAUDEX) {
- baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
- port->tty->termios->c_cflag &= ~CBAUDEX;
- else
- baud += 15;
- }
- if (baud == 15) {
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baud ++;
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baud += 2;
- }
+ baud = tty_get_baud_rate(tty);
X
X /* Select port on the board */
X sbus_writeb(port_No(port) & 7,
X &bp->r[chip]->r[CD180_CAR]);
X udelay(1);
X
- if (!baud_table[baud]) {
+ if (!baud) {
X /* Drop DTR & exit */
X port->MSVR &= ~(bp->DTR|bp->RTS);
X sbus_writeb(port->MSVR,
@@ -1067,10 +1051,10 @@
X /* Now we must calculate some speed dependant things. */
X
X /* Set baud rate for port. */
- tmp = (((bp->oscfreq + baud_table[baud]/2) / baud_table[baud] +
+ tmp = (((bp->oscfreq + baud/2) / baud +
X CD180_TPC/2) / CD180_TPC);
X
-/* tmp = (bp->oscfreq/7)/baud_table[baud];
+/* tmp = (bp->oscfreq/7)/baud;
X if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*/
X /* printk("Prescaler period: %d\n",tmp);*/
X
@@ -1081,7 +1065,7 @@
X sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);
X sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);
X
- baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
+ baud = (baud + 5) / 10; /* Estimated CPS */
X
X /* Two timer ticks seems enough to wakeup something like SLIP driver */
X tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c
--- v2.4.12/linux/drivers/sbus/char/bpp.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/sbus/char/bpp.c Thu Oct 11 09:43:29 2001
@@ -1073,4 +1073,3 @@
X
X module_init(bpp_init);
X module_exit(bpp_cleanup);
-MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c
--- v2.4.12/linux/drivers/sbus/char/jsflash.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/sbus/char/jsflash.c Mon Oct 15 13:27:42 2001
@@ -453,7 +453,7 @@


X
X switch (cmd) {
X case BLKGETSIZE:

- return put_user(jsfd_bytesizes[dev] >> 9, (long *) arg);
+ return put_user(jsfd_bytesizes[dev] >> 9, (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user(jsfd_bytesizes[dev], (u64 *) arg);
X
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- v2.4.12/linux/drivers/sbus/char/sab82532.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/sbus/char/sab82532.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.64 2001/10/08 22:19:51 davem Exp $
+/* $Id: sab82532.c,v 1.65 2001/10/13 08:27:50 davem Exp $
X * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -6,6 +6,10 @@
X * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
X * Maxim Krasnyanskiy <ma...@qualcomm.com>
X *
+ * Fixed to use tty_get_baud_rate, and to allow for arbitrary baud
+ * rates to be programmed into the UART. Also eliminated a lot of
+ * duplicated code in the console setup.
+ * Theodore Ts'o <ty...@mit.edu>, 2001-Oct-12
X */
X
X #include <linux/config.h>
@@ -147,45 +151,47 @@
X * The formula is: Baud = BASE_BAUD / ((N + 1) * (1 << M)),
X *
X * with 0 <= N < 64 and 0 <= M < 16
- *
- * XXX: Speeds with M = 0 might not work properly for XTAL frequencies
- * above 10 MHz.
+ *
+ * 12-Oct-2001 - Replaced table driven approach with code written by
+ * Theodore Ts'o <ty...@alum.mit.edu> which exactly replicates the
+ * table. (Modulo bugs for the 307200 and 61440 baud rates, which
+ * were clearly incorrectly calculated in the original table. This is
+ * why tables filled with magic constants are evil.)
X */
-struct ebrg_struct {
- int baud;
- int n;
- int m;
-};
X
-static struct ebrg_struct ebrg_table[] = {
- { 0, 0, 0 },
- { 50, 35, 10 },
- { 75, 47, 9 },
- { 110, 32, 9 },
- { 134, 53, 8 },
- { 150, 47, 8 },
- { 200, 35, 8 },
- { 300, 47, 7 },
- { 600, 47, 6 },
- { 1200, 47, 5 },
- { 1800, 31, 5 },
- { 2400, 47, 4 },
- { 4800, 47, 3 },
- { 9600, 47, 2 },
- { 19200, 47, 1 },
- { 38400, 23, 1 },
- { 57600, 15, 1 },
- { 115200, 7, 1 },
- { 230400, 3, 1 },
- { 460800, 1, 1 },
- { 76800, 11, 1 },
- { 153600, 5, 1 },
- { 307200, 3, 1 },
- { 614400, 3, 0 },
- { 921600, 0, 1 },
-};
+static void calc_ebrg(int baud, int *n_ret, int *m_ret)
+{
+ int n, m;
X
-#define NR_EBRG_VALUES (sizeof(ebrg_table)/sizeof(struct ebrg_struct))
+ if (baud == 0) {
+ *n_ret = 0;
+ *m_ret = 0;
+ return;
+ }
+
+ /*
+ * We scale numbers by 10 so that we get better accuracy
+ * without having to use floating point. Here we increment m
+ * until n is within the valid range.
+ */
+ n = (BASE_BAUD*10) / baud;
+ m = 0;
+ while (n >= 640) {
+ n = n / 2;
+ m++;
+ }
+ n = (n+5) / 10;
+ /*
+ * We try very hard to avoid speeds with M == 0 since they may
+ * not work correctly for XTAL frequences above 10 MHz.
+ */
+ if ((m == 0) && ((n & 1) == 0)) {
+ n = n / 2;
+ m++;
+ }
+ *n_ret = n - 1;
+ *m_ret = m;
+}
X
X #define SAB82532_MAX_TEC_TIMEOUT 200000 /* 1 character time (at 50 baud) */
X #define SAB82532_MAX_CEC_TIMEOUT 50000 /* 2.5 TX CLKs (at 50 baud) */
@@ -939,7 +945,7 @@
X unsigned int ebrg;
X tcflag_t cflag;
X unsigned char dafo;
- int i, bits;
+ int bits, n, m;
X
X if (!info->tty || !info->tty->termios)
X return;
@@ -982,18 +988,11 @@
X }
X
X /* Determine EBRG values based on baud rate */
- i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~(CBAUDEX);
- if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
- }
- ebrg = ebrg_table[i].n;
- ebrg |= (ebrg_table[i].m << 6);
+ info->baud = tty_get_baud_rate(info->tty);
+ calc_ebrg(info->baud, &n, &m);
+
+ ebrg = n | (m << 6);
X
- info->baud = ebrg_table[i].baud;
X if (info->baud) {
X info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
X info->tec_timeout = (10 * 1000000) / info->baud;
@@ -2205,7 +2204,7 @@
X
X static inline void __init show_serial_version(void)
X {
- char *revision = "$Revision: 1.64 $";
+ char *revision = "$Revision: 1.65 $";
X char *version, *p;
X
X version = strchr(revision, ' ');
@@ -2558,12 +2557,11 @@
X static int
X sab82532_console_setup(struct console *con, char *options)
X {
+ static struct tty_struct c_tty;
+ static struct termios c_termios;
X struct sab82532 *info;
- unsigned int ebrg;
X tcflag_t cflag;
- unsigned char dafo;
- int i, bits;
- unsigned long flags;
+ int i;
X
X info = sab82532_chain;
X for (i = con->index; i; i--) {
@@ -2595,92 +2593,28 @@
X sunserial_console_termios(con);
X cflag = con->cflag;
X
- /* Byte size and parity */
- switch (cflag & CSIZE) {
- case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
- case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
- case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
- case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
- /* Never happens, but GCC is too dumb to figure it out */
- default: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
- }
-
- if (cflag & CSTOPB) {
- dafo |= SAB82532_DAFO_STOP;
- bits++;
- }
-
- if (cflag & PARENB) {
- dafo |= SAB82532_DAFO_PARE;
- bits++;
- }
-
- if (cflag & PARODD) {
-#ifdef CMSPAR
- if (cflag & CMSPAR)
- dafo |= SAB82532_DAFO_PAR_MARK;
- else
-#endif
- dafo |= SAB82532_DAFO_PAR_ODD;
- } else {
-#ifdef CMSPAR
- if (cflag & CMSPAR)
- dafo |= SAB82532_DAFO_PAR_SPACE;
- else
-#endif
- dafo |= SAB82532_DAFO_PAR_EVEN;
+ /*
+ * Fake up the tty and tty->termios structures so we can use
+ * change_speed (and eliminate a lot of duplicate code).
+ */
+ if (!info->tty) {
+ memset(&c_tty, 0, sizeof(c_tty));
+ info->tty = &c_tty;
X }
-
- /* Determine EBRG values based on baud rate */
- i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~(CBAUDEX);
- if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
- cflag &= ~CBAUDEX;
- else
- i += 15;
+ if (!info->tty->termios) {
+ memset(&c_termios, 0, sizeof(c_termios));
+ info->tty->termios = &c_termios;
X }
- ebrg = ebrg_table[i].n;
- ebrg |= (ebrg_table[i].m << 6);
-
- info->baud = ebrg_table[i].baud;
- if (info->baud)
- info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
- else
- info->timeout = 0;
- info->timeout += HZ / 50; /* Add .02 seconds of slop */
-
- /* CTS flow control flags */
- 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;
+ info->tty->termios->c_cflag = con->cflag;
X
- save_flags(flags); cli();
- sab82532_cec_wait(info);
- sab82532_tec_wait(info);
- writeb(dafo, &info->regs->w.dafo);
- writeb(ebrg & 0xff, &info->regs->w.bgr);
- writeb(readb(&info->regs->rw.ccr2) & ~(0xc0), &info->regs->rw.ccr2);
- writeb(readb(&info->regs->rw.ccr2) | ((ebrg >> 2) & 0xc0), &info->regs->rw.ccr2);
- if (info->flags & ASYNC_CTS_FLOW) {
- writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RTS), &info->regs->rw.mode);
- writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
- writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FCTS), &info->regs->rw.mode);
- } else {
- writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
- writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FRTS), &info->regs->rw.mode);
- writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FCTS, &info->regs->rw.mode);
- }
- writeb(~(info->pvr_dtr_bit), &info->regs->rw.pvr);
- writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RAC, &info->regs->rw.mode);
- restore_flags(flags);
+ change_speed(info);
X
+ /* Now take out the pointers to static structures if necessary */
+ if (info->tty->termios == &c_termios)
+ info->tty->termios = 0;
+ if (info->tty == &c_tty)
+ info->tty = 0;
+

X return 0;
X }
X

diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c
--- v2.4.12/linux/drivers/sbus/char/su.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/char/su.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.52 2001/06/29 21:54:32 davem Exp $
+/* $Id: su.c,v 1.53 2001/10/13 08:27:50 davem Exp $
X * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -6,6 +6,9 @@
X *
X * This is mainly a variation of drivers/char/serial.c,
X * credits go to authors mentioned therein.
+ *
+ * Fixed to use tty_get_baud_rate().
+ * Theodore Ts'o <ty...@mit.edu>, 2001-Oct-12
X */
X
X /*
@@ -935,24 +938,18 @@
X static int
X su_get_baud_rate(struct su_struct *info)
X {
- static int baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
- 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0
- };
- int i;
+ static struct tty_struct c_tty;
+ static struct termios c_termios;
X
X if (info->tty)
X return tty_get_baud_rate(info->tty);
X
- i = info->cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~(CBAUDEX);
- if (i < 1 || i > 4)
- info->cflag &= ~(CBAUDEX);
- else
- i += 15;
- }
- return baud_table[i];
+ memset(&c_tty, 0, sizeof(c_tty));
+ memset(&c_termios, 0, sizeof(c_termios));
+ c_tty.termios = &c_termios;
+ c_termios.c_cflag = info->cflag;
+
+ return tty_get_baud_rate(&c_tty);
X }
X
X /*
@@ -1168,7 +1165,7 @@
X if (info->port_type != SU_PORT_MS)
X return;
X
- info->cflag &= ~(CBAUDEX | CBAUD);
+ info->cflag &= ~CBAUD;
X switch (baud) {
X case 1200:
X info->cflag |= B1200;
@@ -2255,7 +2252,7 @@
X */
X static __inline__ void __init show_su_version(void)
X {
- char *revision = "$Revision: 1.52 $";
+ char *revision = "$Revision: 1.53 $";
X char *version, *p;
X
X version = strchr(revision, ' ');
diff -u --recursive --new-file v2.4.12/linux/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- v2.4.12/linux/drivers/sbus/char/zs.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/char/zs.c Wed Oct 17 14:16:39 2001
@@ -1,9 +1,12 @@
-/* $Id: zs.c,v 1.66 2001/06/29 21:33:22 davem Exp $
+/* $Id: zs.c,v 1.67 2001/10/13 08:27:50 davem Exp $
X * zs.c: Zilog serial port driver for the Sparc.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
X * Copyright (C) 1996 Eddie C. Dost (e...@skynet.be)
X * Fixes by Pete A. Zaitcev <zai...@yahoo.com>.
+ *
+ * Fixed to use tty_get_baud_rate().
+ * Theodore Ts'o <ty...@mit.edu>, 2001-Oct-12
X */
X
X #include <linux/errno.h>
@@ -241,12 +244,6 @@


X return 0;
X }
X

-/* This is used to figure out the divisor speeds and the timeouts. */
-static int baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 76800, 0
-};
-
X /* Reading and writing Zilog8530 registers. The delays are to make this
X * driver work on the Sun4 which needs a settling delay after each chip
X * register access, other machines handle this in hardware via auxiliary
@@ -944,8 +941,7 @@
X static void change_speed(struct sun_serial *info)
X {
X unsigned cflag;
- int quot = 0;
- int i;
+ int baud, quot = 0;
X int brg;
X
X if (!info->tty || !info->tty->termios)
@@ -953,20 +949,12 @@
X cflag = info->tty->termios->c_cflag;
X if (!info->port)
X return;
- i = cflag & CBAUD;
- if (cflag & CBAUDEX) {
- i &= ~CBAUDEX;
- if (i != 5)
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i = 16;
- }
- if (i == 15) {
- if ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_HI)
- i += 1;
- if ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_CUST)
- quot = info->custom_divisor;
- }
+ baud = tty_get_baud_rate(info->tty);
+
+ if ((baud == 38400) &&
+ ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_CUST))
+ quot = info->custom_divisor;
+
X if (quot) {
X info->zs_baud = info->baud_base / quot;
X info->clk_divisor = 16;
@@ -978,8 +966,8 @@
X info->curregs[13] = ((brg >> 8) & 255);
X info->curregs[14] = BRSRC | BRENAB;
X zs_rtsdtr(info, 1);
- } else if (baud_table[i]) {
- info->zs_baud = baud_table[i];
+ } else if (baud) {
+ info->zs_baud = baud;
X info->clk_divisor = 16;
X
X info->curregs[4] = X16CLK;
@@ -1945,7 +1933,7 @@
X
X static void show_serial_version(void)
X {
- char *revision = "$Revision: 1.66 $";
+ char *revision = "$Revision: 1.67 $";
X char *version, *p;
X
X version = strchr(revision, ' ');
@@ -2796,22 +2784,23 @@
X
X static int __init zs_console_setup(struct console *con, char *options)
X {
+ static struct tty_struct c_tty;
+ static struct termios c_termios;
X struct sun_serial *info;
- int i, brg, baud;
+ int brg, baud;
X
X info = zs_soft + con->index;
X info->is_cons = 1;
X
X printk("Console: ttyS%d (Zilog8530)\n", info->line);
-
+
X sunserial_console_termios(con);
+ memset(&c_tty, 0, sizeof(c_tty));
+ memset(&c_termios, 0, sizeof(c_termios));
+ c_tty.termios = &c_termios;
+ c_termios.c_cflag = con->cflag;
+ baud = tty_get_baud_rate(&c_tty);
X
- i = con->cflag & CBAUD;
- if (con->cflag & CBAUDEX) {
- i &= ~CBAUDEX;
- con->cflag &= ~CBAUDEX;
- }
- baud = baud_table[i];
X info->zs_baud = baud;
X
X switch (con->cflag & CSIZE) {
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- v2.4.12/linux/drivers/scsi/53c700.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/53c700.c Thu Oct 11 09:43:29 2001
@@ -51,6 +51,12 @@
X
X /* CHANGELOG
X *
+ * Version 2.6
+ *
+ * Following test of the 64 bit parisc kernel by Richard Hirst,
+ * several problems have now been corrected. Also adds support for
+ * consistent memory allocation.
+ *
X * Version 2.5
X *
X * More Compatibility changes for 710 (now actually works). Enhanced
@@ -90,7 +96,7 @@
X * Initial modularisation from the D700. See NCR_D700.c for the rest of
X * the changelog.
X * */
-#define NCR_700_VERSION "2.5"
+#define NCR_700_VERSION "2.6"
X
X #include <linux/config.h>
X #include <linux/version.h>
@@ -217,18 +223,39 @@
X NCR_700_detect(Scsi_Host_Template *tpnt,
X struct NCR_700_Host_Parameters *hostdata)
X {
- dma_addr_t pScript, pSlots;
+ dma_addr_t pScript, pMemory, pSlots;
+ __u8 *memory;
X __u32 *script;
X struct Scsi_Host *host;
X static int banner = 0;
X int j;
X
- /* This separation of pScript and script is not strictly
- * necessay, but may be useful in architectures which can
- * allocate consistent memory on which virt_to_bus will not
- * work */
- script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
- pScript = virt_to_bus(script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+ memory = pci_alloc_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+ &pMemory);
+ hostdata->consistent = 1;
+ if(memory == NULL ) {
+ printk(KERN_WARNING "53c700: consistent memory allocation failed\n");
+#endif
+ memory = kmalloc(TOTAL_MEM_SIZE, GFP_KERNEL);
+ if(memory == NULL) {
+ printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
+ return NULL;
+ }
+ pMemory = pci_map_single(hostdata->pci_dev, memory,
+ TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+ hostdata->consistent = 0;
+ }
+#endif
+ script = (__u32 *)memory;
+ pScript = pMemory;
+ hostdata->msgin = memory + MSGIN_OFFSET;
+ hostdata->msgout = memory + MSGOUT_OFFSET;
+ hostdata->status = memory + STATUS_OFFSET;
+ hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
+
+ pSlots = pMemory + SLOTS_OFFSET;
X
X /* Fill in the missing routines from the host template */
X tpnt->queuecommand = NCR_700_queuecommand;
@@ -251,29 +278,6 @@
X
X if((host = scsi_register(tpnt, 4)) == NULL)
X return NULL;
- if(script == NULL) {
- printk(KERN_ERR "53c700: Failed to allocate script, detatching\n");
- scsi_unregister(host);


- return NULL;
- }
-

- /* This separation of slots and pSlots may facilitate later
- * migration to consistent memory on architectures which
- * support it */
- hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot)
- * NCR_700_COMMAND_SLOTS_PER_HOST,
- GFP_KERNEL);
- pSlots = virt_to_bus(hostdata->slots);
-
- hostdata->msgin = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
- hostdata->msgout = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
- hostdata->status = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
- if(hostdata->slots == NULL || hostdata->msgin == NULL
- || hostdata->msgout == NULL || hostdata->status==NULL) {
- printk(KERN_ERR "53c700: Failed to allocate command slots or message buffers, detatching\n");
- scsi_unregister(host);
- return NULL;
- }
X memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
X * NCR_700_COMMAND_SLOTS_PER_HOST);
X for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
@@ -295,19 +299,17 @@
X for(j = 0; j < PATCHES; j++) {
X script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
X }
- /* now patch up fixed addresses.
- * NOTE: virt_to_bus may be wrong if consistent memory is used
- * for these in the future */
+ /* now patch up fixed addresses. */
X script_patch_32(script, MessageLocation,
- virt_to_bus(&hostdata->msgout[0]));
+ pScript + MSGOUT_OFFSET);
X script_patch_32(script, StatusAddress,
- virt_to_bus(&hostdata->status[0]));
+ pScript + STATUS_OFFSET);
X script_patch_32(script, ReceiveMsgAddress,
- virt_to_bus(&hostdata->msgin[0]));
+ pScript + MSGIN_OFFSET);
X
X hostdata->script = script;
X hostdata->pScript = pScript;
- dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
+ NCR_700_dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
X hostdata->state = NCR_700_HOST_FREE;
X spin_lock_init(&hostdata->lock);
X hostdata->cmd = NULL;
@@ -344,13 +346,18 @@
X struct NCR_700_Host_Parameters *hostdata =
X (struct NCR_700_Host_Parameters *)host->hostdata[0];
X
- /* NOTE: these may be NULL if we weren't fully initialised before
- * the scsi_unregister was called */
- kfree(hostdata->script);
- kfree(hostdata->slots);
- kfree(hostdata->msgin);
- kfree(hostdata->msgout);
- kfree(hostdata->status);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+ if(hostdata->consistent) {
+ pci_free_consistent(hostdata->pci_dev, TOTAL_MEM_SIZE,
+ hostdata->script, hostdata->pScript);
+ } else {
+#endif
+ pci_unmap_single(hostdata->pci_dev, hostdata->pScript,
+ TOTAL_MEM_SIZE, PCI_DMA_BIDIRECTIONAL);
+ kfree(hostdata->script);
+#ifdef CONFIG_53C700_USE_CONSISTENT
+ }
+#endif


X return 1;
X }
X

@@ -620,7 +627,25 @@
X }
X return (offset & 0x0f) | (XFERP & 0x07)<<4;
X }
-
+
+STATIC inline void
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+ struct NCR_700_command_slot *slot)
+{
+ if(SCp->sc_data_direction != SCSI_DATA_NONE &&
+ SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
+ int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
+ if(SCp->use_sg) {
+ pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
+ SCp->use_sg, pci_direction);
+ } else {
+ pci_unmap_single(hostdata->pci_dev,
+ slot->dma_handle,
+ SCp->request_bufflen,
+ pci_direction);
+ }
+ }
+}
X
X STATIC inline void
X NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
@@ -632,31 +657,22 @@
X if(SCp != NULL) {
X struct NCR_700_command_slot *slot =
X (struct NCR_700_command_slot *)SCp->host_scribble;
-
+
+ NCR_700_unmap(hostdata, SCp, slot);
+ pci_unmap_single(hostdata->pci_dev, slot->pCmd,
+ sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
X if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
X #ifdef NCR_700_DEBUG
X printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
X SCp, SCp->cmnd[7], result);
X print_sense("53c700", SCp);
+
X #endif
+ SCp->use_sg = SCp->cmnd[8];
X if(result == 0)
X result = SCp->cmnd[7];
X }
X
- if(SCp->sc_data_direction != SCSI_DATA_NONE &&
- SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
- int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
- if(SCp->use_sg) {


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 36'
echo 'File patch-2.4.13 is continued in part 37'
echo "37" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:07 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part37

#!/bin/sh -x
# this is part 37 of a 53 - part archive


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

if test "$Scheck" != 37; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
- SCp->use_sg, pci_direction);
- } else {
- pci_unmap_single(hostdata->pci_dev,
- slot->dma_handle,
- SCp->request_bufflen,
- pci_direction);
- }
- }
-
X free_slot(slot, hostdata);
X
X SCp->host_scribble = NULL;
@@ -850,7 +866,7 @@
X printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
X host->host_no);
X hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_wback((unsigned long)hostdata->msgout, 1);
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
X script_patch_16(hostdata->script, MessageCount, 1);
X /* SendMsgOut returns, so set up the return
X * address */
@@ -862,7 +878,7 @@
X printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
X host->host_no, pun, lun);
X hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_wback((unsigned long)hostdata->msgout, 1);
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
X script_patch_16(hostdata->script, MessageCount, 1);
X resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
X
@@ -876,7 +892,7 @@
X printk("\n");
X /* just reject it */
X hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_wback((unsigned long)hostdata->msgout, 1);
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
X script_patch_16(hostdata->script, MessageCount, 1);
X /* SendMsgOut returns, so set up the return
X * address */
@@ -954,7 +970,7 @@
X printk("\n");
X /* just reject it */
X hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_wback((unsigned long)hostdata->msgout, 1);
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, 1);
X script_patch_16(hostdata->script, MessageCount, 1);
X /* SendMsgOut returns, so set up the return
X * address */
@@ -964,7 +980,7 @@
X }
X NCR_700_writel(temp, host, TEMP_REG);
X /* set us up to receive another message */
- dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+ NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
X return resume_offset;
X }
X
@@ -1002,10 +1018,15 @@
X printk(" cmd %p has status %d, requesting sense\n",
X SCp, hostdata->status[0]);
X #endif
- /* we can destroy the command here because the
- * contingent allegiance condition will cause a
- * retry which will re-copy the command from the
- * saved data_cmnd */
+ /* we can destroy the command here
+ * because the contingent allegiance
+ * condition will cause a retry which
+ * will re-copy the command from the
+ * saved data_cmnd. We also unmap any
+ * data associated with the command
+ * here */


+ NCR_700_unmap(hostdata, SCp, slot);
+

X SCp->cmnd[0] = REQUEST_SENSE;
X SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
X SCp->cmnd[2] = 0;
@@ -1013,21 +1034,29 @@
X SCp->cmnd[4] = sizeof(SCp->sense_buffer);
X SCp->cmnd[5] = 0;
X SCp->cmd_len = 6;
- /* Here's a quiet hack: the REQUEST_SENSE command is
- * six bytes, so store a flag indicating that this
- * was an internal sense request and the original
- * status at the end of the command */
+ /* Here's a quiet hack: the
+ * REQUEST_SENSE command is six bytes,
+ * so store a flag indicating that
+ * this was an internal sense request
+ * and the original status at the end
+ * of the command */
X SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
X SCp->cmnd[7] = hostdata->status[0];
+ SCp->cmnd[8] = SCp->use_sg;
+ SCp->use_sg = 0;
X SCp->sc_data_direction = SCSI_DATA_READ;
- dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+ pci_dma_sync_single(hostdata->pci_dev,
+ slot->pCmd,
+ SCp->cmd_len,
+ PCI_DMA_TODEVICE);
+ slot->dma_handle = pci_map_single(hostdata->pci_dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), PCI_DMA_FROMDEVICE);
X slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
- slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
+ slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
X slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
X slot->SG[1].pAddr = 0;
X slot->resume_offset = hostdata->pScript;
- dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
- dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
+ NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG[0])*2);
+ NCR_700_dma_cache_inv((unsigned long)SCp->sense_buffer, sizeof(SCp->sense_buffer));
X
X /* queue the command for reissue */
X slot->state = NCR_700_SLOT_QUEUED;
@@ -1136,7 +1165,7 @@
X
X /* re-patch for this command */
X script_patch_32_abs(hostdata->script, CommandAddress,
- virt_to_bus(slot->cmnd->cmnd));
+ slot->pCmd);
X script_patch_16(hostdata->script,
X CommandCount, slot->cmnd->cmd_len);
X script_patch_32_abs(hostdata->script, SGScriptStartAddress,
@@ -1149,13 +1178,13 @@
X * should therefore always clear ACK */
X NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
X host, SXFER_REG);
- dma_cache_inv((unsigned long)hostdata->msgin,
+ NCR_700_dma_cache_inv((unsigned long)hostdata->msgin,
X MSG_ARRAY_SIZE);
- dma_cache_wback((unsigned long)hostdata->msgout,
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout,
X MSG_ARRAY_SIZE);
X /* I'm just being paranoid here, the command should
X * already have been flushed from the cache */
- dma_cache_wback((unsigned long)slot->cmnd->cmnd,
+ NCR_700_dma_cache_wback((unsigned long)slot->cmnd->cmnd,
X slot->cmnd->cmd_len);
X
X
@@ -1219,7 +1248,8 @@
X hostdata->reselection_id = reselection_id;
X /* just in case we have a stale simple tag message, clear it */
X hostdata->msgin[1] = 0;
- dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+ NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin,
+ MSG_ARRAY_SIZE);
X if(hostdata->tag_negotiated & (1<<reselection_id)) {
X resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
X } else {
@@ -1334,7 +1364,7 @@


X hostdata->cmd = NULL;

X /* clear any stale simple tag message */
X hostdata->msgin[1] = 0;
- dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+ NCR_700_dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
X
X if(id == 0xff) {
X /* Selected as target, Ignore */
@@ -1404,7 +1434,7 @@
X * set up so we cannot take a selection interrupt */
X
X hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
- SCp->lun);
+ SCp->lun);
X /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
X * if the negotiated transfer parameters still hold, so
X * always renegotiate them */
@@ -1437,7 +1467,7 @@
X Device_ID, 1<<SCp->target);
X
X script_patch_32_abs(hostdata->script, CommandAddress,
- virt_to_bus(SCp->cmnd));
+ slot->pCmd);
X script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
X /* finally plumb the beginning of the SG list into the script
X * */
@@ -1448,10 +1478,10 @@
X if(slot->resume_offset == 0)
X slot->resume_offset = hostdata->pScript;
X /* now perform all the writebacks and invalidates */
- dma_cache_wback((unsigned long)hostdata->msgout, count);
- dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
- dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
- dma_cache_inv((unsigned long)hostdata->status, 1);
+ NCR_700_dma_cache_wback((unsigned long)hostdata->msgout, count);
+ NCR_700_dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+ NCR_700_dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+ NCR_700_dma_cache_inv((unsigned long)hostdata->status, 1);
X
X /* set the synchronous period/offset */
X NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1519,7 +1549,7 @@
X
X DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
X host->host_no, istat, sstat0, dstat,
- (dsp - (__u32)virt_to_bus(hostdata->script))/4,
+ (dsp - (__u32)(hostdata->pScript))/4,
X dsp, dsps));
X
X if(SCp != NULL) {
@@ -1632,7 +1662,7 @@
X slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
X slot->SG[i].pAddr = 0;
X }
- dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+ NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
X /* and pretend we disconnected after
X * the command phase */
X resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1847,7 +1877,13 @@
X #endif
X
X if(old != NULL && old->tag == SCp->device->current_tag) {
- printk(KERN_WARNING "scsi%d (%d:%d) Tag clock back to current, queueing\n", SCp->host->host_no, SCp->target, SCp->lun);
+ /* On some badly starving drives, this can be
+ * a frequent occurance, so print the message
+ * only once */
+ if(NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED)) {
+ printk(KERN_WARNING "scsi%d (%d:%d) Target is suffering from tag starvation.\n", SCp->host->host_no, SCp->target, SCp->lun);
+ NCR_700_set_flag(SCp->device, NCR_700_DEV_TAG_STARVATION_WARNED);
+ }
X return 1;
X }
X slot->tag = SCp->device->current_tag++;
@@ -1900,6 +1936,18 @@
X hostdata->ITL_Hash_back[hash] = slot;
X slot->ITL_back = NULL;
X
+ /* sanity check: some of the commands generated by the mid-layer
+ * have an eccentric idea of their sc_data_direction */
+ if(!SCp->use_sg && !SCp->request_bufflen
+ && SCp->sc_data_direction != SCSI_DATA_NONE) {
+#ifdef NCR_700_DEBUG
+ printk("53c700: Command");
+ print_command(SCp->cmnd);
+ printk("Has wrong data direction %d\n", SCp->sc_data_direction);
+#endif
+ SCp->sc_data_direction = SCSI_DATA_NONE;
+ }
+
X switch (SCp->cmnd[0]) {
X case REQUEST_SENSE:
X /* clear the internal sense magic */
@@ -1965,12 +2013,14 @@
X }
X slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
X slot->SG[i].pAddr = 0;
- dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
+ NCR_700_dma_cache_wback((unsigned long)slot->SG, sizeof(slot->SG));
X DEBUG((" SETTING %08lx to %x\n",
- virt_to_bus(&slot->SG[i].ins),
+ (&slot->pSG[i].ins),
X slot->SG[i].ins));
X }
X slot->resume_offset = 0;
+ slot->pCmd = pci_map_single(hostdata->pci_dev, SCp->cmnd,
+ sizeof(SCp->cmnd), PCI_DMA_TODEVICE);
X NCR_700_start_command(SCp);
X return 0;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- v2.4.12/linux/drivers/scsi/53c700.h Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/53c700.h Thu Oct 11 09:43:29 2001
@@ -40,6 +40,24 @@
X #error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core."
X #endif
X
+/* macros for consistent memory allocation */
+
+#ifdef CONFIG_53C700_USE_CONSISTENT
+#define NCR_700_dma_cache_wback(mem, size) \
+ if(!hostdata->consistent) \
+ dma_cache_wback(mem, size)
+#define NCR_700_dma_cache_inv(mem, size) \
+ if(!hostdata->consistent) \
+ dma_cache_inv(mem, size)
+#define NCR_700_dma_cache_wback_inv(mem, size) \
+ if(!hostdata->consistent) \
+ dma_cache_wback_inv(mem, size)
+#else
+#define NCR_700_dma_cache_wback(mem, size) dma_cache_wback(mem,size)
+#define NCR_700_dma_cache_inv(mem, size) dma_cache_inv(mem,size)
+#define NCR_700_dma_cache_wback_inv(mem, size) dma_cache_wback_inv(mem,size)
+#endif
+
X
X struct NCR_700_Host_Parameters;
X
@@ -86,6 +104,7 @@
X #define NCR_700_DEV_NEGOTIATED_SYNC (1<<16)
X #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17)
X #define NCR_700_DEV_BEGIN_TAG_QUEUEING (1<<18)
+#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19)


X
X static inline void

X NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
@@ -174,6 +193,8 @@
X __u16 tag;
X __u32 resume_offset;
X Scsi_Cmnd *cmnd;
+ /* The pci_mapped address of the actual command in cmnd */
+ dma_addr_t pCmd;
X __u32 temp;
X /* if this command is a pci_single mapping, holds the dma address
X * for later unmapping in the done routine */
@@ -191,19 +212,22 @@
X int clock; /* board clock speed in MHz */
X __u32 base; /* the base for the port (copied to host) */
X struct pci_dev *pci_dev;
- __u8 dmode_extra; /* adjustable bus settings */
- __u8 differential:1; /* if we are differential */
+ __u32 dmode_extra; /* adjustable bus settings */
+ __u32 differential:1; /* if we are differential */
X #ifdef CONFIG_53C700_LE_ON_BE
X /* This option is for HP only. Set it if your chip is wired for
X * little endian on this platform (which is big endian) */
- __u8 force_le_on_be:1;
+ __u32 force_le_on_be:1;
X #endif
- __u8 chip710:1; /* set if really a 710 not 700 */
- __u8 burst_disable:1; /* set to 1 to disable 710 bursting */
+ __u32 chip710:1; /* set if really a 710 not 700 */
+ __u32 burst_disable:1; /* set to 1 to disable 710 bursting */
X
X /* NOTHING BELOW HERE NEEDS ALTERING */
- __u8 fast:1; /* if we can alter the SCSI bus clock
+ __u32 fast:1; /* if we can alter the SCSI bus clock
X speed (so can negiotiate sync) */
+#ifdef CONFIG_53C700_USE_CONSISTENT
+ __u32 consistent:1;
+#endif
X
X int sync_clock; /* The speed of the SYNC core */
X
@@ -216,15 +240,23 @@
X spinlock_t lock;
X enum NCR_700_Host_State state; /* protected by state lock */
X Scsi_Cmnd *cmd;
-
+ /* Note: pScript contains the single consistent block of
+ * memory. All the msgin, msgout and status are allocated in
+ * this memory too (at separate cache lines). TOTAL_MEM_SIZE
+ * represents the total size of this area */
+#define MSG_ARRAY_SIZE 8
+#define MSGOUT_OFFSET (L1_CACHE_ALIGN(sizeof(SCRIPT)))
X __u8 *msgout;
-#define MSG_ARRAY_SIZE 16
- __u8 tag_negotiated;
- __u8 *status;
+#define MSGIN_OFFSET (MSGOUT_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
X __u8 *msgin;
+#define STATUS_OFFSET (MSGIN_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
+ __u8 *status;
+#define SLOTS_OFFSET (STATUS_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
X struct NCR_700_command_slot *slots;
+#define TOTAL_MEM_SIZE (SLOTS_OFFSET + L1_CACHE_ALIGN(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST))
X int saved_slot_position;
X int command_slot_count; /* protected by state lock */
+ __u8 tag_negotiated;
X __u8 rev;
X __u8 reselection_id;
X /* flags for the host */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.4.12/linux/drivers/scsi/Config.in Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/Config.in Thu Oct 11 09:43:29 2001
@@ -122,10 +122,11 @@
X fi
X fi
X if [ "$CONFIG_PARISC" = "y" ]; then
- dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI700 $CONFIG_SCSI
+ dep_tristate 'HP LASI SCSI support for 53c700/710' CONFIG_SCSI_LASI700 $CONFIG_SCSI
X if [ "$CONFIG_SCSI_LASI700" != "n" ]; then
X define_bool CONFIG_53C700_MEM_MAPPED y
X define_bool CONFIG_53C700_LE_ON_BE y
+ define_bool CONFIG_53C700_USE_CONSISTENT y
X fi
X fi
X dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/README.53c700 linux/drivers/scsi/README.53c700
--- v2.4.12/linux/drivers/scsi/README.53c700 Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/README.53c700 Thu Oct 11 09:43:29 2001
@@ -1,17 +1,154 @@
-This driver supports the 53c700 and 53c700-66 chips only. It is full
-featured and does sync (-66 only), disconnects and tag command
-queueing.
+General Description
+===================
+
+This driver supports the 53c700 and 53c700-66 chips. It also supports
+the 53c710 but only in 53c700 emulation mode. It is full featured and
+does sync (-66 and 710 only), disconnects and tag command queueing.
X
X Since the 53c700 must be interfaced to a bus, you need to wrapper the
X card detector around this driver. For an example, see the
-NCR_D700.[ch] files.
+NCR_D700.[ch] or lasi700.[ch] files.
X
X The comments in the 53c700.[ch] files tell you which parts you need to
X fill in to get the driver working.
X
-The driver is currently I/O mapped only, but it should be easy enough
-to memory map (just make the port reads #defines with MEM_MAPPED for
-memory mapping or nothing for I/O mapping, specify an extra rule for
-53c700-mem.o with the -DMEM_MAPPED flag and make your driver use it,
-that way the make rules will generate the correct version).
+
+Compile Time Flags
+==================
+
+The driver may be either io mapped or memory mapped. This is
+selectable by configuration flags:
+
+CONFIG_53C700_MEM_MAPPED
+
+define if the driver is memory mapped.
+
+CONFIG_53C700_IO_MAPPED
+
+define if the driver is to be io mapped.
+
+One or other of the above flags *must* be defined.
+
+Other flags are:
+
+CONFIG_53C700_LE_ON_BE
+
+define if the chipset must be supported in little endian mode on a big
+endian architecture (used for the 700 on parisc).
+
+CONFIG_53C700_USE_CONSISTENT
+
+allocate consistent memory (should only be used if your architecture
+has a mixture of consistent and inconsistent memory). Fully
+consistent or fully inconsistent architectures should not define this.
+
+
+Using the Chip Core Driver
+==========================
+
+In order to plumb the 53c700 chip core driver into a working SCSI
+driver, you need to know three things about the way the chip is wired
+into your system (or expansion card).
+
+1. The clock speed of the SCSI core
+2. The interrupt line used
+3. The memory (or io space) location of the 53c700 registers.
+
+Optionally, you may also need to know other things, like how to read
+the SCSI Id from the card bios or whether the chip is wired for
+differential operation.
+
+Usually you can find items 2. and 3. from general spec. documents or
+even by examining the configuration of a working driver under another
+operating system.
+
+The clock speed is usually buried deep in the technical literature.
+It is required because it is used to set up both the synchronous and
+asynchronous dividers for the chip. As a general rule of thumb,
+manufacturers set the clock speed at the lowest possible setting
+consistent with the best operation of the chip (although some choose
+to drive it off the CPU or bus clock rather than going to the expense
+of an extra clock chip). The best operation clock speeds are:
+
+53c700 - 25MHz
+53c700-66 - 50MHz
+53c710 - 40Mhz
+
+Writing Your Glue Driver
+========================
+
+This will be a standard SCSI driver (I don't know of a good document
+describing this, just copy from some other driver) with at least a
+detect and release entry.
+
+In the detect routine, you need to allocate a struct
+NCR_700_Host_Parameters sized memory area and clear it (so that the
+default values for everything are 0). Then you must fill in the
+parameters that matter to you (see below), plumb the NCR_700_intr
+routine into the interrupt line and call NCR_700_detect with the host
+template and the new parameters as arguments. You should also call
+the relevant request_*_region function and place the register base
+address into the `base' pointer of the host parameters.
+
+In the release routine, you must free the NCR_700_Host_Parameters that
+you allocated, call the corresponding release_*_region and free the
+interrupt.
+
+Handling Interrupts
+-------------------
+
+In general, you should just plumb the card's interrupt line in with
+
+request_irq(irq, NCR_700_intr, <irq flags>, <driver name>, host);
+
+where host is the return from the relevant NCR_700_detect() routine.
+
+You may also write your own interrupt handling routine which calls
+NCR_700_intr() directly. However, you should only really do this if
+you have a card with more than one chip on it and you can read a
+register to tell which set of chips wants the interrupt.
+
+Settable NCR_700_Host_Parameters
+--------------------------------
+
+The following are a list of the user settable parameters:
+
+clock: (MANDATORY)
+
+Set to the clock speed of the chip in MHz.
+
+base: (MANDATORY)
+
+set to the base of the io or mem region for the register set. On 64
+bit architectures this is only 32 bits wide, so the registers must be
+mapped into the low 32 bits of memory.
+
+pci_dev: (OPTIONAL)
+
+set to the PCI board device. Leave NULL for a non-pci board. This is
+used for the pci_alloc_consistent() and pci_map_*() functions.
+
+dmode_extra: (OPTIONAL, 53c710 only)
+
+extra flags for the DMODE register. These are used to control bus
+output pins on the 710. The settings should be a combination of
+DMODE_FC1 and DMODE_FC2. What these pins actually do is entirely up
+to the board designer. Usually it is safe to ignore this setting.
+
+differential: (OPTIONAL)
+
+set to 1 if the chip drives a differential bus.
+
+force_le_on_be: (OPTIONAL, only if CONFIG_53C700_LE_ON_BE is set)
+
+set to 1 if the chip is operating in little endian mode on a big
+endian architecture.
+
+chip710: (OPTIONAL)
+
+set to 1 if the chip is a 53c710.
+
+burst_disable: (OPTIONAL, 53c710 only)
+
+disable 8 byte bursting for DMA transfers.
X
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.4.12/linux/drivers/scsi/aha152x.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/aha152x.c Thu Oct 11 09:43:29 2001
@@ -390,13 +390,11 @@
X #endif /* !defined(AHA152X_DEBUG) */
X
X #ifdef __ISAPNP__
-
X static struct isapnp_device_id id_table[] __devinitdata = {
X { ISAPNP_DEVICE_SINGLE('A','D','P',0x1505, 'A','D','P',0x1505), },
X { ISAPNP_DEVICE_SINGLE_END, }
X };
X MODULE_DEVICE_TABLE(isapnp, id_table);
-
X #endif /* ISAPNP */


X #endif /* MODULE */

X
@@ -981,28 +979,6 @@
X }
X printk("ok\n");
X }
-#ifdef __ISAPNP__
- while (setup_count <= 2 &&
- (dev = isapnp_find_dev (NULL, ISAPNP_VENDOR('A','D','P'),
- ISAPNP_FUNCTION(0x1505), dev))) {
- if (dev->prepare(dev) < 0)
- continue;
- if (dev->active)
- continue;
- if (!(dev->resource[0].flags & IORESOURCE_IO))
- continue;
- dev->resource[0].flags |= IORESOURCE_AUTO;
- if (dev->activate(dev) < 0)
- continue;
- setup[setup_count].io_port = dev->resource[0].start;
- setup[setup_count].irq = dev->irq_resource[0].start;
- pnpdev[num_pnpdevs++] = dev;
- printk (KERN_INFO
- "aha152x: found ISAPnP AVA-1505A at address 0x%03X, IRQ %d\n",
- setup[setup_count].io_port, setup[setup_count].irq);
- setup_count++;
- }
-#endif
X
X #if defined(SETUP0)
X if (setup_count < 2) {
@@ -1132,6 +1108,41 @@
X setup[setup_count].ext_trans);
X }
X #endif
+
+#ifdef __ISAPNP__
+ while ( setup_count<2 && (dev=isapnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
+ if (dev->prepare(dev) < 0)
+ continue;
+ if (dev->active)
+ continue;
+ if (!(dev->resource[0].flags & IORESOURCE_IO))
+ continue;
+ dev->resource[0].flags |= IORESOURCE_AUTO;
+ if (dev->activate(dev) < 0)
+ continue;
+ if ( setup_count==1 && dev->resource[0].start==setup[0].io_port) {
+ dev->deactivate(dev);
+ continue;
+ }
+ setup[setup_count].io_port = dev->resource[0].start;
+ setup[setup_count].irq = dev->irq_resource[0].start;
+ setup[setup_count].scsiid = 7;
+ setup[setup_count].reconnect = 1;
+ setup[setup_count].parity = 1;
+ setup[setup_count].synchronous = 1;
+ setup[setup_count].delay = DELAY_DEFAULT;
+ setup[setup_count].ext_trans = 0;
+#if defined(AHA152X_DEBUG)
+ setup[setup_count].debug = DEBUG_DEFAULT;
+#endif
+ pnpdev[num_pnpdevs++] = dev;
+ printk (KERN_INFO
+ "aha152x: found ISAPnP AVA-1505A at io=0x%03x, irq=%d\n",
+ setup[setup_count].io_port, setup[setup_count].irq);
+ setup_count++;
+ }
+#endif
+
X
X #if defined(AUTOCONF)
X if (setup_count < 2) {
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v2.4.12/linux/drivers/scsi/aha1542.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/aha1542.c Fri Oct 12 15:35:53 2001
@@ -67,12 +67,10 @@
X int nseg,
X int badseg)
X {
- printk(KERN_CRIT "sgpnt[%d:%d] addr %p/0x%lx alt %p/0x%lx length %d\n",
+ printk(KERN_CRIT "sgpnt[%d:%d] addr %p/0x%lx length %d\n",
X badseg, nseg,
X sgpnt[badseg].address,
X SCSI_PA(sgpnt[badseg].address),
- sgpnt[badseg].alt_address,
- sgpnt[badseg].alt_address ? SCSI_PA(sgpnt[badseg].alt_address) : 0,
X sgpnt[badseg].length);
X
X /*
@@ -716,7 +714,7 @@
X unsigned char *ptr;
X printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
X for (i = 0; i < SCpnt->use_sg; i++) {
- printk(KERN_CRIT "%d: %x %x %d\n", i, (unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
+ printk(KERN_CRIT "%d: %p %d\n", i, sgpnt[i].address,
X sgpnt[i].length);
X };
X printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.12/linux/drivers/scsi/aic7xxx_old.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/scsi/aic7xxx_old.c Thu Oct 11 09:43:30 2001
@@ -220,11 +220,6 @@


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

-
-#if defined(PCMCIA)
-# undef MODULE
-#endif
-
X #include <stdarg.h>
X #include <asm/io.h>
X #include <asm/irq.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c
--- v2.4.12/linux/drivers/scsi/dpt_i2o.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/dpt_i2o.c Mon Oct 22 08:40:41 2001
@@ -78,9 +78,9 @@
X {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
X #ifdef __i386__
X PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
-#elif defined __ia64__
+#elif defined(__ia64__)
X PROC_INTEL, PROC_IA64,
-#elif define __sparc__
+#elif defined(__sparc__)
X PROC_ULTRASPARC,
X #elif defined(__alpha__)
X PROC_ALPHA ,
@@ -1152,12 +1152,12 @@
X timeout *= HZ;
X if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
X if(!timeout){
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X spin_unlock_irq(&io_request_lock);
X schedule();
X spin_lock_irq(&io_request_lock);
X } else {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X spin_unlock_irq(&io_request_lock);
X schedule_timeout(timeout*HZ);
X spin_lock_irq(&io_request_lock);
@@ -1799,11 +1799,11 @@
X
X #if defined __i386__
X adpt_i386_info(&si);
-#elif defined __ia64__
+#elif defined (__ia64__)
X adpt_ia64_info(&si);
-#elif define __sparc__
+#elif defined(__sparc__)
X adpt_sparc_info(&si);
-#elif defined __alpha__
+#elif defined (__alpha__)
X adpt_alpha_info(&si);
X #else
X si.processorType = 0xff ;
@@ -1838,7 +1838,7 @@
X #endif
X
X #if defined __alpha__
-static void adpt_sparc_info(sysInfo_S* si)
+static void adpt_alpha_info(sysInfo_S* si)
X {
X // This is all the info we need for now
X // We will add more info as our new
@@ -3324,4 +3324,4 @@
X static Scsi_Host_Template driver_template = DPT_I2O;
X #include "scsi_module.c"
X EXPORT_NO_SYMBOLS;
-MODULE_LICENSE("BSD without advertising clause");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/i60uscsi.h linux/drivers/scsi/i60uscsi.h
--- v2.4.12/linux/drivers/scsi/i60uscsi.h Fri Mar 2 18:38:38 2001
+++ linux/drivers/scsi/i60uscsi.h Thu Oct 11 09:43:30 2001
@@ -61,6 +61,7 @@
X **************************************************************************/
X
X #include <linux/config.h>
+#include <linux/types.h>
X
X #define ULONG unsigned long
X #define PVOID void *
@@ -72,11 +73,7 @@
X #define UBYTE unsigned char
X #define UWORD unsigned short
X #define UDWORD unsigned long
-#ifdef ALPHA
-#define U32 unsigned int
-#else
-#define U32 unsigned long
-#endif
+#define U32 u32
X
X #ifndef NULL
X #define NULL 0 /* zero */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/i91uscsi.h linux/drivers/scsi/i91uscsi.h
--- v2.4.12/linux/drivers/scsi/i91uscsi.h Fri Mar 2 18:38:38 2001
+++ linux/drivers/scsi/i91uscsi.h Thu Oct 11 09:43:30 2001
@@ -54,6 +54,7 @@
X **************************************************************************/
X
X #include <linux/config.h>
+#include <linux/types.h>
X
X #define ULONG unsigned long
X #define USHORT unsigned short
@@ -64,11 +65,7 @@
X #define UBYTE unsigned char
X #define UWORD unsigned short
X #define UDWORD unsigned long
-#ifdef ALPHA
-#define U32 unsigned int
-#else
-#define U32 unsigned long
-#endif
+#define U32 u32
X
X #ifndef NULL
X #define NULL 0 /* zero */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h
--- v2.4.12/linux/drivers/scsi/ini9100u.h Fri Apr 27 13:59:18 2001
+++ linux/drivers/scsi/ini9100u.h Thu Oct 11 09:43:30 2001
@@ -74,6 +74,7 @@
X #ifndef LINUX_VERSION_CODE
X #include <linux/version.h>
X #endif
+#include <linux/types.h>
X
X #include "sd.h"
X
@@ -121,17 +122,13 @@
X #define ULONG unsigned long
X #define USHORT unsigned short
X #define UCHAR unsigned char
-#define BYTE unsigned char
+#define BYTE u8
X #define WORD unsigned short
X #define DWORD unsigned long
-#define UBYTE unsigned char
+#define UBYTE u8
X #define UWORD unsigned short
X #define UDWORD unsigned long
-#ifdef ALPHA
-#define U32 unsigned int
-#else
-#define U32 unsigned long
-#endif
+#define U32 u32
X
X #ifndef NULL
X #define NULL 0 /* zero */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h
--- v2.4.12/linux/drivers/scsi/inia100.h Fri Mar 2 18:38:38 2001
+++ linux/drivers/scsi/inia100.h Thu Oct 11 09:43:30 2001
@@ -68,6 +68,8 @@
X #include <linux/version.h>
X #endif
X
+#include <linux/types.h>
+
X #include "sd.h"
X
X extern int inia100_detect(Scsi_Host_Template *);
@@ -122,11 +124,7 @@
X #define UBYTE unsigned char
X #define UWORD unsigned short
X #define UDWORD unsigned long
-#ifdef ALPHA
-#define U32 unsigned int
-#else
-#define U32 unsigned long
-#endif
+#define U32 u32
X
X #ifndef NULL
X #define NULL 0 /* zero */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/osst.c linux/drivers/scsi/osst.c
--- v2.4.12/linux/drivers/scsi/osst.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/osst.c Fri Oct 12 15:35:53 2001
@@ -4935,7 +4935,6 @@
X tb->sg[0].address =
X (unsigned char *)__get_free_pages(priority, order);
X if (tb->sg[0].address != NULL) {
- tb->sg[0].alt_address = NULL;
X tb->sg[0].length = b_size;
X break;
X }
@@ -4971,7 +4970,6 @@
X tb = NULL;
X break;
X }
- tb->sg[segs].alt_address = NULL;
X tb->sg[segs].length = b_size;
X got += b_size;
X segs++;
@@ -5045,7 +5043,6 @@
X normalize_buffer(STbuffer);
X return FALSE;
X }
- STbuffer->sg[segs].alt_address = NULL;
X STbuffer->sg[segs].length = b_size;
X STbuffer->sg_segs += 1;
X got += b_size;
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.c Thu Oct 11 09:04:57 2001
@@ -23,7 +23,7 @@
X
X ***********************************************************************/
X
-/* $Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $ */
+/* $Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $ */
X
X #ifdef NSP_KERNEL_2_2
X #include <pcmcia/config.h>
@@ -66,15 +66,14 @@
X
X MODULE_AUTHOR("YOKOTA Hiroshi <yok...@netlab.is.tsukuba.ac.jp>");
X MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
-MODULE_LICENSE("GPL");
-
X MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
+MODULE_LICENSE("GPL");
X
X #ifdef PCMCIA_DEBUG
X static int pc_debug = PCMCIA_DEBUG;
X MODULE_PARM(pc_debug, "i");
X MODULE_PARM_DESC(pc_debug, "set debug level");
-static char *version = "$Id: nsp_cs.c,v 1.35 2001/07/05 16:58:24 elca Exp $";
+static char *version = "$Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $";
X #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
X #else
X #define DEBUG(n, args...) /* */
@@ -93,18 +92,6 @@
X struct bus_operations *bus;
X } scsi_info_t;
X
-static void nsp_cs_release(u_long arg);
-static int nsp_cs_event(event_t event, int priority,
- event_callback_args_t *args);
-static dev_link_t *nsp_cs_attach(void);
-static void nsp_cs_detach(dev_link_t *);
-static int nsp_detect(Scsi_Host_Template * );
-static int nsp_release(struct Scsi_Host *shpnt);
-static const char * nsp_info(struct Scsi_Host *shpnt);
-static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-static int nsp_abort(Scsi_Cmnd *);
-static int nsp_reset(Scsi_Cmnd *, unsigned int);
-
X
X /*----------------------------------------------------------------*/
X
@@ -191,7 +178,7 @@
X data->CurrentSC = NULL;
X SCpnt->result = DID_BAD_TARGET << 16;
X done(SCpnt);
- return FALSE;
+ return -1;
X }
X
X show_command(SCpnt);
@@ -229,12 +216,12 @@
X data->CurrentSC = NULL;
X SCpnt->result = DID_NO_CONNECT << 16;
X done(SCpnt);
- return FALSE;
+ return -1;
X }
X
X
X //DEBUG(0, __FUNCTION__ "() out\n");
- return TRUE;
+ return 0;
X }
X
X /*
@@ -1185,7 +1172,7 @@
X return;
X }
X
-#ifdef DBG_SHOWCOMMAND
+#ifdef PCMCIA_DEBUG
X #include "nsp_debug.c"
X #endif /* DBG_SHOWCOMMAND */
X
@@ -1205,13 +1192,13 @@
X host->unique_id = data->BaseAddress;
X host->n_io_port = data->NumAddress;
X host->irq = data->IrqNumber;
- host->dma_channel = -1;
+ host->dma_channel = 0xff; /* not use dms */
X
X sprintf(nspinfo,
X /* Buffer size is 100 bytes */
X /* 0 1 2 3 4 5 6 7 8 9 0*/
X /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
- "NinjaSCSI-3/32Bi Driver version 2.7, I/O 0x%04lx-0x%04lx IRQ %2d",
+ "NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d",
X host->io_port, host->io_port + host->n_io_port,
X host->irq);
X sht->name = nspinfo;
@@ -1221,6 +1208,7 @@
X return 1; /* detect done. */
X }
X
+/* nsp_cs requires own release handler because its uses dev_id (=data) */
X static int nsp_release(struct Scsi_Host *shpnt)
X {
X nsp_hw_data *data = &nsp_data;
@@ -1228,7 +1216,7 @@
X if (shpnt->irq) {
X free_irq(shpnt->irq, data);
X }
- if (shpnt->io_port) {
+ if (shpnt->io_port && shpnt->n_io_port) {
X release_region(shpnt->io_port, shpnt->n_io_port);
X }
X return 0;
@@ -1249,7 +1237,9 @@
X {
X DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why);
X
- return nsp_eh_bus_reset(SCpnt);
+ nsp_eh_bus_reset(SCpnt);
+
+ return SCSI_RESET_SUCCESS;
X }
X
X static int nsp_abort(Scsi_Cmnd *SCpnt)
@@ -1258,7 +1248,7 @@
X
X nsp_eh_bus_reset(SCpnt);
X
- return SUCCESS;
+ return SCSI_ABORT_SUCCESS;
X }
X
X /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
@@ -1271,6 +1261,7 @@
X DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
X
X nsp_eh_bus_reset(SCpnt);
+


X return SUCCESS;
X }
X

@@ -1309,9 +1300,8 @@
X DEBUG(0, __FUNCTION__ "\n");
X
X nsphw_init(data);
- nsp_eh_bus_reset(SCpnt);
X
- return SUCCESS;
+ return nsp_eh_bus_reset(SCpnt);
X }
X
X
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.h linux/drivers/scsi/pcmcia/nsp_cs.h
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_cs.h Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.h Thu Oct 11 09:04:57 2001
@@ -6,22 +6,17 @@
X Ver 0.1 : Initial version.
X
X This software may be used and distributed according to the terms of
- the GNU Public License.
+ the GNU General Public License.
X
X =========================================================*/
X
-/* $Id: nsp_cs.h,v 1.21 2001/07/04 14:45:31 elca Exp $ */
+/* $Id: nsp_cs.h,v 1.27 2001/09/10 10:31:13 elca Exp $ */
X
X #ifndef __nsp_cs__
X #define __nsp_cs__
X
X /* for debugging */
-/*
-#define DBG
-#define DBG_PRINT
-#define DBG_SHOWCOMMAND
-#define PCMCIA_DEBUG 9
-*/
+/*#define PCMCIA_DEBUG 9*/
X
X /*
X #define static
@@ -258,25 +253,36 @@
X } nsp_hw_data;
X
X
+static void nsp_cs_release(u_long arg);
+static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
+static dev_link_t *nsp_cs_attach(void);
+static void nsp_cs_detach(dev_link_t *);
+
X static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
X static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
X
+static int nsp_detect(Scsi_Host_Template * );
+static int nsp_release(struct Scsi_Host *shpnt);
+static const char * nsp_info(struct Scsi_Host *shpnt);
+static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+
+static int nsp_abort(Scsi_Cmnd *);
+static int nsp_reset(Scsi_Cmnd *, unsigned int);
+
X static int nsp_eh_abort(Scsi_Cmnd * SCpnt);
X static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);
X static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
X static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt);
X
-static int nsp_fifo_count(Scsi_Cmnd *SCpnt);
+static int nsp_fifo_count(Scsi_Cmnd *SCpnt);
X static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
+static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
X
X #ifdef PCMCIA_DEBUG
-# ifdef DBG_SHOWCOMMAND
X static void show_command(Scsi_Cmnd *ptr);
X static void show_phase(Scsi_Cmnd *SCpnt);
X static void show_busphase(unsigned char stat);
X static void show_message(nsp_hw_data *data);
-# endif /* DBG_SHOWCOMMAND */
X #else
X # define show_command(ptr) /* */
X # define show_phase(SCpnt) /* */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_debug.c linux/drivers/scsi/pcmcia/nsp_debug.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_debug.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/pcmcia/nsp_debug.c Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
X the GNU General Public License.
X =========================================================================*/
X
-/* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
+/* $Id: nsp_debug.c,v 1.8 2001/09/07 04:32:28 elca Exp $ */
X
X /*
X * Show the command data of a command
@@ -85,7 +85,7 @@
X }
X }
X
-void print_commandk (unsigned char *command)
+static void print_commandk (unsigned char *command)
X {
X int i,s;
X printk(KERN_DEBUG);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_io.h linux/drivers/scsi/pcmcia/nsp_io.h
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_io.h Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/pcmcia/nsp_io.h Thu Oct 11 09:04:57 2001
@@ -3,11 +3,11 @@
X By: YOKOTA Hiroshi <yok...@netlab.is.tsukuba.ac.jp>
X
X This software may be used and distributed according to the terms of
- the GNU Public License.
+ the GNU General Public License.
X
X */
X
-/* $Id: nsp_io.h,v 1.8 2001/01/30 05:16:02 elca Exp $ */
+/* $Id: nsp_io.h,v 1.9 2001/09/07 04:32:42 elca Exp $ */
X
X #ifndef __NSP_IO_H__
X #define __NSP_IO_H__
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/pcmcia/nsp_message.c linux/drivers/scsi/pcmcia/nsp_message.c
--- v2.4.12/linux/drivers/scsi/pcmcia/nsp_message.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/pcmcia/nsp_message.c Thu Oct 11 09:04:57 2001
@@ -6,7 +6,7 @@
X the GNU General Public License.
X */
X
-/* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
+/* $Id: nsp_message.c,v 1.7 2001/09/07 04:33:01 elca Exp $ */
X
X static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
X {
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- v2.4.12/linux/drivers/scsi/qlogicfc.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/qlogicfc.c Fri Oct 12 15:35:53 2001
@@ -21,6 +21,9 @@
X *
X * Big endian support and dynamic DMA mapping added
X * by Jakub Jelinek <ja...@redhat.com>.
+ *
+ * Conversion to final pci64 DMA interfaces
+ * by David S. Miller <da...@redhat.com>.


X */
X
X /*

@@ -63,31 +66,10 @@
X #include "sd.h"
X #include "hosts.h"
X
-#if 1
-/* Once pci64_ DMA mapping interface is in, kill this. */
-typedef dma_addr_t dma64_addr_t;
-#define pci64_alloc_consistent(d,s,p) pci_alloc_consistent((d),(s),(p))
-#define pci64_free_consistent(d,s,c,a) pci_free_consistent((d),(s),(c),(a))
-#define pci64_map_single(d,c,s,dir) pci_map_single((d),(c),(s),(dir))
-#define pci64_map_sg(d,s,n,dir) pci_map_sg((d),(s),(n),(dir))
-#define pci64_unmap_single(d,a,s,dir) pci_unmap_single((d),(a),(s),(dir))
-#define pci64_unmap_sg(d,s,n,dir) pci_unmap_sg((d),(s),(n),(dir))
-#if BITS_PER_LONG > 32
X #define pci64_dma_hi32(a) ((u32) (0xffffffff & (((u64)(a))>>32)))
X #define pci64_dma_lo32(a) ((u32) (0xffffffff & (((u64)(a)))))
-#else
-#define pci64_dma_hi32(a) 0
-#define pci64_dma_lo32(a) (a)
-#endif /* BITS_PER_LONG */
-#define pci64_dma_build(hi,lo) (lo)
-#define sg_dma64_address(s) sg_dma_address(s)
-#define sg_dma64_len(s) sg_dma_len(s)
-#if BITS_PER_LONG > 32
-#define PCI64_DMA_BITS 64
-#else
-#define PCI64_DMA_BITS 32
-#endif /* BITS_PER_LONG */
-#endif
+#define pci64_dma_build(hi,lo) \
+ ((dma_addr_t)(((u64)(lo))|(((u64)(hi))<<32)))
X
X #include "qlogicfc.h"
X
@@ -243,13 +225,8 @@
X };
X
X /* entry header type commands */
-#if PCI64_DMA_BITS > 32
X #define ENTRY_COMMAND 0x19
X #define ENTRY_CONTINUATION 0x0a
-#else
-#define ENTRY_COMMAND 0x11
-#define ENTRY_CONTINUATION 0x02
-#endif
X
X #define ENTRY_STATUS 0x03
X #define ENTRY_MARKER 0x04
@@ -260,23 +237,12 @@
X #define EFLAG_BAD_HEADER 4
X #define EFLAG_BAD_PAYLOAD 8
X
-#if PCI64_DMA_BITS > 32
-
X struct dataseg {
X u_int d_base;
X u_int d_base_hi;
X u_int d_count;
X };
X
-#else
-
-struct dataseg {
- u_int d_base;
- u_int d_count;
-};
-
-#endif
-
X struct Command_Entry {
X struct Entry_header hdr;
X u_int handle;
@@ -301,18 +267,10 @@
X #define CFLAG_READ 0x20
X #define CFLAG_WRITE 0x40
X
-#if PCI64_DMA_BITS > 32
-struct Continuation_Entry {
- struct Entry_header hdr;
- struct dataseg dataseg[DATASEGS_PER_CONT];
-};
-#else
X struct Continuation_Entry {
X struct Entry_header hdr;
- u32 rsvd;
X struct dataseg dataseg[DATASEGS_PER_CONT];
X };
-#endif
X
X struct Marker_Entry {
X struct Entry_header hdr;
@@ -741,7 +699,7 @@
X struct isp2x00_hostdata *hostdata;
X struct pci_dev *pdev;
X unsigned short device_ids[2];
- dma64_addr_t busaddr;
+ dma_addr_t busaddr;


X int i;
X
X

@@ -753,7 +711,7 @@
X tmpt->proc_name = "isp2x00";
X
X if (pci_present() == 0) {
- printk("qlogicfc : PCI not present\n");
+ printk(KERN_INFO "qlogicfc : PCI not present\n");


X return 0;
X }
X

@@ -763,6 +721,11 @@


X if (pci_enable_device(pdev))
X continue;
X

+ /* Try to configure DMA attributes. */


+ if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
+ pci_set_dma_mask(pdev, (u64) 0xffffffff))
+ continue;
+

X host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata));
X if (!host) {
X printk("qlogicfc%d : could not register host.\n", hosts);
@@ -776,11 +739,11 @@
X
X memset(hostdata, 0, sizeof(struct isp2x00_hostdata));
X hostdata->pci_dev = pdev;
- hostdata->res = pci64_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr);
+ hostdata->res = pci_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr);
X
X if (!hostdata->res){
X printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hosts);
- pci64_free_consistent(pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+ pci_free_consistent(pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
X scsi_unregister(host);
X continue;
X }
@@ -813,7 +776,7 @@
X hostdata->host_id = hosts;
X
X if (isp2x00_init(host) || isp2x00_reset_hardware(host)) {
- pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+ pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
X scsi_unregister(host);
X continue;
X }
@@ -822,7 +785,7 @@
X if (request_irq(host->irq, do_isp2x00_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) {
X printk("qlogicfc%d : interrupt %d already in use\n",
X hostdata->host_id, host->irq);
- pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+ pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
X scsi_unregister(host);
X continue;
X }
@@ -831,7 +794,7 @@
X "in use\n",
X hostdata->host_id, host->io_port, host->io_port + 0xff);
X free_irq(host->irq, host);
- pci64_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+ pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
X scsi_unregister(host);
X continue;
X }
@@ -990,7 +953,7 @@
X u_int port_id;
X struct sns_cb *req;
X u_char *sns_response;
- dma64_addr_t busaddr;
+ dma_addr_t busaddr;
X struct isp2x00_hostdata *hostdata;
X
X hostdata = (struct isp2x00_hostdata *) host->hostdata;
@@ -1007,7 +970,7 @@
X }
X printk("qlogicfc%d : Fabric found.\n", hostdata->host_id);
X
- req = (struct sns_cb *)pci64_alloc_consistent(hostdata->pci_dev, sizeof(*req) + 608, &busaddr);
+ req = (struct sns_cb *)pci_alloc_consistent(hostdata->pci_dev, sizeof(*req) + 608, &busaddr);
X
X if (!req){
X printk("qlogicfc%d : Could not allocate DMA resources for fabric initialization\n", hostdata->host_id);
@@ -1109,12 +1072,12 @@
X done = 1;
X } else {
X printk("qlogicfc%d : Get All Next failed %x.\n", hostdata->host_id, param[0]);
- pci64_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
+ pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);


X return 0;
X }
X }

X
- pci64_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
+ pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);


X return 1;
X }
X

@@ -1124,7 +1087,7 @@
X int isp2x00_release(struct Scsi_Host *host)
X {
X struct isp2x00_hostdata *hostdata;
- dma64_addr_t busaddr;
+ dma_addr_t busaddr;
X
X ENTER("isp2x00_release");
X
@@ -1137,7 +1100,7 @@
X
X busaddr = pci64_dma_build(le32_to_cpu(hostdata->control_block.res_queue_addr_high),
X le32_to_cpu(hostdata->control_block.res_queue_addr_lo));
- pci64_free_consistent(hostdata->pci_dev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+ pci_free_consistent(hostdata->pci_dev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
X
X LEAVE("isp2x00_release");
X
@@ -1281,7 +1244,7 @@
X
X if (Cmnd->use_sg) {
X sg = (struct scatterlist *) Cmnd->request_buffer;
- sg_count = pci64_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X cmd->segment_cnt = cpu_to_le16(sg_count);
X ds = cmd->dataseg;
X /* fill in first two sg entries: */
@@ -1290,11 +1253,9 @@
X n = DATASEGS_PER_COMMAND;
X
X for (i = 0; i < n; i++) {
- ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma64_address(sg)));
-#if PCI64_DMA_BITS > 32
- ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma64_address(sg)));
-#endif
- ds[i].d_count = cpu_to_le32(sg_dma64_len(sg));
+ ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg)));
+ ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg)));
+ ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
X ++sg;
X }
X sg_count -= DATASEGS_PER_COMMAND;
@@ -1316,31 +1277,30 @@
X if (n > DATASEGS_PER_CONT)
X n = DATASEGS_PER_CONT;
X for (i = 0; i < n; ++i) {
- ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma64_address(sg)));
-#if PCI64_DMA_BITS > 32
- ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma64_address(sg)));
-#endif
- ds[i].d_count = cpu_to_le32(sg_dma64_len(sg));
+ ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg)));
+ ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg)));
+ ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
X ++sg;
X }
X sg_count -= n;
X }
X } else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) {
- dma64_addr_t busaddr = pci64_map_single(hostdata->pci_dev, Cmnd->request_buffer, Cmnd->request_bufflen,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ struct page *page = virt_to_page(Cmnd->request_buffer);
+ unsigned long offset = ((unsigned long)Cmnd->request_buffer &
+ ~PAGE_MASK);
+ dma_addr_t busaddr = pci_map_page(hostdata->pci_dev,
+ page, offset,
+ Cmnd->request_bufflen,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ Cmnd->SCp.dma_handle = busaddr;
X
- *(dma64_addr_t *)&Cmnd->SCp = busaddr;
X cmd->dataseg[0].d_base = cpu_to_le32(pci64_dma_lo32(busaddr));
-#if PCI64_DMA_BITS > 32
X cmd->dataseg[0].d_base_hi = cpu_to_le32(pci64_dma_hi32(busaddr));
-#endif
X cmd->dataseg[0].d_count = cpu_to_le32(Cmnd->request_bufflen);
X cmd->segment_cnt = cpu_to_le16(1);
X } else {
X cmd->dataseg[0].d_base = 0;
-#if PCI64_DMA_BITS > 32
X cmd->dataseg[0].d_base_hi = 0;
-#endif
X cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
X }
X
@@ -1433,16 +1393,17 @@
X Scsi_Cmnd *Cmnd = hostdata->handle_ptrs[i];
X
X if (Cmnd->use_sg)
- pci64_unmap_sg(hostdata->pci_dev,
- (struct scatterlist *)Cmnd->buffer,
- Cmnd->use_sg,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ pci_unmap_sg(hostdata->pci_dev,
+ (struct scatterlist *)Cmnd->buffer,
+ Cmnd->use_sg,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X else if (Cmnd->request_bufflen &&
- Cmnd->sc_data_direction != PCI_DMA_NONE)
- pci64_unmap_single(hostdata->pci_dev,
- *(dma64_addr_t *)&Cmnd->SCp,
- Cmnd->request_bufflen,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ Cmnd->sc_data_direction != PCI_DMA_NONE) {
+ pci_unmap_page(hostdata->pci_dev,
+ Cmnd->SCp.dma_handle,
+ Cmnd->request_bufflen,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ }
X
X hostdata->handle_ptrs[i]->result = DID_SOFT_ERROR << 16;
X
@@ -1539,16 +1500,16 @@
X hostdata->queued--;
X if (Cmnd != NULL) {
X if (Cmnd->use_sg)
- pci64_unmap_sg(hostdata->pci_dev,
- (struct scatterlist *)Cmnd->buffer,
- Cmnd->use_sg,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ pci_unmap_sg(hostdata->pci_dev,
+ (struct scatterlist *)Cmnd->buffer,
+ Cmnd->use_sg,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X else if (Cmnd->request_bufflen &&
X Cmnd->sc_data_direction != PCI_DMA_NONE)
- pci64_unmap_single(hostdata->pci_dev,
- *(dma64_addr_t *)&Cmnd->SCp,
- Cmnd->request_bufflen,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ pci_unmap_page(hostdata->pci_dev,
+ Cmnd->SCp.dma_handle,
+ Cmnd->request_bufflen,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X Cmnd->result = 0x0;
X (*Cmnd->scsi_done) (Cmnd);
X } else
@@ -1594,13 +1555,14 @@
X hostdata->queued--;
X
X if (Cmnd->use_sg)
- pci64_unmap_sg(hostdata->pci_dev,
- (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ pci_unmap_sg(hostdata->pci_dev,
+ (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE)
- pci64_unmap_single(hostdata->pci_dev, *(dma64_addr_t *)&Cmnd->SCp,
- Cmnd->request_bufflen,
- scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ pci_unmap_page(hostdata->pci_dev,
+ Cmnd->SCp.dma_handle,
+ Cmnd->request_bufflen,
+ scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
X
X /*
X * if any of the following are true we do not
@@ -1859,7 +1821,7 @@
X u_short param[8];
X struct isp2x00_hostdata *hostdata;
X int loop_count;
- dma64_addr_t busaddr;
+ dma_addr_t busaddr;
X
X ENTER("isp2x00_reset_hardware");
X
@@ -1970,9 +1932,15 @@
X hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0x00ff) << 8;
X hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0xff00) >> 8;
X
- /* FIXME: If the DMA transfer goes one way only, this should use PCI_DMA_TODEVICE and below as well. */
- busaddr = pci64_map_single(hostdata->pci_dev, &hostdata->control_block, sizeof(hostdata->control_block),
- PCI_DMA_BIDIRECTIONAL);
+ /* FIXME: If the DMA transfer goes one way only, this should use
+ * PCI_DMA_TODEVICE and below as well.
+ */
+ busaddr = pci_map_page(hostdata->pci_dev,
+ virt_to_page(&hostdata->control_block),
+ ((unsigned long) &hostdata->control_block &
+ ~PAGE_MASK),
+ sizeof(hostdata->control_block),
+ PCI_DMA_BIDIRECTIONAL);
X
X param[0] = MBOX_INIT_FIRMWARE;
X param[2] = (u_short) (pci64_dma_lo32(busaddr) >> 16);
@@ -1984,21 +1952,24 @@
X isp2x00_mbox_command(host, param);
X if (param[0] != MBOX_COMMAND_COMPLETE) {
X printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id, param[0]);
- pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
- PCI_DMA_BIDIRECTIONAL);
+ pci_unmap_page(hostdata->pci_dev, busaddr,
+ sizeof(hostdata->control_block),
+ PCI_DMA_BIDIRECTIONAL);
X return 1;
X }
X param[0] = MBOX_GET_FIRMWARE_STATE;
X isp2x00_mbox_command(host, param);
X if (param[0] != MBOX_COMMAND_COMPLETE) {
X printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id, param[0]);
- pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
- PCI_DMA_BIDIRECTIONAL);
+ pci_unmap_page(hostdata->pci_dev, busaddr,
+ sizeof(hostdata->control_block),
+ PCI_DMA_BIDIRECTIONAL);


X return 1;
X }
X

- pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),
- PCI_DMA_BIDIRECTIONAL);
+ pci_unmap_page(hostdata->pci_dev, busaddr,
+ sizeof(hostdata->control_block),
+ PCI_DMA_BIDIRECTIONAL);
X LEAVE("isp2x00_reset_hardware");
X
X return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/qlogicfc.h linux/drivers/scsi/qlogicfc.h
--- v2.4.12/linux/drivers/scsi/qlogicfc.h Mon Jun 26 12:02:16 2000
+++ linux/drivers/scsi/qlogicfc.h Sun Oct 21 10:36:54 2001
@@ -62,13 +62,8 @@
X * determined for each queue request anew.
X */
X
-#if BITS_PER_LONG > 32
X #define DATASEGS_PER_COMMAND 2
X #define DATASEGS_PER_CONT 5
-#else
-#define DATASEGS_PER_COMMAND 3
-#define DATASEGS_PER_CONT 7
-#endif
X
X #define QLOGICFC_REQ_QUEUE_LEN 127 /* must be power of two - 1 */
X #define QLOGICFC_MAX_SG(ql) (DATASEGS_PER_COMMAND + (((ql) > 0) ? DATASEGS_PER_CONT*((ql) - 1) : 0))
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.4.12/linux/drivers/scsi/scsi.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/scsi.c Mon Oct 15 19:30:33 2001
@@ -1837,6 +1837,8 @@
X
X pcount = next_scsi_host;
X
+ MOD_INC_USE_COUNT;
+
X /* The detect routine must carefully spinunlock/spinlock if
X it enables interrupts, since all interrupt handlers do
X spinlock as well.
@@ -1966,8 +1968,6 @@
X (scsi_init_memory_start - scsi_memory_lower_value) / 1024,
X (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
X #endif
-
- MOD_INC_USE_COUNT;
X
X if (out_of_space) {
X scsi_unregister_host(tpnt); /* easiest way to clean up?? */
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.4.12/linux/drivers/scsi/scsi.h Thu Oct 18 13:49:48 2001
+++ linux/drivers/scsi/scsi.h Tue Oct 23 22:01:56 2001
@@ -633,6 +633,8 @@
X struct scatterlist *buffer; /* which buffer */
X int buffers_residual; /* how many buffers left */
X
+ dma_addr_t dma_handle;
+
X volatile int Status;
X volatile int Message;
X volatile int have_data_in;
@@ -745,7 +747,8 @@
X unsigned request_bufflen; /* Actual request size */
X
X struct timer_list eh_timeout; /* Used to time out the command. */
- void *request_buffer; /* Actual requested buffer */
+ void *request_buffer; /* Actual requested buffer */
+ void **bounce_buffers; /* Array of bounce buffers when using scatter-gather */
X
X /* These elements define the operation we ultimately want to perform */
X unsigned char data_cmnd[MAX_COMMAND_SIZE];
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v2.4.12/linux/drivers/scsi/scsi_debug.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/scsi_debug.c Fri Oct 12 15:35:54 2001
@@ -154,10 +154,7 @@
X if (SCpnt->use_sg) {
X sgpnt = (struct scatterlist *) SCpnt->buffer;
X for (i = 0; i < SCpnt->use_sg; i++) {
- lpnt = (int *) sgpnt[i].alt_address;
- printk(":%p %p %d\n", sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
- if (lpnt)
- printk(" (Alt %x) ", lpnt[15]);
+ printk(":%p %d\n", sgpnt[i].address, sgpnt[i].length);
X };
X } else {
X printk("nosg: %p %p %d\n", SCpnt->request.buffer, SCpnt->buffer,
@@ -175,12 +172,6 @@
X printk("\n");
X if (flag == 0)
X return;
- lpnt = (unsigned int *) sgpnt[0].alt_address;
- for (i = 0; i < sizeof(Scsi_Cmnd) / 4 + 1; i++) {
- if ((i & 7) == 0)
- printk("\n");
- printk("%x ", *lpnt++);
- };
X #if 0
X printk("\n");
X lpnt = (unsigned int *) sgpnt[0].address;
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- v2.4.12/linux/drivers/scsi/scsi_lib.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/scsi_lib.c Fri Oct 12 15:35:54 2001
@@ -496,13 +496,16 @@
X */
X if (SCpnt->use_sg) {
X struct scatterlist *sgpnt;
+ void **bbpnt;
X int i;
X

SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 37'
echo 'File patch-2.4.13 is continued in part 38'
echo "38" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:09 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part39

#!/bin/sh -x
# this is part 39 of a 53 - part archive


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

if test "$Scheck" != 39; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X if (signal_pending(current)) {
X remove_wait_queue(&pdev->frameq, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X return -ERESTARTSYS;
X }
X schedule();


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X }

X remove_wait_queue(&pdev->frameq, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X
X /* The frame is ready. Expand in the image buffer
X requested by the user. I don't care if you
@@ -1656,18 +1666,37 @@
X break;
X }
X }
- else if (vendor_id == 0x046d) {
- switch(product_id) {
- case 0x08b0:
- Info("Logitech QuickCam 3000 Pro detected.\n");
- type_id = 730;
+ else if (vendor_id == 0x046d) {
+ switch(product_id) {
+ case 0x08b0:
+ Info("Logitech QuickCam 3000 Pro detected.\n");
+ type_id = 730;
X break;
X default:
X return NULL;
X break;
X }
X }
- else return NULL; /* Not Philips or Askey, for sure. */
+ else if (vendor_id == 0x055d) {
+ /* I don't know the difference between the C10 and the C30;
+ I suppose the difference is the sensor, but both cameras
+ work equally well with a type_id of 675
+ */
+ switch(product_id) {
+ case 0x9000:
+ Info("Samsung MPC-C10 USB webcam detected.\n");
+ type_id = 675;
+ break;
+ case 0x9001:
+ Info("Samsung MPC-C30 USB webcam detected.\n");
+ type_id = 675;
+ break;
+ default:
+ return NULL;
+ break;
+ }
+ }
+ else return NULL; /* Not Philips, Askey, Logitech or Samsung, for sure. */
X
X if (udev->descriptor.bNumConfigurations > 1)
X Info("Warning: more than 1 configuration available.\n");
@@ -1799,19 +1828,17 @@
X
X static char *size = NULL;
X static int fps = 0;
-static char *palette = NULL;
X static int fbufs = 0;
X static int mbufs = 0;
X static int trace = -1;
X static int compression = -1;
+static int leds[2] = { -1, -1 };
X
X MODULE_PARM(video_nr, "i");
X MODULE_PARM(size, "s");
X MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
X MODULE_PARM(fps, "i");
X MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
-MODULE_PARM(palette, "s");
-MODULE_PARM_DESC(palette, "Initial colour format of images. One of yuv420, yuv420p");
X MODULE_PARM(fbufs, "i");
X MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
X MODULE_PARM(mbufs, "i");
@@ -1822,7 +1849,8 @@
X MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
X MODULE_PARM(compression, "i");
X MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
-
+MODULE_PARM(leds, "2i");
+MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
X MODULE_DESCRIPTION("Philips USB webcam driver");
X MODULE_AUTHOR("Nemosoft Unv. <nemo...@smcc.demon.nl>");
X MODULE_LICENSE("GPL");
@@ -1833,7 +1861,7 @@
X char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
X
X Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n");
- Info("Also supports Askey VC010 cam.\n");
+ Info("Also supports the Askey VC010, Logitech Quickcam 3000 Pro and the Samsung MPC-C10 and MPC-C30.\n");
X
X if (fps) {
X if (fps < 5 || fps > 30) {


@@ -1858,18 +1886,6 @@
X }

X Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
X }
- if (palette) {
- /* Determine default palette */
- if (!strcmp(palette, "yuv420"))
- default_palette = VIDEO_PALETTE_YUV420;
- else if (!strcmp(palette, "yuv420p"))
- default_palette = VIDEO_PALETTE_YUV420P;
- else {
- Err("Palette not recognized: try palette=yuv420 or yuv420p.\n");
- return -EINVAL;
- }
- Info("Default palette set to %d.\n", default_palette);
- }
X if (mbufs) {
X if (mbufs < 1 || mbufs > MAX_IMAGES) {
X Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
@@ -1900,6 +1916,10 @@
X }
X if (power_save)
X Info("Enabling power save on open/close.\n");
+ if (leds[0] >= 0)
+ led_on = leds[0] / 100;
+ if (leds[1] >= 0)
+ led_off = leds[1] / 100;
X
X init_MUTEX(&mem_lock);
X Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/pwc-ioctl.h linux/drivers/usb/pwc-ioctl.h
--- v2.4.12/linux/drivers/usb/pwc-ioctl.h Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/pwc-ioctl.h Wed Oct 17 14:34:06 2001
@@ -76,6 +76,15 @@
X };
X
X
+/* Used with VIDIOCPWC[SG]LED */
+struct pwc_leds
+{
+ int led_on; /* Led on-time; range = 0..255 */
+ int led_off; /* */
+};
+
+
+
X /* Restore user settings */
X #define VIDIOCPWCRUSER _IO('v', 192)
X /* Save user settings */
@@ -107,9 +116,8 @@
X #define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance)
X
X /* Turn LED on/off ; int range 0..65535 */
-#define VIDIOCPWCSLED _IOW('v', 205, int)
-
+#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds)
X /* Get state of LED; int range 0..65535 */
-#define VIDIOCPWCGLED _IOR('v', 205, int)
+#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds)
X
X #endif
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/pwc.h linux/drivers/usb/pwc.h
--- v2.4.12/linux/drivers/usb/pwc.h Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/pwc.h Wed Oct 17 14:34:06 2001


@@ -60,8 +60,8 @@
X

X /* Version block */
X #define PWC_MAJOR 8
-#define PWC_MINOR 2
-#define PWC_VERSION "8.2"
+#define PWC_MINOR 3
+#define PWC_VERSION "8.3"
X #define PWC_NAME "pwc"
X
X /* Turn certain features on/off */
@@ -245,6 +245,8 @@
X extern int pwc_set_gamma(struct pwc_device *pdev, int value);
X extern int pwc_get_saturation(struct pwc_device *pdev);
X extern int pwc_set_saturation(struct pwc_device *pdev, int value);
+extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
+extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
X
X /* Power down or up the camera; not supported by all models */
X extern int pwc_camera_power(struct pwc_device *pdev, int power);
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- v2.4.12/linux/drivers/usb/scanner.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/scanner.c Sat Oct 20 19:13:11 2001
@@ -1,9 +1,9 @@
X /* -*- linux-c -*- */
X
X /*
- * Driver for USB Scanners (linux-2.4.0)
+ * Driver for USB Scanners (linux-2.4.12)
X *
- * Copyright (C) 1999, 2000 David E. Nelson
+ * Copyright (C) 1999, 2000, 2001 David E. Nelson
X *
X * Portions may be copyright Brad Keryan and Michael Gee.
X *
@@ -226,13 +226,59 @@
X * read_timeout. Thanks to Mark W. Webb <mark...@adelphia.net> for
X * reporting this bug.
X * - Added Epson Perfection 1640SU and 1640SU Photo. Thanks to
- * Jean-Luc <f5...@db0bm.ampr.org>.
+ * Jean-Luc <f5...@db0bm.ampr.org> and Manuel
+ * Pelayo <Manuel...@sesips.org>. Reported to work fine by Manuel.
X *
- * 0.4.6 08/16/2001 Yves Duret <ydu...@mandrakesoft.com>
- * - added devfs support (from printer.c)


- *
- * TODO

+ * 0.4.6 9/27/2001
+ * - Added IOCTL's to report back scanner USB ID's. Thanks to
+ * Karl Heinz <k...@lynx.phpwebhosting.com>
+ * - Added Umax Astra 2100U ID's. Thanks to Ron
+ * Wellsted <r...@wellsted.org.uk>.
+ * and Manuel Pelayo <Manuel...@sesips.org>.
+ * - Added HP 3400 ID's. Thanks to Harald Hannelius <har...@iki.fi>
+ * and Bertrik Sikken <ber...@zonnet.nl>. Reported to work at
+ * htpp://home.zonnet.nl/bertrik/hp3300c/hp3300c.htm.
+ * - Added Minolta Dimage Scan Dual II ID's. Thanks to Jose Paulo
+ * Moitinho de Almeida <moit...@civil.ist.utl.pt>
+ * - Confirmed addition for SnapScan E20. Thanks to Steffen Hübner
+ * <hue...@gmx.de>.
+ * - Added Lifetec LT9385 ID's. Thanks to Van Bruwaene Kris
+ * <kr...@yahoo.co.uk>
+ * - Added Agfa SnapScan e26 ID's. Reported to work with SANE
+ * 1.0.5. Thanks to Falk Sauer <fa...@mgnkatze.franken.de>.
+ * - Added HP 4300 ID's. Thanks to Stefan Schlosser
+ * <cas...@grmmbl.org>.
+ * - Added Relisis Episode ID's. Thanks to Manfred
+ * Morgner <odb-...@gmx.net>.
+ * - Added many Acer ID's. Thanks to Oliver
+ * Schwartz <Oliver....@gmx.de>.
+ * - Added Snapscan e40 ID's. Thanks to Oliver
+ * Schwartz <Oliver....@gmx.de>.
+ * - Thanks to Oliver Neukum <Oliver...@lrz.uni-muenchen.de>
+ * for helping with races.
+ * - Added Epson Perfection 1650 ID's. Thanks to Karl Heinz
+ * Kremer <k...@khk.net>.
+ * - Added Epson Perfection 2450 ID's (aka GT-9700 for the Japanese
+ * market). Thanks to Karl Heinz Kremer <k...@khk.net>.
+ * - Added Mustek 600 USB ID's. Thanks to Marcus
+ * Alanen <maal...@ra.abo.fi>.
+ * - Added Acer ScanPrisa 1240UT ID's. Thanks to Morgan
+ * Collins <sirmo...@morcant.org>.
+ * - Incorporated devfs patches!! Thanks to Tom Rini
+ * <tr...@kernel.crashing.org>, Pavel Roskin <pro...@gnu.org>,
+ * Greg KH <gr...@kroah.com>, Yves Duret <ydu...@mandrakesoft.com>,
+ * Flavio Stanchina <flavio.s...@tin.it>.
+ * - Removed Minolta ScanImage II. This scanner uses USB SCSI. Thanks
+ * to Oliver Neukum <Oliver...@lrz.uni-muenchen.de> for pointing
+ * this out.
+ * - Added additional SMP locking. Thanks to David Brownell and
+ * Oliver Neukum for their help.
+ * - Added version reporting - reports for both module load and modinfo
+ * - Started path to hopefully straighten/clean out ioctl()'s.
+ * - Users are now notified to consult the Documentation/usb/scanner.txt
+ * for common error messages rather than the maintainer.
X *
+ * TODO
X * - Performance
X * - Select/poll methods
X * - More testing
@@ -266,7 +312,6 @@
X */
X #include "scanner.h"
X
-
X static void
X irq_scanner(struct urb *urb)
X {
@@ -276,19 +321,23 @@
X * all I want to do with it -- or somebody else for that matter.
X */
X
- struct scn_usb_data *scn = urb->context;
- unsigned char *data = &scn->button;
+ struct scn_usb_data *scn;
+ unsigned char *data;
+ scn = urb->context;
+ down(&(scn->sem));
+ data = &scn->button;
X data += 0; /* Keep gcc from complaining about unused var */
X
X if (urb->status) {
+ up(&(scn->sem));
X return;
X }
X
X dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data);
+ up(&(scn->sem));
X return;
X }


X
-
X static int

X open_scanner(struct inode * inode, struct file * file)
X {
@@ -299,22 +348,28 @@
X
X int err=0;
X
- lock_kernel();
+ MOD_INC_USE_COUNT;
+
+ down(&scn_mutex);
X
X scn_minor = USB_SCN_MINOR(inode);
X
X dbg("open_scanner: scn_minor:%d", scn_minor);
X
X if (!p_scn_table[scn_minor]) {
+ up(&scn_mutex);
X err("open_scanner(%d): Unable to access minor data", scn_minor);
- err = -ENODEV;
- goto out_error;
+ return -ENODEV;
X }
X
X scn = p_scn_table[scn_minor];
X
X dev = scn->scn_dev;
X
+ down(&(scn->sem)); /* Now protect the scn_usb_data structure */
+
+ up(&scn_mutex); /* Now handled by the above */
+
X if (!dev) {
X err("open_scanner(%d): Scanner device not present", scn_minor);
X err = -ENODEV;


@@ -337,13 +392,15 @@
X

X scn->isopen = 1;
X
- file->private_data = scn; /* Used by the read and write metheds */
+ file->private_data = scn; /* Used by the read and write methods */
X
- MOD_INC_USE_COUNT;
X
X out_error:
X
- unlock_kernel();
+ up(&(scn->sem)); /* Wake up any possible contending processes */
+
+ if (err)
+ MOD_DEC_USE_COUNT;
X
X return err;
X }
@@ -364,12 +421,17 @@


X return -ENODEV;
X }
X

- scn = p_scn_table[scn_minor];
+ down(&scn_mutex);
X
+ scn = p_scn_table[scn_minor];
+ down(&(scn->sem));
X scn->isopen = 0;
X
X file->private_data = NULL;
X
+ up(&scn_mutex);
+ up(&(scn->sem));
+
X MOD_DEC_USE_COUNT;
X
X return 0;
@@ -395,6 +457,8 @@
X
X scn = file->private_data;
X
+ down(&(scn->sem));
+
X scn_minor = scn->scn_minor;
X
X obuf = scn->obuf;
@@ -403,12 +467,10 @@
X
X file->f_dentry->d_inode->i_atime = CURRENT_TIME;
X
- down(&(scn->gen_lock));
-
X while (count > 0) {
X
X if (signal_pending(current)) {
- ret = -EINTR;
+ ret = -ERESTARTSYS;
X break;
X }
X
@@ -427,7 +489,7 @@
X ret = result;
X break;
X } else if (result < 0) { /* We should not get any I/O errors */
- warn("write_scanner(%d): funky result: %d. Please notify the maintainer.", scn_minor, result);
+ warn("write_scanner(%d): funky result: %d. Consult Documentataion/usb/scanner.txt.", scn_minor, result);
X ret = -EIO;
X break;
X }
@@ -457,7 +519,7 @@
X break;
X }
X }
- up(&(scn->gen_lock));
+ up(&(scn->sem));
X mdelay(5); /* This seems to help with SANE queries */
X return ret ? ret : bytes_written;
X }


@@ -483,6 +545,8 @@
X

X scn = file->private_data;
X
+ down(&(scn->sem));
+
X scn_minor = scn->scn_minor;
X
X ibuf = scn->ibuf;
@@ -496,11 +560,9 @@
X atime of
X the device
X node */
- down(&(scn->gen_lock));
-
X while (count > 0) {
X if (signal_pending(current)) {
- ret = -EINTR;
+ ret = -ERESTARTSYS;
X break;
X }
X
@@ -545,7 +607,7 @@
X ret = result;
X break;
X } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
- warn("read_scanner(%d): funky result:%d. Please notify the maintainer.", scn_minor, (int)result);
+ warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result);
X ret = -EIO;
X break;
X }
@@ -577,20 +639,16 @@
X break;
X }
X }
- up(&(scn->gen_lock));
-
+ up(&(scn->sem));
X return ret ? ret : bytes_read;
X }
X
-#ifdef SCN_IOCTL
X static int
X ioctl_scanner(struct inode *inode, struct file *file,
X unsigned int cmd, unsigned long arg)
X {
X struct usb_device *dev;
X
- int result;
-
X kdev_t scn_minor;
X
X scn_minor = USB_SCN_MINOR(inode);
@@ -604,12 +662,15 @@
X
X switch (cmd)
X {
- case IOCTL_SCANNER_VENDOR :
+ case SCANNER_IOCTL_VENDOR :
X return (put_user(dev->descriptor.idVendor, (unsigned int *) arg));
- case IOCTL_SCANNER_PRODUCT :
+ case SCANNER_IOCTL_PRODUCT :
X return (put_user(dev->descriptor.idProduct, (unsigned int *) arg));
+#ifdef PV8630
X case PV8630_IOCTL_INREQUEST :
X {
+ int result;
+
X struct {
X __u8 data;
X __u8 request;
@@ -637,6 +698,8 @@
X }
X case PV8630_IOCTL_OUTREQUEST :
X {
+ int result;
+
X struct {
X __u8 request;
X __u16 value;
@@ -658,20 +721,59 @@
X
X return result;
X }
+#endif /* PV8630 */
+ case SCANNER_IOCTL_CTRLMSG:
+ {
+ struct ctrlmsg_ioctl {
+ devrequest req;
+ void *data;
+ } cmsg;
+ int pipe, nb, ret;
+ unsigned char buf[64];
+
+ if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg)))
+ return -EFAULT;
+
+ nb = le16_to_cpup(&cmsg.req.length);
+
+ if (nb > sizeof(buf))
+ return -EINVAL;
+
+ if ((cmsg.req.requesttype & 0x80) == 0) {
+ pipe = usb_sndctrlpipe(dev, 0);
+ if (nb > 0 && copy_from_user(buf, cmsg.data, nb))
+ return -EFAULT;
+ } else {
+ pipe = usb_rcvctrlpipe(dev, 0);
+ }
+
+ ret = usb_control_msg(dev, pipe, cmsg.req.request,
+ cmsg.req.requesttype,
+ le16_to_cpup(&cmsg.req.value),
+ le16_to_cpup(&cmsg.req.index),
+ buf, nb, HZ);
+
+ if (ret < 0) {
+ err("ioctl_scanner(%d): control_msg returned %d\n", scn_minor, ret);


+ return -EIO;
+ }
+

+ if (nb > 0 && (cmsg.req.requesttype & 0x80) && copy_to_user(cmsg.data, buf, nb))
+ return -EFAULT;


+
+ return 0;
+ }

X default:
X return -ENOTTY;


X }
X return 0;
X }

-#endif /* SCN_IOCTL */
X
X static struct
X file_operations usb_scanner_fops = {
X read: read_scanner,
X write: write_scanner,
-#ifdef SCN_IOCTL
X ioctl: ioctl_scanner,
-#endif /* SCN_IOCTL */
X open: open_scanner,
X release: close_scanner,
X };
@@ -691,6 +793,7 @@
X
X char valid_device = 0;
X char have_bulk_in, have_bulk_out, have_intr;
+ char name[10];
X
X if (vendor != -1 && product != -1) {
X info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product);
@@ -791,7 +894,7 @@
X dbg("probe_scanner: intr_ep:%d", have_intr);
X continue;
X }
- info("probe_scanner: Undetected endpoint. Notify the maintainer.");
+ info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt.");
X return NULL; /* Shouldn't ever get here unless we have something weird */
X }
X
@@ -815,7 +918,7 @@
X }
X break;
X default:
- info("probe_scanner: Endpoint determination failed. Notify the maintainer.");
+ info("probe_scanner: Endpoint determination failed -- consult Documentation/usb/scanner.txt");
X return NULL;
X }
X
@@ -825,6 +928,8 @@
X * with it. The problem with this is that we are counting on the fact
X * that the user will sequentially add device nodes for the scanner
X * devices. */
+
+ down(&scn_mutex);
X
X for (scn_minor = 0; scn_minor < SCN_MAX_MNR; scn_minor++) {
X if (!p_scn_table[scn_minor])
@@ -844,8 +949,10 @@
X return NULL;
X }
X memset (scn, 0, sizeof(struct scn_usb_data));
- dbg ("probe_scanner(%d): Address of scn:%p", scn_minor, scn);
X
+ init_MUTEX(&(scn->sem)); /* Initializes to unlocked */
+
+ dbg ("probe_scanner(%d): Address of scn:%p", scn_minor, scn);
X
X /* Ok, if we detected an interrupt EP, setup a handler for it */
X if (have_intr) {
@@ -859,6 +966,7 @@
X if (usb_submit_urb(&scn->scn_irq)) {
X err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor);
X kfree(scn);
+ up(&scn_mutex);
X return NULL;
X }
X }
@@ -868,6 +976,7 @@
X if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {
X err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor);
X kfree(scn);
+ up(&scn_mutex);
X return NULL;
X }
X dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf);
@@ -876,6 +985,7 @@
X err("probe_scanner(%d): Not enough memory for the input buffer.", scn_minor);
X kfree(scn->obuf);
X kfree(scn);
+ up(&scn_mutex);
X return NULL;
X }
X dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf);
@@ -908,15 +1018,17 @@
X scn->scn_minor = scn_minor;
X scn->isopen = 0;
X
- init_MUTEX(&(scn->gen_lock));
-
- /* if we have devfs, create with perms=660 */
- scn->devfs = devfs_register(usb_devfs_handle, "scanner",
- DEVFS_FL_DEFAULT, USB_MAJOR,
- SCN_BASE_MNR + scn_minor,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
- S_IWGRP, &usb_scanner_fops, NULL);
+ sprintf(name, "scanner%d", scn->scn_minor);
+
+ scn->devfs = devfs_register(usb_devfs_handle, name,
+ DEVFS_FL_DEFAULT, USB_MAJOR,
+ SCN_BASE_MNR + scn->scn_minor,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
+ S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, NULL);
+ if (scn->devfs == NULL)
+ dbg("scanner%d: device node registration failed", scn_minor);
X
+ up(&scn_mutex);
X
X return p_scn_table[scn_minor] = scn;
X }
@@ -926,6 +1038,9 @@
X {
X struct scn_usb_data *scn = (struct scn_usb_data *) ptr;
X
+ down (&scn_mutex);
+ down (&(scn->sem));
+
X if(scn->intr_ep) {
X dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
X usb_unlink_urb(&scn->scn_irq);
@@ -933,17 +1048,17 @@
X usb_driver_release_interface(&scanner_driver,
X &scn->scn_dev->actconfig->interface[scn->ifnum]);
X
- devfs_unregister (scn->devfs);
-
X kfree(scn->ibuf);
X kfree(scn->obuf);
X
X dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
+ devfs_unregister(scn->devfs);
X p_scn_table[scn->scn_minor] = NULL;
+ up (&(scn->sem));
X kfree (scn);
+ up (&scn_mutex);
X }
X
-
X static struct
X usb_driver scanner_driver = {
X name: "usbscanner",
@@ -968,7 +1083,7 @@
X if (usb_register(&scanner_driver) < 0)
X return -1;
X
- info("USB Scanner support registered.");
+ info(DRIVER_VERSION ":" DRIVER_DESC);


X return 0;
X }
X

diff -u --recursive --new-file v2.4.12/linux/drivers/usb/scanner.h linux/drivers/usb/scanner.h
--- v2.4.12/linux/drivers/usb/scanner.h Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/scanner.h Sat Oct 20 19:13:11 2001
@@ -1,12 +1,10 @@
X /*
- * Driver for USB Scanners (linux-2.4.0)
+ * Driver for USB Scanners (linux-2.4.12)
X *
- * Copyright (C) 1999, 2000 David E. Nelson
+ * Copyright (C) 1999, 2000, 2001 David E. Nelson
X *
X * David E. Nelson (dne...@jump.net)
X *
- * 08/16/2001 added devfs support Yves Duret <ydu...@mandrakesoft.com>
- *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as
X * published by the Free Software Foundation; either version 2 of the
@@ -37,12 +35,21 @@
X
X // #define DEBUG
X
+/* Enable this to support the older ioctl interfaces scanners that
+ * a PV8630 Scanner-On-Chip. The prefered method is the
+ * SCANNER_IOCTL_CTRLMSG ioctl.
+ */
+// #define PV8630
+
+#define DRIVER_VERSION "0.4.6"
+#define DRIVER_DESC "USB Scanner Driver"
+
X #include <linux/usb.h>
X
X static __s32 vendor=-1, product=-1, read_timeout=0;
X
X MODULE_AUTHOR("David E. Nelson, dne...@jump.net, http://www.jump.net/~dnelson");
-MODULE_DESCRIPTION("USB Scanner Driver");
+MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);


X MODULE_LICENSE("GPL");
X

X MODULE_PARM(vendor, "i");
@@ -55,10 +62,6 @@
X MODULE_PARM_DESC(read_timeout, "User specified read timeout in seconds");
X
X
-/* Enable to activate the ioctl interface. This is mainly meant for */
-/* development purposes until an ioctl number is officially registered */
-#define SCN_IOCTL
-
X /* WARNING: These DATA_DUMP's can produce a lot of data. Caveat Emptor. */
X // #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
X // #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
@@ -69,26 +72,42 @@
X { USB_DEVICE(0x04a5, 0x2040) }, /* Prisa AcerScan 620U (!) */
X { USB_DEVICE(0x04a5, 0x20c0) }, /* Prisa AcerScan 1240UT */
X { USB_DEVICE(0x04a5, 0x2022) }, /* Vuego Scan Brisa 340U */
+ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */
+ { USB_DEVICE(0x04a5, 0x1a2a) }, /* Unknown - Oliver Schwartz */
+ { USB_DEVICE(0x04a5, 0x207e) }, /* Prisa 640BU */
+ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */
+ { USB_DEVICE(0x04a5, 0x20c0) }, /* Unknown - Oliver Schwartz */
+ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */
+ { USB_DEVICE(0x04a5, 0x20b0) }, /* Unknown - Oliver Schwartz */
+ { USB_DEVICE(0x04a5, 0x20fe) }, /* Unknown - Oliver Schwartz */
X /* Agfa */
X { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */
X { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */
X { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/
X { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */
+ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */
+ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
+ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
X /* Colorado -- See Primax/Colorado below */
X /* Epson -- See Seiko/Epson below */
X /* Genius */
X { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */
X /* Hewlett Packard */
X { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */
+ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */
X { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */
X { USB_DEVICE(0x03f0, 0x0105) }, /* 4200C */
+ { USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */
X { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */
X { USB_DEVICE(0x03f0, 0x0401) }, /* 5200C */
X // { USB_DEVICE(0x03f0, 0x0701) }, /* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */
X { USB_DEVICE(0x03f0, 0x0201) }, /* 6200C */
X { USB_DEVICE(0x03f0, 0x0601) }, /* 6300C */
+ { USB_DEVICE(0x03f0, 0x605) }, /* 2200C */
X /* iVina */
- { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
+ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
+ /* Lifetec */
+ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
X /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */
X // { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */
X // { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */
@@ -97,10 +116,13 @@
X // { USB_DEVICE(0x05da, 0x00a3) }, /* ScanMaker V6USL */
X // { USB_DEVICE(0x05da, 0x80a3) }, /* ScanMaker V6USL #2 */
X // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */
+ /* Minolta */
+ // { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */
X /* Mustek */
X { USB_DEVICE(0x055f, 0x0001) }, /* 1200 CU */
X { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */
X { USB_DEVICE(0x055f, 0x0002) }, /* 600 CU */
+ { USB_DEVICE(0x055f, 0x0873) }, /* 600 USB */
X { USB_DEVICE(0x055f, 0x0003) }, /* 1200 USB */
X { USB_DEVICE(0x055f, 0x0006) }, /* 1200 UB */
X { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
@@ -116,9 +138,11 @@
X { USB_DEVICE(0x0461, 0x0303) }, /* G2E-300 #2 */
X { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */
X { USB_DEVICE(0x0461, 0x0340) }, /* Colorado USB 9600 */
- { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 */
+ // { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 - undetected endpoint */
X { USB_DEVICE(0x0461, 0x0341) }, /* Colorado 600u */
X { USB_DEVICE(0x0461, 0x0361) }, /* Colorado 1200u */
+ /* Relisis */
+ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */
X /* Seiko/Epson Corp. */
X { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */
X { USB_DEVICE(0x04b8, 0x0103) }, /* Perfection 610 */
@@ -129,9 +153,12 @@
X { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
X { USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */
X { USB_DEVICE(0x04b8, 0x010e) }, /* Expression 1680 */
+ { USB_DEVICE(0x04b8, 0x0110) }, /* Perfection 1650 */
+ { USB_DEVICE(0x04b8, 0x0112) }, /* Perfection 2450 - GT-9700 for the Japanese mkt */
X /* Umax */
X { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */
X { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */
+ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */
X { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */
X /* Visioneer */
X { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */
@@ -167,16 +194,24 @@
X
X
X /* FIXME: These are NOT registered ioctls()'s */
+#ifdef PV8630
X #define PV8630_IOCTL_INREQUEST 69
X #define PV8630_IOCTL_OUTREQUEST 70
+#endif /* PV8630 */
+
+
+/* read vendor and product IDs from the scanner */
+#define SCANNER_IOCTL_VENDOR _IOR('U', 0x20, int)
+#define SCANNER_IOCTL_PRODUCT _IOR('U', 0x21, int)
+/* send/recv a control message to the scanner */
+#define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, devrequest )
X
-/* read vendor and product IDs */
-#define IOCTL_SCANNER_VENDOR _IOR('u', 0xa0, int)
-#define IOCTL_SCANNER_PRODUCT _IOR('u', 0xa1, int)
X
X #define SCN_MAX_MNR 16 /* We're allocated 16 minors */
X #define SCN_BASE_MNR 48 /* USB Scanners start at minor 48 */
X
+static DECLARE_MUTEX (scn_mutex); /* Initializes to unlocked */
+
X struct scn_usb_data {
X struct usb_device *scn_dev;
X devfs_handle_t devfs; /* devfs device */
@@ -189,12 +224,12 @@
X char *obuf, *ibuf; /* transfer buffers */
X char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */
X wait_queue_head_t rd_wait_q; /* read timeouts */
- struct semaphore gen_lock; /* lock to prevent concurrent reads or writes */
+ struct semaphore sem; /* lock to prevent concurrent reads or writes */
X unsigned int rd_nak_timeout; /* Seconds to wait before read() timeout. */
X };
X
+extern devfs_handle_t usb_devfs_handle;
+
X static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */};
X
X static struct usb_driver scanner_driver;
-
-extern devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- v2.4.12/linux/drivers/usb/serial/Config.in Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/Config.in Wed Oct 17 14:35:17 2001
@@ -5,36 +5,32 @@
X comment 'USB Serial Converter support'
X
X dep_tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
-if [ "$CONFIG_USB_SERIAL" != "n" ]; then
- if [ "$CONFIG_USB_SERIAL" = "y" ]; then
- bool ' USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
- fi
- bool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
- dep_tristate ' USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
- dep_tristate ' USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
- dep_tristate ' USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
- bool ' USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
- bool ' USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
- bool ' USB Keyspan USA-28XA Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XA
- bool ' USB Keyspan USA-28XB Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XB
- bool ' USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
- bool ' USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
- bool ' USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
- bool ' USB Keyspan USA-49W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA49W
- fi
- dep_tristate ' USB MCT Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_MCT_U232 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Prolific 2303 Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PL2303 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)' CONFIG_USB_SERIAL_CYBERJACK $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Xircom / Entregra Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_XIRCOM $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
- dep_tristate ' USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_USB_SERIAL" = "y" ]; then
+ dep_mbool ' USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG $CONFIG_USB_SERIAL
X fi
+dep_mbool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC $CONFIG_USB_SERIAL
+dep_tristate ' USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
+dep_tristate ' USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
+dep_tristate ' USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+ dep_mbool ' USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28 $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-28XA Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XA $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-28XB Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XB $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19 $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W $CONFIG_USB_SERIAL_KEYSPAN
+ dep_mbool ' USB Keyspan USA-49W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA49W $CONFIG_USB_SERIAL_KEYSPAN
+dep_tristate ' USB MCT Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_MCT_U232 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Prolific 2303 Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PL2303 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)' CONFIG_USB_SERIAL_CYBERJACK $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Xircom / Entregra Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_XIRCOM $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate ' USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
X
X endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- v2.4.12/linux/drivers/usb/serial/ftdi_sio.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/usb/serial/ftdi_sio.c Sat Oct 20 19:13:11 2001
@@ -454,7 +454,7 @@
X while (port->write_urb->status == -EINPROGRESS) {
X dbg(__FUNCTION__ " write in progress - retrying");
X if (signal_pending(current)) {
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue(&port->write_wait, &wait);
X rc = -ERESTARTSYS;
X goto err;
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.12/linux/drivers/usb/uhci.c Thu Oct 11 08:02:26 2001
+++ linux/drivers/usb/uhci.c Sat Oct 20 19:13:11 2001
@@ -113,44 +113,6 @@
X
X static int uhci_free_dev(struct usb_device *dev)
X {
- struct uhci *uhci = (struct uhci *)dev->bus->hcpriv;
- struct list_head list, *tmp, *head;


- unsigned long flags;
-

- /* Walk through the entire URB list and forcefully remove any */
- /* URBs that are still active for that device */
-
- /* Two stage unlink so we don't deadlock on urb_list_lock */
- INIT_LIST_HEAD(&list);
-
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
- head = &uhci->urb_list;
- tmp = head->next;
- while (tmp != head) {
- struct urb *urb = list_entry(tmp, struct urb, urb_list);
-
- tmp = tmp->next;
-
- if (urb->dev == dev) {
- list_del(&urb->urb_list);
- list_add(&urb->urb_list, &list);
- }
- }
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-
- head = &list;
- tmp = head->next;
- while (tmp != head) {
- struct urb *urb = list_entry(tmp, struct urb, urb_list);
- tmp = tmp->next;
-
- /* Make sure we block waiting on these to die */
- urb->transfer_flags &= ~USB_ASYNC_UNLINK;
-
- /* uhci_unlink_urb will unlink from the temp list */
- uhci_unlink_urb(urb);
- }
-


X return 0;
X }
X

@@ -159,7 +121,7 @@


X unsigned long flags;
X

X spin_lock_irqsave(&uhci->frame_list_lock, flags);
- uhci->skel_term_td->status |= TD_CTRL_IOC;
+ set_bit(TD_CTRL_IOC_BIT, &uhci->skel_term_td->status);
X spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
X }
X
@@ -168,7 +130,7 @@


X unsigned long flags;
X

X spin_lock_irqsave(&uhci->frame_list_lock, flags);
- uhci->skel_term_td->status &= ~TD_CTRL_IOC;
+ clear_bit(TD_CTRL_IOC_BIT, &uhci->skel_term_td->status);
X spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
X }
X
@@ -396,50 +358,96 @@
X pci_pool_free(uhci->qh_pool, qh, qh->dma_handle);
X }
X
-static void uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct uhci_qh *qh)
+static void _uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct urb *urb)
X {
+ struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ struct list_head *head, *tmp;
X struct uhci_qh *lqh;


- unsigned long flags;
-

- spin_lock_irqsave(&uhci->frame_list_lock, flags);
X
X /* Grab the last QH */
X lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);
X
- qh->link = lqh->link;
+ if (lqh->urbp) {
+ head = &lqh->urbp->queue_list;
+ tmp = head->next;
+ while (head != tmp) {
+ struct urb_priv *turbp =
+ list_entry(tmp, struct urb_priv, queue_list);
+
+ tmp = tmp->next;
+
+ turbp->qh->link = urbp->qh->dma_handle | UHCI_PTR_QH;
+ }
+ }
+
+ head = &urbp->queue_list;
+ tmp = head->next;
+ while (head != tmp) {
+ struct urb_priv *turbp =
+ list_entry(tmp, struct urb_priv, queue_list);
+
+ tmp = tmp->next;
+
+ turbp->qh->link = lqh->link;
+ }
+
+ urbp->qh->link = lqh->link;
X mb(); /* Ordering is important */
- lqh->link = qh->dma_handle | UHCI_PTR_QH;
+ lqh->link = urbp->qh->dma_handle | UHCI_PTR_QH;
+
+ list_add_tail(&urbp->qh->list, &skelqh->list);
+}
X
- list_add_tail(&qh->list, &skelqh->list);
+static void uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct urb *urb)


+{
+ unsigned long flags;

X
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
+ _uhci_insert_qh(uhci, skelqh, urb);
X spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
X }
X
-static void uhci_remove_qh(struct uhci *uhci, struct uhci_qh *qh)
+static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
X {
+ struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
X unsigned long flags;
- struct uhci_qh *prevqh;
+ struct uhci_qh *qh = urbp->qh, *pqh;
+
+ if (!qh)
+ return;
X
X /* Only go through the hoops if it's actually linked in */
- if (list_empty(&qh->list)) {
- goto list;
- }
+ if (!list_empty(&qh->list)) {
+ qh->urbp = NULL;
X
- qh->urbp = NULL;
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
X
- spin_lock_irqsave(&uhci->frame_list_lock, flags);
+ pqh = list_entry(qh->list.prev, struct uhci_qh, list);
X
- prevqh = list_entry(qh->list.prev, struct uhci_qh, list);
+ if (pqh->urbp) {
+ struct list_head *head, *tmp;
X
- prevqh->link = qh->link;
- mb();
- qh->element = qh->link = UHCI_PTR_TERM;
+ head = &pqh->urbp->queue_list;
+ tmp = head->next;
+ while (head != tmp) {
+ struct urb_priv *turbp =
+ list_entry(tmp, struct urb_priv, queue_list);
X
- list_del_init(&qh->list);
+ tmp = tmp->next;
X
- spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
+ turbp->qh->link = qh->link;
+ }
+ }
+
+ pqh->link = qh->link;
+ mb();
+ qh->element = qh->link = UHCI_PTR_TERM;
+
+ list_del_init(&qh->list);
+
+ spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
+ }
X
-list:
X spin_lock_irqsave(&uhci->qh_remove_list_lock, flags);
X
X /* Check to see if the remove list is empty. Set the IOC bit */
@@ -464,9 +472,10 @@
X
X tmp = tmp->next;
X
- td->info &= ~(1 << TD_TOKEN_TOGGLE);
X if (toggle)
- td->info |= (1 << TD_TOKEN_TOGGLE);
+ set_bit(TD_TOKEN_TOGGLE, &td->info);
+ else
+ clear_bit(TD_TOKEN_TOGGLE, &td->info);
X
X toggle ^= 1;
X }
@@ -481,7 +490,7 @@
X {
X struct urb_priv *eurbp, *urbp, *furbp, *lurbp;
X struct list_head *tmp;
- struct uhci_td *ftd, *lltd;
+ struct uhci_td *lltd;


X unsigned long flags;
X

X eurbp = eurb->hcpriv;
@@ -510,13 +519,15 @@
X lurbp = list_entry(furbp->queue_list.prev, struct urb_priv, queue_list);
X
X lltd = list_entry(lurbp->td_list.prev, struct uhci_td, list);
- ftd = list_entry(urbp->td_list.next, struct uhci_td, list);
X
X uhci_fixup_toggle(urb, uhci_toggle(lltd->info) ^ 1);
X
+ /* All qh's in the queue need to link to the next queue */
+ urbp->qh->link = eurbp->qh->link;
+
X mb(); /* Make sure we flush everything */
X /* Only support bulk right now, so no depth */
- lltd->link = ftd->dma_handle;
+ lltd->link = urbp->qh->dma_handle | UHCI_PTR_QH;
X
X list_add_tail(&urbp->queue_list, &furbp->queue_list);
X
@@ -576,30 +587,9 @@
X usb_pipeout(urb->pipe), toggle);
X
X if (!urbp->queued) {
- int status;
-
- /* The HC may continue using the current QH if it finished */
- /* all of the TD's in this URB and may have started on the */
- /* next URB's TD's already, so we'll take over ownership */
- /* of this QH and use it instead. Don't forget to delete */
- /* the old QH first */
- uhci_free_qh(uhci, nurbp->qh);
-
- nurbp->qh = urbp->qh;
- nurbp->qh->urbp = nurbp;
- urbp->qh = NULL;
-
- /* If the last TD from the first (this) urb didn't */
- /* complete, reset qh->element to the first TD in the */
- /* next urb */
- pltd = list_entry(urbp->td_list.prev, struct uhci_td, list);
- status = uhci_status_bits(pltd->status);
- if ((status & TD_CTRL_ACTIVE) || uhci_actual_length(pltd->status) < uhci_expected_length(pltd->info)) {
- struct uhci_td *ftd = list_entry(nurbp->td_list.next, struct uhci_td, list);
- nurbp->qh->element = ftd->dma_handle;
- }
-
X nurbp->queued = 0;
+
+ _uhci_insert_qh(uhci, uhci->skel_bulk_qh, nurbp->urb);
X } else {
X /* We're somewhere in the middle (or end). A bit trickier */
X /* than the head scenario */
@@ -607,15 +597,10 @@
X queue_list);
X
X pltd = list_entry(purbp->td_list.prev, struct uhci_td, list);
- if (nurbp->queued) {
- struct uhci_td *nftd;
-
- /* Close the gap between the two */
- nftd = list_entry(nurbp->td_list.next, struct uhci_td,
- list);
- pltd->link = nftd->dma_handle;
- } else
- /* The next URB happens to be the beggining, so */
+ if (nurbp->queued)
+ pltd->link = nurbp->qh->dma_handle | UHCI_PTR_QH;
+ else
+ /* The next URB happens to be the beginning, so */
X /* we're the last, end the chain */
X pltd->link = UHCI_PTR_TERM;
X }
@@ -639,6 +624,7 @@
X memset((void *)urbp, 0, sizeof(*urbp));
X
X urbp->inserttime = jiffies;
+ urbp->fsbrtime = jiffies;
X urbp->urb = urb;
X urbp->dev = urb->dev;
X
@@ -796,7 +782,7 @@
X if (status & TD_CTRL_NAK) /* NAK */
X return -ETIMEDOUT;
X if (status & TD_CTRL_BABBLE) /* Babble */
- return -EPIPE;
+ return -EOVERFLOW;
X if (status & TD_CTRL_DBUFERR) /* Buffer error */
X return -ENOSR;
X if (status & TD_CTRL_STALLED) /* Stalled */
@@ -900,19 +886,19 @@
X if (!qh)
X return -ENOMEM;
X
+ urbp->qh = qh;
+ qh->urbp = urbp;
+
X /* Low speed or small transfers gets a different queue and treatment */
X if (urb->pipe & TD_CTRL_LS) {
X uhci_insert_tds_in_qh(qh, urb, 0);
- uhci_insert_qh(uhci, uhci->skel_ls_control_qh, qh);
+ uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urb);
X } else {
X uhci_insert_tds_in_qh(qh, urb, 1);
- uhci_insert_qh(uhci, uhci->skel_hs_control_qh, qh);
+ uhci_insert_qh(uhci, uhci->skel_hs_control_qh, urb);
X uhci_inc_fsbr(uhci, urb);
X }
X
- urbp->qh = qh;
- qh->urbp = urbp;
-
X return -EINPROGRESS;
X }
X
@@ -961,7 +947,8 @@
X !(td->status & TD_CTRL_ACTIVE)) {
X uhci_inc_fsbr(urb->dev->bus->hcpriv, urb);
X urbp->fsbr_timeout = 0;
- td->status &= ~TD_CTRL_IOC;
+ urbp->fsbrtime = jiffies;
+ clear_bit(TD_CTRL_IOC_BIT, &td->status);
X }
X
X status = uhci_status_bits(td->status);
@@ -1043,7 +1030,7 @@
X urbp->short_control_packet = 1;
X
X /* Create a new QH to avoid pointer overwriting problems */
- uhci_remove_qh(uhci, urbp->qh);
+ uhci_remove_qh(uhci, urb);
X
X /* Delete all of the TD's except for the status TD at the end */
X head = &urbp->td_list;
@@ -1071,9 +1058,9 @@
X
X /* Low speed or small transfers gets a different queue and treatment */
X if (urb->pipe & TD_CTRL_LS)
- uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urbp->qh);
+ uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urb);
X else
- uhci_insert_qh(uhci, uhci->skel_hs_control_qh, urbp->qh);
+ uhci_insert_qh(uhci, uhci->skel_hs_control_qh, urb);
X
X return -EINPROGRESS;
X }
@@ -1134,7 +1121,8 @@
X !(td->status & TD_CTRL_ACTIVE)) {
X uhci_inc_fsbr(urb->dev->bus->hcpriv, urb);
X urbp->fsbr_timeout = 0;
- td->status &= ~TD_CTRL_IOC;
+ urbp->fsbrtime = jiffies;
+ clear_bit(TD_CTRL_IOC_BIT, &td->status);
X }
X
X status = uhci_status_bits(td->status);
@@ -1147,10 +1135,6 @@
X goto td_error;
X
X if (uhci_actual_length(td->status) < uhci_expected_length(td->info)) {
- usb_settoggle(urb->dev, uhci_endpoint(td->info),
- uhci_packetout(td->info),
- uhci_toggle(td->info) ^ 1);
-
X if (urb->transfer_flags & USB_DISABLE_SPD) {
X ret = -EREMOTEIO;
X goto err;
@@ -1303,7 +1287,7 @@
X if (urb->transfer_flags & USB_QUEUE_BULK && eurb)
X uhci_append_queued_urb(uhci, eurb, urb);
X else
- uhci_insert_qh(uhci, uhci->skel_bulk_qh, qh);
+ uhci_insert_qh(uhci, uhci->skel_bulk_qh, urb);
X
X uhci_inc_fsbr(uhci, urb);
X
@@ -1681,6 +1665,7 @@
X
X static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
X {
+ struct list_head *head, *tmp;
X struct urb_priv *urbp = urb->hcpriv;
X
X /* We can get called when urbp allocation fails, so check */
@@ -1689,15 +1674,30 @@
X
X uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
X
+ head = &urbp->td_list;
+ tmp = head->next;
+ while (tmp != head) {
+ struct uhci_td *td = list_entry(tmp, struct uhci_td, list);
+
+ tmp = tmp->next;
+
+ /* Control and Isochronous ignore the toggle, so this */
+ /* is safe for all types */
+ if (!(td->status & TD_CTRL_ACTIVE) &&
+ (uhci_actual_length(td->status) < uhci_expected_length(td->info) ||
+ tmp == head)) {
+ usb_settoggle(urb->dev, uhci_endpoint(td->info),
+ uhci_packetout(td->info),
+ uhci_toggle(td->info) ^ 1);
+ }
+ }
+
X uhci_delete_queued_urb(uhci, urb);
X
- if (urbp->qh)
- /* The interrupt loop will reclaim the QH's */
- uhci_remove_qh(uhci, urbp->qh);
+ /* The interrupt loop will reclaim the QH's */
+ uhci_remove_qh(uhci, urb);
X }
X
-/* FIXME: If we forcefully unlink an urb, we should reset the toggle for */
-/* that pipe to match what actually completed */
X static int uhci_unlink_urb(struct urb *urb)
X {
X struct uhci *uhci;
@@ -1796,7 +1796,7 @@
X tmp = tmp->next;
X
X if (td->status & TD_CTRL_ACTIVE) {
- td->status |= TD_CTRL_IOC;
+ set_bit(TD_CTRL_IOC_BIT, &td->status);
X break;
X }
X }
@@ -1951,11 +1951,11 @@
X tmp = tmp->next;
X
X /* Check if the FSBR timed out */
- if (urbp->fsbr && time_after_eq(jiffies, urbp->inserttime + IDLE_TIMEOUT))
+ if (urbp->fsbr && !urbp->fsbr_timeout && time_after_eq(jiffies, urbp->fsbrtime + IDLE_TIMEOUT))
X uhci_fsbr_timeout(uhci, u);
X
X /* Check if the URB timed out */
- if (u->timeout && time_after_eq(jiffies, u->timeout)) {
+ if (u->timeout && time_after_eq(jiffies, urbp->inserttime + u->timeout)) {
X list_del(&u->urb_list);
X list_add_tail(&u->urb_list, &list);
X }
@@ -2565,7 +2565,7 @@
X static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io_size)
X {
X struct uhci *uhci;
- int retval = -EBUSY;
+ int retval;
X char buf[8], *bufp = buf;
X int i, port;
X struct usb_bus *bus;
@@ -2574,27 +2574,27 @@
X struct proc_dir_entry *ent;
X #endif
X
- if (!request_region(io_addr, io_size, "usb-uhci")) {
- err("couldn't allocate I/O range %x - %x", io_addr,
- io_addr + io_size - 1);
- goto err_request_region;
+ retval = -ENODEV;
+ if (pci_enable_device(dev) < 0) {
+ err("couldn't enable PCI device");
+ goto err_enable_device;
X }
X
X if (!dev->irq) {
X err("found UHCI device with no IRQ assigned. check BIOS settings!");
- retval = -EINVAL;
X goto err_invalid_irq;
X }
X
X if (!pci_dma_supported(dev, 0xFFFFFFFF)) {
X err("PCI subsystem doesn't support 32 bit addressing?");
- retval = -ENODEV;
X goto err_pci_dma_supported;
X }
X
- if (pci_enable_device(dev) < 0) {
- err("couldn't enable PCI device");
- goto err_enable_device;
+ retval = -EBUSY;
+ if (!request_region(io_addr, io_size, "usb-uhci")) {
+ err("couldn't allocate I/O range %x - %x", io_addr,
+ io_addr + io_size - 1);
+ goto err_request_region;
X }
X
X pci_set_master(dev);
@@ -2897,15 +2897,15 @@
X err_alloc_uhci:
X
X err_pci_set_dma_mask:
+ release_region(io_addr, io_size);
X
-err_enable_device:
+err_request_region:
X
X err_pci_dma_supported:
- release_region(io_addr, io_size);
X
X err_invalid_irq:
X
-err_request_region:
+err_enable_device:
X
X return retval;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- v2.4.12/linux/drivers/usb/uhci.h Thu Oct 18 13:50:37 2001
+++ linux/drivers/usb/uhci.h Tue Oct 23 22:02:30 2001
@@ -100,6 +100,7 @@
X #define TD_CTRL_C_ERR_SHIFT 27
X #define TD_CTRL_LS (1 << 26) /* Low Speed Device */
X #define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
+#define TD_CTRL_IOC_BIT 24
X #define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
X #define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
X #define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
@@ -344,6 +345,7 @@
X int status; /* Final status */
X
X unsigned long inserttime; /* In jiffies */
+ unsigned long fsbrtime; /* In jiffies */
X
X struct list_head queue_list;
X struct list_head complete_list;
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/ultracam.c linux/drivers/usb/ultracam.c
--- v2.4.12/linux/drivers/usb/ultracam.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/ultracam.c Wed Oct 17 14:34:06 2001
@@ -537,11 +537,7 @@
X * 12-Nov-2000 Reworked to comply with new probe() signature.
X * 23-Jan-2001 Added compatibility with 2.2.x kernels.
X */
-static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum
-#if defined(usb_device_id_ver)
- ,const struct usb_device_id *devid
-#endif
- )
+static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid)
X {
X uvd_t *uvd = NULL;
X int i, nas;
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- v2.4.12/linux/drivers/usb/usb-ohci.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usb-ohci.c Sat Oct 20 19:13:11 2001
@@ -779,7 +779,7 @@
X set_current_state(TASK_UNINTERRUPTIBLE);
X while (timeout && (urb->status == USB_ST_URB_PENDING))
X timeout = schedule_timeout (timeout);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue (&unlink_wakeup, &wait);
X if (urb->status == USB_ST_URB_PENDING) {
X err ("unlink URB timeout");
@@ -884,7 +884,7 @@
X set_current_state(TASK_UNINTERRUPTIBLE);
X while (timeout && dev->ed_cnt)
X timeout = schedule_timeout (timeout);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue (&freedev_wakeup, &wait);
X if (dev->ed_cnt) {
X err ("free device %d timeout", usb_dev->devnum);
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- v2.4.12/linux/drivers/usb/usb-uhci.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/usb-uhci.c Wed Oct 17 14:34:06 2001
@@ -2193,7 +2193,7 @@
X if (status & TD_CTRL_NAK) /* NAK */
X return -ETIMEDOUT;
X if (status & TD_CTRL_BABBLE) /* Babble */
- return -EPIPE;
+ return -EOVERFLOW;
X if (status & TD_CTRL_DBUFERR) /* Buffer error */
X return -ENOSR;
X if (status & TD_CTRL_STALLED) /* Stalled */
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.4.12/linux/drivers/usb/usb.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/usb.c Sat Oct 20 19:13:11 2001
@@ -60,7 +60,7 @@
X */
X LIST_HEAD(usb_driver_list);
X LIST_HEAD(usb_bus_list);
-rwlock_t usb_bus_list_lock = RW_LOCK_UNLOCKED;
+struct semaphore usb_bus_list_lock;
X
X devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
X
@@ -112,7 +112,7 @@
X {
X struct list_head *tmp;
X
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
X tmp = usb_bus_list.next;
X while (tmp != &usb_bus_list) {
X struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
@@ -120,7 +120,7 @@
X tmp = tmp->next;
X usb_check_support(bus->root_hub);
X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
X }
X
X /*
@@ -182,7 +182,7 @@
X */
X list_del(&driver->driver_list);
X
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
X tmp = usb_bus_list.next;
X while (tmp != &usb_bus_list) {
X struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
@@ -190,7 +190,7 @@
X tmp = tmp->next;
X usb_drivers_purge(driver, bus->root_hub);
X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
X }
X
X struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
@@ -421,7 +421,7 @@
X {
X int busnum;
X
- write_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
X busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1);
X if (busnum < USB_MAXBUS) {
X set_bit(busnum, busmap.busmap);


@@ -433,7 +433,7 @@
X

X /* Add it to the list of buses */
X list_add(&bus->bus_list, &usb_bus_list);
- write_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
X
X usbdevfs_add_bus(bus);


X
@@ -455,9 +455,9 @@

X * controller code, as well as having it call this when cleaning
X * itself up
X */
- write_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
X list_del(&bus->bus_list);
- write_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
X
X usbdevfs_remove_bus(bus);
X
@@ -2332,6 +2332,7 @@
X */
X static int __init usb_init(void)
X {
+ init_MUTEX(&usb_bus_list_lock);
X usb_major_init();
X usbdevfs_init();
X usb_hub_init();
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c
--- v2.4.12/linux/drivers/usb/usbnet.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usbnet.c Sat Oct 20 19:13:11 2001
@@ -15,7 +15,7 @@
X * support as appropriate. Devices currently supported include:
X *
X * - AnchorChip 2720
- * - Belkin F5U104 (custom)
+ * - Belkin, eTEK (interops with Win32 drivers)
X * - "Linux Devices" (like iPaq and similar SA-1100 based PDAs)
X * - NetChip 1080 (interoperates with NetChip Win32 drivers)
X * - Prolific PL-2301/2302 (replaces "plusb" driver)
@@ -73,6 +73,9 @@
X * Win32 Belkin driver; other cleanups (db).
X * 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
X * cleanups for problems not yet seen in the field. (db)
+ * 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
+ * from Ioannis Mavroukakis <i.mavr...@btinternet.com>;
+ * rx unlinks somehow weren't async; minor cleanup.
X *
X *-------------------------------------------------------------------------*/
X
@@ -97,7 +100,7 @@
X
X
X #define CONFIG_USB_AN2720
-#define CONFIG_USB_BELKIN_F5U104
+#define CONFIG_USB_BELKIN
X #define CONFIG_USB_LINUXDEV
X #define CONFIG_USB_NET1080
X #define CONFIG_USB_PL2301
@@ -119,7 +122,7 @@
X #endif
X
X // packets are always ethernet inside
-// ... except they can be bigger (up to 64K with this framing)
+// ... except they can be bigger (limit of 64K with NetChip framing)
X #define MIN_PACKET sizeof(struct ethhdr)
X #define MAX_PACKET 32768
X
@@ -161,7 +164,7 @@
X struct sk_buff_head txq;
X struct sk_buff_head done;
X struct tasklet_struct bh;
- struct tq_struct ctrl_task;
+ struct tq_struct ctrl_task;
X };
X
X // device-specific info used by the driver
@@ -169,7 +172,8 @@
X char *description;
X
X int flags;
-#define FLAG_FRAMING 0x0001 /* guard against device dropouts */
+#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
+#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
X
X /* reset device ... can sleep */
X int (*reset)(struct usbnet *);
@@ -251,7 +255,7 @@
X u16 packet_id;
X } __attribute__((__packed__));
X
-// packets may use FLAG_FRAMING and optional pad
+// packets may use FLAG_FRAMING_NC and optional pad
X #define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
X + sizeof (struct ethhdr) \
X + (mtu) \
@@ -288,22 +292,24 @@
X
X
X
-#ifdef CONFIG_USB_BELKIN_F5U104
+#ifdef CONFIG_USB_BELKIN
X
X /*-------------------------------------------------------------------------
X *
X * Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller
X *
+ * ... also two eTEK designs, including one sold as "Advance USBNET"
+ *
X *-------------------------------------------------------------------------*/
X
X static const struct driver_info belkin_info = {
- description: "Belkin USB Direct Connect (F5U104)",
+ description: "Belkin, eTEK, or compatible",
X
X in: 1, out: 1, // direction distinguishes these
X epsize: 64,
X };
X
-#endif /* CONFIG_USB_BELKIN_F5U104 */
+#endif /* CONFIG_USB_BELKIN */
X
X
X
@@ -632,7 +638,7 @@
X
X static const struct driver_info net1080_info = {
X description: "NetChip TurboCONNECT",
- flags: FLAG_FRAMING,
+ flags: FLAG_FRAMING_NC,
X reset: net1080_reset,


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 39'
echo 'File patch-2.4.13 is continued in part 40'
echo "40" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:08 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part38

#!/bin/sh -x
# this is part 38 of a 53 - part archive


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

if test "$Scheck" != 38; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+ bbpnt = SCpnt->bounce_buffers;
X
- for (i = 0; i < SCpnt->use_sg; i++) {
- if (sgpnt[i].alt_address) {
- scsi_free(sgpnt[i].address, sgpnt[i].length);
+ if (bbpnt) {
+ for (i = 0; i < SCpnt->use_sg; i++) {
+ if (bbpnt[i])
+ scsi_free(sgpnt[i].address, sgpnt[i].length);
X }
X }
X scsi_free(SCpnt->request_buffer, SCpnt->sglist_len);
@@ -568,18 +571,22 @@


X */
X if (SCpnt->use_sg) {
X struct scatterlist *sgpnt;
+ void **bbpnt;
X int i;
X

X sgpnt = (struct scatterlist *) SCpnt->buffer;

+ bbpnt = SCpnt->bounce_buffers;
X
- for (i = 0; i < SCpnt->use_sg; i++) {
- if (sgpnt[i].alt_address) {
- if (SCpnt->request.cmd == READ) {
- memcpy(sgpnt[i].alt_address,
- sgpnt[i].address,
- sgpnt[i].length);
+ if (bbpnt) {
+ for (i = 0; i < SCpnt->use_sg; i++) {
+ if (bbpnt[i]) {
+ if (SCpnt->request.cmd == READ) {
+ memcpy(bbpnt[i],
+ sgpnt[i].address,
+ sgpnt[i].length);
+ }
+ scsi_free(sgpnt[i].address, sgpnt[i].length);
X }
- scsi_free(sgpnt[i].address, sgpnt[i].length);
X }
X }
X scsi_free(SCpnt->buffer, SCpnt->sglist_len);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi_merge.c linux/drivers/scsi/scsi_merge.c
--- v2.4.12/linux/drivers/scsi/scsi_merge.c Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/scsi_merge.c Fri Oct 12 15:35:54 2001
@@ -120,9 +120,11 @@
X {
X int jj;


X struct scatterlist *sgpnt;
+ void **bbpnt;

X int consumed = 0;
X
X sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+ bbpnt = SCpnt->bounce_buffers;
X
X /*
X * Now print out a bunch of stats. First, start with the request
@@ -136,15 +138,13 @@
X */
X for(jj=0; jj < SCpnt->use_sg; jj++)
X {
- printk("[%d]\tlen:%d\taddr:%p\talt:%p\n",
+ printk("[%d]\tlen:%d\taddr:%p\tbounce:%p\n",
X jj,
X sgpnt[jj].length,
X sgpnt[jj].address,
- sgpnt[jj].alt_address);
- if( sgpnt[jj].alt_address != NULL )
- {
- consumed = (sgpnt[jj].length >> 9);
- }
+ (bbpnt ? bbpnt[jj] : NULL));
+ if (bbpnt && bbpnt[jj])
+ consumed += sgpnt[jj].length;
X }
X printk("Total %d sectors consumed\n", consumed);
X panic("DMA pool exhausted");
@@ -807,6 +807,7 @@
X int sectors;
X struct scatterlist * sgpnt;
X int this_count;
+ void ** bbpnt;
X
X /*
X * FIXME(eric) - don't inline this - it doesn't depend on the
@@ -861,10 +862,19 @@
X
X /*
X * Allocate the actual scatter-gather table itself.
- * scsi_malloc can only allocate in chunks of 512 bytes
X */
- SCpnt->sglist_len = (SCpnt->use_sg
- * sizeof(struct scatterlist) + 511) & ~511;
+ SCpnt->sglist_len = (SCpnt->use_sg * sizeof(struct scatterlist));
+
+ /* If we could potentially require ISA bounce buffers, allocate
+ * space for this array here.
+ */
+ if (dma_host)
+ SCpnt->sglist_len += (SCpnt->use_sg * sizeof(void *));
+
+ /* scsi_malloc can only allocate in chunks of 512 bytes so
+ * round it up.
+ */
+ SCpnt->sglist_len = (SCpnt->sglist_len + 511) & ~511;
X
X sgpnt = (struct scatterlist *) scsi_malloc(SCpnt->sglist_len);
X
@@ -889,6 +899,14 @@
X SCpnt->request_bufflen = 0;
X bhprev = NULL;
X
+ if (dma_host)
+ bbpnt = (void **) ((char *)sgpnt +
+ (SCpnt->use_sg * sizeof(struct scatterlist)));
+ else
+ bbpnt = NULL;
+
+ SCpnt->bounce_buffers = bbpnt;
+
X for (count = 0, bh = SCpnt->request.bh;
X bh; bh = bh->b_reqnext) {
X if (use_clustering && bhprev != NULL) {
@@ -956,7 +974,7 @@
X if( scsi_dma_free_sectors - sectors <= 10 ) {
X /*
X * If this would nearly drain the DMA
- * pool, mpty, then let's stop here.
+ * pool empty, then let's stop here.
X * Don't make this request any larger.
X * This is kind of a safety valve that
X * we use - we could get screwed later
@@ -970,7 +988,7 @@
X break;
X }
X
- sgpnt[i].alt_address = sgpnt[i].address;
+ bbpnt[i] = sgpnt[i].address;
X sgpnt[i].address =
X (char *) scsi_malloc(sgpnt[i].length);
X /*
@@ -987,7 +1005,7 @@
X break;
X }
X if (SCpnt->request.cmd == WRITE) {
- memcpy(sgpnt[i].address, sgpnt[i].alt_address,
+ memcpy(sgpnt[i].address, bbpnt[i],


X sgpnt[i].length);
X }
X }

diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- v2.4.12/linux/drivers/scsi/scsi_scan.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/scsi_scan.c Thu Oct 11 09:43:30 2001
@@ -421,6 +421,10 @@
X max_scsi_luns : shpnt->max_lun);
X sparse_lun = 0;
X for (lun = 0, lun0_sl = SCSI_2; lun < max_dev_lun; ++lun) {
+ /* don't probe further for luns > 7 for targets <= SCSI_2 */
+ if ((lun0_sl < SCSI_3) && (lun > 7))
+ break;
+
X if (!scan_scsis_single(channel, order_dev, lun, lun0_sl,
X &max_dev_lun, &sparse_lun, &SDpnt, shpnt,
X scsi_result)
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.12/linux/drivers/scsi/sd.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/sd.c Mon Oct 15 19:30:33 2001
@@ -152,6 +152,9 @@
X int diskinfo[4];
X
X SDev = rscsi_disks[DEVICE_NR(dev)].device;
+ if (!SDev)
+ return -ENODEV;
+
X /*
X * If we are in the middle of error recovery, don't let anyone
X * else try and use this device. Also, if error recovery fails, it
@@ -228,7 +231,7 @@
X return 0;
X }


X case BLKGETSIZE: /* Return device size */

- return put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, (long *) arg);
+ return put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)sd[SD_PARTITION(inode->i_rdev)].nr_sects << 9, (u64 *)arg);
X

@@ -533,6 +536,8 @@
X

X target = DEVICE_NR(inode->i_rdev);
X SDev = rscsi_disks[target].device;
+ if (!SDev)
+ return -ENODEV;
X
X SDev->access_count--;
X
@@ -786,7 +791,7 @@
X SRpnt->sr_cmd_len = 0;
X SRpnt->sr_sense_buffer[0] = 0;
X SRpnt->sr_sense_buffer[2] = 0;
- SRpnt->sr_data_direction = SCSI_DATA_READ;
+ SRpnt->sr_data_direction = SCSI_DATA_NONE;
X
X scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
X 0/*512*/, SD_TIMEOUT, MAX_RETRIES);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.4.12/linux/drivers/scsi/sr.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/sr.c Fri Oct 12 15:35:54 2001
@@ -264,6 +264,7 @@
X struct scatterlist *sg, *old_sg = NULL;
X int i, fsize, bsize, sg_ent, sg_count;
X char *front, *back;
+ void **bbpnt, **old_bbpnt = NULL;
X
X back = front = NULL;
X sg_ent = SCpnt->use_sg;
@@ -291,17 +292,25 @@
X * extend or allocate new scatter-gather table
X */
X sg_count = SCpnt->use_sg;
- if (sg_count)
+ if (sg_count) {
X old_sg = (struct scatterlist *) SCpnt->request_buffer;
- else {
+ old_bbpnt = SCpnt->bounce_buffers;
+ } else {
X sg_count = 1;
X sg_ent++;
X }
X
- i = ((sg_ent * sizeof(struct scatterlist)) + 511) & ~511;
+ /* Get space for scatterlist and bounce buffer array. */
+ i = sg_ent * sizeof(struct scatterlist);
+ i += sg_ent * sizeof(void *);
+ i = (i + 511) & ~511;
+
X if ((sg = scsi_malloc(i)) == NULL)
X goto no_mem;
X
+ bbpnt = (void **)
+ ((char *)sg + (sg_ent * sizeof(struct scatterlist)));
+
X /*
X * no more failing memory allocs possible, we can safely assign
X * SCpnt values now
@@ -312,13 +321,15 @@
X
X i = 0;
X if (fsize) {
- sg[0].address = sg[0].alt_address = front;
+ sg[0].address = bbpnt[0] = front;
X sg[0].length = fsize;
X i++;
X }
X if (old_sg) {
X memcpy(sg + i, old_sg, SCpnt->use_sg * sizeof(struct scatterlist));
- scsi_free(old_sg, ((SCpnt->use_sg * sizeof(struct scatterlist)) + 511) & ~511);
+ memcpy(bbpnt + i, old_bbpnt, SCpnt->use_sg * sizeof(void *));
+ scsi_free(old_sg, (((SCpnt->use_sg * sizeof(struct scatterlist)) +
+ (SCpnt->use_sg * sizeof(void *))) + 511) & ~511);
X } else {
X sg[i].address = SCpnt->request_buffer;
X sg[i].length = SCpnt->request_bufflen;
@@ -326,11 +337,12 @@
X
X SCpnt->request_bufflen += (fsize + bsize);
X SCpnt->request_buffer = sg;
+ SCpnt->bounce_buffers = bbpnt;
X SCpnt->use_sg += i;
X
X if (bsize) {
X sg[SCpnt->use_sg].address = back;
- sg[SCpnt->use_sg].alt_address = back;
+ bbpnt[SCpnt->use_sg] = back;
X sg[SCpnt->use_sg].length = bsize;
X SCpnt->use_sg++;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.4.12/linux/drivers/scsi/sr_ioctl.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/sr_ioctl.c Mon Oct 15 13:27:42 2001
@@ -545,7 +545,7 @@
X
X switch (cmd) {
X case BLKGETSIZE:
- return put_user(scsi_CDs[target].capacity, (long *) arg);
+ return put_user(scsi_CDs[target].capacity, (unsigned long *) arg);
X case BLKGETSIZE64:
X return put_user((u64)scsi_CDs[target].capacity << 9, (u64 *)arg);
X case BLKROSET:
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.4.12/linux/drivers/scsi/st.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/st.c Fri Oct 12 15:35:54 2001
@@ -3229,7 +3229,6 @@


X tb->sg[0].address =

X (unsigned char *) __get_free_pages(priority, order);


X if (tb->sg[0].address != NULL) {
- tb->sg[0].alt_address = NULL;
X tb->sg[0].length = b_size;
X break;
X }

@@ -3265,7 +3264,6 @@


X tb = NULL;
X break;
X }
- tb->sg[segs].alt_address = NULL;
X tb->sg[segs].length = b_size;
X got += b_size;
X segs++;

@@ -3339,7 +3337,6 @@


X normalize_buffer(STbuffer);
X return FALSE;
X }
- STbuffer->sg[segs].alt_address = NULL;
X STbuffer->sg[segs].length = b_size;
X STbuffer->sg_segs += 1;
X got += b_size;

diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.4.12/linux/drivers/scsi/sym53c8xx.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/sym53c8xx.c Wed Oct 17 14:16:39 2001
@@ -987,8 +987,8 @@
X if (vbp) {
X dma_addr_t daddr;
X vp = (m_addr_t) pci_alloc_consistent(mp->bush,
- PAGE_SIZE<<MEMO_PAGE_ORDER,
- &daddr);
+ PAGE_SIZE<<MEMO_PAGE_ORDER,
+ &daddr);
X if (vp) {
X int hc = VTOB_HASH_CODE(vp);
X vbp->vaddr = vp;
@@ -1138,26 +1138,26 @@
X /* Linux version with pci bus iommu kernel interface */
X
X /* To keep track of the dma mapping (sg/single) that has been set */
-#define __data_mapped SCp.phase
-#define __data_mapping SCp.have_data_in
+#define __data_mapped(cmd) (cmd)->SCp.phase
+#define __data_mapping(cmd) (cmd)->SCp.dma_handle
X
X static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
X {
X int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
X
- switch(cmd->__data_mapped) {
+ switch(__data_mapped(cmd)) {
X case 2:
X pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
X break;
X case 1:
- pci_unmap_single(pdev, cmd->__data_mapping,
- cmd->request_bufflen, dma_dir);
+ pci_unmap_page(pdev, __data_mapping(cmd),
+ cmd->request_bufflen, dma_dir);
X break;
X }
- cmd->__data_mapped = 0;
+ __data_mapped(cmd) = 0;
X }
X
-static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+static dma_addr_t __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
X {
X dma_addr_t mapping;
X int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
@@ -1165,10 +1165,13 @@
X if (cmd->request_bufflen == 0)
X return 0;
X
- mapping = pci_map_single(pdev, cmd->request_buffer,
- cmd->request_bufflen, dma_dir);
- cmd->__data_mapped = 1;
- cmd->__data_mapping = mapping;
+ mapping = pci_map_page(pdev,
+ virt_to_page(cmd->request_buffer),
+ ((unsigned long)cmd->request_buffer &
+ ~PAGE_MASK),
+ cmd->request_bufflen, dma_dir);
+ __data_mapped(cmd) = 1;
+ __data_mapping(cmd) = mapping;
X
X return mapping;
X }
@@ -1182,8 +1185,8 @@
X return 0;
X
X use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
- cmd->__data_mapped = 2;
- cmd->__data_mapping = use_sg;
+ __data_mapped(cmd) = 2;
+ __data_mapping(cmd) = use_sg;
X
X return use_sg;
X }
@@ -1192,12 +1195,12 @@
X {
X int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
X
- switch(cmd->__data_mapped) {
+ switch(__data_mapped(cmd)) {
X case 2:
X pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
X break;
X case 1:
- pci_dma_sync_single(pdev, cmd->__data_mapping,
+ pci_dma_sync_single(pdev, __data_mapping(cmd),
X cmd->request_bufflen, dma_dir);
X break;
X }
@@ -5029,12 +5032,12 @@
X /*
X ** 64 bit (53C895A or 53C896) ?
X */
- if (np->features & FE_DAC)
-#ifdef SCSI_NCR_USE_64BIT_DAC
- np->rv_ccntl1 |= (XTIMOD | EXTIBMV);
-#else
- np->rv_ccntl1 |= (DDAC);
-#endif
+ if (np->features & FE_DAC) {
+ if (np->features & FE_DAC_IN_USE)
+ np->rv_ccntl1 |= (XTIMOD | EXTIBMV);
+ else
+ np->rv_ccntl1 |= (DDAC);
+ }
X
X /*
X ** Phase mismatch handled by SCRIPTS (53C895A, 53C896 or C1010) ?
@@ -12068,15 +12071,9 @@
X ** code will get more complex later).
X */
X
-#ifdef SCSI_NCR_USE_64BIT_DAC
X #define SCATTER_ONE(data, badd, len) \
X (data)->addr = cpu_to_scr(badd); \
X (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);
-#else
-#define SCATTER_ONE(data, badd, len) \
- (data)->addr = cpu_to_scr(badd); \
- (data)->size = cpu_to_scr(len);
-#endif
X
X #define CROSS_16MB(p, n) (((((u_long) p) + n - 1) ^ ((u_long) p)) & ~0xffffff)
X
@@ -12088,7 +12085,7 @@
X cp->data_len = cmd->request_bufflen;
X
X if (cmd->request_bufflen) {
- u_long baddr = map_scsi_single_data(np, cmd);
+ dma_addr_t baddr = map_scsi_single_data(np, cmd);
X
X SCATTER_ONE(data, baddr, cmd->request_bufflen);
X if (CROSS_16MB(baddr, cmd->request_bufflen)) {
@@ -12139,7 +12136,7 @@
X data = &cp->phys.data[MAX_SCATTER - use_sg];
X
X for (segn = 0; segn < use_sg; segn++) {
- u_long baddr = scsi_sg_dma_address(&scatter[segn]);
+ dma_addr_t baddr = scsi_sg_dma_address(&scatter[segn]);
X unsigned int len = scsi_sg_dma_len(&scatter[segn]);
X
X SCATTER_ONE(&data[segn],
@@ -12178,7 +12175,7 @@
X data = &cp->phys.data[MAX_SCATTER - use_sg];
X
X for (segment = 0; segment < use_sg; segment++) {
- u_long baddr = scsi_sg_dma_address(&scatter[segment]);
+ dma_addr_t baddr = scsi_sg_dma_address(&scatter[segment]);
X unsigned int len = scsi_sg_dma_len(&scatter[segment]);
X
X SCATTER_ONE(&data[segment],
@@ -13098,14 +13095,6 @@
X (int) (PciDeviceFn(pdev) & 0xf8) >> 3,
X (int) (PciDeviceFn(pdev) & 7));
X
-#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
- if (pci_set_dma_mask(pdev, (dma_addr_t) (0xffffffffUL))) {
- printk(KERN_WARNING NAME53C8XX
- "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
- return -1;
- }
-#endif
-
X /*
X ** Read info from the PCI config space.
X ** pci_read_config_xxx() functions are assumed to be used for
@@ -13173,6 +13162,28 @@
X break;
X }
X
+#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
+ /* Configure DMA attributes. For DAC capable boards, we can encode
+ ** 32+8 bits for SCSI DMA data addresses with the extra bits used
+ ** in the size field. We use normal 32-bit PCI addresses for
+ ** descriptors.
+ */
+ if (chip && (chip->features & FE_DAC)) {
+ if (pci_set_dma_mask(pdev, (u64) 0xffffffffff))
+ chip->features &= ~FE_DAC_IN_USE;
+ else
+ chip->features |= FE_DAC_IN_USE;
+ }
+
+ if (chip && !(chip->features & FE_DAC_IN_USE)) {
+ if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
+ printk(KERN_WARNING NAME53C8XX
+ "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");


+ return -1;
+ }
+ }

+#endif
+
X /*
X ** Ignore Symbios chips controlled by SISL RAID controller.
X ** This controller sets value 0x52414944 at RAM end - 16.
@@ -13609,8 +13620,8 @@
X cmd->SCp.ptr = NULL;
X cmd->SCp.buffer = NULL;
X #ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
- cmd->__data_mapped = 0;
- cmd->__data_mapping = 0;
+ __data_mapped(cmd) = 0;
+ __data_mapping(cmd) = 0;
X #endif
X
X NCR_LOCK_NCB(np, flags);
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sym53c8xx_comm.h linux/drivers/scsi/sym53c8xx_comm.h
--- v2.4.12/linux/drivers/scsi/sym53c8xx_comm.h Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/sym53c8xx_comm.h Fri Oct 12 15:35:54 2001
@@ -2186,7 +2186,7 @@
X (int) (PciDeviceFn(pdev) & 7));
X
X #ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
- if (!pci_dma_supported(pdev, (dma_addr_t) (0xffffffffUL))) {
+ if (!pci_dma_supported(pdev, 0xffffffff)) {
X printk(KERN_WARNING NAME53C8XX
X "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
X return -1;
diff -u --recursive --new-file v2.4.12/linux/drivers/scsi/sym53c8xx_defs.h linux/drivers/scsi/sym53c8xx_defs.h
--- v2.4.12/linux/drivers/scsi/sym53c8xx_defs.h Thu Oct 18 13:50:38 2001
+++ linux/drivers/scsi/sym53c8xx_defs.h Tue Oct 23 22:02:29 2001
@@ -184,20 +184,6 @@
X #endif
X
X /*
- * Should we enable DAC cycles on Sparc64 platform?
- * Until further investigation we do not enable it


- * at the moment.

- * We may want to enable it for __ia64__ (untested)
- */
-#if defined(__ia64__)
-# if !defined(SCSI_NCR_USE_64BIT_DAC)
-# define SCSI_NCR_USE_64BIT_DAC
-# endif
-#else
-# undef SCSI_NCR_USE_64BIT_DAC
-#endif
-
-/*
X * Immediate arbitration
X */
X #if defined(CONFIG_SCSI_NCR53C8XX_IARB)
@@ -205,13 +191,6 @@
X #endif
X
X /*
- * Should we enable DAC cycles on sparc64 platforms?
- * Until further investigation we do not enable it
- * anywhere at the moment.
- */
-#undef SCSI_NCR_USE_64BIT_DAC
-
-/*
X * Sync transfer frequency at startup.
X * Allow from 5Mhz to 80Mhz default 20 Mhz.
X */
@@ -746,6 +725,7 @@
X #define FE_66MHZ (1<<23) /* 66MHz PCI Support */
X #define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */
X #define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */
+#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */
X
X #define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
X #define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80)
diff -u --recursive --new-file v2.4.12/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.4.12/linux/drivers/sgi/char/graphics.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/sgi/char/graphics.c Thu Oct 11 09:43:30 2001
@@ -343,6 +343,8 @@


X }
X
X #ifdef MODULE

+MODULE_LICENSE("GPL");
+
X int init_module(void) {
X static int initiated = 0;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/btaudio.c linux/drivers/sound/btaudio.c
--- v2.4.12/linux/drivers/sound/btaudio.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/btaudio.c Wed Oct 17 14:19:20 2001
@@ -748,6 +748,24 @@
X case SNDCTL_DSP_SYNC:
X /* NOP */
X return 0;
+ case SNDCTL_DSP_GETISPACE:
+ {
+ audio_buf_info info;
+ if (!bta->recording)
+ return -EINVAL;
+ info.fragsize = bta->block_bytes>>bta->sampleshift;
+ info.fragstotal = bta->block_count;
+ info.bytes = bta->read_count;
+ info.fragments = info.bytes / info.fragsize;
+ if (debug)
+ printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE "
+ "returns %d/%d/%d/%d\n",
+ info.fragsize, info.fragstotal,
+ info.bytes, info.fragments);
+ if (copy_to_user((void *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
X #if 0 /* TODO */
X case SNDCTL_DSP_GETTRIGGER:
X case SNDCTL_DSP_SETTRIGGER:
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.12/linux/drivers/sound/cmpci.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/cmpci.c Thu Oct 11 09:43:30 2001
@@ -74,6 +74,7 @@
X * 18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
X * was calling prog_dmabuf with s->lock held, call missing
X * unlock_kernel in cm_midi_release
+ * 08/10/2001 - use set_current_state in some more places
X *
X * Carlos Eduardo Gorges <car...@techlinux.com.br>
X * Fri May 25 2001
@@ -1483,7 +1484,7 @@
X
X if (s->dma_dac.mapped || !s->dma_dac.ready)
X return 0;


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);

X add_wait_queue(&s->dma_dac.wait, &wait);
X for (;;) {
X spin_lock_irqsave(&s->lock, flags);
@@ -1495,7 +1496,7 @@
X break;
X if (nonblock) {
X remove_wait_queue(&s->dma_dac.wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X return -EBUSY;
X }
X tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
@@ -1504,7 +1505,7 @@
X printk(KERN_DEBUG "cmpci: dma timed out??\n");
X }
X remove_wait_queue(&s->dma_dac.wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X if (signal_pending(current))
X return -ERESTARTSYS;
X return 0;
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/ite8172.c linux/drivers/sound/ite8172.c
--- v2.4.12/linux/drivers/sound/ite8172.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/ite8172.c Thu Oct 11 09:43:30 2001
@@ -58,7 +58,7 @@
X #include <linux/sched.h>
X #include <linux/delay.h>
X #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/soundcard.h>
X #include <linux/pci.h>
X #include <linux/init.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- v2.4.12/linux/drivers/sound/maestro3.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/maestro3.c Thu Oct 11 09:43:30 2001
@@ -172,7 +172,7 @@
X #define SND_DEV_DSP16 5
X
X #ifdef M_DEBUG
-static int debug=0;
+static int debug;
X #define DPMOD 1 /* per module load */
X #define DPSTR 2 /* per 'stream' */
X #define DPSYS 3 /* per syscall */
@@ -365,7 +365,7 @@
X return r;
X }
X
-static struct m3_card *devs = NULL;
+static struct m3_card *devs;
X
X /*
X * I'm not very good at laying out functions in a file :)
@@ -1289,7 +1289,7 @@
X
X if (s->dma_dac.mapped || !s->dma_dac.ready)
X return 0;


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);

X add_wait_queue(&s->dma_dac.wait, &wait);
X for (;;) {
X spin_lock_irqsave(&s->lock, flags);
@@ -1301,7 +1301,7 @@
X break;
X if (nonblock) {
X remove_wait_queue(&s->dma_dac.wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X return -EBUSY;
X }
X tmo = (count * HZ) / s->ratedac;
@@ -1312,7 +1312,7 @@
X DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
X }
X remove_wait_queue(&s->dma_dac.wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X if (signal_pending(current))
X return -ERESTARTSYS;
X return 0;
@@ -2251,7 +2251,7 @@
X if(busywait) {
X mdelay(delay1);
X } else {
- current->state = TASK_UNINTERRUPTIBLE;
+ set_current_state(TASK_UNINTERRUPTIBLE);
X schedule_timeout((delay1 * HZ) / 1000);
X }
X
@@ -2264,7 +2264,7 @@
X if(busywait) {
X mdelay(delay2);
X } else {
- current->state = TASK_UNINTERRUPTIBLE;
+ set_current_state(TASK_UNINTERRUPTIBLE);
X schedule_timeout((delay2 * HZ) / 1000);
X }
X if(! try_read_vendor(card))
@@ -2958,8 +2958,8 @@
X
X card->in_suspend++;
X add_wait_queue(&card->suspend_queue, &wait);
- current->state = TASK_UNINTERRUPTIBLE;
+ set_current_state(TASK_UNINTERRUPTIBLE);
X schedule();
X remove_wait_queue(&card->suspend_queue, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X }
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/nec_vrc5477.c linux/drivers/sound/nec_vrc5477.c
--- v2.4.12/linux/drivers/sound/nec_vrc5477.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/nec_vrc5477.c Thu Oct 11 09:43:30 2001
@@ -67,7 +67,7 @@
X #include <linux/sched.h>
X #include <linux/delay.h>
X #include <linux/sound.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/soundcard.h>
X #include <linux/pci.h>
X #include <linux/init.h>
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.4.12/linux/drivers/sound/opl3sa2.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/opl3sa2.c Thu Oct 11 09:43:30 2001
@@ -862,9 +862,9 @@
X
X /* Our own config: */
X hw_cfg->io_base = dev->resource[4].start;
- hw_cfg->irq = 0;
- hw_cfg->dma = -1;
- hw_cfg->dma2 = -1;
+ hw_cfg->irq = dev->irq_resource[0].start;
+ hw_cfg->dma = dev->dma_resource[0].start;
+ hw_cfg->dma2 = dev->dma_resource[1].start;
X
X /* The MSS config: */
X mss_cfg->io_base = dev->resource[1].start;
@@ -944,9 +944,9 @@
X * give pretty output from conf_printf. :)
X */
X cfg[card].io_base = io;
- cfg[card].irq = 0;
- cfg[card].dma = -1;
- cfg[card].dma2 = -1;
+ cfg[card].irq = irq;
+ cfg[card].dma = dma;
+ cfg[card].dma2 = dma2;
X
X /* The MSS config: */
X cfg_mss[card].io_base = mss_io;
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.4.12/linux/drivers/sound/sb_card.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/sb_card.c Thu Oct 11 09:43:30 2001
@@ -53,6 +53,9 @@
X *
X * 28-10-2000 Added pnplegacy support
X * Daniel Church <dch...@mbhs.edu>
+ *
+ * 01-10-2001 Added a new flavor of Creative SB AWE64 PnP (CTL00E9).
+ * Jerome Cornet <jco...@free.fr>
X */
X
X #include <linux/config.h>
@@ -434,6 +437,11 @@
X ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
X 0,0,0,0,
X 0,1,1,-1},
+ {"Sound Blaster AWE 64",
+ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
+ ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
+ 0,0,0,0,
+ 0,1,1,-1},
X {"ESS 1688",
X ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
X ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
@@ -621,6 +629,9 @@
X ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
X
X { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
+ ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
+
+ { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
X ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
X
X { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.12/linux/drivers/sound/trident.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/trident.c Thu Oct 11 09:43:30 2001
@@ -36,6 +36,10 @@


X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *

X * History
+ * v0.14.9d
+ * October 8 2001 Arnaldo Carvalho de Melo <ac...@conectiva.com.br>
+ * use set_current_state, properly release resources on failure in
+ * trident_probe, get rid of check_region
X * v0.14.9c
X * August 10 2001 Peter Wächtler <pwaec...@loewe-komp.de>
X * added support for Tvia (formerly Integraphics/IGST) CyberPro5050
@@ -176,7 +180,7 @@
X
X #include <linux/pm.h>
X
-#define DRIVER_VERSION "0.14.9c"
+#define DRIVER_VERSION "0.14.9d"
X
X /* magic numbers to protect our data structures */
X #define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
@@ -1358,7 +1362,7 @@
X for (;;) {
X /* It seems that we have to set the current state to TASK_INTERRUPTIBLE
X every time to make the process really go to sleep */


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X

X spin_lock_irqsave(&state->card->lock, flags);
X count = dmabuf->count;
@@ -1372,7 +1376,7 @@
X
X if (nonblock) {
X remove_wait_queue(&dmabuf->wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X return -EBUSY;
X }
X
@@ -1395,7 +1399,7 @@
X }
X }
X remove_wait_queue(&dmabuf->wait, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X if (signal_pending(current))
X return -ERESTARTSYS;
X
@@ -3695,7 +3699,7 @@
X }
X
X #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *res = NULL;
+struct proc_dir_entry *res;
X static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
X {
X struct trident_card *card = (struct trident_card *)data;
@@ -3936,14 +3940,15 @@


X int i = 0;

X u16 temp;
X struct pci_dev *pci_dev_m1533 = NULL;
+ int rc = -ENODEV;
X
X if (pci_enable_device(pci_dev))
- return -ENODEV;
+ goto out;
X
X if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
X printk(KERN_ERR "trident: architecture does not support"
X " 30bit PCI busmaster DMA\n");
- return -ENODEV;
+ goto out;
X }
X pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
X
@@ -3952,15 +3957,16 @@
X else
X iobase = pci_resource_start(pci_dev, 0);
X
- if (check_region(iobase, 256)) {
+ if (!request_region(iobase, 256, card_names[pci_id->driver_data])) {
X printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
X iobase);
- return -ENODEV;
+ goto out;
X }
X
+ rc = -ENOMEM;
X if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
X printk(KERN_ERR "trident: out of memory\n");
- return -ENOMEM;
+ goto out_release_region;
X }
X memset(card, 0, sizeof(*card));
X
@@ -4014,8 +4020,9 @@
X /* Add H/W Volume Control By Matt Wu Jul. 06, 2001 */
X card->hwvolctl = 0;
X pci_dev_m1533 = pci_find_device(PCI_VENDOR_ID_AL,PCI_DEVICE_ID_AL_M1533, pci_dev_m1533);
+ rc = -ENODEV;
X if (pci_dev_m1533 == NULL)
- return -ENODEV;
+ goto out_proc_fs;
X pci_read_config_byte(pci_dev_m1533, 0x63, &bits);
X if (bits & (1<<5))
X card->hwvolctl = 1;
@@ -4044,22 +4051,17 @@
X card->address_interrupt = trident_address_interrupt;
X }
X
- /* claim our iospace and irq */
- request_region(card->iobase, 256, card_names[pci_id->driver_data]);
+ /* claim our irq */
+ rc = -ENODEV;
X if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
X card_names[pci_id->driver_data], card)) {
X printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
- release_region(card->iobase, 256);
- kfree(card);
- return -ENODEV;
+ goto out_proc_fs;
X }
X /* register /dev/dsp */
X if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) {
X printk(KERN_ERR "trident: couldn't register DSP device!\n");
- release_region(iobase, 256);
- free_irq(card->irq, card);
- kfree(card);
- return -ENODEV;
+ goto out_free_irq;
X }
X card->mixer_regs_ready = 0;
X /* initialize AC97 codec and register /dev/mixer */
@@ -4071,11 +4073,7 @@
X kfree (card->ac97_codec[i]);
X }
X }
- unregister_sound_dsp(card->dev_audio);
- release_region(iobase, 256);
- free_irq(card->irq, card);
- kfree(card);
- return -ENODEV;
+ goto out_unregister_sound_dsp;
X }
X card->mixer_regs_ready = 1;
X outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
@@ -4112,13 +4110,28 @@
X #endif
X /* edited by HMSEO for GT sound*/
X }
-
+ rc = 0;
X pci_set_drvdata(pci_dev, card);
X
X /* Enable Address Engine Interrupts */
X trident_enable_loop_interrupts(card);
-
- return 0;
+out: return rc;
+out_unregister_sound_dsp:
+ unregister_sound_dsp(card->dev_audio);
+out_free_irq:
+ free_irq(card->irq, card);
+out_proc_fs:
+#ifdef CONFIG_PROC_FS
+ if (res) {
+ remove_proc_entry("ALi5451", NULL);
+ res = NULL;
+ }
+#endif
+ kfree(card);
+ devs = NULL;
+out_release_region:
+ release_region(iobase, 256);
+ goto out;
X }
X
X static void __exit trident_remove(struct pci_dev *pci_dev)
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/vidc.c linux/drivers/sound/vidc.c
--- v2.4.12/linux/drivers/sound/vidc.c Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/vidc.c Thu Oct 11 09:43:30 2001
@@ -542,3 +542,8 @@
X
X module_init(init_vidc);
X module_exit(cleanup_vidc);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC20 audio driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- v2.4.12/linux/drivers/sound/ymfpci.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/sound/ymfpci.c Mon Oct 22 08:38:18 2001
@@ -66,10 +66,13 @@
X * I do not believe in debug levels as I never can guess what
X * part of the code is going to be problematic in the future.
X * Don't forget to run your klogd with -c 8.
+ *
+ * Example (do not remove):
+ * #define YMFDBG(fmt, arg...) do{ printk(KERN_DEBUG fmt, ##arg); }while(0)
X */
-/* #define YMFDBG(fmt, arg...) do{ printk(KERN_DEBUG fmt, ##arg); }while(0) */
-#define YMFDBGW(fmt, arg...) /* */
-#define YMFDBGI(fmt, arg...) /* */
+#define YMFDBGW(fmt, arg...) /* */ /* write counts */
+#define YMFDBGI(fmt, arg...) /* */ /* interrupts */
+#define YMFDBGX(fmt, arg...) /* */ /* ioctl */
X
X static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
X static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
@@ -330,7 +333,7 @@
X int w_16;
X unsigned bufsize;
X unsigned long flags;
- int redzone;
+ int redzone, redfrags;
X int ret;
X
X w_16 = ymf_pcm_format_width(state->format.format) == 16;
@@ -352,36 +355,27 @@
X * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT.
X */
X bufsize = PAGE_SIZE << dmabuf->buforder;
- /* lets hand out reasonable big ass buffers by default */
- dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
+ /* By default we give 4 big buffers. */
+ dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT - 2);
X if (dmabuf->ossfragshift > 3 &&
X dmabuf->ossfragshift < dmabuf->fragshift) {
+ /* If OSS set smaller fragments, give more smaller buffers. */
X dmabuf->fragshift = dmabuf->ossfragshift;
X }
- dmabuf->numfrag = bufsize >> dmabuf->fragshift;
- while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) {
- dmabuf->fragshift--;
- dmabuf->numfrag = bufsize >> dmabuf->fragshift;
- }
X dmabuf->fragsize = 1 << dmabuf->fragshift;
- dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
X
- if (dmabuf->ossmaxfrags >= 2 && dmabuf->ossmaxfrags < dmabuf->numfrag) {
- dmabuf->numfrag = dmabuf->ossmaxfrags;
- dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
+ dmabuf->numfrag = bufsize >> dmabuf->fragshift;
+ dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
X
+ if (dmabuf->ossmaxfrags >= 2) {
X redzone = ymf_calc_lend(state->format.rate);
- redzone <<= (state->format.shift + 1);
- if (dmabuf->dmasize < redzone*3) {
- /*
- * The driver works correctly with minimum dmasize
- * of redzone*2, but it produces stoppage and clicks.
- * So, make it little larger for smoother sound.
- * XXX Make dmasize a wholy divisible by fragsize.
- */
-// printk(KERN_ERR "ymfpci: dmasize=%d < redzone=%d * 3\n",
-// dmabuf->dmasize, redzone);
- dmabuf->dmasize = redzone*3;
+ redzone <<= state->format.shift;
+ redzone *= 3;
+ redfrags = (redzone + dmabuf->fragsize-1) >> dmabuf->fragshift;
+
+ if (dmabuf->ossmaxfrags + redfrags < dmabuf->numfrag) {
+ dmabuf->numfrag = dmabuf->ossmaxfrags + redfrags;
+ dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
X }
X }
X
@@ -1440,7 +1434,7 @@
X set_current_state(TASK_RUNNING);
X remove_wait_queue(&dmabuf->wait, &waita);
X
- YMFDBGW("ymf_write: dmabuf.count %d\n", dmabuf->count);
+ YMFDBGW("ymf_write: ret %d dmabuf.count %d\n", ret, dmabuf->count);


X return ret;
X }
X

@@ -1794,6 +1788,7 @@
X case SNDCTL_DSP_SETSYNCRO:
X case SOUND_PCM_WRITE_FILTER:
X case SOUND_PCM_READ_FILTER:
+ YMFDBGX("ymf_ioctl: cmd 0x%x unsupported\n", cmd);
X return -ENOTTY;
X
X default:
@@ -1802,7 +1797,8 @@
X * or perhaps they expect "universal" ioctls,
X * for instance we get SNDCTL_TMR_CONTINUE here.
X */
- break;
+ YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd);
+ break;
X }
X return -ENOTTY;
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/tc/tc.c linux/drivers/tc/tc.c
--- v2.4.12/linux/drivers/tc/tc.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/tc/tc.c Thu Oct 11 09:43:30 2001
@@ -25,6 +25,7 @@
X
X #define TC_DEBUG
X
+MODULE_LICENSE("GPL");
X slot_info tc_bus[MAX_SLOT];
X static int max_tcslot;
X static tcinfo *info;
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.4.12/linux/drivers/usb/Config.in Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/Config.in Wed Oct 17 14:35:17 2001
@@ -4,8 +4,8 @@
X mainmenu_option next_comment
X comment 'USB support'
X
-tristate 'Support for USB' CONFIG_USB
-if [ ! "$CONFIG_USB" = "n" ]; then
+dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then
X bool ' USB verbose debug messages' CONFIG_USB_DEBUG
X
X comment 'Miscellaneous USB options'
@@ -15,73 +15,84 @@
X else
X define_bool CONFIG_USB_BANDWIDTH n
X fi
+ bool ' Long timeout for slow-responding devices (some MGE Ellipse UPSes)' CONFIG_USB_LONG_TIMEOUT
+ bool ' Large report fetching for "broken" devices (some APC UPSes)' CONFIG_USB_LARGE_CONFIG
+fi
X
X comment 'USB Controllers'
- if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
- dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
- fi
- if [ "$CONFIG_USB_UHCI" != "y" ]; then
- dep_tristate ' UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
- fi
- dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
+if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
+ dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
+fi
+if [ "$CONFIG_USB_UHCI" != "y" ]; then
+ dep_tristate ' UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
+else
+ define_bool CONFIG_USB_UHCI_ALT n
+fi
+dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
X
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
- dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
- if [ "$CONFIG_USB_STORAGE" != "n" ]; then
- bool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
- bool ' Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM
- bool ' ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200
- bool ' Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e
- bool ' SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09
- fi
+comment 'USB Device Class drivers'
+dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
+dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
+ dep_mbool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE
+ dep_mbool ' Datafab MDCFE-B Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+ dep_mbool ' Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM $CONFIG_USB_STORAGE
+ dep_mbool ' ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE
+ dep_mbool ' Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE
+ dep_mbool ' HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+ dep_mbool ' SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+ dep_mbool ' Lexar Jumpshot Compact Flash Reader' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
+dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
+
+comment 'USB Human Interface Devices (HID)'
+if [ "$CONFIG_INPUT" = "n" ]; then
+ comment ' Input core support is needed for USB HID'
+else
+ dep_tristate ' USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
+ dep_mbool ' /dev/hiddev raw HID device support (EXPERIMENTAL)' CONFIG_USB_HIDDEV $CONFIG_USB_HID
+ if [ "$CONFIG_USB_HID" != "y" ]; then
+ dep_tristate ' USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
+ dep_tristate ' USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
X fi
- dep_tristate ' USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
- dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
-
- comment 'USB Human Interface Devices (HID)'
- if [ "$CONFIG_INPUT" = "n" ]; then
- comment ' Input core support is needed for USB HID'
- else
- dep_tristate ' USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
- if [ "$CONFIG_USB_HID" != "y" ]; then
- dep_tristate ' USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
- dep_tristate ' USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
- fi
- dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
- fi
-
- comment 'USB Imaging devices'
- dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
- dep_tristate ' USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
- dep_tristate ' USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
- dep_tristate ' Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
- dep_tristate ' HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+ dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
+fi
X
- comment 'USB Multimedia devices'
+comment 'USB Imaging devices'
+dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
+dep_tristate ' USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate ' USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+dep_tristate ' Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
+dep_tristate ' HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+
+comment 'USB Multimedia devices'
+if [ "$CONFIG_VIDEO_DEV" = "n" ]; then
+ comment ' Video4Linux support is needed for USB Multimedia device support'
+else
X dep_tristate ' USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
X dep_tristate ' USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
X dep_tristate ' USB Philips Cameras' CONFIG_USB_PWC $CONFIG_USB $CONFIG_VIDEO_DEV
X dep_tristate ' USB SE401 Camera support' CONFIG_USB_SE401 $CONFIG_USB $CONFIG_VIDEO_DEV
X dep_tristate ' D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
X dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
+fi
X
- comment 'USB Network adaptors'
+comment 'USB Network adaptors'
+if [ "$CONFIG_NET" = "n" ]; then
+ comment ' Networking support is needed for USB Networking device support'
+else
X dep_tristate ' USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
- dep_tristate ' USB CATC NetMate-based Ethernet driver (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
- dep_tristate ' USB CDC Ethernet class (USB cable modem) support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
X dep_tristate ' USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
- dep_tristate ' USB-to-USB Networking (NetChip, Prolific, ...) (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+ dep_tristate ' USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+ dep_tristate ' USB Communication Class Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+ dep_tristate ' USB-to-USB Networking cable device support (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+fi
X
- comment 'USB port drivers'
- dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
- source drivers/usb/serial/Config.in
+comment 'USB port drivers'
+dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+source drivers/usb/serial/Config.in
X
- comment 'USB misc drivers'
- dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
-fi
+comment 'USB Miscellaneous drivers'
+dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
X
X endmenu
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/devices.c linux/drivers/usb/devices.c
--- v2.4.12/linux/drivers/usb/devices.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/devices.c Sat Oct 20 19:13:11 2001
@@ -488,7 +488,7 @@
X return -EFAULT;
X
X /* enumerate busses */


- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);

X for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {
X /* print devices for this bus */
X bus = list_entry(buslist, struct usb_bus, bus_list);
@@ -498,7 +498,7 @@
X return ret;
X total_written += ret;


X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);

X return total_written;
X }
X
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/hiddev.c linux/drivers/usb/hiddev.c
--- v2.4.12/linux/drivers/usb/hiddev.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/hiddev.c Sat Oct 20 19:13:11 2001
@@ -264,7 +264,7 @@
X if (list->head == list->tail) {
X
X add_wait_queue(&list->hiddev->wait, &wait);


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X

X while (list->head == list->tail) {
X
@@ -284,7 +284,7 @@
X schedule();
X }
X

- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X remove_wait_queue(&list->hiddev->wait, &wait);
X }
X
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/inode.c linux/drivers/usb/inode.c
--- v2.4.12/linux/drivers/usb/inode.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/inode.c Sat Oct 20 19:13:11 2001
@@ -260,15 +260,15 @@
X struct list_head *list;
X struct usb_bus *bus;


X
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);

X for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
X bus = list_entry(list, struct usb_bus, bus_list);
X if (bus->busnum == busnr) {


- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);

X return bus;
X }


X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);

X return NULL;
X }
X

@@ -416,7 +416,7 @@
X if (i < 2+NRSPECIAL)
X return 0;
X i -= 2+NRSPECIAL;


- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);

X for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
X if (i > 0) {
X i--;
@@ -428,7 +428,7 @@
X break;
X filp->f_pos++;


X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);

X return 0;
X }
X }

@@ -639,13 +639,13 @@
X list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
X list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);


X }
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);

X for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
X bus = list_entry(blist, struct usb_bus, bus_list);
X new_bus_inode(bus, s);
X recurse_new_dev_inode(bus->root_hub, s);


X }
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);

X return s;
X
X out_no_root:
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- v2.4.12/linux/drivers/usb/kaweth.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/kaweth.c Sat Oct 20 19:13:11 2001
@@ -969,14 +969,14 @@
X init_waitqueue_head(&awd.wqh);
X awd.done = 0;
X

- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);

X add_wait_queue(&awd.wqh, &wait);
X urb->context = &awd;
X status = usb_submit_urb(urb);
X if (status) {
X // something went wrong
X usb_free_urb(urb);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X remove_wait_queue(&awd.wqh, &wait);
X return status;
X }
@@ -984,7 +984,7 @@
X while (timeout && !awd.done)
X timeout = schedule_timeout(timeout);
X

- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X remove_wait_queue(&awd.wqh, &wait);
X
X if (!timeout) {
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- v2.4.12/linux/drivers/usb/pegasus.h Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/pegasus.h Wed Oct 17 14:34:06 2001
@@ -131,6 +131,8 @@
X #define VENDOR_ABOCOM 0x07b8
X #define VENDOR_ACCTON 0x083a
X #define VENDOR_ADMTEK 0x07a6
+#define VENDOR_ALLIEDTEL 0x07c9
+#define VENDOR_BELKIN 0x050d
X #define VENDOR_BILLIONTON 0x08dd
X #define VENDOR_COREGA 0x07aa
X #define VENDOR_DLINK 0x2001
@@ -142,7 +144,7 @@
X #define VENDOR_SMARTBRIDGES 0x08d1
X #define VENDOR_SMC 0x0707
X #define VENDOR_SOHOWARE 0x15e8
-#define VENDOR_BELKIN 0x050d
+
X
X #else /* PEGASUS_DEV */
X
@@ -176,6 +178,10 @@
X PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
X VENDOR_ADMTEK, 0x0986,
X DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
X PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
X DEFAULT_GPIO_RESET )
X PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
@@ -236,8 +242,6 @@
X DEFAULT_GPIO_RESET )
X PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
X DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Belkin F5D5050 USB Ethernet",
- VENDOR_BELKIN, 0x0121,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+
X
X #endif /* PEGASUS_DEV */
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/pwc-ctrl.c linux/drivers/usb/pwc-ctrl.c
--- v2.4.12/linux/drivers/usb/pwc-ctrl.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/pwc-ctrl.c Wed Oct 17 14:34:06 2001
@@ -495,7 +495,7 @@
X }
X
X
-#ifdef __KERNEL__
+
X /* BRIGHTNESS */
X
X int pwc_get_brightness(struct pwc_device *pdev)
@@ -983,6 +983,7 @@
X
X return (buf << 8);
X }
+
X static inline int pwc_read_blue_gain(struct pwc_device *pdev)
X {
X unsigned char buf;
@@ -1001,43 +1002,55 @@
X return (buf << 8);
X }
X
-/* still unused (it doesn't work yet...) */
-static inline int pwc_set_led(struct pwc_device *pdev, int value)
+int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
X {
- unsigned char buf;


+ unsigned char buf[2];

X
- if (value < 0)
- value = 0;
- if (value > 0xffff)
- value = 0xffff;
+ if (pdev->type < 730)
+ return 0;
+ if (on_value < 0)
+ on_value = 0;
+ if (on_value > 0xff)
+ on_value = 0xff;
+ if (off_value < 0)
+ off_value = 0;
+ if (off_value > 0xff)
+ off_value = 0xff;
X
- buf = (value >> 8);
+ buf[0] = on_value;
+ buf[1] = off_value;
X
X return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
X SET_STATUS_CTL,
X USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
X LED_FORMATTER,
X pdev->vcinterface,
- &buf, 1, HZ / 2);
+ &buf, 2, HZ / 2);
X }
X
-/* still unused (it doesn't work yet...) */
-static inline int pwc_get_led(struct pwc_device *pdev)
+int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
X {
- unsigned char buf;


+ unsigned char buf[2];

X int ret;
X
+ if (pdev->type < 730) {
+ *on_value = -1;
+ *off_value = -1;


+ return 0;
+ }
+

X ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
X GET_STATUS_CTL,
X USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
X LED_FORMATTER,
X pdev->vcinterface,
- &buf, 1, HZ / 2);
+ &buf, 2, HZ / 2);
X
X if (ret < 0)
- return ret;
-
- return (buf << 8);
+ return ret;
+ *on_value = buf[0];
+ *off_value = buf[1];


+ return 0;
X }
X

X /* End of Add-Ons */
@@ -1167,15 +1180,15 @@
X
X case VIDIOCPWCSLED:
X {
- int led, ret;
- if (copy_from_user(&led,arg,sizeof(led)))
- return -EFAULT;
- else {
- /* ret = pwc_set_led(pdev, led); */
- ret = 0;
+ int ret;
+ struct pwc_leds leds;
+
+ if (copy_from_user(&leds, arg, sizeof(leds)))
+ return -EFAULT;
+
+ ret = pwc_set_leds(pdev, leds.led_on, leds.led_off);
X if (ret<0)
X return ret;
- }
X break;
X }
X
@@ -1184,11 +1197,12 @@
X case VIDIOCPWCGLED:
X {
X int led;
+ struct pwc_leds leds;
X
- led = pwc_get_led(pdev);
+ led = pwc_get_leds(pdev, &leds.led_on, &leds.led_off);
X if (led < 0)
X return -EINVAL;
- if (copy_to_user(arg, &led, sizeof(led)))
+ if (copy_to_user(arg, &leds, sizeof(leds)))


X return -EFAULT;
X break;
X }

@@ -1202,9 +1216,6 @@


X }
X return 0;
X }
-

-#endif
-
X
X
X
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c
--- v2.4.12/linux/drivers/usb/pwc-if.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/pwc-if.c Wed Oct 17 14:34:06 2001
@@ -73,7 +73,9 @@
X { USB_DEVICE(0x0471, 0x0311) },
X { USB_DEVICE(0x0471, 0x0312) },
X { USB_DEVICE(0x069A, 0x0001) },
- { USB_DEVICE(0x046D, 0x0b80) },
+ { USB_DEVICE(0x046D, 0x08b0) },
+ { USB_DEVICE(0x055D, 0x9000) },
+ { USB_DEVICE(0x055D, 0x9001) },
X { }
X };
X MODULE_DEVICE_TABLE(usb, pwc_device_table);
@@ -96,6 +98,7 @@
X static int default_mbufs = 2; /* Default number of mmap() buffers */
X int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
X static int power_save = 0;
+static int led_on = 1, led_off = 0; /* defaults to LED that is on while in use */
X int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
X
X static struct semaphore mem_lock;
@@ -592,7 +595,8 @@
X pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
X }
X
-/* XXX: 2001-06-17: The YUV420 palette will be phased out soon */
+/* 2001-10-14: The YUV420 is still there, but you can only set it from within
+ a program (YUV420P being the default) */
X static int pwc_set_palette(struct pwc_device *pdev, int pal)
X {
X if ( pal == VIDEO_PALETTE_YUV420
@@ -947,14 +951,16 @@
X Info("Failed to set alternate interface to 0.\n");
X pdev->usb_init = 1;
X }
- else {
- /* Turn on camera */
- if (power_save) {
- i = pwc_camera_power(pdev, 1);
- if (i < 0)
- Info("Failed to restore power to the camera! (%d)\n", i);
- }
+
+ /* Turn on camera */
+ if (power_save) {
+ i = pwc_camera_power(pdev, 1);
+ if (i < 0)
+ Info("Failed to restore power to the camera! (%d)\n", i);
X }
+ /* Set LED on/off time */
+ if (pwc_set_leds(pdev, led_on, led_off) < 0)
+ Info("Failed to set LED on/off time.\n");
X
X /* Find our decompressor, if any */
X pdev->decompressor = pwc_find_decompressor(pdev->type);
@@ -1007,6 +1013,7 @@
X up(&pdev->modlock);
X return i;
X }
+
X i = usb_set_interface(pdev->udev, 0, pdev->valternate);
X if (i) {
X Trace(TRACE_OPEN, "Failed to set alternate interface = %d.\n", i);
@@ -1066,7 +1073,10 @@
X Trace(TRACE_OPEN, "Normal close(): setting interface to 0.\n");
X usb_set_interface(pdev->udev, 0, 0);
X
- /* Turn off LED by powering down camera */
+ /* Turn LEDs off */
+ if (pwc_set_leds(pdev, 0, 0) < 0)
+ Info("Failed to set LED on/off time..\n");
+ /* Power down camere to save energy */
X if (power_save) {
X i = pwc_camera_power(pdev, 0);
X if (i < 0)
@@ -1121,19 +1131,19 @@
X while (pdev->full_frames == NULL) {
X if (noblock) {


X remove_wait_queue(&pdev->frameq, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);

X return -EWOULDBLOCK;
X }


X if (signal_pending(current)) {
X remove_wait_queue(&pdev->frameq, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X return -ERESTARTSYS;
X }
X schedule();

- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X }

X remove_wait_queue(&pdev->frameq, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X

X /* Decompress [, convert] and release frame */
X if (pwc_handle_frame(pdev))
@@ -1473,14 +1483,14 @@
X while (pdev->full_frames == NULL) {


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 38'
echo 'File patch-2.4.13 is continued in part 39'
echo "39" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:10 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part40

#!/bin/sh -x
# this is part 40 of a 53 - part archive


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

if test "$Scheck" != 40; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X check_connect: net1080_check_connect,
X
@@ -729,9 +735,9 @@
X {
X struct usbnet *dev = (struct usbnet *) net->priv;
X
- if (new_mtu <= sizeof (struct ethhdr) || new_mtu > MAX_PACKET)
+ if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
X return -EINVAL;
- if (((dev->driver_info->flags) & FLAG_FRAMING)) {
+ if (((dev->driver_info->flags) & FLAG_FRAMING_NC)) {
X if (FRAMED_SIZE (new_mtu) > MAX_PACKET)
X return -EINVAL;
X // no second zero-length packet read wanted after mtu-sized packets
@@ -779,9 +785,11 @@
X unsigned long lockflags;
X size_t size;
X
- size = (dev->driver_info->flags & FLAG_FRAMING)
- ? FRAMED_SIZE (dev->net.mtu)
- : (sizeof (struct ethhdr) + dev->net.mtu);
+ if (dev->driver_info->flags & FLAG_FRAMING_NC)
+ size = FRAMED_SIZE (dev->net.mtu);
+ else
+ size = (sizeof (struct ethhdr) + dev->net.mtu);
+
X if ((skb = alloc_skb (size, flags)) == 0) {
X dbg ("no rx skb");
X tasklet_schedule (&dev->bh);
@@ -798,9 +806,15 @@
X FILL_BULK_URB (urb, dev->udev,
X usb_rcvbulkpipe (dev->udev, dev->driver_info->in),
X skb->data, size, rx_complete, skb);
+ urb->transfer_flags |= USB_ASYNC_UNLINK;
X #ifdef REALLY_QUEUE
X urb->transfer_flags |= USB_QUEUE_BULK;
X #endif
+#if 0
+ // Idle-but-posted reads with UHCI really chew up
+ // PCI bandwidth unless FSBR is disabled
+ urb->transfer_flags |= USB_NO_FSBR;
+#endif
X
X spin_lock_irqsave (&dev->rxq.lock, lockflags);
X
@@ -827,7 +841,7 @@
X
X static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
X {
- if (dev->driver_info->flags & FLAG_FRAMING) {
+ if (dev->driver_info->flags & FLAG_FRAMING_NC) {
X struct nc_header *header;
X struct nc_trailer *trailer;
X
@@ -1042,7 +1056,7 @@
X while (skb_queue_len (&dev->rxq)
X && skb_queue_len (&dev->txq)
X && skb_queue_len (&dev->done)) {


- current->state = TASK_UNINTERRUPTIBLE;
+ set_current_state(TASK_UNINTERRUPTIBLE);

X schedule_timeout (UNLINK_TIMEOUT_JIFFIES);
X dbg ("waited for %d urb completions", temp);


X }
@@ -1083,9 +1097,11 @@
X }

X
X netif_start_queue (net);
- devdbg (dev, "open: enable queueing (rx %d, tx %d) mtu %d %sframed",
+ devdbg (dev, "open: enable queueing (rx %d, tx %d) mtu %d %s framing",
X RX_QLEN, TX_QLEN, dev->net.mtu,
- (info->flags & FLAG_FRAMING) ? "" : "un"
+ (info->flags & FLAG_FRAMING_NC)
+ ? "NetChip"
+ : "raw"
X );
X
X // delay posting reads until we're fully open
@@ -1194,7 +1210,7 @@
X
X flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
X
- if (info->flags & FLAG_FRAMING) {
+ if (info->flags & FLAG_FRAMING_NC) {
X struct sk_buff *skb2;
X skb2 = fixup_skb (skb, flags);
X if (!skb2) {
@@ -1215,7 +1231,7 @@
X entry->state = tx_start;
X entry->length = length;
X
- if (info->flags & FLAG_FRAMING) {
+ if (info->flags & FLAG_FRAMING_NC) {
X header = (struct nc_header *) skb_push (skb, sizeof *header);
X header->hdr_len = cpu_to_le16 (sizeof (*header));
X header->packet_len = cpu_to_le16 (length);
@@ -1223,31 +1239,31 @@
X *skb_put (skb, 1) = PAD_BYTE;
X trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
X } else if ((length % EP_SIZE (dev)) == 0) {
- if (skb_shared (skb)) {
- struct sk_buff *skb2;
- skb2 = skb_unshare (skb, flags);
- if (!skb2) {
- dbg ("can't unshare skb");
- goto drop;
- }
- skb = skb2;
+ // not all hardware behaves with USB_ZERO_PACKET,
+ // so we add an extra one-byte packet
+ if (skb_shared (skb)) {
+ struct sk_buff *skb2;
+ skb2 = skb_unshare (skb, flags);
+ if (!skb2) {
+ dbg ("can't unshare skb");
+ goto drop;
X }
- skb->len++;
+ skb = skb2;
X }
+ skb->len++;
+ }
X
X FILL_BULK_URB (urb, dev->udev,
X usb_sndbulkpipe (dev->udev, info->out),
X skb->data, skb->len, tx_complete, skb);
- // Idle-but-posted reads with UHCI really chew up
- // PCI bandwidth unless FSBR is disabled
- urb->transfer_flags |= USB_ASYNC_UNLINK | USB_NO_FSBR;
+ urb->transfer_flags |= USB_ASYNC_UNLINK;
X #ifdef REALLY_QUEUE
X urb->transfer_flags |= USB_QUEUE_BULK;
X #endif
X // FIXME urb->timeout = ... jiffies ... ;
X
X spin_lock_irqsave (&dev->txq.lock, flags);
- if (info->flags & FLAG_FRAMING) {
+ if (info->flags & FLAG_FRAMING_NC) {
X header->packet_id = cpu_to_le16 (dev->packet_id++);
X put_unaligned (header->packet_id, &trailer->packet_id);
X #if 0
@@ -1408,9 +1424,12 @@


X return 0;
X }
X

- if (usb_set_interface (udev, ifnum, altnum) < 0) {
- err ("set_interface failed");
- return 0;
+ // more sanity (unless the device is broken)
+ if (!(info->flags & FLAG_NO_SETINT)) {
+ if (usb_set_interface (udev, ifnum, altnum) < 0) {
+ err ("set_interface failed");


+ return 0;
+ }
X }

X
X // set up our own records
@@ -1484,6 +1503,18 @@
X },
X #endif
X
+#ifdef CONFIG_USB_BELKIN
+{
+ USB_DEVICE (0x050d, 0x0004), // Belkin
+ driver_info: (unsigned long) &belkin_info,
+}, {
+ USB_DEVICE (0x056c, 0x8100), // eTEK
+ driver_info: (unsigned long) &belkin_info,
+}, {
+ USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
+ driver_info: (unsigned long) &belkin_info,
+},
+#endif
X
X // GeneSys GL620USB (www.genesyslogic.com.tw)
X // (patch exists against an older driver version)
@@ -1508,16 +1539,6 @@
X },
X #endif
X
-#ifdef CONFIG_USB_BELKIN_F5U104
-{
- USB_DEVICE (0x050d, 0x0004), // Belkin
- driver_info: (unsigned long) &belkin_info,
-}, {
- USB_DEVICE (0x056c, 0x8100), // eTEK
- driver_info: (unsigned long) &belkin_info,
-},
-#endif
-
X #ifdef CONFIG_USB_PL2301
X {
X USB_DEVICE (0x067b, 0x0000), // PL-2301
@@ -1563,6 +1584,7 @@
X }
X module_exit (usbnet_exit);
X
+EXPORT_NO_SYMBOLS;
X MODULE_AUTHOR ("David Brownell <dbro...@users.sourceforge.net>");
-MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (Belkin, Linux, NetChip, Prolific, ...)");
-MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (numerous vendors)");
+MODULE_LICENSE ("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c
--- v2.4.12/linux/drivers/usb/uss720.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/uss720.c Sat Oct 20 19:13:11 2001
@@ -159,7 +159,7 @@
X if (time_after_eq (jiffies, expire))
X /* The FIFO is stuck. */
X return -EBUSY;


- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);

X schedule_timeout((HZ + 99) / 100);
X if (signal_pending (current))
X break;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.4.12/linux/drivers/video/Config.in Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/Config.in Mon Oct 15 13:43:24 2001
@@ -135,9 +135,6 @@
X if [ "$CONFIG_FB_ATY" != "n" ]; then
X bool ' Mach64 GX support (EXPERIMENTAL)' CONFIG_FB_ATY_GX
X bool ' Mach64 CT/VT/GT/LT (incl. 3D RAGE) support' CONFIG_FB_ATY_CT
- if [ "$CONFIG_FB_ATY_CT" = "y" ]; then
- bool ' Sony Vaio C1VE 1024x480 LCD support' CONFIG_FB_ATY_CT_VAIO_LCD
- fi
X fi
X tristate ' ATI Radeon display support (EXPERIMENTAL)' CONFIG_FB_RADEON
X tristate ' ATI Rage128 display support (EXPERIMENTAL)' CONFIG_FB_ATY128
@@ -198,13 +195,6 @@
X fi
X if [ "$CONFIG_NINO" = "y" ]; then
X bool ' TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912
- fi
- if [ "$CONFIG_DECSTATION" = "y" ]; then
- if [ "$CONFIG_TC" = "y" ]; then
- bool ' PMAG-BA TURBOchannel framebuffer support' CONFIG_FB_PMAG_BA
- bool ' PMAGB-B TURBOchannel framebuffer spport' CONFIG_FB_PMAGB_B
- bool ' Maxine (Personal DECstation) onboard framebuffer spport' CONFIG_FB_MAXINE
- fi
X fi
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL
diff -u --recursive --new-file v2.4.12/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- v2.4.12/linux/drivers/video/acornfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/acornfb.c Sun Oct 21 10:13:07 2001
@@ -1528,7 +1528,7 @@
X
X acornfb_init_fbinfo();
X
- for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) {
+ while (opt = strsep(&options, ",")) {
X if (!*opt)
X continue;
X
@@ -1772,4 +1772,7 @@
X return 0;
X }
X
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("VIDC 1/1a/20 framebuffer driver");
X MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/amifb.c linux/drivers/video/amifb.c
--- v2.4.12/linux/drivers/video/amifb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/amifb.c Sun Oct 21 10:14:38 2001
@@ -1192,7 +1192,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strcmp(this_opt, "inverse")) {
X amifb_inverse = 1;
X fb_invert_cmaps();
diff -u --recursive --new-file v2.4.12/linux/drivers/video/aty/atyfb_base.c linux/drivers/video/aty/atyfb_base.c
--- v2.4.12/linux/drivers/video/aty/atyfb_base.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/aty/atyfb_base.c Sun Oct 21 10:14:38 2001
@@ -2521,8 +2521,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/aty128fb.c linux/drivers/video/aty128fb.c
--- v2.4.12/linux/drivers/video/aty128fb.c Tue Jul 3 17:08:21 2001
+++ linux/drivers/video/aty128fb.c Sun Oct 21 10:14:38 2001
@@ -1613,8 +1613,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cgsixfb.c linux/drivers/video/cgsixfb.c
--- v2.4.12/linux/drivers/video/cgsixfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/cgsixfb.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.25 2001/09/19 00:04:33 davem Exp $
+/* $Id: cgsixfb.c,v 1.26 2001/10/16 05:44:44 davem Exp $
X * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
X *
X * Copyright (C) 1996,1998 Jakub Jelinek (j...@ultra.linux.cz)
@@ -364,13 +364,15 @@
X unsigned long flags;
X int i, x, y;
X u8 *fd1, *fd2, *fd3, *fd4;
+ u16 c;
X
X spin_lock_irqsave(&fb->lock, flags);
X do {
X i = sbus_readl(&fbc->s);
X } while (i & 0x10000000);
- sbus_writel(attr_fgcol(p, scr_readw(s)), &fbc->fg);
- sbus_writel(attr_bgcol(p, scr_readw(s)), &fbc->bg);
+ c = scr_readw(s);
+ sbus_writel(attr_fgcol(p, c), &fbc->fg);
+ sbus_writel(attr_bgcol(p, c), &fbc->bg);
X sbus_writel(0x140000, &fbc->mode);
X sbus_writel(0xe880fc30, &fbc->alu);
X sbus_writel(~0, &fbc->pixelm);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/controlfb.c linux/drivers/video/controlfb.c
--- v2.4.12/linux/drivers/video/controlfb.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/video/controlfb.c Sun Oct 21 10:14:38 2001
@@ -1423,8 +1423,7 @@
X if (!options || !*options)
X return;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
--- v2.4.12/linux/drivers/video/creatorfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/creatorfb.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.36 2001/09/19 00:04:33 davem Exp $
+/* $Id: creatorfb.c,v 1.37 2001/10/16 05:44:44 davem Exp $
X * creatorfb.c: Creator/Creator3D frame buffer driver
X *
X * Copyright (C) 1997,1998,1999 Jakub Jelinek (j...@ultra.linux.cz)
@@ -475,11 +475,13 @@
X unsigned long flags;
X int i, xy;
X u8 *fd1, *fd2, *fd3, *fd4;
+ u16 c;
X u64 fgbg;
X
X spin_lock_irqsave(&fb->lock, flags);
- fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,scr_readw(s))])) << 32) |
- ((u32 *)p->dispsw_data)[attr_bgcol(p,scr_readw(s))];
+ c = scr_readw(s);
+ fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p, c)])) << 32) |
+ ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
X if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
X FFBFifo(fb, 2);
X upa_writeq(fgbg, &fbc->fg);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.4.12/linux/drivers/video/cyber2000fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/cyber2000fb.c Thu Oct 11 09:43:30 2001
@@ -3,6 +3,9 @@
X *
X * Copyright (C) 1998-2000 Russell King
X *
+ * MIPS and 50xx clock support
+ * Copyright (C) 2001 Bradley D. LaRonde <br...@ltc.com>
+ *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License version 2 as
X * published by the Free Software Foundation.
@@ -53,14 +56,14 @@
X */
X /*#define CFB16_IS_CFB15*/
X
-static char *CyberRegs;
-
X #include "cyber2000fb.h"
X
X struct cfb_info {
X struct fb_info fb;
X struct display_switch *dispsw;
X struct pci_dev *dev;
+ unsigned char *region;
+ unsigned char *regs;
X signed int currcon;
X int func_use_count;
X u_long ref_ps;
@@ -80,19 +83,67 @@
X u_char mclk_div;
X };
X
+static char default_font_storage[40];
+static char *default_font = "Acorn8x8";
+MODULE_PARM(default_font, "s");
+MODULE_PARM_DESC(default_font, "Default font name");
+
+/*
+ * Our access methods.
+ */
+#define cyber2000fb_writel(val,reg,cfb) writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val,reg,cfb) writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val,reg,cfb) writeb(val, (cfb)->regs + (reg))
+
+#define cyber2000fb_readb(reg,cfb) readb((cfb)->regs + (reg))
+
+static inline void
+cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+ cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);


+}
+
+static inline void

+cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+ cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
+}
+
+static inline unsigned int
+cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
+{
+ cyber2000fb_writeb(reg, 0x3ce, cfb);
+ return cyber2000fb_readb(0x3cf, cfb);


+}
+
+static inline void

+cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+ cyber2000fb_readb(0x3da, cfb);
+ cyber2000fb_writeb(reg, 0x3c0, cfb);
+ cyber2000fb_readb(0x3c1, cfb);
+ cyber2000fb_writeb(val, 0x3c0, cfb);


+}
+
+static inline void

+cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
+{
+ cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
+}
+
X /* -------------------- Hardware specific routines ------------------------- */
X
X /*
X * Hardware Cyber2000 Acceleration
X */
-static void cyber2000_accel_wait(void)
+static void cyber2000_accel_wait(struct cfb_info *cfb)
X {
X int count = 100000;
X
- while (cyber2000_inb(CO_REG_CONTROL) & 0x80) {
+ while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & 0x80) {
X if (!count--) {
X debug_printf("accel_wait timed out\n");
- cyber2000_outb(0, CO_REG_CONTROL);
+ cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
X return;
X }
X udelay(1);
@@ -110,6 +161,7 @@
X cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
X int height, int width)
X {
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
X struct fb_var_screeninfo *var = &p->fb_info->var;
X u_long src, dst;
X u_int fh, fw;
@@ -142,29 +194,30 @@
X src = sx + sy * var->xres_virtual;
X dst = dx + dy * var->xres_virtual;
X
- cyber2000_accel_wait();
- cyber2000_outb(0x00, CO_REG_CONTROL);
- cyber2000_outb(0x03, CO_REG_FORE_MIX);
- cyber2000_outw(width, CO_REG_WIDTH);
+ cyber2000_accel_wait(cfb);
+ cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
+ cyber2000fb_writeb(0x03, CO_REG_FORE_MIX, cfb);
+ cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
X
X if (var->bits_per_pixel != 24) {
- cyber2000_outl(dst, CO_REG_DEST_PTR);
- cyber2000_outl(src, CO_REG_SRC_PTR);
+ cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
+ cyber2000fb_writel(src, CO_REG_SRC_PTR, cfb);
X } else {
- cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
- cyber2000_outb(dst, CO_REG_X_PHASE);
- cyber2000_outl(src * 3, CO_REG_SRC_PTR);
+ cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+ cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
+ cyber2000fb_writel(src * 3, CO_REG_SRC_PTR, cfb);
X }
X
- cyber2000_outw(height, CO_REG_HEIGHT);
- cyber2000_outw(cmd, CO_REG_CMD_L);
- cyber2000_outw(0x2800, CO_REG_CMD_H);
+ cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
+ cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
+ cyber2000fb_writew(0x2800, CO_REG_CMD_H, cfb);


X }
X
X static void

X cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
X int height, int width)
X {
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
X struct fb_var_screeninfo *var = &p->fb_info->var;
X u_long dst;
X u_int fw, fh;
@@ -177,30 +230,30 @@
X width = width * fw - 1;
X height = height * fh - 1;
X
- cyber2000_accel_wait();
- cyber2000_outb(0x00, CO_REG_CONTROL);
- cyber2000_outb(0x03, CO_REG_FORE_MIX);
- cyber2000_outw(width, CO_REG_WIDTH);
- cyber2000_outw(height, CO_REG_HEIGHT);
+ cyber2000_accel_wait(cfb);
+ cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
+ cyber2000fb_writeb(0x03, CO_REG_FORE_MIX, cfb);
+ cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
+ cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
X
X switch (var->bits_per_pixel) {
X case 15:
X case 16:
X bgx = ((u16 *)p->dispsw_data)[bgx];
X case 8:
- cyber2000_outl(dst, CO_REG_DEST_PTR);
+ cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
X break;
X
X case 24:
- cyber2000_outl(dst * 3, CO_REG_DEST_PTR);
- cyber2000_outb(dst, CO_REG_X_PHASE);
+ cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
+ cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
X bgx = ((u32 *)p->dispsw_data)[bgx];
X break;
X }
X
- cyber2000_outl(bgx, CO_REG_FOREGROUND);
- cyber2000_outw(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L);
- cyber2000_outw(0x0800, CO_REG_CMD_H);
+ cyber2000fb_writel(bgx, CO_REG_FOREGROUND, cfb);
+ cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
+ cyber2000fb_writew(0x0800, CO_REG_CMD_H, cfb);


X }
X
X static void

@@ -209,7 +262,7 @@
X {
X struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
X
- cyber2000_accel_wait();
+ cyber2000_accel_wait(cfb);
X cfb->dispsw->putc(conp, p, c, yy, xx);
X }
X
@@ -219,7 +272,7 @@
X {
X struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
X
- cyber2000_accel_wait();
+ cyber2000_accel_wait(cfb);
X cfb->dispsw->putcs(conp, p, s, count, yy, xx);
X }
X

@@ -227,7 +280,7 @@
X {

X struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
X
- cyber2000_accel_wait();
+ cyber2000_accel_wait(cfb);
X cfb->dispsw->revc(p, xx, yy);
X }
X
@@ -274,10 +327,10 @@
X switch (cfb->fb.var.bits_per_pixel) {
X #ifdef FBCON_HAS_CFB8
X case 8:
- cyber2000_outb(regno, 0x3c8);
- cyber2000_outb(red, 0x3c9);
- cyber2000_outb(green, 0x3c9);
- cyber2000_outb(blue, 0x3c9);
+ cyber2000fb_writeb(regno, 0x3c8, cfb);
+ cyber2000fb_writeb(red, 0x3c9, cfb);
+ cyber2000fb_writeb(green, 0x3c9, cfb);
+ cyber2000fb_writeb(blue, 0x3c9, cfb);
X break;
X #endif
X
@@ -286,18 +339,18 @@
X #ifndef CFB16_IS_CFB15
X if (regno < 64) {
X /* write green */
- cyber2000_outb(regno << 2, 0x3c8);
- cyber2000_outb(cfb->palette[regno >> 1].red, 0x3c9);
- cyber2000_outb(green, 0x3c9);
- cyber2000_outb(cfb->palette[regno >> 1].blue, 0x3c9);
+ cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
+ cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+ cyber2000fb_writeb(green, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
X }
X
X if (regno < 32) {
X /* write red,blue */
- cyber2000_outb(regno << 3, 0x3c8);
- cyber2000_outb(red, 0x3c9);
- cyber2000_outb(cfb->palette[regno << 1].green, 0x3c9);
- cyber2000_outb(blue, 0x3c9);
+ cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+ cyber2000fb_writeb(red, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[regno << 1].green, 0x3c9, cfb);
+ cyber2000fb_writeb(blue, 0x3c9, cfb);
X }
X
X if (regno < 16)
@@ -308,10 +361,10 @@
X
X case 15:
X if (regno < 32) {
- cyber2000_outb(regno << 3, 0x3c8);
- cyber2000_outb(red, 0x3c9);
- cyber2000_outb(green, 0x3c9);
- cyber2000_outb(blue, 0x3c9);
+ cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
+ cyber2000fb_writeb(red, 0x3c9, cfb);
+ cyber2000fb_writeb(green, 0x3c9, cfb);
+ cyber2000fb_writeb(blue, 0x3c9, cfb);
X }
X if (regno < 16)
X ((u16 *)cfb->fb.pseudo_palette)[regno] =
@@ -322,10 +375,10 @@
X
X #ifdef FBCON_HAS_CFB24
X case 24:
- cyber2000_outb(regno, 0x3c8);
- cyber2000_outb(red, 0x3c9);
- cyber2000_outb(green, 0x3c9);
- cyber2000_outb(blue, 0x3c9);
+ cyber2000fb_writeb(regno, 0x3c8, cfb);
+ cyber2000fb_writeb(red, 0x3c9, cfb);
+ cyber2000fb_writeb(green, 0x3c9, cfb);
+ cyber2000fb_writeb(blue, 0x3c9, cfb);
X
X if (regno < 16)
X ((u32 *)cfb->fb.pseudo_palette)[regno] =
@@ -375,92 +428,92 @@
X * Blank palette
X */
X for (i = 0; i < NR_PALETTE; i++) {
- cyber2000_outb(i, 0x3c8);
- cyber2000_outb(0, 0x3c9);
- cyber2000_outb(0, 0x3c9);
- cyber2000_outb(0, 0x3c9);
- }
-
- cyber2000_outb(0xef, 0x3c2);
- cyber2000_crtcw(0x11, 0x0b);
- cyber2000_attrw(0x11, 0x00);
-
- cyber2000_seqw(0x00, 0x01);
- cyber2000_seqw(0x01, 0x01);
- cyber2000_seqw(0x02, 0x0f);
- cyber2000_seqw(0x03, 0x00);
- cyber2000_seqw(0x04, 0x0e);
- cyber2000_seqw(0x00, 0x03);
+ cyber2000fb_writeb(i, 0x3c8, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
+ }
+
+ cyber2000fb_writeb(0xef, 0x3c2, cfb);
+ cyber2000_crtcw(0x11, 0x0b, cfb);
+ cyber2000_attrw(0x11, 0x00, cfb);
+
+ cyber2000_seqw(0x00, 0x01, cfb);
+ cyber2000_seqw(0x01, 0x01, cfb);
+ cyber2000_seqw(0x02, 0x0f, cfb);
+ cyber2000_seqw(0x03, 0x00, cfb);
+ cyber2000_seqw(0x04, 0x0e, cfb);
+ cyber2000_seqw(0x00, 0x03, cfb);
X
X for (i = 0; i < sizeof(crtc_idx); i++)
- cyber2000_crtcw(crtc_idx[i], hw->crtc[i]);
+ cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
X
X for (i = 0x0a; i < 0x10; i++)
- cyber2000_crtcw(i, 0);
+ cyber2000_crtcw(i, 0, cfb);
X
- cyber2000_grphw(0x11, hw->crtc_ofl);
- cyber2000_grphw(0x00, 0x00);
- cyber2000_grphw(0x01, 0x00);
- cyber2000_grphw(0x02, 0x00);
- cyber2000_grphw(0x03, 0x00);
- cyber2000_grphw(0x04, 0x00);
- cyber2000_grphw(0x05, 0x60);
- cyber2000_grphw(0x06, 0x05);
- cyber2000_grphw(0x07, 0x0f);
- cyber2000_grphw(0x08, 0xff);
+ cyber2000_grphw(0x11, hw->crtc_ofl, cfb);
+ cyber2000_grphw(0x00, 0x00, cfb);
+ cyber2000_grphw(0x01, 0x00, cfb);
+ cyber2000_grphw(0x02, 0x00, cfb);
+ cyber2000_grphw(0x03, 0x00, cfb);
+ cyber2000_grphw(0x04, 0x00, cfb);
+ cyber2000_grphw(0x05, 0x60, cfb);
+ cyber2000_grphw(0x06, 0x05, cfb);
+ cyber2000_grphw(0x07, 0x0f, cfb);
+ cyber2000_grphw(0x08, 0xff, cfb);
X
X /* Attribute controller registers */
X for (i = 0; i < 16; i++)
- cyber2000_attrw(i, i);
+ cyber2000_attrw(i, i, cfb);
X
- cyber2000_attrw(0x10, 0x01);
- cyber2000_attrw(0x11, 0x00);
- cyber2000_attrw(0x12, 0x0f);
- cyber2000_attrw(0x13, 0x00);
- cyber2000_attrw(0x14, 0x00);
+ cyber2000_attrw(0x10, 0x01, cfb);
+ cyber2000_attrw(0x11, 0x00, cfb);
+ cyber2000_attrw(0x12, 0x0f, cfb);
+ cyber2000_attrw(0x13, 0x00, cfb);
+ cyber2000_attrw(0x14, 0x00, cfb);
X
X /* woody: set the interlaced bit... */
X /* FIXME: what about doublescan? */
- cyber2000_outb(0x11, 0x3ce);
- i = cyber2000_inb(0x3cf);
+ cyber2000fb_writeb(0x11, 0x3ce, cfb);
+ i = cyber2000fb_readb(0x3cf, cfb);
X if (hw->vmode == FB_VMODE_INTERLACED)
X i |= 0x20;
X else
X i &= ~0x20;
- cyber2000_outb(i, 0x3cf);
+ cyber2000fb_writeb(i, 0x3cf, cfb);
X
X /* PLL registers */
- cyber2000_grphw(DCLK_MULT, hw->clock_mult);
- cyber2000_grphw(DCLK_DIV, hw->clock_div);
- cyber2000_grphw(MCLK_MULT, cfb->mclk_mult);
- cyber2000_grphw(MCLK_DIV, cfb->mclk_div);
- cyber2000_grphw(0x90, 0x01);
- cyber2000_grphw(0xb9, 0x80);
- cyber2000_grphw(0xb9, 0x00);
-
- cyber2000_outb(0x56, 0x3ce);
- i = cyber2000_inb(0x3cf);
- cyber2000_outb(i | 4, 0x3cf);
- cyber2000_outb(hw->palette_ctrl, 0x3c6);
- cyber2000_outb(i, 0x3cf);
+ cyber2000_grphw(DCLK_MULT, hw->clock_mult, cfb);
+ cyber2000_grphw(DCLK_DIV, hw->clock_div, cfb);
+ cyber2000_grphw(MCLK_MULT, cfb->mclk_mult, cfb);
+ cyber2000_grphw(MCLK_DIV, cfb->mclk_div, cfb);
+ cyber2000_grphw(0x90, 0x01, cfb);
+ cyber2000_grphw(0xb9, 0x80, cfb);
+ cyber2000_grphw(0xb9, 0x00, cfb);
+
+ cyber2000fb_writeb(0x56, 0x3ce, cfb);
+ i = cyber2000fb_readb(0x3cf, cfb);
+ cyber2000fb_writeb(i | 4, 0x3cf, cfb);
+ cyber2000fb_writeb(hw->palette_ctrl, 0x3c6, cfb);
+ cyber2000fb_writeb(i, 0x3cf, cfb);
X
- cyber2000_outb(0x20, 0x3c0);
- cyber2000_outb(0xff, 0x3c6);
+ cyber2000fb_writeb(0x20, 0x3c0, cfb);
+ cyber2000fb_writeb(0xff, 0x3c6, cfb);
X
- cyber2000_grphw(0x14, hw->fetch);
+ cyber2000_grphw(0x14, hw->fetch, cfb);
X cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
- ((hw->pitch >> 4) & 0x30));
- cyber2000_grphw(0x77, hw->visualid);
+ ((hw->pitch >> 4) & 0x30), cfb);
+ cyber2000_grphw(0x77, hw->visualid, cfb);
X
X /* make sure we stay in linear mode */
- cyber2000_grphw(0x33, 0x0d);
+ cyber2000_grphw(0x33, 0x0d, cfb);
X
X /*
X * Set up accelerator registers
X */
- cyber2000_outw(hw->width, CO_REG_SRC_WIDTH);
- cyber2000_outw(hw->width, CO_REG_DEST_WIDTH);
- cyber2000_outb(hw->pixformat, CO_REG_PIX_FORMAT);
+ cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
+ cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
+ cyber2000fb_writeb(hw->pixformat, CO_REG_PIX_FORMAT, cfb);
X }
X
X static inline int
@@ -475,9 +528,9 @@
X if (base >= 1 << 20)
X return -EINVAL;
X
- cyber2000_grphw(0x10, base >> 16 | 0x10);
- cyber2000_crtcw(0x0c, base >> 8);
- cyber2000_crtcw(0x0d, base);
+ cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
+ cyber2000_crtcw(0x0c, base >> 8, cfb);
+ cyber2000_crtcw(0x0d, base, cfb);


X
X return 0;
X }

@@ -623,6 +676,7 @@
X const u_long ref_ps = cfb->ref_ps;
X u_int div2, t_div1, best_div1, best_mult;
X int best_diff;
+ int vco;
X
X /*
X * Step 1:
@@ -697,6 +751,11 @@
X hw->clock_mult = best_mult - 1;
X hw->clock_div = div2 << 6 | (best_div1 - 1);
X
+ vco = ref_ps * best_div1 / best_mult;
+ if ((ref_ps == 40690) && (vco < 5556))
+ /* Set VFSEL when VCO > 180MHz (5.556 ps). */
+ hw->clock_div |= DCLK_DIV_VFSEL;
+


X return 0;
X }
X

@@ -1057,30 +1116,30 @@
X
X switch (blank) {
X case 4: /* powerdown - both sync lines down */
- cyber2000_grphw(0x16, 0x05);
+ cyber2000_grphw(0x16, 0x05, cfb);
X break;
X case 3: /* hsync off */
- cyber2000_grphw(0x16, 0x01);
+ cyber2000_grphw(0x16, 0x01, cfb);
X break;
X case 2: /* vsync off */
- cyber2000_grphw(0x16, 0x04);
+ cyber2000_grphw(0x16, 0x04, cfb);
X break;
X case 1: /* soft blank */
- cyber2000_grphw(0x16, 0x00);
+ cyber2000_grphw(0x16, 0x00, cfb);
X for (i = 0; i < NR_PALETTE; i++) {
- cyber2000_outb(i, 0x3c8);
- cyber2000_outb(0, 0x3c9);
- cyber2000_outb(0, 0x3c9);
- cyber2000_outb(0, 0x3c9);
+ cyber2000fb_writeb(i, 0x3c8, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
+ cyber2000fb_writeb(0, 0x3c9, cfb);
X }
X break;
X default: /* unblank */
- cyber2000_grphw(0x16, 0x00);
+ cyber2000_grphw(0x16, 0x00, cfb);
X for (i = 0; i < NR_PALETTE; i++) {
- cyber2000_outb(i, 0x3c8);
- cyber2000_outb(cfb->palette[i].red, 0x3c9);
- cyber2000_outb(cfb->palette[i].green, 0x3c9);
- cyber2000_outb(cfb->palette[i].blue, 0x3c9);
+ cyber2000fb_writeb(i, 0x3c8, cfb);
+ cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
X }
X break;
X }
@@ -1136,8 +1195,8 @@
X if (cfb->func_use_count == 1) {
X int old;
X
- old = cyber2000_grphr(FUNC_CTL);
- cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL);
+ old = cyber2000_grphr(FUNC_CTL, cfb);
+ cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL, cfb);
X }
X }
X
@@ -1149,8 +1208,8 @@
X if (cfb->func_use_count == 1) {
X int old;
X
- old = cyber2000_grphr(FUNC_CTL);
- cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL);
+ old = cyber2000_grphr(FUNC_CTL, cfb);
+ cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL, cfb);
X }
X
X cfb->func_use_count -= 1;
@@ -1170,7 +1229,7 @@
X {
X if (int_cfb_info != NULL) {
X info->dev = int_cfb_info->dev;
- info->regs = CyberRegs;
+ info->regs = int_cfb_info->regs;
X info->fb = int_cfb_info->fb.screen_base;
X info->fb_size = int_cfb_info->fb.fix.smem_len;
X info->enable_extregs = cyber2000fb_enable_extregs;
@@ -1281,14 +1340,14 @@
X * initialising this card for the first time.
X * FIXME: what about hotplug?
X */
- cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
- cfb->mclk_div = cyber2000_grphr(MCLK_DIV);
+ cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+ cfb->mclk_div = cyber2000_grphr(MCLK_DIV, cfb);
X }
X #endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
X /*
- * x86 is simple, we just do regular outb's instead of
- * cyber2000_outb.
+ * x86 and MIPS are simple, we just do regular
+ * outb's instead of cyber2000fb_writeb.
X */
X outb(0x18, 0x46e8);
X outb(0x01, 0x102);
@@ -1302,16 +1361,16 @@
X * initialising this card for the first time.
X * FIXME: what about hotplug?
X */
- cfb->mclk_mult = cyber2000_grphr(MCLK_MULT);
- cfb->mclk_div = cyber2000_grphr(MCLK_DIV);
+ cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
+ cfb->mclk_div = cyber2000_grphr(MCLK_DIV, cfb);
X }
X #endif
X #ifdef __arm__
- cyber2000_outb(0x18, 0x46e8);
- cyber2000_outb(0x01, 0x102);
- cyber2000_outb(0x08, 0x46e8);
- cyber2000_outb(0x33, 0x3ce);
- cyber2000_outb(0x01, 0x3cf);
+ cyber2000fb_writeb(0x18, 0x46e8, cfb);
+ cyber2000fb_writeb(0x01, 0x102, cfb);
+ cyber2000fb_writeb(0x08, 0x46e8, cfb);
+ cyber2000fb_writeb(0x33, 0x3ce, cfb);
+ cyber2000fb_writeb(0x01, 0x3cf, cfb);
X
X /*
X * MCLK on the NetWinder and the Shark is fixed at 75MHz
@@ -1324,7 +1383,7 @@
X * Initialise the CyberPro
X */
X for (i = 0; i < sizeof(igs_regs); i += 2)
- cyber2000_grphw(igs_regs[i], igs_regs[i+1]);
+ cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
X
X if (at_boot) {
X /*
@@ -1332,14 +1391,14 @@
X * This should have been already initialised by the BIOS,
X * but if it's garbage, claim default 1MB VRAM (woody)
X */
- cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1);
- cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2);
+ cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1, cfb);
+ cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2, cfb);
X } else {
X /*
X * Reprogram the MEM_CTL1 and MEM_CTL2 registers
X */
- cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1);
- cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2);
+ cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1, cfb);
+ cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2, cfb);
X }
X
X /*
@@ -1347,8 +1406,8 @@
X * (CyberPro 5000's may be programmed to use
X * an additional set of PLLs.
X */
- cyber2000_outb(0xba, 0x3ce);
- cyber2000_outb(cyber2000_inb(0x3cf) & 0x80, 0x3cf);
+ cyber2000fb_writeb(0xba, 0x3ce, cfb);
+ cyber2000fb_writeb(cyber2000fb_readb(0x3cf, cfb) & 0x80, 0x3cf, cfb);
X }
X
X static struct cfb_info * __devinit
@@ -1366,15 +1425,20 @@
X
X cfb->currcon = -1;
X cfb->dev = dev;
- cfb->ref_ps = 69842;
+
+ if (id->driver_data == FB_ACCEL_IGS_CYBER5000)
+ cfb->ref_ps = 40690; // 24.576 MHz
+ else
+ cfb->ref_ps = 69842; // 14.31818 MHz (69841?)
+
X cfb->divisors[0] = 1;
X cfb->divisors[1] = 2;
X cfb->divisors[2] = 4;
X
- if (id->driver_data == FB_ACCEL_IGS_CYBER2010)
- cfb->divisors[3] = 6;
- else
+ if (id->driver_data == FB_ACCEL_IGS_CYBER2000)
X cfb->divisors[3] = 8;
+ else
+ cfb->divisors[3] = 6;
X
X strcpy(cfb->fb.fix.id, name);
X
@@ -1392,7 +1456,7 @@
X cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
X
X strcpy(cfb->fb.modename, cfb->fb.fix.id);
- strcpy(cfb->fb.fontname, "Acorn8x8");
+ strcpy(cfb->fb.fontname, default_font);
X
X cfb->fb.fbops = &cyber2000fb_ops;
X cfb->fb.changevar = NULL;
@@ -1422,69 +1486,32 @@
X }
X
X /*
- * Map in the registers
- */
-static int __devinit
-cyberpro_map_mmio(struct cfb_info *cfb, struct pci_dev *dev)
-{
- u_long mmio_base;
-
- mmio_base = pci_resource_start(dev, 0) + MMIO_OFFSET;
-
- cfb->fb.fix.mmio_start = mmio_base;
- cfb->fb.fix.mmio_len = MMIO_SIZE;
-
- CyberRegs = ioremap(mmio_base, MMIO_SIZE);
- if (!CyberRegs) {
- printk("%s: unable to map memory mapped IO\n",
- cfb->fb.fix.id);
- return -ENOMEM;


- }
- return 0;
-}
-

-/*
- * Unmap registers
+ * Parse Cyber2000fb options. Usage:
+ * video=cyber2000:font:fontname
X */
-static void __devinit cyberpro_unmap_mmio(struct cfb_info *cfb)
+int
+cyber2000fb_setup(char *options)
X {
- if (cfb && CyberRegs) {
- iounmap(CyberRegs);
- CyberRegs = NULL;
- }
-}
+ char *opt;
X
-/*
- * Map in screen memory
- */
-static int __devinit
-cyberpro_map_smem(struct cfb_info *cfb, struct pci_dev *dev, u_long smem_len)
-{
- u_long smem_base;
+ if (!options || !*options)
+ return 0;
X
- smem_base = pci_resource_start(dev, 0);
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
X
- cfb->fb.fix.smem_start = smem_base;
- cfb->fb.fix.smem_len = smem_len;
+ if (strncmp(opt, "font:", 5) == 0) {
+ strncpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+ default_font = default_font_storage;
+ continue;
+ }
X
- cfb->fb.screen_base = ioremap(smem_base, smem_len);
- if (!cfb->fb.screen_base) {
- printk("%s: unable to map screen memory\n",
- cfb->fb.fix.id);
- return -ENOMEM;
+ printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
X }


-
X return 0;
X }
X

-static void __devinit cyberpro_unmap_smem(struct cfb_info *cfb)
-{
- if (cfb && cfb->fb.screen_base) {
- iounmap(cfb->fb.screen_base);
- cfb->fb.screen_base = NULL;
- }


-}
-
X static int __devinit

X cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
X {
@@ -1507,11 +1534,14 @@
X err = -ENOMEM;
X cfb = cyberpro_alloc_fb_info(dev, id, name);
X if (!cfb)
- goto failed;
+ goto failed_release;
X
- err = cyberpro_map_mmio(cfb, dev);
- if (err)
- goto failed;
+ cfb->region = ioremap(pci_resource_start(dev, 0),
+ pci_resource_len(dev, 0));
+ if (!cfb->region)
+ goto failed_ioremap;
+
+ cfb->regs = cfb->region + MMIO_OFFSET;
X
X cyberpro_init_hw(cfb, 1);
X
@@ -1521,9 +1551,15 @@
X default: smem_size = 0x00100000; break;
X }
X
- err = cyberpro_map_smem(cfb, dev, smem_size);
- if (err)
- goto failed;
+ /*
+ * Hmm, we _need_ a portable way of finding the address for
+ * the remap stuff, both for mmio and for smem.
+ */
+ cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
+ cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
+ cfb->fb.fix.mmio_len = MMIO_SIZE;
+ cfb->fb.fix.smem_len = smem_size;
+ cfb->fb.screen_base = cfb->region;
X
X if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
X &cyber2000fb_default_mode, 8)) {
@@ -1570,11 +1606,10 @@
X return 0;
X
X failed:
- cyberpro_unmap_smem(cfb);
- cyberpro_unmap_mmio(cfb);
+ iounmap(cfb->region);
+failed_ioremap:
X cyberpro_free_fb_info(cfb);
-
-release:
+failed_release:
X pci_release_regions(dev);
X
X return err;
@@ -1594,8 +1629,7 @@
X printk(KERN_WARNING "%s: danger Will Robinson, "
X "danger danger! Oopsen imminent!\n",
X cfb->fb.fix.id);
- cyberpro_unmap_smem(cfb);
- cyberpro_unmap_mmio(cfb);
+ iounmap(cfb->region);
X cyberpro_free_fb_info(cfb);
X
X /*
@@ -1673,7 +1707,10 @@


X }
X
X #ifdef MODULE

-MODULE_LICENSE("GPL");
X module_init(cyber2000fb_init);
X #endif
X module_exit(cyberpro_exit);


+
+MODULE_AUTHOR("Russell King");

+MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cyber2000fb.h linux/drivers/video/cyber2000fb.h
--- v2.4.12/linux/drivers/video/cyber2000fb.h Mon Sep 18 15:15:22 2000
+++ linux/drivers/video/cyber2000fb.h Thu Oct 11 09:43:30 2001
@@ -11,14 +11,6 @@
X */
X #include <linux/config.h>
X
-#define cyber2000_outb(dat,reg) writeb(dat, CyberRegs + reg)
-#define cyber2000_outw(dat,reg) writew(dat, CyberRegs + reg)
-#define cyber2000_outl(dat,reg) writel(dat, CyberRegs + reg)
-
-#define cyber2000_inb(reg) readb(CyberRegs + reg)
-#define cyber2000_inw(reg) readw(CyberRegs + reg)
-#define cyber2000_inl(reg) readl(CyberRegs + reg)
-
X /*
X * Internal CyberPro sizes and offsets.
X */
@@ -30,6 +22,7 @@
X #if defined(DEBUG) && defined(CONFIG_DEBUG_LL)
X static void debug_printf(char *fmt, ...)
X {
+ extern void printascii(const char *);
X char buffer[128];
X va_list ap;
X
@@ -43,38 +36,6 @@
X #define debug_printf(x...) do { } while (0)
X #endif
X
-static inline void cyber2000_crtcw(int reg, int val)
-{
- cyber2000_outb(reg, 0x3d4);
- cyber2000_outb(val, 0x3d5);
-}
-
-static inline void cyber2000_grphw(int reg, int val)
-{
- cyber2000_outb(reg, 0x3ce);
- cyber2000_outb(val, 0x3cf);
-}
-
-static inline unsigned int cyber2000_grphr(int reg)
-{
- cyber2000_outb(reg, 0x3ce);
- return cyber2000_inb(0x3cf);
-}
-
-static inline void cyber2000_attrw(int reg, int val)
-{
- cyber2000_inb(0x3da);
- cyber2000_outb(reg, 0x3c0);
- cyber2000_inb(0x3c1);
- cyber2000_outb(val, 0x3c0);
-}
-
-static inline void cyber2000_seqw(int reg, int val)
-{
- cyber2000_outb(reg, 0x3c4);
- cyber2000_outb(val, 0x3c5);
-}
-
X #define PIXFORMAT_8BPP 0
X #define PIXFORMAT_16BPP 1
X #define PIXFORMAT_24BPP 2


@@ -166,6 +127,7 @@
X

X #define DCLK_MULT 0xb0
X #define DCLK_DIV 0xb1
+#define DCLK_DIV_VFSEL 0x20
X #define MCLK_MULT 0xb2
X #define MCLK_DIV 0xb3
X
diff -u --recursive --new-file v2.4.12/linux/drivers/video/cyberfb.c linux/drivers/video/cyberfb.c
--- v2.4.12/linux/drivers/video/cyberfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/cyberfb.c Sun Oct 21 10:14:38 2001
@@ -1022,8 +1022,7 @@


X return 0;
X }
X

- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strcmp(this_opt, "inverse")) {
X Cyberfb_inverse = 1;
X fb_invert_cmaps();
diff -u --recursive --new-file v2.4.12/linux/drivers/video/dn_cfb8.c linux/drivers/video/dn_cfb8.c
--- v2.4.12/linux/drivers/video/dn_cfb8.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/dn_cfb8.c Mon Oct 15 13:47:13 2001
@@ -518,7 +518,7 @@
X underl = attr_underline(p,conp);
X
X while (count--) {
- c = *s++;
+ c = scr_readw(s++);
X dest = dest0++;
X cdat = p->fontdata+c*p->fontheight;
X for (rows = p->fontheight; rows--; dest += p->next_line) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-afb.c linux/drivers/video/fbcon-afb.c
--- v2.4.12/linux/drivers/video/fbcon-afb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-afb.c Mon Oct 15 13:47:13 2001
@@ -290,8 +290,9 @@
X int fg0, bg0, fg, bg;
X
X dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
- fg0 = attr_fgcol(p, scr_readw(s));
- bg0 = attr_bgcol(p, scr_readw(s));
+ c1 = scr_readw(s);
+ fg0 = attr_fgcol(p, c1);
+ bg0 = attr_bgcol(p, c1);
X
X while (count--)
X if (xx&3 || count < 3) { /* Slow version */
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb16.c linux/drivers/video/fbcon-cfb16.c
--- v2.4.12/linux/drivers/video/fbcon-cfb16.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb16.c Mon Oct 15 13:47:13 2001
@@ -178,8 +178,9 @@
X u32 eorx, fgx, bgx;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
X fgx |= (fgx << 16);
X bgx |= (bgx << 16);
X eorx = fgx ^ bgx;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb2.c linux/drivers/video/fbcon-cfb2.c
--- v2.4.12/linux/drivers/video/fbcon-cfb2.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb2.c Mon Oct 15 13:47:13 2001
@@ -154,8 +154,9 @@
X u32 eorx, fgx, bgx;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 2;
- fgx=3/*attr_fgcol(p,scr_readw(s))*/;
- bgx=attr_bgcol(p,scr_readw(s));
+ c = scr_readw(s);
+ fgx = 3/*attr_fgcol(p, c)*/;
+ bgx = attr_bgcol(p, c);
X fgx |= (fgx << 2);
X fgx |= (fgx << 4);
X bgx |= (bgx << 2);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb24.c linux/drivers/video/fbcon-cfb24.c
--- v2.4.12/linux/drivers/video/fbcon-cfb24.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb24.c Mon Oct 15 13:47:13 2001
@@ -191,8 +191,9 @@
X u32 eorx, fgx, bgx, d1, d2, d3, d4;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
X eorx = fgx ^ bgx;
X while (count--) {
X c = scr_readw(s++) & p->charmask;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb32.c linux/drivers/video/fbcon-cfb32.c
--- v2.4.12/linux/drivers/video/fbcon-cfb32.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb32.c Mon Oct 15 13:47:13 2001
@@ -164,8 +164,9 @@
X u32 eorx, fgx, bgx, *pt;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
X eorx = fgx ^ bgx;
X while (count--) {
X c = scr_readw(s++) & p->charmask;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb4.c linux/drivers/video/fbcon-cfb4.c
--- v2.4.12/linux/drivers/video/fbcon-cfb4.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb4.c Mon Oct 15 13:47:13 2001
@@ -156,8 +156,9 @@
X u32 eorx, fgx, bgx;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 4;
- fgx=attr_fgcol(p,scr_readw(s));
- bgx=attr_bgcol(p,scr_readw(s));
+ c = scr_readw(s);
+ fgx = attr_fgcol(p, c);
+ bgx = attr_bgcol(p, c);
X fgx |= (fgx << 4);
X fgx |= (fgx << 8);
X fgx |= (fgx << 16);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-cfb8.c linux/drivers/video/fbcon-cfb8.c
--- v2.4.12/linux/drivers/video/fbcon-cfb8.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-cfb8.c Mon Oct 15 13:47:13 2001
@@ -163,8 +163,9 @@
X u32 eorx, fgx, bgx;
X
X dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- fgx=attr_fgcol(p,scr_readw(s));
- bgx=attr_bgcol(p,scr_readw(s));
+ c = scr_readw(s);
+ fgx = attr_fgcol(p, c);
+ bgx = attr_bgcol(p, c);
X fgx |= (fgx << 8);
X fgx |= (fgx << 16);
X bgx |= (bgx << 8);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-hga.c linux/drivers/video/fbcon-hga.c
--- v2.4.12/linux/drivers/video/fbcon-hga.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-hga.c Mon Oct 15 13:47:13 2001
@@ -148,9 +148,10 @@
X u8 d;
X u16 c;
X
- bold = attr_bold(p,scr_readw(s));
- revs = attr_reverse(p,scr_readw(s));
- underl = attr_underline(p,scr_readw(s));
+ c = scr_readw(s);
+ bold = attr_bold(p, c);
+ revs = attr_reverse(p, c);
+ underl = attr_underline(p, c);
X y0 = yy*fontheight(p);
X
X while (count--) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-ilbm.c linux/drivers/video/fbcon-ilbm.c
--- v2.4.12/linux/drivers/video/fbcon-ilbm.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-ilbm.c Mon Oct 15 13:47:13 2001
@@ -154,8 +154,9 @@
X int fg0, bg0, fg, bg;
X
X dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
- fg0 = attr_fgcol(p,scr_readw(s));
- bg0 = attr_bgcol(p,scr_readw(s));
+ c1 = scr_readw(s);
+ fg0 = attr_fgcol(p, c1);
+ bg0 = attr_bgcol(p, c1);
X
X while (count--)
X if (xx&3 || count < 3) { /* Slow version */
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-iplan2p2.c linux/drivers/video/fbcon-iplan2p2.c
--- v2.4.12/linux/drivers/video/fbcon-iplan2p2.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-iplan2p2.c Mon Oct 15 13:47:13 2001
@@ -364,8 +364,9 @@
X else
X dest0 = (p->screen_base + yy * bytes * fontheight(p) +
X (xx>>1)*4 + (xx & 1));
- fgx = expand2w(COLOR_2P(attr_fgcol(p,scr_readw(s))));
- bgx = expand2w(COLOR_2P(attr_bgcol(p,scr_readw(s))));
+ c = scr_readw(s);
+ fgx = expand2w(COLOR_2P(attr_fgcol(p, c)));
+ bgx = expand2w(COLOR_2P(attr_bgcol(p, c)));
X eorx = fgx ^ bgx;
X
X while (count--) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-iplan2p4.c linux/drivers/video/fbcon-iplan2p4.c
--- v2.4.12/linux/drivers/video/fbcon-iplan2p4.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-iplan2p4.c Mon Oct 15 13:47:13 2001
@@ -374,8 +374,9 @@
X else
X dest0 = (p->screen_base + yy * bytes * fontheight(p) +
X (xx>>1)*8 + (xx & 1));
- fgx = expand4l(attr_fgcol(p,scr_readw(s)));
- bgx = expand4l(attr_bgcol(p,scr_readw(s)));
+ c = scr_readw(s);
+ fgx = expand4l(attr_fgcol(p, c));
+ bgx = expand4l(attr_bgcol(p, c));
X eorx = fgx ^ bgx;
X
X while (count--) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-iplan2p8.c linux/drivers/video/fbcon-iplan2p8.c
--- v2.4.12/linux/drivers/video/fbcon-iplan2p8.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-iplan2p8.c Mon Oct 15 13:47:13 2001
@@ -407,8 +407,9 @@
X dest0 = (p->screen_base + yy * bytes * fontheight(p) +
X (xx>>1)*16 + (xx & 1));
X
- expand8dl(attr_fgcol(p,scr_readw(s)), &fgx1, &fgx2);
- expand8dl(attr_bgcol(p,scr_readw(s)), &bgx1, &bgx2);
+ c = scr_readw(s);
+ expand8dl(attr_fgcol(p, c), &fgx1, &fgx2);
+ expand8dl(attr_bgcol(p, c), &bgx1, &bgx2);
X eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
X
X while (count--) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-mfb.c linux/drivers/video/fbcon-mfb.c
--- v2.4.12/linux/drivers/video/fbcon-mfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-mfb.c Mon Oct 15 13:47:13 2001
@@ -117,9 +117,10 @@
X u16 c;
X
X dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
- bold = attr_bold(p,scr_readw(s));
- revs = attr_reverse(p,scr_readw(s));
- underl = attr_underline(p,scr_readw(s));
+ c = scr_readw(s);
+ bold = attr_bold(p, c);
+ revs = attr_reverse(p, c);
+ underl = attr_underline(p, c);
X
X while (count--) {
X c = scr_readw(s++) & p->charmask;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-sti.c linux/drivers/video/fbcon-sti.c
--- v2.4.12/linux/drivers/video/fbcon-sti.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-sti.c Mon Oct 15 13:47:13 2001
@@ -257,9 +257,10 @@
X return;
X }
X
- bold = attr_bold(p,scr_readw(s));
- revs = attr_reverse(p,scr_readw(s));
- underl = attr_underline(p,scr_readw(s));
+ c = scr_readw(s);
+ bold = attr_bold(p, c);
+ revs = attr_reverse(p, c);
+ underl = attr_underline(p, c);
X
X while (count--) {
X c = scr_readw(s++) & p->charmask;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon-vga-planes.c linux/drivers/video/fbcon-vga-planes.c
--- v2.4.12/linux/drivers/video/fbcon-vga-planes.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon-vga-planes.c Mon Oct 15 13:47:13 2001
@@ -236,8 +236,9 @@
X void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
X int count, int yy, int xx)
X {
- int fg = attr_fgcol(p,scr_readw(s));
- int bg = attr_bgcol(p,scr_readw(s));
+ u16 c = scr_readw(s);
+ int fg = attr_fgcol(p, c);
+ int bg = attr_bgcol(p, c);
X
X char *where;
X int n;
@@ -274,8 +275,9 @@
X void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
X int count, int yy, int xx)
X {
- int fg = attr_fgcol(p,*s);
- int bg = attr_bgcol(p,*s);
+ u16 c = scr_readw(s);
+ int fg = attr_fgcol(p, c);
+ int bg = attr_bgcol(p, c);
X
X char *where;
X int n;
@@ -295,7 +297,7 @@
X wmb();
X for (n = 0; n < count; n++) {
X int y;
- int c = *s++ & p->charmask;
+ int c = scr_readw(s++) & p->charmask;
X u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
X
X for (y = 0; y < fontheight(p); y++, cdat++) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.4.12/linux/drivers/video/fbcon.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbcon.c Mon Oct 15 13:47:13 2001
@@ -664,7 +664,7 @@
X scr_memsetw(save, conp->vc_video_erase_char, logo_lines * nr_cols * 2);
X r = q - step;
X for (cnt = 0; cnt < logo_lines; cnt++, r += i)
- scr_memcpyw_from(save + cnt * nr_cols, r, 2 * i);
+ scr_memcpyw(save + cnt * nr_cols, r, 2 * i);
X r = q;
X }
X }
@@ -682,7 +682,7 @@
X }
X scr_memsetw((unsigned short *)conp->vc_origin,
X conp->vc_video_erase_char,
- conp->vc_size_row * logo_lines);
+ conp->vc_size_row * logo_lines);
X }
X
X /*
@@ -2010,17 +2010,14 @@
X static void fbcon_invert_region(struct vc_data *conp, u16 *p, int cnt)
X {
X while (cnt--) {
+ u16 a = scr_readw(p);
X if (!conp->vc_can_do_color)
- *p++ ^= 0x0800;
- else if (conp->vc_hi_font_mask == 0x100) {
- u16 a = *p;
+ a ^= 0x0800;
+ else if (conp->vc_hi_font_mask == 0x100)
X a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
- *p++ = a;
- } else {
- u16 a = *p;
+ else
X a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
- *p++ = a;
- }
+ scr_writew(a, p++);
X if (p == (u16 *)softback_end)
X p = (u16 *)softback_buf;
X if (p == (u16 *)softback_in)
diff -u --recursive --new-file v2.4.12/linux/drivers/video/fm2fb.c linux/drivers/video/fm2fb.c
--- v2.4.12/linux/drivers/video/fm2fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fm2fb.c Sun Oct 21 10:14:38 2001
@@ -430,8 +430,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "pal", 3))
X fm2fb_mode = FM2FB_MODE_PAL;
X else if (!strncmp(this_opt, "ntsc", 4))
diff -u --recursive --new-file v2.4.12/linux/drivers/video/hgafb.c linux/drivers/video/hgafb.c
--- v2.4.12/linux/drivers/video/hgafb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/hgafb.c Sun Oct 21 10:14:38 2001
@@ -203,7 +203,7 @@
X fillchar = 0x00;
X spin_unlock_irqrestore(&hga_reg_lock, flags);
X if (fillchar != 0xbf)
- memset((char *)hga_vram_base, fillchar, hga_vram_len);
+ isa_memset_io(hga_vram_base, fillchar, hga_vram_len);
X }
X
X
@@ -275,11 +275,12 @@
X static void hga_show_logo(void)
X {
X int x, y;
- char *dest = (char *)hga_vram_base;
+ unsigned long dest = hga_vram_base;
X char *logo = linux_logo_bw;
X for (y = 134; y < 134 + 80 ; y++) /* this needs some cleanup */
X for (x = 0; x < 10 ; x++)
- *(dest + (y%4)*8192 + (y>>2)*90 + x + 40) = ~*(logo++);
+ isa_writeb(~*(logo++),
+ (dest + (y%4)*8192 + (y>>2)*90 + x + 40));
X }


X #endif /* MODULE */
X

@@ -794,8 +795,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5))
X strcpy(fb_info.fontname, this_opt+5);
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/video/igafb.c linux/drivers/video/igafb.c
--- v2.4.12/linux/drivers/video/igafb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/igafb.c Sun Oct 21 10:14:38 2001
@@ -773,8 +773,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
--- v2.4.12/linux/drivers/video/imsttfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/imsttfb.c Sun Oct 21 10:14:38 2001
@@ -1977,8 +1977,7 @@
X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;
diff -u --recursive --new-file v2.4.12/linux/drivers/video/leofb.c linux/drivers/video/leofb.c
--- v2.4.12/linux/drivers/video/leofb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/leofb.c Wed Oct 17 14:16:39 2001
@@ -1,4 +1,4 @@
-/* $Id: leofb.c,v 1.13 2001/09/19 00:04:33 davem Exp $
+/* $Id: leofb.c,v 1.14 2001/10/16 05:44:44 davem Exp $
X * leofb.c: Leo (ZX) 24/8bit frame buffer driver
X *
X * Copyright (C) 1996-1999 Jakub Jelinek (j...@ultra.linux.cz)
@@ -285,14 +285,16 @@
X unsigned long flags;
X int i, x, y;
X u8 *fd1, *fd2, *fd3, *fd4;
+ u16 c;
X u32 *u;
X
X spin_lock_irqsave(&fb->lock, flags);
X do {
X i = sbus_readl(&us->csr);
X } while (i & 0x20000000);
- sbus_writel(attr_fgcol(p,scr_readw(s)) << 24, &ss->fg);
- sbus_writel(attr_bgcol(p,scr_readw(s)) << 24, &ss->bg);
+ c = scr_readw(s);
+ sbus_writel(attr_fgcol(p, c) << 24, &ss->fg);
+ sbus_writel(attr_bgcol(p, c) << 24, &ss->bg);
X sbus_writel(0xFFFFFFFF<<(32-fontwidth(p)), &us->fontmsk);
X if (fontwidthlog(p))
X x = (xx << fontwidthlog(p));
diff -u --recursive --new-file v2.4.12/linux/drivers/video/macfb.c linux/drivers/video/macfb.c
--- v2.4.12/linux/drivers/video/macfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/macfb.c Sun Oct 21 10:14:38 2001
@@ -848,7 +848,7 @@
X if (!options || !*options)
X return;
X
- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!*this_opt) continue;
X
X if (! strcmp(this_opt, "inverse"))
diff -u --recursive --new-file v2.4.12/linux/drivers/video/matrox/matroxfb_accel.c linux/drivers/video/matrox/matroxfb_accel.c
--- v2.4.12/linux/drivers/video/matrox/matroxfb_accel.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/video/matrox/matroxfb_accel.c Mon Oct 15 13:47:13 2001
@@ -654,13 +654,15 @@
X
X #ifdef FBCON_HAS_CFB8
X static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
X u_int32_t fgx, bgx;
X MINFO_FROM_DISP(p);
X
X DBG_HEAVY("matroxfb_cfb8_putcs");
X
- fgx = attr_fgcol(p, scr_readw(s));
- bgx = attr_bgcol(p, scr_readw(s));
+ c = scr_readw(s);
+ fgx = attr_fgcol(p, c);
+ bgx = attr_bgcol(p, c);
X fgx |= (fgx << 8);
X fgx |= (fgx << 16);
X bgx |= (bgx << 8);


@@ -671,13 +673,15 @@
X

X #ifdef FBCON_HAS_CFB16
X static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
X u_int32_t fgx, bgx;
X MINFO_FROM_DISP(p);
X
X DBG_HEAVY("matroxfb_cfb16_putcs");
X
- fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
X fgx |= (fgx << 16);
X bgx |= (bgx << 16);
X ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
@@ -686,13 +690,15 @@
X
X #if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
X static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
X u_int32_t fgx, bgx;
X MINFO_FROM_DISP(p);
X
X DBG_HEAVY("matroxfb_cfb32_putcs");
X
- fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
X ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
X }
X #endif
@@ -900,12 +906,14 @@
X unsigned int offs;
X unsigned int attr;
X unsigned int step;
+ u_int16_t c;
X CRITFLAGS
X MINFO_FROM_DISP(p);
X
X step = ACCESS_FBINFO(devflags.textstep);
X offs = yy * p->next_line + xx * step;
- attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
+ c = scr_readw(s);
+ attr = attr_fgcol(p, c) | (attr_bgcol(p, c) << 4);
X
X CRITBEGIN
X
diff -u --recursive --new-file v2.4.12/linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- v2.4.12/linux/drivers/video/matrox/matroxfb_base.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/video/matrox/matroxfb_base.c Sun Oct 21 10:14:38 2001
@@ -2355,7 +2355,7 @@
X if (!options || !*options)
X return 0;
X
- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!*this_opt) continue;
X
X dprintk("matroxfb_setup: option %s\n", this_opt);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/newport_con.c linux/drivers/video/newport_con.c
--- v2.4.12/linux/drivers/video/newport_con.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/newport_con.c Mon Oct 15 13:47:24 2001


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 40'
echo 'File patch-2.4.13 is continued in part 41'
echo "41" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:11 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part41

#!/bin/sh -x
# this is part 41 of a 53 - part archive


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

if test "$Scheck" != 41; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

@@ -379,7 +379,7 @@
X int charattr;
X unsigned char *p;
X
- charattr = (*s >> 8) & 0xff;
+ charattr = (scr_readw(s) >> 8) & 0xff;
X
X xpos <<= 3;
X ypos <<= 4;
@@ -399,7 +399,7 @@
X NPORT_DMODE0_L32);
X
X for (i = 0; i < count; i++, xpos += 8) {
- p = &font_data[vc->vc_num][(s[i] & 0xff) << 4];
+ p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
X
X newport_wait();
X
diff -u --recursive --new-file v2.4.12/linux/drivers/video/platinumfb.c linux/drivers/video/platinumfb.c
--- v2.4.12/linux/drivers/video/platinumfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/platinumfb.c Sun Oct 21 10:14:38 2001
@@ -841,8 +841,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;

diff -u --recursive --new-file v2.4.12/linux/drivers/video/promcon.c linux/drivers/video/promcon.c
--- v2.4.12/linux/drivers/video/promcon.c Fri Feb 9 11:30:23 2001
+++ linux/drivers/video/promcon.c Mon Oct 15 13:47:13 2001


@@ -51,27 +51,30 @@
X {

X unsigned short *s = (unsigned short *)
X (conp->vc_origin + py * conp->vc_size_row + (px << 1));
+ u16 cs;
X
+ cs = scr_readw(s);
X if (px == pw) {
X unsigned short *t = s - 1;
+ u16 ct = scr_readw(t);
X
- if (inverted(*s) && inverted(*t))
- return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m",
- *s, *t);
- else if (inverted(*s))
- return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c",
- *s, *t);
- else if (inverted(*t))
- return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m",
- *s, *t);
+ if (inverted(cs) && inverted(ct))
+ return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
+ ct);
+ else if (inverted(cs))
+ return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
+ ct);
+ else if (inverted(ct))
+ return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
+ ct);
X else
- return sprintf(b, "\b%c\b\033[@%c", *s, *t);
+ return sprintf(b, "\b%c\b\033[@%c", cs, ct);
X }
X
- if (inverted(*s))
- return sprintf(b, "\033[7m%c\033[m\b", *s);
+ if (inverted(cs))
+ return sprintf(b, "\033[7m%c\033[m\b", cs);
X else
- return sprintf(b, "%c\b", *s);
+ return sprintf(b, "%c\b", cs);


X }
X
X static int

@@ -80,27 +83,30 @@
X unsigned short *s = (unsigned short *)
X (conp->vc_origin + py * conp->vc_size_row + (px << 1));
X char *p = b;
+ u16 cs;
X
X b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
X
+ cs = scr_readw(s);
X if (px == pw) {
X unsigned short *t = s - 1;
+ u16 ct = scr_readw(t);
X
- if (inverted(*s) && inverted(*t))
- b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", *s, *t);
- else if (inverted(*s))
- b += sprintf(b, "\b%c\b\033[@%c", *s, *t);
- else if (inverted(*t))
- b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", *s, *t);
+ if (inverted(cs) && inverted(ct))
+ b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
+ else if (inverted(cs))
+ b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
+ else if (inverted(ct))
+ b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
X else
- b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", *s, *t);
+ b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
X return b - p;
X }
X
- if (inverted(*s))
- b += sprintf(b, "%c\b", *s);
+ if (inverted(cs))
+ b += sprintf(b, "%c\b", cs);
X else
- b += sprintf(b, "\033[7m%c\033[m\b", *s);
+ b += sprintf(b, "\033[7m%c\033[m\b", cs);
X return b - p;
X }
X
@@ -206,8 +212,9 @@
X unsigned char *b = *bp;
X
X while (cnt--) {
- if (attr != inverted(*s)) {
- attr = inverted(*s);


+ u16 c = scr_readw(s);

+ if (attr != inverted(c)) {
+ attr = inverted(c);
X if (attr) {
X strcpy (b, "\033[7m");
X b += 4;
@@ -216,7 +223,8 @@
X b += 3;
X }
X }
- *b++ = *s++;
+ *b++ = c;
+ s++;
X if (b - buf >= 224) {
X promcon_puts(buf, b - buf);
X b = buf;
@@ -246,9 +254,9 @@
X if (x + count >= pw + 1) {
X if (count == 1) {
X x -= 1;
- save = *(unsigned short *)(conp->vc_origin
+ save = scr_readw((unsigned short *)(conp->vc_origin
X + y * conp->vc_size_row
- + (x << 1));
+ + (x << 1)));
X
X if (px != x || py != y) {
X b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/pvr2fb.c linux/drivers/video/pvr2fb.c
--- v2.4.12/linux/drivers/video/pvr2fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/pvr2fb.c Mon Oct 15 13:36:48 2001
@@ -286,7 +286,7 @@
X
X {
X /* 640x480 @ 60hz (VGA) */
- "vga_640x480", 60, 640, 480, 38, 33, 0, 18, 146, 26,
+ "vga_640x480", 60, 640, 480, VGA_CLK, 38, 33, 0, 18, 146, 26,
X 0, FB_VMODE_YWRAP
X },
X
@@ -382,6 +382,7 @@
X
X pvr2_encode_fix(&fix, &par);
X display->screen_base = (char *)fix.smem_start;
+ display->scrollmode = SCROLL_YREDRAW;
X display->visual = fix.visual;
X display->type = fix.type;
X display->type_aux = fix.type_aux;
@@ -589,7 +590,7 @@
X #ifdef FBCON_HAS_CFB16
X case 16: /* RGB 565 */
X fbcon_cmap.cfb16[regno] = (red & 0xf800) |
- ((green & 0xf800) >> 6) |
+ ((green & 0xfc00) >> 5) |
X ((blue & 0xf800) >> 11);
X break;
X #endif
@@ -1076,8 +1077,8 @@
X printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n",
X GET_FB_IDX(fb_info.node), var.xres, var.yres, var.bits_per_pixel,
X get_line_length(var.xres, var.bits_per_pixel),
- (char *)pvr2_get_param(cables, NULL, cable_type, 6),
- (char *)pvr2_get_param(outputs, NULL, video_output, 6));
+ (char *)pvr2_get_param(cables, NULL, cable_type, 3),
+ (char *)pvr2_get_param(outputs, NULL, video_output, 3));


X
X return 0;
X }

@@ -1155,10 +1156,10 @@
X }
X
X if (*cable_arg)
- cable_type = pvr2_get_param(cables, cable_arg, 0, 6);
+ cable_type = pvr2_get_param(cables, cable_arg, 0, 3);
X
X if (*output_arg)
- video_output = pvr2_get_param(outputs, output_arg, 0, 6);
+ video_output = pvr2_get_param(outputs, output_arg, 0, 3);


X
X return 0;
X }

diff -u --recursive --new-file v2.4.12/linux/drivers/video/radeonfb.c linux/drivers/video/radeonfb.c
--- v2.4.12/linux/drivers/video/radeonfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/radeonfb.c Sun Oct 21 10:14:38 2001
@@ -537,8 +537,7 @@


X if (!options || !*options)
X return 0;
X

- for (this_opt = strtok (options, ","); this_opt;
- this_opt = strtok (NULL, ",")) {


+ while (this_opt = strsep (&options, ",")) {

X if (!strncmp (this_opt, "font:", 5)) {


X char *p;
X int i;

diff -u --recursive --new-file v2.4.12/linux/drivers/video/retz3fb.c linux/drivers/video/retz3fb.c
--- v2.4.12/linux/drivers/video/retz3fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/retz3fb.c Sun Oct 21 10:14:38 2001
@@ -1348,8 +1348,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")){
+ while (this_opt = strsep(&options, ",")) {

X if (!strcmp(this_opt, "inverse")) {
X z3fb_inverse = 1;
X fb_invert_cmaps();
diff -u --recursive --new-file v2.4.12/linux/drivers/video/riva/accel.c linux/drivers/video/riva/accel.c
--- v2.4.12/linux/drivers/video/riva/accel.c Sat Feb 3 12:48:00 2001
+++ linux/drivers/video/riva/accel.c Mon Oct 15 13:47:13 2001
@@ -207,10 +207,11 @@
X xx *= fontwidth(p);
X yy *= fontheight(p);
X

+ c = scr_readw(s);
+ fgx = attr_fgcol(p, c);
+ bgx = attr_bgcol(p, c);

X while (count--) {
X c = scr_readw(s++);
- fgx = attr_fgcol(p,c);
- bgx = attr_bgcol(p,c);
X fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
X xx += fontwidth(p);
X }
@@ -321,12 +322,13 @@
X xx *= fontwidth(p);
X yy *= fontheight(p);
X

+ c = scr_readw(s);
+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];

+ if (p->var.green.length == 6)
+ convert_bgcolor_16(&bgx);
X while (count--) {
X c = scr_readw(s++);
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p,c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p,c)];
- if (p->var.green.length == 6)
- convert_bgcolor_16(&bgx);
X fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
X xx += fontwidth(p);
X }
@@ -396,10 +398,11 @@
X xx *= fontwidth(p);
X yy *= fontheight(p);
X

+ c = scr_readw(s);
+ fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];

X while (count--) {
X c = scr_readw(s++);
- fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
- bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
X fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
X xx += fontwidth(p);
X }
diff -u --recursive --new-file v2.4.12/linux/drivers/video/riva/fbdev.c linux/drivers/video/riva/fbdev.c
--- v2.4.12/linux/drivers/video/riva/fbdev.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/video/riva/fbdev.c Sun Oct 21 10:14:38 2001
@@ -2045,8 +2045,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;

diff -u --recursive --new-file v2.4.12/linux/drivers/video/sa1100fb.c linux/drivers/video/sa1100fb.c
--- v2.4.12/linux/drivers/video/sa1100fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/sa1100fb.c Sun Oct 21 10:14:38 2001
@@ -2299,8 +2299,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X

X if (!strncmp(this_opt, "bpp:", 4))
X current_par.max_bpp =
diff -u --recursive --new-file v2.4.12/linux/drivers/video/sgivwfb.c linux/drivers/video/sgivwfb.c
--- v2.4.12/linux/drivers/video/sgivwfb.c Fri Feb 9 11:30:23 2001
+++ linux/drivers/video/sgivwfb.c Sun Oct 21 10:14:38 2001
@@ -862,8 +862,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5))
X strcpy(fb_info.fontname, this_opt+5);
X }

diff -u --recursive --new-file v2.4.12/linux/drivers/video/sis/sis_main.c linux/drivers/video/sis/sis_main.c
--- v2.4.12/linux/drivers/video/sis/sis_main.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/sis/sis_main.c Sun Oct 21 10:14:38 2001
@@ -1726,8 +1726,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {

X if (!*this_opt)
X continue;
X
diff -u --recursive --new-file v2.4.12/linux/drivers/video/sstfb.c linux/drivers/video/sstfb.c
--- v2.4.12/linux/drivers/video/sstfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/sstfb.c Sun Oct 21 10:14:38 2001
@@ -1697,8 +1697,7 @@


X if (!options || !*options)
X return 0;
X

- for(this_opt = strtok(options, ","); this_opt;


- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {

X if (!*this_opt) continue;
X
X f_ddprintk("option %s\n", this_opt);
diff -u --recursive --new-file v2.4.12/linux/drivers/video/sticon-bmode.c linux/drivers/video/sticon-bmode.c
--- v2.4.12/linux/drivers/video/sticon-bmode.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/sticon-bmode.c Mon Oct 15 13:47:13 2001
@@ -318,7 +318,7 @@
X int count, int ypos, int xpos)
X {
X while(count--) {
- sti_putc(&default_sti, *s++, ypos, xpos++);
+ sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
X }
X }
X
@@ -402,16 +402,6 @@


X return 0;
X }
X

-static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
-{


- return NULL;
-}
-

-static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)


-{
- return 0;
-}
-

X static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
X {
X u8 attr = ((color & 0x70) >> 1) | ((color & 7));
@@ -440,11 +430,7 @@
X con_set_palette: sticon_set_palette,
X con_scrolldelta: sticon_scrolldelta,
X con_set_origin: sticon_set_origin,
- con_save_screen: NULL,
X con_build_attr: sticon_build_attr,
- con_invert_region: NULL,
- con_screen_pos: sticon_screen_pos,
- con_getxy: sticon_getxy,
X };
X
X #include <asm/pgalloc.h> /* need cache flush routines */
diff -u --recursive --new-file v2.4.12/linux/drivers/video/sticon.c linux/drivers/video/sticon.c
--- v2.4.12/linux/drivers/video/sticon.c Tue Dec 5 12:29:39 2000
+++ linux/drivers/video/sticon.c Mon Oct 15 13:47:13 2001
@@ -86,7 +86,7 @@
X int count, int ypos, int xpos)
X {
X while(count--) {
- sti_putc(&default_sti, *s++, ypos, xpos++);
+ sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
X }
X }
X
@@ -170,16 +170,6 @@


X return 0;
X }
X

-static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
-{


- return NULL;
-}
-

-static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)


-{
- return 0;
-}
-

X static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
X {
X u8 attr = ((color & 0x70) >> 1) | ((color & 7));
@@ -208,11 +198,7 @@
X con_set_palette: sticon_set_palette,
X con_scrolldelta: sticon_scrolldelta,
X con_set_origin: sticon_set_origin,
- con_save_screen: NULL,
X con_build_attr: sticon_build_attr,
- con_invert_region: NULL,
- con_screen_pos: sticon_screen_pos,
- con_getxy: sticon_getxy,
X };
X
X static int __init sti_init(void)
diff -u --recursive --new-file v2.4.12/linux/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- v2.4.12/linux/drivers/video/tdfxfb.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/video/tdfxfb.c Sun Oct 21 10:14:38 2001
@@ -1088,27 +1088,27 @@
X struct display* p,
X const unsigned short *s,int count,int yy,int xx)
X {
- u32 fgx,bgx;
- fgx=attr_fgcol(p, *s);
- bgx=attr_bgcol(p, *s);


+ u16 c = scr_readw(s);

+ u32 fgx = attr_fgcol(p, c);
+ u32 bgx = attr_bgcol(p, c);
X do_putcs( fgx,bgx,p,s,count,yy,xx );
X }
X static void tdfx_cfb16_putcs(struct vc_data* conp,
X struct display* p,
X const unsigned short *s,int count,int yy,int xx)
X {
- u32 fgx,bgx;
- fgx=((u16*)p->dispsw_data)[attr_fgcol(p,*s)];
- bgx=((u16*)p->dispsw_data)[attr_bgcol(p,*s)];


+ u16 c = scr_readw(s);

+ u32 fgx = ((u16*)p->dispsw_data)[attr_fgcol(p, c)];
+ u32 bgx = ((u16*)p->dispsw_data)[attr_bgcol(p, c)];
X do_putcs( fgx,bgx,p,s,count,yy,xx );
X }
X static void tdfx_cfb32_putcs(struct vc_data* conp,
X struct display* p,
X const unsigned short *s,int count,int yy,int xx)
X {
- u32 fgx,bgx;
- fgx=((u32*)p->dispsw_data)[attr_fgcol(p,*s)];
- bgx=((u32*)p->dispsw_data)[attr_bgcol(p,*s)];


+ u16 c = scr_readw(s);

+ u32 fgx = ((u32*)p->dispsw_data)[attr_fgcol(p, c)];
+ u32 bgx = ((u32*)p->dispsw_data)[attr_bgcol(p, c)];
X do_putcs( fgx,bgx,p,s,count,yy,xx );
X }
X
@@ -2086,9 +2086,7 @@
X if(!options || !*options)


X return;
X
- for(this_opt = strtok(options, ",");

- this_opt;


- this_opt = strtok(NULL, ",")) {

+ while(this_opt = strsep(&options, ",")) {
X if(!strcmp(this_opt, "inverse")) {
X inverse = 1;
X fb_invert_cmaps();
diff -u --recursive --new-file v2.4.12/linux/drivers/video/tgafb.c linux/drivers/video/tgafb.c
--- v2.4.12/linux/drivers/video/tgafb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/tgafb.c Sun Oct 21 10:14:38 2001
@@ -889,7 +889,7 @@
X int i;
X
X if (options && *options) {


- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!*this_opt) { continue; }
X

X if (!strncmp(this_opt, "font:", 5)) {
diff -u --recursive --new-file v2.4.12/linux/drivers/video/valkyriefb.c linux/drivers/video/valkyriefb.c
--- v2.4.12/linux/drivers/video/valkyriefb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/valkyriefb.c Sun Oct 21 10:14:38 2001
@@ -801,8 +801,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5)) {
X char *p;
X int i;

diff -u --recursive --new-file v2.4.12/linux/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- v2.4.12/linux/drivers/video/vesafb.c Wed Apr 18 11:49:12 2001
+++ linux/drivers/video/vesafb.c Sun Oct 21 10:14:38 2001
@@ -457,7 +457,7 @@


X if (!options || !*options)
X return 0;
X
- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!*this_opt) continue;
X

X if (! strcmp(this_opt, "inverse"))

diff -u --recursive --new-file v2.4.12/linux/drivers/video/vfb.c linux/drivers/video/vfb.c
--- v2.4.12/linux/drivers/video/vfb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/vfb.c Sun Oct 21 10:14:38 2001
@@ -382,8 +382,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt;
- this_opt = strtok(NULL, ",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!strncmp(this_opt, "font:", 5))
X strcpy(fb_info.fontname, this_opt+5);
X }

diff -u --recursive --new-file v2.4.12/linux/drivers/video/vga16fb.c linux/drivers/video/vga16fb.c
--- v2.4.12/linux/drivers/video/vga16fb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/vga16fb.c Sun Oct 21 10:14:38 2001
@@ -692,7 +692,7 @@


X if (!options || !*options)
X return 0;
X

- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while (this_opt = strsep(&options, ",")) {
X if (!*this_opt) continue;
X

X if (!strncmp(this_opt, "font:", 5))
diff -u --recursive --new-file v2.4.12/linux/drivers/video/vgacon.c linux/drivers/video/vgacon.c
--- v2.4.12/linux/drivers/video/vgacon.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/vgacon.c Mon Oct 15 13:47:13 2001
@@ -487,7 +487,7 @@
X vga_video_num_columns = c->vc_cols;
X vga_video_num_lines = c->vc_rows;
X if (!vga_is_gfx)
- scr_memcpyw_to((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
+ scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
X return 0; /* Redrawing not needed */
X }
X
@@ -978,7 +978,7 @@
X c->vc_y = ORIG_Y;
X }
X if (!vga_is_gfx)
- scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
+ scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
X }
X
X static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
diff -u --recursive --new-file v2.4.12/linux/drivers/video/virgefb.c linux/drivers/video/virgefb.c
--- v2.4.12/linux/drivers/video/virgefb.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/virgefb.c Sun Oct 21 10:14:38 2001
@@ -1085,7 +1085,7 @@


X if (!options || !*options)
X return 0;
X
- for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+ while (this_opt = strsep(&options, ",")) {
X if (!strcmp(this_opt, "inverse")) {

X Cyberfb_inverse = 1;
X fb_invert_cmaps();

diff -u --recursive --new-file v2.4.12/linux/fs/attr.c linux/fs/attr.c
--- v2.4.12/linux/fs/attr.c Tue Oct 9 17:06:53 2001
+++ linux/fs/attr.c Thu Oct 11 09:43:30 2001
@@ -137,7 +137,7 @@
X (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
X error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
X if (!error)
- inode_setattr(inode, attr);
+ error = inode_setattr(inode, attr);
X }
X }
X unlock_kernel();
diff -u --recursive --new-file v2.4.12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.4.12/linux/fs/binfmt_elf.c Tue Oct 9 17:06:53 2001
+++ linux/fs/binfmt_elf.c Sat Oct 20 19:16:59 2001
@@ -270,6 +270,8 @@
X */
X if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
X goto out;
+ if (interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
+ goto out;
X
X /* Now read in all of the header information */
X
@@ -757,8 +759,7 @@
X printk("(brk) %lx\n" , (long) current->mm->brk);
X #endif
X
- if ( current->personality == PER_SVR4 )
- {
+ if (current->personality & MMAP_PAGE_ZERO) {
X /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
X and some applications "depend" upon this behavior.
X Since we do not have the power to recompile these, we
diff -u --recursive --new-file v2.4.12/linux/fs/binfmt_misc.c linux/fs/binfmt_misc.c
--- v2.4.12/linux/fs/binfmt_misc.c Fri Feb 9 11:29:44 2001
+++ linux/fs/binfmt_misc.c Sat Oct 20 19:14:42 2001
@@ -13,165 +13,80 @@
X * 1997-06-26 hpa: pass the real filename rather than argv[0]
X * 1997-06-30 minor cleanup
X * 1997-08-09 removed extension stripping, locking cleanup
+ * 2001-02-28 AV: rewritten into something that resembles C. Original didn't.
X */
X
-#include <linux/config.h>
X #include <linux/module.h>
+#include <linux/init.h>
X
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
X #include <linux/binfmts.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/string.h>
+#include <linux/slab.h>
X #include <linux/ctype.h>
X #include <linux/file.h>
-#include <linux/spinlock.h>
+#include <linux/pagemap.h>
+
X #include <asm/uaccess.h>
X
-/*
- * We should make this work with a "stub-only" /proc,
- * which would just not be able to be configured.
- * Right now the /proc-fs support is too black and white,
- * though, so just remind people that this should be
- * fixed..
- */
-#ifndef CONFIG_PROC_FS
-#error You really need /proc support for binfmt_misc. Please reconfigure!
-#endif
-
-#define VERBOSE_STATUS /* undef this to save 400 bytes kernel memory */
-
-struct binfmt_entry {
- struct binfmt_entry *next;
- long id;
+enum {
+ VERBOSE_STATUS = 1 /* make it zero to save 400 bytes kernel memory */
+};
+
+static LIST_HEAD(entries);
+static int enabled = 1;
+
+enum {Enabled, Magic};
+
+typedef struct {
+ struct list_head list;
X int flags; /* type, status, etc. */
X int offset; /* offset of magic */
X int size; /* size of magic/mask */
X char *magic; /* magic or filename extension */
X char *mask; /* mask, NULL for exact match */
X char *interpreter; /* filename of interpreter */
- char *proc_name;
- struct proc_dir_entry *proc_dir;
-};
-
-#define ENTRY_ENABLED 1 /* the old binfmt_entry.enabled */
-#define ENTRY_MAGIC 8 /* not filename detection */
-
-static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs);
-static void entry_proc_cleanup(struct binfmt_entry *e);
-static int entry_proc_setup(struct binfmt_entry *e);
-
-static struct linux_binfmt misc_format = {
- NULL, THIS_MODULE, load_misc_binary, NULL, NULL, 0
-};
-
-static struct proc_dir_entry *bm_dir;
-
-static struct binfmt_entry *entries;
-static int free_id = 1;
-static int enabled = 1;
+ char *name;
+ struct dentry *dentry;
+} Node;
X
X static rwlock_t entries_lock __attribute__((unused)) = RW_LOCK_UNLOCKED;
X
-
-/*
- * Unregister one entry
- */
-static void clear_entry(int id)
-{
- struct binfmt_entry **ep, *e;
-
- write_lock(&entries_lock);
- ep = &entries;
- while (*ep && ((*ep)->id != id))
- ep = &((*ep)->next);
- if ((e = *ep))
- *ep = e->next;
- write_unlock(&entries_lock);
-
- if (e) {
- entry_proc_cleanup(e);
- kfree(e);
- }
-}
-
-/*
- * Clear all registered binary formats
- */
-static void clear_entries(void)
-{
- struct binfmt_entry *e, *n;
-
- write_lock(&entries_lock);
- n = entries;
- entries = NULL;
- write_unlock(&entries_lock);
-
- while ((e = n)) {
- n = e->next;
- entry_proc_cleanup(e);
- kfree(e);
- }
-}
-
-/*
- * Find entry through id and lock it
- */
-static struct binfmt_entry *get_entry(int id)
-{
- struct binfmt_entry *e;
-
- read_lock(&entries_lock);
- e = entries;
- while (e && (e->id != id))
- e = e->next;
- if (!e)
- read_unlock(&entries_lock);
- return e;
-}
-
-/*
- * unlock entry
- */
-static inline void put_entry(struct binfmt_entry *e)
-{
- if (e)
- read_unlock(&entries_lock);
-}
-
-
X /*
X * Check if we support the binfmt
- * if we do, return the binfmt_entry, else NULL
+ * if we do, return the node, else NULL
X * locking is done in load_misc_binary
X */
-static struct binfmt_entry *check_file(struct linux_binprm *bprm)
+static Node *check_file(struct linux_binprm *bprm)
X {
- struct binfmt_entry *e;
X char *p = strrchr(bprm->filename, '.');
- int j;
+ struct list_head *l;
X
- e = entries;
- while (e) {
- if (e->flags & ENTRY_ENABLED) {
- if (!(e->flags & ENTRY_MAGIC)) {
- if (p && !strcmp(e->magic, p + 1))
- return e;
- } else {
- j = 0;
- while ((j < e->size) &&
- !((bprm->buf[e->offset + j] ^ e->magic[j])
- & (e->mask ? e->mask[j] : 0xff)))
- j++;
- if (j == e->size)
- return e;
- }
+ for (l = entries.next; l != &entries; l = l->next) {
+ Node *e = list_entry(l, Node, list);
+ char *s;
+ int j;
+
+ if (!test_bit(Enabled, &e->flags))
+ continue;
+
+ if (!test_bit(Magic, &e->flags)) {
+ if (p && !strcmp(e->magic, p + 1))
+ return e;
+ continue;
X }
- e = e->next;
- };
+
+ s = bprm->buf + e->offset;
+ if (e->mask) {
+ for (j = 0; j < e->size; j++)
+ if ((*s++ ^ e->magic[j]) & e->mask[j])
+ break;
+ } else {
+ for (j = 0; j < e->size; j++)
+ if ((*s++ ^ e->magic[j]))
+ break;
+ }
+ if (j == e->size)
+ return e;
+ }


X return NULL;
X }
X

@@ -180,7 +95,7 @@
X */
X static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
X {
- struct binfmt_entry *fmt;
+ Node *fmt;
X struct file * file;
X char iname[BINPRM_BUF_SIZE];
X char *iname_addr = iname;
@@ -228,11 +143,7 @@
X return retval;
X }
X
-
-
-/*
- * /proc handling routines
- */
+/* Command parsers */
X
X /*
X * parses and copies one argument enclosed in del from *sp to *dp,
@@ -240,34 +151,38 @@
X * returns pointer to the copied argument or NULL in case of an
X * error (and sets err) or null argument length.
X */
-static char *copyarg(char **dp, const char **sp, int *count,
- char del, int special, int *err)
+static char *scanarg(char *s, char del)
X {
- char c = 0, *res = *dp;
+ char c;
X
- while (!*err && ((c = *((*sp)++)), (*count)--) && (c != del)) {
- switch (c) {
- case '\\':
- if (special && (**sp == 'x')) {
- if (!isxdigit(c = toupper(*(++*sp))))
- *err = -EINVAL;
- **dp = (c - (isdigit(c) ? '0' : 'A' - 10)) * 16;
- if (!isxdigit(c = toupper(*(++*sp))))
- *err = -EINVAL;
- *((*dp)++) += c - (isdigit(c) ? '0' : 'A' - 10);
- ++*sp;
- *count -= 3;
- break;
- }
- default:
- *((*dp)++) = c;
+ while ((c = *s++) != del) {
+ if (c == '\\' && *s == 'x') {
+ s++;
+ if (!isxdigit(*s++))
+ return NULL;
+ if (!isxdigit(*s++))
+ return NULL;
X }
X }
- if (*err || (c != del) || (res == *dp))
- res = NULL;
- else if (!special)
- *((*dp)++) = '\0';
- return res;
+ return s;
+}
+
+static int unquote(char *from)
+{
+ char c = 0, *s = from, *p = from;
+
+ while ((c = *s++) != '\0') {
+ if (c == '\\' && *s == 'x') {
+ s++;
+ c = toupper(*s++);
+ *p = (c - (isdigit(c) ? '0' : 'A' - 10)) << 4;
+ c = toupper(*s++);
+ *p++ |= c - (isdigit(c) ? '0' : 'A' - 10);
+ continue;
+ }
+ *p++ = c;
+ }
+ return p - from;
X }
X
X /*
@@ -275,245 +190,533 @@
X * ':name:type:offset:magic:mask:interpreter:'
X * where the ':' is the IFS, that can be chosen with the first char
X */
-static int proc_write_register(struct file *file, const char *buffer,
- unsigned long count, void *data)
+static Node *create_entry(const char *buffer, size_t count)
X {
- const char *sp;
- char del, *dp;
- struct binfmt_entry *e;
- int memsize, cnt = count - 1, err;
+ Node *e;
+ int memsize, err;
+ char *buf, *p;
+ char del;
X
X /* some sanity checks */
X err = -EINVAL;
X if ((count < 11) || (count > 256))
- goto _err;
+ goto out;
X
X err = -ENOMEM;
- memsize = sizeof(struct binfmt_entry) + count;
- if (!(e = (struct binfmt_entry *) kmalloc(memsize, GFP_USER)))
- goto _err;
-
- err = 0;
- sp = buffer + 1;
- del = buffer[0];
- dp = (char *)e + sizeof(struct binfmt_entry);
-
- e->proc_name = copyarg(&dp, &sp, &cnt, del, 0, &err);
-
- /* we can use bit 3 of type for ext/magic
- flag due to the nice encoding of E and M */
- if ((*sp & ~('E' | 'M')) || (sp[1] != del))
- err = -EINVAL;
- else
- e->flags = (*sp++ & (ENTRY_MAGIC | ENTRY_ENABLED));
- cnt -= 2; sp++;
-
- e->offset = 0;
- while (cnt-- && isdigit(*sp))
- e->offset = e->offset * 10 + *sp++ - '0';
- if (*sp++ != del)
- err = -EINVAL;
-
- e->magic = copyarg(&dp, &sp, &cnt, del, (e->flags & ENTRY_MAGIC), &err);
- e->size = dp - e->magic;
- e->mask = copyarg(&dp, &sp, &cnt, del, 1, &err);
- if (e->mask && ((dp - e->mask) != e->size))
- err = -EINVAL;
- e->interpreter = copyarg(&dp, &sp, &cnt, del, 0, &err);
- e->id = free_id++;
-
- /* more sanity checks */
- if (err || !(!cnt || (!(--cnt) && (*sp == '\n'))) ||
- (e->size < 1) || ((e->size + e->offset) > (BINPRM_BUF_SIZE - 1)) ||
- !(e->proc_name) || !(e->interpreter) || entry_proc_setup(e))
- goto free_err;
+ memsize = sizeof(Node) + count + 8;
+ e = (Node *) kmalloc(memsize, GFP_USER);
+ if (!e)
+ goto out;
X
- write_lock(&entries_lock);
- e->next = entries;
- entries = e;
- write_unlock(&entries_lock);
+ p = buf = (char *)e + sizeof(Node);
X
- err = count;
-_err:
- return err;
-free_err:
+ memset(e, 0, sizeof(Node));
+ if (copy_from_user(buf, buffer, count))
+ goto Efault;
+
+ del = *p++; /* delimeter */
+
+ memset(buf+count, del, 8);
+
+ e->name = p;
+ p = strchr(p, del);
+ if (!p)
+ goto Einval;
+ *p++ = '\0';
+ if (!e->name[0] ||
+ !strcmp(e->name, ".") ||
+ !strcmp(e->name, "..") ||
+ strchr(e->name, '/'))
+ goto Einval;
+ switch (*p++) {
+ case 'E': e->flags = 1<<Enabled; break;
+ case 'M': e->flags = (1<<Enabled) | (1<<Magic); break;
+ default: goto Einval;
+ }
+ if (*p++ != del)
+ goto Einval;
+ if (test_bit(Magic, &e->flags)) {
+ char *s = strchr(p, del);
+ if (!s)
+ goto Einval;
+ *s++ = '\0';
+ e->offset = simple_strtoul(p, &p, 10);
+ if (*p++)
+ goto Einval;
+ e->magic = p;
+ p = scanarg(p, del);
+ if (!p)
+ goto Einval;
+ p[-1] = '\0';
+ if (!e->magic[0])
+ goto Einval;
+ e->mask = p;
+ p = scanarg(p, del);
+ if (!p)
+ goto Einval;
+ p[-1] = '\0';
+ if (!e->mask[0])
+ e->mask = NULL;
+ e->size = unquote(e->magic);
+ if (e->mask && unquote(e->mask) != e->size)
+ goto Einval;
+ if (e->size + e->offset > BINPRM_BUF_SIZE)
+ goto Einval;
+ } else {
+ p = strchr(p, del);
+ if (!p)
+ goto Einval;
+ *p++ = '\0';
+ e->magic = p;
+ p = strchr(p, del);
+ if (!p)
+ goto Einval;
+ *p++ = '\0';
+ if (!e->magic[0] || strchr(e->magic, '/'))
+ goto Einval;
+ p = strchr(p, del);
+ if (!p)
+ goto Einval;
+ *p++ = '\0';
+ }
+ e->interpreter = p;
+ p = strchr(p, del);
+ if (!p)
+ goto Einval;
+ *p++ = '\0';
+ if (!e->interpreter[0])
+ goto Einval;
+
+ if (*p == '\n')
+ p++;
+ if (p != buf + count)
+ goto Einval;
+ return e;
+
+out:
+ return ERR_PTR(err);
+
+Efault:
X kfree(e);
- err = -EINVAL;
- goto _err;
+ return ERR_PTR(-EFAULT);
+Einval:
+ kfree(e);
+ return ERR_PTR(-EINVAL);
X }
X
X /*
- * Get status of entry/binfmt_misc
- * FIXME? should an entry be marked disabled if binfmt_misc is disabled though
- * entry is enabled?
+ * Set status of entry/binfmt_misc:
+ * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
X */
-static int proc_read_status(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int parse_command(const char *buffer, size_t count)
+{
+ char s[4];
+
+ if (!count)
+ return 0;
+ if (count > 3)
+ return -EINVAL;
+ if (copy_from_user(s, buffer, count))
+ return -EFAULT;
+ if (s[count-1] == '\n')
+ count--;
+ if (count == 1 && s[0] == '0')
+ return 1;
+ if (count == 1 && s[0] == '1')
+ return 2;
+ if (count == 2 && s[0] == '-' && s[1] == '1')
+ return 3;


+ return -EINVAL;
+}
+

+/* generic stuff */
+
+static void entry_status(Node *e, char *page)
X {
- struct binfmt_entry *e;
X char *dp;
- int elen, i, err;
+ char *status = "disabled";
X
-#ifndef VERBOSE_STATUS
- if (data) {
- if (!(e = get_entry((int) data))) {
- err = -ENOENT;
- goto _err;
- }
- i = e->flags & ENTRY_ENABLED;
- put_entry(e);
+ if (test_bit(Enabled, &e->flags))
+ status = "enabled";
+
+ if (!VERBOSE_STATUS) {
+ sprintf(page, "%s\n", status);
+ return;
+ }
+
+ sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter);
+ dp = page + strlen(page);
+ if (!test_bit(Magic, &e->flags)) {
+ sprintf(dp, "extension .%s\n", e->magic);
X } else {
- i = enabled;
- }
- sprintf(page, "%s\n", (i ? "enabled" : "disabled"));
-#else
- if (!data)
- sprintf(page, "%s\n", (enabled ? "enabled" : "disabled"));
- else {
- if (!(e = get_entry((long) data))) {
- err = -ENOENT;
- goto _err;
- }
- sprintf(page, "%s\ninterpreter %s\n",
- (e->flags & ENTRY_ENABLED ? "enabled" : "disabled"),
- e->interpreter);
+ int i;
+
+ sprintf(dp, "offset %i\nmagic ", e->offset);
X dp = page + strlen(page);
- if (!(e->flags & ENTRY_MAGIC)) {
- sprintf(dp, "extension .%s\n", e->magic);
- dp = page + strlen(page);
- } else {
- sprintf(dp, "offset %i\nmagic ", e->offset);
- dp = page + strlen(page);
+ for (i = 0; i < e->size; i++) {
+ sprintf(dp, "%02x", 0xff & (int) (e->magic[i]));
+ dp += 2;
+ }
+ if (e->mask) {
+ sprintf(dp, "\nmask ");
+ dp += 6;
X for (i = 0; i < e->size; i++) {
- sprintf(dp, "%02x", 0xff & (int) (e->magic[i]));
+ sprintf(dp, "%02x", 0xff & (int) (e->mask[i]));
X dp += 2;
X }
- if (e->mask) {
- sprintf(dp, "\nmask ");
- dp += 6;
- for (i = 0; i < e->size; i++) {
- sprintf(dp, "%02x", 0xff & (int) (e->mask[i]));
- dp += 2;
- }
- }
- *dp++ = '\n';
- *dp = '\0';
X }
- put_entry(e);
+ *dp++ = '\n';
+ *dp = '\0';
X }
-#endif
+}
X
- elen = strlen(page) - off;
- if (elen < 0)
- elen = 0;
- *eof = (elen <= count) ? 1 : 0;
- *start = page + off;
- err = elen;
+static struct inode *bm_get_inode(struct super_block *sb, int mode)
+{
+ struct inode * inode = new_inode(sb);
X
-_err:
- return err;
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ }
+ return inode;
X }
X
-/*
- * Set status of entry/binfmt_misc:
- * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
- */
-static int proc_write_status(struct file *file, const char *buffer,
- unsigned long count, void *data)
+static void bm_clear_inode(struct inode *inode)
X {
- struct binfmt_entry *e;
- int res = count;
+ Node *e = inode->u.generic_ip;
X
- if (buffer[count-1] == '\n')
- count--;
- if ((count == 1) && !(buffer[0] & ~('0' | '1'))) {
- if (data) {
- if ((e = get_entry((long) data)))
- e->flags = (e->flags & ~ENTRY_ENABLED)
- | (int)(buffer[0] - '0');
- put_entry(e);
+ if (e) {
+ write_lock(&entries_lock);
+ list_del(&e->list);
+ write_unlock(&entries_lock);
+ kfree(e);
+ }
+}
+
+static void kill_node(Node *e)
+{
+ struct dentry *dentry;
+
+ write_lock(&entries_lock);
+ dentry = e->dentry;
+ if (dentry) {
+ list_del(&e->list);
+ INIT_LIST_HEAD(&e->list);
+ e->dentry = NULL;
+ }
+ write_unlock(&entries_lock);
+
+ if (dentry) {
+ dentry->d_inode->i_nlink--;
+ d_drop(dentry);
+ dput(dentry);
+ }
+}
+
+/* /<entry> */
+
+static ssize_t
+bm_entry_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+{
+ Node *e = file->f_dentry->d_inode->u.generic_ip;
+ loff_t pos = *ppos;
+ ssize_t res;
+ char *page;
+ int len;
+
+ if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ entry_status(e, page);
+ len = strlen(page);
+
+ res = -EINVAL;
+ if (pos < 0)
+ goto out;
+ res = 0;
+ if (pos >= len)
+ goto out;
+ if (len < pos + nbytes)
+ nbytes = len - pos;
+ res = -EFAULT;
+ if (copy_to_user(buf, page + pos, nbytes))
+ goto out;
+ *ppos = pos + nbytes;
+ res = nbytes;
+out:
+ free_page((unsigned long) page);
+ return res;
+}
+
+static ssize_t bm_entry_write(struct file *file, const char *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct dentry *root;
+ Node *e = file->f_dentry->d_inode->u.generic_ip;
+ int res = parse_command(buffer, count);
+
+ switch (res) {
+ case 1: clear_bit(Enabled, &e->flags);
+ break;
+ case 2: set_bit(Enabled, &e->flags);
+ break;
+ case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
+ down(&root->d_inode->i_sem);
+ down(&root->d_inode->i_zombie);
+
+ kill_node(e);
+
+ up(&root->d_inode->i_zombie);
+ up(&root->d_inode->i_sem);
+ dput(root);
+ break;
+ default: return res;


+ }
+ return count;
+}
+

+static struct file_operations bm_entry_operations = {
+ read: bm_entry_read,
+ write: bm_entry_write,
+};
+
+/* /register */
+
+static ssize_t bm_register_write(struct file *file, const char *buffer,
+ size_t count, loff_t *ppos)
+{
+ Node *e;
+ struct dentry *root, *dentry;
+ struct super_block *sb = file->f_vfsmnt->mnt_sb;


+ int err = 0;
+

+ e = create_entry(buffer, count);
+
+ if (IS_ERR(e))
+ return PTR_ERR(e);
+
+ root = dget(sb->s_root);
+ down(&root->d_inode->i_sem);
+ dentry = lookup_one_len(e->name, root, strlen(e->name));
+ err = PTR_ERR(dentry);
+ if (!IS_ERR(dentry)) {
+ down(&root->d_inode->i_zombie);
+ if (dentry->d_inode) {
+ err = -EEXIST;
X } else {
- enabled = buffer[0] - '0';
+ struct inode * inode = bm_get_inode(sb, S_IFREG | 0644);
+ err = -ENOMEM;
+
+ if (inode) {
+ write_lock(&entries_lock);
+
+ e->dentry = dget(dentry);
+ inode->u.generic_ip = e;
+ inode->i_fop = &bm_entry_operations;
+ d_instantiate(dentry, inode);
+
+ list_add(&e->list, &entries);
+ write_unlock(&entries_lock);
+
+ err = 0;
+ }
X }
- } else if ((count == 2) && (buffer[0] == '-') && (buffer[1] == '1')) {
- if (data)
- clear_entry((long) data);
- else
- clear_entries();
- } else {
- res = -EINVAL;
+ up(&root->d_inode->i_zombie);
+ dput(dentry);
X }
- return res;
+ up(&root->d_inode->i_sem);
+ dput(root);
+
+ if (err) {
+ kfree(e);
+ return -EINVAL;
+ }
+ return count;
X }
X
-/*
- * Remove the /proc-dir entries of one binfmt
- */
-static void entry_proc_cleanup(struct binfmt_entry *e)
+static struct file_operations bm_register_operations = {
+ write: bm_register_write,
+};
+
+/* /status */
+
+static ssize_t
+bm_status_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
X {
- remove_proc_entry(e->proc_name, bm_dir);
+ char *s = enabled ? "enabled" : "disabled";
+ int len = strlen(s);
+ loff_t pos = *ppos;
+
+ if (pos < 0)
+ return -EINVAL;
+ if (pos >= len)
+ return 0;
+ if (len < pos + nbytes)
+ nbytes = len - pos;
+ if (copy_to_user(buf, s + pos, nbytes))
+ return -EFAULT;
+ *ppos = pos + nbytes;
+ return nbytes;
+}
+
+static ssize_t bm_status_write(struct file * file, const char * buffer,
+ size_t count, loff_t *ppos)
+{
+ int res = parse_command(buffer, count);
+ struct dentry *root;
+
+ switch (res) {
+ case 1: enabled = 0; break;
+ case 2: enabled = 1; break;
+ case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
+ down(&root->d_inode->i_sem);
+ down(&root->d_inode->i_zombie);
+
+ while (!list_empty(&entries))
+ kill_node(list_entry(entries.next, Node, list));
+
+ up(&root->d_inode->i_zombie);
+ up(&root->d_inode->i_sem);
+ dput(root);
+ default: return res;
+ }
+ return count;
X }
X
-/*
- * Create the /proc-dir entry for binfmt
- */
-static int entry_proc_setup(struct binfmt_entry *e)
+static struct file_operations bm_status_operations = {
+ read: bm_status_read,
+ write: bm_status_write,
+};
+
+/* / */
+
+static struct dentry * bm_lookup(struct inode *dir, struct dentry *dentry)
+{
+ d_add(dentry, NULL);


+ return NULL;
+}
+

+static struct file_operations bm_dir_operations = {
+ read: generic_read_dir,
+ readdir: dcache_readdir,
+};
+
+static struct inode_operations bm_dir_inode_operations = {
+ lookup: bm_lookup,
+};
+
+/* Superblock handling */
+
+static int bm_statfs(struct super_block *sb, struct statfs *buf)
X {
- if (!(e->proc_dir = create_proc_entry(e->proc_name,
- S_IFREG | S_IRUGO | S_IWUSR, bm_dir)))
- {
- printk(KERN_WARNING "Unable to create /proc entry.\n");
- return -ENOENT;
- }
- e->proc_dir->data = (void *) (e->id);
- e->proc_dir->read_proc = proc_read_status;
- e->proc_dir->write_proc = proc_write_status;
+ buf->f_type = sb->s_magic;
+ buf->f_bsize = PAGE_CACHE_SIZE;
+ buf->f_namelen = 255;


X return 0;
X }
X

-static int __init init_misc_binfmt(void)
+static struct super_operations s_ops = {
+ statfs: bm_statfs,
+ put_inode: force_delete,
+ clear_inode: bm_clear_inode,
+};
+
+static struct super_block *bm_read_super(struct super_block * sb, void * data, int silent)
X {
- int error = -ENOENT;
- struct proc_dir_entry *status = NULL, *reg;
+ struct qstr names[2] = {{name:"status"}, {name:"register"}};
+ struct inode * inode;
+ struct dentry * dentry[3];
+ int i;
+
+ for (i=0; i<sizeof(names)/sizeof(names[0]); i++) {
+ names[i].len = strlen(names[i].name);
+ names[i].hash = full_name_hash(names[i].name, names[i].len);
+ }
X
- bm_dir = proc_mkdir("sys/fs/binfmt_misc", NULL); /* WTF??? */
- if (!bm_dir)
- goto out;
- bm_dir->owner = THIS_MODULE;
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = 0x42494e4d;
+ sb->s_op = &s_ops;
+
+ inode = bm_get_inode(sb, S_IFDIR | 0755);
+ if (!inode)
+ return NULL;
+ inode->i_op = &bm_dir_inode_operations;
+ inode->i_fop = &bm_dir_operations;
+ dentry[0] = d_alloc_root(inode);
+ if (!dentry[0]) {
+ iput(inode);
+ return NULL;
+ }
+ dentry[1] = d_alloc(dentry[0], &names[0]);
+ if (!dentry[1])
+ goto out1;
+ dentry[2] = d_alloc(dentry[0], &names[1]);
+ if (!dentry[2])
+ goto out2;
+ inode = bm_get_inode(sb, S_IFREG | 0644);
+ if (!inode)
+ goto out3;
+ inode->i_fop = &bm_status_operations;
+ d_add(dentry[1], inode);
+ inode = bm_get_inode(sb, S_IFREG | 0400);
+ if (!inode)
+ goto out3;
+ inode->i_fop = &bm_register_operations;
+ d_add(dentry[2], inode);
+
+ sb->s_root = dentry[0];
+ return sb;
+
+out3:
+ dput(dentry[2]);
+out2:
+ dput(dentry[1]);
+out1:
+ dput(dentry[0]);


+ return NULL;
+}
+

+static struct linux_binfmt misc_format = {
+ NULL, THIS_MODULE, load_misc_binary, NULL, NULL, 0
+};
X
- status = create_proc_entry("status", S_IFREG | S_IRUGO | S_IWUSR,
- bm_dir);
- if (!status)
- goto cleanup_bm;
- status->read_proc = proc_read_status;
- status->write_proc = proc_write_status;
-
- reg = create_proc_entry("register", S_IFREG | S_IWUSR, bm_dir);
- if (!reg)
- goto cleanup_status;
- reg->write_proc = proc_write_register;
+static DECLARE_FSTYPE(bm_fs_type, "binfmt_misc", bm_read_super, FS_SINGLE|FS_LITTER);
X
- error = register_binfmt(&misc_format);
-out:
- return error;
+static struct vfsmount *bm_mnt;
X
-cleanup_status:
- remove_proc_entry("status", bm_dir);
-cleanup_bm:
- remove_proc_entry("sys/fs/binfmt_misc", NULL);
- goto out;
+static int __init init_misc_binfmt(void)
+{
+ int err = register_filesystem(&bm_fs_type);
+ if (!err) {
+ bm_mnt = kern_mount(&bm_fs_type);
+ err = PTR_ERR(bm_mnt);
+ if (IS_ERR(bm_mnt))
+ unregister_filesystem(&bm_fs_type);
+ else {
+ err = register_binfmt(&misc_format);
+ if (err) {
+ unregister_filesystem(&bm_fs_type);
+ kern_umount(bm_mnt);
+ }
+ }
+ }
+ return err;
X }
X
X static void __exit exit_misc_binfmt(void)
X {
X unregister_binfmt(&misc_format);
- remove_proc_entry("register", bm_dir);
- remove_proc_entry("status", bm_dir);
- clear_entries();
- remove_proc_entry("sys/fs/binfmt_misc", NULL);
+ unregister_filesystem(&bm_fs_type);
+ kern_umount(bm_mnt);
X }
X
X EXPORT_NO_SYMBOLS;
X
X module_init(init_misc_binfmt);
X module_exit(exit_misc_binfmt);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.4.12/linux/fs/block_dev.c Tue Oct 9 17:06:53 2001
+++ linux/fs/block_dev.c Thu Oct 11 08:32:35 2001
@@ -24,29 +24,6 @@
X
X #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
X
-static inline unsigned int blksize_bits(unsigned int size)
-{
- unsigned int bits = 8;
- do {
- bits++;
- size >>= 1;
- } while (size > 256);
- return bits;
-}
-
-static inline unsigned int block_size(kdev_t dev)
-{
- int retval = BLOCK_SIZE;
- int major = MAJOR(dev);
-
- if (blksize_size[major]) {
- int minor = MINOR(dev);
- if (blksize_size[major][minor])
- retval = blksize_size[major][minor];
- }
- return retval;
-}
-
X static unsigned long max_block(kdev_t dev)
X {
X unsigned int retval = ~0U;
diff -u --recursive --new-file v2.4.12/linux/fs/buffer.c linux/fs/buffer.c
--- v2.4.12/linux/fs/buffer.c Tue Oct 9 17:06:53 2001
+++ linux/fs/buffer.c Tue Oct 23 17:54:19 2001
@@ -112,15 +112,16 @@
X int dummy5; /* unused */
X } b_un;
X unsigned int data[N_PARAM];
-} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}};
+} bdf_prm = {{40, 0, 0, 0, 5*HZ, 30*HZ, 60, 0, 0}};
X
X /* These are the min and max parameter values that we will allow to be assigned */
X int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 0, 0, 0};
X int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 6000*HZ, 100, 0, 0};
X
-inline void unlock_buffer(struct buffer_head *bh)
+void unlock_buffer(struct buffer_head *bh)
X {
X clear_bit(BH_Wait_IO, &bh->b_state);
+ clear_bit(BH_launder, &bh->b_state);
X clear_bit(BH_Lock, &bh->b_state);
X smp_mb__after_clear_bit();
X if (waitqueue_active(&bh->b_wait))
@@ -480,10 +481,12 @@
X
X static __inline__ void __hash_unlink(struct buffer_head *bh)
X {
- if (bh->b_pprev) {
- if (bh->b_next)
- bh->b_next->b_pprev = bh->b_pprev;
- *(bh->b_pprev) = bh->b_next;
+ struct buffer_head **pprev = bh->b_pprev;
+ if (pprev) {
+ struct buffer_head *next = bh->b_next;
+ if (next)
+ next->b_pprev = pprev;
+ *pprev = next;
X bh->b_pprev = NULL;
X }
X }
@@ -506,16 +509,22 @@
X size_buffers_type[blist] += bh->b_size;
X }
X
-static void __remove_from_lru_list(struct buffer_head * bh, int blist)
+static void __remove_from_lru_list(struct buffer_head * bh)
X {
- if (bh->b_prev_free || bh->b_next_free) {
- bh->b_prev_free->b_next_free = bh->b_next_free;
- bh->b_next_free->b_prev_free = bh->b_prev_free;
- if (lru_list[blist] == bh)
- lru_list[blist] = bh->b_next_free;
- if (lru_list[blist] == bh)
- lru_list[blist] = NULL;
- bh->b_next_free = bh->b_prev_free = NULL;
+ struct buffer_head *next = bh->b_next_free;
+ if (next) {
+ struct buffer_head *prev = bh->b_prev_free;
+ int blist = bh->b_list;
+
+ prev->b_next_free = next;
+ next->b_prev_free = prev;
+ if (lru_list[blist] == bh) {
+ if (next == bh)
+ next = NULL;
+ lru_list[blist] = next;
+ }
+ bh->b_next_free = NULL;
+ bh->b_prev_free = NULL;
X nr_buffers_type[blist]--;
X size_buffers_type[blist] -= bh->b_size;
X }
@@ -526,7 +535,7 @@
X static void __remove_from_queues(struct buffer_head *bh)
X {
X __hash_unlink(bh);
- __remove_from_lru_list(bh, bh->b_list);
+ __remove_from_lru_list(bh);
X }
X
X struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
@@ -1095,7 +1104,7 @@
X if (buffer_dirty(bh))
X dispose = BUF_DIRTY;
X if (dispose != bh->b_list) {
- __remove_from_lru_list(bh, bh->b_list);
+ __remove_from_lru_list(bh);
X bh->b_list = dispose;
X if (dispose == BUF_CLEAN)
X remove_inode_queue(bh);
@@ -1123,13 +1132,12 @@
X }
X
X /*
- * bforget() is like brelse(), except it puts the buffer on the
- * free list if it can.. We can NOT free the buffer if:
- * - there are other users of it
- * - it is locked and thus can have active IO
+ * bforget() is like brelse(), except it discards any
+ * potentially dirty data.
X */
X void __bforget(struct buffer_head * buf)
X {
+ mark_buffer_clean(buf);
X __brelse(buf);
X }
X
@@ -1422,10 +1430,7 @@
X mark_buffer_clean(old_bh);
X wait_on_buffer(old_bh);
X clear_bit(BH_Req, &old_bh->b_state);
- /* Here we could run brelse or bforget. We use
- bforget because it will try to put the buffer
- in the freelist. */
- __bforget(old_bh);
+ __brelse(old_bh);
X }
X }
X
@@ -2327,29 +2332,40 @@


X return 1;
X }
X

-static int sync_page_buffers(struct buffer_head *bh, unsigned int gfp_mask)
+static int sync_page_buffers(struct buffer_head *head, unsigned int gfp_mask)
X {
- struct buffer_head * p = bh;
- int tryagain = 1;
+ struct buffer_head * bh = head;
+ int tryagain = 0;
X
X do {
- if (buffer_dirty(p) || buffer_locked(p)) {
- if (test_and_set_bit(BH_Wait_IO, &p->b_state)) {
- if (buffer_dirty(p)) {
- ll_rw_block(WRITE, 1, &p);
- tryagain = 0;
- } else if (buffer_locked(p)) {
- if (gfp_mask & __GFP_WAITBUF) {
- wait_on_buffer(p);
- tryagain = 1;
- } else
- tryagain = 0;
- }
- } else
- tryagain = 0;
+ if (!buffer_dirty(bh) && !buffer_locked(bh))
+ continue;
+
+ /* Don't start IO first time around.. */
+ if (!test_and_set_bit(BH_Wait_IO, &bh->b_state))
+ continue;
+
+ /* Second time through we start actively writing out.. */
+ if (test_and_set_bit(BH_Lock, &bh->b_state)) {
+ if (!test_bit(BH_launder, &bh->b_state))
+ continue;
+ wait_on_buffer(bh);
+ tryagain = 1;
+ continue;
+ }
+
+ if (!atomic_set_buffer_clean(bh)) {
+ unlock_buffer(bh);
+ continue;
X }
- p = p->b_this_page;
- } while (p != bh);
+
+ __mark_buffer_clean(bh);
+ get_bh(bh);
+ set_bit(BH_launder, &bh->b_state);
+ bh->b_end_io = end_buffer_io_sync;
+ submit_bh(WRITE, bh);
+ tryagain = 0;
+ } while ((bh = bh->b_this_page) != head);
X
X return tryagain;
X }
diff -u --recursive --new-file v2.4.12/linux/fs/devfs/util.c linux/fs/devfs/util.c
--- v2.4.12/linux/fs/devfs/util.c Sun Sep 23 11:41:00 2001
+++ linux/fs/devfs/util.c Thu Oct 11 09:43:30 2001
@@ -52,7 +52,7 @@


X #include <linux/module.h>
X #include <linux/init.h>

X #include <linux/devfs_fs_kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
X #include <linux/vmalloc.h>
X
X #include <asm/bitops.h>
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/Makefile linux/fs/ext2/Makefile
--- v2.4.12/linux/fs/ext2/Makefile Fri Dec 29 14:07:23 2000
+++ linux/fs/ext2/Makefile Thu Oct 11 08:05:18 2001


@@ -9,7 +9,7 @@
X

X O_TARGET := ext2.o
X
-obj-y := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
X ioctl.o namei.o super.o symlink.o
X obj-m := $(O_TARGET)
X
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/acl.c linux/fs/ext2/acl.c
--- v2.4.12/linux/fs/ext2/acl.c Tue Dec 14 11:16:22 1999
+++ linux/fs/ext2/acl.c Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-/*
- * linux/fs/ext2/acl.c
- *
- * Copyright (C) 1993, 1994, 1995
- * Remy Card (ca...@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- */
-
-#include <linux/fs.h>
-#include <linux/sched.h>
-
-
-/*
- * This file will contain the Access Control Lists management for the
- * second extended file system.
- */
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.4.12/linux/fs/ext2/file.c Wed Jul 25 17:10:24 2001
+++ linux/fs/ext2/file.c Thu Oct 11 08:05:18 2001
@@ -22,51 +22,6 @@
X #include <linux/ext2_fs.h>
X #include <linux/sched.h>
X
-static loff_t ext2_file_lseek(struct file *, loff_t, int);
-static int ext2_open_file (struct inode *, struct file *);
-
-#define EXT2_MAX_SIZE(bits) \
- (((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + \
- (1LL << (bits - 2)) * (1LL << (bits - 2)) + \
- (1LL << (bits - 2)) * (1LL << (bits - 2)) * (1LL << (bits - 2))) * \
- (1LL << bits)) - 1)
-
-static long long ext2_max_sizes[] = {
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
-};
-
-/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static loff_t ext2_file_lseek(
- struct file *file,
- loff_t offset,
- int origin)
-{
- struct inode *inode = file->f_dentry->d_inode;
-
- switch (origin) {
- case 2:
- offset += inode->i_size;


- break;
- case 1:

- offset += file->f_pos;
- }
- if (offset<0)
- return -EINVAL;
- if (((unsigned long long) offset >> 32) != 0) {
- if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
- return -EINVAL;
- }
- if (offset != file->f_pos) {
- file->f_pos = offset;
- file->f_reada = 0;
- file->f_version = ++event;
- }
- return offset;
-}
-
X /*
X * Called when an inode is released. Note that this is different
X * from ext2_open_file: open gets called at every open, but release
@@ -80,30 +35,16 @@
X }
X
X /*
- * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE. On 64bit systems we force
- * on this flag in sys_open.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
- if (!(filp->f_flags & O_LARGEFILE) &&
- inode->i_size > 0x7FFFFFFFLL)
- return -EFBIG;


- return 0;
-}
-
-/*

X * We have mostly NULL's here: the current defaults are ok for
X * the ext2 filesystem.
X */
X struct file_operations ext2_file_operations = {
- llseek: ext2_file_lseek,
+ llseek: generic_file_llseek,
X read: generic_file_read,
X write: generic_file_write,
X ioctl: ext2_ioctl,
X mmap: generic_file_mmap,
- open: ext2_open_file,
+ open: generic_file_open,
X release: ext2_release_file,
X fsync: ext2_sync_file,
X };
diff -u --recursive --new-file v2.4.12/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.12/linux/fs/ext2/inode.c Thu Oct 11 08:02:26 2001
+++ linux/fs/ext2/inode.c Thu Oct 11 09:43:38 2001
@@ -29,6 +29,12 @@
X #include <linux/sched.h>
X #include <linux/highuid.h>
X #include <linux/quotaops.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Remy Card and others");
+MODULE_DESCRIPTION("Second Extended Filesystem");


+MODULE_LICENSE("GPL");
+
X

X static int ext2_update_inode(struct inode * inode, int do_sync);
X
@@ -592,7 +598,7 @@
X sync_page: block_sync_page,
X prepare_write: ext2_prepare_write,
X commit_write: generic_commit_write,
- bmap: ext2_bmap,
+ bmap: ext2_bmap
X };
X
X /*
diff -u --recursive --new-file v2.4.12/linux/fs/fat/cache.c linux/fs/fat/cache.c
--- v2.4.12/linux/fs/fat/cache.c Thu May 24 15:36:33 2001
+++ linux/fs/fat/cache.c Fri Oct 12 13:48:42 2001
@@ -15,8 +15,6 @@
X #include <linux/stat.h>
X #include <linux/fat_cvf.h>
X
-#include "msbuffer.h"
-
X #if 0
X # define PRINTK(x) printk x
X #else
diff -u --recursive --new-file v2.4.12/linux/fs/fat/dir.c linux/fs/fat/dir.c
--- v2.4.12/linux/fs/fat/dir.c Mon Aug 27 12:41:46 2001
+++ linux/fs/fat/dir.c Fri Oct 12 13:48:42 2001
@@ -10,12 +10,9 @@
X * VFAT extensions by Gordon Chaffee <cha...@plateau.cs.berkeley.edu>
X * Merged with msdos fs by Henrik Storner <sto...@osiris.ping.dk>
X * Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV
- * Short name translation 1999 by Wolfram Pienkoss <w...@bszh.de>
+ * Short name translation 1999, 2001 by Wolfram Pienkoss <w...@bszh.de>
X */
X
-#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
-
-#include <linux/version.h>
X #include <linux/fs.h>
X #include <linux/msdos_fs.h>
X #include <linux/nls.h>
@@ -30,8 +27,6 @@
X
X #include <asm/uaccess.h>
X
-#include "msbuffer.h"
-
X #define PRINTK(X)
X
X struct file_operations fat_dir_operations = {
@@ -163,6 +158,27 @@


X return 0;
X }
X

+static inline int
+fat_shortname2uni(struct nls_table *nls, char *buf, int buf_size,
+ wchar_t *uni_buf, unsigned short opt, int lower)
+{


+ int len = 0;
+

+ if (opt & VFAT_SFN_DISPLAY_LOWER)
+ len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
+ else if (opt & VFAT_SFN_DISPLAY_WIN95)
+ len = fat_short2uni(nls, buf, buf_size, uni_buf);
+ else if (opt & VFAT_SFN_DISPLAY_WINNT) {
+ if (lower)
+ len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
+ else
+ len = fat_short2uni(nls, buf, buf_size, uni_buf);
+ } else
+ len = fat_short2uni(nls, buf, buf_size, uni_buf);


+
+ return len;
+}

+
X /*
X * Return values: negative -> error, 0 -> not found, positive -> found,
X * value is the total amount of slots, including the shortname entry.
@@ -176,11 +192,12 @@
X struct nls_table *nls_io = MSDOS_SB(sb)->nls_io;
X struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk;
X wchar_t bufuname[14];
- unsigned char xlate_len, long_slots, *unicode = NULL;
+ unsigned char xlate_len, long_slots;
+ wchar_t *unicode = NULL;
X char work[8], bufname[260]; /* 256 + 4 */
X int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
X int utf8 = MSDOS_SB(sb)->options.utf8;
- int nocase = MSDOS_SB(sb)->options.nocase;
+ unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;
X int ino, chl, i, j, last_u, res = 0;
X loff_t cpos = 0;
X
@@ -197,7 +214,6 @@
X continue;
X if (de->attr == ATTR_EXT) {
X struct msdos_dir_slot *ds;
- int offset;
X unsigned char id;
X unsigned char slot;
X unsigned char slots;
@@ -205,7 +221,7 @@
X unsigned char alias_checksum;
X
X if (!unicode) {
- unicode = (unsigned char *)
+ unicode = (wchar_t *)
X __get_free_page(GFP_KERNEL);
X if (!unicode) {
X fat_brelse(sb, bh);
@@ -214,7 +230,6 @@
X }
X parse_long:
X slots = 0;
- offset = 0;
X ds = (struct msdos_dir_slot *) de;
X id = ds->id;
X if (!(id & 0x40))
@@ -227,16 +242,16 @@
X
X slot = slots;
X while (1) {
+ int offset;
+
X slot--;
- offset = slot * 26;
- memcpy(&unicode[offset], ds->name0_4, 10);
- memcpy(&unicode[offset+10], ds->name5_10, 12);
- memcpy(&unicode[offset+22], ds->name11_12, 4);
- offset += 26;
+ offset = slot * 13;
+ fat16_towchar(unicode + offset, ds->name0_4, 5);
+ fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
+ fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
X
X if (ds->id & 0x40) {


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 41'
echo 'File patch-2.4.13 is continued in part 42'
echo "42" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:12 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part42

#!/bin/sh -x
# this is part 42 of a 53 - part archive


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

if test "$Scheck" != 42; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

- unicode[offset] = 0;
- unicode[offset+1] = 0;
+ unicode[offset + 13] = 0;
X }
X if (fat_get_entry(inode,&cpos,&bh,&de,&ino)<0)
X goto EODir;
@@ -271,10 +286,9 @@
X }
X for (i = 0, j = 0, last_u = 0; i < 8;) {
X if (!work[i]) break;
- if (nocase)
- chl = fat_short2uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
- else
- chl = fat_short2lower_uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+ chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
+ &bufuname[j++], opt_shortname,
+ de->lcase & CASE_LOWER_BASE);
X if (chl <= 1) {
X if (work[i] != ' ')
X last_u = j;
@@ -287,10 +301,9 @@
X fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
X for (i = 0; i < 3;) {
X if (!de->ext[i]) break;
- if (nocase)
- chl = fat_short2uni(nls_disk, &de->ext[i], 3 - i, &bufuname[j++]);
- else
- chl = fat_short2lower_uni(nls_disk, &de->ext[i], 3 - i, &bufuname[j++]);
+ chl = fat_shortname2uni(nls_disk, &de->ext[i], 3 - i,
+ &bufuname[j++], opt_shortname,
+ de->lcase & CASE_LOWER_EXT);
X if (chl <= 1) {
X if (de->ext[i] != ' ')
X last_u = j;
@@ -314,8 +327,8 @@
X
X if (long_slots) {
X xlate_len = utf8
- ?utf8_wcstombs(bufname, (wchar_t *) unicode, sizeof(bufname))
- :uni16_to_x8(bufname, (wchar_t *) unicode, uni_xlate, nls_io);
+ ?utf8_wcstombs(bufname, unicode, sizeof(bufname))
+ :uni16_to_x8(bufname, unicode, uni_xlate, nls_io);
X if (xlate_len != name_len)
X continue;
X if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
@@ -346,13 +359,15 @@


X struct nls_table *nls_io = MSDOS_SB(sb)->nls_io;
X struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk;
X wchar_t bufuname[14];

- unsigned char long_slots, *unicode = NULL;
+ unsigned char long_slots;


+ wchar_t *unicode = NULL;

X char c, work[8], bufname[56], *ptname = bufname;
X unsigned long lpos, dummy, *furrfu = &lpos;


X int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;

X int isvfat = MSDOS_SB(sb)->options.isvfat;


X int utf8 = MSDOS_SB(sb)->options.utf8;

X int nocase = MSDOS_SB(sb)->options.nocase;


+ unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;

X int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0;
X loff_t cpos;
X
@@ -394,7 +409,6 @@
X
X if (isvfat && de->attr == ATTR_EXT) {


X struct msdos_dir_slot *ds;
- int offset;
X unsigned char id;
X unsigned char slot;
X unsigned char slots;

@@ -402,7 +416,7 @@


X unsigned char alias_checksum;
X
X if (!unicode) {
- unicode = (unsigned char *)
+ unicode = (wchar_t *)
X __get_free_page(GFP_KERNEL);
X if (!unicode) {

X filp->f_pos = cpos;
@@ -412,7 +426,6 @@
X }
X ParseLong:


X slots = 0;
- offset = 0;
X ds = (struct msdos_dir_slot *) de;
X id = ds->id;
X if (!(id & 0x40))

@@ -425,16 +438,16 @@


X
X slot = slots;
X while (1) {
+ int offset;
+
X slot--;
- offset = slot * 26;
- memcpy(&unicode[offset], ds->name0_4, 10);
- memcpy(&unicode[offset+10], ds->name5_10, 12);
- memcpy(&unicode[offset+22], ds->name11_12, 4);
- offset += 26;
+ offset = slot * 13;
+ fat16_towchar(unicode + offset, ds->name0_4, 5);
+ fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
+ fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
X
X if (ds->id & 0x40) {

- unicode[offset] = 0;
- unicode[offset+1] = 0;
+ unicode[offset + 13] = 0;
X }
X if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1)
X goto EODir;
@@ -474,10 +487,9 @@
X }
X for (i = 0, j = 0, last = 0, last_u = 0; i < 8;) {
X if (!(c = work[i])) break;
- if (nocase)
- chl = fat_short2uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
- else
- chl = fat_short2lower_uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+ chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
+ &bufuname[j++], opt_shortname,
+ de->lcase & CASE_LOWER_BASE);
X if (chl <= 1) {
X ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
X if (c != ' ') {
@@ -498,10 +510,9 @@
X ptname[i++] = '.';
X for (i2 = 0; i2 < 3;) {
X if (!(c = de->ext[i2])) break;
- if (nocase)
- chl = fat_short2uni(nls_disk, &de->ext[i2], 3 - i2, &bufuname[j++]);
- else
- chl = fat_short2lower_uni(nls_disk, &de->ext[i2], 3 - i2, &bufuname[j++]);
+ chl = fat_shortname2uni(nls_disk, &de->ext[i2], 3 - i2,
+ &bufuname[j++], opt_shortname,
+ de->lcase & CASE_LOWER_EXT);
X if (chl <= 1) {
X i2++;
X ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
@@ -553,8 +564,8 @@
X } else {
X char longname[275];
X int long_len = utf8
- ? utf8_wcstombs(longname, (wchar_t *) unicode, sizeof(longname))
- : uni16_to_x8(longname, (wchar_t *) unicode, uni_xlate,
+ ? utf8_wcstombs(longname, unicode, sizeof(longname))
+ : uni16_to_x8(longname, unicode, uni_xlate,
X nls_io);
X if (both) {
X memcpy(&longname[long_len+1], bufname, i);
diff -u --recursive --new-file v2.4.12/linux/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c
--- v2.4.12/linux/fs/fat/fatfs_syms.c Wed Apr 18 11:49:12 2001
+++ linux/fs/fat/fatfs_syms.c Fri Oct 12 13:48:42 2001
@@ -4,8 +4,7 @@
X * Exported kernel symbols for the low-level FAT-based fs support.
X *
X */


-#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))

-#include <linux/version.h>
+


X #include <linux/module.h>
X #include <linux/init.h>
X

@@ -13,8 +12,6 @@
X #include <linux/msdos_fs.h>


X #include <linux/fat_cvf.h>
X
-#include "msbuffer.h"
-

X EXPORT_SYMBOL(fat_new_dir);
X EXPORT_SYMBOL(fat_get_block);
X EXPORT_SYMBOL(fat_clear_inode);
@@ -23,7 +20,6 @@
X EXPORT_SYMBOL(fat__get_entry);
X EXPORT_SYMBOL(fat_mark_buffer_dirty);
X EXPORT_SYMBOL(fat_notify_change);
-EXPORT_SYMBOL(fat_parent_ino);
X EXPORT_SYMBOL(fat_put_super);
X EXPORT_SYMBOL(fat_attach);
X EXPORT_SYMBOL(fat_detach);
diff -u --recursive --new-file v2.4.12/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.4.12/linux/fs/fat/inode.c Sun Sep 23 11:41:00 2001
+++ linux/fs/fat/inode.c Fri Oct 12 13:48:42 2001
@@ -10,17 +10,14 @@
X * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0


X */
X
-#include <linux/config.h>

-#include <linux/version.h>
-#define __NO_VERSION__
X #include <linux/module.h>
-


X #include <linux/msdos_fs.h>
X #include <linux/nls.h>

X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/errno.h>
X #include <linux/string.h>
+#include <linux/bitops.h>
X #include <linux/major.h>
X #include <linux/blkdev.h>
X #include <linux/fs.h>
@@ -28,11 +25,8 @@
X #include <linux/locks.h>
X #include <linux/fat_cvf.h>
X #include <linux/slab.h>
-#include <linux/bitops.h>
X #include <linux/smp_lock.h>
X
-#include "msbuffer.h"
-
X #include <asm/uaccess.h>
X #include <asm/unaligned.h>
X
@@ -81,9 +75,10 @@
X static struct list_head fat_inode_hashtable[FAT_HASH_SIZE];
X spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
X
-void fat_hash_init(void) {
+void fat_hash_init(void)
+{
X int i;
- for(i=0;i<FAT_HASH_SIZE;i++) {
+ for(i = 0; i < FAT_HASH_SIZE; i++) {
X INIT_LIST_HEAD(&fat_inode_hashtable[i]);
X }
X }
@@ -91,19 +86,21 @@
X static inline unsigned long fat_hash(struct super_block *sb, int i_pos)
X {
X unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
- tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS*2);
+ tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2);
X return tmp & FAT_HASH_MASK;
X }
X
-void fat_attach(struct inode *inode, int i_pos) {
+void fat_attach(struct inode *inode, int i_pos)
+{
X spin_lock(&fat_inode_lock);
X MSDOS_I(inode)->i_location = i_pos;
X list_add(&MSDOS_I(inode)->i_fat_hash,
- fat_inode_hashtable+fat_hash(inode->i_sb, i_pos));
+ fat_inode_hashtable + fat_hash(inode->i_sb, i_pos));
X spin_unlock(&fat_inode_lock);
X }
X
-void fat_detach(struct inode *inode) {
+void fat_detach(struct inode *inode)
+{
X spin_lock(&fat_inode_lock);
X MSDOS_I(inode)->i_location = 0;
X list_del(&MSDOS_I(inode)->i_fat_hash);
@@ -111,13 +108,15 @@
X spin_unlock(&fat_inode_lock);
X }
X
-struct inode *fat_iget(struct super_block *sb, int i_pos) {
+struct inode *fat_iget(struct super_block *sb, int i_pos)
+{
X struct list_head *p = fat_inode_hashtable + fat_hash(sb, i_pos);
X struct list_head *walk;
X struct msdos_inode_info *i;
X struct inode *inode = NULL;
+
X spin_lock(&fat_inode_lock);
- for(walk=p->next;walk!=p;walk=walk->next) {
+ list_for_each(walk, p) {
X i = list_entry(walk, struct msdos_inode_info, i_fat_hash);
X if (i->i_fat_inode->i_sb != sb)
X continue;
@@ -222,6 +221,7 @@
X opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = 0;
X opts->codepage = 0;
X opts->nocase = 0;
+ opts->shortname = 0;
X opts->utf8 = 0;
X opts->iocharset = NULL;
X *debug = *fat = 0;
@@ -330,16 +330,22 @@
X }
X else if (!strcmp(this_char,"iocharset") && value) {
X p = value;
- while (*value && *value != ',') value++;
+ while (*value && *value != ',')
+ value++;
X len = value - p;
- if (len) {
- char * buffer = kmalloc(len+1, GFP_KERNEL);
- if (buffer) {
+ if (len) {
+ char *buffer;
+
+ if (opts->iocharset != NULL) {
+ kfree(opts->iocharset);
+ opts->iocharset = NULL;
+ }
+ buffer = kmalloc(len + 1, GFP_KERNEL);
+ if (buffer != NULL) {
X opts->iocharset = buffer;
X memcpy(buffer, p, len);
X buffer[len] = 0;
- printk("MSDOS FS: IO charset %s\n",
- buffer);
+ printk("MSDOS FS: IO charset %s\n", buffer);
X } else


X ret = 0;
X }

@@ -647,7 +653,7 @@
X fsinfo_offset =
X (sbi->fsinfo_sector * logical_sector_size) % hard_blksize;
X fsinfo_bh = bh;
- if (bh->b_blocknr != fsinfo_block) {
+ if (fsinfo_block != 0) {
X fsinfo_bh = bread(sb->s_dev, fsinfo_block, hard_blksize);
X if (fsinfo_bh == NULL) {
X printk("FAT: bread failed, FSINFO block"
@@ -667,7 +673,7 @@
X sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
X }
X
- if (bh->b_blocknr != fsinfo_block)
+ if (fsinfo_block != 0)
X brelse(fsinfo_bh);
X } else {
X fat32 = 0;
@@ -705,6 +711,9 @@
X }
X brelse(bh);
X
+ if (error)
+ goto out_invalid;
+
X sb->s_blocksize = logical_sector_size;
X sb->s_blocksize_bits = ffs(logical_sector_size) - 1;
X set_blocksize(sb->s_dev, sb->s_blocksize);


@@ -740,7 +749,6 @@
X

X sb->s_magic = MSDOS_SUPER_MAGIC;
X /* set up enough so that it can read an inode */
- init_waitqueue_head(&sbi->fat_wait);
X init_MUTEX(&sbi->fat_lock);
X sbi->prev_free = 0;
X
@@ -957,7 +965,7 @@
X struct super_block *sb = inode->i_sb;
X struct buffer_head *bh;
X struct msdos_dir_entry *raw_entry;
- int i_pos;
+ unsigned int i_pos;
X
X retry:
X i_pos = MSDOS_I(inode)->i_location;
@@ -1036,7 +1044,9 @@
X if (error)
X return MSDOS_SB(sb)->options.quiet ? 0 : error;
X

- inode_setattr(inode, attr);
+ error = inode_setattr(inode, attr);

+ if (error)
+ return error;
X
X if (S_ISDIR(inode->i_mode))
X inode->i_mode |= S_IXUGO;
@@ -1046,3 +1056,4 @@
X ~MSDOS_SB(sb)->options.fs_umask;
X return 0;
X }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.12/linux/fs/fat/misc.c linux/fs/fat/misc.c
--- v2.4.12/linux/fs/fat/misc.c Thu May 24 15:36:34 2001
+++ linux/fs/fat/misc.c Fri Oct 12 13:48:42 2001
@@ -2,6 +2,8 @@
X * linux/fs/fat/misc.c
X *
X * Written 1992,1993 by Werner Almesberger
+ * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
+ * and date_dos2unix for date==0 by Igor Zhbanov(b...@uniyar.ac.ru)
X */
X
X #include <linux/fs.h>
@@ -12,8 +14,6 @@
X #include <linux/string.h>
X #include <linux/stat.h>


X
-#include "msbuffer.h"
-
X #if 0
X # define PRINTK(x) printk x
X #else

@@ -75,30 +75,11 @@
X }
X }
X
-
-/* File creation lock. This is system-wide to avoid deadlocks in rename. */
-/* (rename might deadlock before detecting cross-FS moves.) */
-
-static DECLARE_MUTEX(creation_lock);
-
-void fat_lock_creation(void)
-{
- down(&creation_lock);
-}
-
-
-void fat_unlock_creation(void)
-{
- up(&creation_lock);
-}
-
-
X void lock_fat(struct super_block *sb)
X {
X down(&(MSDOS_SB(sb)->fat_lock));
X }
X
-
X void unlock_fat(struct super_block *sb)
X {
X up(&(MSDOS_SB(sb)->fat_lock));
@@ -132,39 +113,44 @@
X }
X
X /*
- * fat_add_cluster tries to allocate a new cluster and adds it to the file
- * represented by inode. The cluster is zero-initialized.
+ * fat_add_cluster tries to allocate a new cluster and adds it to the
+ * file represented by inode.
X */
-
-/* not a directory */
-
X int fat_add_cluster(struct inode *inode)
X {
X struct super_block *sb = inode->i_sb;
- int count,nr,limit,last,curr,file_cluster;
+ int count, nr, limit, last, curr, file_cluster;
+ int cluster_size = MSDOS_SB(sb)->cluster_size;
X int res = -ENOSPC;
-
- if (!MSDOS_SB(sb)->free_clusters) return res;
+
X lock_fat(sb);
+
+ if (MSDOS_SB(sb)->free_clusters == 0) {
+ unlock_fat(sb);
+ return res;
+ }
X limit = MSDOS_SB(sb)->clusters;
X nr = limit; /* to keep GCC happy */
X for (count = 0; count < limit; count++) {
- nr = ((count+MSDOS_SB(sb)->prev_free) % limit)+2;
- if (fat_access(sb,nr,-1) == 0) break;
+ nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
+ if (fat_access(sb, nr, -1) == 0)
+ break;
X }
- MSDOS_SB(sb)->prev_free = (count+MSDOS_SB(sb)->prev_free+1) % limit;
X if (count >= limit) {
X MSDOS_SB(sb)->free_clusters = 0;
X unlock_fat(sb);
X return res;
X }
- fat_access(sb,nr,EOF_FAT(sb));
+
+ MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
+ fat_access(sb, nr, EOF_FAT(sb));
X if (MSDOS_SB(sb)->free_clusters != -1)
X MSDOS_SB(sb)->free_clusters--;
X if (MSDOS_SB(sb)->fat_bits == 32)
X fat_clusters_flush(sb);
+
X unlock_fat(sb);
-
+
X /* We must locate the last cluster of the file to add this
X new one (nr) to the end of the link list (the FAT).
X
@@ -177,12 +163,12 @@
X */
X last = file_cluster = 0;
X if ((curr = MSDOS_I(inode)->i_start) != 0) {
- fat_cache_lookup(inode,INT_MAX,&last,&curr);
+ fat_cache_lookup(inode, INT_MAX, &last, &curr);
X file_cluster = last;
X while (curr && curr != -1){
X file_cluster++;
X if (!(curr = fat_access(sb, last = curr,-1))) {
- fat_fs_panic(sb,"File without EOF");
+ fat_fs_panic(sb, "File without EOF");
X return res;
X }
X }
@@ -195,94 +181,34 @@
X MSDOS_I(inode)->i_logstart = nr;
X mark_inode_dirty(inode);
X }
+ if (file_cluster
+ != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
+ printk ("file_cluster badly computed!!! %d <> %ld\n",
+ file_cluster,
+ inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
+ fat_cache_inval_inode(inode);
+ }
X inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
- return 0;
+
+ return nr;
X }
X
X struct buffer_head *fat_extend_dir(struct inode *inode)
X {
X struct super_block *sb = inode->i_sb;
- int count,nr,limit,last,curr,sector,last_sector,file_cluster;
- struct buffer_head *bh, *res=NULL;
+ int nr, sector, last_sector;
+ struct buffer_head *bh, *res = NULL;
X int cluster_size = MSDOS_SB(sb)->cluster_size;
X
X if (MSDOS_SB(sb)->fat_bits != 32) {
X if (inode->i_ino == MSDOS_ROOT_INO)
X return res;
X }
- if (!MSDOS_SB(sb)->free_clusters)
- return res;
-
- lock_fat(sb);
X
- limit = MSDOS_SB(sb)->clusters;
- nr = limit; /* to keep GCC happy */
- for (count = 0; count < limit; count++) {
- nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
- if (fat_access(sb, nr, -1) == 0)
- break;
- }
- PRINTK (("cnt = %d --", count));
-#ifdef DEBUG
- printk("free cluster: %d\n", nr);
-#endif
- if (count >= limit) {
- MSDOS_SB(sb)->free_clusters = 0;
- unlock_fat(sb);
+ nr = fat_add_cluster(inode);
+ if (nr < 0)
X return res;
- }
-
- MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
- fat_access(sb, nr, EOF_FAT(sb));
- if (MSDOS_SB(sb)->free_clusters != -1)
- MSDOS_SB(sb)->free_clusters--;
- if (MSDOS_SB(sb)->fat_bits == 32)
- fat_clusters_flush(sb);
-
- unlock_fat(sb);
-
-#ifdef DEBUG
- printk("set to %x\n", fat_access(sb, nr, -1));
-#endif
-
- /* We must locate the last cluster of the file to add this
- new one (nr) to the end of the link list (the FAT).
-
- Here file_cluster will be the number of the last cluster of the
- file (before we add nr).
-
- last is the corresponding cluster number on the disk. We will
- use last to plug the nr cluster. We will use file_cluster to
- update the cache.
- */
- last = file_cluster = 0;
- if ((curr = MSDOS_I(inode)->i_start) != 0) {
- fat_cache_lookup(inode, INT_MAX, &last, &curr);
- file_cluster = last;
- while (curr && curr != -1){
- PRINTK (("."));
- file_cluster++;
- if (!(curr = fat_access(sb, last = curr, -1))) {
- fat_fs_panic(sb,"File without EOF");
- return res;
- }
- }
- PRINTK ((" -- "));
- }
-#ifdef DEBUG
- printk("last = %d\n", last);
-#endif
- if (last)
- fat_access(sb, last, nr);
- else {
- MSDOS_I(inode)->i_start = nr;
- MSDOS_I(inode)->i_logstart = nr;
- mark_inode_dirty(inode);
- }
-#ifdef DEBUG
- if (last)
- printk("next set to %d\n",fat_access(sb, last, -1));
-#endif
+
X sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
X last_sector = sector + cluster_size;
X if (MSDOS_SB(sb)->cvf_format && MSDOS_SB(sb)->cvf_format->zero_out_cluster)
@@ -305,23 +231,15 @@
X }
X }
X }
- if (file_cluster
- != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
- printk ("file_cluster badly computed!!! %d <> %ld\n",
- file_cluster,
- inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
- }else{
- fat_cache_add(inode, file_cluster, nr);
- }
- inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
X if (inode->i_size & (sb->s_blocksize - 1)) {
X fat_fs_panic(sb, "Odd directory size");
- inode->i_size = (inode->i_size + sb->s_blocksize) &
- ~(sb->s_blocksize - 1);
+ inode->i_size = (inode->i_size + sb->s_blocksize)
+ & ~(sb->s_blocksize - 1);
X }
X inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits;
X MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits;
X mark_inode_dirty(inode);
+
X return res;
X }
X
@@ -340,7 +258,9 @@
X {
X int month,year,secs;
X
- month = ((date >> 5) & 15)-1;
+ /* first subtract and mask after that... Otherwise, if
+ date == 0, bad things happen */
+ month = ((date >> 5) - 1) & 15;
X year = date >> 9;
X secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
X ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
@@ -359,7 +279,10 @@
X int day,year,nl_day,month;
X
X unix_date -= sys_tz.tz_minuteswest*60;
- if (sys_tz.tz_dsttime) unix_date += 3600;
+
+ /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
+ if (unix_date < 315532800)
+ unix_date = 315532800;
X
X *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
X (((unix_date/3600) % 24) << 11);
@@ -592,61 +515,9 @@
X }
X
X /*
- * fat_parent_ino returns the inode number of the parent directory of dir.
- * File creation has to be deferred while fat_parent_ino is running to
- * prevent renames.
- *
- * AV. Bad, bad, bad... We need a mapping that would give us inode by
- * first cluster. Sheeeeit... OK, we can do it on fat_fill_inode() and
- * update on fat_add_cluster(). When will we remove it? fat_clear_inode()
- * and fat_truncate() to zero?
- */
-
-int fat_parent_ino(struct inode *dir,int locked)
-{
- static int zero = 0;
- int error,curr,prev,nr;
-
- PRINTK(("fat_parent_ino: Debug 0\n"));
- if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i");
- if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino;
- if (!locked) fat_lock_creation(); /* prevent renames */
- if ((curr = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,MSDOS_DOTDOT,
- &zero,NULL,NULL,NULL)) < 0) {
- if (!locked) fat_unlock_creation();
- return curr;
- }
- PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr));
- if (!curr) nr = MSDOS_ROOT_INO;
- else {
- PRINTK(("fat_parent_ino: Debug 2\n"));
- if ((prev = raw_scan(dir->i_sb,curr,MSDOS_DOTDOT,&zero,NULL,
- NULL,NULL)) < 0) {
- PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev));
- if (!locked) fat_unlock_creation();
- return prev;
- }
- PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev));
- if (prev == 0 && MSDOS_SB(dir->i_sb)->fat_bits == 32) {
- prev = MSDOS_SB(dir->i_sb)->root_cluster;
- }
- if ((error = raw_scan(dir->i_sb,prev,NULL,&curr,&nr,NULL,
- NULL)) < 0) {
- PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error));
- if (!locked) fat_unlock_creation();
- return error;
- }
- PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr));
- }
- if (!locked) fat_unlock_creation();
- return nr;
-}
-
-/*
X * fat_subdirs counts the number of sub-directories of dir. It can be run
X * on directories being created.
X */
-
X int fat_subdirs(struct inode *dir)
X {
X int count;
diff -u --recursive --new-file v2.4.12/linux/fs/fat/msbuffer.h linux/fs/fat/msbuffer.h
--- v2.4.12/linux/fs/fat/msbuffer.h Tue Sep 5 14:07:29 2000
+++ linux/fs/fat/msbuffer.h Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/* Number of bytes to readahead on disc access */
-#define FAT_READAHEAD (18*1024)
-
-struct buffer_head *fat_bread (struct super_block *sb, int block);
-struct buffer_head *fat_getblk (struct super_block *sb, int block);
-void fat_brelse (struct super_block *sb, struct buffer_head *bh);
-void fat_mark_buffer_dirty (struct super_block *sb,
- struct buffer_head *bh);
-void fat_set_uptodate (struct super_block *sb,
- struct buffer_head *bh,
- int val);
-int fat_is_uptodate (struct super_block *sb, struct buffer_head *bh);
-void fat_ll_rw_block (struct super_block *sb, int opr,
- int nbreq, struct buffer_head *bh[32]);
diff -u --recursive --new-file v2.4.12/linux/fs/fat/tables.c linux/fs/fat/tables.c
--- v2.4.12/linux/fs/fat/tables.c Thu Oct 23 14:00:15 1997
+++ linux/fs/fat/tables.c Wed Dec 31 16:00:00 1969
@@ -1,76 +0,0 @@
-/*
- * linux/fs/fat/tables.c
- *
- * Unicode escape translation tables for VFAT filename handling.
- * By Gordon Chaffee.
- *
- * Note: This file is used by all fat-based filesystems.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/msdos_fs.h>
-
-unsigned char fat_uni2esc[64] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
- 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z', '+', '-'
-};
-
-unsigned char fat_esc2uni[256] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0x3e, 0xff, 0x3f, 0xff, 0xff,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
- 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
- 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
- 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
diff -u --recursive --new-file v2.4.12/linux/fs/fat/tables.h linux/fs/fat/tables.h
--- v2.4.12/linux/fs/fat/tables.h Tue Mar 5 03:03:27 1996
+++ linux/fs/fat/tables.h Wed Dec 31 16:00:00 1969
@@ -1,35 +0,0 @@
-struct unicode_value {
- unsigned char uni1;
- unsigned char uni2;
-};
-
-extern unsigned char fat_a2alias[]; /* Ascii to alias name conversion table */
-extern struct unicode_value fat_a2uni[]; /* Ascii to Unicode conversion table */
-extern unsigned char *fat_uni2asc_pg[];
-
-/*
- * Since Linux can't deal with Unicode in filenames, these provide
- * a method to encode the Unicode names in a manner that the vfat
- * filesystem can them decode back to Unicode. This conversion
- * only occurs when the filesystem was mounted with the 'uni_xlate' mount
- * option.
- */
-extern unsigned char fat_uni2code[];
-extern unsigned char fat_code2uni[];
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
diff -u --recursive --new-file v2.4.12/linux/fs/freevxfs/vxfs_super.c linux/fs/freevxfs/vxfs_super.c
--- v2.4.12/linux/fs/freevxfs/vxfs_super.c Sun Sep 23 11:41:00 2001
+++ linux/fs/freevxfs/vxfs_super.c Thu Oct 11 09:43:38 2001
@@ -49,6 +49,7 @@
X
X MODULE_AUTHOR("Christoph Hellwig");
X MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
+MODULE_LICENSE("Dual BSD/GPL");
X
X
X static void vxfs_put_super(struct super_block *);
diff -u --recursive --new-file v2.4.12/linux/fs/hfs/catalog.c linux/fs/hfs/catalog.c
--- v2.4.12/linux/fs/hfs/catalog.c Tue Feb 13 14:13:45 2001
+++ linux/fs/hfs/catalog.c Mon Oct 15 19:30:33 2001
@@ -100,7 +100,7 @@
X static LIST_HEAD(entry_unused);
X static struct list_head hash_table[C_HASHSIZE];
X
-spinlock_t entry_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t entry_lock = SPIN_LOCK_UNLOCKED;
X
X static struct {
X int nr_entries;
diff -u --recursive --new-file v2.4.12/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v2.4.12/linux/fs/isofs/inode.c Mon Aug 27 12:41:46 2001
+++ linux/fs/isofs/inode.c Fri Oct 12 13:48:42 2001
@@ -1184,11 +1184,14 @@
X inode->i_size = isonum_733 (de->size);
X }
X
- /* There are defective discs out there - we do this to protect
- ourselves. A cdrom will never contain more than 800Mb
- .. but a DVD may be up to 1Gig (Ulrich Habel) */
-
- if ((inode->i_size < 0 || inode->i_size > 1073741824) &&
+ /*
+ * The ISO-9660 filesystem only stores 32 bits for file size.
+ * mkisofs handles files up to 2GB-2 = 2147483646 = 0x7FFFFFFE bytes
+ * in size. This is according to the large file summit paper from 1996.
+ * WARNING: ISO-9660 filesystems > 1 GB and even > 2 GB are fully
+ * legal. Do not prevent to use DVD's schi...@fokus.gmd.de
+ */
+ if ((inode->i_size < 0 || inode->i_size > 0x7FFFFFFE) &&
X inode->i_sb->u.isofs_sb.s_cruft == 'n') {
X printk(KERN_WARNING "Warning: defective CD-ROM. "
X "Enabling \"cruft\" mount option.\n");
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
--- v2.4.12/linux/fs/lockd/clntproc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/lockd/clntproc.c Thu Oct 11 07:52:18 2001
@@ -6,6 +6,7 @@
X * Copyright (C) 1996, Olaf Kirch <ok...@monad.swb.de>
X */
X
+#include <linux/config.h>
X #include <linux/types.h>
X #include <linux/errno.h>
X #include <linux/fs.h>
@@ -676,6 +677,18 @@
X case NLM_LCK_BLOCKED:
X printk(KERN_NOTICE "lockd: unexpected status NLM_BLOCKED\n");
X return -ENOLCK;
+#ifdef CONFIG_LOCKD_V4
+ case NLM_DEADLCK:
+ return -EDEADLK;
+ case NLM_ROFS:
+ return -EROFS;
+ case NLM_STALE_FH:
+ return -ESTALE;
+ case NLM_FBIG:
+ return -EOVERFLOW;
+ case NLM_FAILED:
+ return -ENOLCK;
+#endif
X }
X printk(KERN_NOTICE "lockd: unexpected server status %d\n", status);
X return -ENOLCK;
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/svc.c linux/fs/lockd/svc.c
--- v2.4.12/linux/fs/lockd/svc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/lockd/svc.c Sun Oct 21 10:32:33 2001
@@ -323,6 +323,7 @@
X
X MODULE_AUTHOR("Olaf Kirch <ok...@monad.swb.de>");
X MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION ".");
+MODULE_LICENSE("GPL");
X MODULE_PARM(nlm_grace_period, "10-240l");
X MODULE_PARM(nlm_timeout, "3-20l");
X MODULE_PARM(nlm_udpport, "0-65535l");
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/svclock.c linux/fs/lockd/svclock.c
--- v2.4.12/linux/fs/lockd/svclock.c Tue Nov 7 10:18:57 2000
+++ linux/fs/lockd/svclock.c Thu Oct 11 07:52:18 2001
@@ -31,9 +31,14 @@
X #include <linux/lockd/nlm.h>
X #include <linux/lockd/lockd.h>
X
-
X #define NLMDBG_FACILITY NLMDBG_SVCLOCK
X
+#ifdef CONFIG_LOCKD_V4
+#define nlm_deadlock nlm4_deadlock
+#else
+#define nlm_deadlock nlm_lck_denied
+#endif
+
X static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
X static int nlmsvc_remove_block(struct nlm_block *block);
X static void nlmsvc_grant_callback(struct rpc_task *task);
@@ -330,12 +335,7 @@
X case 0:
X return nlm_granted;
X case EDEADLK:
-#ifdef CONFIG_LOCKD_V4
- return nlm4_deadlock; /* will be downgraded to lck_deined if this
- * is a NLMv1,3 request */
-#else
- /* no applicable NLM status */
-#endif
+ return nlm_deadlock;
X case EAGAIN:
X return nlm_lck_denied;
X default: /* includes ENOLCK */
@@ -346,6 +346,11 @@
X if (!wait) {
X up(&file->f_sema);
X return nlm_lck_denied;
+ }
+
+ if (posix_locks_deadlock(&lock->fl, conflock)) {
+ up(&file->f_sema);
+ return nlm_deadlock;
X }
X
X /* If we don't have a block, create and initialize it. Then
diff -u --recursive --new-file v2.4.12/linux/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- v2.4.12/linux/fs/lockd/svcproc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/lockd/svcproc.c Thu Oct 11 07:52:18 2001
@@ -29,17 +29,20 @@
X static u32
X cast_to_nlm(u32 status, u32 vers)
X {
-
+ /* Note: status is assumed to be in network byte order !!! */
X if (vers != 4){
- switch(ntohl(status)){
- case NLM_LCK_GRANTED:
- case NLM_LCK_DENIED:
- case NLM_LCK_DENIED_NOLOCKS:
- case NLM_LCK_BLOCKED:
- case NLM_LCK_DENIED_GRACE_PERIOD:
+ switch (status) {
+ case nlm_granted:
+ case nlm_lck_denied:
+ case nlm_lck_denied_nolocks:
+ case nlm_lck_blocked:
+ case nlm_lck_denied_grace_period:
+ break;
+ case nlm4_deadlock:
+ status = nlm_lck_denied;
X break;
X default:
- status = NLM_LCK_DENIED_NOLOCKS;
+ status = nlm_lck_denied_nolocks;
X }
X }
X
diff -u --recursive --new-file v2.4.12/linux/fs/locks.c linux/fs/locks.c
--- v2.4.12/linux/fs/locks.c Sun Sep 23 11:41:00 2001
+++ linux/fs/locks.c Thu Oct 11 07:52:18 2001
@@ -548,7 +548,7 @@
X return (1);
X
X default:
- printk("locks_conflict(): impossible lock type - %d\n",
+ printk(KERN_ERR "locks_conflict(): impossible lock type - %d\n",
X caller_fl->fl_type);
X break;
X }
@@ -660,7 +660,7 @@
X * from a broken NFS client. But broken NFS clients have a lot more to
X * worry about than proper deadlock detection anyway... --okir
X */
-static int posix_locks_deadlock(struct file_lock *caller_fl,
+int posix_locks_deadlock(struct file_lock *caller_fl,
X struct file_lock *block_fl)


X {
X struct list_head *tmp;

@@ -715,6 +715,9 @@
X struct file_lock *new_fl = locks_alloc_lock(0);
X int error;
X
+ if (new_fl == NULL)
+ return -ENOMEM;
+
X new_fl->fl_owner = current->files;
X new_fl->fl_pid = current->pid;
X new_fl->fl_file = filp;
@@ -1428,6 +1431,9 @@
X struct inode *inode;
X int error;
X
+ if (file_lock == NULL)
+ return -ENOLCK;
+
X /*
X * This might block, so we do it before checking the inode.
X */
@@ -1580,6 +1586,9 @@
X struct flock64 flock;
X struct inode *inode;
X int error;
+
+ if (file_lock == NULL)
+ return -ENOLCK;
X
X /*
X * This might block, so we do it before checking the inode.
diff -u --recursive --new-file v2.4.12/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v2.4.12/linux/fs/msdos/namei.c Sun Sep 23 11:41:00 2001
+++ linux/fs/msdos/namei.c Fri Oct 12 13:48:42 2001
@@ -17,8 +17,6 @@


X
X #include <asm/uaccess.h>
X

-#include "../fat/msbuffer.h"
-
X #define MSDOS_DEBUG 0
X #define PRINTK(x)
X
diff -u --recursive --new-file v2.4.12/linux/fs/namei.c linux/fs/namei.c
--- v2.4.12/linux/fs/namei.c Thu Oct 11 08:02:26 2001
+++ linux/fs/namei.c Wed Oct 17 14:46:29 2001
@@ -646,10 +646,14 @@
X static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
X {
X if (path_walk(name, nd))
- return 0;
+ return 0; /* something went wrong... */
X
- if (!nd->dentry->d_inode) {
+ if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
X struct nameidata nd_root;
+ /*
+ * NAME was not found in alternate root or it's a directory. Try to find
+ * it in the normal root:
+ */
X nd_root.last_type = LAST_ROOT;
X nd_root.flags = nd->flags;
X read_lock(&current->fs->lock);
diff -u --recursive --new-file v2.4.12/linux/fs/namespace.c linux/fs/namespace.c
--- v2.4.12/linux/fs/namespace.c Thu Oct 11 08:02:26 2001
+++ linux/fs/namespace.c Mon Oct 15 18:47:36 2001
@@ -153,6 +153,8 @@
X atomic_inc(&sb->s_active);
X mnt->mnt_sb = sb;
X mnt->mnt_root = dget(root);
+ mnt->mnt_mountpoint = mnt->mnt_root;
+ mnt->mnt_parent = mnt;
X }
X return mnt;
X }
@@ -1086,7 +1088,7 @@
X printk(KERN_NOTICE "Trying to unmount old root ... ");
X if (!blivet) {
X spin_lock(&dcache_lock);
- list_del(&old_rootmnt->mnt_list);
+ list_del_init(&old_rootmnt->mnt_list);
X spin_unlock(&dcache_lock);
X mntput(old_rootmnt);
X mntput(old_rootmnt);
diff -u --recursive --new-file v2.4.12/linux/fs/nfs/read.c linux/fs/nfs/read.c
--- v2.4.12/linux/fs/nfs/read.c Tue Apr 3 13:45:37 2001
+++ linux/fs/nfs/read.c Thu Oct 11 08:12:52 2001
@@ -59,7 +59,7 @@
X static __inline__ struct nfs_read_data *nfs_readdata_alloc(void)
X {
X struct nfs_read_data *p;
- p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NFS);
+ p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NOFS);
X if (p) {
X memset(p, 0, sizeof(*p));
X INIT_LIST_HEAD(&p->pages);
diff -u --recursive --new-file v2.4.12/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.4.12/linux/fs/nfs/write.c Tue Oct 9 17:06:53 2001
+++ linux/fs/nfs/write.c Thu Oct 11 08:12:52 2001
@@ -109,7 +109,7 @@
X static __inline__ struct nfs_page *nfs_page_alloc(void)
X {
X struct nfs_page *p;
- p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL);
+ p = kmem_cache_alloc(nfs_page_cachep, SLAB_NOFS);
X if (p) {
X memset(p, 0, sizeof(*p));
X INIT_LIST_HEAD(&p->wb_hash);
@@ -127,7 +127,7 @@
X static __inline__ struct nfs_write_data *nfs_writedata_alloc(void)
X {
X struct nfs_write_data *p;
- p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NFS);
+ p = kmem_cache_alloc(nfs_wdata_cachep, SLAB_NOFS);
X if (p) {
X memset(p, 0, sizeof(*p));
X INIT_LIST_HEAD(&p->pages);
diff -u --recursive --new-file v2.4.12/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.4.12/linux/fs/nfsd/nfsctl.c Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/nfsctl.c Sun Oct 21 10:32:33 2001
@@ -309,6 +309,7 @@
X /* New-style module support since 2.1.18 */
X EXPORT_NO_SYMBOLS;
X MODULE_AUTHOR("Olaf Kirch <ok...@monad.swb.de>");
+MODULE_LICENSE("GPL");
X
X struct nfsd_linkage nfsd_linkage_s = {
X do_nfsservctl: handle_sys_nfsservctl,
diff -u --recursive --new-file v2.4.12/linux/fs/nfsd/nfsproc.c linux/fs/nfsd/nfsproc.c
--- v2.4.12/linux/fs/nfsd/nfsproc.c Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/nfsproc.c Sun Oct 21 10:40:36 2001
@@ -86,8 +86,8 @@
X {
X int nfserr;
X
- dprintk("nfsd: LOOKUP %s %s\n",
- SVCFH_fmt(&argp->fh), argp->name);
+ dprintk("nfsd: LOOKUP %s %.*s\n",
+ SVCFH_fmt(&argp->fh), argp->len, argp->name);
X
X fh_init(&resp->fh, NFS_FHSIZE);
X nfserr = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
@@ -199,8 +199,8 @@
X int nfserr, type, mode;
X dev_t rdev = NODEV;
X
- dprintk("nfsd: CREATE %s %s\n",
- SVCFH_fmt(dirfhp), argp->name);
+ dprintk("nfsd: CREATE %s %.*s\n",
+ SVCFH_fmt(dirfhp), argp->len, argp->name);
X
X /* First verify the parent file handle */
X nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_EXEC);
@@ -349,7 +349,8 @@
X {
X int nfserr;
X
- dprintk("nfsd: REMOVE %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+ dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh),
+ argp->len, argp->name);
X
X /* Unlink. -SIFDIR means file must not be a directory */
X nfserr = nfsd_unlink(rqstp, &argp->fh, -S_IFDIR, argp->name, argp->len);
@@ -363,10 +364,10 @@
X {
X int nfserr;
X
- dprintk("nfsd: RENAME %s %s -> \n",
- SVCFH_fmt(&argp->ffh), argp->fname);
- dprintk("nfsd: -> %s %s\n",
- SVCFH_fmt(&argp->tfh), argp->tname);
+ dprintk("nfsd: RENAME %s %.*s -> \n",
+ SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
+ dprintk("nfsd: -> %s %.*s\n",
+ SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname);
X
X nfserr = nfsd_rename(rqstp, &argp->ffh, argp->fname, argp->flen,
X &argp->tfh, argp->tname, argp->tlen);


@@ -383,8 +384,9 @@
X

X dprintk("nfsd: LINK %s ->\n",
X SVCFH_fmt(&argp->ffh));
- dprintk("nfsd: %s %s\n",
+ dprintk("nfsd: %s %.*s\n",
X SVCFH_fmt(&argp->tfh),
+ argp->tlen,
X argp->tname);
X
X nfserr = nfsd_link(rqstp, &argp->tfh, argp->tname, argp->tlen,
@@ -401,8 +403,9 @@
X struct svc_fh newfh;
X int nfserr;
X
- dprintk("nfsd: SYMLINK %s %s -> %s\n",
- SVCFH_fmt(&argp->ffh), argp->fname, argp->tname);
+ dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n",
+ SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
+ argp->tlen, argp->tname);
X
X fh_init(&newfh, NFS_FHSIZE);
X /*
@@ -428,7 +431,7 @@
X {
X int nfserr;
X
- dprintk("nfsd: MKDIR %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+ dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
X
X if (resp->fh.fh_dentry) {
X printk(KERN_WARNING
@@ -452,7 +455,7 @@
X {
X int nfserr;
X
- dprintk("nfsd: RMDIR %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+ dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
X
X nfserr = nfsd_unlink(rqstp, &argp->fh, S_IFDIR, argp->name, argp->len);
X fh_put(&argp->fh);
diff -u --recursive --new-file v2.4.12/linux/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c
--- v2.4.12/linux/fs/nfsd/nfssvc.c Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/nfssvc.c Wed Oct 17 14:16:34 2001
@@ -162,7 +162,7 @@
X lock_kernel();
X daemonize();
X sprintf(current->comm, "nfsd");
- current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+ 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.12/linux/fs/nfsd/nfsxdr.c linux/fs/nfsd/nfsxdr.c
--- v2.4.12/linux/fs/nfsd/nfsxdr.c Tue Oct 9 17:06:53 2001
+++ linux/fs/nfsd/nfsxdr.c Wed Oct 17 14:16:34 2001
@@ -70,7 +70,6 @@
X if (*name == '\0' || *name == '/')
X return NULL;
X }
- *name = '\0';
X }
X
X return p;
@@ -87,7 +86,6 @@
X if (*name == '\0')
X return NULL;
X }
- *name = '\0';
X }
X
X return p;
diff -u --recursive --new-file v2.4.12/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.4.12/linux/fs/ntfs/fs.c Tue Oct 9 17:06:53 2001
+++ linux/fs/ntfs/fs.c Tue Oct 23 08:17:31 2001
@@ -1159,6 +1159,7 @@
X */
X MODULE_AUTHOR("Anton Altaparmakov <ai...@cus.cam.ac.uk>");
X MODULE_DESCRIPTION("Linux NTFS driver");
+MODULE_LICENSE("GPL");
X #ifdef DEBUG
X MODULE_PARM(ntdebug, "i");
X MODULE_PARM_DESC(ntdebug, "Debug level");
diff -u --recursive --new-file v2.4.12/linux/fs/open.c linux/fs/open.c
--- v2.4.12/linux/fs/open.c Tue Oct 9 17:06:53 2001
+++ linux/fs/open.c Fri Oct 12 13:48:42 2001
@@ -104,7 +104,12 @@
X goto out;
X inode = nd.dentry->d_inode;
X
- error = -EACCES;
+ /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
+ error = -EISDIR;
+ if (S_ISDIR(inode->i_mode))
+ goto dput_and_out;
+
+ error = -EINVAL;
X if (!S_ISREG(inode->i_mode))
X goto dput_and_out;
X
@@ -146,10 +151,11 @@
X
X asmlinkage long sys_truncate(const char * path, unsigned long length)
X {
- return do_sys_truncate(path, length);
+ /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */
+ return do_sys_truncate(path, (long)length);
X }
X
-static inline long do_sys_ftruncate(unsigned int fd, loff_t length)
+static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
X {
X struct inode * inode;
X struct dentry *dentry;
@@ -163,13 +169,24 @@
X file = fget(fd);
X if (!file)
X goto out;
+
+ /* explicitly opened as large or we are on 64-bit box */
+ if (file->f_flags & O_LARGEFILE)
+ small = 0;
+
X dentry = file->f_dentry;
X inode = dentry->d_inode;
- error = -EACCES;
+ error = -EINVAL;
X if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
X goto out_putf;
+
+ error = -EINVAL;
+ /* Cannot ftruncate over 2^31 bytes without large file support */
+ if (small && length > MAX_NON_LFS)
+ goto out_putf;
+
X error = -EPERM;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ if (IS_APPEND(inode))
X goto out_putf;
X
X error = locks_verify_truncate(inode, file, length);
@@ -183,7 +200,7 @@
X
X asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
X {
- return do_sys_ftruncate(fd, length);
+ return do_sys_ftruncate(fd, length, 1);
X }
X
X /* LFS versions of truncate are only needed on 32 bit machines */
@@ -195,7 +212,7 @@
X
X asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
X {
- return do_sys_ftruncate(fd, length);
+ return do_sys_ftruncate(fd, length, 0);
X }
X #endif
X
@@ -507,7 +524,7 @@
X
X error = -ENOENT;
X if (!(inode = dentry->d_inode)) {
- printk("chown_common: NULL inode\n");
+ printk(KERN_ERR "chown_common: NULL inode\n");
X goto out;
X }
X error = -EROFS;
@@ -744,7 +761,7 @@
X #if 1
X /* Sanity check */
X if (files->fd[fd] != NULL) {
- printk("get_unused_fd: slot %d not NULL!\n", fd);
+ printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
X files->fd[fd] = NULL;
X }
X #endif
@@ -807,7 +824,7 @@
X int retval;
X
X if (!file_count(filp)) {
- printk("VFS: Close: file count is 0\n");
+ printk(KERN_ERR "VFS: Close: file count is 0\n");
X return 0;
X }
X retval = 0;
diff -u --recursive --new-file v2.4.12/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.4.12/linux/fs/partitions/check.c Tue Oct 9 17:06:53 2001
+++ linux/fs/partitions/check.c Thu Oct 11 17:25:10 2001
@@ -247,6 +247,7 @@
X printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
X bdev = bdget(kdev_t_to_nr(dev));
X bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
+ bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
X for (i = 0; check_part[i]; i++) {
X int res;
X res = check_part[i](hd, bdev, first_sector, first_part_minor);
@@ -385,6 +386,12 @@
X if (!size || minors == 1)
X return;
X
+ if (dev->sizes) {
+ dev->sizes[first_minor] = size >> (BLOCK_SIZE_BITS - 9);
+ for (i = first_minor + 1; i < end_minor; i++)
+ dev->sizes[i] = 0;
+ }
+ blk_size[dev->major] = dev->sizes;
X check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
X
X /*
@@ -394,7 +401,6 @@
X if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
X for (i = first_minor; i < end_minor; i++)
X dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
- blk_size[dev->major] = dev->sizes;
X }
X }
X
diff -u --recursive --new-file v2.4.12/linux/fs/partitions/msdos.c linux/fs/partitions/msdos.c
--- v2.4.12/linux/fs/partitions/msdos.c Tue Oct 9 17:06:53 2001
+++ linux/fs/partitions/msdos.c Thu Oct 11 08:07:07 2001
@@ -103,21 +103,20 @@
X */
X
X static void extended_partition(struct gendisk *hd, struct block_device *bdev,
- int minor, int *current_minor)
+ int minor, unsigned long first_size, int *current_minor)
X {
X struct partition *p;
X Sector sect;
X unsigned char *data;
- unsigned long first_sector, first_size, this_sector, this_size;
+ unsigned long first_sector, this_sector, this_size;
X int mask = (1 << hd->minor_shift) - 1;
X int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
X int loopct = 0; /* number of links followed
X without finding a data partition */
X int i;
X
- first_sector = hd->part[minor].start_sect;
- first_size = hd->part[minor].nr_sects;
- this_sector = first_sector;
+ this_sector = first_sector = hd->part[minor].start_sect;
+ this_size = first_size;
X
X while (1) {
X if (++loopct > 100)
@@ -133,8 +132,6 @@
X
X p = (struct partition *) (data + 0x1be);
X
- this_size = hd->part[minor].nr_sects;
-
X /*
X * Usually, the first entry is the real data partition,
X * the 2nd entry is the next extended partition, or empty,
@@ -196,6 +193,7 @@
X goto done; /* nothing left to do */
X
X this_sector = first_sector + START_SECT(p) * sector_size;
+ this_size = NR_SECTS(p) * sector_size;
X minor = *current_minor;
X put_dev_sector(sect);
X }
@@ -586,12 +584,13 @@
X }
X #endif
X if (is_extended_partition(p)) {
+ unsigned long size = hd->part[minor].nr_sects;
X printk(" <");
X /* prevent someone doing mkfs or mkswap on an
X extended partition, but leave room for LILO */
- if (hd->part[minor].nr_sects > 2)
+ if (size > 2)
X hd->part[minor].nr_sects = 2;
- extended_partition(hd, bdev, minor, &current_minor);
+ extended_partition(hd, bdev, minor, size, &current_minor);
X printk(" >");
X }
X }
diff -u --recursive --new-file v2.4.12/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.4.12/linux/fs/proc/array.c Sun Sep 23 11:41:00 2001
+++ linux/fs/proc/array.c Thu Oct 11 09:00:01 2001
@@ -151,12 +151,13 @@
X read_lock(&tasklist_lock);
X buffer += sprintf(buffer,
X "State:\t%s\n"
+ "Tgid:\t%d\n"
X "Pid:\t%d\n"
X "PPid:\t%d\n"
X "TracerPid:\t%d\n"
X "Uid:\t%d\t%d\t%d\t%d\n"
X "Gid:\t%d\t%d\t%d\t%d\n",
- get_task_state(p),
+ get_task_state(p), p->tgid,
X p->pid, p->pid ? p->p_opptr->pid : 0, 0,
X p->uid, p->euid, p->suid, p->fsuid,
X p->gid, p->egid, p->sgid, p->fsgid);
diff -u --recursive --new-file v2.4.12/linux/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- v2.4.12/linux/fs/proc/proc_misc.c Sun Sep 23 11:41:00 2001
+++ linux/fs/proc/proc_misc.c Thu Oct 11 10:46:57 2001
@@ -140,6 +140,7 @@
X {
X struct sysinfo i;
X int len;
+ int pg_size ;
X
X /*
X * display in kilobytes.
@@ -148,12 +149,14 @@
X #define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
X si_meminfo(&i);
X si_swapinfo(&i);
+ pg_size = atomic_read(&page_cache_size) - i.bufferram ;
+
X len = sprintf(page, " total: used: free: shared: buffers: cached:\n"
X "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
X "Swap: %8Lu %8Lu %8Lu\n",
X B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
X B(i.sharedram), B(i.bufferram),
- B(atomic_read(&page_cache_size)), B(i.totalswap),
+ B(pg_size), B(i.totalswap),
X B(i.totalswap-i.freeswap), B(i.freeswap));
X /*
X * Tagged format, for easy grepping and expansion.
@@ -179,7 +182,7 @@
X K(i.freeram),
X K(i.sharedram),
X K(i.bufferram),
- K(atomic_read(&page_cache_size) - swapper_space.nrpages),
+ K(pg_size - swapper_space.nrpages),
X K(swapper_space.nrpages),
X K(nr_active_pages),
X K(nr_inactive_pages),
diff -u --recursive --new-file v2.4.12/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.4.12/linux/fs/proc/root.c Wed May 16 18:05:34 2001
+++ linux/fs/proc/root.c Sat Oct 20 19:14:42 2001
@@ -44,6 +44,10 @@
X #ifdef CONFIG_SYSCTL
X proc_sys_root = proc_mkdir("sys", 0);
X #endif
+#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
+ proc_mkdir("sys/fs", 0);
+ proc_mkdir("sys/fs/binfmt_misc", 0);
+#endif
X proc_root_fs = proc_mkdir("fs", 0);
X proc_root_driver = proc_mkdir("driver", 0);
X #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/Makefile linux/fs/reiserfs/Makefile
--- v2.4.12/linux/fs/reiserfs/Makefile Mon Jan 15 12:42:32 2001
+++ linux/fs/reiserfs/Makefile Fri Oct 12 14:19:28 2001
@@ -13,6 +13,16 @@
X

X obj-m := $(O_TARGET)
X

+# gcc -O2 (the kernel default) is overaggressive on ppc when many inline
+# functions are used. This causes the compiler to advance the stack
+# pointer out of the available stack space, corrupting kernel space,
+# and causing a panic. Since this behavior only affects ppc, this ifeq
+# will work around it. If any other architecture displays this behavior,
+# add it here.
+ifeq ($(shell uname -m),ppc)
+EXTRA_CFLAGS := -O1
+endif


+
X include $(TOPDIR)/Rules.make
X

X TAGS:
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/README linux/fs/reiserfs/README
--- v2.4.12/linux/fs/reiserfs/README Mon Jan 15 12:42:32 2001
+++ linux/fs/reiserfs/README Fri Oct 12 14:19:28 2001
@@ -145,6 +145,10 @@
X
X Vitaly Fertman is doing fsck.
X
+Jeff Mahoney, of SuSE, contributed a few cleanup fixes, most notably
+the endian safe patches which allow ReiserFS to run on any platform
+supported by the Linux kernel.
+
X SuSE, IntegratedLinux.com, Ecila, MP3.com, bigstorage.com, and the
X Alpha PC Company made it possible for me to not have a day job
X anymore, and to dramatically increase our staffing. Ecila funded
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
--- v2.4.12/linux/fs/reiserfs/bitmap.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/bitmap.c Sun Oct 14 10:31:45 2001


@@ -116,7 +116,7 @@
X

X reiserfs_prepare_for_journal(s, sbh, 1) ;
X /* update super block */
- rs->s_free_blocks = cpu_to_le32 (le32_to_cpu (rs->s_free_blocks) + 1);
+ set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );
X
X journal_mark_dirty (th, s, sbh);
X s->s_dirt = 1;
@@ -304,8 +304,7 @@
X
X /* We continue the while loop if another process snatches our found
X * free block from us after we find it but before we successfully
- * mark it as in use, or if we need to use sync to free up some
- * blocks on the preserve list. */
+ * mark it as in use */
X
X while (amount_needed--) {
X /* skip over any blocknrs already gotten last time. */


@@ -405,26 +404,26 @@
X

X reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
X /* update free block count in super block */
- s->u.reiserfs_sb.s_rs->s_free_blocks = cpu_to_le32 (SB_FREE_BLOCKS (s) - init_amount_needed);
+ PUT_SB_FREE_BLOCKS( s, SB_FREE_BLOCKS(s) - init_amount_needed );
X journal_mark_dirty (th, s, SB_BUFFER_WITH_SB (s));
X s->s_dirt = 1;
X
X return CARRY_ON;
X }
X
-// this is called only by get_empty_nodes with for_preserve_list==0
+// this is called only by get_empty_nodes
X int reiserfs_new_blocknrs (struct reiserfs_transaction_handle *th, unsigned long * free_blocknrs,
X unsigned long search_start, int amount_needed) {
- return do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, amount_needed, 0/*for_preserve_list-priority*/, 0/*for_formatted*/, 0/*for_prealloc */) ;
+ return do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, amount_needed, 0/*priority*/, 0/*for_formatted*/, 0/*for_prealloc */) ;
X }
X
X
-// called by get_new_buffer and by reiserfs_get_block with amount_needed == 1 and for_preserve_list == 0
+// called by get_new_buffer and by reiserfs_get_block with amount_needed == 1
X int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle *th, unsigned long * free_blocknrs,
X unsigned long search_start) {
X return do_reiserfs_new_blocknrs(th, free_blocknrs, search_start,
X 1/*amount_needed*/,
- 0/*for_preserve_list-priority*/,
+ 0/*priority*/,
X 1/*for formatted*/,
X 0/*for prealloc */) ;
X }
@@ -478,14 +477,14 @@
X ** highest allocated oid, it is far from perfect, and files will tend
X ** to be grouped towards the start of the border
X */
- border = (INODE_PKEY(p_s_inode)->k_dir_id) % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
+ border = le32_to_cpu(INODE_PKEY(p_s_inode)->k_dir_id) % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
X } else {
X /* why would we want to delcare a local variable to this if statement
X ** name border????? -chris
X ** unsigned long border = 0;
X */
X if (!reiserfs_hashed_relocation(th->t_super)) {
- hash_in = (INODE_PKEY(p_s_inode))->k_dir_id;
+ hash_in = le32_to_cpu((INODE_PKEY(p_s_inode))->k_dir_id);
X /* I wonder if the CPU cost of the
X hash will obscure the layout
X effect? Of course, whether that
@@ -666,10 +665,10 @@
X if (inode->u.reiserfs_i.i_prealloc_count < 0)
X reiserfs_warning("zam-4001:" __FUNCTION__ ": inode has negative prealloc blocks count.\n");
X #endif
- if (inode->u.reiserfs_i.i_prealloc_count > 0) {
+ if (inode->u.reiserfs_i.i_prealloc_count > 0) {
X __discard_prealloc(th, inode);
X }
-}
+ }
X
X void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
X {
@@ -684,6 +683,6 @@
X }
X #endif
X __discard_prealloc(th, inode);
- }
+ }
X }
X #endif
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/dir.c linux/fs/reiserfs/dir.c
--- v2.4.12/linux/fs/reiserfs/dir.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/dir.c Fri Oct 12 14:20:42 2001
@@ -39,22 +39,10 @@
X };
X
X int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {


- int ret = 0 ;

- int windex ;
- struct reiserfs_transaction_handle th ;
-
X lock_kernel();
-
- journal_begin(&th, dentry->d_inode->i_sb, 1) ;
- windex = push_journal_writer("dir_fsync") ;
- reiserfs_prepare_for_journal(th.t_super, SB_BUFFER_WITH_SB(th.t_super), 1) ;
- journal_mark_dirty(&th, dentry->d_inode->i_sb, SB_BUFFER_WITH_SB (dentry->d_inode->i_sb)) ;
- pop_journal_writer(windex) ;
- journal_end_sync(&th, dentry->d_inode->i_sb, 1) ;
-
- unlock_kernel();
-
- return ret ;
+ reiserfs_commit_for_inode(dentry->d_inode) ;
+ unlock_kernel() ;


+ return 0 ;
X }
X
X

@@ -210,24 +198,3 @@
X reiserfs_check_path(&path_to_entry) ;


X return 0;
X }
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/do_balan.c linux/fs/reiserfs/do_balan.c
--- v2.4.12/linux/fs/reiserfs/do_balan.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/do_balan.c Fri Oct 12 14:19:28 2001
@@ -104,20 +104,9 @@
X switch (flag) {
X case M_DELETE: /* delete item in S[0] */
X
- RFALSE( le16_to_cpu (ih->ih_item_len) + IH_SIZE != -tb->insert_size [0],
- "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
- ih);
-
-#if 0 /* rigth delim key not supported */
- if ( ! item_pos && (! tb->L[0] || COMP_KEYS(B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY(tbS0, 0))) ) {
- print_cur_tb ("12015");
- reiserfs_panic (tb->tb_sb, "PAP-12015: balance_leaf_when_delete: L0's rkey does not match to 1st key of S0: "
- "rkey in L %k, first key in S0 %k, rkey in CFL %k",
- tb->L[0] ? B_PRIGHT_DELIM_KEY(tb->L[0]) : 0,
- B_N_PKEY(tbS0, 0),
- tb->CFL[0] ? B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]) : 0);
- }
-#endif
+ RFALSE( ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
+ "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
+ ih);
X
X bi.tb = tb;
X bi.bi_bh = tbS0;
@@ -128,18 +117,10 @@
X if ( ! item_pos && tb->CFL[0] ) {
X if ( B_NR_ITEMS(tbS0) ) {
X replace_key(tb, tb->CFL[0],tb->lkey[0],tbS0,0);
-#if 0 /* right delim key support */
- copy_key(B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY(tbS0, 0));
- reiserfs_mark_buffer_dirty (tb->L[0], 0);
-#endif
X }
X else {
X if ( ! PATH_H_POSITION (tb->tb_path, 1) )
X replace_key(tb, tb->CFL[0],tb->lkey[0],PATH_H_PPARENT(tb->tb_path, 0),0);
-#if 0 /* right delim key support */
- copy_key(B_PRIGHT_DELIM_KEY(tb->L[0]), B_PRIGHT_DELIM_KEY(tbS0));
- reiserfs_mark_buffer_dirty (tb->L[0], 0);
-#endif
X }
X }
X
@@ -155,14 +136,6 @@
X bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
X if (is_direntry_le_ih (ih)) {
X
-#ifdef CONFIG_REISERFS_CHECK
-#if 0 /* right delim key support */
- if ( ! item_pos && ! pos_in_item && (! tb->L[0] || COMP_KEYS(B_PRIGHT_DELIM_KEY(tb->L[0]),
- B_N_PKEY(tbS0, 0))) )
- reiserfs_panic(tb->tb_sb, "PAP-12025: balance_leaf_when_delete: illegal right delimiting key");
-#endif
-#endif
-
X /* UFS unlink semantics are such that you can only delete one directory entry at a time. */
X /* when we cut a directory tb->insert_size[0] means number of entries to be cut (always 1) */
X tb->insert_size[0] = -1;
@@ -174,16 +147,12 @@
X
X if ( ! item_pos && ! pos_in_item && tb->CFL[0] ) {
X replace_key(tb, tb->CFL[0],tb->lkey[0],tbS0,0);
-#if 0/* right delim key support */
- copy_key(B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY(tbS0, 0));
- reiserfs_mark_buffer_dirty (tb->L[0], 0);
-#endif
X }
X } else {
X leaf_cut_from_buffer (&bi, item_pos, pos_in_item, -tb->insert_size[0]);
X
- RFALSE( ! ih->ih_item_len,
- "PAP-12035: cut must leave non-zero dynamic length of item");
+ RFALSE( ! ih_item_len(ih),


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 42'
echo 'File patch-2.4.13 is continued in part 43'
echo "43" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:13 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part43

#!/bin/sh -x
# this is part 43 of a 53 - part archive


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

if test "$Scheck" != 43; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ "PAP-12035: cut must leave non-zero dynamic length of item");
X }
X break;
X }
@@ -208,17 +177,9 @@
X if ( PATH_H_POSITION (tb->tb_path, 1) == 0 && 1 < B_NR_ITEMS(tb->FR[0]) )
X replace_key(tb, tb->CFL[0],tb->lkey[0],tb->FR[0],1);
X
- /* update right_delimiting_key field */
-#if 0
- copy_key (B_PRIGHT_DELIM_KEY (tb->L[0]), B_PRIGHT_DELIM_KEY (tb->R[0]));
-#endif
X leaf_move_items (LEAF_FROM_S_TO_L, tb, n, -1, 0);
X leaf_move_items (LEAF_FROM_R_TO_L, tb, B_NR_ITEMS(tb->R[0]), -1, 0);
X
-#if 0/*preserve list*/
- preserve_invalidate(tb, tbS0, tb->L[0]);
- preserve_invalidate(tb, tb->R[0], tb->L[0]);
-#endif
X reiserfs_invalidate_buffer (tb, tbS0);
X reiserfs_invalidate_buffer (tb, tb->R[0]);
X
@@ -231,11 +192,6 @@
X /* right_delimiting_key is correct in R[0] */
X replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
X
-#if 0
- /* mark tb->R[0] as suspected recipient */
- preserve_invalidate(tb,tbS0, tb->R[0]);
- preserve_invalidate(tb,tb->L[0], tb->R[0]);
-#endif
X reiserfs_invalidate_buffer (tb, tbS0);
X reiserfs_invalidate_buffer (tb, tb->L[0]);
X
@@ -247,9 +203,6 @@
X /* all contents of L[0] and S[0] will be in L[0] */
X leaf_shift_left(tb, n, -1);
X
-#if 0/*preserve list*/
- preserve_invalidate(tb, tbS0, tb->L[0]); /* preserved, shifting */
-#endif
X reiserfs_invalidate_buffer (tb, tbS0);
X
X return 0;
@@ -272,10 +225,6 @@
X leaf_shift_left (tb, tb->lnum[0], tb->lbytes);
X leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
X
-#if 0/*preserve list*/
- preserve_invalidate (tb, tbS0, tb->L[0]);
- mark_suspected_recipient (tb->tb_sb, tb->R[0]);
-#endif
X reiserfs_invalidate_buffer (tb, tbS0);
X
X return 0;
@@ -284,9 +233,6 @@
X if ( tb->rnum[0] == -1 ) {
X /* all contents of R[0] and S[0] will be in R[0] */
X leaf_shift_right(tb, n, -1);
-#if 0/*preserve list*/
- preserve_invalidate(tb, tbS0, tb->R[0]);
-#endif
X reiserfs_invalidate_buffer (tb, tbS0);
X return 0;
X }
@@ -310,10 +256,6 @@
X )
X {
X struct buffer_head * tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#if 0/*preserve list*/
- struct buffer_head * tbF0 = PATH_H_PPARENT (tb->tb_path, 0);
- int S0_b_item_order = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);
-#endif
X int item_pos = PATH_LAST_POSITION (tb->tb_path); /* index into the array of item headers in S[0]
X of the affected item */
X struct buffer_info bi;
@@ -344,7 +286,7 @@
X
X zeros_num = 0;
X if (flag == M_INSERT && body == 0)
- zeros_num = le16_to_cpu (ih->ih_item_len);
+ zeros_num = ih_item_len( ih );
X
X pos_in_item = tb->tb_path->pos_in_item;
X /* for indirect item pos_in_item is measured in unformatted node
@@ -366,27 +308,18 @@
X int new_item_len;
X int version;
X
- RFALSE( !is_direct_le_ih (ih),
+ RFALSE (!is_direct_le_ih (ih),
X "PAP-12075: only direct inserted item can be broken. %h", ih);
X ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
- /* when reading the if conditions preceding the subsequent preserve_shifted
- lines understand that their goal is to determine if all that we are
- shifting is the new data being added */
-#if 0/*preserve list*/
- if (tb->lnum[0] - 1 > 0) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X
X /* Calculate item length to insert to S[0] */
- new_item_len = le16_to_cpu (ih->ih_item_len) - tb->lbytes;
+ new_item_len = ih_item_len(ih) - tb->lbytes;
X /* Calculate and check item length to insert to L[0] */
- ih->ih_item_len -= new_item_len;
+ put_ih_item_len(ih, ih_item_len(ih) - new_item_len );
X
- RFALSE( (int)(ih->ih_item_len) <= 0,
+ RFALSE( ih_item_len(ih) <= 0,
X "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
- (int)ih->ih_item_len);
+ ih_item_len(ih));
X
X /* Insert new item into L[0] */
X bi.tb = tb;
@@ -394,14 +327,14 @@
X bi.bi_parent = tb->FL[0];
X bi.bi_position = get_left_neighbor_position (tb, 0);
X leaf_insert_into_buf (&bi, n + item_pos - ret_val, ih, body,
- zeros_num > ih->ih_item_len ? ih->ih_item_len : zeros_num);
+ zeros_num > ih_item_len(ih) ? ih_item_len(ih) : zeros_num);
X
X version = ih_version (ih);
X
X /* Calculate key component, item length and body to insert into S[0] */
- set_le_key_k_offset (ih_version (ih), &(ih->ih_key),
- le_key_k_offset (ih_version (ih), &(ih->ih_key)) + tb->lbytes);
- ih->ih_item_len = cpu_to_le16 (new_item_len);
+ set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes );
+
+ put_ih_item_len( ih, new_item_len );
X if ( tb->lbytes > zeros_num ) {
X body += (tb->lbytes - zeros_num);
X zeros_num = 0;
@@ -409,30 +342,19 @@
X else
X zeros_num -= tb->lbytes;
X
- RFALSE( (int)(ih->ih_item_len) <= 0,
- "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
- (int)ih->ih_item_len);
+ RFALSE( ih_item_len(ih) <= 0,
+ "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
+ ih_item_len(ih));
X } else {
X /* new item in whole falls into L[0] */
X /* Shift lnum[0]-1 items to L[0] */
X ret_val = leaf_shift_left(tb, tb->lnum[0]-1, tb->lbytes);
-#if 0/*preserve list*/
- if (tb->lnum[0] > 1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Insert new item into L[0] */
X bi.tb = tb;
X bi.bi_bh = tb->L[0];
X bi.bi_parent = tb->FL[0];
X bi.bi_position = get_left_neighbor_position (tb, 0);
X leaf_insert_into_buf (&bi, n + item_pos - ret_val, ih, body, zeros_num);
-#if 0/*preserve list*/
- if (tb->preserve_mode == PRESERVE_INDIRECT_TO_DIRECT){
- mark_suspected_recipient (tb->tb_sb, bi.bi_bh);
- }
-#endif
X tb->insert_size[0] = 0;
X zeros_num = 0;
X }
@@ -454,10 +376,6 @@
X
X /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */
X ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes - 1);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X if ( ret_val && ! item_pos ) {
X pasted = B_N_PITEM_HEAD(tb->L[0],B_NR_ITEMS(tb->L[0])-1);
X l_pos_in_item += I_ENTRY_COUNT(pasted) - (tb->lbytes-1);
@@ -485,10 +403,6 @@
X /* new directory item doesn't fall into L[0] */
X /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */
X leaf_shift_left (tb, tb->lnum[0], tb->lbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X /* Calculate new position to append in item body */
X pos_in_item -= tb->lbytes;
@@ -496,11 +410,12 @@
X else {
X /* regular object */
X RFALSE( tb->lbytes <= 0,
- "PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
+ "PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
X tb->lbytes);
- RFALSE( pos_in_item != B_N_PITEM_HEAD(tbS0, item_pos)->ih_item_len,
- "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
- B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len, pos_in_item);
+ RFALSE( pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)),
+ "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
+ ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)), pos_in_item);
+
X if ( tb->lbytes >= pos_in_item ) {
X /* appended item will be in L[0] in whole */
X int l_n;
@@ -515,11 +430,7 @@
X "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
X tb->insert_size[0]);
X ret_val = leaf_shift_left(tb,tb->lnum[0],
- B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
+ ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)));
X /* Append to body of item in L[0] */
X bi.tb = tb;
X bi.bi_bh = tb->L[0];
@@ -527,7 +438,7 @@
X bi.bi_position = get_left_neighbor_position (tb, 0);
X leaf_paste_in_buffer(
X &bi,n + item_pos - ret_val,
- B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)->ih_item_len,
+ ih_item_len( B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)),
X l_n,body, zeros_num > l_n ? l_n : zeros_num
X );
X
@@ -541,15 +452,13 @@
X {
X int version;
X
- version = le16_to_cpu (B_N_PITEM_HEAD (tbS0, 0)->ih_version);
+ version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
X set_le_key_k_offset (version, B_N_PKEY (tbS0, 0),
X le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + l_n);
+ version = ih_version (B_N_PITEM_HEAD(tb->CFL[0],tb->lkey[0]));
X set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
X le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + l_n);
X }
- /* k_offset (B_N_PKEY (tbS0, 0)) += l_n;
- k_offset (B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) += l_n;
- k_offset (B_PRIGHT_DELIM_KEY(tb->L[0])) += l_n;*/
X
X /* Calculate new body, position in item and insert_size[0] */
X if ( l_n > zeros_num ) {
@@ -581,10 +490,6 @@
X
X /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
X leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X }
X }
@@ -597,17 +502,13 @@
X /* then increment pos_in_item by the size of the last item in L[0] */
X pasted = B_N_PITEM_HEAD(tb->L[0],n-1);
X if ( is_direntry_le_ih (pasted) )
- pos_in_item += le16_to_cpu (pasted->u.ih_entry_count);
+ pos_in_item += ih_entry_count(pasted);
X else
- pos_in_item += le16_to_cpu (pasted->ih_item_len);
+ pos_in_item += ih_item_len(pasted);
X }
X
X /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
X ret_val = leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X /* Append to body of item in L[0] */
X bi.tb = tb;
X bi.bi_bh = tb->L[0];
@@ -637,10 +538,6 @@
X } else {
X /* new item doesn't fall into L[0] */
X leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->L[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X } /* tb->lnum[0] > 0 */
X
@@ -667,22 +564,16 @@
X ih);
X
X leaf_shift_right(tb,tb->rnum[0]-1,-1);
-#if 0/*preserve list*/
- if (tb->rnum[0]>1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X
- version = le16_to_cpu (ih->ih_version);
+ version = ih_version(ih);
X /* Remember key component and item length */
- old_key_comp = le_key_k_offset (version, &(ih->ih_key));
- old_len = le16_to_cpu (ih->ih_item_len);
+ old_key_comp = le_ih_k_offset( ih );
+ old_len = ih_item_len(ih);
X
X /* Calculate key component and item length to insert into R[0] */
- offset = le_key_k_offset (version, &(ih->ih_key)) + (old_len - tb->rbytes);
- set_le_key_k_offset (version, &(ih->ih_key), offset);
- ih->ih_item_len = cpu_to_le16 (tb->rbytes);
+ offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes );
+ set_le_ih_k_offset( ih, offset );
+ put_ih_item_len( ih, tb->rbytes);
X /* Insert part of the item into R[0] */
X bi.tb = tb;
X bi.bi_bh = tb->R[0];
@@ -704,8 +595,8 @@
X replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
X
X /* Calculate key component and item length to insert into S[0] */
- set_le_key_k_offset (version, &(ih->ih_key), old_key_comp);
- ih->ih_item_len = cpu_to_le16 (old_len - tb->rbytes);
+ set_le_ih_k_offset( ih, old_key_comp );
+ put_ih_item_len( ih, old_len - tb->rbytes );
X
X tb->insert_size[0] -= tb->rbytes;
X
@@ -714,33 +605,16 @@
X {
X /* Shift rnum[0]-1 items to R[0] */
X ret_val = leaf_shift_right(tb,tb->rnum[0]-1,tb->rbytes);
-#if 0/*preserve list*/
- if (tb->rnum[0]>1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Insert new item into R[0] */
X bi.tb = tb;
X bi.bi_bh = tb->R[0];
X bi.bi_parent = tb->FR[0];
X bi.bi_position = get_right_neighbor_position (tb, 0);
X leaf_insert_into_buf (&bi, item_pos - n + tb->rnum[0] - 1, ih, body, zeros_num);
-#if 0/*preserve list*/
- if (tb->preserve_mode == PRESERVE_INDIRECT_TO_DIRECT){
- mark_suspected_recipient (tb->tb_sb, bi.bi_bh);
- }
-#endif
X
- /* If we insert new item in the begin of R[0] change the right delimiting key */
X if ( item_pos - n + tb->rnum[0] - 1 == 0 ) {
X replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
X
-#if 0
- /* update right delimiting key */
- copy_key(B_PRIGHT_DELIM_KEY(tbS0), &(ih->ih_key));
- reiserfs_mark_buffer_dirty (tbS0, 0);
-#endif
X }
X zeros_num = tb->insert_size[0] = 0;
X }
@@ -748,10 +622,6 @@
X else /* new item or part of it doesn't fall into R[0] */
X {
X leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X break;
X
@@ -779,13 +649,6 @@
X tb->rbytes, entry_count);
X /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */
X leaf_shift_right(tb,tb->rnum[0],tb->rbytes - 1);
-#if 0/*preserve list*/
- /* if we are shifting more than just the new entry */
- if (tb->rbytes > 1 || tb->rnum[0] > 1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Paste given directory entry to directory item */
X paste_entry_position = pos_in_item - entry_count + tb->rbytes - 1;
X bi.tb = tb;
@@ -803,10 +666,6 @@
X if ( paste_entry_position == 0 ) {
X /* change delimiting keys */
X replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
-#if 0
- copy_key(B_PRIGHT_DELIM_KEY(tbS0), B_N_PKEY(tb->R[0], 0));
- reiserfs_mark_buffer_dirty (tbS0, 0);
-#endif
X }
X
X tb->insert_size[0] = 0;
@@ -815,10 +674,6 @@
X else /* new directory entry doesn't fall into R[0] */
X {
X leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X }
X else /* regular object */
@@ -830,18 +685,11 @@
X if ( (n_shift = tb->rbytes - tb->insert_size[0]) < 0 )
X n_shift = 0;
X
- RFALSE( pos_in_item != B_N_PITEM_HEAD (tbS0, item_pos)->ih_item_len,
- "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
- pos_in_item, B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len);
+ RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD (tbS0, item_pos)),
+ "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
+ pos_in_item, ih_item_len( B_N_PITEM_HEAD(tbS0,item_pos)));
X
X leaf_shift_right(tb,tb->rnum[0],n_shift);
-#if 0/*preserve list*/
- /* if we are shifting an old part from the appended item or more than the appended item is going into R */
- if (n_shift || tb->rnum[0] > 1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Calculate number of bytes which must remain in body after appending to R[0] */
X if ( (n_rem = tb->insert_size[0] - tb->rbytes) < 0 )
X n_rem = 0;
@@ -859,11 +707,6 @@
X k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
X do_balance_mark_internal_dirty (tb, tb->CFR[0], 0);
X
-#if 0
- set_le_key_k_offset (B_PRIGHT_DELIM_KEY(tbS0), le_key_k_offset (B_PRIGHT_DELIM_KEY(tbS0)) + n_rem);
-/* k_offset (B_PRIGHT_DELIM_KEY(tbS0)) += n_rem;*/
- reiserfs_mark_buffer_dirty (tbS0, 0);
-#endif
X /* Append part of body into R[0] */
X bi.tb = tb;
X bi.bi_bh = tb->R[0];
@@ -899,10 +742,6 @@
X struct item_head * pasted;
X
X ret_val = leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X /* append item in R[0] */
X if ( pos_in_item >= 0 ) {
X bi.tb = tb;
@@ -927,10 +766,6 @@
X
X /* update delimiting keys */
X replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
-#if 0
- copy_key(B_PRIGHT_DELIM_KEY(tbS0),B_N_PKEY(tb->R[0], 0));
- reiserfs_mark_buffer_dirty (tbS0, 0);
-#endif
X }
X }
X
@@ -942,10 +777,6 @@
X else /* new item doesn't fall into R[0] */
X {
X leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, tb->R[0]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X break;
X default: /* cases d and t */
@@ -967,7 +798,7 @@
X if ( tb->blknum[0] == 0 ) { /* node S[0] is empty now */
X
X RFALSE( ! tb->lnum[0] || ! tb->rnum[0],
- "PAP-12190: lnum and rnum must not be zero");
+ "PAP-12190: lnum and rnum must not be zero");
X /* if insertion was done before 0-th position in R[0], right
X delimiting key of the tb->L[0]'s and left delimiting key are
X not set correctly */
@@ -1000,7 +831,7 @@
X S_new[i] = get_FEB(tb);
X
X /* initialized block type and tree level */
- B_BLK_HEAD(S_new[i])->blk_level = cpu_to_le16 (DISK_LEAF_NODE_LEVEL);
+ set_blkh_level( B_BLK_HEAD(S_new[i]), DISK_LEAF_NODE_LEVEL );
X
X
X n = B_NR_ITEMS(tbS0);
@@ -1024,22 +855,16 @@
X
X /* Move snum[i]-1 items from S[0] to S_new[i] */
X leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
-#if 0/*preserve list*/
- if (snum[i] > 1 ) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, S_new[i]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Remember key component and item length */
X version = ih_version (ih);
- old_key_comp = le_key_k_offset (version, &(ih->ih_key));
- old_len = le16_to_cpu (ih->ih_item_len);
+ old_key_comp = le_ih_k_offset( ih );
+ old_len = ih_item_len(ih);
X
X /* Calculate key component and item length to insert into S_new[i] */
- set_le_key_k_offset (version, &(ih->ih_key),
- le_key_k_offset (version, &(ih->ih_key)) + (old_len - sbytes[i]));
+ set_le_ih_k_offset( ih,
+ le_ih_k_offset(ih) + (old_len - sbytes[i] ) );
X
- ih->ih_item_len = cpu_to_le16 (sbytes[i]);
+ put_ih_item_len( ih, sbytes[i] );
X
X /* Insert part of the item into S_new[i] before 0-th item */
X bi.tb = tb;
@@ -1047,21 +872,21 @@
X bi.bi_parent = 0;
X bi.bi_position = 0;
X
- if ( le_key_k_offset (version, &(ih->ih_key)) - old_key_comp > zeros_num ) {
+ if ( le_ih_k_offset (ih) - old_key_comp > zeros_num ) {
X r_zeros_number = 0;
- r_body = body + (le_key_k_offset (version, &(ih->ih_key)) - old_key_comp) - zeros_num;
+ r_body = body + (le_ih_k_offset(ih) - old_key_comp) - zeros_num;
X }
X else {
X r_body = body;
- r_zeros_number = zeros_num - (le_key_k_offset (version, &(ih->ih_key)) - old_key_comp);
+ r_zeros_number = zeros_num - (le_ih_k_offset (ih) - old_key_comp);
X zeros_num -= r_zeros_number;
X }
X
X leaf_insert_into_buf (&bi, 0, ih, r_body, r_zeros_number);
X
X /* Calculate key component and item length to insert into S[i] */
- set_le_key_k_offset (version, &(ih->ih_key), old_key_comp);
- ih->ih_item_len = cpu_to_le16 (old_len - sbytes[i]);
+ set_le_ih_k_offset( ih, old_key_comp );
+ put_ih_item_len( ih, old_len - sbytes[i] );
X tb->insert_size[0] -= sbytes[i];
X }
X else /* whole new item falls into S_new[i] */
@@ -1075,11 +900,6 @@
X bi.bi_parent = 0;
X bi.bi_position = 0;
X leaf_insert_into_buf (&bi, item_pos - n + snum[i] - 1, ih, body, zeros_num);
-#if 0/*preserve list*/
- if (tb->preserve_mode == PRESERVE_INDIRECT_TO_DIRECT){
- mark_suspected_recipient (tb->tb_sb, bi.bi_bh);
- }
-#endif
X
X zeros_num = tb->insert_size[0] = 0;
X }
@@ -1088,10 +908,6 @@
X else /* new item or it part don't falls into S_new[i] */
X {
X leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, S_new[i]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X break;
X
@@ -1110,7 +926,7 @@
X
X int entry_count;
X
- entry_count = le16_to_cpu (aux_ih->u.ih_entry_count);
+ entry_count = ih_entry_count(aux_ih);
X
X if ( entry_count - sbytes[i] < pos_in_item && pos_in_item <= entry_count ) {
X /* new directory entry falls into S_new[i] */
@@ -1123,14 +939,6 @@
X
X /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
X leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i]-1, S_new[i]);
-#if 0/*preserve list*/
- /* if more than the affected item is shifted, or if more than
- one entry (from the affected item) is shifted */
- if (snum[i] > 1 || sbytes[i] > 1) {
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, S_new[i]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
- }
-#endif
X /* Paste given directory entry to directory item */
X bi.tb = tb;
X bi.bi_bh = S_new[i];
@@ -1155,9 +963,9 @@
X int n_shift, n_rem, r_zeros_number;
X const char * r_body;
X
- RFALSE( pos_in_item != B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len ||
- tb->insert_size[0] <= 0,
- "PAP-12225: item too short or insert_size <= 0");
+ RFALSE( pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)) ||
+ tb->insert_size[0] <= 0,
+ "PAP-12225: item too short or insert_size <= 0");
X
X /* Calculate number of bytes which must be shifted from appended item */
X n_shift = sbytes[i] - tb->insert_size[0];
@@ -1195,8 +1003,7 @@
X reiserfs_panic (tb->tb_sb, "PAP-12230: balance_leaf: invalid action with indirect item");
X set_ih_free_space (tmp, ((struct unfm_nodeinfo*)body)->unfm_freespace);
X }
- set_le_key_k_offset (ih_version (tmp), &tmp->ih_key,
- le_key_k_offset (ih_version (tmp), &tmp->ih_key) + n_rem);
+ set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + n_rem );
X }
X
X tb->insert_size[0] = n_rem;
@@ -1213,17 +1020,12 @@
X #ifdef CONFIG_REISERFS_CHECK
X struct item_head * ih = B_N_PITEM_HEAD(tbS0,item_pos);
X
- if ( ! is_direntry_le_ih(ih) && (pos_in_item != ih->ih_item_len ||
+ if ( ! is_direntry_le_ih(ih) && (pos_in_item != ih_item_len(ih) ||
X tb->insert_size[0] <= 0) )
X reiserfs_panic (tb->tb_sb, "PAP-12235: balance_leaf: pos_in_item must be equal to ih_item_len");
X #endif /* CONFIG_REISERFS_CHECK */
X
X ret_val = leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-#if 0/*preserve list*/
- /* we must preserve that which we are pasting onto the end of and shifting */
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, S_new[i]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X
X RFALSE( ret_val,
X "PAP-12240: unexpected value returned by leaf_move_items (%d)",
@@ -1255,10 +1057,6 @@
X else /* pasted item doesn't fall into S_new[i] */
X {
X leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-#if 0/*preserve list*/
- preserve_shifted(tb, &(PATH_PLAST_BUFFER (tb->tb_path)), tbF0, S0_b_item_order, S_new[i]);
- tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-#endif
X }
X break;
X default: /* cases d and t */
@@ -1275,12 +1073,6 @@
X buffer_journal_dirty(S_new[i]))),
X "PAP-12247: S_new[%d] : (%b)\n", i, S_new[i]);
X
-#if 0
- /* update right_delimiting_key fields */
- copy_key (B_PRIGHT_DELIM_KEY (S_new[i]), B_PRIGHT_DELIM_KEY (tbS0));
- copy_key (B_PRIGHT_DELIM_KEY (tbS0), B_N_PKEY (S_new[i], 0));
- reiserfs_mark_buffer_dirty (tbS0, 0);
-#endif
X
X }
X
@@ -1297,29 +1089,12 @@
X bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);


X bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);

X leaf_insert_into_buf (&bi, item_pos, ih, body, zeros_num);
-#if 0/*preserve list*/
- if (tb->preserve_mode == PRESERVE_INDIRECT_TO_DIRECT){
- mark_suspected_recipient (tb->tb_sb, bi.bi_bh);
- }
-#endif
X
X /* If we insert the first key change the delimiting key */
X if( item_pos == 0 ) {
X if (tb->CFL[0]) /* can be 0 in reiserfsck */


X replace_key(tb, tb->CFL[0], tb->lkey[0],tbS0,0);

X

-#if 0 /* right delim key support */

-#ifdef CONFIG_REISERFS_CHECK
- if ( ! tb->CFL[0] || ! tb->L[0] || (B_NR_ITEMS (tbS0) > 1 &&
- COMP_KEYS(B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY(tbS0, 1))) )
- reiserfs_panic(tb->tb_sb, "PAP-12250: balance_leaf: invalid right delimiting key");
- if (!buffer_dirty (tb->L[0]) && !(buffer_journaled(tb->L[0]) ||
- buffer_journal_dirty(tb->L[0])))
- reiserfs_panic (tb->tb_sb, "PAP-12255: balance_leaf: tb->L[0] must be dirty");
-#endif
- if (tb->L[0]) /* can be 0 in reiserfsck */
- copy_key (B_PRIGHT_DELIM_KEY (tb->L[0]), &(ih->ih_key));
-#endif /* right delim key support */
X }
X break;
X
@@ -1329,7 +1104,8 @@
X pasted = B_N_PITEM_HEAD (tbS0, item_pos);
X /* when directory, may be new entry already pasted */
X if (is_direntry_le_ih (pasted)) {
- if ( pos_in_item >= 0 && pos_in_item <= le16_to_cpu (pasted->u.ih_entry_count) ) {
+ if ( pos_in_item >= 0 &&
+ pos_in_item <= ih_entry_count(pasted) ) {
X
X RFALSE( ! tb->insert_size[0],
X "PAP-12260: insert_size is 0 already");
@@ -1341,15 +1117,6 @@


X bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);

X leaf_paste_in_buffer(&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
X
-
-#ifdef CONFIG_REISERFS_CHECK
-#if 0


- if ( ! item_pos && ! pos_in_item && (! tb->L[0] || COMP_KEYS(B_PRIGHT_DELIM_KEY(tb->L[0]),
- B_N_PKEY(tbS0, 0))) )

- reiserfs_panic(tb->tb_sb, "PAP-12265: balance_leaf: invalid right delimiting key");
-#endif
-#endif
-
X /* paste entry */
X leaf_paste_entries (
X bi.bi_bh, item_pos, pos_in_item, 1, (struct reiserfs_de_head *)body,
@@ -1361,21 +1128,16 @@
X if (tb->CFL[0]) {


X replace_key(tb, tb->CFL[0], tb->lkey[0],tbS0,0);

X
-#if 0
- /* update right delimiting key */
- copy_key (B_PRIGHT_DELIM_KEY (tb->L[0]), B_N_PKEY(tbS0, 0));
- /* probably not needed as something has been shifted to tb->L[0] already */


- reiserfs_mark_buffer_dirty (tb->L[0], 0);
-#endif
X }
X }

X tb->insert_size[0] = 0;
X }
X } else { /* regular object */
- if ( pos_in_item == pasted->ih_item_len ) {
+ if ( pos_in_item == ih_item_len(pasted) ) {
+
X RFALSE( tb->insert_size[0] <= 0,
- "PAP-12275: insert size must not be %d",
- tb->insert_size[0]);
+ "PAP-12275: insert size must not be %d",
+ tb->insert_size[0]);


X bi.tb = tb;
X bi.bi_bh = tbS0;

X bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
@@ -1425,11 +1187,12 @@
X
X RFALSE( bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
X
- (blkh = B_BLK_HEAD(bi->bi_bh))->blk_nr_item = cpu_to_le16 (0);
- blkh->blk_free_space = cpu_to_le16 (MAX_CHILD_SIZE(bi->bi_bh));
+ blkh = B_BLK_HEAD(bi->bi_bh);
+ set_blkh_nr_item( blkh, 0 );
+ set_blkh_free_space( blkh, MAX_CHILD_SIZE(bi->bi_bh) );
X
X if (bi->bi_parent)
- B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size = 0;
+ B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size = 0; /* Endian safe if 0 */
X }
X
X
@@ -1494,8 +1257,11 @@
X
X void reiserfs_invalidate_buffer (struct tree_balance * tb, struct buffer_head * bh)
X {
- B_BLK_HEAD (bh)->blk_level = cpu_to_le16 (FREE_LEVEL)/*0*/;
- B_BLK_HEAD (bh)->blk_nr_item = cpu_to_le16 (0);
+ struct block_head *blkh;
+ blkh = B_BLK_HEAD(bh);
+ set_blkh_level( blkh, FREE_LEVEL );
+ set_blkh_nr_item( blkh, 0 );
+
X mark_buffer_clean (bh);
X /* reiserfs_free_block is no longer schedule safe
X reiserfs_free_block (tb->transaction_handle, tb->tb_sb, bh->b_blocknr);
@@ -1583,7 +1349,7 @@
X dc = B_N_CHILD (bh, 0);
X
X for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++) {
- if (!is_reusable (s, dc->dc_block_number, 1) ) {
+ if (!is_reusable (s, dc_block_number(dc), 1) ) {
X print_cur_tb (mes);
X reiserfs_panic (s, "PAP-12338: check_internal_node: invalid child pointer %y in %b", dc, bh);
X }
@@ -1636,23 +1402,37 @@
X {
X if (tb->lnum[0]) {
X if (B_FREE_SPACE (tb->L[0]) !=
- MAX_CHILD_SIZE (tb->L[0]) - B_N_CHILD (tb->FL[0], get_left_neighbor_position (tb, 0))->dc_size) {
+ MAX_CHILD_SIZE (tb->L[0]) - dc_size(B_N_CHILD (tb->FL[0], get_left_neighbor_position (tb, 0)))) {
X print_cur_tb ("12221");
X reiserfs_panic (tb->tb_sb, "PAP-12355: check_after_balance_leaf: shift to left was incorrect");
X }
X }
X if (tb->rnum[0]) {
X if (B_FREE_SPACE (tb->R[0]) !=
- MAX_CHILD_SIZE (tb->R[0]) - B_N_CHILD (tb->FR[0], get_right_neighbor_position (tb, 0))->dc_size) {
+ MAX_CHILD_SIZE (tb->R[0]) - dc_size(B_N_CHILD (tb->FR[0], get_right_neighbor_position (tb, 0)))) {
X print_cur_tb ("12222");
X reiserfs_panic (tb->tb_sb, "PAP-12360: check_after_balance_leaf: shift to right was incorrect");
X }
X }
- if (PATH_H_PBUFFER(tb->tb_path,1) && (B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) !=
- (MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)) -
- B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
- PATH_H_POSITION (tb->tb_path, 1))->dc_size))) {
+ if (PATH_H_PBUFFER(tb->tb_path,1) &&
+ (B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) !=
+ (MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)) -
+ dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
+ PATH_H_POSITION (tb->tb_path, 1)))) )) {
+ int left = B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0));
+ int right = (MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)) -
+ dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
+ PATH_H_POSITION (tb->tb_path, 1))));
X print_cur_tb ("12223");
+ reiserfs_warning(
+ "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
+ "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d\n",
+ left,
+ MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)),
+ PATH_H_PBUFFER(tb->tb_path,1),
+ PATH_H_POSITION (tb->tb_path, 1),
+ dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1), PATH_H_POSITION (tb->tb_path, 1 )) ),
+ right );
X reiserfs_panic (tb->tb_sb, "PAP-12365: check_after_balance_leaf: S is incorrect");
X }
X }
@@ -1783,8 +1563,8 @@
X existing file or to insert a directory
X entry. */
X {
- int child_pos, /* position of a child node in its parent */
- h; /* level of the tree being processed */
+ int child_pos, /* position of a child node in its parent */
+ h; /* level of the tree being processed */
X struct item_head insert_key[2]; /* in our processing of one level
X we sometimes determine what
X must be inserted into the next
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/file.c linux/fs/reiserfs/file.c
--- v2.4.12/linux/fs/reiserfs/file.c Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/file.c Fri Oct 12 14:20:42 2001
@@ -42,6 +42,7 @@
X lock_kernel() ;
X down (&inode->i_sem);
X journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
+ reiserfs_update_inode_transaction(inode) ;
X
X #ifdef REISERFS_PREALLOCATE
X reiserfs_discard_prealloc (&th, inode);
@@ -75,10 +76,7 @@
X int datasync
X ) {
X struct inode * p_s_inode = p_s_dentry->d_inode;
- struct reiserfs_transaction_handle th ;
X int n_err;
- int windex ;
- int jbegin_count = 1 ;
X
X lock_kernel() ;
X
@@ -87,14 +85,7 @@
X
X n_err = fsync_inode_buffers(p_s_inode) ;
X n_err |= fsync_inode_data_buffers(p_s_inode);
- /* commit the current transaction to flush any metadata
- ** changes. sys_fsync takes care of flushing the dirty pages for us
- */
- journal_begin(&th, p_s_inode->i_sb, jbegin_count) ;
- windex = push_journal_writer("sync_file") ;
- reiserfs_update_sd(&th, p_s_inode);
- pop_journal_writer(windex) ;
- journal_end_sync(&th, p_s_inode->i_sb,jbegin_count) ;
+ reiserfs_commit_for_inode(p_s_inode) ;
X unlock_kernel() ;
X return ( n_err < 0 ) ? -EIO : 0;
X }
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- v2.4.12/linux/fs/reiserfs/fix_node.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/fix_node.c Fri Oct 12 14:19:28 2001
@@ -124,7 +124,7 @@
X /* get item number in source node */
X j = old_item_num (new_num, vn->vn_affected_item_num, vn->vn_mode);
X
- vi->vi_item_len += ih[j].ih_item_len + IH_SIZE;
+ vi->vi_item_len += ih_item_len(ih + j) + IH_SIZE;
X vi->vi_ih = ih + j;
X vi->vi_item = B_I_PITEM (Sh, ih + j);
X vi->vi_uarea = vn->vn_free_ptr;
@@ -658,9 +658,8 @@
X
X /* we might check that left neighbor exists and is of the
X same directory */
- RFALSE( le_key_k_offset
- (ih_version (ih), &(ih->ih_key)) == DOT_OFFSET,
- "vs-8130: first directory item can not be removed until directory is not empty");
+ RFALSE(le_ih_k_offset (ih) == DOT_OFFSET,
+ "vs-8130: first directory item can not be removed until directory is not empty");
X }
X
X }
@@ -857,7 +856,7 @@
X f = l;
X }
X
- return (MAX_CHILD_SIZE(f) - le16_to_cpu (B_N_CHILD(f,order)->dc_size));
+ return (MAX_CHILD_SIZE(f) - dc_size(B_N_CHILD(f,order)));
X }
X
X
@@ -879,7 +878,7 @@
X f = r;
X }
X
- return (MAX_CHILD_SIZE(f) - B_N_CHILD(f,order)->dc_size);
+ return (MAX_CHILD_SIZE(f) - dc_size( B_N_CHILD(f,order)));
X
X }
X
@@ -959,7 +958,7 @@
X struct path * p_s_path = p_s_tb->tb_path;
X struct cpu_key s_lr_father_key;
X int n_counter,
- n_position = MAX_INT,
+ n_position = INT_MAX,
X n_first_last_position = 0,
X n_path_offset = PATH_H_PATH_OFFSET(p_s_path, n_h);
X
@@ -1134,17 +1133,8 @@
X decrement_bcount(p_s_tb->CFR[n_h]);
X p_s_tb->CFR[n_h] = p_s_curcf; /* New initialization of CFR[n_path_offset]. */


X
-#ifdef CONFIG_REISERFS_CHECK
-#if 0

- if (n_h == 0 && p_s_tb->CFR[n_h] && COMP_KEYS (B_PRIGHT_DELIM_KEY (PATH_H_PBUFFER(p_s_path, n_h)),
- B_N_PDELIM_KEY (p_s_tb->CFR[n_h], p_s_tb->rkey[n_h]))) {
- reiserfs_panic (p_s_tb->tb_sb, "PAP-8200: get_parents: rdkey in S0 %k, rdkey in CFR0 %k do not match",
- B_PRIGHT_DELIM_KEY (PATH_H_PBUFFER(p_s_path, n_h)), B_N_PDELIM_KEY (p_s_tb->CFR[n_h], p_s_tb->rkey[n_h]));
- }
-#endif
-#endif
- RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) ||
- (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
+ RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) ||
+ (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
X "PAP-8205: FR (%b) or CFR (%b) is invalid", p_s_curf, p_s_curcf);
X
X return CARRY_ON;
@@ -1590,7 +1580,7 @@
X int order_L;
X
X order_L = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
- n = B_N_CHILD(tb->FL[h],order_L)->dc_size / (DC_SIZE + KEY_SIZE);
+ n = dc_size(B_N_CHILD(tb->FL[h],order_L)) / (DC_SIZE + KEY_SIZE);
X set_parameters (tb, h, -n-1, 0, 0, NULL, -1, -1);
X return CARRY_ON;
X }
@@ -1602,7 +1592,7 @@
X int order_R;
X
X order_R = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==B_NR_ITEMS(Fh)) ? 0 : n + 1;
- n = B_N_CHILD(tb->FR[h],order_R)->dc_size / (DC_SIZE + KEY_SIZE);
+ n = dc_size(B_N_CHILD(tb->FR[h],order_R)) / (DC_SIZE + KEY_SIZE);
X set_parameters (tb, h, 0, -n-1, 0, NULL, -1, -1);
X return CARRY_ON;
X }
@@ -1633,7 +1623,7 @@
X int order_L;
X
X order_L = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
- n = B_N_CHILD(tb->FL[h],order_L)->dc_size / (DC_SIZE + KEY_SIZE);
+ n = dc_size(B_N_CHILD(tb->FL[h],order_L)) / (DC_SIZE + KEY_SIZE);
X set_parameters (tb, h, -n-1, 0, 0, NULL, -1, -1);
X return CARRY_ON;
X }
@@ -1645,7 +1635,7 @@
X int order_R;
X
X order_R = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==B_NR_ITEMS(Fh)) ? 0 : (n + 1);
- n = B_N_CHILD(tb->FR[h],order_R)->dc_size / (DC_SIZE + KEY_SIZE);
+ n = dc_size(B_N_CHILD(tb->FR[h],order_R)) / (DC_SIZE + KEY_SIZE);
X set_parameters (tb, h, 0, -n-1, 0, NULL, -1, -1);
X return CARRY_ON;
X }
@@ -1934,14 +1924,14 @@
X return REPEAT_SEARCH;
X }
X
- RFALSE( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) ||
- n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
- B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) !=
- p_s_bh->b_blocknr, "PAP-8275: invalid parent");
+ RFALSE( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) ||
+ n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
+ B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) !=
+ p_s_bh->b_blocknr, "PAP-8275: invalid parent");
X RFALSE( ! B_IS_IN_TREE(p_s_bh), "PAP-8280: invalid child");
- RFALSE( ! n_h &&
- B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FL[0],n_child_position)->dc_size,
- "PAP-8290: invalid child size of left neighbor");
+ RFALSE( ! n_h &&
+ B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - dc_size(B_N_CHILD (p_s_tb->FL[0],n_child_position)),
+ "PAP-8290: invalid child size of left neighbor");
X
X decrement_bcount(p_s_tb->L[n_h]);
X p_s_tb->L[n_h] = p_s_bh;
@@ -1967,10 +1957,10 @@
X decrement_bcount(p_s_tb->R[n_h]);
X p_s_tb->R[n_h] = p_s_bh;
X
- RFALSE( ! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size,
- "PAP-8300: invalid child size of right neighbor (%d != %d - %d)",
- B_FREE_SPACE (p_s_bh), MAX_CHILD_SIZE (p_s_bh),
- B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size);
+ RFALSE( ! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - dc_size(B_N_CHILD (p_s_tb->FR[0],n_child_position)),
+ "PAP-8300: invalid child size of right neighbor (%d != %d - %d)",
+ B_FREE_SPACE (p_s_bh), MAX_CHILD_SIZE (p_s_bh),
+ dc_size(B_N_CHILD (p_s_tb->FR[0],n_child_position)));
X
X }
X return CARRY_ON;
@@ -2027,7 +2017,7 @@
X size += sizeof (struct virtual_item);
X if (is_direntry_le_ih (ih))
X /* each entry and new one occupeis 2 byte in the virtual node */
- size += (le16_to_cpu (ih->u.ih_entry_count) + 1) * sizeof (__u16);
+ size += (ih_entry_count(ih) + 1) * sizeof( __u16 );
X }
X
X /* 1 bit for each bitmap block to note whether bitmap block was
@@ -2544,8 +2534,9 @@
X brelse (tb->used[i]);
X }
X }
+
X if (tb->vn_buf)
- reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+ reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
X
X }
X
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/hashes.c linux/fs/reiserfs/hashes.c
--- v2.4.12/linux/fs/reiserfs/hashes.c Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/hashes.c Fri Oct 12 14:19:28 2001
@@ -48,7 +48,7 @@
X } while(0)
X
X
-u32 keyed_hash(const char *msg, int len)
+u32 keyed_hash(const signed char *msg, int len)
X {
X u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3};
X
@@ -174,7 +174,7 @@
X /* What follows in this file is copyright 2000 by Hans Reiser, and the
X * licensing of what follows is governed by reiserfs/README */
X
-u32 yura_hash (const char *msg, int len)
+u32 yura_hash (const signed char *msg, int len)
X {
X int j, pow;
X u32 a, c;
@@ -209,7 +209,7 @@
X return a;
X }
X
-u32 r5_hash (const char *msg, int len)
+u32 r5_hash (const signed char *msg, int len)
X {
X u32 a=0;
X while(*msg) {
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/ibalance.c linux/fs/reiserfs/ibalance.c
--- v2.4.12/linux/fs/reiserfs/ibalance.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/ibalance.c Fri Oct 12 14:19:28 2001
@@ -140,7 +140,8 @@
X if (count <= 0)
X return;
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD(cur))->blk_nr_item);
+ blkh = B_BLK_HEAD(cur);
+ nr = blkh_nr_item(blkh);
X
X RFALSE( count > 2,
X "too many children (%d) are to be inserted", count);
@@ -155,9 +156,8 @@
X
X /* copy to_be_insert disk children */
X for (i = 0; i < count; i ++) {
- new_dc[i].dc_size =
- cpu_to_le16 (MAX_CHILD_SIZE(bh[i]) - B_FREE_SPACE (bh[i]));
- new_dc[i].dc_block_number = cpu_to_le32 (bh[i]->b_blocknr);
+ put_dc_size( &(new_dc[i]), MAX_CHILD_SIZE(bh[i]) - B_FREE_SPACE(bh[i]));
+ put_dc_block_number( &(new_dc[i]), bh[i]->b_blocknr );
X }
X memcpy (dc, new_dc, DC_SIZE * count);
X
@@ -173,8 +173,9 @@
X memcpy (ih + 1, inserted + 1, KEY_SIZE);
X
X /* sizes, item number */
- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) + count);
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - count * (DC_SIZE + KEY_SIZE));
+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) + count );
+ set_blkh_free_space( blkh,
+ blkh_free_space(blkh) - count * (DC_SIZE + KEY_SIZE ) );
X
X do_balance_mark_internal_dirty (cur_bi->tb, cur,0);
X
@@ -183,7 +184,8 @@
X /*&&&&&&&&&&&&&&&&&&&&&&&&*/
X
X if (cur_bi->bi_parent) {
- B_N_CHILD (cur_bi->bi_parent,cur_bi->bi_position)->dc_size += count * (DC_SIZE + KEY_SIZE);
+ struct disk_child *t_dc = B_N_CHILD (cur_bi->bi_parent,cur_bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) + (count * (DC_SIZE + KEY_SIZE)));
X do_balance_mark_internal_dirty(cur_bi->tb, cur_bi->bi_parent, 0);
X
X /*&&&&&&&&&&&&&&&&&&&&&&&&*/
@@ -210,17 +212,18 @@
X struct disk_child * dc;
X
X RFALSE( cur == NULL, "buffer is 0");
- RFALSE( del_num < 0,
- "negative number of items (%d) can not be deleted", del_num);
+ RFALSE( del_num < 0,
+ "negative number of items (%d) can not be deleted", del_num);
X RFALSE( first_p < 0 || first_p + del_num > B_NR_ITEMS (cur) + 1 || first_i < 0,
- "first pointer order (%d) < 0 or "
- "no so many pointers (%d), only (%d) or "
- "first key order %d < 0", first_p,
- first_p + del_num, B_NR_ITEMS (cur) + 1, first_i);
+ "first pointer order (%d) < 0 or "
+ "no so many pointers (%d), only (%d) or "
+ "first key order %d < 0", first_p,
+ first_p + del_num, B_NR_ITEMS (cur) + 1, first_i);
X if ( del_num == 0 )
X return;
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD(cur))->blk_nr_item);
+ blkh = B_BLK_HEAD(cur);
+ nr = blkh_nr_item(blkh);
X
X if ( first_p == 0 && del_num == nr + 1 ) {
X RFALSE( first_i != 0, "1st deleted key must have order 0, not %d", first_i);
@@ -229,9 +232,9 @@
X }
X
X RFALSE( first_i + del_num > B_NR_ITEMS (cur),
- "first_i = %d del_num = %d "
- "no so many keys (%d) in the node (%b)(%z)",
- first_i, del_num, first_i + del_num, cur, cur);
+ "first_i = %d del_num = %d "
+ "no so many keys (%d) in the node (%b)(%z)",
+ first_i, del_num, first_i + del_num, cur, cur);
X
X
X /* deleting */
@@ -243,8 +246,9 @@
X
X
X /* sizes, item number */
- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) - del_num);
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) + del_num * (KEY_SIZE + DC_SIZE));
+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );
+ set_blkh_free_space( blkh,
+ blkh_free_space(blkh) + (del_num * (KEY_SIZE + DC_SIZE) ) );
X
X do_balance_mark_internal_dirty (cur_bi->tb, cur, 0);
X /*&&&&&&&&&&&&&&&&&&&&&&&*/
@@ -252,7 +256,10 @@
X /*&&&&&&&&&&&&&&&&&&&&&&&*/
X
X if (cur_bi->bi_parent) {
- B_N_CHILD (cur_bi->bi_parent, cur_bi->bi_position)->dc_size -= del_num * (KEY_SIZE + DC_SIZE);
+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD (cur_bi->bi_parent, cur_bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) - (del_num * (KEY_SIZE + DC_SIZE) ) );
+
X do_balance_mark_internal_dirty (cur_bi->tb, cur_bi->bi_parent,0);
X /*&&&&&&&&&&&&&&&&&&&&&&&&*/
X check_internal (cur_bi->bi_parent);
@@ -312,7 +319,8 @@
X return;
X
X /* coping */
- nr_dest = le16_to_cpu ((blkh = B_BLK_HEAD(dest))->blk_nr_item);
+ blkh = B_BLK_HEAD(dest);
+ nr_dest = blkh_nr_item(blkh);
X
X /*dest_order = (last_first == LAST_TO_FIRST) ? 0 : nr_dest;*/
X /*src_order = (last_first == LAST_TO_FIRST) ? (nr_src - cpy_num + 1) : 0;*/
@@ -338,8 +346,9 @@
X memcpy (key, B_N_PDELIM_KEY (src, src_order), KEY_SIZE * (cpy_num - 1));
X
X /* sizes, item number */
- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) + (cpy_num - 1));
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - (KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num));
+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) + (cpy_num - 1 ) );
+ set_blkh_free_space( blkh,
+ blkh_free_space(blkh) - (KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num ) );
X
X do_balance_mark_internal_dirty (dest_bi->tb, dest, 0);
X
@@ -348,8 +357,9 @@
X /*&&&&&&&&&&&&&&&&&&&&&&&&*/
X
X if (dest_bi->bi_parent) {
- B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position)->dc_size +=
- KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num;
+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) + (KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num) );
X
X do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent,0);
X /*&&&&&&&&&&&&&&&&&&&&&&&&*/
@@ -413,7 +423,8 @@
X RFALSE( B_FREE_SPACE (dest) < KEY_SIZE,
X "no enough free space (%d) in dest buffer", B_FREE_SPACE (dest));
X
- nr = le16_to_cpu ((blkh=B_BLK_HEAD(dest))->blk_nr_item);
+ blkh = B_BLK_HEAD(dest);
+ nr = blkh_nr_item(blkh);
X
X /* prepare space for inserting key */
X key = B_N_PDELIM_KEY (dest, dest_position_before);
@@ -423,13 +434,17 @@
X memcpy (key, B_N_PDELIM_KEY(src, src_position), KEY_SIZE);
X
X /* Change dirt, free space, item number fields. */
- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) + 1);
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - KEY_SIZE);
+
+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
+ set_blkh_free_space( blkh, blkh_free_space(blkh) - KEY_SIZE );
X
X do_balance_mark_internal_dirty (dest_bi->tb, dest, 0);
X
X if (dest_bi->bi_parent) {
- B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position)->dc_size += KEY_SIZE;
+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) + KEY_SIZE );
+
X do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent,0);
X }
X }
@@ -607,9 +622,9 @@
X else
X new_root = tb->L[h-1];
X /* switch super block's tree root block number to the new value */
- tb->tb_sb->u.reiserfs_sb.s_rs->s_root_block = cpu_to_le32 (new_root->b_blocknr);
+ PUT_SB_ROOT_BLOCK( tb->tb_sb, new_root->b_blocknr );
X //tb->tb_sb->u.reiserfs_sb.s_rs->s_tree_height --;
- tb->tb_sb->u.reiserfs_sb.s_rs->s_tree_height = cpu_to_le16 (SB_TREE_HEIGHT (tb->tb_sb) - 1);
+ PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) - 1 );
X
X do_balance_mark_sb_dirty (tb, tb->tb_sb->u.reiserfs_sb.s_sbh, 1);
X /*&&&&&&&&&&&&&&&&&&&&&&*/
@@ -818,8 +833,8 @@
X
X /* replace the first node-ptr in S[h] by node-ptr to insert_ptr[k] */
X dc = B_N_CHILD(tbSh, 0);
- dc->dc_size = cpu_to_le16 (MAX_CHILD_SIZE(insert_ptr[k]) - B_FREE_SPACE (insert_ptr[k]));
- dc->dc_block_number = cpu_to_le32 (insert_ptr[k]->b_blocknr);
+ put_dc_size( dc, MAX_CHILD_SIZE(insert_ptr[k]) - B_FREE_SPACE (insert_ptr[k]));
+ put_dc_block_number( dc, insert_ptr[k]->b_blocknr );
X
X do_balance_mark_internal_dirty (tb, tbSh, 0);
X
@@ -874,10 +889,9 @@
X
X /* replace the first node-ptr in R[h] by node-ptr insert_ptr[insert_num-k-1]*/
X dc = B_N_CHILD(tb->R[h], 0);
- dc->dc_size =
- cpu_to_le16 (MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
- B_FREE_SPACE (insert_ptr[insert_num-k-1]));
- dc->dc_block_number = cpu_to_le32 (insert_ptr[insert_num-k-1]->b_blocknr);
+ put_dc_size( dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
+ B_FREE_SPACE (insert_ptr[insert_num-k-1]));
+ put_dc_block_number( dc, insert_ptr[insert_num-k-1]->b_blocknr );
X
X do_balance_mark_internal_dirty (tb, tb->R[h],0);
X
@@ -902,22 +916,24 @@
X /* create new root */
X struct disk_child * dc;
X struct buffer_head * tbSh_1 = PATH_H_PBUFFER (tb->tb_path, h - 1);
+ struct block_head * blkh;
X
X
X if ( tb->blknum[h] != 1 )
X reiserfs_panic(0, "balance_internal", "One new node required for creating the new root");
X /* S[h] = empty buffer from the list FEB. */
X tbSh = get_FEB (tb);
- B_BLK_HEAD(tbSh)->blk_level = cpu_to_le16 (h + 1);
+ blkh = B_BLK_HEAD(tbSh);
+ set_blkh_level( blkh, h + 1 );
X
X /* Put the unique node-pointer to S[h] that points to S[h-1]. */
X
X dc = B_N_CHILD(tbSh, 0);
- dc->dc_block_number = cpu_to_le32 (tbSh_1->b_blocknr);
- dc->dc_size = cpu_to_le16 (MAX_CHILD_SIZE (tbSh_1) - B_FREE_SPACE (tbSh_1));
+ put_dc_block_number( dc, tbSh_1->b_blocknr );
+ put_dc_size( dc, (MAX_CHILD_SIZE (tbSh_1) - B_FREE_SPACE (tbSh_1)));
X
X tb->insert_size[h] -= DC_SIZE;
- B_BLK_HEAD(tbSh)->blk_free_space = cpu_to_le16 (B_FREE_SPACE (tbSh) - DC_SIZE);
+ set_blkh_free_space( blkh, blkh_free_space(blkh) - DC_SIZE );
X
X do_balance_mark_internal_dirty (tb, tbSh, 0);
X
@@ -929,8 +945,8 @@
X PATH_OFFSET_PBUFFER(tb->tb_path, ILLEGAL_PATH_ELEMENT_OFFSET) = tbSh;
X
X /* Change root in structure super block. */
- tb->tb_sb->u.reiserfs_sb.s_rs->s_root_block = cpu_to_le32 (tbSh->b_blocknr);
- tb->tb_sb->u.reiserfs_sb.s_rs->s_tree_height = cpu_to_le16 (SB_TREE_HEIGHT (tb->tb_sb) + 1);
+ PUT_SB_ROOT_BLOCK( tb->tb_sb, tbSh->b_blocknr );
+ PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) + 1 );
X do_balance_mark_sb_dirty (tb, tb->tb_sb->u.reiserfs_sb.s_sbh, 1);
X tb->tb_sb->s_dirt = 1;
X }
@@ -943,7 +959,7 @@
X /* S_new = free buffer from list FEB */
X S_new = get_FEB(tb);
X
- B_BLK_HEAD(S_new)->blk_level = cpu_to_le16 (h + 1);
+ set_blkh_level( B_BLK_HEAD(S_new), h + 1 );
X
X dest_bi.tb = tb;
X dest_bi.bi_bh = S_new;
@@ -998,9 +1014,9 @@
X /* replace first node-ptr in S_new by node-ptr to insert_ptr[insert_num-k-1] */
X
X dc = B_N_CHILD(S_new,0);
- dc->dc_size = cpu_to_le16 (MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
- B_FREE_SPACE(insert_ptr[insert_num-k-1]));
- dc->dc_block_number = cpu_to_le32 (insert_ptr[insert_num-k-1]->b_blocknr);
+ put_dc_size( dc, (MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
+ B_FREE_SPACE(insert_ptr[insert_num-k-1])) );
+ put_dc_block_number( dc, insert_ptr[insert_num-k-1]->b_blocknr );
X
X do_balance_mark_internal_dirty (tb, S_new,0);
X
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- v2.4.12/linux/fs/reiserfs/inode.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/inode.c Sun Oct 14 10:31:45 2001
@@ -8,6 +8,7 @@
X #include <linux/locks.h>
X #include <linux/smp_lock.h>
X #include <asm/uaccess.h>
+#include <asm/unaligned.h>
X
X /* args for the create parameter of reiserfs_get_block */
X #define GET_BLOCK_NO_CREATE 0 /* don't create new blocks or convert tails */
@@ -34,6 +35,7 @@
X down (&inode->i_sem);
X
X journal_begin(&th, inode->i_sb, jbegin_count) ;
+ reiserfs_update_inode_transaction(inode) ;
X windex = push_journal_writer("delete_inode") ;
X
X reiserfs_delete_object (&th, inode);
@@ -53,26 +55,26 @@
X }
X
X static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid,
- loff_t offset, int type, int length)
+ loff_t offset, int type, int length )
X {
- key->version = version;
+ key->version = version;
X
- key->on_disk_key.k_dir_id = dirid;
- key->on_disk_key.k_objectid = objectid;
- set_cpu_key_k_offset (key, offset);
- set_cpu_key_k_type (key, type);
- key->key_length = length;
+ key->on_disk_key.k_dir_id = dirid;
+ key->on_disk_key.k_objectid = objectid;
+ set_cpu_key_k_offset (key, offset);
+ set_cpu_key_k_type (key, type);
+ key->key_length = length;
X }
X
X
X /* take base of inode_key (it comes from inode always) (dirid, objectid) and version from an inode, set
X offset and type of key */
X void make_cpu_key (struct cpu_key * key, const struct inode * inode, loff_t offset,
- int type, int length)
+ int type, int length )
X {
X _make_cpu_key (key, inode_items_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
- le32_to_cpu (INODE_PKEY (inode)->k_objectid),
- offset, type, length);
+ le32_to_cpu (INODE_PKEY (inode)->k_objectid),
+ offset, type, length);
X }
X
X
@@ -86,14 +88,14 @@
X ih->ih_key.k_dir_id = cpu_to_le32 (key->on_disk_key.k_dir_id);
X ih->ih_key.k_objectid = cpu_to_le32 (key->on_disk_key.k_objectid);
X }
- ih->ih_version = cpu_to_le16 (version);
+ put_ih_version( ih, version );
X set_le_ih_k_offset (ih, offset);
X set_le_ih_k_type (ih, type);
- ih->ih_item_len = cpu_to_le16 (length);
+ put_ih_item_len( ih, length );
X /* set_ih_free_space (ih, 0);*/
X // for directory items it is entry count, for directs and stat
X // datas - 0xffff, for indirects - 0
- ih->u.ih_entry_count = cpu_to_le16 (entry_count);
+ put_ih_entry_count( ih, entry_count );
X }
X
X static void add_to_flushlist(struct inode *inode, struct buffer_head *bh) {
@@ -159,6 +161,7 @@
X static b_blocknr_t find_tag (struct buffer_head * bh, struct item_head * ih,
X __u32 * item, int pos_in_item)
X {
+ __u32 block ;
X if (!is_indirect_le_ih (ih))
X /* something more complicated could be here */
X return bh->b_blocknr;
@@ -168,8 +171,9 @@
X if (pos_in_item == I_UNFM_NUM (ih))
X pos_in_item --;
X while (pos_in_item >= 0) {
- if (item [pos_in_item])
- return item [pos_in_item];
+ block = get_block_num(item, pos_in_item) ;
+ if (block)
+ return block ;
X pos_in_item --;
X }
X return bh->b_blocknr;
@@ -184,7 +188,8 @@
X {
X if (allocated)
X return 0;
- if (retval == POSITION_FOUND && is_indirect_le_ih (ih) && item[pos_in_item])
+ if (retval == POSITION_FOUND && is_indirect_le_ih (ih) &&
+ get_block_num(item, pos_in_item))
X return 0;
X return 1;
X }
@@ -226,6 +231,7 @@
X reiserfs_update_sd(th, inode) ;
X journal_end(th, s, len) ;
X journal_begin(th, s, len) ;
+ reiserfs_update_inode_transaction(inode) ;
X }
X
X // it is called by get_block when create == 0. Returns block number
@@ -276,7 +282,7 @@
X /* FIXME: here we could cache indirect item or part of it in
X the inode to avoid search_by_key in case of subsequent
X access to file */
- blocknr = le32_to_cpu (ind_item [path.pos_in_item]);
+ blocknr = get_block_num(ind_item, path.pos_in_item) ;
X ret = 0 ;
X if (blocknr) {
X bh_result->b_dev = inode->i_dev;
@@ -320,10 +326,10 @@
X ** kmap schedules
X */
X if (!p) {
- p = (char *)kmap(bh_result->b_page) ;
- if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
- goto research;
- }
+ p = (char *)kmap(bh_result->b_page) ;
+ if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
+ goto research;
+ }
X }
X p += offset ;
X memset (p, 0, inode->i_sb->s_blocksize);
@@ -342,7 +348,7 @@
X chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item;


X done = 1 ;
X } else {

- chars = le16_to_cpu (ih->ih_item_len) - path.pos_in_item;
+ chars = ih_item_len(ih) - path.pos_in_item;
X }
X memcpy (p, B_I_PITEM (bh, ih) + path.pos_in_item, chars);
X
@@ -565,6 +571,7 @@
X TYPE_ANY, 3/*key length*/);
X if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
X journal_begin(&th, inode->i_sb, jbegin_count) ;
+ reiserfs_update_inode_transaction(inode) ;
X transaction_started = 1 ;


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 43'
echo 'File patch-2.4.13 is continued in part 44'
echo "44" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:14 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part44

#!/bin/sh -x
# this is part 44 of a 53 - part archive


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

if test "$Scheck" != 44; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X }
X research:
@@ -589,6 +596,7 @@
X if (!transaction_started) {
X pathrelse(&path) ;


X journal_begin(&th, inode->i_sb, jbegin_count) ;
+ reiserfs_update_inode_transaction(inode) ;
X transaction_started = 1 ;

X goto research ;
X }
@@ -616,12 +624,11 @@
X }
X
X if (indirect_item_found (retval, ih)) {
- b_blocknr_t unfm_ptr;
-
+ b_blocknr_t unfm_ptr;
X /* 'block'-th block is in the file already (there is
X corresponding cell in some indirect item). But it may be
X zero unformatted node pointer (hole) */
- unfm_ptr = le32_to_cpu (item[pos_in_item]);
+ unfm_ptr = get_block_num (item, pos_in_item);
X if (unfm_ptr == 0) {
X /* use allocated block to plug the hole */
X reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
@@ -630,8 +637,8 @@
X goto research;
X }
X bh_result->b_state |= (1UL << BH_New);
- item[pos_in_item] = cpu_to_le32 (allocated_block_nr);
- unfm_ptr = allocated_block_nr;
+ put_block_num(item, pos_in_item, allocated_block_nr) ;
+ unfm_ptr = allocated_block_nr;
X journal_mark_dirty (&th, inode->i_sb, bh);
X inode->i_blocks += (inode->i_sb->s_blocksize / 512) ;
X reiserfs_update_sd(&th, inode) ;
@@ -658,6 +665,7 @@
X */
X pathrelse(&path) ;


X journal_begin(&th, inode->i_sb, jbegin_count) ;
+ reiserfs_update_inode_transaction(inode) ;
X transaction_started = 1 ;

X goto research;
X }
@@ -758,7 +766,7 @@
X struct cpu_key tmp_key;
X struct unfm_nodeinfo un = {0, 0};
X
- RFALSE( pos_in_item != le16_to_cpu (ih->ih_item_len) / UNFM_P_SIZE,
+ RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
X "vs-804: invalid position for append");
X /* indirect item has to be appended, set up key of that position */
X make_cpu_key (&tmp_key, inode,
@@ -871,17 +879,17 @@
X unsigned long blocks;
X
X inode_items_version (inode) = ITEM_VERSION_1;
- inode->i_mode = le16_to_cpu (sd->sd_mode);
- inode->i_nlink = le16_to_cpu (sd->sd_nlink);
- inode->i_uid = le16_to_cpu (sd->sd_uid);
- inode->i_gid = le16_to_cpu (sd->sd_gid);
- inode->i_size = le32_to_cpu (sd->sd_size);
- inode->i_atime = le32_to_cpu (sd->sd_atime);
- inode->i_mtime = le32_to_cpu (sd->sd_mtime);
- inode->i_ctime = le32_to_cpu (sd->sd_ctime);
+ inode->i_mode = sd_v1_mode(sd);
+ inode->i_nlink = sd_v1_nlink(sd);
+ inode->i_uid = sd_v1_uid(sd);
+ inode->i_gid = sd_v1_gid(sd);
+ inode->i_size = sd_v1_size(sd);
+ inode->i_atime = sd_v1_atime(sd);
+ inode->i_mtime = sd_v1_mtime(sd);
+ inode->i_ctime = sd_v1_ctime(sd);
X
- inode->i_blocks = le32_to_cpu (sd->u.sd_blocks);
- inode->i_generation = INODE_PKEY (inode)->k_dir_id;
+ inode->i_blocks = sd_v1_blocks(sd);
+ inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
X blocks = (inode->i_size + 511) >> 9;
X blocks = _ROUND_UP (blocks, inode->i_blksize >> 9);
X if (inode->i_blocks > blocks) {
@@ -893,8 +901,8 @@
X inode->i_blocks = blocks;
X }
X
- rdev = le32_to_cpu (sd->u.sd_rdev);
- inode->u.reiserfs_i.i_first_direct_byte = le32_to_cpu (sd->sd_first_direct_byte);
+ rdev = sd_v1_rdev(sd);
+ inode->u.reiserfs_i.i_first_direct_byte = sd_v1_first_direct_byte(sd);
X } else {
X // new stat data found, but object may have old items
X // (directories and symlinks)
@@ -902,24 +910,26 @@
X
X /* both old and new directories have old keys */
X //version = (S_ISDIR (sd->sd_mode) ? ITEM_VERSION_1 : ITEM_VERSION_2);
- if (S_ISDIR (sd->sd_mode) || S_ISLNK (sd->sd_mode))
+
+ inode->i_mode = sd_v2_mode(sd);
+ inode->i_nlink = sd_v2_nlink(sd);
+ inode->i_uid = sd_v2_uid(sd);
+ inode->i_size = sd_v2_size(sd);
+ inode->i_gid = sd_v2_gid(sd);
+ inode->i_mtime = sd_v2_mtime(sd);
+ inode->i_atime = sd_v2_atime(sd);
+ inode->i_ctime = sd_v2_ctime(sd);
+ inode->i_blocks = sd_v2_blocks(sd);
+ rdev = sd_v2_rdev(sd);
+ if( S_ISCHR( inode -> i_mode ) || S_ISBLK( inode -> i_mode ) )
+ inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
+ else
+ inode->i_generation = sd_v2_generation(sd);
+
+ if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
X inode_items_version (inode) = ITEM_VERSION_1;
X else
X inode_items_version (inode) = ITEM_VERSION_2;
- inode->i_mode = le16_to_cpu (sd->sd_mode);
- inode->i_nlink = le32_to_cpu (sd->sd_nlink);
- inode->i_uid = le32_to_cpu (sd->sd_uid);
- inode->i_size = le64_to_cpu (sd->sd_size);
- inode->i_gid = le32_to_cpu (sd->sd_gid);
- inode->i_mtime = le32_to_cpu (sd->sd_mtime);
- inode->i_atime = le32_to_cpu (sd->sd_atime);
- inode->i_ctime = le32_to_cpu (sd->sd_ctime);
- inode->i_blocks = le32_to_cpu (sd->sd_blocks);
- rdev = le32_to_cpu (sd->u.sd_rdev);
- if( S_ISCHR( inode -> i_mode ) || S_ISBLK( inode -> i_mode ) )
- inode->i_generation = INODE_PKEY (inode)->k_dir_id;
- else
- inode->i_generation = le32_to_cpu( sd->u.sd_generation );
X }
X
X /* nopack = 0, by default */
@@ -948,19 +958,21 @@
X {
X struct stat_data * sd_v2 = (struct stat_data *)sd;
X
- sd_v2->sd_mode = cpu_to_le16 (inode->i_mode);
- sd_v2->sd_nlink = cpu_to_le16 (inode->i_nlink);
- sd_v2->sd_uid = cpu_to_le32 (inode->i_uid);
- sd_v2->sd_size = cpu_to_le64 (inode->i_size);
- sd_v2->sd_gid = cpu_to_le32 (inode->i_gid);
- sd_v2->sd_mtime = cpu_to_le32 (inode->i_mtime);
- sd_v2->sd_atime = cpu_to_le32 (inode->i_atime);
- sd_v2->sd_ctime = cpu_to_le32 (inode->i_ctime);
- sd_v2->sd_blocks = cpu_to_le32 (inode->i_blocks);
+ set_sd_v2_mode(sd_v2, inode->i_mode );
+ set_sd_v2_nlink(sd_v2, inode->i_nlink );
+ set_sd_v2_uid(sd_v2, inode->i_uid );
+ set_sd_v2_size(sd_v2, inode->i_size );
+ set_sd_v2_gid(sd_v2, inode->i_gid );
+ set_sd_v2_mtime(sd_v2, inode->i_mtime );
+ set_sd_v2_atime(sd_v2, inode->i_atime );
+ set_sd_v2_ctime(sd_v2, inode->i_ctime );
+ set_sd_v2_blocks(sd_v2, inode->i_blocks );
X if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- sd_v2->u.sd_rdev = cpu_to_le32 (inode->i_rdev);
- } else {
- sd_v2->u.sd_generation = cpu_to_le32( inode -> i_generation );
+ set_sd_v2_rdev(sd_v2, inode->i_rdev );
+}
+ else
+ {
+ set_sd_v2_generation(sd_v2, inode->i_generation);
X }
X }
X
@@ -970,21 +982,22 @@
X {
X struct stat_data_v1 * sd_v1 = (struct stat_data_v1 *)sd;
X
- sd_v1->sd_mode = cpu_to_le16 (inode->i_mode);
- sd_v1->sd_uid = cpu_to_le16 (inode->i_uid);
- sd_v1->sd_gid = cpu_to_le16 (inode->i_gid);
- sd_v1->sd_nlink = cpu_to_le16 (inode->i_nlink);
- sd_v1->sd_size = cpu_to_le32 (inode->i_size);
- sd_v1->sd_atime = cpu_to_le32 (inode->i_atime);
- sd_v1->sd_ctime = cpu_to_le32 (inode->i_ctime);
- sd_v1->sd_mtime = cpu_to_le32 (inode->i_mtime);
+ set_sd_v1_mode(sd_v1, inode->i_mode );
+ set_sd_v1_uid(sd_v1, inode->i_uid );
+ set_sd_v1_gid(sd_v1, inode->i_gid );
+ set_sd_v1_nlink(sd_v1, inode->i_nlink );
+ set_sd_v1_size(sd_v1, inode->i_size );
+ set_sd_v1_atime(sd_v1, inode->i_atime );
+ set_sd_v1_ctime(sd_v1, inode->i_ctime );
+ set_sd_v1_mtime(sd_v1, inode->i_mtime );
+
X if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- sd_v1->u.sd_rdev = cpu_to_le32 (inode->i_rdev);
+ set_sd_v1_rdev(sd_v1, inode->i_rdev );
X else
- sd_v1->u.sd_blocks = cpu_to_le32 (inode->i_blocks);
+ set_sd_v1_blocks(sd_v1, inode->i_blocks );
X
X // Sigh. i_first_direct_byte is back
- sd_v1->sd_first_direct_byte = cpu_to_le32 (inode->u.reiserfs_i.i_first_direct_byte);
+ set_sd_v1_first_direct_byte(sd_v1, inode->u.reiserfs_i.i_first_direct_byte);
X }
X
X
@@ -1110,8 +1123,8 @@
X retval = search_item (inode->i_sb, &key, &path_to_sd);
X if (retval == IO_ERROR) {
X reiserfs_warning ("vs-13070: reiserfs_read_inode2: "
- "i/o failure occurred trying to find stat data of %K\n",
- &key);
+ "i/o failure occurred trying to find stat data of %K\n",
+ &key);
X make_bad_inode(inode) ;
X return;
X }
@@ -1297,6 +1310,10 @@
X return ;
X }
X lock_kernel() ;
+
+ /* this is really only used for atime updates, so they don't have
+ ** to be included in O_SYNC or fsync
+ */
X journal_begin(&th, inode->i_sb, 1) ;
X reiserfs_update_sd (&th, inode);
X journal_end(&th, inode->i_sb, 1) ;
@@ -1317,7 +1334,8 @@
X /* stat data of new object is inserted already, this inserts the item
X containing "." and ".." entries */
X static int reiserfs_new_directory (struct reiserfs_transaction_handle *th,
- struct item_head * ih, struct path * path, const struct inode * dir)
+ struct item_head * ih, struct path * path,
+ const struct inode * dir)
X {
X struct super_block * sb = th->t_super;
X char empty_dir [EMPTY_DIR_SIZE];
@@ -1335,14 +1353,14 @@
X make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
X
X make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
- le32_to_cpu (INODE_PKEY (dir)->k_dir_id),
- le32_to_cpu (INODE_PKEY (dir)->k_objectid));
+ INODE_PKEY (dir)->k_dir_id,
+ INODE_PKEY (dir)->k_objectid );
X } else {
X make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
X
X make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
- le32_to_cpu (INODE_PKEY (dir)->k_dir_id),
- le32_to_cpu (INODE_PKEY (dir)->k_objectid));
+ INODE_PKEY (dir)->k_dir_id,
+ INODE_PKEY (dir)->k_objectid );
X }
X
X /* look for place in the tree for new item */
@@ -1441,7 +1459,7 @@
X ** note that the private part of inode isn't filled in yet, we have
X ** to use the directory.
X */
- inode->i_generation = INODE_PKEY (dir)->k_objectid;
+ inode->i_generation = le32_to_cpu (INODE_PKEY (dir)->k_objectid);
X else
X #if defined( USE_INODE_GENERATION_COUNTER )
X inode->i_generation =
@@ -1671,6 +1689,7 @@
X ** (it will unmap bh if it packs).
X */
X journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
+ reiserfs_update_inode_transaction(p_s_inode) ;
X windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
X reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
X pop_journal_writer(windex) ;
@@ -1717,6 +1736,7 @@
X start_over:
X lock_kernel() ;


X journal_begin(&th, inode->i_sb, jbegin_count) ;
+ reiserfs_update_inode_transaction(inode) ;
X

X make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;
X
@@ -1737,18 +1757,18 @@
X if (bytes_copied > 0) {
X reiserfs_warning("clm-6002: bytes_copied %d\n", bytes_copied) ;
X }
- if (!item[pos_in_item]) {
+ if (!get_block_num(item, pos_in_item)) {
X /* crap, we are writing to a hole */
X use_get_block = 1;
X goto out ;
X }
- set_block_dev_mapped(bh_result, le32_to_cpu(item[pos_in_item]), inode);
- mark_buffer_uptodate(bh_result, 1);
+ set_block_dev_mapped(bh_result, get_block_num(item,pos_in_item),inode);
+ mark_buffer_uptodate(bh_result, 1);
X } else if (is_direct_le_ih(ih)) {
X char *p ;
X p = page_address(bh_result->b_page) ;
X p += (byte_offset -1) & (PAGE_CACHE_SIZE - 1) ;
- copy_size = le16_to_cpu(ih->ih_item_len) - pos_in_item ;
+ copy_size = ih_item_len(ih) - pos_in_item;
X
X fs_gen = get_generation(inode->i_sb) ;
X copy_item_head(&tmp_ih, ih) ;
@@ -1763,7 +1783,7 @@
X journal_mark_dirty(&th, inode->i_sb, bh) ;
X bytes_copied += copy_size ;
X set_block_dev_mapped(bh_result, 0, inode);
- mark_buffer_uptodate(bh_result, 1);
+ mark_buffer_uptodate(bh_result, 1);
X
X /* are there still bytes left? */
X if (bytes_copied < bh_result->b_size &&
@@ -1944,26 +1964,38 @@
X return generic_block_bmap(as, block, reiserfs_bmap) ;
X }
X
-static int reiserfs_commit_write(struct file *f, struct page *page,
- unsigned from, unsigned to) {
- struct inode *inode = page->mapping->host;
- int ret ;
-
+static int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to) {
+ struct inode *inode = page->mapping->host ;
+ loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ int ret ;
+
X reiserfs_wait_on_write_block(inode->i_sb) ;
+
+ /* generic_commit_write does this for us, but does not update the
+ ** transaction tracking stuff when the size changes. So, we have
+ ** to do the i_size updates here.
+ */
+ if (pos > inode->i_size) {
+ struct reiserfs_transaction_handle th ;
+ lock_kernel() ;
+ journal_begin(&th, inode->i_sb, 1) ;
+ reiserfs_update_inode_transaction(inode) ;
+ inode->i_size = pos ;
+ reiserfs_update_sd(&th, inode) ;
+ journal_end(&th, inode->i_sb, 1) ;
+ unlock_kernel() ;
+ }
+
X ret = generic_commit_write(f, page, from, to) ;
X
X /* we test for O_SYNC here so we can commit the transaction
X ** for any packed tails the file might have had
X */
X if (f->f_flags & O_SYNC) {
- struct reiserfs_transaction_handle th ;
X lock_kernel() ;
- journal_begin(&th, inode->i_sb, 1) ;
- reiserfs_prepare_for_journal(inode->i_sb,
- SB_BUFFER_WITH_SB(inode->i_sb), 1) ;
- journal_mark_dirty(&th, inode->i_sb, SB_BUFFER_WITH_SB(inode->i_sb)) ;
- journal_end_sync(&th, inode->i_sb, 1) ;
- unlock_kernel() ;
+ reiserfs_commit_for_inode(inode) ;
+ unlock_kernel();
X }
X return ret ;
X }
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/item_ops.c linux/fs/reiserfs/item_ops.c
--- v2.4.12/linux/fs/reiserfs/item_ops.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/item_ops.c Fri Oct 12 14:19:28 2001
@@ -48,13 +48,15 @@
X if (stat_data_v1 (ih)) {
X struct stat_data_v1 * sd = (struct stat_data_v1 *)item;
X
- printk ("\t0%-6o | %6u | %2u | %d | %s\n", sd->sd_mode, sd->sd_size,
- sd->sd_nlink, sd->sd_first_direct_byte, print_time (sd->sd_mtime));
+ printk ("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd),
+ sd_v1_size(sd), sd_v1_nlink(sd), sd_v1_first_direct_byte(sd),
+ print_time( sd_v1_mtime(sd) ) );
X } else {
X struct stat_data * sd = (struct stat_data *)item;
X
- printk ("\t0%-6o | %6Lu | %2u | %d | %s\n", sd->sd_mode, (unsigned long long)(sd->sd_size),
- sd->sd_nlink, sd->u.sd_rdev, print_time (sd->sd_mtime));
+ printk ("\t0%-6o | %6Lu | %2u | %d | %s\n", sd_v2_mode(sd),
+ (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
+ sd_v2_rdev(sd), print_time(sd_v2_mtime(sd)));
X }
X }
X
@@ -130,7 +132,7 @@
X //
X static int direct_bytes_number (struct item_head * ih, int block_size)
X {
- return le16_to_cpu (ih->ih_item_len);
+ return ih_item_len(ih);
X }
X
X

@@ -156,7 +158,7 @@
X

X // return;
X printk ("\"");
- while (j < ih->ih_item_len)
+ while (j < ih_item_len(ih))
X printk ("%c", item[j++]);
X printk ("\"\n");
X }


@@ -234,7 +236,7 @@
X

X static int indirect_bytes_number (struct item_head * ih, int block_size)
X {
- return le16_to_cpu (ih->ih_item_len) / UNFM_P_SIZE * block_size; //- get_ih_free_space (ih);
+ return ih_item_len(ih) / UNFM_P_SIZE * block_size; //- get_ih_free_space (ih);
X }
X
X
@@ -299,14 +301,14 @@
X
X unp = (__u32 *)item;
X
- if (ih->ih_item_len % UNFM_P_SIZE)
+ if (ih_item_len(ih) % UNFM_P_SIZE)
X printk ("indirect_print_item: invalid item len");
X
X printk ("%d pointers\n[ ", (int)I_UNFM_NUM (ih));
X for (j = 0; j < I_UNFM_NUM (ih); j ++) {
- if (sequence_finished (prev, &num, unp[j])) {
+ if (sequence_finished (prev, &num, get_block_num(unp, j))) {
X print_sequence (prev, num);
- start_new_sequence (&prev, &num, unp[j]);
+ start_new_sequence (&prev, &num, get_block_num(unp, j));
X }
X }
X print_sequence (prev, num);
@@ -424,8 +426,8 @@
X deh = (struct reiserfs_de_head *)item;
X
X for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
- namelen = (i ? ((deh - 1)->deh_location) : ih->ih_item_len) - deh->deh_location;
- name = item + deh->deh_location;
+ namelen = (i ? (deh_location(deh - 1)) : ih_item_len(ih)) - deh_location(deh);
+ name = item + deh_location(deh);
X if (name[namelen-1] == 0)
X namelen = strlen (name);
X namebuf[0] = '"';


@@ -441,7 +443,7 @@
X

X printk ("%d: %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n",
X i, namebuf,
- deh->deh_dir_id, deh->deh_objectid,
+ deh_dir_id(deh), deh_objectid(deh),
X GET_HASH_VALUE (deh_offset (deh)), GET_GENERATION_NUMBER ((deh_offset (deh))),
X (de_hidden (deh)) ? "HIDDEN" : "VISIBLE");
X }
@@ -466,9 +468,9 @@
X
X struct direntry_uarea {
X int flags;
- short entry_count;
- short entry_sizes[1];
-};
+ __u16 entry_count;
+ __u16 entry_sizes[1];
+} __attribute__ ((__packed__)) ;
X
X
X /*
@@ -531,8 +533,9 @@
X
X for (i = 0; i < dir_u->entry_count; i ++) {
X j = old_entry_num (is_affected, i, vn->vn_pos_in_item, vn->vn_mode);
- dir_u->entry_sizes[i] = (j ? le16_to_cpu (deh[j - 1].deh_location) : le16_to_cpu (vi->vi_ih->ih_item_len)) -
- le16_to_cpu (deh[j].deh_location) + DEH_SIZE;
+ dir_u->entry_sizes[i] = (j ? deh_location( &(deh[j - 1]) ) :
+ ih_item_len (vi->vi_ih)) -
+ deh_location( &(deh[j])) + DEH_SIZE;
X }
X
X size += (dir_u->entry_count * sizeof (short));
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- v2.4.12/linux/fs/reiserfs/journal.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/journal.c Fri Oct 12 14:20:42 2001
@@ -746,7 +746,7 @@
X }
X atomic_set(&(jl->j_commit_flushing), 0) ;
X wake_up(&(jl->j_commit_wait)) ;
-
+


X s->s_dirt = 1 ;

X return 0 ;
X }
@@ -1936,7 +1936,7 @@
X where it belongs */
X
X INIT_LIST_HEAD (&SB_JOURNAL(p_s_sb)->j_prealloc_list);
-
+
X if (reiserfs_dont_log (p_s_sb))
X return 0;
X
@@ -2319,6 +2319,11 @@
X ** will wait until the current transaction is done/commited before returning
X */
X int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
+
+ if (SB_JOURNAL(p_s_sb)->j_len == 0) {
+ reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
+ journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
+ }
X return do_journal_end(th, p_s_sb, nblocks, COMMIT_NOW | WAIT) ;
X }
X
@@ -2416,8 +2421,8 @@
X journal_mark_dirty(&th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
X do_journal_end(&th, p_s_sb,1, COMMIT_NOW | WAIT) ;
X }
- reiserfs_journal_kupdate(p_s_sb) ;
- return 0 ;
+ reiserfs_journal_kupdate(p_s_sb) ;


+ return 0 ;
X }
X

X /*
@@ -2603,6 +2608,41 @@


X return 0 ;
X }
X

+void reiserfs_update_inode_transaction(struct inode *inode) {
+
+ inode->u.reiserfs_i.i_trans_index = SB_JOURNAL_LIST_INDEX(inode->i_sb);
+
+ inode->u.reiserfs_i.i_trans_id = SB_JOURNAL(inode->i_sb)->j_trans_id ;
+}
+
+static int reiserfs_inode_in_this_transaction(struct inode *inode) {
+ if (inode->u.reiserfs_i.i_trans_id == SB_JOURNAL(inode->i_sb)->j_trans_id ||
+ inode->u.reiserfs_i.i_trans_id == 0) {
+ return 1;
+ }

+ return 0 ;
+}
+

+void reiserfs_commit_for_inode(struct inode *inode) {
+ struct reiserfs_journal_list *jl ;
+ struct reiserfs_transaction_handle th ;
+ struct super_block *sb = inode->i_sb ;
+
+ jl = SB_JOURNAL_LIST(sb) + inode->u.reiserfs_i.i_trans_index ;
+
+ /* is it from the current transaction, or from an unknown transaction? */
+ if (reiserfs_inode_in_this_transaction(inode)) {
+ journal_join(&th, sb, 1) ;
+ reiserfs_update_inode_transaction(inode) ;
+ journal_end_sync(&th, sb, 1) ;
+ } else if (jl->j_trans_id == inode->u.reiserfs_i.i_trans_id) {
+ flush_commit_list(sb, jl, 1) ;
+ }
+ /* if the transaction id does not match, this list is long since flushed
+ ** and we don't have to do anything here
+ */
+}
+
X void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb,
X struct buffer_head *bh) {
X if (reiserfs_dont_log (p_s_sb))
@@ -2645,7 +2685,7 @@
X }
X }
X
-/*
+/*
X ** long and ugly. If flush, will not return until all commit
X ** blocks and all real buffers in the trans are on disk.
X ** If no_async, won't return until all commit blocks are on disk.
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/lbalance.c linux/fs/reiserfs/lbalance.c
--- v2.4.12/linux/fs/reiserfs/lbalance.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/lbalance.c Fri Oct 12 14:19:28 2001
@@ -42,9 +42,10 @@
X /* length of all record to be copied and first byte of the last of them */
X deh = B_I_DEH (source, ih);
X if (copy_count) {
- copy_records_len = (from ? deh[from - 1].deh_location : ih->ih_item_len) -
- deh[from + copy_count - 1].deh_location;
- records = source->b_data + ih->ih_item_location + deh[from + copy_count - 1].deh_location;
+ copy_records_len = (from ? deh_location( &(deh[from - 1]) ) :
+ ih_item_len(ih)) - deh_location( &(deh[from + copy_count - 1]));
+ records = source->b_data + ih_location(ih) +
+ deh_location( &(deh[from + copy_count - 1]));
X } else {
X copy_records_len = 0;
X records = 0;


@@ -55,26 +56,26 @@
X

X /* if there are no items in dest or the first/last item in dest is not item of the same directory */
X if ( (item_num_in_dest == - 1) ||
- (last_first == FIRST_TO_LAST && le_key_k_offset (ih_version (ih), &(ih->ih_key)) == DOT_OFFSET) ||
+ (last_first == FIRST_TO_LAST && le_ih_k_offset (ih) == DOT_OFFSET) ||
X (last_first == LAST_TO_FIRST && comp_short_le_keys/*COMP_SHORT_KEYS*/ (&ih->ih_key, B_N_PKEY (dest, item_num_in_dest)))) {
X /* create new item in dest */
X struct item_head new_ih;
X
X /* form item header */
X memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
- new_ih.ih_version = cpu_to_le16 (ITEM_VERSION_1);
+ put_ih_version( &new_ih, ITEM_VERSION_1 );
X /* calculate item len */
- new_ih.ih_item_len = cpu_to_le16 (DEH_SIZE * copy_count + copy_records_len);
- I_ENTRY_COUNT(&new_ih) = 0;
+ put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len );
+ put_ih_entry_count( &new_ih, 0 );
X
X if (last_first == LAST_TO_FIRST) {
X /* form key by the following way */
X if (from < I_ENTRY_COUNT(ih)) {
- set_le_ih_k_offset (&new_ih, cpu_to_le32 (le32_to_cpu (deh[from].deh_offset)));
+ set_le_ih_k_offset( &new_ih, deh_offset( &(deh[from]) ) );
X /*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE);*/
X } else {
X /* no entries will be copied to this item in this function */
- set_le_ih_k_offset (&new_ih, cpu_to_le32 (U32_MAX));
+ set_le_ih_k_offset (&new_ih, U32_MAX);
X /* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
X }
X set_le_key_k_type (ITEM_VERSION_1, &(new_ih.ih_key), TYPE_DIRENTRY);
@@ -123,12 +124,12 @@
X /* there is nothing to merge */
X return 0;
X
- RFALSE( ! ih->ih_item_len, "vs-10010: item can not have empty length");
+ RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length");
X
X if ( is_direntry_le_ih (ih) ) {
X if ( bytes_or_entries == -1 )
X /* copy all entries to dest */
- bytes_or_entries = le16_to_cpu (ih->u.ih_entry_count);
+ bytes_or_entries = ih_entry_count(ih);
X leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, 0, 0, bytes_or_entries);
X return 1;
X }
@@ -137,11 +138,11 @@
X part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
X */
X if ( bytes_or_entries == -1 )
- bytes_or_entries = le16_to_cpu (ih->ih_item_len);
+ bytes_or_entries = ih_item_len(ih);
X
X #ifdef CONFIG_REISERFS_CHECK
X else {
- if (bytes_or_entries == le16_to_cpu (ih->ih_item_len) && is_indirect_le_ih(ih))
+ if (bytes_or_entries == ih_item_len(ih) && is_indirect_le_ih(ih))
X if (get_ih_free_space (ih))
X reiserfs_panic (0, "vs-10020: leaf_copy_boundary_item: "
X "last unformatted node must be filled entirely (%h)",
@@ -152,14 +153,14 @@
X /* merge first item (or its part) of src buffer with the last
X item of dest buffer. Both are of the same file */
X leaf_paste_in_buffer (dest_bi,
- dest_nr_item - 1, dih->ih_item_len, bytes_or_entries, B_I_PITEM(src,ih), 0
+ dest_nr_item - 1, ih_item_len(dih), bytes_or_entries, B_I_PITEM(src,ih), 0
X );
X
X if (is_indirect_le_ih (dih)) {
X RFALSE( get_ih_free_space (dih),
- "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zero free space",
- ih);
- if (bytes_or_entries == le16_to_cpu (ih->ih_item_len))
+ "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
+ ih);
+ if (bytes_or_entries == ih_item_len(ih))
X set_ih_free_space (dih, get_ih_free_space (ih));
X }
X
@@ -182,9 +183,9 @@
X if ( is_direntry_le_ih (ih)) {
X if ( bytes_or_entries == -1 )
X /* bytes_or_entries = entries number in last item body of SOURCE */
- bytes_or_entries = le16_to_cpu (ih->u.ih_entry_count);
+ bytes_or_entries = ih_entry_count(ih);
X
- leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, src_nr_item - 1, le16_to_cpu (ih->u.ih_entry_count) - bytes_or_entries, bytes_or_entries);
+ leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, src_nr_item - 1, ih_entry_count(ih) - bytes_or_entries, bytes_or_entries);


X return 1;
X }
X

@@ -194,16 +195,16 @@
X */
X
X RFALSE( is_indirect_le_ih(ih) && get_ih_free_space (ih),
- "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
+ "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
X ih);
X
X if ( bytes_or_entries == -1 ) {
X /* bytes_or_entries = length of last item body of SOURCE */
- bytes_or_entries = ih->ih_item_len;
+ bytes_or_entries = ih_item_len(ih);
X
- RFALSE( le_ih_k_offset (dih) !=
- le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
- "vs-10050: items %h and %h do not match", ih, dih);
+ RFALSE( le_ih_k_offset (dih) !=
+ le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
+ "vs-10050: items %h and %h do not match", ih, dih);
X
X /* change first item key of the DEST */
X set_le_ih_k_offset (dih, le_ih_k_offset (ih));
@@ -213,9 +214,9 @@
X set_le_ih_k_type (dih, le_ih_k_type (ih));
X } else {
X /* merge to right only part of item */
- RFALSE( le16_to_cpu (ih->ih_item_len) <= bytes_or_entries,
- "vs-10060: no so much bytes %lu (needed %lu)",
- ih->ih_item_len, bytes_or_entries);
+ RFALSE( ih_item_len(ih) <= bytes_or_entries,
+ "vs-10060: no so much bytes %lu (needed %lu)",
+ ih_item_len(ih), bytes_or_entries);
X
X /* change first item key of the DEST */
X if ( is_direct_le_ih (dih) ) {
@@ -223,15 +224,15 @@
X "vs-10070: dih %h, bytes_or_entries(%d)", dih, bytes_or_entries);
X set_le_ih_k_offset (dih, le_ih_k_offset (dih) - bytes_or_entries);
X } else {
- RFALSE( le_ih_k_offset (dih) <=
- (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
- "vs-10080: dih %h, bytes_or_entries(%d)",
- dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
+ RFALSE( le_ih_k_offset (dih) <=
+ (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
+ "vs-10080: dih %h, bytes_or_entries(%d)",
+ dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
X set_le_ih_k_offset (dih, le_ih_k_offset (dih) - ((bytes_or_entries / UNFM_P_SIZE) * dest->b_size));
X }
X }
X
- leaf_paste_in_buffer (dest_bi, 0, 0, bytes_or_entries, B_I_PITEM(src,ih) + ih->ih_item_len - bytes_or_entries, 0);
+ leaf_paste_in_buffer (dest_bi, 0, 0, bytes_or_entries, B_I_PITEM(src,ih) + ih_item_len(ih) - bytes_or_entries, 0);


X return 1;
X }
X

@@ -244,7 +245,7 @@
X int first, int cpy_num)
X {
X struct buffer_head * dest;
- int nr;
+ int nr, free_space;
X int dest_before;
X int last_loc, last_inserted_loc, location;
X int i, j;
@@ -266,7 +267,9 @@
X if (cpy_num == 0)
X return;
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD(dest))->blk_nr_item);
+ blkh = B_BLK_HEAD(dest);
+ nr = blkh_nr_item( blkh );
+ free_space = blkh_free_space(blkh);
X
X /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
X dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
@@ -274,9 +277,9 @@
X /* location of head of first new item */
X ih = B_N_PITEM_HEAD (dest, dest_before);
X
- RFALSE( le16_to_cpu (blkh->blk_free_space) < cpy_num * IH_SIZE,
- "vs-10140: not enough free space for headers %d (needed %d)",
- B_FREE_SPACE (dest), cpy_num * IH_SIZE);
+ RFALSE( blkh_free_space(blkh) < cpy_num * IH_SIZE,
+ "vs-10140: not enough free space for headers %d (needed %d)",
+ B_FREE_SPACE (dest), cpy_num * IH_SIZE);
X
X /* prepare space for headers */
X memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
@@ -284,22 +287,24 @@
X /* copy item headers */
X memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
X
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - IH_SIZE * cpy_num);
+ free_space -= (IH_SIZE * cpy_num);
+ set_blkh_free_space( blkh, free_space );
X
X /* location of unmovable item */
- j = location = (dest_before == 0) ? dest->b_size : (ih-1)->ih_item_location;
- for (i = dest_before; i < nr + cpy_num; i ++)
- ih[i-dest_before].ih_item_location =
- (location -= ih[i-dest_before].ih_item_len);
+ j = location = (dest_before == 0) ? dest->b_size : ih_location(ih-1);
+ for (i = dest_before; i < nr + cpy_num; i ++) {
+ location -= ih_item_len( ih + i - dest_before );
+ put_ih_location( ih + i - dest_before, location );
+ }
X
X /* prepare space for items */
- last_loc = ih[nr+cpy_num-1-dest_before].ih_item_location;
- last_inserted_loc = ih[cpy_num-1].ih_item_location;
+ last_loc = ih_location( &(ih[nr+cpy_num-1-dest_before]) );
+ last_inserted_loc = ih_location( &(ih[cpy_num-1]) );
X
X /* check free space */
- RFALSE( le16_to_cpu (blkh->blk_free_space) < j - last_inserted_loc,
+ RFALSE( free_space < j - last_inserted_loc,
X "vs-10150: not enough free space for items %d (needed %d)",
- le16_to_cpu (blkh->blk_free_space), j - last_inserted_loc);
+ free_space, j - last_inserted_loc);
X
X memmove (dest->b_data + last_loc,
X dest->b_data + last_loc + j - last_inserted_loc,
@@ -310,17 +315,18 @@
X j - last_inserted_loc);


X
X /* sizes, item number */

- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) + cpy_num);
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - (j - last_inserted_loc));
+ set_blkh_nr_item( blkh, nr + cpy_num );
+ set_blkh_free_space( blkh, free_space - (j - last_inserted_loc) );
X
X do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);


X
X if (dest_bi->bi_parent) {

- RFALSE( B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number != dest->b_blocknr,
- "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
- dest->b_blocknr, B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number);
- B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_size +=
- j - last_inserted_loc + IH_SIZE * cpy_num;


+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position);

+ RFALSE( dc_block_number(t_dc) != dest->b_blocknr,
+ "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
+ dest->b_blocknr, dc_block_number(t_dc));
+ put_dc_size( t_dc, dc_size(t_dc) + (j - last_inserted_loc + IH_SIZE * cpy_num ) );
X
X do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
X }
@@ -349,18 +355,17 @@
X n_ih = new item_header;
X */
X memcpy (&n_ih, ih, IH_SIZE);
- n_ih.ih_item_len = cpu_to_le16 (cpy_bytes);
+ put_ih_item_len( &n_ih, cpy_bytes );
X if (is_indirect_le_ih (ih)) {
- RFALSE( cpy_bytes == le16_to_cpu (ih->ih_item_len) &&
- get_ih_free_space (ih),
- "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
- get_ih_free_space (ih));
+ RFALSE( cpy_bytes == ih_item_len(ih) && get_ih_free_space(ih),
+ "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
+ get_ih_free_space (ih));
X set_ih_free_space (&n_ih, 0);
X }
X
X RFALSE( op_is_left_mergeable (&(ih->ih_key), src->b_size),
X "vs-10190: bad mergeability of item %h", ih);
- n_ih.ih_version = ih->ih_version;;
+ n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
X leaf_insert_into_buf (dest_bi, B_NR_ITEMS(dest), &n_ih, B_N_PITEM (src, item_num), 0);
X }
X } else {
@@ -375,24 +380,28 @@
X n_ih = new item_header;
X */
X memcpy (&n_ih, ih, SHORT_KEY_SIZE);
- n_ih.ih_version = cpu_to_le16 (ih_version (ih));
+
+ n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
+
X if (is_direct_le_ih (ih)) {
- set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + le16_to_cpu (ih->ih_item_len) - cpy_bytes);
+ set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + ih_item_len(ih) - cpy_bytes);
X set_le_ih_k_type (&n_ih, TYPE_DIRECT);
X set_ih_free_space (&n_ih, MAX_US_INT);
X } else {
X /* indirect item */
X RFALSE( !cpy_bytes && get_ih_free_space (ih),
- "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
- set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (le16_to_cpu (ih->ih_item_len) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
+ "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
+ set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (ih_item_len(ih) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
X set_le_ih_k_type (&n_ih, TYPE_INDIRECT);
X set_ih_free_space (&n_ih, get_ih_free_space (ih));
X }
X
X /* set item length */
- n_ih.ih_item_len = cpu_to_le16 (cpy_bytes);
- n_ih.ih_version = cpu_to_le16 (le16_to_cpu (ih->ih_version));
- leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + le16_to_cpu (ih->ih_item_len) - cpy_bytes, 0);
+ put_ih_item_len( &n_ih, cpy_bytes );
+
+ n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
+
+ leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
X }
X }
X }
@@ -602,21 +611,13 @@
X if (PATH_H_POSITION (tb->tb_path, 1) == 0)
X replace_key (tb, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0);
X
-#if 0
- /* change right_delimiting_key field in L0's block header */
- copy_key (B_PRIGHT_DELIM_KEY(tb->L[0]), B_PRIGHT_DELIM_KEY (S0));
-#endif
X } else {
X /* replace lkey in CFL[0] by 0-th key from S[0]; */
X replace_key (tb, tb->CFL[0], tb->lkey[0], S0, 0);
X
-#if 0
- /* change right_delimiting_key field in L0's block header */
- copy_key (B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY (S0, 0));
-#endif
- RFALSE( (shift_bytes != -1 &&
- !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
- && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&
+ RFALSE( (shift_bytes != -1 &&
+ !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
+ && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&
X (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)),
X "vs-10280: item must be mergeable");
X }
@@ -651,10 +652,6 @@
X if (shift_num) {
X replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
X
-#if 0
- /* change right_delimiting_key field in S0's block header */
- copy_key (B_PRIGHT_DELIM_KEY(S0), B_N_PKEY (tb->R[0], 0));
-#endif
X }
X
X return ret_value;
@@ -714,10 +711,10 @@
X
X if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) /* the last item is directory */
X /* len = numbers of directory entries in this item */
- len = le16_to_cpu (ih->u.ih_entry_count);
+ len = ih_entry_count(ih);
X else
X /* len = body len of item */
- len = le16_to_cpu (ih->ih_item_len);
+ len = ih_item_len(ih);
X
X /* delete the part of the last item of the bh
X do not delete item header
@@ -735,7 +732,7 @@
X int zeros_number)
X {
X struct buffer_head * bh = bi->bi_bh;
- int nr;
+ int nr, free_space;
X struct block_head * blkh;
X struct item_head * ih;
X int i;
@@ -743,37 +740,39 @@
X char * to;
X
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD (bh))->blk_nr_item);
+ blkh = B_BLK_HEAD(bh);
+ nr = blkh_nr_item(blkh);
+ free_space = blkh_free_space( blkh );
X
X /* check free space */
- RFALSE( le16_to_cpu (blkh->blk_free_space) <
- le16_to_cpu (inserted_item_ih->ih_item_len) + IH_SIZE,
- "not enough free space in block %z, new item %h",
- bh, inserted_item_ih);
- RFALSE( zeros_number > inserted_item_ih->ih_item_len,
- "vs-10172: zero number == %d, item length == %d",
- zeros_number, inserted_item_ih->ih_item_len);
+ RFALSE( free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
+ "vs-10170: not enough free space in block %z, new item %h",
+ bh, inserted_item_ih);
+ RFALSE( zeros_number > ih_item_len(inserted_item_ih),
+ "vs-10172: zero number == %d, item length == %d",
+ zeros_number, ih_item_len(inserted_item_ih));
X
X
X /* get item new item must be inserted before */
X ih = B_N_PITEM_HEAD (bh, before);
X
X /* prepare space for the body of new item */
- last_loc = nr ? ih[nr - before - 1].ih_item_location : bh->b_size;
- unmoved_loc = before ? (ih-1)->ih_item_location : bh->b_size;
+ last_loc = nr ? ih_location( &(ih[nr - before - 1]) ) : bh->b_size;
+ unmoved_loc = before ? ih_location( ih-1 ) : bh->b_size;
+
X
- memmove (bh->b_data + last_loc - inserted_item_ih->ih_item_len,
+ memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih),
X bh->b_data + last_loc, unmoved_loc - last_loc);
X
- to = bh->b_data + unmoved_loc - inserted_item_ih->ih_item_len;
+ to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
X memset (to, 0, zeros_number);
X to += zeros_number;
X
X /* copy body to prepared space */
X if (inserted_item_body)
- memmove (to, inserted_item_body, inserted_item_ih->ih_item_len - zeros_number);
+ memmove (to, inserted_item_body, ih_item_len(inserted_item_ih) - zeros_number);
X else
- memset(to, '\0', inserted_item_ih->ih_item_len - zeros_number);
+ memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
X
X /* insert item header */
X memmove (ih + 1, ih, IH_SIZE * (nr - before));
@@ -781,18 +780,21 @@
X
X /* change locations */
X for (i = before; i < nr + 1; i ++)
- ih[i-before].ih_item_location =
- (unmoved_loc -= ih[i-before].ih_item_len);
+ {
+ unmoved_loc -= ih_item_len( &(ih[i-before]));
+ put_ih_location( &(ih[i-before]), unmoved_loc );
+ }
X
X /* sizes, free space, item number */


- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) + 1);
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) -

- (IH_SIZE + inserted_item_ih->ih_item_len));
-


+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
+ set_blkh_free_space( blkh,

+ free_space - (IH_SIZE + ih_item_len(inserted_item_ih ) ) );
X do_balance_mark_leaf_dirty (bi->tb, bh, 1);


X
X if (bi->bi_parent) {

- B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size += (IH_SIZE + inserted_item_ih->ih_item_len);
+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) + (IH_SIZE + ih_item_len(inserted_item_ih)));
X do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
X }
X }
@@ -806,24 +808,27 @@
X int zeros_number)
X {
X struct buffer_head * bh = bi->bi_bh;
- int nr;
+ int nr, free_space;
X struct block_head * blkh;
X struct item_head * ih;
X int i;
X int last_loc, unmoved_loc;
X
+ blkh = B_BLK_HEAD(bh);
+ nr = blkh_nr_item(blkh);
+ free_space = blkh_free_space(blkh);
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD(bh))->blk_nr_item);
X
X /* check free space */
- RFALSE( le16_to_cpu (blkh->blk_free_space) < paste_size,
- "10175: not enough free space: needed %d, available %d",
- paste_size, le16_to_cpu (blkh->blk_free_space));
+ RFALSE( free_space < paste_size,
+ "vs-10175: not enough free space: needed %d, available %d",
+ paste_size, free_space);
+
X #ifdef CONFIG_REISERFS_CHECK
X if (zeros_number > paste_size) {
X print_cur_tb ("10177");
- reiserfs_panic (0, "vs-10177: leaf_paste_in_buffer: zero number == %d, paste_size == %d",
- zeros_number, paste_size);
+ reiserfs_panic ( 0, "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
+ zeros_number, paste_size);
X }


X #endif /* CONFIG_REISERFS_CHECK */
X

@@ -831,8 +836,8 @@
X /* item to be appended */
X ih = B_N_PITEM_HEAD(bh, affected_item_num);
X
- last_loc = ih[nr - affected_item_num - 1].ih_item_location;
- unmoved_loc = affected_item_num ? (ih-1)->ih_item_location : bh->b_size;
+ last_loc = ih_location( &(ih[nr - affected_item_num - 1]) );
+ unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size;
X
X /* prepare space */
X memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
@@ -841,17 +846,18 @@
X
X /* change locations */
X for (i = affected_item_num; i < nr; i ++)
- ih[i-affected_item_num].ih_item_location -= paste_size;
+ put_ih_location( &(ih[i-affected_item_num]),
+ ih_location( &(ih[i-affected_item_num])) - paste_size );
X
X if ( body ) {
X if (!is_direntry_le_ih (ih)) {
X if (!pos_in_item) {
X /* shift data to right */
- memmove (bh->b_data + ih->ih_item_location + paste_size,
- bh->b_data + ih->ih_item_location, ih->ih_item_len);
+ memmove (bh->b_data + ih_location(ih) + paste_size,
+ bh->b_data + ih_location(ih), ih_item_len(ih));
X /* paste data in the head of item */
- memset (bh->b_data + ih->ih_item_location, 0, zeros_number);
- memcpy (bh->b_data + ih->ih_item_location + zeros_number, body, paste_size - zeros_number);
+ memset (bh->b_data + ih_location(ih), 0, zeros_number);
+ memcpy (bh->b_data + ih_location(ih) + zeros_number, body, paste_size - zeros_number);
X } else {
X memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number);
X memcpy (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number);
@@ -859,17 +865,18 @@
X }
X }
X else
- memset(bh->b_data + unmoved_loc - paste_size,'\0',paste_size);
+ memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
X
- ih->ih_item_len += paste_size;
+ put_ih_item_len( ih, ih_item_len(ih) + paste_size );
X
X /* change free space */
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) - paste_size);
+ set_blkh_free_space( blkh, free_space - paste_size );
X
X do_balance_mark_leaf_dirty (bi->tb, bh, 0);


X
X if (bi->bi_parent) {

- B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size += paste_size;
+ struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) + paste_size );
X do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
X }
X }
@@ -905,26 +912,29 @@
X return 0;
X
X /* first byte of item */
- item = bh->b_data + ih->ih_item_location;
+ item = bh->b_data + ih_location(ih);
X
X /* entry head array */
X deh = B_I_DEH (bh, ih);
X
X /* first byte of remaining entries, those are BEFORE cut entries
X (prev_record) and length of all removed records (cut_records_len) */
- prev_record_offset = (from ? deh[from - 1].deh_location : ih->ih_item_len);
- cut_records_len = prev_record_offset/*from_record*/ - deh[from + del_count - 1].deh_location;
+ prev_record_offset = (from ? deh_location( &(deh[from - 1])) : ih_item_len(ih));
+ cut_records_len = prev_record_offset/*from_record*/ -
+ deh_location( &(deh[from + del_count - 1]));
X prev_record = item + prev_record_offset;
X
X
X /* adjust locations of remaining entries */
X for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i --)
- deh[i].deh_location -= (DEH_SIZE * del_count);
+ put_deh_location( &(deh[i]),
+ deh_location( &deh[i] ) - (DEH_SIZE * del_count ) );
X
X for (i = 0; i < from; i ++)
- deh[i].deh_location -= DEH_SIZE * del_count + cut_records_len;
+ put_deh_location( &(deh[i]),
+ deh_location( &deh[i] ) - (DEH_SIZE * del_count + cut_records_len) );
X
- I_ENTRY_COUNT(ih) -= del_count;
+ put_ih_entry_count( ih, ih_entry_count(ih) - del_count );
X
X /* shift entry head array and entries those are AFTER removed entries */
X memmove ((char *)(deh + from),
@@ -933,7 +943,7 @@
X
X /* shift records, those are BEFORE removed entries */
X memmove (prev_record - cut_records_len - DEH_SIZE * del_count,
- prev_record, item + ih->ih_item_len - prev_record);
+ prev_record, item + ih_item_len(ih) - prev_record);
X
X return DEH_SIZE * del_count + cut_records_len;
X }
@@ -957,7 +967,8 @@
X int last_loc, unmoved_loc;
X int i;
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD (bh))->blk_nr_item);
+ blkh = B_BLK_HEAD(bh);


+ nr = blkh_nr_item(blkh);
X

X /* item head of truncated item */
X ih = B_N_PITEM_HEAD (bh, cut_item_num);
@@ -967,43 +978,42 @@
X cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size);
X if (pos_in_item == 0) {
X /* change key */
- RFALSE( cut_item_num,
+ RFALSE( cut_item_num,
X "when 0-th enrty of item is cut, that item must be first in the node, not %d-th", cut_item_num);
X /* change item key by key of first entry in the item */
- set_le_ih_k_offset (ih, le32_to_cpu (B_I_DEH (bh, ih)->deh_offset));
+ set_le_ih_k_offset (ih, deh_offset(B_I_DEH (bh, ih)));
X /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/
X }
X } else {
X /* item is direct or indirect */
- RFALSE( is_statdata_le_ih (ih), "10195: item is stat data");
- RFALSE( pos_in_item &&
- pos_in_item + cut_size != le16_to_cpu (ih->ih_item_len),
- "invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
- pos_in_item, cut_size, le16_to_cpu (ih->ih_item_len));
+ RFALSE( is_statdata_le_ih (ih), "10195: item is stat data");
+ RFALSE( pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
+ "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
+ pos_in_item, cut_size, ih_item_len (ih));
X
X /* shift item body to left if cut is from the head of item */
X if (pos_in_item == 0) {
- memmove (bh->b_data + le16_to_cpu (ih->ih_item_location), bh->b_data + le16_to_cpu (ih->ih_item_location) + cut_size,
- le16_to_cpu (ih->ih_item_len) - cut_size);
+ memmove( bh->b_data + ih_location(ih),
+ bh->b_data + ih_location(ih) + cut_size,
+ ih_item_len(ih) - cut_size);
X
X /* change key of item */
X if (is_direct_le_ih (ih))
X set_le_ih_k_offset (ih, le_ih_k_offset (ih) + cut_size);
X else {
X set_le_ih_k_offset (ih, le_ih_k_offset (ih) + (cut_size / UNFM_P_SIZE) * bh->b_size);
- RFALSE( le16_to_cpu (ih->ih_item_len) == cut_size &&
- get_ih_free_space (ih),
- "10205: invalid ih_free_space (%h)", ih);
+ RFALSE( ih_item_len(ih) == cut_size && get_ih_free_space (ih),
+ "10205: invalid ih_free_space (%h)", ih);
X }
X }
X }
X
X
X /* location of the last item */
- last_loc = le16_to_cpu (ih[nr - cut_item_num - 1].ih_item_location);
+ last_loc = ih_location( &(ih[nr - cut_item_num - 1]) );
X
X /* location of the item, which is remaining at the same place */
- unmoved_loc = cut_item_num ? le16_to_cpu ((ih-1)->ih_item_location) : bh->b_size;
+ unmoved_loc = cut_item_num ? ih_location(ih-1) : bh->b_size;
X
X
X /* shift */
@@ -1011,8 +1021,7 @@
X unmoved_loc - last_loc - cut_size);
X
X /* change item length */
-/* ih->ih_item_len -= cut_size;*/
- ih->ih_item_len = cpu_to_le16 (le16_to_cpu (ih->ih_item_len) - cut_size);
+ put_ih_item_len( ih, ih_item_len(ih) - cut_size );
X
X if (is_indirect_le_ih (ih)) {
X if (pos_in_item)
@@ -1021,17 +1030,17 @@
X
X /* change locations */
X for (i = cut_item_num; i < nr; i ++)
-/* ih[i-cut_item_num].ih_item_location += cut_size;*/
- ih[i-cut_item_num].ih_item_location =
- cpu_to_le16 (le16_to_cpu (ih[i-cut_item_num].ih_item_location) + cut_size);
+ put_ih_location( &(ih[i-cut_item_num]), ih_location( &ih[i-cut_item_num]) + cut_size );
X
X /* size, free space */
- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) + cut_size);
+ set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
X
X do_balance_mark_leaf_dirty (bi->tb, bh, 0);


X
X if (bi->bi_parent) {

- B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size -= cut_size;
+ struct disk_child *t_dc;
+ t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
+ put_dc_size( t_dc, dc_size(t_dc) - cut_size );
X do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
X }
X }
@@ -1054,10 +1063,11 @@
X if (del_num == 0)
X return;
X
- nr = le16_to_cpu ((blkh = B_BLK_HEAD(bh))->blk_nr_item);
+ blkh = B_BLK_HEAD(bh);


+ nr = blkh_nr_item(blkh);
X

X RFALSE( first < 0 || first + del_num > nr,
- "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
+ "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
X
X if (first == 0 && del_num == nr) {
X /* this does not work */
@@ -1070,11 +1080,11 @@
X ih = B_N_PITEM_HEAD (bh, first);
X
X /* location of unmovable item */
- j = (first == 0) ? bh->b_size : (ih-1)->ih_item_location;
+ j = (first == 0) ? bh->b_size : ih_location(ih-1);
X
X /* delete items */
- last_loc = ih[nr-1-first].ih_item_location;
- last_removed_loc = ih[del_num-1].ih_item_location;
+ last_loc = ih_location( &(ih[nr-1-first]) );
+ last_removed_loc = ih_location( &(ih[del_num-1]) );
X
X memmove (bh->b_data + last_loc + j - last_removed_loc,
X bh->b_data + last_loc, last_removed_loc - last_loc);
@@ -1084,16 +1094,18 @@
X
X /* change item location */
X for (i = first; i < nr - del_num; i ++)
- ih[i-first].ih_item_location += j - last_removed_loc;
+ put_ih_location( &(ih[i-first]), ih_location( &(ih[i-first]) ) + (j - last_removed_loc) );


X
X /* sizes, item number */
- blkh->blk_nr_item = cpu_to_le16 (le16_to_cpu (blkh->blk_nr_item) - del_num);

- blkh->blk_free_space = cpu_to_le16 (le16_to_cpu (blkh->blk_free_space) + (j - last_removed_loc + IH_SIZE * del_num));


+ set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );

+ set_blkh_free_space( blkh, blkh_free_space(blkh) + (j - last_removed_loc + IH_SIZE * del_num) );
X
X do_balance_mark_leaf_dirty (bi->tb, bh, 0);


X
X if (bi->bi_parent) {

- B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size -= j - last_removed_loc + IH_SIZE * del_num;
+ struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);


+ put_dc_size( t_dc, dc_size(t_dc) -

+ (j - last_removed_loc + IH_SIZE * del_num));
X do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
X }
X }
@@ -1132,27 +1144,28 @@
X
X
X /* first byte of dest item */
- item = bh->b_data + ih->ih_item_location;
+ item = bh->b_data + ih_location(ih);
X
X /* entry head array */
X deh = B_I_DEH (bh, ih);
X
X /* new records will be pasted at this point */
- insert_point = item + (before ? deh[before - 1].deh_location : (ih->ih_item_len - paste_size));
+ insert_point = item + (before ? deh_location( &(deh[before - 1])) : (ih_item_len(ih) - paste_size));
X
X /* adjust locations of records that will be AFTER new records */
X for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i --)
- deh[i].deh_location += DEH_SIZE * new_entry_count;
+ put_deh_location( &(deh[i]),
+ deh_location(&(deh[i])) + (DEH_SIZE * new_entry_count ));
X
X /* adjust locations of records that will be BEFORE new records */
X for (i = 0; i < before; i ++)
- deh[i].deh_location += paste_size;
+ put_deh_location( &(deh[i]), deh_location(&(deh[i])) + paste_size );
X
X old_entry_num = I_ENTRY_COUNT(ih);
- I_ENTRY_COUNT(ih) += new_entry_count;
+ put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count );
X
X /* prepare space for pasted records */
- memmove (insert_point + paste_size, insert_point, item + (ih->ih_item_len - paste_size) - insert_point);
+ memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point);
X
X /* copy new records */
X memcpy (insert_point + DEH_SIZE * new_entry_count, records,
@@ -1168,14 +1181,18 @@
X
X /* set locations of new records */
X for (i = 0; i < new_entry_count; i ++)
- deh[i].deh_location +=
- (- new_dehs[new_entry_count - 1].deh_location + insert_point + DEH_SIZE * new_entry_count - item);
+ {
+ put_deh_location( &(deh[i]),
+ deh_location( &(deh[i] )) +
+ (- deh_location( &(new_dehs[new_entry_count - 1])) +
+ insert_point + DEH_SIZE * new_entry_count - item));
+ }
X
X
X /* change item key if neccessary (when we paste before 0-th entry */
X if (!before)
X {
- set_le_ih_k_offset (ih, le32_to_cpu (new_dehs->deh_offset));
+ set_le_ih_k_offset (ih, deh_offset(new_dehs));
X /* memcpy (&ih->ih_key.k_offset,
X &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
X }
@@ -1186,13 +1203,13 @@
X /* check record locations */
X deh = B_I_DEH (bh, ih);
X for (i = 0; i < I_ENTRY_COUNT(ih); i ++) {
- next = (i < I_ENTRY_COUNT(ih) - 1) ? deh[i + 1].deh_location : 0;
- prev = (i != 0) ? deh[i - 1].deh_location : 0;
+ next = (i < I_ENTRY_COUNT(ih) - 1) ? deh_location( &(deh[i + 1])) : 0;
+ prev = (i != 0) ? deh_location( &(deh[i - 1]) ) : 0;
X
- if (prev && prev <= deh[i].deh_location)
+ if (prev && prev <= deh_location( &(deh[i])))
X reiserfs_warning ("vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)\n",
X ih, deh + i - 1, i, deh + i);
- if (next && next >= deh[i].deh_location)
+ if (next && next >= deh_location( &(deh[i])))
X reiserfs_warning ("vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)\n",
X ih, i, deh + i, deh + i + 1);
X }
@@ -1200,6 +1217,3 @@
X #endif
X
X }
-
-
-
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- v2.4.12/linux/fs/reiserfs/namei.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/namei.c Fri Oct 12 14:20:42 2001
@@ -81,7 +81,7 @@
X
X de->de_entrylen = entry_length (de->de_bh, de->de_ih, de->de_entry_num);
X de->de_namelen = de->de_entrylen - (de_with_sd (deh) ? SD_SIZE : 0);
- de->de_name = B_I_PITEM (de->de_bh, de->de_ih) + le16_to_cpu (deh->deh_location);
+ de->de_name = B_I_PITEM (de->de_bh, de->de_ih) + deh_location(deh);
X if (de->de_name[de->de_namelen - 1] == 0)
X de->de_namelen = strlen (de->de_name);
X }
@@ -92,8 +92,8 @@
X {
X if (de->de_entry_num >= ih_entry_count (de->de_ih))
X BUG ();
- de->de_dir_id = le32_to_cpu (de->de_deh[de->de_entry_num].deh_dir_id);
- de->de_objectid = le32_to_cpu (de->de_deh[de->de_entry_num].deh_objectid);
+ de->de_dir_id = deh_dir_id( &(de->de_deh[de->de_entry_num]));
+ de->de_objectid = deh_objectid( &(de->de_deh[de->de_entry_num]));
X }
X
X
@@ -159,7 +159,7 @@
X COMP_SHORT_KEYS (&(de->de_ih->ih_key), key)) {
X print_block (de->de_bh, 0, -1, -1);
X reiserfs_panic (sb, "vs-7005: search_by_entry_key: found item %h is not directory item or "
- "does not belong to the same directory as key %k", de->de_ih, key);
+ "does not belong to the same directory as key %K", de->de_ih, key);
X }


X #endif /* CONFIG_REISERFS_CHECK */
X

@@ -322,12 +322,7 @@
X retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de);
X if (retval == IO_ERROR)
X // FIXME: still has to be dealt with
-
- /* I want you to conform to our error
- printing standard. How many times
- do I have to ask? -Hans */
-
- BUG ();
+ reiserfs_panic (dir->i_sb, "zam-7001: io error in " __FUNCTION__ "\n");
X
X /* compare names for all entries having given hash value */
X retval = linear_search_in_dir_item (&key_to_search, de, name, namelen);
@@ -434,12 +429,12 @@
X
X /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
X deh = (struct reiserfs_de_head *)buffer;
- deh->deh_location = 0;
- deh->deh_offset = cpu_to_le32 (cpu_key_k_offset (&entry_key));
- deh->deh_state = 0;
+ deh->deh_location = 0; /* JDM Endian safe if 0 */
+ put_deh_offset( deh, cpu_key_k_offset( &entry_key ) );
+ deh->deh_state = 0; /* JDM Endian safe if 0 */


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 44'
echo 'File patch-2.4.13 is continued in part 45'
echo "45" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:16 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part46

#!/bin/sh -x
# this is part 46 of a 53 - part archive


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

if test "$Scheck" != 46; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ else if (alloc_count > block_count)
X {
X alloc_count = block_count;
X eloc.logicalBlockNum += alloc_count;
@@ -765,37 +727,24 @@
X UDF_SB_LVID(sb)->freeSpaceTable[partition] =
X cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
X mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+ sb->s_dirt = 1;
X }
- sb->s_dirt = 1;
X unlock_super(sb);
- udf_debug("alloc_count=%d\n", alloc_count);
X return alloc_count;
X }
X
-static int udf_table_new_block(const struct inode * inode,
+static int udf_table_new_block(struct super_block * sb,
+ struct inode * inode,
X struct inode *table, Uint16 partition, Uint32 goal, int *err)
X {
- struct super_block *sb;
X Uint32 spread = 0xFFFFFFFF, nspread;
X Uint32 newblock = 0, adsize;
X Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
X lb_addr bloc, goal_bloc, eloc, goal_eloc;
X struct buffer_head *bh, *goal_bh;
- char etype;
-
- udf_debug("ino=%ld, partition=%d, goal=%d\n",
- inode->i_ino, partition, goal);
+ Sint8 etype;
X
X *err = -ENOSPC;
- sb = inode->i_sb;
- if (!sb)
- {
- udf_debug("nonexistent device\n");
- return newblock;
- }
-
- if (table == NULL)
- return newblock;
X
X if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
X adsize = sizeof(short_ad);
@@ -868,6 +817,14 @@
X goal_eloc.logicalBlockNum ++;
X goal_elen -= sb->s_blocksize;
X
+ if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
+ {
+ udf_release_data(goal_bh);
+ unlock_super(sb);
+ *err = -EDQUOT;


+ return 0;
+ }
+

X if (goal_elen)
X udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
X else
@@ -887,93 +844,98 @@
X return newblock;
X }
X
-inline void udf_free_blocks(struct inode * inode, lb_addr bloc,
- Uint32 offset, Uint32 count)
+inline void udf_free_blocks(struct super_block * sb,
+ struct inode * inode,
+ lb_addr bloc, Uint32 offset, Uint32 count)
X {
- if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
+ Uint16 partition = bloc.partitionReferenceNum;
+
+ if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
X {
- return udf_bitmap_free_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
+ return udf_bitmap_free_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
X bloc, offset, count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
X {
- return udf_table_free_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
+ return udf_table_free_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
X bloc, offset, count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
X {
- return udf_bitmap_free_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
+ return udf_bitmap_free_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
X bloc, offset, count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
X {
- return udf_table_free_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
+ return udf_table_free_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
X bloc, offset, count);
X }
X else
X return;
X }
X
-inline int udf_prealloc_blocks(struct inode * inode, Uint16 partition,
- Uint32 first_block, Uint32 block_count)
+inline int udf_prealloc_blocks(struct super_block * sb,
+ struct inode * inode,
+ Uint16 partition, Uint32 first_block, Uint32 block_count)
X {
- if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+ if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
X {
- return udf_bitmap_prealloc_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+ return udf_bitmap_prealloc_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
X partition, first_block, block_count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
X {
- return udf_table_prealloc_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+ return udf_table_prealloc_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
X partition, first_block, block_count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
X {
- return udf_bitmap_prealloc_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+ return udf_bitmap_prealloc_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
X partition, first_block, block_count);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
X {
- return udf_table_prealloc_blocks(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+ return udf_table_prealloc_blocks(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
X partition, first_block, block_count);
X }
X else


X return 0;
X }
X

-inline int udf_new_block(struct inode * inode, Uint16 partition,
- Uint32 goal, int *err)
+inline int udf_new_block(struct super_block * sb,
+ struct inode * inode,
+ Uint16 partition, Uint32 goal, int *err)
X {
- if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
+ if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
X {
- return udf_bitmap_new_block(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+ return udf_bitmap_new_block(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
X partition, goal, err);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
X {
- return udf_table_new_block(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
+ return udf_table_new_block(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
X partition, goal, err);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
X {
- return udf_bitmap_new_block(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+ return udf_bitmap_new_block(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
X partition, goal, err);
X }
- else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+ else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE)
X {
- return udf_table_new_block(inode,
- UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
+ return udf_table_new_block(sb, inode,
+ UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
X partition, goal, err);
X }
X else
diff -u --recursive --new-file v2.4.12/linux/fs/udf/dir.c linux/fs/udf/dir.c
--- v2.4.12/linux/fs/udf/dir.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/dir.c Thu Oct 11 08:59:24 2001
@@ -186,7 +186,7 @@
X udf_release_data(fibh.ebh);
X udf_release_data(fibh.sbh);
X udf_release_data(bh);
- return -ENOENT;


+ return 0;
X }
X

X liu = le16_to_cpu(cfi.lengthOfImpUse);
diff -u --recursive --new-file v2.4.12/linux/fs/udf/file.c linux/fs/udf/file.c
--- v2.4.12/linux/fs/udf/file.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/file.c Thu Oct 11 08:59:24 2001
@@ -206,7 +206,7 @@
X int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
X unsigned long arg)
X {
- int result = -1;
+ int result = -EINVAL;
X struct buffer_head *bh = NULL;
X long_ad eaicb;
X Uint8 *ea = NULL;
@@ -228,16 +228,16 @@
X switch (cmd)
X {
X case UDF_GETVOLIDENT:
- if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
- result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
- return result;
+ return copy_to_user((char *)arg,
+ UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
X case UDF_RELOCATE_BLOCKS:
X {
X long old, new;
X
X if (!capable(CAP_SYS_ADMIN)) return -EACCES;
- get_user(old, (long *)arg);
- if ((result = udf_relocate_blocks(inode->i_sb, old, &new)) == 0)
+ if (get_user(old, (long *)arg)) return -EFAULT;
+ if ((result = udf_relocate_blocks(inode->i_sb,
+ old, &new)) == 0)
X result = put_user(new, (long *)arg);
X
X return result;
@@ -277,16 +277,12 @@
X switch (cmd)
X {
X case UDF_GETEASIZE:
- if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0)
- result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
+ result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
X break;
X
X case UDF_GETEABLOCK:
- if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0)
- result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));


- break;
-
- default:

+ result = copy_to_user((char *)arg, ea,
+ UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
X break;
X }
X
diff -u --recursive --new-file v2.4.12/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.4.12/linux/fs/udf/ialloc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/udf/ialloc.c Thu Oct 11 08:59:24 2001
@@ -64,10 +64,9 @@
X
X mark_buffer_dirty(UDF_SB_LVIDBH(sb));
X }
-
X unlock_super(sb);
X
- udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
+ udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
X }
X
X struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
@@ -87,7 +86,7 @@
X }
X *err = -ENOSPC;
X
- block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
+ block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
X start, err);
X if (*err)
X {
diff -u --recursive --new-file v2.4.12/linux/fs/udf/inode.c linux/fs/udf/inode.c
--- v2.4.12/linux/fs/udf/inode.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/inode.c Fri Oct 12 13:48:42 2001
@@ -37,10 +37,15 @@
X #include <linux/locks.h>
X #include <linux/mm.h>
X #include <linux/smp_lock.h>
+#include <linux/module.h>
X
X #include "udf_i.h"
X #include "udf_sb.h"
X
+MODULE_AUTHOR("Ben Fennema");
+MODULE_DESCRIPTION("Universal Disk Format Filesystem");
+MODULE_LICENSE("GPL");
+
X #define EXTENT_MERGE_SIZE 5
X
X static mode_t udf_convert_permissions(struct FileEntry *);
@@ -236,7 +241,7 @@
X }
X
X /* alloc block, and copy data to it */
- *block = udf_new_block(inode,
+ *block = udf_new_block(inode->i_sb, inode,
X UDF_I_LOCATION(inode).partitionReferenceNum,
X UDF_I_LOCATION(inode).logicalBlockNum, err);
X
@@ -302,7 +307,6 @@
X udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
X /* UniqueID stuff */
X
- inode->i_blocks = inode->i_sb->s_blocksize / 512;
X mark_buffer_dirty(sbh);
X udf_release_data(sbh);
X mark_inode_dirty(inode);
@@ -402,14 +406,14 @@
X Uint32 elen = 0;
X lb_addr eloc, pbloc, cbloc, nbloc;
X int c = 1;
- int lbcount = 0, b_off = 0, offset = 0;
- Uint32 newblocknum, newblock;
- char etype;
+ Uint64 lbcount = 0, b_off = 0;
+ Uint32 newblocknum, newblock, offset = 0;
+ Sint8 etype;
X int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
X char lastblock = 0;
X
X pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
- b_off = block << inode->i_sb->s_blocksize_bits;
+ b_off = (Uint64)block << inode->i_sb->s_blocksize_bits;
X pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
X
X /* find the extent which contains the block we are looking for.
@@ -546,7 +550,7 @@
X goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
X }
X
- if (!(newblocknum = udf_new_block(inode,
+ if (!(newblocknum = udf_new_block(inode->i_sb, inode,
X UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
X {
X udf_release_data(pbh);
@@ -588,7 +592,7 @@
X UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
X inode->i_ctime = CURRENT_TIME;
X UDF_I_UCTIME(inode) = CURRENT_UTIME;
- inode->i_blocks += inode->i_sb->s_blocksize / 512;
+
X if (IS_SYNC(inode))
X udf_sync_inode(inode);
X else
@@ -622,8 +626,17 @@
X
X if (offset)
X {
- laarr[curr].extLength = type |
- (offset << inode->i_sb->s_blocksize_bits);
+ if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+ {
+ udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
+ laarr[curr].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
+ (offset << inode->i_sb->s_blocksize_bits);
+ laarr[curr].extLocation.logicalBlockNum = 0;
+ laarr[curr].extLocation.partitionReferenceNum = 0;
+ }
+ else
+ laarr[curr].extLength = type |
+ (offset << inode->i_sb->s_blocksize_bits);
X curr ++;
X (*c) ++;
X (*endnum) ++;
@@ -692,7 +705,7 @@
X int next = laarr[start].extLocation.logicalBlockNum +
X (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
X inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
- int numalloc = udf_prealloc_blocks(inode,
+ int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
X laarr[start].extLocation.partitionReferenceNum,
X next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
X UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
@@ -825,9 +838,6 @@
X int create, int * err)
X {
X struct buffer_head * bh = NULL;
- int prev_blocks;
-
- prev_blocks = inode->i_blocks;
X
X bh = udf_getblk(inode, block, create, err);
X if (!bh)
@@ -1602,7 +1612,7 @@
X return inode;
X }
X
-int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
X lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
X {
X int adsize;
@@ -1637,7 +1647,7 @@
X int err, loffset;
X lb_addr obloc = *bloc;
X
- if (!(bloc->logicalBlockNum = udf_new_block(inode,
+ if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, inode,
X obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
X {
X return -1;
@@ -1739,7 +1749,7 @@
X return ret;
X }
X
-int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
+Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
X lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
X {
X int adsize;
@@ -1808,12 +1818,12 @@
X return (elen >> 30);
X }
X
-int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
X lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
X {
X Uint16 tagIdent;
X int pos, alen;
- Uint8 etype;
+ Sint8 etype;
X
X if (!(*bh))


X {
@@ -1932,11 +1942,11 @@

X return -1;
X }
X
-int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
+Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
X lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
X {
X int pos, alen;
- Uint8 etype;
+ Sint8 etype;
X
X if (!(*bh))
X {
@@ -2013,12 +2023,12 @@


X return -1;
X }
X

-int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
+Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
X lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
X {
X lb_addr oeloc;
X Uint32 oelen;
- int type;
+ Sint8 etype;
X
X if (!bh)
X {
@@ -2034,25 +2044,25 @@
X else
X atomic_inc(&bh->b_count);
X
- while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+ while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
X {
X udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
X
X neloc = oeloc;
- nelen = (type << 30) | oelen;
+ nelen = (etype << 30) | oelen;
X }
X udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
X udf_release_data(bh);
X return (nelen >> 30);
X }
X
-int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
+Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
X lb_addr eloc, Uint32 elen, struct buffer_head *nbh)
X {
X struct buffer_head *obh;
X lb_addr obloc;
X int oextoffset, adsize;
- char type;
+ Sint8 etype;
X struct AllocExtDesc *aed;
X
X if (!(nbh))
@@ -2084,9 +2094,9 @@
X if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
X return -1;
X
- while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+ while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
X {
- udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, obh, 1);
+ udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
X if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
X {
X obloc = nbloc;
@@ -2101,7 +2111,7 @@
X
X if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
X {
- udf_free_blocks(inode, nbloc, 0, 1);
+ udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
X udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
X udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
X if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
@@ -2147,11 +2157,11 @@
X return (elen >> 30);
X }
X
-int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
+Sint8 inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
X lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
X {
- Uint64 lbcount = 0, bcount = block << inode->i_sb->s_blocksize_bits;
- char etype;
+ Uint64 lbcount = 0, bcount = (Uint64)block << inode->i_sb->s_blocksize_bits;
+ Sint8 etype;
X
X if (block < 0)
X {
diff -u --recursive --new-file v2.4.12/linux/fs/udf/lowlevel.c linux/fs/udf/lowlevel.c
--- v2.4.12/linux/fs/udf/lowlevel.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/lowlevel.c Mon Oct 15 13:27:41 2001
@@ -67,7 +67,7 @@
X return vol_desc_start;
X }
X
-unsigned int
+unsigned long
X udf_get_last_block(struct super_block *sb)
X {
X struct block_device *bdev = sb->s_bdev;
diff -u --recursive --new-file v2.4.12/linux/fs/udf/namei.c linux/fs/udf/namei.c
--- v2.4.12/linux/fs/udf/namei.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/namei.c Thu Oct 11 08:59:24 2001
@@ -835,7 +835,7 @@
X static int udf_rmdir(struct inode * dir, struct dentry * dentry)
X {
X int retval;
- struct inode * inode;
+ struct inode * inode = dentry->d_inode;
X struct udf_fileident_bh fibh;
X struct FileIdentDesc *fi, cfi;


X
@@ -844,9 +844,6 @@

X if (!fi)
X goto out;
X
- inode = dentry->d_inode;
- DQUOT_INIT(inode);
-
X retval = -EIO;
X if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) != inode->i_ino)
X goto end_rmdir;
@@ -881,7 +878,7 @@
X static int udf_unlink(struct inode * dir, struct dentry * dentry)
X {
X int retval;
- struct inode * inode;
+ struct inode * inode = dentry->d_inode;
X struct udf_fileident_bh fibh;
X struct FileIdentDesc *fi;
X struct FileIdentDesc cfi;
@@ -891,9 +888,6 @@
X if (!fi)
X goto out;
X
- inode = dentry->d_inode;
- DQUOT_INIT(inode);
-
X retval = -EIO;
X
X if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
@@ -954,7 +948,7 @@
X lb_addr bloc, eloc;
X Uint32 elen, extoffset;
X
- block = udf_new_block(inode,
+ block = udf_new_block(inode->i_sb, inode,
X UDF_I_LOCATION(inode).partitionReferenceNum,
X UDF_I_LOCATION(inode).logicalBlockNum, &err);
X if (!block)
@@ -968,7 +962,6 @@
X udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
X udf_release_data(bh);
X
- inode->i_blocks = inode->i_sb->s_blocksize / 512;
X block = udf_get_pblock(inode->i_sb, block,
X UDF_I_LOCATION(inode).partitionReferenceNum, 0);
X bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
@@ -1150,13 +1143,13 @@
X static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
X struct inode * new_dir, struct dentry * new_dentry)
X {
- struct inode * old_inode, * new_inode;
+ struct inode * old_inode = old_dentry->d_inode;
+ struct inode * new_inode = new_dentry->d_inode;
X struct udf_fileident_bh ofibh, nfibh;
X struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
X struct buffer_head *dir_bh = NULL;
X int retval = -ENOENT;
X
- old_inode = old_dentry->d_inode;
X if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
X {
X if (ofibh.sbh != ofibh.ebh)
@@ -1169,7 +1162,6 @@
X goto end_rename;
X }
X
- new_inode = new_dentry->d_inode;
X nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
X if (nfi)
X {
@@ -1179,10 +1171,6 @@
X udf_release_data(nfibh.ebh);
X udf_release_data(nfibh.sbh);
X nfi = NULL;
- }
- else
- {
- DQUOT_INIT(new_inode);
X }
X }
X if (S_ISDIR(old_inode->i_mode))
diff -u --recursive --new-file v2.4.12/linux/fs/udf/super.c linux/fs/udf/super.c
--- v2.4.12/linux/fs/udf/super.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/super.c Thu Oct 11 08:59:24 2001
@@ -85,7 +85,7 @@
X static int udf_load_partition(struct super_block *, lb_addr *);
X static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
X static void udf_load_logicalvolint(struct super_block *, extent_ad);
-static int udf_find_anchor(struct super_block *, int, int);
+static void udf_find_anchor(struct super_block *);
X static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
X static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
X static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
@@ -164,7 +164,7 @@
X * noadinicb Don't embed data in the inode
X * shortad Use short ad's
X * longad Use long ad's (default)
- * strict Set strict conformance
+ * nostrict Unset strict conformance
X * iocharset= Set the NLS character set
X *
X * The remaining are for debugging and disaster recovery:
@@ -208,8 +208,8 @@
X uopt->blocksize = 2048;
X uopt->partition = 0xFFFF;
X uopt->session = 0xFFFFFFFF;
- uopt->lastblock = 0xFFFFFFFF;
- uopt->anchor = 0xFFFFFFFF;
+ uopt->lastblock = 0;
+ uopt->anchor = 0;
X uopt->volume = 0xFFFFFFFF;
X uopt->rootdir = 0xFFFFFFFF;
X uopt->fileset = 0xFFFFFFFF;
@@ -244,8 +244,8 @@
X uopt->gid = simple_strtoul(val, NULL, 0);
X else if (!strcmp(opt, "umask") && val)
X uopt->umask = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "strict") && !val)
- uopt->flags |= (1 << UDF_FLAG_STRICT);
+ else if (!strcmp(opt, "nostrict") && !val)
+ uopt->flags &= ~(1 << UDF_FLAG_STRICT);
X else if (!strcmp(opt, "uid") && val)
X uopt->uid = simple_strtoul(val, NULL, 0);
X else if (!strcmp(opt, "session") && val)
@@ -496,72 +496,36 @@
X * July 1, 1997 - Andrew E. Mileski
X * Written, tested, and released.
X */
-static int
-udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
+static void
+udf_find_anchor(struct super_block *sb)
X {
- int varlastblock = udf_variable_to_fixed(lastblock);
- int last[] = { lastblock, lastblock - 2,
- lastblock - 150, lastblock - 152,
- varlastblock, varlastblock - 2,
- varlastblock - 150, varlastblock - 152 };
+ int lastblock = UDF_SB_LASTBLOCK(sb);
X struct buffer_head *bh = NULL;
X Uint16 ident;
X Uint32 location;
X int i;
X
- UDF_SB_ANCHOR(sb)[0] = 0;
- UDF_SB_ANCHOR(sb)[1] = 0;
- UDF_SB_ANCHOR(sb)[2] = 0;
- UDF_SB_ANCHOR(sb)[3] = 256 + UDF_SB_SESSION(sb);
+ if (lastblock)
+ {
+ int varlastblock = udf_variable_to_fixed(lastblock);
+ int last[] = { lastblock, lastblock - 2,
+ lastblock - 150, lastblock - 152,
+ varlastblock, varlastblock - 2,
+ varlastblock - 150, varlastblock - 152 };
X
- lastblock = 0;
+ lastblock = 0;
X
- /* Search for an anchor volume descriptor pointer */
+ /* Search for an anchor volume descriptor pointer */
X
- /* according to spec, anchor is in either:
- * block 256
- * lastblock-256
- * lastblock
- * however, if the disc isn't closed, it could be 512 */
+ /* according to spec, anchor is in either:
+ * block 256
+ * lastblock-256
+ * lastblock
+ * however, if the disc isn't closed, it could be 512 */
X
- for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
- {
- if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
- {
- ident = location = 0;
- }
- else
+ for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
X {
- ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
- location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
- }
-
- if (ident == TID_ANCHOR_VOL_DESC_PTR)
- {
- if (location == last[i] - UDF_SB_SESSION(sb))
- {
- lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
- UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
- }
- else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
- {
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
- lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
- UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
- }
- else
- udf_debug("Anchor found at block %d, location mismatch %d.\n",
- last[i], location);
- }
- else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
- {
- lastblock = last[i];
- UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb);
- }
- else
- {
- if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
+ if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
X {
X ident = location = 0;
X }
@@ -571,17 +535,32 @@
X location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
X udf_release_data(bh);
X }
-
- if (ident == TID_ANCHOR_VOL_DESC_PTR &&
- location == last[i] - 256 - UDF_SB_SESSION(sb))
+
+ if (ident == TID_ANCHOR_VOL_DESC_PTR)
+ {
+ if (location == last[i] - UDF_SB_SESSION(sb))
+ {
+ lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
+ UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ }
+ else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
+ {
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
+ UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ }
+ else
+ udf_debug("Anchor found at block %d, location mismatch %d.\n",
+ last[i], location);
+ }
+ else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
X {
X lastblock = last[i];
- UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
X }
X else
X {
- if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
- sb->s_blocksize)))
+ if (last[i] < 256 || !(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
X {
X ident = location = 0;
X }
@@ -591,13 +570,34 @@
X location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
X udf_release_data(bh);
X }
-
+
X if (ident == TID_ANCHOR_VOL_DESC_PTR &&
- location == udf_variable_to_fixed(last[i]) - 256)
+ location == last[i] - 256 - UDF_SB_SESSION(sb))
X {
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
- lastblock = udf_variable_to_fixed(last[i]);
- UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ lastblock = last[i];
+ UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ }
+ else
+ {
+ if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
+ sb->s_blocksize)))
+ {
+ ident = location = 0;
+ }
+ else
+ {
+ ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+ location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+ udf_release_data(bh);
+ }
+
+ if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+ location == udf_variable_to_fixed(last[i]) - 256)
+ {
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ lastblock = udf_variable_to_fixed(last[i]);
+ UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ }
X }
X }
X }
@@ -636,15 +636,9 @@
X }
X }
X }
- else if (useranchor != 0xFFFFFFFF)
- {
- UDF_SB_ANCHOR(sb)[i] = useranchor;
- useranchor = 0xFFFFFFFF;
- i --;
- }
X }
X
- return lastblock;
+ UDF_SB_LASTBLOCK(sb) = lastblock;


X }
X
X static int

@@ -985,8 +979,10 @@
X struct buffer_head *bh = NULL;
X Uint16 ident;
X
- while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) &&
- ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0)
+ while (loc.extLength > 0 &&
+ (bh = udf_read_tagged(sb, loc.extLocation,
+ loc.extLocation, &ident)) &&
+ ident == TID_LOGICAL_VOL_INTEGRITY_DESC)
X {
X UDF_SB_LVIDBH(sb) = bh;
X
@@ -1152,6 +1148,8 @@
X else if ((block = udf_vrs(sb, silent)) == -1)
X {
X udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+ if (!UDF_SB_LASTBLOCK(sb))
+ UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
X return 0;
X }
X else
@@ -1220,6 +1218,12 @@
X
X if (!UDF_SB_LASTBLOCK(sb))
X {
+ UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+ udf_find_anchor(sb);
+ }
+
+ if (!UDF_SB_LASTBLOCK(sb))
+ {
X udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
X return 1;
X }
@@ -1355,7 +1359,7 @@
X struct udf_options uopt;
X lb_addr rootdir, fileset;
X
- uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
+ uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
X uopt.uid = -1;
X uopt.gid = -1;
X uopt.umask = 0;
@@ -1409,14 +1413,10 @@
X
X udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
X
- if ( uopt.lastblock == 0xFFFFFFFF )
- UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
- else
- UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
-
- UDF_SB_LASTBLOCK(sb) = udf_find_anchor(sb, uopt.anchor, UDF_SB_LASTBLOCK(sb));
-
- udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+ UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
+ UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
+ UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
+ UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256;
X
X if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
X {
@@ -1424,6 +1424,8 @@
X goto error_out;
X }
X
+ udf_find_anchor(sb);
+
X /* Fill in the rest of the superblock */
X sb->s_op = &udf_sb_ops;
X sb->dq_op = NULL;
@@ -1436,6 +1438,8 @@
X goto error_out;
X }
X
+ udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+
X if ( UDF_SB_LVIDBH(sb) )
X {
X Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
@@ -1744,7 +1748,7 @@
X unsigned int accum = 0;
X Uint32 extoffset, elen;
X lb_addr bloc, eloc;
- char etype;
+ Sint8 etype;
X struct buffer_head *bh = NULL;
X
X bloc = UDF_I_LOCATION(table);
@@ -1763,6 +1767,20 @@
X {
X unsigned int accum = 0;
X
+ if (UDF_SB_LVIDBH(sb))
+ {
+ if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
+ {
+ accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+
+ if (accum == 0xFFFFFFFF)
+ accum = 0;
+ }
+ }
+
+ if (accum)
+ return accum;
+
X if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
X {
X accum += udf_count_free_bitmap(sb,
@@ -1786,18 +1804,6 @@
X accum += udf_count_free_table(sb,
X UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
X }
- if (accum)
- return accum;
X
- if (UDF_SB_LVIDBH(sb))
- {
- if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
- {
- accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
-
- if (accum == 0xFFFFFFFF)
- accum = 0;
- }
- }
X return accum;
X }
diff -u --recursive --new-file v2.4.12/linux/fs/udf/truncate.c linux/fs/udf/truncate.c
--- v2.4.12/linux/fs/udf/truncate.c Tue Jul 3 17:08:21 2001
+++ linux/fs/udf/truncate.c Thu Oct 11 08:59:24 2001
@@ -33,10 +33,9 @@
X #include "udf_sb.h"
X
X static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
- lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
+ lb_addr eloc, Sint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
X {
X lb_addr neloc = { 0, 0 };
- int blocks = inode->i_sb->s_blocksize / 512;
X int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
X int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
X
@@ -52,12 +51,10 @@
X if (last_block - first_block > 0)
X {
X if (etype == EXTENT_RECORDED_ALLOCATED)
- {
- inode->i_blocks -= (blocks * (last_block - first_block));
X mark_inode_dirty(inode);
- }
+
X if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
- udf_free_blocks(inode, eloc, first_block, last_block - first_block);
+ udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
X }
X }
X }
@@ -66,7 +63,7 @@
X {
X lb_addr bloc, eloc, neloc = { 0, 0 };
X Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
- int etype;
+ Sint8 etype;
X int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
X struct buffer_head *bh = NULL;
X int adsize;
@@ -108,7 +105,7 @@
X memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
X else
X memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
- udf_free_blocks(inode, bloc, 0, lelen);
+ udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
X }
X else
X {
@@ -153,7 +150,7 @@
X memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
X else
X memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
- udf_free_blocks(inode, bloc, 0, lelen);
+ udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
X }
X else
X {
diff -u --recursive --new-file v2.4.12/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- v2.4.12/linux/fs/udf/udfdecl.h Tue Oct 9 17:06:53 2001
+++ linux/fs/udf/udfdecl.h Mon Oct 15 18:49:21 2001
@@ -11,7 +11,6 @@
X
X #include <linux/config.h>
X #include <linux/types.h>
-
X #include <linux/fs.h>
X
X #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
@@ -129,13 +128,13 @@
X extern void udf_delete_inode(struct inode *);
X extern void udf_write_inode(struct inode *, int);
X extern long udf_block_map(struct inode *, long);
-extern int inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
-extern int udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
-extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
-extern int udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
-extern int udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
-extern int udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
+extern Sint8 udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
+extern Sint8 udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
+extern Sint8 udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
+extern Sint8 udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
+extern Sint8 udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
X extern void udf_discard_prealloc(struct inode *);
X
X /* misc.c */
@@ -151,7 +150,7 @@
X
X /* lowlevel.c */
X extern unsigned int udf_get_last_session(struct super_block *);
-extern unsigned int udf_get_last_block(struct super_block *);
+extern unsigned long udf_get_last_block(struct super_block *);
X
X /* partition.c */
X extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32);
@@ -171,9 +170,9 @@
X extern void udf_truncate_extents(struct inode *);
X
X /* balloc.c */
-extern void udf_free_blocks(struct inode *, lb_addr, Uint32, Uint32);
-extern int udf_prealloc_blocks(struct inode *, Uint16, Uint32, Uint32);
-extern int udf_new_block(struct inode *, Uint16, Uint32, int *);
+extern void udf_free_blocks(struct super_block *, struct inode *, lb_addr, Uint32, Uint32);
+extern int udf_prealloc_blocks(struct super_block *, struct inode *, Uint16, Uint32, Uint32);
+extern int udf_new_block(struct super_block *, struct inode *, Uint16, Uint32, int *);
X
X /* fsync.c */
X extern int udf_fsync_file(struct file *, struct dentry *, int);
diff -u --recursive --new-file v2.4.12/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.4.12/linux/fs/ufs/dir.c Fri Aug 11 14:29:02 2000
+++ linux/fs/ufs/dir.c Sat Oct 20 19:14:42 2001
@@ -13,6 +13,8 @@
X * on code by Martin von Loewis <mar...@mira.isdn.cs.tu-berlin.de>.
X */
X
+#include <linux/sched.h>
+#include <linux/locks.h>
X #include <linux/fs.h>
X #include <linux/ufs_fs.h>
X
@@ -28,6 +30,21 @@
X #endif
X
X /*
+ * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
+ *
+ * len <= UFS_MAXNAMLEN and de != NULL are guaranteed by caller.
+ */
+static inline int ufs_match (int len, const char * const name,
+ struct ufs_dir_entry * de, unsigned flags, unsigned swab)
+{
+ if (len != ufs_get_de_namlen(de))
+ return 0;
+ if (!de->d_ino)
+ return 0;
+ return !memcmp(name, de->d_name, len);
+}
+
+/*
X * This is blatantly stolen from ext2fs


X */
X static int

@@ -145,6 +162,130 @@


X return 0;
X }
X

+/*
+ * define how far ahead to read directories while searching them.
+ */
+#define NAMEI_RA_CHUNKS 2
+#define NAMEI_RA_BLOCKS 4
+#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
+
+/*
+ * ufs_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the cache buffer in which the entry was found, and the entry
+ * itself (as a parameter - res_bh). It does NOT read the inode of the
+ * entry - you'll have to do that yourself if you want to.
+ */
+struct ufs_dir_entry * ufs_find_entry (struct dentry *dentry,
+ struct buffer_head ** res_bh)
+{
+ struct super_block * sb;
+ struct buffer_head * bh_use[NAMEI_RA_SIZE];
+ struct buffer_head * bh_read[NAMEI_RA_SIZE];
+ unsigned long offset;
+ int block, toread, i, err;
+ unsigned flags, swab;
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+
+ UFSD(("ENTER, dir_ino %lu, name %s, namlen %u\n", dir->i_ino, name, namelen))
+
+ *res_bh = NULL;
+
+ sb = dir->i_sb;
+ flags = sb->u.ufs_sb.s_flags;
+ swab = sb->u.ufs_sb.s_swab;
+
+ if (namelen > UFS_MAXNAMLEN)
+ return NULL;
+
+ memset (bh_use, 0, sizeof (bh_use));
+ toread = 0;
+ for (block = 0; block < NAMEI_RA_SIZE; ++block) {
+ struct buffer_head * bh;
+
+ if ((block << sb->s_blocksize_bits) >= dir->i_size)
+ break;
+ bh = ufs_getfrag (dir, block, 0, &err);
+ bh_use[block] = bh;
+ if (bh && !buffer_uptodate(bh))
+ bh_read[toread++] = bh;
+ }
+
+ for (block = 0, offset = 0; offset < dir->i_size; block++) {
+ struct buffer_head * bh;
+ struct ufs_dir_entry * de;
+ char * dlimit;
+
+ if ((block % NAMEI_RA_BLOCKS) == 0 && toread) {
+ ll_rw_block (READ, toread, bh_read);
+ toread = 0;
+ }
+ bh = bh_use[block % NAMEI_RA_SIZE];
+ if (!bh) {
+ ufs_error (sb, "ufs_find_entry",
+ "directory #%lu contains a hole at offset %lu",
+ dir->i_ino, offset);
+ offset += sb->s_blocksize;
+ continue;
+ }
+ wait_on_buffer (bh);
+ if (!buffer_uptodate(bh)) {
+ /*
+ * read error: all bets are off
+ */
+ break;
+ }
+
+ de = (struct ufs_dir_entry *) bh->b_data;
+ dlimit = bh->b_data + sb->s_blocksize;
+ while ((char *) de < dlimit && offset < dir->i_size) {
+ /* this code is executed quadratically often */
+ /* do minimal checking by hand */
+ int de_len;
+
+ if ((char *) de + namelen <= dlimit &&
+ ufs_match (namelen, name, de, flags, swab)) {
+ /* found a match -
+ just to be sure, do a full check */
+ if (!ufs_check_dir_entry("ufs_find_entry",
+ dir, de, bh, offset))
+ goto failed;
+ for (i = 0; i < NAMEI_RA_SIZE; ++i) {
+ if (bh_use[i] != bh)
+ brelse (bh_use[i]);
+ }
+ *res_bh = bh;
+ return de;
+ }
+ /* prevent looping on a bad block */
+ de_len = SWAB16(de->d_reclen);
+ if (de_len <= 0)
+ goto failed;
+ offset += de_len;
+ de = (struct ufs_dir_entry *) ((char *) de + de_len);
+ }
+
+ brelse (bh);
+ if (((block + NAMEI_RA_SIZE) << sb->s_blocksize_bits ) >=
+ dir->i_size)
+ bh = NULL;
+ else
+ bh = ufs_getfrag (dir, block + NAMEI_RA_SIZE, 0, &err);
+ bh_use[block % NAMEI_RA_SIZE] = bh;
+ if (bh && !buffer_uptodate(bh))
+ bh_read[toread++] = bh;
+ }
+
+failed:
+ for (i = 0; i < NAMEI_RA_SIZE; ++i) brelse (bh_use[i]);
+ UFSD(("EXIT\n"))


+ return NULL;
+}
+

X int ufs_check_dir_entry (const char * function, struct inode * dir,
X struct ufs_dir_entry * de, struct buffer_head * bh,
X unsigned long offset)
@@ -178,6 +319,312 @@
X SWAB16(de->d_reclen), ufs_get_de_namlen(de));
X
X return (error_msg == NULL ? 1 : 0);
+}
+
+struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct buffer_head **p)
+{
+ int err;
+ struct buffer_head *bh = ufs_bread (dir, 0, 0, &err);
+ struct ufs_dir_entry *res = NULL;
+
+ if (bh) {
+ unsigned swab = dir->i_sb->u.ufs_sb.s_swab;
+
+ res = (struct ufs_dir_entry *) bh->b_data;
+ res = (struct ufs_dir_entry *)((char *)res +
+ SWAB16(res->d_reclen));
+ }
+ *p = bh;
+ return res;
+}
+ino_t ufs_inode_by_name(struct inode * dir, struct dentry *dentry)
+{
+ unsigned swab = dir->i_sb->u.ufs_sb.s_swab;
+ ino_t res = 0;
+ struct ufs_dir_entry * de;
+ struct buffer_head *bh;
+
+ de = ufs_find_entry (dentry, &bh);
+ if (de) {
+ res = SWAB32(de->d_ino);
+ brelse(bh);
+ }


+ return res;
+}
+

+void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
+ struct buffer_head *bh, struct inode *inode)
+{
+ unsigned swab = dir->i_sb->u.ufs_sb.s_swab;
+ dir->i_version = ++event;
+ de->d_ino = SWAB32(inode->i_ino);
+ mark_buffer_dirty(bh);
+ if (IS_SYNC(dir)) {
+ ll_rw_block (WRITE, 1, &bh);
+ wait_on_buffer(bh);
+ }
+ brelse (bh);
+}
+
+/*
+ * ufs_add_entry()
+ *
+ * adds a file entry to the specified directory, using the same
+ * semantics as ufs_find_entry(). It returns NULL if it failed.
+ */
+int ufs_add_link(struct dentry *dentry, struct inode *inode)
+{
+ struct super_block * sb;
+ struct ufs_sb_private_info * uspi;
+ unsigned long offset;
+ unsigned fragoff;
+ unsigned short rec_len;
+ struct buffer_head * bh;
+ struct ufs_dir_entry * de, * de1;
+ unsigned flags, swab;
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ int err;
+
+ UFSD(("ENTER, name %s, namelen %u\n", name, namelen))
+
+ sb = dir->i_sb;
+ flags = sb->u.ufs_sb.s_flags;
+ swab = sb->u.ufs_sb.s_swab;
+ uspi = sb->u.ufs_sb.s_uspi;
+
+ if (!namelen)
+ return -EINVAL;
+ bh = ufs_bread (dir, 0, 0, &err);
+ if (!bh)
+ return err;
+ rec_len = UFS_DIR_REC_LEN(namelen);
+ offset = 0;
+ de = (struct ufs_dir_entry *) bh->b_data;
+ while (1) {
+ if ((char *)de >= UFS_SECTOR_SIZE + bh->b_data) {
+ fragoff = offset & ~uspi->s_fmask;
+ if (fragoff != 0 && fragoff != UFS_SECTOR_SIZE)
+ ufs_error (sb, "ufs_add_entry", "internal error"
+ " fragoff %u", fragoff);
+ if (!fragoff) {
+ brelse (bh);
+ bh = ufs_bread (dir, offset >> sb->s_blocksize_bits, 1, &err);
+ if (!bh)
+ return err;
+ }
+ if (dir->i_size <= offset) {
+ if (dir->i_size == 0) {
+ brelse(bh);
+ return -ENOENT;
+ }
+ de = (struct ufs_dir_entry *) (bh->b_data + fragoff);
+ de->d_ino = SWAB32(0);
+ de->d_reclen = SWAB16(UFS_SECTOR_SIZE);
+ ufs_set_de_namlen(de,0);
+ dir->i_size = offset + UFS_SECTOR_SIZE;
+ mark_inode_dirty(dir);
+ } else {
+ de = (struct ufs_dir_entry *) bh->b_data;
+ }
+ }
+ if (!ufs_check_dir_entry ("ufs_add_entry", dir, de, bh, offset)) {
+ brelse (bh);
+ return -ENOENT;
+ }
+ if (ufs_match (namelen, name, de, flags, swab)) {
+ brelse (bh);
+ return -EEXIST;
+ }
+ if (SWAB32(de->d_ino) == 0 && SWAB16(de->d_reclen) >= rec_len)
+ break;
+
+ if (SWAB16(de->d_reclen) >= UFS_DIR_REC_LEN(ufs_get_de_namlen(de)) + rec_len)
+ break;
+ offset += SWAB16(de->d_reclen);
+ de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
+ }
+
+ if (SWAB32(de->d_ino)) {
+ de1 = (struct ufs_dir_entry *) ((char *) de +
+ UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
+ de1->d_reclen = SWAB16(SWAB16(de->d_reclen) -
+ UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
+ de->d_reclen = SWAB16(UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
+ de = de1;
+ }
+ de->d_ino = SWAB32(0);
+ ufs_set_de_namlen(de, namelen);
+ memcpy (de->d_name, name, namelen + 1);
+ de->d_ino = SWAB32(inode->i_ino);
+ ufs_set_de_type (de, inode->i_mode);
+ mark_buffer_dirty(bh);
+ if (IS_SYNC(dir)) {
+ ll_rw_block (WRITE, 1, &bh);
+ wait_on_buffer (bh);
+ }
+ brelse (bh);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ dir->i_version = ++event;
+ mark_inode_dirty(dir);
+
+ UFSD(("EXIT\n"))


+ return 0;
+}
+

+/*
+ * ufs_delete_entry deletes a directory entry by merging it with the
+ * previous entry.
+ */
+int ufs_delete_entry (struct inode * inode, struct ufs_dir_entry * dir,
+ struct buffer_head * bh )
+
+{
+ struct super_block * sb;
+ struct ufs_dir_entry * de, * pde;
+ unsigned i;
+ unsigned flags, swab;
+
+ UFSD(("ENTER\n"))
+
+ sb = inode->i_sb;
+ flags = sb->u.ufs_sb.s_flags;
+ swab = sb->u.ufs_sb.s_swab;
+ i = 0;
+ pde = NULL;
+ de = (struct ufs_dir_entry *) bh->b_data;
+
+ UFSD(("ino %u, reclen %u, namlen %u, name %s\n", SWAB32(de->d_ino),
+ SWAB16(de->d_reclen), ufs_get_de_namlen(de), de->d_name))
+
+ while (i < bh->b_size) {
+ if (!ufs_check_dir_entry ("ufs_delete_entry", inode, de, bh, i)) {
+ brelse(bh);
+ return -EIO;
+ }
+ if (de == dir) {
+ if (pde)
+ pde->d_reclen =
+ SWAB16(SWAB16(pde->d_reclen) +
+ SWAB16(dir->d_reclen));
+ dir->d_ino = SWAB32(0);
+ inode->i_version = ++event;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ mark_buffer_dirty(bh);
+ if (IS_SYNC(inode)) {
+ ll_rw_block(WRITE, 1, &bh);
+ wait_on_buffer(bh);
+ }
+ brelse(bh);
+ UFSD(("EXIT\n"))
+ return 0;
+ }
+ i += SWAB16(de->d_reclen);
+ if (i == UFS_SECTOR_SIZE) pde = NULL;
+ else pde = de;
+ de = (struct ufs_dir_entry *)
+ ((char *) de + SWAB16(de->d_reclen));
+ if (i == UFS_SECTOR_SIZE && SWAB16(de->d_reclen) == 0)
+ break;
+ }
+ UFSD(("EXIT\n"))
+ brelse(bh);


+ return -ENOENT;
+}
+

+int ufs_make_empty(struct inode * inode, struct inode *dir)
+{
+ struct super_block * sb = dir->i_sb;
+ unsigned flags = sb->u.ufs_sb.s_flags;
+ unsigned swab = sb->u.ufs_sb.s_swab;
+ struct buffer_head * dir_block;
+ struct ufs_dir_entry * de;
+ int err;
+
+ dir_block = ufs_bread (inode, 0, 1, &err);
+ if (!dir_block)
+ return err;
+
+ inode->i_blocks = sb->s_blocksize / UFS_SECTOR_SIZE;
+ de = (struct ufs_dir_entry *) dir_block->b_data;
+ de->d_ino = SWAB32(inode->i_ino);
+ ufs_set_de_type (de, inode->i_mode);
+ ufs_set_de_namlen(de,1);
+ de->d_reclen = SWAB16(UFS_DIR_REC_LEN(1));
+ strcpy (de->d_name, ".");
+ de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
+ de->d_ino = SWAB32(dir->i_ino);
+ ufs_set_de_type (de, dir->i_mode);
+ de->d_reclen = SWAB16(UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1));
+ ufs_set_de_namlen(de,2);
+ strcpy (de->d_name, "..");
+ mark_buffer_dirty(dir_block);
+ brelse (dir_block);
+ mark_inode_dirty(inode);


+ return 0;
+}
+

+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int ufs_empty_dir (struct inode * inode)
+{
+ struct super_block * sb;
+ unsigned long offset;
+ struct buffer_head * bh;
+ struct ufs_dir_entry * de, * de1;
+ int err;
+ unsigned swab;
+
+ sb = inode->i_sb;
+ swab = sb->u.ufs_sb.s_swab;
+
+ if (inode->i_size < UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||
+ !(bh = ufs_bread (inode, 0, 0, &err))) {
+ ufs_warning (inode->i_sb, "empty_dir",
+ "bad directory (dir #%lu) - no data block",
+ inode->i_ino);
+ return 1;
+ }
+ de = (struct ufs_dir_entry *) bh->b_data;
+ de1 = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
+ if (SWAB32(de->d_ino) != inode->i_ino || !SWAB32(de1->d_ino) ||
+ strcmp (".", de->d_name) || strcmp ("..", de1->d_name)) {
+ ufs_warning (inode->i_sb, "empty_dir",
+ "bad directory (dir #%lu) - no `.' or `..'",
+ inode->i_ino);
+ return 1;
+ }
+ offset = SWAB16(de->d_reclen) + SWAB16(de1->d_reclen);
+ de = (struct ufs_dir_entry *) ((char *) de1 + SWAB16(de1->d_reclen));
+ while (offset < inode->i_size ) {
+ if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
+ brelse (bh);
+ bh = ufs_bread (inode, offset >> sb->s_blocksize_bits, 1, &err);
+ if (!bh) {
+ ufs_error (sb, "empty_dir",
+ "directory #%lu contains a hole at offset %lu",
+ inode->i_ino, offset);
+ offset += sb->s_blocksize;
+ continue;
+ }
+ de = (struct ufs_dir_entry *) bh->b_data;
+ }
+ if (!ufs_check_dir_entry ("empty_dir", inode, de, bh, offset)) {
+ brelse (bh);
+ return 1;
+ }
+ if (SWAB32(de->d_ino)) {
+ brelse (bh);
+ return 0;
+ }
+ offset += SWAB16(de->d_reclen);
+ de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
+ }
+ brelse (bh);
+ return 1;
X }
X
X struct file_operations ufs_dir_operations = {
diff -u --recursive --new-file v2.4.12/linux/fs/ufs/ialloc.c linux/fs/ufs/ialloc.c
--- v2.4.12/linux/fs/ufs/ialloc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/ufs/ialloc.c Sat Oct 20 19:14:42 2001
@@ -143,7 +143,7 @@
X * For other inodes, search forward from the parent directory's block
X * group to find a free inode.
X */
-struct inode * ufs_new_inode (const struct inode * dir, int mode, int * err )
+struct inode * ufs_new_inode (const struct inode * dir, int mode)
X {
X struct super_block * sb;
X struct ufs_sb_private_info * uspi;
@@ -157,24 +157,18 @@
X UFSD(("ENTER\n"))
X
X /* Cannot create files in a deleted directory */
- if (!dir || !dir->i_nlink) {
- *err = -EPERM;
- return NULL;
- }
+ if (!dir || !dir->i_nlink)
+ return ERR_PTR(-EPERM);
X sb = dir->i_sb;
X inode = new_inode(sb);
- if (!inode) {
- *err = -ENOMEM;
- return NULL;
- }
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
X swab = sb->u.ufs_sb.s_swab;
X uspi = sb->u.ufs_sb.s_uspi;
X usb1 = ubh_get_usb_first(USPI_UBH);
X
X lock_super (sb);
X
- *err = -ENOSPC;
-
X /*
X * Try to place the inode in its parent directory
X */
@@ -262,7 +256,7 @@
X if (dir->i_mode & S_ISGID) {
X inode->i_gid = dir->i_gid;
X if (S_ISDIR(mode))
- mode |= S_ISGID;
+ inode->i_mode |= S_ISGID;
X } else
X inode->i_gid = current->fsgid;
X
@@ -283,12 +277,10 @@
X inode->i_flags |= S_NOQUOTA;
X inode->i_nlink = 0;
X iput(inode);
- *err = -EDQUOT;
- return NULL;
+ return ERR_PTR(-EDQUOT);
X }
X
X UFSD(("allocating inode %lu\n", inode->i_ino))
- *err = 0;
X UFSD(("EXIT\n"))
X return inode;
X
@@ -297,5 +289,5 @@
X make_bad_inode(inode);
X iput (inode);
X UFSD(("EXIT (FAILED)\n"))
- return NULL;
+ return ERR_PTR(-ENOSPC);
X }
diff -u --recursive --new-file v2.4.12/linux/fs/ufs/inode.c linux/fs/ufs/inode.c
--- v2.4.12/linux/fs/ufs/inode.c Mon Dec 4 19:00:54 2000
+++ linux/fs/ufs/inode.c Sat Oct 20 19:14:42 2001
@@ -50,130 +50,84 @@
X #define UFSD(x)
X #endif
X
-#ifdef UFS_INODE_DEBUG_MORE
-static void ufs_print_inode(struct inode * inode)
-{
- unsigned swab = inode->i_sb->u.ufs_sb.s_swab;
- printk("ino %lu mode 0%6.6o nlink %d uid %d gid %d"
- " size %lu blocks %lu\n",
- inode->i_ino, inode->i_mode, inode->i_nlink,
- inode->i_uid, inode->i_gid,
- inode->i_size, inode->i_blocks);
- printk(" db <%u %u %u %u %u %u %u %u %u %u %u %u>\n",
- SWAB32(inode->u.ufs_i.i_u1.i_data[0]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[1]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[2]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[3]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[4]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[5]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[6]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[7]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[8]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[9]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[10]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[11]));
- printk(" gen %u ib <%u %u %u>\n",
- inode->u.ufs_i.i_gen,
- SWAB32(inode->u.ufs_i.i_u1.i_data[UFS_IND_BLOCK]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[UFS_DIND_BLOCK]),
- SWAB32(inode->u.ufs_i.i_u1.i_data[UFS_TIND_BLOCK]));
-}
-#endif
-
-#define ufs_inode_bmap(inode, nr) \
- (SWAB32((inode)->u.ufs_i.i_u1.i_data[(nr) >> uspi->s_fpbshift]) + ((nr) & uspi->s_fpbmask))
-
-static inline unsigned int ufs_block_bmap (struct buffer_head * bh, unsigned nr,
+static inline unsigned int ufs_block_bmap1(struct buffer_head * bh, unsigned nr,
X struct ufs_sb_private_info * uspi, unsigned swab)
X {
X unsigned int tmp;
-
- UFSD(("ENTER, nr %u\n", nr))
X if (!bh)
X return 0;
- tmp = SWAB32(((u32 *) bh->b_data)[nr >> uspi->s_fpbshift]) + (nr & uspi->s_fpbmask);
+ tmp = SWAB32(((u32 *) bh->b_data)[nr]);
X brelse (bh);
- UFSD(("EXIT, result %u\n", tmp))
X return tmp;
X }
X
+static int ufs_block_to_path(struct inode *inode, long i_block, int offsets[4])
+{
+ struct ufs_sb_private_info *uspi = inode->i_sb->u.ufs_sb.s_uspi;
+ int ptrs = uspi->s_apb;
+ int ptrs_bits = uspi->s_apbshift;
+ const long direct_blocks = UFS_NDADDR,
+ indirect_blocks = ptrs,
+ double_blocks = (1 << (ptrs_bits * 2));
+ int n = 0;
+
+ if (i_block < 0) {
+ ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
+ } else if (i_block < direct_blocks) {
+ offsets[n++] = i_block;
+ } else if ((i_block -= direct_blocks) < indirect_blocks) {
+ offsets[n++] = UFS_IND_BLOCK;
+ offsets[n++] = i_block;
+ } else if ((i_block -= indirect_blocks) < double_blocks) {
+ offsets[n++] = UFS_DIND_BLOCK;
+ offsets[n++] = i_block >> ptrs_bits;
+ offsets[n++] = i_block & (ptrs - 1);
+ } else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
+ offsets[n++] = UFS_TIND_BLOCK;
+ offsets[n++] = i_block >> (ptrs_bits * 2);
+ offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1);
+ offsets[n++] = i_block & (ptrs - 1);
+ } else {
+ ufs_warning(inode->i_sb, "ufs_block_to_path", "block > big");
+ }
+ return n;
+}
+
X int ufs_frag_map(struct inode *inode, int frag)
X {
- struct super_block *sb;
- struct ufs_sb_private_info *uspi;
- unsigned int swab;
- int i, ret;


+ struct super_block *sb = inode->i_sb;

+ struct ufs_sb_private_info *uspi = sb->u.ufs_sb.s_uspi;
+ unsigned int swab = sb->u.ufs_sb.s_swab;
+ int mask = uspi->s_apbmask>>uspi->s_fpbshift;
+ int shift = uspi->s_apbshift-uspi->s_fpbshift;
+ int offsets[4], *p;
+ int depth = ufs_block_to_path(inode, frag >> uspi->s_fpbshift, offsets);


+ int ret = 0;

+ u32 block;
X
- ret = 0;
- lock_kernel();
-
- sb = inode->i_sb;
- uspi = sb->u.ufs_sb.s_uspi;
- swab = sb->u.ufs_sb.s_swab;
- if (frag < 0) {
- ufs_warning(sb, "ufs_frag_map", "frag < 0");
- goto out;
- }
- if (frag >=
- ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
- << uspi->s_fpbshift)) {
- ufs_warning(sb, "ufs_frag_map", "frag > big");
- goto out;
- }
+ if (depth == 0)
+ return 0;
X
- if (frag < UFS_NDIR_FRAGMENT) {
- ret = uspi->s_sbbase + ufs_inode_bmap(inode, frag);
- goto out;
- }
+ p = offsets;
X
- frag -= UFS_NDIR_FRAGMENT;
- if (frag < (1 << (uspi->s_apbshift + uspi->s_fpbshift))) {
- i = ufs_inode_bmap(inode,
- UFS_IND_FRAGMENT + (frag >> uspi->s_apbshift));
- if (!i)
- goto out;
- ret = (uspi->s_sbbase +
- ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i,
- sb->s_blocksize),
- frag & uspi->s_apbmask, uspi, swab));
+ lock_kernel();
+ block = inode->u.ufs_i.i_u1.i_data[*p++];
+ if (!block)
X goto out;
- }
- frag -= 1 << (uspi->s_apbshift + uspi->s_fpbshift);
- if (frag < (1 << (uspi->s_2apbshift + uspi->s_fpbshift))) {
- i = ufs_inode_bmap (inode,
- UFS_DIND_FRAGMENT + (frag >> uspi->s_2apbshift));
- if (!i)
+ while (--depth) {
+ struct buffer_head *bh;
+ int n = *p++;
+
+ bh = bread(sb->s_dev, uspi->s_sbbase+SWAB32(block)+(n>>shift),
+ sb->s_blocksize);
+ if (!bh)
X goto out;
- i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i,
- sb->s_blocksize),
- (frag >> uspi->s_apbshift) & uspi->s_apbmask,
- uspi, swab);
- if (!i)
+ block = ((u32*) bh->b_data)[n & mask];
+ brelse (bh);
+ if (!block)
X goto out;
- ret = (uspi->s_sbbase +
- ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i,
- sb->s_blocksize),
- (frag & uspi->s_apbmask), uspi, swab));
- goto out;
X }
- frag -= 1 << (uspi->s_2apbshift + uspi->s_fpbshift);
- i = ufs_inode_bmap(inode,
- UFS_TIND_FRAGMENT + (frag >> uspi->s_3apbshift));
- if (!i)
- goto out;
- i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize),
- (frag >> uspi->s_2apbshift) & uspi->s_apbmask,
- uspi, swab);
- if (!i)
- goto out;
- i = ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize),
- (frag >> uspi->s_apbshift) & uspi->s_apbmask,
- uspi, swab);
- if (!i)
- goto out;
- ret = (uspi->s_sbbase +
- ufs_block_bmap(bread(sb->s_dev, uspi->s_sbbase + i, sb->s_blocksize),
- (frag & uspi->s_apbmask), uspi, swab));
+ ret = uspi->s_sbbase + SWAB32(block) + (frag & uspi->s_fpbmask);
X out:
X unlock_kernel();
X return ret;
@@ -640,9 +594,6 @@
X
X brelse (bh);
X
-#ifdef UFS_INODE_DEBUG_MORE
- ufs_print_inode (inode);


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 46'
echo 'File patch-2.4.13 is continued in part 47'
echo "47" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:15 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part45

#!/bin/sh -x
# this is part 45 of a 53 - part archive


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

if test "$Scheck" != 45; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X /* put key (ino analog) to de */
- deh->deh_dir_id = INODE_PKEY (inode)->k_dir_id;
- deh->deh_objectid = INODE_PKEY (inode)->k_objectid;
+ deh->deh_dir_id = INODE_PKEY (inode)->k_dir_id; /* safe: k_dir_id is le */
+ deh->deh_objectid = INODE_PKEY (inode)->k_objectid; /* safe: k_objectid is le */
X
X /* copy name */
X memcpy ((char *)(deh + 1), name, namelen);
@@ -454,36 +449,37 @@
X memset (bit_string, 0, sizeof (bit_string));
X de.de_gen_number_bit_string = (char *)bit_string;
X retval = reiserfs_find_entry (dir, name, namelen, &path, &de);
- if (retval != NAME_NOT_FOUND) {
+ if( retval != NAME_NOT_FOUND ) {
X if (buffer != small_buf)
X reiserfs_kfree (buffer, buflen, dir->i_sb);
X pathrelse (&path);
-
- if (retval != NAME_FOUND) {
+
+ if (retval != NAME_FOUND) {
X reiserfs_warning ("zam-7002:" __FUNCTION__ ": \"reiserfs_find_entry\" has returned"
- " unexpected value (%d)\n", retval);
- }
-
+ " unexpected value (%d)\n", retval);
+ }
+
X return -EEXIST;
X }
X
X gen_number = find_first_zero_bit (bit_string, MAX_GENERATION_NUMBER + 1);
X if (gen_number > MAX_GENERATION_NUMBER) {
- /* there is no free generation number */
- reiserfs_warning ("reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");
- if (buffer != small_buf)
- reiserfs_kfree (buffer, buflen, dir->i_sb);
- pathrelse (&path);
- return -EBUSY;
+ /* there is no free generation number */
+ reiserfs_warning ("reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");
+ if (buffer != small_buf)
+ reiserfs_kfree (buffer, buflen, dir->i_sb);
+ pathrelse (&path);
+ return -EBUSY;
X }
X /* adjust offset of directory enrty */
- deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (deh_offset (deh), gen_number));
- set_cpu_key_k_offset (&entry_key, le32_to_cpu (deh->deh_offset));
-
+ put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number));
+ set_cpu_key_k_offset (&entry_key, deh_offset(deh));
+
X if (gen_number != 0) { /* we need to re-search for the insertion point */
- if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
- reiserfs_warning ("vs-7032: reiserfs_add_entry: "
- "entry with this key (%k) already exists\n", &entry_key);
+ if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
+ reiserfs_warning ("vs-7032: reiserfs_add_entry: "
+ "entry with this key (%k) already exists\n", &entry_key);
+
X if (buffer != small_buf)
X reiserfs_kfree (buffer, buflen, dir->i_sb);
X pathrelse (&path);
@@ -558,6 +554,8 @@
X iput (inode);
X return retval;
X }
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
X
X d_instantiate(dentry, inode);
X pop_journal_writer(windex) ;
@@ -600,6 +598,9 @@
X //FIXME: needed for block and char devices only


X reiserfs_update_sd (&th, inode);
X

+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
+
X retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
X inode, 1/*visible*/);
X if (retval) {
@@ -655,6 +656,8 @@
X journal_end(&th, dir->i_sb, jbegin_count) ;
X return retval;
X }
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
X
X inode->i_op = &reiserfs_dir_inode_operations;
X inode->i_fop = &reiserfs_dir_operations;


@@ -723,6 +726,9 @@
X }

X inode = dentry->d_inode;
X
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
+
X if (de.de_objectid != inode->i_ino) {
X // FIXME: compare key of an object and a key found in the
X // entry
@@ -796,6 +802,9 @@
X }
X inode = dentry->d_inode;
X
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
+
X if (de.de_objectid != inode->i_ino) {
X // FIXME: compare key of an object and a key found in the
X // entry
@@ -885,6 +894,9 @@
X return retval;
X }
X
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
+
X inode->i_op = &page_symlink_inode_operations;
X inode->i_mapping->a_ops = &reiserfs_address_space_operations;
X
@@ -940,6 +952,10 @@
X /* create new entry */
X retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
X inode, 1/*visible*/);
+
+ reiserfs_update_inode_transaction(inode) ;
+ reiserfs_update_inode_transaction(dir) ;
+
X if (retval) {
X pop_journal_writer(windex) ;
X journal_end(&th, dir->i_sb, jbegin_count) ;
@@ -994,6 +1010,7 @@
X /* sets key of objectid the entry has to point to */
X static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * key)
X {
+ /* JDM These operations are endian safe - both are le */
X de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id;
X de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid;
X }
@@ -1085,6 +1102,16 @@


X return retval;
X }
X

+ reiserfs_update_inode_transaction(old_dir) ;
+ reiserfs_update_inode_transaction(new_dir) ;
+
+ /* this makes it so an fsync on an open fd for the old name will
+ ** commit the rename operation
+ */
+ reiserfs_update_inode_transaction(old_inode) ;
+
+ if (new_inode)
+ reiserfs_update_inode_transaction(new_inode) ;
X
X while (1) {
X // look for old name using corresponding entry key (found by reiserfs_find_entry)
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/objectid.c linux/fs/reiserfs/objectid.c
--- v2.4.12/linux/fs/reiserfs/objectid.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/objectid.c Fri Oct 12 14:19:28 2001
@@ -80,10 +80,9 @@
X first two odd sequences into one sequence. If so, then the net
X result is to eliminate a pair of objectids from oids. We do this
X by shifting the entire map to the left. */
- if (le16_to_cpu (rs->s_oid_cursize) > 2 && map[1] == map[2]) {
- memmove (map + 1, map + 3, (le16_to_cpu (rs->s_oid_cursize) - 3) * sizeof(__u32));
- //rs->s_oid_cursize -= 2;
- rs->s_oid_cursize = cpu_to_le16 (le16_to_cpu (rs->s_oid_cursize) - 2);
+ if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) {
+ memmove (map + 1, map + 3, (sb_oid_cursize(rs) - 3) * sizeof(__u32));
+ set_sb_oid_cursize( rs, sb_oid_cursize(rs) - 2 );
X }
X
X journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s));
@@ -114,7 +113,7 @@
X what we use, though it is possible that binary search would be
X more efficient after performing lots of deletions (which is
X when oids is large.) We only check even i's. */
- while (i < le16_to_cpu (rs->s_oid_cursize)) {
+ while (i < sb_oid_cursize(rs)) {
X if (objectid_to_release == le32_to_cpu (map[i])) {
X /* This incrementation unallocates the objectid. */
X //map[i]++;
@@ -124,14 +123,14 @@
X if (map[i] == map[i+1]) {
X /* shrink objectid map */
X memmove (map + i, map + i + 2,
- (le16_to_cpu (rs->s_oid_cursize) - i - 2) * sizeof (__u32));
+ (sb_oid_cursize(rs) - i - 2) * sizeof (__u32));
X //disk_sb->s_oid_cursize -= 2;
- rs->s_oid_cursize = cpu_to_le16 (le16_to_cpu (rs->s_oid_cursize) - 2);
+ set_sb_oid_cursize( rs, sb_oid_cursize(rs) - 2 );
X
- RFALSE( le16_to_cpu (rs->s_oid_cursize) < 2 ||
- le16_to_cpu (rs->s_oid_cursize) > le16_to_cpu (rs->s_oid_maxsize),
- "vs-15005: objectid map corrupted cur_size == %d (max == %d)",
- le16_to_cpu (rs->s_oid_cursize), le16_to_cpu (rs->s_oid_maxsize));
+ RFALSE( sb_oid_cursize(rs) < 2 ||
+ sb_oid_cursize(rs) > sb_oid_maxsize(rs),
+ "vs-15005: objectid map corrupted cur_size == %d (max == %d)",
+ sb_oid_cursize(rs), sb_oid_maxsize(rs));
X }
X return;
X }
@@ -145,16 +144,17 @@
X return;
X }
X
+ /* JDM comparing two little-endian values for equality -- safe */
X if (rs->s_oid_cursize == rs->s_oid_maxsize)
X /* objectid map must be expanded, but there is no space */
X return;
X
X /* expand the objectid map*/
X memmove (map + i + 3, map + i + 1,
- (le16_to_cpu (rs->s_oid_cursize) - i - 1) * sizeof(__u32));
+ (sb_oid_cursize(rs) - i - 1) * sizeof(__u32));
X map[i + 1] = cpu_to_le32 (objectid_to_release);
X map[i + 2] = cpu_to_le32 (objectid_to_release + 1);
- rs->s_oid_cursize = cpu_to_le16 (le16_to_cpu (rs->s_oid_cursize) + 2);
+ set_sb_oid_cursize( rs, sb_oid_cursize(rs) + 2 );
X return;
X }
X i += 2;
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/prints.c linux/fs/reiserfs/prints.c
--- v2.4.12/linux/fs/reiserfs/prints.c Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/prints.c Sun Oct 14 10:31:45 2001
@@ -15,7 +15,7 @@
X static char off_buf[80];
X
X
-static char * cpu_offset (struct cpu_key * key)
+static char * reiserfs_cpu_offset (struct cpu_key * key)
X {
X if (cpu_key_k_type(key) == TYPE_DIRENTRY)
X sprintf (off_buf, "%Lu(%Lu)",
@@ -90,11 +90,21 @@
X {
X if (key)
X sprintf (buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
- key->on_disk_key.k_objectid, cpu_offset (key), cpu_type (key));
+ key->on_disk_key.k_objectid, reiserfs_cpu_offset (key),
+ cpu_type (key));
X else
X sprintf (buf, "[NULL]");
X }
X
+static void sprintf_de_head( char *buf, struct reiserfs_de_head *deh )
+{
+ if( deh )
+ sprintf( buf, "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", deh_offset(deh), deh_dir_id(deh),
+ deh_objectid(deh), deh_location(deh), deh_state(deh) );
+ else
+ sprintf( buf, "[NULL]" );
+
+}
X
X static void sprintf_item_head (char * buf, struct item_head * ih)
X {
@@ -103,7 +113,7 @@
X sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
X sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
X "free_space(entry_count) %d",
- ih->ih_item_len, ih->ih_item_location, ih_free_space (ih));
+ ih_item_len(ih), ih_location(ih), ih_free_space (ih));
X } else
X sprintf (buf, "[NULL]");
X }
@@ -123,10 +133,6 @@
X {
X sprintf (buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
X B_LEVEL (bh), B_NR_ITEMS (bh), B_FREE_SPACE (bh));
-#if 0
- if (B_LEVEL (bh) == DISK_LEAF_NODE_LEVEL)
- sprintf_le_key (buf + strlen (buf), B_PRIGHT_DELIM_KEY (bh));
-#endif
X }
X
X
@@ -143,7 +149,7 @@
X
X static void sprintf_disk_child (char * buf, struct disk_child * dc)
X {
- sprintf (buf, "[dc_number=%d, dc_size=%u]", dc->dc_block_number, dc->dc_size);
+ sprintf (buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), dc_size(dc));
X }
X
X
@@ -153,12 +159,10 @@
X
X *skip = 0;
X
- while (1) {
- k = strstr (k, "%");
- if (!k)
- break;
- if (k && (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
- k[1] == 'z' || k[1] == 'b' || k[1] == 'y')) {
+ while ((k = strstr (k, "%")) != NULL)
+ {
+ if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
+ k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' ) {
X *what = k[1];
X break;
X }
@@ -182,59 +186,58 @@
X key->k_offset, key->k_uniqueness);
X */
X
-#define do_reiserfs_warning \
-{\
- char * fmt1 = fmt_buf;\
- va_list args;\
- int i, j;\
- char * k;\
- char * p = error_buf;\
- int what, skip;\
-\
- strcpy (fmt1, fmt);\
- va_start(args, fmt);\
-\
- while (1) {\
- k = is_there_reiserfs_struct (fmt1, &what, &skip);\
- if (k != 0) {\
- *k = 0;\
- p += vsprintf (p, fmt1, args);\
-\
- for (i = 0; i < skip; i ++)\
- j = va_arg (args, int);\
-\
- switch (what) {\
- case 'k':\
- sprintf_le_key (p, va_arg(args, struct key *));\
- break;\
- case 'K':\
- sprintf_cpu_key (p, va_arg(args, struct cpu_key *));\
- break;\
- case 'h':\
- sprintf_item_head (p, va_arg(args, struct item_head *));\
- break;\
- case 't':\
- sprintf_direntry (p, va_arg(args, struct reiserfs_dir_entry *));\
- break;\
- case 'y':\
- sprintf_disk_child (p, va_arg(args, struct disk_child *));\
- break;\
- case 'z':\
- sprintf_block_head (p, va_arg(args, struct buffer_head *));\
- break;\
- case 'b':\
- sprintf_buffer_head (p, va_arg(args, struct buffer_head *));\
- break;\
- }\
- p += strlen (p);\
- fmt1 = k + 2;\
- } else {\
- i = vsprintf (p, fmt1, args);\
- break;\
- }\
- }\
-\
- va_end(args);\
+
+static void
+prepare_error_buf( const char *fmt, va_list args )
+{
+ char * fmt1 = fmt_buf;
+ char * k;
+ char * p = error_buf;
+ int i, j, what, skip;
+
+ strcpy (fmt1, fmt);
+
+ while( (k = is_there_reiserfs_struct( fmt1, &what, &skip )) != NULL )
+ {
+ *k = 0;
+
+ p += vsprintf (p, fmt1, args);
+
+ for (i = 0; i < skip; i ++)
+ j = va_arg (args, int);
+
+ switch (what) {
+ case 'k':
+ sprintf_le_key (p, va_arg(args, struct key *));
+ break;
+ case 'K':
+ sprintf_cpu_key (p, va_arg(args, struct cpu_key *));
+ break;
+ case 'h':
+ sprintf_item_head (p, va_arg(args, struct item_head *));
+ break;
+ case 't':
+ sprintf_direntry (p, va_arg(args, struct reiserfs_dir_entry *));
+ break;
+ case 'y':
+ sprintf_disk_child (p, va_arg(args, struct disk_child *));
+ break;
+ case 'z':
+ sprintf_block_head (p, va_arg(args, struct buffer_head *));
+ break;
+ case 'b':
+ sprintf_buffer_head (p, va_arg(args, struct buffer_head *));
+ break;
+ case 'a':
+ sprintf_de_head (p, va_arg(args, struct reiserfs_de_head *));
+ break;
+ }
+
+ p += strlen (p);
+ fmt1 = k + 2;
+ }
+ vsprintf (p, fmt1, args);
+
X }
X
X
@@ -247,9 +250,18 @@
X %z to print block head (arg must be struct buffer_head *
X %b to print buffer_head
X */
+
+#define do_reiserfs_warning(fmt)\
+{\
+ va_list args;\
+ va_start( args, fmt );\
+ prepare_error_buf( fmt, args );\
+ va_end( args );\
+}
+
X void reiserfs_warning (const char * fmt, ...)
X {
- do_reiserfs_warning;
+ do_reiserfs_warning(fmt);
X /* console_print (error_buf); */
X printk (KERN_WARNING "%s", error_buf);
X }
@@ -257,7 +269,7 @@
X void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...)
X {
X #ifdef CONFIG_REISERFS_CHECK
- do_reiserfs_warning;
+ do_reiserfs_warning(fmt);
X printk (KERN_DEBUG "%s", error_buf);
X #else
X ;
@@ -291,7 +303,7 @@
X
X panics in reiserfs_fs.h have numbers from 1000 to 1999
X super.c 2000 to 2999
- preserve.c 3000 to 3999
+ preserve.c (unused) 3000 to 3999
X bitmap.c 4000 to 4999
X stree.c 5000 to 5999
X prints.c 6000 to 6999
@@ -317,8 +329,8 @@
X void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
X {
X show_reiserfs_locks() ;
- do_reiserfs_warning;
- printk ("%s", error_buf);
+ do_reiserfs_warning(fmt);
+ printk ( KERN_EMERG "%s", error_buf);
X BUG ();
X // console_print (error_buf);
X // for (;;);
@@ -437,7 +449,7 @@
X {


X struct block_head * blkh;
X struct item_head * ih;

- int i;
+ int i, nr;
X int from, to;
X
X if (!B_IS_ITEMS_LEVEL (bh))


@@ -447,23 +459,24 @@
X

X blkh = B_BLK_HEAD (bh);
X ih = B_N_PITEM_HEAD (bh,0);


+ nr = blkh_nr_item(blkh);
X

X printk ("\n===================================================================\n");
X reiserfs_warning ("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
X
X if (!(print_mode & PRINT_LEAF_ITEMS)) {
X reiserfs_warning ("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
- &(ih->ih_key), &((ih + le16_to_cpu (blkh->blk_nr_item) - 1)->ih_key));
+ &(ih->ih_key), &((ih + nr - 1)->ih_key));


X return 0;
X }
X

- if (first < 0 || first > le16_to_cpu (blkh->blk_nr_item) - 1)
+ if (first < 0 || first > nr - 1)
X from = 0;
X else
X from = first;
X
- if (last < 0 || last > le16_to_cpu (blkh->blk_nr_item))
- to = le16_to_cpu (blkh->blk_nr_item);
+ if (last < 0 || last > nr )
+ to = nr;
X else
X to = last;
X
@@ -482,52 +495,50 @@


X return 0;
X }
X

-static char * reiserfs_version (char * buf)
-{
- __u16 * pversion;
-
- pversion = (__u16 *)(buf) + 36;
- if (*pversion == 0)
- return "0";
- if (*pversion == 2)
- return "2";
- return "Unknown";
-}
-
-
X /* return 1 if this is not super block */
X static int print_super_block (struct buffer_head * bh)
X {
X struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data);
X int skipped, data_blocks;
+ char *version;
X
X
- if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) &&
- strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING)))
+ if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING,
+ strlen ( REISERFS_SUPER_MAGIC_STRING)) == 0) {
+ version = "3.5";
+ } else if( strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING,
+ strlen ( REISER2FS_SUPER_MAGIC_STRING)) == 0) {
+ version = "3.6";
+ } else {
X return 1;
+ }
X
- printk ("%s\'s super block in block %ld\n======================\n", kdevname (bh->b_dev), bh->b_blocknr);
- printk ("Reiserfs version %s\n", reiserfs_version (bh->b_data));
- printk ("Block count %u\n", le32_to_cpu (rs->s_block_count));
- printk ("Blocksize %d\n", le16_to_cpu (rs->s_blocksize));
- printk ("Free blocks %u\n", le32_to_cpu (rs->s_free_blocks));
- skipped = bh->b_blocknr; // FIXME: this would be confusing if
+ printk ("%s\'s super block in block %ld\n======================\n",
+ kdevname (bh->b_dev), bh->b_blocknr);
+ printk ("Reiserfs version %s\n", version );
+ printk ("Block count %u\n", sb_block_count(rs));
+ printk ("Blocksize %d\n", sb_blocksize(rs));
+ printk ("Free blocks %u\n", sb_free_blocks(rs));
+ // FIXME: this would be confusing if
X // someone stores reiserfs super block in some data block ;)
- data_blocks = le32_to_cpu (rs->s_block_count) - skipped - 1 -
- le16_to_cpu (rs->s_bmap_nr) - (le32_to_cpu (rs->s_orig_journal_size) + 1) -
- le32_to_cpu (rs->s_free_blocks);
+// skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
+ skipped = bh->b_blocknr;
+ data_blocks = sb_block_count(rs) - skipped - 1 -
+ sb_bmap_nr(rs) - (sb_orig_journal_size(rs) + 1) -
+ sb_free_blocks(rs);
X printk ("Busy blocks (skipped %d, bitmaps - %d, journal blocks - %d\n"
X "1 super blocks, %d data blocks\n",
- skipped, le16_to_cpu (rs->s_bmap_nr),
- (le32_to_cpu (rs->s_orig_journal_size) + 1), data_blocks);
- printk ("Root block %u\n", le32_to_cpu (rs->s_root_block));
- printk ("Journal block (first) %d\n", le32_to_cpu (rs->s_journal_block));
- printk ("Journal dev %d\n", le32_to_cpu (rs->s_journal_dev));
- printk ("Journal orig size %d\n", le32_to_cpu (rs->s_orig_journal_size));
+ skipped, sb_bmap_nr(rs),
+ (sb_orig_journal_size(rs) + 1), data_blocks);
+ printk ("Root block %u\n", sb_root_block(rs));
+ printk ("Journal block (first) %d\n", sb_journal_block(rs));
+ printk ("Journal dev %d\n", sb_journal_dev(rs));
+ printk ("Journal orig size %d\n", sb_orig_journal_size(rs));
X printk ("Filesystem state %s\n",
- (le16_to_cpu (rs->s_state) == REISERFS_VALID_FS) ? "VALID" : "ERROR");
- printk ("Hash function \"%s\"\n", le16_to_cpu (rs->s_hash_function_code) == TEA_HASH ? "tea" :
- ((le16_to_cpu (rs->s_hash_function_code) == YURA_HASH) ? "rupasov" : "unknown"));
+ (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR");
+ printk ("Hash function \"%s\"\n",
+ sb_hash_function_code(rs) == TEA_HASH ? "tea" :
+ ((sb_hash_function_code(rs) == YURA_HASH) ? "rupasov" : "unknown"));
X
X #if 0
X __u32 s_journal_trans_max ; /* max number of blocks in a transaction. */
@@ -536,7 +547,7 @@
X __u32 s_journal_max_commit_age ; /* in seconds, how old can an async commit be */
X __u32 s_journal_max_trans_age ; /* in seconds, how old can a transaction be */
X #endif
- printk ("Tree height %d\n", rs->s_tree_height);
+ printk ("Tree height %d\n", sb_tree_height(rs));


X return 0;
X }
X

@@ -665,12 +676,14 @@
X static void check_leaf_block_head (struct buffer_head * bh)
X {


X struct block_head * blkh;

+ int nr;
X
X blkh = B_BLK_HEAD (bh);
- if (le16_to_cpu (blkh->blk_nr_item) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
+ nr = blkh_nr_item(blkh);
+ if ( nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
X reiserfs_panic (0, "vs-6010: check_leaf_block_head: invalid item number %z", bh);
- if (le16_to_cpu (blkh->blk_free_space) >
- bh->b_size - BLKH_SIZE - IH_SIZE * le16_to_cpu (blkh->blk_nr_item))
+ if ( blkh_free_space(blkh) >
+ bh->b_size - BLKH_SIZE - IH_SIZE * nr )
X reiserfs_panic (0, "vs-6020: check_leaf_block_head: invalid free space %z", bh);
X
X }
@@ -718,9 +731,9 @@
X {
X
X /*
- printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, preserve list freeings %d, \
+ printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
X bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
- s->u.reiserfs_sb.s_do_balance, s->u.reiserfs_sb.s_fix_nodes, s->u.reiserfs_sb.s_preserve_list_freeings,
+ s->u.reiserfs_sb.s_do_balance, s->u.reiserfs_sb.s_fix_nodes,
X s->u.reiserfs_sb.s_bmaps, s->u.reiserfs_sb.s_bmaps_without_search,
X s->u.reiserfs_sb.s_direct2indirect, s->u.reiserfs_sb.s_indirect2direct);
X */
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- v2.4.12/linux/fs/reiserfs/stree.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/stree.c Fri Oct 12 14:20:42 2001
@@ -226,8 +226,8 @@
X to->on_disk_key.u.k_offset_v1.k_offset = le32_to_cpu (from->u.k_offset_v1.k_offset);
X to->on_disk_key.u.k_offset_v1.k_uniqueness = le32_to_cpu (from->u.k_offset_v1.k_uniqueness);
X } else {
- to->on_disk_key.u.k_offset_v2.k_offset = le64_to_cpu (from->u.k_offset_v2.k_offset);
- to->on_disk_key.u.k_offset_v2.k_type = le16_to_cpu (from->u.k_offset_v2.k_type);
+ to->on_disk_key.u.k_offset_v2.k_offset = offset_v2_k_offset(&from->u.k_offset_v2);
+ to->on_disk_key.u.k_offset_v2.k_type = offset_v2_k_type(&from->u.k_offset_v2);
X }
X }
X
@@ -268,19 +268,19 @@
X the item size. */
X int * p_n_pos /* Number of the searched for element. */
X ) {
- int n_rbound, n_lbound, n_j;
+ int n_rbound, n_lbound, n_j;
X
- for ( n_j = ((n_rbound = p_n_num - 1) + (n_lbound = 0))/2; n_lbound <= n_rbound; n_j = (n_rbound + n_lbound)/2 )
- switch( COMP_KEYS((struct key *)((char * )p_v_base + n_j * p_n_width), (struct cpu_key *)p_v_key) ) {
- case -1: n_lbound = n_j + 1; continue;
- case 1: n_rbound = n_j - 1; continue;
- case 0: *p_n_pos = n_j; return ITEM_FOUND; /* Key found in the array. */
- }
-
- /* bin_search did not find given key, it returns position of key,
- that is minimal and greater than the given one. */
- *p_n_pos = n_lbound;
- return ITEM_NOT_FOUND;
+ for ( n_j = ((n_rbound = p_n_num - 1) + (n_lbound = 0))/2; n_lbound <= n_rbound; n_j = (n_rbound + n_lbound)/2 )
+ switch( COMP_KEYS((struct key *)((char * )p_v_base + n_j * p_n_width), (struct cpu_key *)p_v_key) ) {
+ case -1: n_lbound = n_j + 1; continue;
+ case 1: n_rbound = n_j - 1; continue;
+ case 0: *p_n_pos = n_j; return ITEM_FOUND; /* Key found in the array. */
+ }
+
+ /* bin_search did not find given key, it returns position of key,
+ that is minimal and greater than the given one. */
+ *p_n_pos = n_lbound;
+ return ITEM_NOT_FOUND;
X }
X
X #ifdef CONFIG_REISERFS_CHECK
@@ -495,12 +495,12 @@
X int nr;
X
X blkh = (struct block_head *)buf;
- if (le16_to_cpu (blkh->blk_level) != DISK_LEAF_NODE_LEVEL) {
+ if ( blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
X printk ("is_leaf: this should be caught earlier\n");


X return 0;
X }
X

- nr = le16_to_cpu (blkh->blk_nr_item);
+ nr = blkh_nr_item(blkh);
X if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
X /* item number is too big or too small */
X reiserfs_warning ("is_leaf: nr_item seems wrong: %z\n", bh);
@@ -508,7 +508,7 @@
X }
X ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
X used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location (ih));
- if (used_space != blocksize - le16_to_cpu (blkh->blk_free_space)) {
+ if (used_space != blocksize - blkh_free_space(blkh)) {
X /* free space does not match to calculated amount of use space */
X reiserfs_warning ("is_leaf: free space seems wrong: %z\n", bh);
X return 0;
@@ -549,14 +549,14 @@
X int used_space;
X
X blkh = (struct block_head *)buf;
- if (le16_to_cpu (blkh->blk_level) <= DISK_LEAF_NODE_LEVEL ||
- le16_to_cpu (blkh->blk_level) > MAX_HEIGHT) {
+ nr = blkh_level(blkh);
+ if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) {
X /* this level is not possible for internal nodes */
X printk ("is_internal: this should be caught earlier\n");


X return 0;
X }
X

- nr = le16_to_cpu (blkh->blk_nr_item);
+ nr = blkh_nr_item(blkh);
X if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
X /* for internal which is not root we might check min number of keys */
X reiserfs_warning ("is_internal: number of key seems wrong: %z\n", bh);
@@ -564,7 +564,7 @@
X }
X
X used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
- if (used_space != blocksize - le16_to_cpu (blkh->blk_free_space)) {
+ if (used_space != blocksize - blkh_free_space(blkh)) {
X reiserfs_warning ("is_internal: free space seems wrong: %z\n", bh);
X return 0;
X }
@@ -741,8 +741,10 @@
X "vs-5152: tree level is less than stop level (%d)",
X n_node_level, n_stop_level);
X
- n_retval = bin_search (p_s_key, B_N_PITEM_HEAD(p_s_bh, 0), B_NR_ITEMS(p_s_bh),
- ( n_node_level == DISK_LEAF_NODE_LEVEL ) ? IH_SIZE : KEY_SIZE, &(p_s_last_element->pe_position));
+ n_retval = bin_search( p_s_key, B_N_PITEM_HEAD(p_s_bh, 0),
+ B_NR_ITEMS(p_s_bh),
+ ( n_node_level == DISK_LEAF_NODE_LEVEL ) ? IH_SIZE : KEY_SIZE,
+ &(p_s_last_element->pe_position));
X if (n_node_level == n_stop_level) {
X return n_retval;
X }
@@ -808,16 +810,16 @@
X return retval;
X if ( retval == ITEM_FOUND ) {
X
- RFALSE( ! B_N_PITEM_HEAD
- (PATH_PLAST_BUFFER(p_s_search_path),
- PATH_LAST_POSITION(p_s_search_path))->ih_item_len,
- "PAP-5165: item length equals zero");
+ RFALSE( ! ih_item_len(
+ B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path),
+ PATH_LAST_POSITION(p_s_search_path))),
+ "PAP-5165: item length equals zero");
X
X pos_in_item(p_s_search_path) = 0;
X return POSITION_FOUND;
X }
X
- RFALSE( ! PATH_LAST_POSITION(p_s_search_path),
+ RFALSE( ! PATH_LAST_POSITION(p_s_search_path),
X "PAP-5170: position equals zero");
X
X /* Item is not found. Set path to the previous item. */
@@ -846,9 +848,9 @@
X /* Needed byte is not contained in the item pointed to by the
X path. Set pos_in_item out of the item. */
X if ( is_indirect_le_ih (p_le_ih) )
- pos_in_item (p_s_search_path) = le16_to_cpu (p_le_ih->ih_item_len) / UNFM_P_SIZE;
+ pos_in_item (p_s_search_path) = ih_item_len(p_le_ih) / UNFM_P_SIZE;
X else
- pos_in_item (p_s_search_path) = le16_to_cpu (p_le_ih->ih_item_len);
+ pos_in_item (p_s_search_path) = ih_item_len( p_le_ih );
X
X return POSITION_NOT_FOUND;
X }
@@ -880,9 +882,9 @@
X return 1;
X
X /* Compare other items fields. */
- if ( le16_to_cpu (p_s_path_item->u.ih_entry_count) != p_cpu_ih->u.ih_entry_count ||
- le16_to_cpu (p_s_path_item->ih_item_len) != p_cpu_ih->ih_item_len ||
- le16_to_cpu ( p_s_path_item->ih_item_location) != p_cpu_ih->ih_item_location )
+ if( ih_entry_count(p_s_path_item) != ih_entry_count(p_cpu_ih) ||
+ ih_item_len(p_s_path_item) != ih_item_len(p_cpu_ih) ||
+ ih_location(p_s_path_item) != ih_location(p_cpu_ih) )
X return 1;
X
X /* Items are equal. */
@@ -913,7 +915,7 @@
X
X if ( new_file_length == max_reiserfs_offset (inode) ) {
X /* item has to be deleted */
- *cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
+ *cut_size = -(IH_SIZE + ih_item_len(le_ih));
X return M_DELETE;
X }
X
@@ -923,12 +925,12 @@
X round_len = ROUND_UP (new_file_length);
X /* this was n_new_file_length < le_ih ... */
X if ( round_len < le_ih_k_offset (le_ih) ) {
- *cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
+ *cut_size = -(IH_SIZE + ih_item_len(le_ih));
X return M_DELETE; /* Delete this item. */
X }
X /* Calculate first position and size for cutting from item. */
X pos_in_item (path) = round_len - (le_ih_k_offset (le_ih) - 1);
- *cut_size = -(le16_to_cpu (le_ih->ih_item_len) - pos_in_item(path));
+ *cut_size = -(ih_item_len(le_ih) - pos_in_item(path));
X
X return M_CUT; /* Cut from this item. */
X }
@@ -937,11 +939,11 @@
X // old file: items may have any length
X
X if ( new_file_length < le_ih_k_offset (le_ih) ) {
- *cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
+ *cut_size = -(IH_SIZE + ih_item_len(le_ih));
X return M_DELETE; /* Delete this item. */
X }
X /* Calculate first position and size for cutting from item. */
- *cut_size = -(le16_to_cpu (le_ih->ih_item_len) -
+ *cut_size = -(ih_item_len(le_ih) -
X (pos_in_item (path) = new_file_length + 1 - le_ih_k_offset (le_ih)));
X return M_CUT; /* Cut from this item. */
X }
@@ -956,15 +958,15 @@
X if (le_ih_k_offset (le_ih) == DOT_OFFSET &&
X new_file_length == max_reiserfs_offset (inode)) {
X RFALSE( ih_entry_count (le_ih) != 2,
- "PAP-5220: incorrect empty directory item (%h)", le_ih);
- *cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
+ "PAP-5220: incorrect empty directory item (%h)", le_ih);
+ *cut_size = -(IH_SIZE + ih_item_len(le_ih));
X return M_DELETE; /* Delete the directory item containing "." and ".." entry. */
X }
X
X if ( ih_entry_count (le_ih) == 1 ) {
X /* Delete the directory item such as there is one record only
X in this item*/
- *cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
+ *cut_size = -(IH_SIZE + ih_item_len(le_ih));
X return M_DELETE;
X }
X
@@ -1003,7 +1005,7 @@
X RFALSE( n_new_file_length != max_reiserfs_offset (inode),
X "PAP-5210: mode must be M_DELETE");
X
- *p_n_cut_size = -(IH_SIZE + le16_to_cpu (p_le_ih->ih_item_len));
+ *p_n_cut_size = -(IH_SIZE + ih_item_len(p_le_ih));
X return M_DELETE;
X }
X
@@ -1051,13 +1053,13 @@
X /* Calculate balance mode and position in the item to remove unformatted nodes. */
X if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
X pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + le16_to_cpu (s_ih.ih_item_len));
+ *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
X c_mode = M_DELETE;
X }
X else { /* Case of truncate. */
X if ( n_new_file_length < le_ih_k_offset (&s_ih) ) {
X pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + le16_to_cpu (s_ih.ih_item_len));
+ *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
X c_mode = M_DELETE; /* Delete this item. */
X }
X else {
@@ -1074,7 +1076,7 @@
X return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
X }
X /* Calculate size to cut. */
- *p_n_cut_size = -(s_ih.ih_item_len - pos_in_item (p_s_path) * UNFM_P_SIZE);
+ *p_n_cut_size = -(ih_item_len(&s_ih) - pos_in_item(p_s_path) * UNFM_P_SIZE);
X
X c_mode = M_CUT; /* Cut from this indirect item. */
X }
@@ -1111,29 +1113,29 @@
X p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1,
X "vs-5265: pointer out of range");
X
- if ( ! *p_n_unfm_pointer ) { /* Hole, nothing to remove. */
+ if ( ! get_block_num(p_n_unfm_pointer,0) ) { /* Hole, nothing to remove. */
X if ( ! n_retry )
X (*p_n_removed)++;
X continue;
X }
X /* Search for the buffer in cache. */
- p_s_un_bh = get_hash_table(p_s_sb->s_dev, *p_n_unfm_pointer, n_blk_size);
+ p_s_un_bh = get_hash_table(p_s_sb->s_dev, get_block_num(p_n_unfm_pointer,0), n_blk_size);
X
X if (p_s_un_bh) {
X mark_buffer_clean(p_s_un_bh) ;
X if (buffer_locked(p_s_un_bh)) {
- __wait_on_buffer(p_s_un_bh) ;
+ __wait_on_buffer(p_s_un_bh) ;
X }
X /* even if the item moves, the block number of the
X ** unformatted node we want to cut won't. So, it was
X ** safe to clean the buffer here, this block _will_
X ** get freed during this call to prepare_for_delete_or_cut
X */
- if ( item_moved (&s_ih, p_s_path) ) {
- need_research = 1;
- brelse(p_s_un_bh) ;
- break ;
- }
+ if ( item_moved (&s_ih, p_s_path) ) {
+ need_research = 1;
+ brelse(p_s_un_bh) ;
+ break ;
+ }
X }
X if ( p_s_un_bh && block_in_use (p_s_un_bh)) {
X /* Block is locked or held more than by one holder and by
@@ -1157,15 +1159,15 @@
X if ( ! n_retry )
X (*p_n_removed)++;
X
- RFALSE( p_s_un_bh &&
- (*p_n_unfm_pointer != p_s_un_bh->b_blocknr ),
+ RFALSE( p_s_un_bh &&
+ get_block_num(p_n_unfm_pointer, 0) != p_s_un_bh->b_blocknr,
X // note: minix_truncate allows that. As truncate is
X // protected by down (inode->i_sem), two truncates can not
X // co-exist
- "PAP-5280: blocks numbers are different");
+ "PAP-5280: blocks numbers are different");
X
- tmp = *p_n_unfm_pointer;
- *p_n_unfm_pointer = 0;
+ tmp = get_block_num(p_n_unfm_pointer,0);
+ put_block_num(p_n_unfm_pointer, 0, 0);
X journal_mark_dirty (th, p_s_sb, p_s_bh);
X bforget (p_s_un_bh);
X inode->i_blocks -= p_s_sb->s_blocksize / 512;
@@ -1173,7 +1175,7 @@
X if ( item_moved (&s_ih, p_s_path) ) {
X need_research = 1;
X break ;
- }
+ }
X }
X
X /* a trick. If the buffer has been logged, this
@@ -1237,9 +1239,9 @@
X // we can't use EMPTY_DIR_SIZE, as old format dirs have a different
X // empty size. ick. FIXME, is this right?
X //
- return le16_to_cpu(p_le_ih->ih_item_len) ;
+ return ih_item_len(p_le_ih);
X }
- n_del_size = ( c_mode == M_DELETE ) ? le16_to_cpu (p_le_ih->ih_item_len) : -p_s_tb->insert_size[0];
+ n_del_size = ( c_mode == M_DELETE ) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];
X
X if ( is_indirect_le_ih (p_le_ih) )
X n_del_size = (n_del_size/UNFM_P_SIZE)*
@@ -1416,7 +1418,7 @@
X }
X if (!tb_init) {
X tb_init = 1 ;
- item_len = le16_to_cpu (PATH_PITEM_HEAD (&path)->ih_item_len);
+ item_len = ih_item_len( PATH_PITEM_HEAD(&path) );
X init_tb_struct (th, &tb, th->t_super, &path, - (IH_SIZE + item_len));
X }
X
@@ -1523,14 +1525,14 @@
X /* look for the last byte of the tail */
X if (search_for_position_by_key (inode->i_sb, &tail_key, path) == POSITION_NOT_FOUND)
X reiserfs_panic (inode->i_sb, "vs-5615: indirect_to_direct_roll_back: found invalid item");
- RFALSE( path->pos_in_item != PATH_PITEM_HEAD (path)->ih_item_len - 1,
- "vs-5616: appended bytes found");
+ RFALSE( path->pos_in_item != ih_item_len(PATH_PITEM_HEAD (path)) - 1,
+ "vs-5616: appended bytes found");
X PATH_LAST_POSITION (path) --;
X
X removed = reiserfs_delete_item (th, path, &tail_key, inode, 0/*unbh not needed*/);
X RFALSE( removed <= 0 || removed > tail_len,
- "vs-5617: there was tail %d bytes, removed item length %d bytes",
- tail_len, removed);
+ "vs-5617: there was tail %d bytes, removed item length %d bytes",
+ tail_len, removed);
X tail_len -= removed;
X set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);
X }
@@ -1672,7 +1674,7 @@
X reiserfs_panic (p_s_sb, "vs-5652: reiserfs_cut_from_item: "
X "item must be indirect %h", le_ih);
X
- if (c_mode == M_DELETE && le16_to_cpu (le_ih->ih_item_len) != UNFM_P_SIZE)
+ if (c_mode == M_DELETE && ih_item_len(le_ih) != UNFM_P_SIZE)
X reiserfs_panic (p_s_sb, "vs-5653: reiserfs_cut_from_item: "
X "completing indirect2direct conversion indirect item %h"
X "being deleted must be of 4 byte long", le_ih);
@@ -1825,6 +1827,7 @@
X
X journal_end(th, p_s_inode->i_sb, orig_len_alloc) ;
X journal_begin(th, p_s_inode->i_sb, orig_len_alloc) ;
+ reiserfs_update_inode_transaction(p_s_inode) ;
X }
X } while ( n_file_size > ROUND_UP (n_new_file_size) &&
X search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path) == POSITION_FOUND ) ;
@@ -1923,11 +1926,11 @@
X struct tree_balance s_ins_balance;
X int retval;
X
- init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, IH_SIZE + p_s_ih->ih_item_len);
+ init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, IH_SIZE + ih_item_len(p_s_ih));
X
X /*
X if (p_c_body == 0)
- n_zeros_num = p_s_ih->ih_item_len;
+ n_zeros_num = ih_item_len(p_s_ih);
X */
X // le_key2cpu_key (&key, &(p_s_ih->ih_key));
X
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- v2.4.12/linux/fs/reiserfs/super.c Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/super.c Sun Oct 21 10:14:38 2001
@@ -79,9 +79,6 @@
X // at the ext2 code and comparing. It's subfunctions contain no code
X // used as a template unless they are so labeled.
X //
-/* there should be no suspected recipients already. True and cautious
- bitmaps should not differ. We only have to free preserve list and
- write both bitmaps */
X void reiserfs_put_super (struct super_block * s)
X {
X int i;
@@ -91,7 +88,7 @@
X if (!(s->s_flags & MS_RDONLY)) {
X journal_begin(&th, s, 10) ;
X reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
- s->u.reiserfs_sb.s_rs->s_state = le16_to_cpu (s->u.reiserfs_sb.s_mount_state);
+ set_sb_state( SB_DISK_SUPER_BLOCK(s), s->u.reiserfs_sb.s_mount_state );
X journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
X }
X
@@ -250,26 +247,26 @@
X
X if (*flags & MS_RDONLY) {
X /* try to remount file system with read-only permissions */
- if (le16_to_cpu (rs->s_state) == REISERFS_VALID_FS || s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) {
+ if (sb_state(rs) == REISERFS_VALID_FS || s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) {


X return 0;
X }
X

X journal_begin(&th, s, 10) ;
X /* Mounting a rw partition read-only. */
X reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
- rs->s_state = cpu_to_le16 (s->u.reiserfs_sb.s_mount_state);
+ set_sb_state( rs, s->u.reiserfs_sb.s_mount_state );
X journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
X s->s_dirt = 0;
X } else {
- s->u.reiserfs_sb.s_mount_state = le16_to_cpu(rs->s_state) ;
+ s->u.reiserfs_sb.s_mount_state = sb_state(rs) ;
X s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
X journal_begin(&th, s, 10) ;
X
X /* Mount a partition which is read-only, read-write */
X reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
- s->u.reiserfs_sb.s_mount_state = le16_to_cpu (rs->s_state);
+ s->u.reiserfs_sb.s_mount_state = sb_state(rs);
X s->s_flags &= ~MS_RDONLY;
- rs->s_state = cpu_to_le16 (REISERFS_ERROR_FS);
+ set_sb_state( rs, REISERFS_ERROR_FS );
X /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
X journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
X s->s_dirt = 0;
@@ -287,10 +284,10 @@
X int i, bmp, dl ;
X struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s);
X
- SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr), GFP_NOFS, s);
+ SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s);
X if (SB_AP_BITMAP (s) == 0)
X return 1;
- memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr));
+ memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs));
X
X /* reiserfs leaves the first 64k unused so that any partition
X labeling scheme currently used will have enough space. Then we
@@ -299,7 +296,7 @@
X SB_AP_BITMAP (s)[0] = reiserfs_bread (s->s_dev, bmp, s->s_blocksize);
X if(!SB_AP_BITMAP(s)[0])
X return 1;
- for (i = 1, bmp = dl = rs->s_blocksize * 8; i < le16_to_cpu (rs->s_bmap_nr); i ++) {
+ for (i = 1, bmp = dl = s->s_blocksize * 8; i < sb_bmap_nr(rs); i ++) {
X SB_AP_BITMAP (s)[i] = reiserfs_bread (s->s_dev, bmp, s->s_blocksize);
X if (!SB_AP_BITMAP (s)[i])
X return 1;
@@ -316,13 +313,13 @@
X int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */
X
X /* read true bitmap */
- SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr), GFP_NOFS, s);
+ SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s);
X if (SB_AP_BITMAP (s) == 0)
X return 1;
X
- memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * le16_to_cpu (rs->s_bmap_nr));
+ memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs));
X
- for (i = 0; i < le16_to_cpu (rs->s_bmap_nr); i ++) {
+ for (i = 0; i < sb_bmap_nr(rs); i ++) {
X SB_AP_BITMAP (s)[i] = reiserfs_bread (s->s_dev, bmp1 + i, s->s_blocksize);
X if (!SB_AP_BITMAP (s)[i])
X return 1;
@@ -349,35 +346,33 @@
X free, SB_FREE_BLOCKS (s));
X }
X
-
-
X static int read_super_block (struct super_block * s, int size, int offset)
X {
X struct buffer_head * bh;
X struct reiserfs_super_block * rs;
-
+
X
X bh = bread (s->s_dev, offset / size, size);
X if (!bh) {
- printk ("read_super_block: "
- "bread failed (dev %s, block %d, size %d)\n",
- kdevname (s->s_dev), offset / size, size);
- return 1;
+ printk ("read_super_block: "
+ "bread failed (dev %s, block %d, size %d)\n",
+ kdevname (s->s_dev), offset / size, size);
+ return 1;
X }
-
+
X rs = (struct reiserfs_super_block *)bh->b_data;
X if (!is_reiserfs_magic_string (rs)) {
- printk ("read_super_block: "
- "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
- kdevname(s->s_dev), bh->b_blocknr, size);
- brelse (bh);
- return 1;
+ printk ("read_super_block: "
+ "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
+ kdevname(s->s_dev), bh->b_blocknr, size);


+ brelse (bh);
+ return 1;
X }

-
+
X //
X // ok, reiserfs signature (old or new) found in at the given offset
- //
- s->s_blocksize = le16_to_cpu (rs->s_blocksize);
+ //
+ s->s_blocksize = sb_blocksize(rs);
X s->s_blocksize_bits = 0;
X while ((1 << s->s_blocksize_bits) != s->s_blocksize)
X s->s_blocksize_bits ++;
@@ -387,21 +382,22 @@
X if (s->s_blocksize != size)
X set_blocksize (s->s_dev, s->s_blocksize);
X
- bh = bread (s->s_dev, offset / s->s_blocksize, s->s_blocksize);
+ bh = reiserfs_bread (s->s_dev, offset / s->s_blocksize, s->s_blocksize);
X if (!bh) {
- printk ("read_super_block: "
- "bread failed (dev %s, block %d, size %d)\n",
- kdevname (s->s_dev), offset / size, size);
+ printk("read_super_block: "
+ "bread failed (dev %s, block %d, size %d)\n",
+ kdevname (s->s_dev), offset / size, size);


X return 1;
X }
X

X rs = (struct reiserfs_super_block *)bh->b_data;
X if (!is_reiserfs_magic_string (rs) ||
- le16_to_cpu (rs->s_blocksize) != s->s_blocksize) {
+ sb_blocksize(rs) != s->s_blocksize) {
X printk ("read_super_block: "
X "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
X kdevname(s->s_dev), bh->b_blocknr, size);
X brelse (bh);
+ printk ("read_super_block: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev));
X return 1;
X }
X /* must check to be sure we haven't pulled an old format super out
@@ -409,8 +405,8 @@
X ** will work. If block we've just read in is inside the
X ** journal for that super, it can't be valid.
X */
- if (bh->b_blocknr >= le32_to_cpu(rs->s_journal_block) &&
- bh->b_blocknr < (le32_to_cpu(rs->s_journal_block) + JOURNAL_BLOCK_COUNT)) {
+ if (bh->b_blocknr >= sb_journal_block(rs) &&
+ bh->b_blocknr < (sb_journal_block(rs) + JOURNAL_BLOCK_COUNT)) {
X brelse(bh) ;
X printk("super-459: read_super_block: "
X "super found at block %lu is within its own log. "
@@ -483,7 +479,7 @@
X if (retval == NAME_NOT_FOUND)
X de.de_entry_num --;
X set_de_name_and_namelen (&de);
- if (le32_to_cpu (de.de_deh[de.de_entry_num].deh_offset) == DOT_DOT_OFFSET) {
+ if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {
X /* allow override in this case */
X if (reiserfs_rupasov_hash(s)) {
X hash = YURA_HASH ;
@@ -499,7 +495,7 @@
X hash = UNSET_HASH ;
X break;
X }
- if (GET_HASH_VALUE(le32_to_cpu(de.de_deh[de.de_entry_num].deh_offset))==
+ if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) ==
X GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen)))
X hash = YURA_HASH;
X else
@@ -516,7 +512,7 @@
X {
X __u32 code;
X
- code = le32_to_cpu (s->u.reiserfs_sb.s_rs->s_hash_function_code);
+ code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));
X
X /* reiserfs_hash_detect() == true if any of the hash mount options
X ** were used. We must check them to make sure the user isn't
@@ -558,8 +554,8 @@
X */
X if (code != UNSET_HASH &&
X !(s->s_flags & MS_RDONLY) &&
- code != le32_to_cpu (s->u.reiserfs_sb.s_rs->s_hash_function_code)) {
- s->u.reiserfs_sb.s_rs->s_hash_function_code = cpu_to_le32(code) ;
+ code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
+ set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
X }
X return code;
X }
@@ -646,7 +642,7 @@
X old_format = 1;
X }
X
- s->u.reiserfs_sb.s_mount_state = le16_to_cpu (SB_DISK_SUPER_BLOCK (s)->s_state); /* journal victim */
+ s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s);
X s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;
X
X if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
@@ -702,10 +698,10 @@
X
X if (!(s->s_flags & MS_RDONLY)) {
X struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
- int old_magic;
+ int old_magic;
X
- old_magic = strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING,
- strlen ( REISER2FS_SUPER_MAGIC_STRING));
+ old_magic = strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING,
+ strlen ( REISER2FS_SUPER_MAGIC_STRING));
X if( old_magic && le16_to_cpu(rs->s_version) != 0 ) {
X dput(s->s_root) ;
X s->s_root = NULL ;
@@ -716,7 +712,7 @@
X journal_begin(&th, s, 1) ;


X reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
X

- rs->s_state = cpu_to_le16 (REISERFS_ERROR_FS);
+ set_sb_state( rs, REISERFS_ERROR_FS );
X
X if ( old_magic ) {
X // filesystem created under 3.5.x found
@@ -736,7 +732,7 @@
X }
X
X // mark hash in super block: it could be unset. overwrite should be ok
- rs->s_hash_function_code = cpu_to_le32 (function2code (s->u.reiserfs_sb.s_hash_function));
+ set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) );
X
X journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
X journal_end(&th, s, 1) ;
@@ -785,13 +781,13 @@
X struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
X
X /* changed to accomodate gcc folks.*/
- buf->f_type = REISERFS_SUPER_MAGIC;
- buf->f_bsize = le32_to_cpu (s->s_blocksize);
- buf->f_blocks = le32_to_cpu (rs->s_block_count) - le16_to_cpu (rs->s_bmap_nr) - 1;
- buf->f_bfree = le32_to_cpu (rs->s_free_blocks);
- buf->f_bavail = buf->f_bfree;
- buf->f_files = -1;
- buf->f_ffree = -1;
+ buf->f_type = REISERFS_SUPER_MAGIC;
+ buf->f_bsize = s->s_blocksize;
+ buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
+ buf->f_bfree = sb_free_blocks(rs);
+ buf->f_bavail = buf->f_bfree;
+ buf->f_files = -1;
+ buf->f_ffree = -1;
X buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize));
X return 0;
X }
@@ -806,6 +802,9 @@
X return register_filesystem(&reiserfs_fs_type);
X }
X
+MODULE_DESCRIPTION("ReiserFS journaled filesystem");
+MODULE_AUTHOR("Hans Reiser <rei...@namesys.com>");
+MODULE_LICENSE("GPL");
X EXPORT_NO_SYMBOLS;
X
X //
diff -u --recursive --new-file v2.4.12/linux/fs/reiserfs/tail_conversion.c linux/fs/reiserfs/tail_conversion.c
--- v2.4.12/linux/fs/reiserfs/tail_conversion.c Tue Oct 9 17:06:53 2001
+++ linux/fs/reiserfs/tail_conversion.c Fri Oct 12 14:19:28 2001
@@ -61,7 +61,7 @@
X if ( is_statdata_le_ih (p_le_ih) ) {
X /* Insert new indirect item. */
X set_ih_free_space (&ind_ih, 0); /* delete at nearest future */
- ind_ih.ih_item_len = cpu_to_le16 (UNFM_P_SIZE);
+ put_ih_item_len( &ind_ih, UNFM_P_SIZE );
X PATH_LAST_POSITION (path)++;
X n_retval = reiserfs_insert_item (th, path, &end_key, &ind_ih,
X (char *)&unfm_ptr);
@@ -93,10 +93,10 @@
X "direct item (%k) not found", &end_key);
X p_le_ih = PATH_PITEM_HEAD (path);
X RFALSE( !is_direct_le_ih (p_le_ih),
- "vs-14055: direct item expected(%k), found %h",
- &end_key, p_le_ih);
- tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
- + ih_item_len(p_le_ih) - 1;
+ "vs-14055: direct item expected(%k), found %h",
+ &end_key, p_le_ih);
+ tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
+ + ih_item_len(p_le_ih) - 1;
X
X /* we only send the unbh pointer if the buffer is not up to date.
X ** this avoids overwriting good data from writepage() with old data
@@ -214,7 +214,7 @@
X else
X round_tail_len = tail_len;
X
- pos = le_ih_k_offset (&s_ih) - 1 + (le16_to_cpu (s_ih.ih_item_len) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
+ pos = le_ih_k_offset (&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
X pos1 = pos;
X
X // we are protected by i_sem. The tail can not disapper, not
@@ -231,7 +231,7 @@
X copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
X #ifdef CONFIG_REISERFS_CHECK
X pos = le_ih_k_offset (&s_ih) - 1 +
- (le16_to_cpu (s_ih.ih_item_len) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
+ (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
X if (pos != pos1)
X reiserfs_panic (p_s_sb, "vs-5530: indirect2direct: "
X "tail position changed while we were reading it");
diff -u --recursive --new-file v2.4.12/linux/fs/super.c linux/fs/super.c
--- v2.4.12/linux/fs/super.c Thu Oct 11 08:02:26 2001
+++ linux/fs/super.c Sat Oct 20 19:14:42 2001
@@ -681,6 +681,7 @@
X } else {
X kdev_t dev = get_unnamed_dev();
X if (!dev) {
+ spin_unlock(&sb_lock);
X put_super(s);
X return ERR_PTR(-EMFILE);
X }
@@ -865,13 +866,21 @@
X return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
X }
X
+static char * __initdata root_mount_data;
+static int __init root_data_setup(char *str)
+{
+ root_mount_data = str;


+ return 1;
+}
+

X static char * __initdata root_fs_names;
X static int __init fs_names_setup(char *str)
X {
X root_fs_names = str;
- return 0;


+ return 1;
X }
X

+__setup("rootflags=", root_data_setup);
X __setup("rootfstype=", fs_names_setup);
X
X static void __init get_fs_names(char *page)
@@ -1022,7 +1031,8 @@
X struct file_system_type * fs_type = get_fs_type(p);
X if (!fs_type)
X continue;
- sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL);
+ sb = read_super(ROOT_DEV, bdev, fs_type,
+ root_mountflags, root_mount_data);
X if (sb)
X goto mount_it;
X put_filesystem(fs_type);
diff -u --recursive --new-file v2.4.12/linux/fs/udf/balloc.c linux/fs/udf/balloc.c
--- v2.4.12/linux/fs/udf/balloc.c Tue Oct 9 17:06:53 2001
+++ linux/fs/udf/balloc.c Thu Oct 11 08:59:24 2001
@@ -44,12 +44,15 @@
X #define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
X #define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
X #define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
+#define UintBPL Uint(BITS_PER_LONG)
+#define Uint(x) xUint(x)
+#define xUint(x) Uint ## x
X
X extern inline int find_next_one_bit (void * addr, int size, int offset)
X {
- unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
+ UintBPL * p = ((UintBPL *) addr) + (offset / BITS_PER_LONG);
+ UintBPL result = offset & ~(BITS_PER_LONG-1);
+ UintBPL tmp;
X
X if (offset >= size)
X return size;
@@ -126,7 +129,7 @@
X }
X }
X
-static inline int load_block_bitmap(struct super_block *sb,
+static inline int load_block_bitmap(struct super_block * sb,
X struct udf_bitmap *bitmap, unsigned int block_group)
X {
X int slot;
@@ -142,7 +145,8 @@
X return slot;
X }
X
-static void udf_bitmap_free_blocks(struct inode * inode,
+static void udf_bitmap_free_blocks(struct super_block * sb,


+ struct inode * inode,

X struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
X {
X struct buffer_head * bh = NULL;
@@ -152,14 +156,6 @@
X unsigned long i;
X int bitmap_nr;
X unsigned long overflow;
- struct super_block * sb;


-
- sb = inode->i_sb;

- if (!sb)
- {
- udf_debug("nonexistent device");
- return;
- }
X
X lock_super(sb);
X if (bloc.logicalBlockNum < 0 ||
@@ -200,7 +196,8 @@
X }
X else
X {
- DQUOT_FREE_BLOCK(inode, 1);
+ if (inode)
+ DQUOT_FREE_BLOCK(inode, 1);
X if (UDF_SB_LVIDBH(sb))
X {
X UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -223,7 +220,8 @@
X return;
X }
X
-static int udf_bitmap_prealloc_blocks(struct inode * inode,
+static int udf_bitmap_prealloc_blocks(struct super_block * sb,


+ struct inode * inode,

X struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
X Uint32 block_count)
X {
@@ -231,14 +229,7 @@
X int bit, block, block_group, group_start;
X int nr_groups, bitmap_nr;
X struct buffer_head *bh;


- struct super_block *sb;
X

- sb = inode->i_sb;
- if (!sb)
- {
- udf_debug("nonexistent device\n");

- return 0;
- }
X lock_super(sb);
X
X if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -293,23 +284,17 @@


X return alloc_count;
X }
X

-static int udf_bitmap_new_block(struct inode * inode,
+static int udf_bitmap_new_block(struct super_block * sb,


+ struct inode * inode,

X struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
X {
X int newbit, bit=0, block, block_group, group_start;
X int end_goal, nr_groups, bitmap_nr, i;


X struct buffer_head *bh = NULL;

- struct super_block *sb;
X char *ptr;
X int newblock = 0;


X
X *err = -ENOSPC;
- sb = inode->i_sb;
- if (!sb)
- {
- udf_debug("nonexistent device\n");
- return newblock;
- }

X lock_super(sb);
X
X repeat:
@@ -404,7 +389,7 @@
X /*
X * Check quota for allocation of this block.
X */
- if (DQUOT_ALLOC_BLOCK(inode, 1))


+ if (inode && DQUOT_ALLOC_BLOCK(inode, 1))

X {
X unlock_super(sb);
X *err = -EDQUOT;
@@ -439,30 +424,17 @@


X return 0;
X }
X

-static void udf_table_free_blocks(struct inode * inode,
+static void udf_table_free_blocks(struct super_block * sb,


+ struct inode * inode,

X struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
X {
- struct super_block * sb;
X Uint32 start, end;
X Uint32 nextoffset, oextoffset, elen;
X lb_addr nbloc, obloc, eloc;
X struct buffer_head *obh, *nbh;


- char etype;
+ Sint8 etype;

X int i;
X
- udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
- inode->i_ino, bloc.logicalBlockNum, offset, count);


-
- sb = inode->i_sb;

- if (!sb)
- {
- udf_debug("nonexistent device");
- return;


- }
-
- if (table == NULL)

- return;
-
X lock_super(sb);
X if (bloc.logicalBlockNum < 0 ||
X (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
@@ -475,7 +447,8 @@
X
X /* We do this up front - There are some error conditions that could occure,
X but.. oh well */
- DQUOT_FREE_BLOCK(inode, count);
+ if (inode)
+ DQUOT_FREE_BLOCK(inode, count);
X if (UDF_SB_LVIDBH(sb))
X {
X UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -690,33 +663,20 @@
X return;
X }
X
-static int udf_table_prealloc_blocks(struct inode * inode,
+static int udf_table_prealloc_blocks(struct super_block * sb,


+ struct inode * inode,

X struct inode *table, Uint16 partition, Uint32 first_block,
X Uint32 block_count)


X {
- struct super_block *sb;

X int alloc_count = 0;
X Uint32 extoffset, elen, adsize;
X lb_addr bloc, eloc;
X struct buffer_head *bh;
- char etype = -1;
-
- udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
- inode->i_ino, partition, first_block, block_count);


-
- sb = inode->i_sb;

- if (!sb)
- {
- udf_debug("nonexistent device\n");

- return 0;
- }
+ Sint8 etype = -1;
X
X if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
X return 0;
X

- if (table == NULL)

- return 0;
-


X if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
X adsize = sizeof(short_ad);

X else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
@@ -745,7 +705,9 @@
X extoffset -= adsize;
X
X alloc_count = (elen >> sb->s_blocksize_bits);
- if (alloc_count > block_count)
+ if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
+ alloc_count = 0;


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 45'
echo 'File patch-2.4.13 is continued in part 46'
echo "46" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:17 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part47

#!/bin/sh -x
# this is part 47 of a 53 - part archive


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

if test "$Scheck" != 47; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

-#endif


X UFSD(("EXIT\n"))
X }

X
diff -u --recursive --new-file v2.4.12/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.4.12/linux/fs/ufs/namei.c Tue Sep 5 14:07:30 2000
+++ linux/fs/ufs/namei.c Sat Oct 20 19:14:42 2001
@@ -24,20 +24,9 @@
X * David S. Miller (da...@caip.rutgers.edu), 1995
X */
X
-#include <asm/uaccess.h>
-
-#include <linux/errno.h>
+#include <linux/sched.h>


X #include <linux/fs.h>
X #include <linux/ufs_fs.h>

-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/locks.h>
-#include <linux/quotaops.h>
-
-#include "swab.h"
-#include "util.h"
X
X #undef UFS_NAMEI_DEBUG
X
@@ -47,345 +36,49 @@


X #define UFSD(x)
X #endif
X

-/*
- * define how far ahead to read directories while searching them.
- */
-#define NAMEI_RA_CHUNKS 2
-#define NAMEI_RA_BLOCKS 4
-#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
-
-/*
- * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
- *
- * len <= UFS_MAXNAMLEN and de != NULL are guaranteed by caller.
- */
-static inline int ufs_match (int len, const char * const name,
- struct ufs_dir_entry * de, unsigned flags, unsigned swab)
+static inline void ufs_inc_count(struct inode *inode)
X {
- if (len != ufs_get_de_namlen(de))
- return 0;
- if (!de->d_ino)
- return 0;
- return !memcmp(name, de->d_name, len);
+ inode->i_nlink++;
+ mark_inode_dirty(inode);
X }
X
-/*
- * ufs_find_entry()
- *
- * finds an entry in the specified directory with the wanted name. It
- * returns the cache buffer in which the entry was found, and the entry
- * itself (as a parameter - res_dir). It does NOT read the inode of the
- * entry - you'll have to do that yourself if you want to.
- */
-static struct buffer_head * ufs_find_entry (struct inode * dir,
- const char * const name, int namelen, struct ufs_dir_entry ** res_dir)
+static inline void ufs_dec_count(struct inode *inode)


X {
- struct super_block * sb;

- struct buffer_head * bh_use[NAMEI_RA_SIZE];
- struct buffer_head * bh_read[NAMEI_RA_SIZE];
- unsigned long offset;
- int block, toread, i, err;
- unsigned flags, swab;
-
- UFSD(("ENTER, dir_ino %lu, name %s, namlen %u\n", dir->i_ino, name, namelen))
-
- *res_dir = NULL;
-
- sb = dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;
-

- if (namelen > UFS_MAXNAMLEN)
- return NULL;
-
- memset (bh_use, 0, sizeof (bh_use));
- toread = 0;
- for (block = 0; block < NAMEI_RA_SIZE; ++block) {
- struct buffer_head * bh;
-
- if ((block << sb->s_blocksize_bits) >= dir->i_size)
- break;
- bh = ufs_getfrag (dir, block, 0, &err);
- bh_use[block] = bh;
- if (bh && !buffer_uptodate(bh))
- bh_read[toread++] = bh;
- }
-
- for (block = 0, offset = 0; offset < dir->i_size; block++) {
- struct buffer_head * bh;
- struct ufs_dir_entry * de;
- char * dlimit;
-
- if ((block % NAMEI_RA_BLOCKS) == 0 && toread) {
- ll_rw_block (READ, toread, bh_read);
- toread = 0;
- }
- bh = bh_use[block % NAMEI_RA_SIZE];
- if (!bh) {
- ufs_error (sb, "ufs_find_entry",
- "directory #%lu contains a hole at offset %lu",
- dir->i_ino, offset);
- offset += sb->s_blocksize;
- continue;
- }
- wait_on_buffer (bh);
- if (!buffer_uptodate(bh)) {
- /*
- * read error: all bets are off
- */
- break;
- }
-
- de = (struct ufs_dir_entry *) bh->b_data;
- dlimit = bh->b_data + sb->s_blocksize;
- while ((char *) de < dlimit && offset < dir->i_size) {
- /* this code is executed quadratically often */
- /* do minimal checking by hand */
- int de_len;
-
- if ((char *) de + namelen <= dlimit &&
- ufs_match (namelen, name, de, flags, swab)) {
- /* found a match -
- just to be sure, do a full check */
- if (!ufs_check_dir_entry("ufs_find_entry",
- dir, de, bh, offset))
- goto failed;
- for (i = 0; i < NAMEI_RA_SIZE; ++i) {
- if (bh_use[i] != bh)
- brelse (bh_use[i]);
- }
- *res_dir = de;
- return bh;
- }
- /* prevent looping on a bad block */
- de_len = SWAB16(de->d_reclen);
- if (de_len <= 0)
- goto failed;
- offset += de_len;
- de = (struct ufs_dir_entry *) ((char *) de + de_len);
- }
+ inode->i_nlink--;
+ mark_inode_dirty(inode);
+}
X
- brelse (bh);
- if (((block + NAMEI_RA_SIZE) << sb->s_blocksize_bits ) >=
- dir->i_size)
- bh = NULL;
- else
- bh = ufs_getfrag (dir, block + NAMEI_RA_SIZE, 0, &err);
- bh_use[block % NAMEI_RA_SIZE] = bh;
- if (bh && !buffer_uptodate(bh))
- bh_read[toread++] = bh;
+static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+ int err = ufs_add_link(dentry, inode);
+ if (!err) {
+ d_instantiate(dentry, inode);


+ return 0;
X }
-

-failed:
- for (i = 0; i < NAMEI_RA_SIZE; ++i) brelse (bh_use[i]);
- UFSD(("EXIT\n"))
- return NULL;
+ ufs_dec_count(inode);
+ iput(inode);


+ return err;
X }
X

X static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)


X {
- struct super_block * sb;

- struct inode * inode;

- struct ufs_dir_entry * de;
- struct buffer_head * bh;
- unsigned swab;
-
- UFSD(("ENTER\n"))
-
- sb = dir->i_sb;


- swab = sb->u.ufs_sb.s_swab;

+ struct inode * inode = NULL;
+ ino_t ino;
X
X if (dentry->d_name.len > UFS_MAXNAMLEN)
X return ERR_PTR(-ENAMETOOLONG);
X
- bh = ufs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
- inode = NULL;
- if (bh) {
- unsigned long ino = SWAB32(de->d_ino);
- brelse (bh);
- inode = iget(sb, ino);
+ ino = ufs_inode_by_name(dir, dentry);
+ if (ino) {
+ inode = iget(dir->i_sb, ino);
X if (!inode)
X return ERR_PTR(-EACCES);
X }
X d_add(dentry, inode);
- UFSD(("EXIT\n"))
- return NULL;
-}
-
-/*
- * ufs_add_entry()
- *
- * adds a file entry to the specified directory, using the same
- * semantics as ufs_find_entry(). It returns NULL if it failed.
- *
- * NOTE!! The inode part of 'de' is left at 0 - which means you
- * may not sleep between calling this and putting something into
- * the entry, as someone else might have used it while you slept.
- */
-static struct buffer_head * ufs_add_entry (struct inode * dir,
- const char * name, int namelen, struct ufs_dir_entry ** res_dir,
- int *err )
-{


- struct super_block * sb;

- struct ufs_sb_private_info * uspi;
- unsigned long offset;
- unsigned fragoff;
- unsigned short rec_len;
- struct buffer_head * bh;
- struct ufs_dir_entry * de, * de1;
- unsigned flags, swab;
-
- UFSD(("ENTER, name %s, namelen %u\n", name, namelen))
-
- *err = -EINVAL;
- *res_dir = NULL;
-
- sb = dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;
- uspi = sb->u.ufs_sb.s_uspi;
-

- if (!namelen)
- return NULL;
- bh = ufs_bread (dir, 0, 0, err);
- if (!bh)
- return NULL;
- rec_len = UFS_DIR_REC_LEN(namelen);
- offset = 0;
- de = (struct ufs_dir_entry *) bh->b_data;
- *err = -ENOSPC;
- while (1) {
- if ((char *)de >= UFS_SECTOR_SIZE + bh->b_data) {
- fragoff = offset & ~uspi->s_fmask;
- if (fragoff != 0 && fragoff != UFS_SECTOR_SIZE)
- ufs_error (sb, "ufs_add_entry", "internal error"
- " fragoff %u", fragoff);
- if (!fragoff) {
- brelse (bh);
- bh = NULL;
- bh = ufs_bread (dir, offset >> sb->s_blocksize_bits, 1, err);
- }
- if (!bh)
- return NULL;
- if (dir->i_size <= offset) {
- if (dir->i_size == 0) {
- *err = -ENOENT;
- return NULL;
- }
- de = (struct ufs_dir_entry *) (bh->b_data + fragoff);
- de->d_ino = SWAB32(0);
- de->d_reclen = SWAB16(UFS_SECTOR_SIZE);
- ufs_set_de_namlen(de,0);
- dir->i_size = offset + UFS_SECTOR_SIZE;
- mark_inode_dirty(dir);
- } else {
- de = (struct ufs_dir_entry *) bh->b_data;
- }
- }
- if (!ufs_check_dir_entry ("ufs_add_entry", dir, de, bh, offset)) {
- *err = -ENOENT;
- brelse (bh);
- return NULL;
- }
- if (ufs_match (namelen, name, de, flags, swab)) {
- *err = -EEXIST;
- brelse (bh);
- return NULL;
- }
- if ((SWAB32(de->d_ino) == 0 && SWAB16(de->d_reclen) >= rec_len) ||
- (SWAB16(de->d_reclen) >= UFS_DIR_REC_LEN(ufs_get_de_namlen(de)) + rec_len)) {
- offset += SWAB16(de->d_reclen);
- if (SWAB32(de->d_ino)) {
- de1 = (struct ufs_dir_entry *) ((char *) de +
- UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
- de1->d_reclen = SWAB16(SWAB16(de->d_reclen) -
- UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
- de->d_reclen = SWAB16(UFS_DIR_REC_LEN(ufs_get_de_namlen(de)));
- de = de1;
- }
- de->d_ino = SWAB32(0);
- ufs_set_de_namlen(de, namelen);
- memcpy (de->d_name, name, namelen + 1);
- /*
- * XXX shouldn't update any times until successful
- * completion of syscall, but too many callers depend
- * on this.
- *
- * XXX similarly, too many callers depend on
- * ufs_new_inode() setting the times, but error
- * recovery deletes the inode, so the worst that can
- * happen is that the times are slightly out of date
- * and/or different from the directory change time.
- */
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- mark_inode_dirty(dir);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- *res_dir = de;
- *err = 0;
-
- UFSD(("EXIT\n"))
- return bh;
- }
- offset += SWAB16(de->d_reclen);
- de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
- }
- brelse (bh);
- UFSD(("EXIT (FAILED)\n"))
X return NULL;
X }
X
X /*
- * ufs_delete_entry deletes a directory entry by merging it with the
- * previous entry.
- */
-static int ufs_delete_entry (struct inode * inode, struct ufs_dir_entry * dir,
- struct buffer_head * bh )
-
-{


- struct super_block * sb;

- struct ufs_dir_entry * de, * pde;
- unsigned i;
- unsigned flags, swab;
-
- UFSD(("ENTER\n"))


-
- sb = inode->i_sb;

- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;

- i = 0;
- pde = NULL;
- de = (struct ufs_dir_entry *) bh->b_data;
-
- UFSD(("ino %u, reclen %u, namlen %u, name %s\n", SWAB32(de->d_ino),
- SWAB16(de->d_reclen), ufs_get_de_namlen(de), de->d_name))
-
- while (i < bh->b_size) {
- if (!ufs_check_dir_entry ("ufs_delete_entry", inode, de, bh, i))
- return -EIO;
- if (de == dir) {
- if (pde)
- pde->d_reclen =
- SWAB16(SWAB16(pde->d_reclen) +
- SWAB16(dir->d_reclen));
- dir->d_ino = SWAB32(0);
- UFSD(("EXIT\n"))
- return 0;
- }
- i += SWAB16(de->d_reclen);
- if (i == UFS_SECTOR_SIZE) pde = NULL;
- else pde = de;
- de = (struct ufs_dir_entry *)
- ((char *) de + SWAB16(de->d_reclen));
- if (i == UFS_SECTOR_SIZE && SWAB16(de->d_reclen) == 0)
- break;
- }
- UFSD(("EXIT\n"))
- return -ENOENT;
-}
-
-/*
X * By the time this is called, we already have created
X * the directory cache entry for the new file, but it
X * is so far negative - it has no inode.
@@ -395,375 +88,45 @@
X */
X static int ufs_create (struct inode * dir, struct dentry * dentry, int mode)


X {
- struct super_block * sb;

- struct inode * inode;

- struct buffer_head * bh;
- struct ufs_dir_entry * de;
- int err = -EIO;
- unsigned flags, swab;
-
- sb = dir->i_sb;


- swab = sb->u.ufs_sb.s_swab;

- flags = sb->u.ufs_sb.s_flags;
- /*
- * N.B. Several error exits in ufs_new_inode don't set err.
- */
- UFSD(("ENTER\n"))
-
- inode = ufs_new_inode (dir, mode, &err);
- if (!inode)
- return err;
- inode->i_op = &ufs_file_inode_operations;
- inode->i_fop = &ufs_file_operations;
- inode->i_mapping->a_ops = &ufs_aops;
- inode->i_mode = mode;
- mark_inode_dirty(inode);
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh) {
- inode->i_nlink--;
+ struct inode * inode = ufs_new_inode(dir, mode);
+ int err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ inode->i_op = &ufs_file_inode_operations;
+ inode->i_fop = &ufs_file_operations;
+ inode->i_mapping->a_ops = &ufs_aops;
X mark_inode_dirty(inode);
- iput (inode);
- return err;
- }
- de->d_ino = SWAB32(inode->i_ino);
- ufs_set_de_type (de, inode->i_mode);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- brelse (bh);
- d_instantiate(dentry, inode);
-
- UFSD(("EXIT\n"))


-
- return 0;
-}
-

-static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
-{


- struct super_block * sb;

- struct inode * inode;

- struct buffer_head * bh;
- struct ufs_dir_entry * de;
- int err = -EIO;
- unsigned flags, swab;
-
- sb = dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;
-

- inode = ufs_new_inode (dir, mode, &err);
- if (!inode)
- goto out;
-
- inode->i_uid = current->fsuid;
- init_special_inode(inode, mode, rdev);
- mark_inode_dirty(inode);
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh)
- goto out_no_entry;
- de->d_ino = SWAB32(inode->i_ino);
- ufs_set_de_type (de, inode->i_mode);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
+ err = ufs_add_nondir(dentry, inode);
X }
- d_instantiate(dentry, inode);
- brelse(bh);
- err = 0;
-out:
X return err;
-
-out_no_entry:
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- goto out;
X }
X
-static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)


X {
- struct super_block * sb;

- struct inode * inode;

- struct buffer_head * bh, * dir_block;
- struct ufs_dir_entry * de;
- int err;
- unsigned flags, swab;
-
- sb = dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;
-

- err = -EMLINK;
- if (dir->i_nlink >= UFS_LINK_MAX)
- goto out;
- err = -EIO;
- inode = ufs_new_inode (dir, S_IFDIR, &err);
- if (!inode)
- goto out;
-
- inode->i_op = &ufs_dir_inode_operations;
- inode->i_fop = &ufs_dir_operations;
- inode->i_size = UFS_SECTOR_SIZE;
- dir_block = ufs_bread (inode, 0, 1, &err);
- if (!dir_block) {
- inode->i_nlink--; /* is this nlink == 0? */
+ struct inode * inode = ufs_new_inode(dir, mode);
+ int err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, mode, rdev);
X mark_inode_dirty(inode);
- iput (inode);
- return err;
- }
- inode->i_blocks = sb->s_blocksize / UFS_SECTOR_SIZE;
- de = (struct ufs_dir_entry *) dir_block->b_data;
- de->d_ino = SWAB32(inode->i_ino);
- ufs_set_de_type (de, inode->i_mode);
- ufs_set_de_namlen(de,1);
- de->d_reclen = SWAB16(UFS_DIR_REC_LEN(1));
- strcpy (de->d_name, ".");
- de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
- de->d_ino = SWAB32(dir->i_ino);
- ufs_set_de_type (de, dir->i_mode);
- de->d_reclen = SWAB16(UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1));
- ufs_set_de_namlen(de,2);
- strcpy (de->d_name, "..");
- inode->i_nlink = 2;
- mark_buffer_dirty(dir_block);
- brelse (dir_block);
- inode->i_mode = S_IFDIR | mode;
- if (dir->i_mode & S_ISGID)
- inode->i_mode |= S_ISGID;
- mark_inode_dirty(inode);
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh)
- goto out_no_entry;
- de->d_ino = SWAB32(inode->i_ino);
- ufs_set_de_type (de, inode->i_mode);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
+ err = ufs_add_nondir(dentry, inode);
X }
- dir->i_nlink++;
- mark_inode_dirty(dir);
- d_instantiate(dentry, inode);
- brelse (bh);
- err = 0;
-out:
X return err;
-
-out_no_entry:
- inode->i_nlink = 0;
- mark_inode_dirty(inode);
- iput (inode);


- goto out;
-}
-

-/*
- * routine to check that the specified directory is empty (for rmdir)
- */
-static int ufs_empty_dir (struct inode * inode)
-{


- struct super_block * sb;

- unsigned long offset;
- struct buffer_head * bh;
- struct ufs_dir_entry * de, * de1;
- int err;
- unsigned swab;

-
- sb = inode->i_sb;

- swab = sb->u.ufs_sb.s_swab;
-

- if (inode->i_size < UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) ||
- !(bh = ufs_bread (inode, 0, 0, &err))) {
- ufs_warning (inode->i_sb, "empty_dir",
- "bad directory (dir #%lu) - no data block",
- inode->i_ino);
- return 1;
- }
- de = (struct ufs_dir_entry *) bh->b_data;
- de1 = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
- if (SWAB32(de->d_ino) != inode->i_ino || !SWAB32(de1->d_ino) ||
- strcmp (".", de->d_name) || strcmp ("..", de1->d_name)) {
- ufs_warning (inode->i_sb, "empty_dir",
- "bad directory (dir #%lu) - no `.' or `..'",
- inode->i_ino);
- return 1;
- }
- offset = SWAB16(de->d_reclen) + SWAB16(de1->d_reclen);
- de = (struct ufs_dir_entry *) ((char *) de1 + SWAB16(de1->d_reclen));
- while (offset < inode->i_size ) {
- if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
- brelse (bh);
- bh = ufs_bread (inode, offset >> sb->s_blocksize_bits, 1, &err);
- if (!bh) {
- ufs_error (sb, "empty_dir",
- "directory #%lu contains a hole at offset %lu",
- inode->i_ino, offset);
- offset += sb->s_blocksize;
- continue;
- }
- de = (struct ufs_dir_entry *) bh->b_data;
- }
- if (!ufs_check_dir_entry ("empty_dir", inode, de, bh, offset)) {


- brelse (bh);
- return 1;

- }
- if (SWAB32(de->d_ino)) {
- brelse (bh);
- return 0;
- }
- offset += SWAB16(de->d_reclen);
- de = (struct ufs_dir_entry *) ((char *) de + SWAB16(de->d_reclen));
- }


- brelse (bh);
- return 1;

X }
X
-static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
-{
- struct super_block *sb;
- int retval;


- struct inode * inode;

- struct buffer_head * bh;
- struct ufs_dir_entry * de;
- unsigned swab;
-
- sb = dir->i_sb;


- swab = sb->u.ufs_sb.s_swab;
-

- UFSD(("ENTER\n"))
-
- retval = -ENOENT;
- bh = ufs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
- if (!bh)
- goto end_rmdir;
-


- inode = dentry->d_inode;
- DQUOT_INIT(inode);
-

- retval = -EIO;
- if (SWAB32(de->d_ino) != inode->i_ino)
- goto end_rmdir;
-
- retval = -ENOTEMPTY;
- if (!ufs_empty_dir (inode))
- goto end_rmdir;
-
- retval = ufs_delete_entry (dir, de, bh);
- dir->i_version = ++event;
- if (retval)
- goto end_rmdir;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- if (inode->i_nlink != 2)
- ufs_warning (inode->i_sb, "ufs_rmdir",
- "empty directory has nlink!=2 (%d)",
- inode->i_nlink);
- inode->i_version = ++event;
- inode->i_nlink = 0;
- inode->i_size = 0;
- mark_inode_dirty(inode);
- dir->i_nlink--;
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- mark_inode_dirty(dir);
-
-end_rmdir:
- brelse (bh);
- UFSD(("EXIT\n"))


-
- return retval;
-}
-

-static int ufs_unlink(struct inode * dir, struct dentry *dentry)
-{


- struct super_block * sb;

- int retval;


- struct inode * inode;

- struct buffer_head * bh;
- struct ufs_dir_entry * de;
- unsigned flags, swab;
-
- sb = dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;
-

- retval = -ENOENT;
- bh = ufs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
- UFSD(("de: ino %u, reclen %u, namelen %u, name %s\n", SWAB32(de->d_ino),
- SWAB16(de->d_reclen), ufs_get_de_namlen(de), de->d_name))
- if (!bh)
- goto end_unlink;
-


- inode = dentry->d_inode;
- DQUOT_INIT(inode);
-

- retval = -EIO;
- if (SWAB32(de->d_ino) != inode->i_ino)
- goto end_unlink;
-
- if (!inode->i_nlink) {
- ufs_warning (inode->i_sb, "ufs_unlink",
- "Deleting nonexistent file (%lu), %d",
- inode->i_ino, inode->i_nlink);
- inode->i_nlink = 1;
- }
- retval = ufs_delete_entry (dir, de, bh);
- if (retval)
- goto end_unlink;
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- mark_inode_dirty(dir);
- inode->i_nlink--;
- mark_inode_dirty(inode);
- inode->i_ctime = dir->i_ctime;
- retval = 0;
-
-end_unlink:
- brelse (bh);
- return retval;
-}
-
-
-/*
- * Create symbolic link. We use only slow symlinks at this time.
- */
X static int ufs_symlink (struct inode * dir, struct dentry * dentry,
X const char * symname)
X {
X struct super_block * sb = dir->i_sb;
- struct ufs_dir_entry * de;
+ int err = -ENAMETOOLONG;
+ unsigned l = strlen(symname)+1;


X struct inode * inode;

- struct buffer_head * bh = NULL;
- unsigned l;
- int err;
- unsigned swab = sb->u.ufs_sb.s_swab;
-
- UFSD(("ENTER\n"))
-
X
- err = -ENAMETOOLONG;
- l = strlen(symname)+1;
X if (l > sb->s_blocksize)
X goto out;
X
- err = -EIO;
-
- if (!(inode = ufs_new_inode (dir, S_IFLNK, &err))) {
- return err;
- }
- inode->i_mode = S_IFLNK | S_IRWXUGO;
+ inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out;
X
X if (l > sb->u.ufs_sb.s_uspi->s_maxsymlinklen) {
X /* slow symlink */
@@ -771,7 +134,7 @@
X inode->i_mapping->a_ops = &ufs_aops;
X err = block_symlink(inode, symname, l);
X if (err)
- goto out_no_entry;
+ goto out_fail;
X } else {
X /* fast symlink */
X inode->i_op = &ufs_fast_symlink_inode_operations;
@@ -780,26 +143,13 @@
X }
X mark_inode_dirty(inode);
X
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh)
- goto out_no_entry;
- de->d_ino = SWAB32(inode->i_ino);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- brelse (bh);
- d_instantiate(dentry, inode);
- err = 0;
+ err = ufs_add_nondir(dentry, inode);
X out:
X return err;
X
-out_no_entry:
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput (inode);
+out_fail:
+ ufs_dec_count(inode);
+ iput(inode);


X goto out;
X }
X

@@ -807,161 +157,171 @@
X struct dentry *dentry)
X {
X struct inode *inode = old_dentry->d_inode;
- struct super_block * sb = inode->i_sb;
- struct ufs_dir_entry * de;
- struct buffer_head * bh;
- int err;
- unsigned swab = sb->u.ufs_sb.s_swab;
-
+
X if (S_ISDIR(inode->i_mode))
X return -EPERM;
X
X if (inode->i_nlink >= UFS_LINK_MAX)
X return -EMLINK;
X
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh)
- return err;
-
- de->d_ino = SWAB32(inode->i_ino);
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- brelse (bh);
- inode->i_nlink++;


X inode->i_ctime = CURRENT_TIME;

- mark_inode_dirty(inode);
+ ufs_inc_count(inode);
X atomic_inc(&inode->i_count);
+
+ return ufs_add_nondir(dentry, inode);
+}
+
+static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+ struct inode * inode;
+ int err = -EMLINK;
+
+ if (dir->i_nlink >= UFS_LINK_MAX)
+ goto out;
+
+ ufs_inc_count(dir);
+
+ inode = ufs_new_inode(dir, S_IFDIR|mode);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out_dir;
+
+ inode->i_op = &ufs_dir_inode_operations;
+ inode->i_fop = &ufs_dir_operations;
+
+ ufs_inc_count(inode);
+
+ err = ufs_make_empty(inode, dir);
+ if (err)
+ goto out_fail;
+
+ err = ufs_add_link(dentry, inode);
+ if (err)
+ goto out_fail;
+
X d_instantiate(dentry, inode);
- return 0;
+out:
+ return err;
+
+out_fail:
+ ufs_dec_count(inode);
+ ufs_dec_count(inode);
+ iput (inode);
+out_dir:
+ ufs_dec_count(dir);


+ goto out;
X }
X

+static int ufs_unlink(struct inode * dir, struct dentry *dentry)
+{


+ struct inode * inode = dentry->d_inode;

+ struct buffer_head * bh;
+ struct ufs_dir_entry * de;

+ int err = -ENOENT;
X
-#define PARENT_INO(buffer) \
- ((struct ufs_dir_entry *) ((char *) buffer + \
- SWAB16(((struct ufs_dir_entry *) buffer)->d_reclen)))->d_ino
-/*
- * Anybody can rename anything with this: the permission checks are left to the
- * higher-level routines.
- */
-static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
- struct inode * new_dir, struct dentry * new_dentry )


+ de = ufs_find_entry (dentry, &bh);

+ if (!de)
+ goto out;
+
+ err = ufs_delete_entry (dir, de, bh);
+ if (err)
+ goto out;
+
+ inode->i_ctime = dir->i_ctime;
+ ufs_dec_count(inode);
+ err = 0;
+out:


+ return err;
+}
+

+static int ufs_rmdir (struct inode * dir, struct dentry *dentry)


X {
- struct super_block * sb;

- struct inode * old_inode, * new_inode;

- struct buffer_head * old_bh, * new_bh, * dir_bh;
- struct ufs_dir_entry * old_de, * new_de;
- int retval;
- unsigned flags, swab;
-
- sb = old_dir->i_sb;
- flags = sb->u.ufs_sb.s_flags;


- swab = sb->u.ufs_sb.s_swab;

+ struct inode * inode = dentry->d_inode;

+ int err= -ENOTEMPTY;
X
- UFSD(("ENTER\n"))
-
- old_inode = new_inode = NULL;
- old_bh = new_bh = dir_bh = NULL;
- new_de = NULL;
-
- old_bh = ufs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
- /*
- * Check for inode number is _not_ due to possible IO errors.
- * We might rmdir the source, keep it as pwd of some process
- * and merrily kill the link to whatever was created under the
- * same name. Goodbye sticky bit ;-<
- */
- retval = -ENOENT;


- old_inode = old_dentry->d_inode;

- if (!old_bh || SWAB32(old_de->d_ino) != old_inode->i_ino)
- goto end_rename;
-


- new_inode = new_dentry->d_inode;

- new_bh = ufs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de);
- if (new_bh) {
- if (!new_inode) {
- brelse (new_bh);
- new_bh = NULL;
- } else {
- DQUOT_INIT(new_inode);
+ if (ufs_empty_dir (inode)) {
+ err = ufs_unlink(dir, dentry);
+ if (!err) {
+ inode->i_size = 0;
+ ufs_dec_count(inode);
+ ufs_dec_count(dir);
X }
X }
- if (S_ISDIR(old_inode->i_mode)) {
- if (new_inode) {
- retval = -ENOTEMPTY;
- if (!ufs_empty_dir (new_inode))
- goto end_rename;
- }
+ return err;
+}
X
- retval = -EIO;
- dir_bh = ufs_bread (old_inode, 0, 0, &retval);
- if (!dir_bh)
- goto end_rename;
- if (SWAB32(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
- goto end_rename;
- retval = -EMLINK;
- if (!new_inode && new_dir->i_nlink >= UFS_LINK_MAX)
- goto end_rename;
- }
+static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
+ struct inode * new_dir, struct dentry * new_dentry )
+{
+ struct inode *old_inode = old_dentry->d_inode;


+ struct inode *new_inode = new_dentry->d_inode;

+ struct buffer_head *dir_bh = NULL;
+ struct ufs_dir_entry *dir_de = NULL;
+ struct buffer_head *old_bh;
+ struct ufs_dir_entry *old_de;
+ int err = -ENOENT;
X
- if (!new_bh)
- new_bh = ufs_add_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de,
- &retval);
- if (!new_bh)
- goto end_rename;
- new_dir->i_version = ++event;
-
- /*
- * ok, that's it
- */
- new_de->d_ino = SWAB32(old_inode->i_ino);
- ufs_delete_entry (old_dir, old_de, old_bh);
+ old_de = ufs_find_entry (old_dentry, &old_bh);
+ if (!old_de)
+ goto out;
+
+ if (S_ISDIR(old_inode->i_mode)) {
+ err = -EIO;
+ dir_de = ufs_dotdot(old_inode, &dir_bh);
+ if (!dir_de)
+ goto out_old;
+ }
X
- old_dir->i_version = ++event;
X if (new_inode) {
- new_inode->i_nlink--;
+ struct buffer_head *new_bh;
+ struct ufs_dir_entry *new_de;
+
+ err = -ENOTEMPTY;
+ if (dir_de && !ufs_empty_dir (new_inode))
+ goto out_dir;
+ err = -ENOENT;
+ new_de = ufs_find_entry (new_dentry, &new_bh);
+ if (!new_de)
+ goto out_dir;
+ ufs_inc_count(old_inode);
+ ufs_set_link(new_dir, new_de, new_bh, old_inode);
X new_inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(new_inode);
- }
- old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
- mark_inode_dirty(old_dir);
- if (dir_bh) {
- PARENT_INO(dir_bh->b_data) = SWAB32(new_dir->i_ino);
- mark_buffer_dirty(dir_bh);
- old_dir->i_nlink--;
- mark_inode_dirty(old_dir);
- if (new_inode) {
+ if (dir_de)
X new_inode->i_nlink--;
- mark_inode_dirty(new_inode);
- } else {
- new_dir->i_nlink++;
- mark_inode_dirty(new_dir);
+ ufs_dec_count(new_inode);
+ } else {
+ if (dir_de) {
+ err = -EMLINK;
+ if (new_dir->i_nlink >= UFS_LINK_MAX)
+ goto out_dir;
+ }
+ ufs_inc_count(old_inode);
+ err = ufs_add_link(new_dentry, old_inode);
+ if (err) {
+ ufs_dec_count(old_inode);
+ goto out_dir;
X }
+ if (dir_de)
+ ufs_inc_count(new_dir);
X }
- mark_buffer_dirty(old_bh);
- if (IS_SYNC(old_dir)) {
- ll_rw_block (WRITE, 1, &old_bh);
- wait_on_buffer (old_bh);
- }
-
- mark_buffer_dirty(new_bh);
- if (IS_SYNC(new_dir)) {
- ll_rw_block (WRITE, 1, &new_bh);
- wait_on_buffer (new_bh);
+
+ ufs_delete_entry (old_dir, old_de, old_bh);
+
+ ufs_dec_count(old_inode);
+
+ if (dir_de) {
+ ufs_set_link(old_inode, dir_de, dir_bh, new_dir);
+ ufs_dec_count(old_dir);
X }
+ return 0;
X
- retval = 0;
-end_rename:
- brelse (dir_bh);
+out_dir:
+ if (dir_de)
+ brelse(dir_bh);
+out_old:
X brelse (old_bh);
- brelse (new_bh);
-
- UFSD(("EXIT\n"))
-
- return retval;
+out:


+ return err;
X }
X

X struct inode_operations ufs_dir_inode_operations = {
diff -u --recursive --new-file v2.4.12/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.4.12/linux/fs/vfat/namei.c Fri Apr 6 10:51:19 2001
+++ linux/fs/vfat/namei.c Fri Oct 12 13:48:42 2001
@@ -9,13 +9,12 @@
X * what file operation caused you trouble and if you can duplicate
X * the problem, send a script that demonstrates it.
X *


- * Short name translation 1999 by Wolfram Pienkoss <w...@bszh.de>
+ * Short name translation 1999, 2001 by Wolfram Pienkoss <w...@bszh.de>
X *

X * Support Multibyte character and cleanup by
X * OGAWA Hirofumi <hiro...@mail.parknet.co.jp>
X */
X

-#define __NO_VERSION__
X #include <linux/module.h>

X
X #include <linux/sched.h>
@@ -29,8 +28,6 @@
X #include <linux/mm.h>
X #include <linux/slab.h>
X
-#include "../fat/msbuffer.h"
-
X #define DEBUG_LEVEL 0
X #if (DEBUG_LEVEL >= 1)
X # define PRINTK1(x) printk x
@@ -48,12 +45,6 @@
X # define PRINTK3(x)
X #endif
X
-#ifndef DEBUG
-# define CHECK_STACK
-#else
-# define CHECK_STACK check_stack(__FILE__, __LINE__)
-#endif
-
X static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
X static int vfat_hash(struct dentry *parent, struct qstr *qstr);
X static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
@@ -117,6 +108,13 @@
X opts->unicode_xlate = opts->posixfs = 0;
X opts->numtail = 1;


X opts->utf8 = 0;

+ opts->shortname = VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95;
+ /* for backward compatible */
+ if (opts->nocase) {
+ opts->nocase = 0;
+ opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ | VFAT_SFN_CREATE_WIN95;
+ }
X
X if (!options) return 1;
X save = 0;
@@ -142,6 +140,21 @@
X if (ret) {
X opts->numtail = !val;
X }
+ } else if (!strcmp(this_char, "shortname")) {
+ if (!strcmp(value, "lower"))
+ opts->shortname = VFAT_SFN_DISPLAY_LOWER
+ | VFAT_SFN_CREATE_WIN95;
+ else if (!strcmp(value, "win95"))
+ opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ | VFAT_SFN_CREATE_WIN95;
+ else if (!strcmp(value, "winnt"))
+ opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ | VFAT_SFN_CREATE_WINNT;
+ else if (!strcmp(value, "mixed"))
+ opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ | VFAT_SFN_CREATE_WIN95;
+ else
+ ret = 0;
X }
X if (this_char != options)
X *(this_char-1) = ',';
@@ -157,167 +170,7 @@
X }
X return 1;
X }
-#if 0 /* not used functions */
-static inline unsigned char
-vfat_getlower(struct nls_table *t, unsigned char c)
-{
- return t->charset2lower[c];
-}
-
-static inline unsigned char
-vfat_getupper(struct nls_table *t, unsigned char c)
-{
- return t->charset2upper[c];
-}
-
-static inline int
-vfat_uni2short(struct nls_table *t, wchar_t uc, unsigned char *op, int bound)
-{
- int charlen;
-
- if ( (charlen = t->uni2char(uc, op, bound)) < 0)
- charlen = 0;
-
- return charlen;
-}
-
-static int vfat_valid_shortname(struct nls_table *nls, wchar_t *name, int len)
-{
- wchar_t *walk;
- unsigned char c, charbuf[NLS_MAX_CHARSET_SIZE];
- int chl, chi;
- int space;
-
- if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
- return -EINVAL;
-
- if (IS_FREE(charbuf))
- return -EINVAL;
-
- chl = 0;
- c = 0;
- space = 1; /* disallow names starting with a dot */
- for (walk = name; len && walk-name < 8;) {
- len--;
- chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl < 0)
- return -EINVAL;
-
- for (chi = 0; chi < chl; chi++) {
- c = vfat_getupper(nls, charbuf[chi]);
- if (!c) return -EINVAL;
- if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
- if (strchr(replace_chars,c)) return -EINVAL;
- if (c < ' '|| c==':') return -EINVAL;
- if (c == '.') goto dot;
- space = c == ' ';
- }
- }
-dot:;
- if (space) return -EINVAL;
- if (len && c != '.') {
- len--;
- if (vfat_uni2upper_short(nls, *walk++, charbuf, NLS_MAX_CHARSET_SIZE) == 1) {
- if (charbuf[0] != '.') return -EINVAL;
- } else
- return -EINVAL;
- c = '.';
- }
- if (c == '.') {
- if (len >= 4) return -EINVAL;
- while (len > 0) {
- len--;
- chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl < 0)
- return -EINVAL;
- for (chi = 0; chi < chl; chi++) {
- c = vfat_getupper(nls, charbuf[chi]);
- if (!c) return -EINVAL;
- if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
- if (strchr(replace_chars,c))
- return -EINVAL;
- if (c < ' ' || c == '.'|| c==':')
- return -EINVAL;
- space = c == ' ';
- }
- }
- if (space) return -EINVAL;
- }
-


- return 0;
-}
X

-static int vfat_format_name(struct nls_table *nls, wchar_t *name,
- int len, char *res)
-{
- char *walk;
- unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
- int chi, chl;
- int space;
-
- if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
- return -EINVAL;
-
- if (IS_FREE(charbuf))
- return -EINVAL;
-
- space = 1; /* disallow names starting with a dot */
- for (walk = res; len--; ) {
- chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (chl == 0)
- return -EINVAL;
- for (chi = 0; chi < chl; chi++){
- if (charbuf[chi] == '.') goto dot;
- if (!charbuf[chi]) return -EINVAL;
- if (walk-res == 8) return -EINVAL;
- if (strchr(replace_chars,charbuf[chi])) return -EINVAL;
- if (charbuf[chi] < ' '|| charbuf[chi]==':') return -EINVAL;
- space = charbuf[chi] == ' ';
- *walk = charbuf[chi];
- walk++;
- }
- }
-dot:;
- if (space) return -EINVAL;
- if (len >= 0) {
- while (walk-res < 8) *walk++ = ' ';
- while (len > 0 && walk-res < MSDOS_NAME) {
- chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
- if (len < chl)
- chl = len;
- len -= chl;
- for (chi = 0; chi < chl; chi++){
- if (!charbuf[chi]) return -EINVAL;
- if (strchr(replace_chars,charbuf[chi]))
- return -EINVAL;
- if (charbuf[chi] < ' ' || charbuf[chi] == '.'|| charbuf[chi]==':')
- return -EINVAL;
- space = charbuf[chi] == ' ';
- *walk++ = charbuf[chi];
- }
- }
- if (space) return -EINVAL;
- if (len) return -EINVAL;
- }
- while (walk-res < MSDOS_NAME) *walk++ = ' ';


-
- return 0;
-}
-

-static inline int
-vfat_uni2upper_short(struct nls_table *t, wchar_t uc, char *op, int bound)
-{
- int chl;
-
- if ( (chl = t->uni2char(uc, op, bound)) < 0)
- chl = 0;
-
- if (chl == 1)
- op[0] = vfat_toupper(t, op[0]);
-
- return chl;
-}
-#endif
X static inline unsigned char
X vfat_tolower(struct nls_table *t, unsigned char c)
X {
@@ -437,33 +290,6 @@
X
X #ifdef DEBUG
X
-static void
-check_stack(const char *fname, int lineno)
-{
- int stack_level;
- char *pg_dir;
-
- stack_level = (long)(&pg_dir)-current->kernel_stack_page;
- if (stack_level < 0)
- printk("*-*-*-* vfat kstack overflow in %s line %d: SL=%d\n",
- fname, lineno, stack_level);
- else if (stack_level < 500)
- printk("*-*-*-* vfat kstack low in %s line %d: SL=%d\n",
- fname, lineno, stack_level);
-#if 0
- else
- printk("------- vfat kstack ok in %s line %d: SL=%d\n",
- fname, lineno, stack_level);
-#endif
-#if 0
- if (*(unsigned long *) current->kernel_stack_page != STACK_MAGIC) {
- printk("******* vfat stack corruption detected in %s at line %d\n",
- fname, lineno);
- }
-#endif
-}
-
-static int debug = 0;
X static void dump_fat(struct super_block *sb,int start)
X {
X printk("[");
@@ -510,8 +336,10 @@
X /* Characters that are undesirable in an MS-DOS file name */
X
X static wchar_t bad_chars[] = {
- /* `*' `?' `<' `>' `|' `"' `:' `/' `\' */
- 0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F, 0x005C, 0,
+ /* `*' `?' `<' `>' `|' `"' `:' `/' */
+ 0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F,
+ /* `\' */
+ 0x005C, 0,
X };
X #define IS_BADCHAR(uni) (vfat_unistrchr(bad_chars, (uni)) != NULL)
X
@@ -521,6 +349,13 @@
X };
X #define IS_REPLACECHAR(uni) (vfat_unistrchr(replace_chars, (uni)) != NULL)
X
+static wchar_t skip_chars[] = {
+ /* `.' ` ' */
+ 0x002E, 0x0020, 0,
+};
+#define IS_SKIPCHAR(uni) \
+ ((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
+
X static inline wchar_t *vfat_unistrchr(const wchar_t *s, const wchar_t c)
X {
X for(; *s != c; ++s)
@@ -582,47 +417,119 @@


X return 0;
X }
X

-static wchar_t skip_chars[] = {
- /* `.' ` ' */
- 0x002E, 0x0020, 0,
+/*
+ * 1) Valid characters for the 8.3 format alias are any combination of
+ * letters, uppercase alphabets, digits, any of the
+ * following special characters:
+ * $ % ' ` - @ { } ~ ! # ( ) & _ ^
+ * In this case Longfilename is not stored in disk.
+ *
+ * WinNT's Extension:
+ * File name and extension name is contain uppercase/lowercase
+ * only. And it is expressed by CASE_LOWER_BASE and CASE_LOWER_EXT.
+ *
+ * 2) File name is 8.3 format, but it contain the uppercase and
+ * lowercase char, muliti bytes char, etc. In this case numtail is not
+ * added, but Longfilename is stored.
+ *
+ * 3) When the one except for the above, or the following special
+ * character are contained:
+ * . [ ] ; , + =
+ * numtail is added, and Longfilename must be stored in disk .
+ */
+struct shortname_info {
+ unsigned char lower:1,
+ upper:1,
+ valid:1;
X };
-#define IS_SKIPCHAR(uni) \
- ((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
+#define INIT_SHORTNAME_INFO(x) do { \
+ (x)->lower = 1; \
+ (x)->upper = 1; \
+ (x)->valid = 1; \
+} while (0);
X
-/* Given a valid longname, create a unique shortname. Make sure the
+static inline unsigned char
+shortname_info_to_lcase(struct shortname_info *base,
+ struct shortname_info *ext)
+{
+ unsigned char lcase = 0;
+
+ if (base->valid && ext->valid) {
+ if (!base->upper && base->lower && (ext->lower || ext->upper))
+ lcase |= CASE_LOWER_BASE;
+ if (!ext->upper && ext->lower && (base->lower || base->upper))
+ lcase |= CASE_LOWER_EXT;
+ }
+
+ return lcase;
+}
+
+static inline int to_shortname_char(struct nls_table *nls,
+ char *buf, int buf_size, wchar_t *src,
+ struct shortname_info *info)
+{
+ int len;
+
+ if (IS_SKIPCHAR(*src)) {
+ info->valid = 0;
+ return 0;
+ }
+ if (IS_REPLACECHAR(*src)) {
+ info->valid = 0;
+ buf[0] = '_';


+ return 1;
+ }
+

+ len = nls->uni2char(*src, buf, buf_size);
+ if (len <= 0) {
+ info->valid = 0;
+ buf[0] = '_';
+ len = 1;
+ } else if (len == 1) {
+ unsigned char prev = buf[0];
+
+ if (buf[0] >= 0x7F) {
+ info->lower = 0;
+ info->upper = 0;
+ }
+
+ buf[0] = vfat_toupper(nls, buf[0]);
+ if (isalpha(buf[0])) {
+ if (buf[0] == prev)
+ info->lower = 0;
+ else
+ info->upper = 0;
+ }
+ } else {
+ info->lower = 0;
+ info->upper = 0;
+ }
+
+ return len;
+}
+
+/*
+ * Given a valid longname, create a unique shortname. Make sure the
X * shortname does not exist
X * Returns negative number on error, 0 for a normal
X * return, and 1 for valid shortname
X */
X static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
X wchar_t *uname, int ulen,
- char *name_res)
+ char *name_res, unsigned char *lcase)
X {
X wchar_t *ip, *ext_start, *end, *name_start;
X unsigned char base[9], ext[4], buf[8], *p;
X unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
X int chl, chi;
X int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
- int is_uppercase, is_shortname;
+ int is_shortname;
+ struct shortname_info base_info, ext_info;
+ unsigned short opt_shortname = MSDOS_SB(dir->i_sb)->options.shortname;
X
- /*
- * 1) Valid characters for the 8.3 format alias are any
- * combination of letters, uppercase alphabets, digits, any of
- * the following special characters:
- * $ % ' ` - @ { } ~ ! # ( ) & _ ^
- * In this case Longfilename is not stored in disk.
- *
- * 2) File name is 8.3 format, but it contain the lowercase
- * alphabet etc. In this case numtail is not added, but
- * Longfilename is stored.
- *
- * 3) When the one except for the above, or the following special
- * character are contained:
- * . [ ] ; , + =
- * numtail is added, and Longfilename must be stored in disk .
- */
- is_uppercase = 1;
X is_shortname = 1;
+ INIT_SHORTNAME_INFO(&base_info);
+ INIT_SHORTNAME_INFO(&ext_info);
X
X /* Now, we need to create a shortname from the long name */
X ext_start = end = &uname[ulen];
@@ -662,31 +569,11 @@
X
X numtail_baselen = 6;
X numtail2_baselen = 2;
- for (baselen = i = 0, p = base, ip = uname; i < sz; i++, ip++)
- {
- if (IS_SKIPCHAR(*ip)) {
- is_shortname = 0;
+ for (baselen = i = 0, p = base, ip = uname; i < sz; i++, ip++) {
+ chl = to_shortname_char(nls, charbuf, sizeof(charbuf),
+ ip, &base_info);
+ if (chl == 0)
X continue;
- }
- if (IS_REPLACECHAR(*ip)) {
- is_shortname = 0;
- charbuf[0] = '_';
- chl = 1;
- } else {
- chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
- if (chl <= 0) {
- is_shortname = 0;
- charbuf[0] = '_';
- chl = 1;
- } else if (chl == 1) {
- unsigned char c = charbuf[0];
- charbuf[0] = vfat_toupper(nls, charbuf[0]);
- if (c >= 0x7F || charbuf[0] != c)
- is_uppercase = 0;
- } else {
- is_uppercase = 0;
- }
- }
X
X if (baselen < 2 && (baselen + chl) > 2)
X numtail2_baselen = baselen;
@@ -711,30 +598,11 @@
X extlen = 0;
X if (ext_start) {
X for (p = ext, ip = ext_start; extlen < 3 && ip < end; ip++) {
- if (IS_SKIPCHAR(*ip)) {
- is_shortname = 0;
+ chl = to_shortname_char(nls, charbuf, sizeof(charbuf),
+ ip, &ext_info);
+ if (chl == 0)
X continue;
- }
- if (IS_REPLACECHAR(*ip)) {
- is_shortname = 0;
- charbuf[0] = '_';
- chl = 1;
- } else {
- chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
- if (chl <= 0) {
- is_shortname = 0;
- charbuf[0] = '_';
- chl = 1;
- } else if (chl == 1) {
- unsigned char c = charbuf[0];
- charbuf[0] = vfat_toupper(nls, charbuf[0]);
- if (c >= 0x7F || charbuf[0] != c)
- is_uppercase = 0;
- } else {
- is_uppercase = 0;
- }
- }
-
+
X if ((extlen + chl) > 3) {
X is_shortname = 0;
X break;
@@ -763,14 +631,26 @@
X */
X
X memset(name_res, ' ', MSDOS_NAME);
- memcpy(name_res,base,baselen);
- memcpy(name_res+8,ext,extlen);
-
- if (is_shortname) {
- if (vfat_find_form(dir, name_res) < 0)
- return is_uppercase;
- else
+ memcpy(name_res, base, baselen);
+ memcpy(name_res + 8, ext, extlen);
+ *lcase = 0;
+ if (is_shortname && base_info.valid && ext_info.valid) {
+ if (vfat_find_form(dir, name_res) == 0)
X return -EEXIST;
+
+ if (opt_shortname & VFAT_SFN_CREATE_WIN95) {
+ return (base_info.upper && ext_info.upper);
+ } else if (opt_shortname & VFAT_SFN_CREATE_WINNT) {
+ if ((base_info.upper || base_info.lower)
+ && (ext_info.upper || ext_info.lower)) {
+ *lcase = shortname_info_to_lcase(&base_info,
+ &ext_info);
+ return 1;
+ }
+ return 0;
+ } else {
+ BUG();
+ }
X }
X
X if (MSDOS_SB(dir->i_sb)->options.numtail == 0)
@@ -866,7 +746,6 @@
X } else {
X if ((charlen = nls->char2uni(ip, len-i, (wchar_t *)op)) < 0)
X return -EINVAL;
-
X ip += charlen;
X i += charlen;
X op += 2;
@@ -904,31 +783,31 @@
X
X static int
X vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name,
- int len, int *slots, int uni_xlate)
+ int len, int *slots, int is_dir, int uni_xlate)
X {
X struct nls_table *nls_io, *nls_disk;
X wchar_t *uname;
X struct msdos_dir_slot *ps;
X struct msdos_dir_entry *de;
X unsigned long page;
- unsigned char cksum;
- const char *ip;
+ unsigned char cksum, lcase;
X char *uniname, msdos_name[MSDOS_NAME];
X int res, utf8, slot, ulen, unilen, i;
X loff_t offset;
X
- de = (struct msdos_dir_entry *) ds;
+ *slots = 0;
X utf8 = MSDOS_SB(dir->i_sb)->options.utf8;
X nls_io = MSDOS_SB(dir->i_sb)->nls_io;
X nls_disk = MSDOS_SB(dir->i_sb)->nls_disk;
X
- if (name[len-1] == '.') len--;
+ if (name[len-1] == '.')
+ len--;
X if(!(page = __get_free_page(GFP_KERNEL)))
X return -ENOMEM;
- uniname = (char *) page;
X
+ uniname = (char *) page;
X res = xlate_to_uni(name, len, uniname, &ulen, &unilen, uni_xlate,
- utf8, nls_io);
+ utf8, nls_io);
X if (res < 0)
X goto out_free;
X
@@ -937,15 +816,17 @@
X if (res < 0)
X goto out_free;
X
- res = vfat_create_shortname(dir, nls_disk, uname, ulen, msdos_name);
+ res = vfat_create_shortname(dir, nls_disk, uname, ulen,
+ msdos_name, &lcase);
X if (res < 0)
X goto out_free;
X else if (res == 1) {
- strncpy(de->name, msdos_name, MSDOS_NAME);
+ de = (struct msdos_dir_entry *)ds;
X res = 0;
- goto out_free;
+ goto shortname;
X }
X
+ /* build the entry of long file name */
X *slots = unilen / 13;
X for (cksum = i = 0; i < 11; i++) {
X cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
@@ -958,18 +839,26 @@
X ps->reserved = 0;
X ps->alias_checksum = cksum;
X ps->start = 0;
- offset = (slot - 1) * 26;
- ip = &uniname[offset];
- memcpy(ps->name0_4, ip, 10);
- memcpy(ps->name5_10, ip+10, 12);
- memcpy(ps->name11_12, ip+22, 4);
+ offset = (slot - 1) * 13;
+ fatwchar_to16(ps->name0_4, uname + offset, 5);
+ fatwchar_to16(ps->name5_10, uname + offset + 5, 6);
+ fatwchar_to16(ps->name11_12, uname + offset + 11, 2);
X }
X ds[0].id |= 0x40;
-
X de = (struct msdos_dir_entry *) ps;
+
+shortname:
X PRINTK3(("vfat_fill_slots 9\n"));
- strncpy(de->name, msdos_name, MSDOS_NAME);
+ /* build the entry of 8.3 alias name */
X (*slots)++;
+ strncpy(de->name, msdos_name, MSDOS_NAME);
+ de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
+ de->lcase = lcase;
+ de->adate = de->cdate = de->date = 0;
+ de->ctime_ms = de->ctime = de->time = 0;
+ de->start = 0;
+ de->starthi = 0;
+ de->size = 0;
X
X out_free:
X free_page(page);
@@ -978,96 +867,92 @@
X
X /* We can't get "." or ".." here - VFS takes care of those cases */
X
-static int vfat_build_slots(struct inode *dir,const char *name,int len,
- struct msdos_dir_slot *ds, int *slots)
+static int vfat_build_slots(struct inode *dir, const char *name, int len,
+ struct msdos_dir_slot *ds, int *slots, int is_dir)
X {
X int res, xlate;
X
X xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate;
- *slots = 1;
X res = vfat_valid_longname(name, len, xlate);
X if (res < 0)
X return res;
- return vfat_fill_slots(dir, ds, name, len, slots, xlate);
+
+ return vfat_fill_slots(dir, ds, name, len, slots, is_dir, xlate);
X }
X
X static int vfat_add_entry(struct inode *dir,struct qstr* qname,
- int is_dir,struct vfat_slot_info *sinfo_out,
- struct buffer_head **bh, struct msdos_dir_entry **de)
+ int is_dir, struct vfat_slot_info *sinfo_out,
+ struct buffer_head **bh, struct msdos_dir_entry **de)
X {
X struct super_block *sb = dir->i_sb;
- struct msdos_dir_slot *ps;
+ struct msdos_dir_slot *dir_slots;
X loff_t offset;
- struct msdos_dir_slot *ds;
X int slots, slot;
- int res;
- struct msdos_dir_entry *de1;
- struct buffer_head *bh1;
- int ino;
- int len;
+ int res, len;
+ struct msdos_dir_entry *dummy_de;
+ struct buffer_head *dummy_bh;
+ int dummy_ino;
X loff_t dummy;
X
- ds = (struct msdos_dir_slot *)
- kmalloc(sizeof(struct msdos_dir_slot)*MSDOS_SLOTS, GFP_KERNEL);
- if (ds == NULL) return -ENOMEM;
+ dir_slots = (struct msdos_dir_slot *)
+ kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);
+ if (dir_slots == NULL)
+ return -ENOMEM;
X
X len = qname->len;
X while (len && qname->name[len-1] == '.')
X len--;
X res = fat_search_long(dir, qname->name, len,
- (MSDOS_SB(sb)->options.name_check != 's') ||
- !MSDOS_SB(sb)->options.posixfs,
- &dummy, &dummy);
+ (MSDOS_SB(sb)->options.name_check != 's')
+ || !MSDOS_SB(sb)->options.posixfs,
+ &dummy, &dummy);
X if (res > 0) /* found */
X res = -EEXIST;
X if (res)
X goto cleanup;
X
- res = vfat_build_slots(dir, qname->name, len, ds, &slots);
+ res = vfat_build_slots(dir, qname->name, len,
+ dir_slots, &slots, is_dir);
X if (res < 0)
X goto cleanup;
X
- offset = fat_add_entries(dir, slots, &bh1, &de1, &ino);
+ /* build the empty directory entry of number of slots */
+ offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_ino);
X if (offset < 0) {
X res = offset;
X goto cleanup;
X }
- fat_brelse(sb, bh1);
+ fat_brelse(sb, dummy_bh);
X
X /* Now create the new entry */
X *bh = NULL;
- for (slot = 0, ps = ds; slot < slots; slot++, ps++) {
- if (fat_get_entry(dir,&offset,bh,de, &sinfo_out->ino) < 0) {
+ for (slot = 0; slot < slots; slot++) {
+ if (fat_get_entry(dir, &offset, bh, de, &sinfo_out->ino) < 0) {
X res = -EIO;
X goto cleanup;
X }
- memcpy(*de, ps, sizeof(struct msdos_dir_slot));
+ memcpy(*de, dir_slots + slot, sizeof(struct msdos_dir_slot));
X fat_mark_buffer_dirty(sb, *bh);
X }
X
+ res = 0;
+ /* update timestamp */
X dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
X mark_inode_dirty(dir);
X
- fat_date_unix2dos(dir->i_mtime,&(*de)->time,&(*de)->date);
- (*de)->ctime_ms = 0;
+ fat_date_unix2dos(dir->i_mtime, &(*de)->time, &(*de)->date);
X (*de)->ctime = (*de)->time;
X (*de)->adate = (*de)->cdate = (*de)->date;
- (*de)->start = 0;
- (*de)->starthi = 0;
- (*de)->size = 0;
- (*de)->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
- (*de)->lcase = CASE_LOWER_BASE | CASE_LOWER_EXT;
-
X
X fat_mark_buffer_dirty(sb, *bh);
X
X /* slots can't be less than 1 */
X sinfo_out->long_slots = slots - 1;
- sinfo_out->longname_offset = offset - sizeof(struct msdos_dir_slot) * slots;
- res = 0;
+ sinfo_out->longname_offset =
+ offset - sizeof(struct msdos_dir_slot) * slots;
X
X cleanup:
- kfree(ds);
+ kfree(dir_slots);
X return res;
X }
X
diff -u --recursive --new-file v2.4.12/linux/fs/vfat/vfatfs_syms.c linux/fs/vfat/vfatfs_syms.c
--- v2.4.12/linux/fs/vfat/vfatfs_syms.c Mon Mar 13 12:35:39 2000
+++ linux/fs/vfat/vfatfs_syms.c Fri Oct 12 13:48:42 2001
@@ -5,8 +5,6 @@
X * These symbols are used by dmsdos.
X */
X

-#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
-#include <linux/version.h>

X #include <linux/module.h>
X #include <linux/init.h>

X
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- v2.4.12/linux/include/asm-alpha/bitops.h Thu May 24 15:20:18 2001
+++ linux/include/asm-alpha/bitops.h Fri Oct 12 15:35:54 2001
@@ -20,7 +20,7 @@
X * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
X */
X
-extern __inline__ void
+static inline void
X set_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long temp;
@@ -41,7 +41,7 @@
X /*
X * WARNING: non atomic version.
X */
-extern __inline__ void
+static inline void
X __set_bit(unsigned long nr, volatile void * addr)
X {
X int *m = ((int *) addr) + (nr >> 5);
@@ -52,7 +52,7 @@
X #define smp_mb__before_clear_bit() smp_mb()
X #define smp_mb__after_clear_bit() smp_mb()
X
-extern __inline__ void
+static inline void
X clear_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long temp;
@@ -81,7 +81,7 @@
X *m ^= 1 << (nr & 31);
X }
X
-extern __inline__ void
+static inline void
X change_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long temp;
@@ -99,7 +99,7 @@
X :"Ir" (1UL << (nr & 31)), "m" (*m));
X }
X
-extern __inline__ int
+static inline int
X test_and_set_bit(unsigned long nr, volatile void *addr)
X {
X unsigned long oldbit;
@@ -129,7 +129,7 @@
X /*
X * WARNING: non atomic version.
X */
-extern __inline__ int
+static inline int
X __test_and_set_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long mask = 1 << (nr & 0x1f);
@@ -140,7 +140,7 @@
X return (old & mask) != 0;
X }
X
-extern __inline__ int
+static inline int
X test_and_clear_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long oldbit;
@@ -170,7 +170,7 @@
X /*
X * WARNING: non atomic version.
X */
-extern __inline__ int
+static inline int
X __test_and_clear_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long mask = 1 << (nr & 0x1f);
@@ -195,7 +195,7 @@
X return (old & mask) != 0;
X }
X
-extern __inline__ int
+static inline int
X test_and_change_bit(unsigned long nr, volatile void * addr)
X {
X unsigned long oldbit;
@@ -220,7 +220,7 @@
X return oldbit != 0;
X }
X
-extern __inline__ int
+static inline int
X test_bit(int nr, volatile void * addr)
X {
X return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
@@ -233,7 +233,7 @@
X * Do a binary search on the bits. Due to the nature of large
X * constants on the alpha, it is worthwhile to split the search.
X */
-extern inline unsigned long ffz_b(unsigned long x)
+static inline unsigned long ffz_b(unsigned long x)
X {
X unsigned long sum = 0;
X
@@ -245,7 +245,7 @@
X return sum;
X }
X
-extern inline unsigned long ffz(unsigned long word)
+static inline unsigned long ffz(unsigned long word)
X {
X #if defined(__alpha_cix__) && defined(__alpha_fix__)
X /* Whee. EV67 can calculate it directly. */
@@ -272,12 +272,32 @@
X * differs in spirit from the above ffz (man ffs).
X */
X
-extern inline int ffs(int word)
+static inline int ffs(int word)
X {
X int result = ffz(~word);
X return word ? result+1 : 0;
X }
X
+/* Compute powers of two for the given integer. */
+static inline int floor_log2(unsigned long word)
+{
+ long bit;
+#if defined(__alpha_cix__) && defined(__alpha_fix__)
+ __asm__("ctlz %1,%0" : "=r"(bit) : "r"(word));
+ return 63 - bit;
+#else
+ for (bit = -1; word ; bit++)
+ word >>= 1;
+ return bit;
+#endif
+}
+
+static inline int ceil_log2(unsigned int word)
+{
+ long bit = floor_log2(word);
+ return bit + (word > (1UL << bit));
+}
+
X /*
X * hweightN: returns the hamming weight (i.e. the number
X * of bits set) of a N-bit word
@@ -285,7 +305,7 @@
X
X #if defined(__alpha_cix__) && defined(__alpha_fix__)
X /* Whee. EV67 can calculate it directly. */
-extern __inline__ unsigned long hweight64(unsigned long w)
+static inline unsigned long hweight64(unsigned long w)
X {
X unsigned long result;
X __asm__("ctpop %1,%0" : "=r"(result) : "r"(w));
@@ -306,7 +326,7 @@
X /*
X * Find next zero bit in a bitmap reasonably efficiently..
X */
-extern inline unsigned long
+static inline unsigned long
X find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
X {
X unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/core_cia.h linux/include/asm-alpha/core_cia.h
--- v2.4.12/linux/include/asm-alpha/core_cia.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/core_cia.h Fri Oct 12 15:35:54 2001
@@ -263,6 +263,9 @@
X #define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL)
X #define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL)
X
+/* Offset between ram physical addresses and pci64 DAC bus addresses. */
+#define PYXIS_DAC_OFFSET (1UL << 40)
+
X /*
X * Data structure for handling CIA machine checks.
X */
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/core_mcpcia.h linux/include/asm-alpha/core_mcpcia.h
--- v2.4.12/linux/include/asm-alpha/core_mcpcia.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/core_mcpcia.h Fri Oct 12 15:35:54 2001
@@ -181,6 +181,8 @@
X #define MCPCIA_IO_BIAS MCPCIA_IO(4)
X #define MCPCIA_MEM_BIAS MCPCIA_DENSE(4)
X
+/* Offset between ram physical addresses and pci64 DAC bus addresses. */
+#define MCPCIA_DAC_OFFSET (1UL << 40)
X
X /*
X * Data structure for handling MCPCIA machine checks:
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/core_titan.h linux/include/asm-alpha/core_titan.h
--- v2.4.12/linux/include/asm-alpha/core_titan.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/core_titan.h Fri Oct 12 15:35:54 2001
@@ -308,14 +308,18 @@
X * devices can use their familiar numbers and have them map to bus 0.
X */
X
-#define TITAN_IO_BIAS TITAN_IO(0)
-#define TITAN_MEM_BIAS TITAN_MEM(0)
+#define TITAN_IO_BIAS TITAN_IO(0)
+#define TITAN_MEM_BIAS TITAN_MEM(0)
X
X /* The IO address space is larger than 0xffff */
X #define TITAN_IO_SPACE (TITAN_CONF(0) - TITAN_IO(0))
X
X /* TIG Space */
X #define TITAN_TIG_SPACE (TITAN_BASE + 0x100000000UL)
+
+/* Offset between ram physical addresses and pci64 DAC bus addresses. */
+/* ??? Just a guess. Ought to confirm it hasn't been moved. */
+#define TITAN_DAC_OFFSET (1UL << 40)
X
X /*
X * Data structure for handling TITAN machine checks:
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h
--- v2.4.12/linux/include/asm-alpha/core_tsunami.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/core_tsunami.h Fri Oct 12 15:35:54 2001
@@ -275,7 +275,7 @@
X /* The IO address space is larger than 0xffff */
X #define TSUNAMI_IO_SPACE (TSUNAMI_CONF(0) - TSUNAMI_IO(0))
X
-/* Offset between ram physical addresses and pci64 DAC bus addresses */
+/* Offset between ram physical addresses and pci64 DAC bus addresses. */
X #define TSUNAMI_DAC_OFFSET (1UL << 40)
X
X /*
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h
--- v2.4.12/linux/include/asm-alpha/machvec.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/machvec.h Fri Oct 12 15:35:54 2001
@@ -39,6 +39,7 @@
X unsigned long iack_sc;
X unsigned long min_io_address;
X unsigned long min_mem_address;


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 47'
echo 'File patch-2.4.13 is continued in part 48'
echo "48" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:18 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part48

#!/bin/sh -x
# this is part 48 of a 53 - part archive


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

if test "$Scheck" != 48; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ unsigned long pci_dac_offset;
X
X void (*mv_pci_tbi)(struct pci_controller *hose,
X dma_addr_t start, dma_addr_t end);
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/pci.h linux/include/asm-alpha/pci.h
--- v2.4.12/linux/include/asm-alpha/pci.h Mon May 21 13:38:41 2001
+++ linux/include/asm-alpha/pci.h Fri Oct 12 15:35:54 2001
@@ -15,6 +15,7 @@
X struct pci_bus;
X struct resource;
X struct pci_iommu_arena;
+struct page;
X
X /* A controller. Used to manage multiple PCI busses. */
X
@@ -60,12 +61,17 @@
X
X /* IOMMU controls. */
X
+/* The PCI address space does not equal the physical memory address space.
+ The networking and block device layers use this boolean for bounce buffer
+ decisions. */
+#define PCI_DMA_BUS_IS_PHYS 0
+
X /* Allocate and map kernel buffer using consistant mode DMA for PCI
X device. Returns non-NULL cpu-view pointer to the buffer if
X successful and sets *DMA_ADDRP to the pci side dma address as well,
X else DMA_ADDRP is undefined. */
X
-extern void *pci_alloc_consistent(struct pci_dev *, long, dma_addr_t *);
+extern void *pci_alloc_consistent(struct pci_dev *, size_t, dma_addr_t *);
X
X /* Free and unmap a consistant DMA buffer. CPU_ADDR and DMA_ADDR must
X be values that were returned from pci_alloc_consistant. SIZE must
@@ -73,14 +79,18 @@
X References to the memory and mappings assosciated with CPU_ADDR or
X DMA_ADDR past this call are illegal. */
X
-extern void pci_free_consistent(struct pci_dev *, long, void *, dma_addr_t);
+extern void pci_free_consistent(struct pci_dev *, size_t, void *, dma_addr_t);
X
X /* Map a single buffer of the indicate size for PCI DMA in streaming
X mode. The 32-bit PCI bus mastering address to use is returned.
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 dma_addr_t pci_map_single(struct pci_dev *, void *, long, int);
+extern dma_addr_t pci_map_single(struct pci_dev *, void *, size_t, int);
+
+/* Likewise, but for a page instead of an address. */
+extern dma_addr_t pci_map_page(struct pci_dev *, struct page *,
+ unsigned long, size_t, int);
X
X /* Unmap a single streaming mode DMA translation. The DMA_ADDR and
X SIZE must match what was provided for in a previous pci_map_single
@@ -88,7 +98,8 @@
X the cpu to the buffer are guarenteed to see whatever the device
X wrote there. */
X
-extern void pci_unmap_single(struct pci_dev *, dma_addr_t, long, int);
+extern void pci_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
+extern void pci_unmap_page(struct pci_dev *, dma_addr_t, size_t, int);
X
X /* Map a set of buffers described by scatterlist in streaming mode for
X PCI DMA. This is the scather-gather version of the above
@@ -121,7 +132,7 @@
X point you give the PCI dma address back to the card, the device
X again owns the buffer. */
X
-extern inline void
+static inline void
X pci_dma_sync_single(struct pci_dev *dev, dma_addr_t dma_addr, long size,
X int direction)
X {
@@ -132,7 +143,7 @@
X translations after a transfer. The same as pci_dma_sync_single but
X for a scatter-gather list, same rules and usage. */
X
-extern inline void
+static inline void
X pci_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sg, int nents,
X int direction)
X {
@@ -144,7 +155,22 @@
X only drive the low 24-bits during PCI bus mastering, then
X you would pass 0x00ffffff as the mask to this function. */
X
-extern int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask);
+extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/* True if the machine supports DAC addressing, and DEV can
+ make use of it given MASK. */
+extern int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/* Convert to/from DAC dma address and struct page. */
+extern dma64_addr_t pci_dac_page_to_dma(struct pci_dev *, struct page *, unsigned long, int);
+extern struct page *pci_dac_dma_to_page(struct pci_dev *, dma64_addr_t);
+extern unsigned long pci_dac_dma_to_offset(struct pci_dev *, dma64_addr_t);
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+ /* Nothing to do. */
+}
X
X /* Return the index of the PCI controller for device PDEV. */
X extern int pci_controller_num(struct pci_dev *pdev);
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/scatterlist.h linux/include/asm-alpha/scatterlist.h
--- v2.4.12/linux/include/asm-alpha/scatterlist.h Mon Feb 7 20:09:05 2000
+++ linux/include/asm-alpha/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -1,19 +1,25 @@
X #ifndef _ALPHA_SCATTERLIST_H
X #define _ALPHA_SCATTERLIST_H
X
-#include <linux/types.h>
-
+#include <asm/page.h>
+
X struct scatterlist {
- char *address; /* Source/target vaddr. */
- char *alt_address; /* Location of actual if address is a
- dma indirect buffer, else NULL. */
- dma_addr_t dma_address;
+ /* This will disappear in 2.5.x */
+ char *address;
+
+ /* These two are only valid if ADDRESS member of this
+ struct is NULL. */
+ struct page *page;
+ unsigned int offset;
+
X unsigned int length;
- unsigned int dma_length;
+
+ dma_addr_t dma_address;
+ __u32 dma_length;
X };
X
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->dma_length)
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->dma_length)
X
X #define ISA_DMA_THRESHOLD (~0UL)
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/types.h linux/include/asm-alpha/types.h
--- v2.4.12/linux/include/asm-alpha/types.h Mon Feb 7 20:09:05 2000
+++ linux/include/asm-alpha/types.h Fri Oct 12 15:35:54 2001
@@ -47,10 +47,8 @@
X
X #define BITS_PER_LONG 64
X
-/* PCI dma addresses are 32-bits wide. Ignore PCI64 for now, since
- we'll typically be sending it all through iommu tables anyway. */
-
-typedef u32 dma_addr_t;
+typedef u64 dma_addr_t;
+typedef u64 dma64_addr_t;
X
X #endif /* __KERNEL__ */
X #endif /* _ALPHA_TYPES_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-alpha/vga.h linux/include/asm-alpha/vga.h
--- v2.4.12/linux/include/asm-alpha/vga.h Fri Mar 17 13:01:38 2000
+++ linux/include/asm-alpha/vga.h Mon Oct 15 13:47:28 2001
@@ -12,7 +12,6 @@
X #define VT_BUF_HAVE_RW
X #define VT_BUF_HAVE_MEMSETW
X #define VT_BUF_HAVE_MEMCPYW
-#define VT_BUF_HAVE_MEMCPYF
X
X extern inline void scr_writew(u16 val, volatile u16 *addr)
X {
@@ -40,8 +39,6 @@
X
X /* Do not trust that the usage will be correct; analyze the arguments. */
X extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
-#define scr_memcpyw_from scr_memcpyw
-#define scr_memcpyw_to scr_memcpyw
X
X /* ??? These are currently only used for downloading character sets. As
X such, they don't need memory barriers. Is this all they are intended
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/a.out.h linux/include/asm-arm/a.out.h
--- v2.4.12/linux/include/asm-arm/a.out.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/a.out.h Thu Oct 11 09:04:57 2001
@@ -1,6 +1,7 @@
X #ifndef __ARM_A_OUT_H__
X #define __ARM_A_OUT_H__
X
+#include <linux/personality.h>
X #include <asm/types.h>
X
X struct exec
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/SA-1111.h linux/include/asm-arm/arch-sa1100/SA-1111.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/SA-1111.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/SA-1111.h Thu Oct 11 09:04:57 2001
@@ -42,15 +42,15 @@
X * SKID ID Register
X */
X
-#define _SKCR _SA1111( 0x0000 )
-#define _SMCR _SA1111( 0x0004 )
-#define _SKID _SA1111( 0x0008 )
+#define _SBI_SKCR _SA1111( 0x0000 )
+#define _SBI_SMCR _SA1111( 0x0004 )
+#define _SBI_SKID _SA1111( 0x0008 )
X
X #if LANGUAGE == C
X
-#define SKCR (*((volatile Word *) SA1111_p2v (_SKCR)))
-#define SMCR (*((volatile Word *) SA1111_p2v (_SMCR)))
-#define SKID (*((volatile Word *) SA1111_p2v (_SKID)))
+#define SBI_SKCR (*((volatile Word *) SA1111_p2v (_SBI_SKCR)))
+#define SBI_SMCR (*((volatile Word *) SA1111_p2v (_SBI_SMCR)))
+#define SBI_SKID (*((volatile Word *) SA1111_p2v (_SBI_SKID)))
X
X #endif /* LANGUAGE == C */
X
@@ -66,6 +66,18 @@
X #define SKCR_OPPC (1<<9)
X #define SKCR_PLLTSTEN (1<<10)
X #define SKCR_USBIOTSTEN (1<<11)
+/*
+ * Don't believe the specs! Take them, throw them outside. Leave them
+ * there for a week. Spit on them. Walk on them. Stamp on them.
+ * Pour gasoline over them and finally burn them. Now think about coding.
+ * - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
+ * - The Feb 2001 errata (278260-010) says that the previous errata
+ * (278260-009) is wrong, and its bit actually 12, fixed in spec
+ * 278242-003.
+ * - The SA1111 manual (278242) says bit 12, but 0 to enable.
+ * - Reality is bit 13, 1 to enable.
+ * -- rmk
+ */
X #define SKCR_OE_EN (1<<13)
X
X #define SMCR_DTIM (1<<0)
@@ -129,6 +141,34 @@
X #define SKPCR_PTCLKEN (1<<6)
X #define SKPCR_DCLKEN (1<<7)
X #define SKPCR_PWMCLKEN (1<<8)
+
+/*
+ * USB Host controller
+ */
+#define _USB_OHCI_OP_BASE _SA1111( 0x400 )
+#define _USB_STATUS _SA1111( 0x518 )
+#define _USB_RESET _SA1111( 0x51c )
+#define _USB_INTERRUPTEST _SA1111( 0x520 )
+
+#define _USB_EXTENT (_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
+
+#if LANGUAGE == C
+
+#define USB_OHCI_OP_BASE (*((volatile Word *) SA1111_p2v (_USB_OHCI_OP_BASE)))
+#define USB_STATUS (*((volatile Word *) SA1111_p2v (_USB_STATUS)))
+#define USB_RESET (*((volatile Word *) SA1111_p2v (_USB_RESET)))
+#define USB_INTERRUPTEST (*((volatile Word *) SA1111_p2v (_USB_INTERRUPTEST)))
+
+#endif /* LANGUAGE == C */
+
+#define USB_RESET_FORCEIFRESET (1 << 0)
+#define USB_RESET_FORCEHCRESET (1 << 1)
+#define USB_RESET_CLKGENRESET (1 << 2)
+#define USB_RESET_SIMSCALEDOWN (1 << 3)
+#define USB_RESET_USBINTTEST (1 << 4)
+#define USB_RESET_SLEEPSTBYEN (1 << 5)
+#define USB_RESET_PWRSENSELOW (1 << 6)
+#define USB_RESET_PWRCTRLLOW (1 << 7)
X
X /*
X * Serial Audio Controller
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/adsbitsy.h linux/include/asm-arm/arch-sa1100/adsbitsy.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/adsbitsy.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/adsbitsy.h Thu Oct 11 09:04:57 2001
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/adsbitsy.h
+ *
+ * Created 7/3/01 by Woojung <wh...@applieddata.net>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS Bitsy Board
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define SA1111_BASE (0x18000000)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/assabet.h linux/include/asm-arm/arch-sa1100/assabet.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/assabet.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/assabet.h Thu Oct 11 09:04:57 2001
@@ -38,7 +38,7 @@
X #define BCR_DB1111 \
X (BCR_SPK_OFF | BCR_QMUTE | BCR_LED_GREEN | BCR_LED_RED | \
X BCR_RS232EN | BCR_LCD_12RGB | BCR_CF_BUS_OFF | BCR_STEREO_LB | \
- BCR_IRDA_MD1 | BCR_CF_RST)
+ BCR_IRDA_MD0 | BCR_CF_RST)
X
X #define BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */
X #define BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */
@@ -183,6 +183,10 @@
X #define NCR_A1VPP (1<<6)
X
X #ifndef __ASSEMBLY__
+#ifdef CONFIG_ASSABET_NEPONSET
X #define machine_has_neponset() ((SCR_value & SCR_SA1111) == 0)
+#else
+#define machine_has_neponset() (0)
+#endif
X #endif
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/bitsy.h linux/include/asm-arm/arch-sa1100/bitsy.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/bitsy.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/bitsy.h Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-/*
-*
-* Definitions for H3600 Handheld Computer
-*
-* Copyright 2000 Compaq Computer Corporation.
-*
-* Use consistent with the GNU GPL is permitted,
-* provided that this copyright notice is
-* preserved in its entirety in all copies and derived works.
-*
-* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-* FITNESS FOR ANY PARTICULAR PURPOSE.
-*
-* Author: Jamey Hicks.
-*
-*/
-
-#ifndef _INCLUDE_BITSY_H_
-#define _INCLUDE_BITSY_H_
-
-#define GPIO_BITSY_NPOWER_BUTTON GPIO_GPIO (0)
-#define GPIO_BITSY_ACTION_BUTTON GPIO_GPIO (18)
-
-#define GPIO_BITSY_PCMCIA_CD0 GPIO_GPIO (17)
-#define GPIO_BITSY_PCMCIA_CD1 GPIO_GPIO (10)
-#define GPIO_BITSY_PCMCIA_IRQ0 GPIO_GPIO (21)
-#define GPIO_BITSY_PCMCIA_IRQ1 GPIO_GPIO (11)
-
-/* audio sample rate clock generator */
-#define GPIO_BITSY_CLK_SET0 GPIO_GPIO (12)
-#define GPIO_BITSY_CLK_SET1 GPIO_GPIO (13)
-
-/* UDA1341 L3 Interface */
-#define GPIO_BITSY_L3_DATA GPIO_GPIO (14)
-#define GPIO_BITSY_L3_CLOCK GPIO_GPIO (16)
-#define GPIO_BITSY_L3_MODE GPIO_GPIO (15)
-
-#define GPIO_BITSY_OPT_LOCK GPIO_GPIO (22)
-#define GPIO_BITSY_OPT_IRQ GPIO_GPIO (24)
-#define GPIO_BITSY_OPT_DET GPIO_GPIO (27)
-
-#define GPIO_BITSY_COM_DCD GPIO_GPIO (23)
-#define GPIO_BITSY_COM_CTS GPIO_GPIO (25)
-#define GPIO_BITSY_COM_RTS GPIO_GPIO (26)
-
-#define IRQ_GPIO_BITSY_NPOWER_BUTTON IRQ_GPIO0
-#define IRQ_GPIO_BITSY_ACTION_BUTTON IRQ_GPIO18
-#define IRQ_GPIO_BITSY_PCMCIA_CD0 IRQ_GPIO17
-#define IRQ_GPIO_BITSY_PCMCIA_CD1 IRQ_GPIO10
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ0 IRQ_GPIO21
-#define IRQ_GPIO_BITSY_PCMCIA_IRQ1 IRQ_GPIO11
-#define IRQ_GPIO_BITSY_OPT_IRQ IRQ_GPIO24
-#define IRQ_GPIO_BITSY_OPT_DET IRQ_GPIO27
-#define IRQ_GPIO_BITSY_COM_DCD IRQ_GPIO23
-#define IRQ_GPIO_BITSY_COM_CTS IRQ_GPIO25
-
-#define EGPIO_BITSY_VPP_ON (1 << 0)
-#define EGPIO_BITSY_CARD_RESET (1 << 1) /* reset the attached pcmcia/compactflash card. active high. */
-#define EGPIO_BITSY_OPT_RESET (1 << 2) /* reset the attached option pack. active high. */
-#define EGPIO_BITSY_CODEC_NRESET (1 << 3) /* reset the onboard UDA1341. active low. */
-#define EGPIO_BITSY_OPT_NVRAM_ON (1 << 4) /* apply power to optionpack nvram, active high. */
-#define EGPIO_BITSY_OPT_ON (1 << 5) /* full power to option pack. active high. */
-#define EGPIO_BITSY_LCD_ON (1 << 6) /* enable 3.3V to LCD. active high. */
-#define EGPIO_BITSY_RS232_ON (1 << 7) /* UART3 transceiver force on. Active high. */
-#define EGPIO_BITSY_LCD_PCI (1 << 8) /* LCD control IC enable. active high. */
-#define EGPIO_BITSY_IR_ON (1 << 9) /* apply power to IR module. active high. */
-#define EGPIO_BITSY_AUD_AMP_ON (1 << 10) /* apply power to audio power amp. active high. */
-#define EGPIO_BITSY_AUD_PWR_ON (1 << 11) /* apply poewr to reset of audio circuit. active high. */
-#define EGPIO_BITSY_QMUTE (1 << 12) /* mute control for onboard UDA1341. active high. */
-#define EGPIO_BITSY_IR_FSEL (1 << 13) /* IR speed select: 1->fast, 0->slow */
-#define EGPIO_BITSY_LCD_5V_ON (1 << 14) /* enable 5V to LCD. active high. */
-#define EGPIO_BITSY_LVDD_ON (1 << 15) /* enable 9V and -6.5V to LCD. */
-
-#ifndef __ASSEMBLY__
-#define BITSY_EGPIO (*(volatile int *)0xf0000000)
-extern void clr_bitsy_egpio(unsigned long x);
-extern void set_bitsy_egpio(unsigned long x);
-#endif
-
-#endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/dma.h linux/include/asm-arm/arch-sa1100/dma.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/dma.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/dma.h Thu Oct 11 09:04:57 2001
@@ -109,8 +109,13 @@
X static inline void
X __arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
X {
- size[1] = size[0] - 256;
- size[0] = 256;
+ unsigned int sz = 256;
+
+ if (node != 0)
+ sz = 0;
+
+ size[1] = size[0] - sz;
+ size[0] = sz;
X }
X
X #define arch_adjust_zones(node,size,holes) __arch_adjust_zones(node,size,holes)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/graphicsmaster.h linux/include/asm-arm/arch-sa1100/graphicsmaster.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/graphicsmaster.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/graphicsmaster.h Thu Oct 11 09:04:57 2001
@@ -0,0 +1,66 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/graphicsmaster.h
+ *
+ * Created 2000/12/18 by Woojung Huh <wh...@applieddata.net>
+ *
+ * This file comes from graphicsclient.h of Nicolas Pitre <ni...@cam.org>
+ *
+ * This file contains the hardware specific definitions for the
+ * ADS GraphicsMaster
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error "include <asm/hardware.h> instead"
+#endif
+
+#define ADS_CPLD_BASE (0x10000000)
+#define ADS_p2v( x ) ((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x ) ((x) - 0xf0000000 + ADS_CPLD_BASE)
+
+
+#define _ADS_SW_SWITCHES 0x10060000 /* Software Switches */
+
+/* Extra IRQ Controller */
+#define _ADS_INT_ST1 0x10080000 /* IRQ Status #1 */
+#define _ADS_INT_ST2 0x10080004 /* IRQ Status #2 */
+#define _ADS_INT_EN1 0x10080008 /* IRQ Enable #1 */
+#define _ADS_INT_EN2 0x1008000c /* IRQ Enable #2 */
+#define _ADS_DCR 0x10080018 /* Discrete Control Reg */
+
+/* Discrete Controller (AVR:Atmel AT90LS8535) */
+#define _ADS_AVR_REG 0x10080018
+
+/* On-Board Ethernet */
+#define _ADS_ETHERNET 0x100e0000 /* Ethernet */
+
+/* On-Board Quad UART 16C554 */
+#define ADS_QUAD_UART1 0x10100000
+#define ADS_QUAD_UART2 0x10120000
+#define ADS_QUAD_UART3 0x10140000
+#define ADS_QUAD_UART4 0x10160000
+
+/* LEDs */
+#define ADS_LED0 GPIO_GPIO20 /* on-board Green */
+#define ADS_LED1 GPIO_GPIO25 /* on-board Yellow */
+#define ADS_LED2 GPIO_GPIO26 /* on-board Red */
+
+/* DCR */
+#define DCR_AVR_RESET 0x01
+#define DCR_SA1111_RESET 0x02
+#define DCR_BACKLITE_ON 0x04
+
+/* Virtual register addresses */
+
+#ifndef __ASSEMBLY__
+#define ADS_INT_ST1 (*((volatile u_char *) ADS_p2v(_ADS_INT_ST1)))
+#define ADS_INT_ST2 (*((volatile u_char *) ADS_p2v(_ADS_INT_ST2)))
+#define ADS_INT_EN1 (*((volatile u_char *) ADS_p2v(_ADS_INT_EN1)))
+#define ADS_INT_EN2 (*((volatile u_char *) ADS_p2v(_ADS_INT_EN2)))
+#define ADS_ETHERNET ((int) ADS_p2v(_ADS_ETHERNET))
+#define ADS_AVR_REG (*((volatile u_char *) ADS_p2v(_ADS_AVR_REG)))
+#define ADS_DCR (*((volatile u_char *) ADS_p2v(_ADS_DCR)))
+#endif
+
+#define SA1111_BASE (0x18000000)
+
+#include "SA-1111.h"
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/h3600.h linux/include/asm-arm/arch-sa1100/h3600.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/h3600.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-sa1100/h3600.h Thu Oct 11 09:04:57 2001
@@ -0,0 +1,81 @@
+/*
+*
+* Definitions for H3600 Handheld Computer
+*
+* Copyright 2000 Compaq Computer Corporation.
+*
+* Use consistent with the GNU GPL is permitted,
+* provided that this copyright notice is
+* preserved in its entirety in all copies and derived works.
+*
+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+* FITNESS FOR ANY PARTICULAR PURPOSE.
+*
+* Author: Jamey Hicks.
+*
+*/
+
+#ifndef _INCLUDE_H3600_H_
+#define _INCLUDE_H3600_H_
+
+#define GPIO_H3600_NPOWER_BUTTON GPIO_GPIO (0)
+#define GPIO_H3600_ACTION_BUTTON GPIO_GPIO (18)
+
+#define GPIO_H3600_PCMCIA_CD0 GPIO_GPIO (17)
+#define GPIO_H3600_PCMCIA_CD1 GPIO_GPIO (10)
+#define GPIO_H3600_PCMCIA_IRQ0 GPIO_GPIO (21)
+#define GPIO_H3600_PCMCIA_IRQ1 GPIO_GPIO (11)
+
+/* audio sample rate clock generator */
+#define GPIO_H3600_CLK_SET0 GPIO_GPIO (12)
+#define GPIO_H3600_CLK_SET1 GPIO_GPIO (13)
+
+/* UDA1341 L3 Interface */
+#define GPIO_H3600_L3_DATA GPIO_GPIO (14)
+#define GPIO_H3600_L3_CLOCK GPIO_GPIO (16)
+#define GPIO_H3600_L3_MODE GPIO_GPIO (15)
+
+#define GPIO_H3600_OPT_LOCK GPIO_GPIO (22)
+#define GPIO_H3600_OPT_IRQ GPIO_GPIO (24)
+#define GPIO_H3600_OPT_DET GPIO_GPIO (27)
+
+#define GPIO_H3600_COM_DCD GPIO_GPIO (23)
+#define GPIO_H3600_COM_CTS GPIO_GPIO (25)
+#define GPIO_H3600_COM_RTS GPIO_GPIO (26)
+
+#define IRQ_GPIO_H3600_NPOWER_BUTTON IRQ_GPIO0
+#define IRQ_GPIO_H3600_ACTION_BUTTON IRQ_GPIO18
+#define IRQ_GPIO_H3600_PCMCIA_CD0 IRQ_GPIO17
+#define IRQ_GPIO_H3600_PCMCIA_CD1 IRQ_GPIO10
+#define IRQ_GPIO_H3600_PCMCIA_IRQ0 IRQ_GPIO21
+#define IRQ_GPIO_H3600_PCMCIA_IRQ1 IRQ_GPIO11
+#define IRQ_GPIO_H3600_OPT_IRQ IRQ_GPIO24
+#define IRQ_GPIO_H3600_OPT_DET IRQ_GPIO27
+#define IRQ_GPIO_H3600_COM_DCD IRQ_GPIO23
+#define IRQ_GPIO_H3600_COM_CTS IRQ_GPIO25
+
+#define EGPIO_H3600_VPP_ON (1 << 0)
+#define EGPIO_H3600_CARD_RESET (1 << 1) /* reset the attached pcmcia/compactflash card. active high. */
+#define EGPIO_H3600_OPT_RESET (1 << 2) /* reset the attached option pack. active high. */
+#define EGPIO_H3600_CODEC_NRESET (1 << 3) /* reset the onboard UDA1341. active low. */
+#define EGPIO_H3600_OPT_NVRAM_ON (1 << 4) /* apply power to optionpack nvram, active high. */
+#define EGPIO_H3600_OPT_ON (1 << 5) /* full power to option pack. active high. */
+#define EGPIO_H3600_LCD_ON (1 << 6) /* enable 3.3V to LCD. active high. */
+#define EGPIO_H3600_RS232_ON (1 << 7) /* UART3 transceiver force on. Active high. */
+#define EGPIO_H3600_LCD_PCI (1 << 8) /* LCD control IC enable. active high. */
+#define EGPIO_H3600_IR_ON (1 << 9) /* apply power to IR module. active high. */
+#define EGPIO_H3600_AUD_AMP_ON (1 << 10) /* apply power to audio power amp. active high. */
+#define EGPIO_H3600_AUD_PWR_ON (1 << 11) /* apply poewr to reset of audio circuit. active high. */
+#define EGPIO_H3600_QMUTE (1 << 12) /* mute control for onboard UDA1341. active high. */
+#define EGPIO_H3600_IR_FSEL (1 << 13) /* IR speed select: 1->fast, 0->slow */
+#define EGPIO_H3600_LCD_5V_ON (1 << 14) /* enable 5V to LCD. active high. */
+#define EGPIO_H3600_LVDD_ON (1 << 15) /* enable 9V and -6.5V to LCD. */
+
+#ifndef __ASSEMBLY__
+#define H3600_EGPIO (*(volatile int *)0xf0000000)
+extern void clr_h3600_egpio(unsigned long x);
+extern void set_h3600_egpio(unsigned long x);
+#endif
+
+#endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/hardware.h linux/include/asm-arm/arch-sa1100/hardware.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/hardware.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/hardware.h Thu Oct 11 09:04:57 2001
@@ -122,8 +122,8 @@
X #include "empeg.h"
X #endif
X
-#ifdef CONFIG_SA1100_BITSY
-#include "bitsy.h"
+#ifdef CONFIG_SA1100_H3600
+#include "h3600.h"
X #endif
X
X #ifdef CONFIG_SA1100_ITSY
@@ -152,6 +152,14 @@
X
X #ifdef CONFIG_SA1100_SIMPAD
X #include "simpad.h"
+#endif
+
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#include "graphicsmaster.h"
+#endif
+
+#if defined(CONFIG_SA1100_ADSBITSY)
+#include "adsbitsy.h"
X #endif
X
X #ifdef CONFIG_SA1101
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/irqs.h linux/include/asm-arm/arch-sa1100/irqs.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/irqs.h Thu Feb 8 16:32:44 2001
+++ linux/include/asm-arm/arch-sa1100/irqs.h Thu Oct 11 09:04:57 2001
@@ -72,7 +72,7 @@
X #define NR_IRQS (IRQ_GPIO27 + 1)
X
X
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_GRAPHICSMASTER)
X #define ADS_EXT_IRQ(x) (IRQ_GPIO27 + 1 + (x))
X #undef NR_IRQS
X #define NR_IRQS (ADS_EXT_IRQ(15) + 1)
@@ -81,7 +81,11 @@
X
X #if defined(CONFIG_SA1111)
X
+#if defined(CONFIG_SA1100_GRAPHICSMASTER)
+#define SA1111_IRQ(x) (ADS_EXT_IRQ(15) + 1 + 1 + (x))
+#else
X #define SA1111_IRQ(x) (IRQ_GPIO27 + 1 + (x))
+#endif
X
X #define GPAIN0 SA1111_IRQ(0)
X #define GPAIN1 SA1111_IRQ(1)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/keyboard.h linux/include/asm-arm/arch-sa1100/keyboard.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/keyboard.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/keyboard.h Thu Oct 11 09:04:57 2001
@@ -8,11 +8,37 @@
X #define _SA1100_KEYBOARD_H
X
X #include <linux/config.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
X
+extern struct kbd_ops_struct *kbd_ops;
X
-// #ifdef CONFIG_SA1100_BRUTUS
-/* need fixing... */
-#if 0
+#define kbd_disable_irq() do { } while(0);
+#define kbd_enable_irq() do { } while(0);
+
+
+/*
+ * SA1111 keyboard driver
+ */
+extern void sa1111_kbd_init_hw(void);
+
+/*
+ * GraphicsClient keyboard driver
+ */
+extern void gc_kbd_init_hw(void);
+
+static inline void kbd_init_hw(void)
+{
+ if (machine_is_assabet() && machine_has_neponset())
+ sa1111_kbd_init_hw();
+
+ if (machine_is_graphicsclient())
+ gc_kbd_init_hw();
+}
+
+
+
+#if 0 /* Brutus needs fixing */
X
X extern int Brutus_kbd_translate(unsigned char scancode, unsigned char *keycode,
X char raw_mode);
@@ -34,7 +60,9 @@
X
X #define SYSRQ_KEY 0x54
X
-#elif CONFIG_SA1100_GRAPHICSCLIENT
+#elif 0 // CONFIG_SA1100_GRAPHICSCLIENT
+extern int gc_kbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int gc_kbd_getkeycode(unsigned int scancode);
X extern int gc_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
X extern void gc_kbd_leds(unsigned char leds);
X extern void gc_kbd_init_hw(void);
@@ -42,137 +70,17 @@
X extern void gc_kbd_disable_irq(void);
X extern unsigned char gc_kbd_sysrq_xlate[128];
X
-#define kbd_setkeycode(x...) (-ENOSYS)
-#define kbd_getkeycode(x...) (-ENOSYS)
+#define kbd_setkeycode(x...) gc_kbd_setkeycode //(-ENOSYS)
+#define kbd_getkeycode(x...) gc_kbd_getkeycode //(-ENOSYS)
X #define kbd_translate gc_kbd_translate
X #define kbd_unexpected_up(x...) (1)
X #define kbd_leds gc_kbd_leds
X #define kbd_init_hw gc_kbd_init_hw
X #define kbd_enable_irq gc_kbd_enable_irq
X #define kbd_disable_irq gc_kbd_disable_irq
-#define kbd_sysrq_xlate gc_kbd_sysrq_xlate
-
-#elif CONFIG_SA1100_BITSY
-
-#define kbd_setkeycode(x...) (-ENOSYS)
-#define kbd_getkeycode(x...) (-ENOSYS)
-#define kbd_translate(sc_,kc_,rm_) ((*(kc_)=(sc_)),1)
-#define kbd_unexpected_up(x...) (1)
-#define kbd_leds(x...) do { } while (0)
-#define kbd_init_hw(x...) do { } while (0)
-#define kbd_enable_irq(x...) do { } while (0)
-#define kbd_disable_irq(x...) do { } while (0)
-
-#elif 0 //defined(CONFIG_SA1111) /*@@@@@*/
-
-#define KEYBOARD_IRQ TPRXINT
-#define DISABLE_KBD_DURING_INTERRUPTS 0
-
-/* redefine some macros */
-#ifdef KBD_DATA_REG
-#undef KBD_DATA_REG
-#endif
-#ifdef KBD_STATUS_REG
-#undef KBD_STATUS_REG
-#endif
-#ifdef KBD_CNTL_REG
-#undef KBD_CNTL_REG
-#endif
-#define KBD_DATA_REG KBDDATA
-#define KBD_STATUS_REG KBDSTAT
-#define KBD_CNTL_REG KBDCR
-
-extern int sa1111_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int sa1111_getkeycode(unsigned int scancode);
-extern int sa1111_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode);
-extern char sa1111_unexpected_up(unsigned char keycode);
-extern void sa1111_leds(unsigned char leds);
-extern void sa1111_init_hw(void);
-extern unsigned char sa1111_sysrq_xlate[128];
-
-#define kbd_setkeycode sa1111_setkeycode
-#define kbd_getkeycode sa1111_getkeycode
-#define kbd_translate sa1111_translate
-#define kbd_unexpected_up sa1111_unexpected_up
-#define kbd_leds sa1111_leds
-#define kbd_init_hw sa1111_init_hw
-#define kbd_sysrq_xlate sa1111_sysrq_xlate
-#define kbd_disable_irq(x...) do{;}while(0)
-#define kbd_enable_irq(x...) do{;}while(0)
-
-#define SYSRQ_KEY 0x54
-
-/* resource allocation */
-#define kbd_request_region()
-#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
- "keyboard", NULL)
-
-/* How to access the keyboard macros on this platform. */
-#define kbd_read_input() (*KBDDATA & 0x00ff)
-#define kbd_read_status() (*KBDSTAT & 0x01ff)
-#define kbd_write_output(val) (*KBDDATA = (val))
-#define kbd_write_command(val) (*KBDCR = (val))
-
-/* Some stoneage hardware needs delays after some operations. */
-#define kbd_pause() do {;} while(0)
-
-/* bit definitions for some registers */
-#define KBD_CR_ENA (1<<3)
-
-#define KBD_STAT_RXB (1<<4)
-#define KBD_STAT_RXF (1<<5)
-#define KBD_STAT_TXB (1<<6)
-#define KBD_STAT_TXE (1<<7)
-#define KBD_STAT_STP (1<<8)
-
-/*
- * Machine specific bits for the PS/2 driver
- */
-
-#define AUX_IRQ MSRXINT
-
-#define aux_request_irq(hand, dev_id) \
- request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
-#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
-
-/* How to access the mouse macros on this platform. */
-#define mse_read_input() (*MSEDATA & 0x00ff)
-#define mse_read_status() (*MSESTAT & 0x01ff)
-#define mse_write_output(val) (*MSEDATA = (val))
-#define mse_write_command(val) (*MSECR = (val))
-
-/* bit definitions for some registers */
-#define MSE_CR_ENA (1<<3)
-
-#define MSE_STAT_RXB (1<<4)
-#define MSE_STAT_RXF (1<<5)
-#define MSE_STAT_TXB (1<<6)
-#define MSE_STAT_TXE (1<<7)
-#define MSE_STAT_STP (1<<8)
-
-
-#else
-
-/* dummy i.e. no real keyboard */
-#define kbd_setkeycode(x...) (-ENOSYS)
-#define kbd_getkeycode(x...) (-ENOSYS)
-#define kbd_translate(x...) (0)
-#define kbd_unexpected_up(x...) (1)
-#define kbd_leds(x...) do {;} while (0)
-#define kbd_init_hw(x...) do {;} while (0)
-#define kbd_enable_irq(x...) do {;} while (0)
-#define kbd_disable_irq(x...) do {;} while (0)
+#define kbd_sysrq_xlate (1)
X
X #endif
-
-
-/* needed if MAGIC_SYSRQ is enabled for serial console */
-#ifndef SYSRQ_KEY
-#define SYSRQ_KEY ((unsigned char)(-1))
-#define kbd_sysrq_xlate ((unsigned char *)NULL)
-#endif
-
X
X #endif /* _SA1100_KEYBOARD_H */
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/pangolin.h linux/include/asm-arm/arch-sa1100/pangolin.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/pangolin.h Thu Feb 8 16:32:44 2001
+++ linux/include/asm-arm/arch-sa1100/pangolin.h Thu Oct 11 09:04:57 2001
@@ -11,6 +11,7 @@
X #error "include <asm/hardware.h> instead"
X #endif
X
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
X
X /* GPIOs for which the generic definition doesn't say much */
X #define GPIO_CF_BUS_ON GPIO_GPIO (3)
@@ -20,3 +21,41 @@
X
X #define IRQ_GPIO_CF_IRQ IRQ_GPIO21
X #define IRQ_GPIO_CF_CD IRQ_GPIO22
+
+#else
+/*
+ * These definitions are for PCMCIA/IDE card
+ *
+ * PSKTSEL = 0 ---> PCMCIA
+ * PCMCIA_RESET = GPIO_7 ( output )( 0: normal 1: reset )
+ * PCMCIA_IRQ = GPIO_24 ( input )
+ * PCMCIA_CD = GPIO_25 ( input )
+ *
+ * PSKTSEL = 1 ---> IDE port
+ * IDE_IRQ = GPIO_23 ( input )
+ *
+ * !!WARNING!!
+ * When the PCMCIA/IDE card is inserted, the CF slot
+ * should not have any card inserted!!


+ *
+ */
+

+#define GPIO_PCMCIA_RESET GPIO_GPIO (7)
+#define GPIO_PCMCIA_IRQ GPIO_GPIO (24)
+#define GPIO_PCMCIA_CD GPIO_GPIO (25)
+#define GPIO_IDE_IRQ GPIO_GPIO (8)
+
+#define IRQ_PCMCIA_IRQ IRQ_GPIO24
+#define IRQ_PCMCIA_CD IRQ_GPIO25
+#define IRQ_IDE_IRQ IRQ_GPIO8
+
+#endif
+
+/*
+ * On board LAN chip
+ */
+#define PANGOLIN_LAN_ADDR 0x32000000
+#define PANGOLIN_LAN_RESET GPIO_GPIO (8)
+#define PANGOLIN_LAN_IRQ GPIO_GPIO (26)
+#define PANGOLIN_IRQ_LAN_IRQ IRQ_GPIO26
+
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/arch-sa1100/uncompress.h linux/include/asm-arm/arch-sa1100/uncompress.h
--- v2.4.12/linux/include/asm-arm/arch-sa1100/uncompress.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/arch-sa1100/uncompress.h Thu Oct 11 09:04:57 2001
@@ -3,23 +3,16 @@
X *
X * (C) 1999 Nicolas Pitre <ni...@cam.org>
X *
- * Reorganised to use machine_is_*() macros.
+ * Reorganised to be machine independent.
X */
X
X #include "hardware.h"
X
-#include <asm/mach-types.h>
-
-/* Assabet's Status Control "Register" */
-unsigned long SCR_value;
-
-/* sa1100_setup() will perform any special initialization for UART, etc. */
-extern void sa1100_setup( int arch_id );
-#define arch_decomp_setup() sa1100_setup(arch_id)
-
X /*
X * The following code assumes the serial port has already been
- * initialized by the bootloader or such...
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
X */
X
X #define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
@@ -28,22 +21,15 @@
X {
X unsigned long serial_port;
X
- if (machine_is_assabet()) {
- if( machine_has_neponset() )
- serial_port = _Ser3UTCR0;
- else
- serial_port = _Ser1UTCR0;
- } else if (machine_is_brutus()||machine_is_nanoengine() ||
- machine_is_pangolin() || machine_is_freebird() ||
- machine_is_pfs168() || machine_is_flexanet())
- serial_port = _Ser1UTCR0;
- else if (machine_is_empeg() || machine_is_bitsy() ||
- machine_is_victor() || machine_is_lart() ||
- machine_is_sherman() || machine_is_yopy() ||
- machine_is_huw_webpanel() || machine_is_itsy() )
+ do {
X serial_port = _Ser3UTCR0;
- else
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser1UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser2UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
X return;
+ } while (0);
X
X for (; *s; s++) {
X /* wait for space in the UART's transmiter */
@@ -63,4 +49,5 @@
X /*
X * Nothing to do for these
X */
+#define arch_decomp_setup()
X #define arch_decomp_wdog()
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/atomic.h linux/include/asm-arm/atomic.h
--- v2.4.12/linux/include/asm-arm/atomic.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/atomic.h Thu Oct 11 09:04:57 2001
@@ -22,11 +22,7 @@
X #error SMP not supported
X #endif
X
-#ifdef CONFIG_ARCH_CO285
X typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
X
X #define ATOMIC_INIT(i) { (i) }
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/cpu-multi32.h linux/include/asm-arm/cpu-multi32.h
--- v2.4.12/linux/include/asm-arm/cpu-multi32.h Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/cpu-multi32.h Thu Oct 11 09:04:57 2001
@@ -9,6 +9,7 @@
X */
X #ifndef __ASSEMBLY__
X
+#include <asm/memory.h>
X #include <asm/page.h>
X
X /* forward-declare task_struct */
@@ -155,5 +156,14 @@
X #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)))
+
+#define cpu_get_pgd() \
+ ({ \
+ unsigned long pg; \
+ __asm__("mrc p15, 0, %0, c2, c0, 0" \
+ : "=r" (pg)); \
+ pg &= ~0x3fff; \
+ (pgd_t *)phys_to_virt(pg); \
+ })
X
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/cpu-single.h linux/include/asm-arm/cpu-single.h
--- v2.4.12/linux/include/asm-arm/cpu-single.h Mon Sep 18 15:15:23 2000
+++ linux/include/asm-arm/cpu-single.h Thu Oct 11 09:04:57 2001
@@ -51,6 +51,7 @@
X
X #ifndef __ASSEMBLY__
X
+#include <asm/memory.h>
X #include <asm/page.h>
X
X /* forward declare task_struct */
@@ -85,5 +86,14 @@
X extern volatile void cpu_reset(unsigned long addr);
X
X #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
+
+#define cpu_get_pgd() \
+ ({ \
+ unsigned long pg; \
+ __asm__("mrc p15, 0, %0, c2, c0, 0" \
+ : "=r" (pg)); \
+ pg &= ~0x3fff; \
+ (pgd_t *)phys_to_virt(pg); \
+ })
X
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/hardirq.h linux/include/asm-arm/hardirq.h
--- v2.4.12/linux/include/asm-arm/hardirq.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/hardirq.h Thu Oct 11 09:04:57 2001
@@ -2,6 +2,7 @@
X #define __ASM_HARDIRQ_H
X
X #include <linux/config.h>
+#include <linux/cache.h>
X #include <linux/threads.h>
X
X /* softirq.h is sensitive to the offsets of these fields */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/hardware/pci_v3.h linux/include/asm-arm/hardware/pci_v3.h
--- v2.4.12/linux/include/asm-arm/hardware/pci_v3.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/hardware/pci_v3.h Thu Oct 11 09:04:57 2001
@@ -102,6 +102,10 @@
X
X /* PCI_CFG bits
X */
+#define V3_PCI_CFG_M_I2O_EN (1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS (1 << 14)
+#define V3_PCI_CFG_M_IO_DIS (1 << 13)
+#define V3_PCI_CFG_M_EN3V (1 << 12)
X #define V3_PCI_CFG_M_RETRY_EN (1 << 10)
X #define V3_PCI_CFG_M_AD_LOW1 (1 << 9)
X #define V3_PCI_CFG_M_AD_LOW0 (1 << 8)
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/io.h linux/include/asm-arm/io.h
--- v2.4.12/linux/include/asm-arm/io.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/io.h Thu Oct 11 09:04:57 2001
@@ -72,18 +72,22 @@
X #include <asm/arch/io.h>
X
X /*
- * IO definitions. We define {out,in,outs,ins}[bwl] if __io is
- * defined by the machine. Otherwise, these definitions are left
- * for the machine specific header files to pick up.
+ * IO definitions. We define {out,in,outs,ins}[bwl] if __io is defined
+ * by the machine. Otherwise, these definitions are left for the machine
+ * specific header files to pick up.
+ *
+ * Note that we prevent GCC re-ordering or caching values in expressions
+ * by introducing sequence points into the in*() definitions. Note that
+ * __raw_* do not guarantee this behaviour.
X */
X #ifdef __io
X #define outb(v,p) __raw_writeb(v,__io(p))
X #define outw(v,p) __raw_writew(v,__io(p))
X #define outl(v,p) __raw_writel(v,__io(p))
X
-#define inb(p) __raw_readb(__io(p))
-#define inw(p) __raw_readw(__io(p))
-#define inl(p) __raw_readl(__io(p))
+#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
+#define inw(p) ({ unsigned int __v = __raw_readw(__io(p)); __v; })
+#define inl(p) ({ unsigned int __v = __raw_readl(__io(p)); __v; })
X
X #define outsb(p,d,l) __raw_writesb(__io(p),d,l)
X #define outsw(p,d,l) __raw_writesw(__io(p),d,l)
@@ -168,9 +172,10 @@
X */
X #ifdef __mem_pci
X
-#define readb(addr) __raw_readb(__mem_pci(addr))
-#define readw(addr) __raw_readw(__mem_pci(addr))
-#define readl(addr) __raw_readl(__mem_pci(addr))
+#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
+#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
+#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
+
X #define writeb(val,addr) __raw_writeb(val,__mem_pci(addr))
X #define writew(val,addr) __raw_writew(val,__mem_pci(addr))
X #define writel(val,addr) __raw_writel(val,__mem_pci(addr))
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/mach/arch.h linux/include/asm-arm/mach/arch.h
--- v2.4.12/linux/include/asm-arm/mach/arch.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/mach/arch.h Thu Oct 11 09:04:57 2001
@@ -27,7 +27,8 @@
X unsigned int nr; /* architecture number */
X unsigned int phys_ram; /* start of physical ram */
X unsigned int phys_io; /* start of physical io */
- unsigned int virt_io; /* start of virtual io */
+ unsigned int io_pg_offst; /* byte offset for io
+ * page tabe entry */
X
X const char *name; /* architecture name */
X unsigned int param_offset; /* parameter page */
@@ -59,9 +60,9 @@
X #define MAINTAINER(n)
X
X #define BOOT_MEM(_pram,_pio,_vio) \
- phys_ram: _pram, \
- phys_io: _pio, \
- virt_io: _vio,
+ phys_ram: _pram, \
+ phys_io: _pio, \
+ io_pg_offst: ((_vio)>>18)&0xfffc,
X
X #define BOOT_PARAMS(_params) \
X param_offset: _params,
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/param.h linux/include/asm-arm/param.h
--- v2.4.12/linux/include/asm-arm/param.h Tue Mar 6 19:44:35 2001
+++ linux/include/asm-arm/param.h Thu Oct 11 09:04:57 2001
@@ -16,6 +16,9 @@
X #ifndef HZ
X #define HZ 100
X #endif
+#if defined(__KERNEL__) && (HZ == 100)
+#define hz_to_std(a) (a)
+#endif
X
X #ifndef NGROUPS
X #define NGROUPS 32
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/pci.h linux/include/asm-arm/pci.h
--- v2.4.12/linux/include/asm-arm/pci.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/pci.h Fri Oct 12 15:35:54 2001
@@ -44,7 +44,6 @@
X consistent_free(vaddr, size, dma_handle);
X }
X
-#if !defined(CONFIG_SA1111)
X /* Map a single buffer of the indicated size for DMA in streaming mode.
X * The 32-bit bus address to use is returned.
X *
@@ -54,6 +53,17 @@
X static inline dma_addr_t
X pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
X {
+#ifdef CONFIG_SA1111
+ extern dma_addr_t sa1111_map_single(struct pci_dev *, void *, size_t, int);
+
+ /*
+ * for SA1111 these functions are "magic" and relocate buffers. We
+ * only need to do these if hwdev is non-null; otherwise we expect
+ * the buffer to already be suitable for DMA.
+ */
+ if (hwdev != NULL)
+ return sa1111_map_single(hwdev, ptr, size, direction);
+#endif
X consistent_sync(ptr, size, direction);
X return virt_to_bus(ptr);
X }
@@ -68,16 +78,14 @@
X static inline void
X pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
X {
+#ifdef CONFIG_SA1111
+ extern void sa1111_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
+
+ if (hwdev != NULL)
+ sa1111_unmap_single(hwdev, dma_addr, size, direction);
+#endif
X /* nothing to do */
X }
-#else
-/* for SA1111 these functions are "magic" and relocate buffers */
-extern dma_addr_t pci_map_single(struct pci_dev *hwdev,
- void *ptr, size_t size, int direction);
-extern void pci_unmap_single(struct pci_dev *hwdev,
- dma_addr_t dma_addr,
- size_t size, int direction);
-#endif
X
X /* Map a set of buffers described by scatterlist in streaming
X * mode for DMA. This is the scather-gather version of the
@@ -152,7 +160,7 @@
X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */
-static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)


X {
X return 1;
X }

diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
--- v2.4.12/linux/include/asm-arm/pgtable.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/pgtable.h Thu Oct 11 09:04:57 2001


@@ -175,6 +175,8 @@
X

X #include <asm-generic/pgtable.h>
X
+extern void pgtable_cache_init(void);
+
X #endif /* !__ASSEMBLY__ */
X
X #endif /* _ASMARM_PGTABLE_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- v2.4.12/linux/include/asm-arm/processor.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-arm/processor.h Thu Oct 11 09:04:57 2001
@@ -68,6 +68,13 @@
X EXTRA_THREAD_STRUCT
X };
X
+#define INIT_MMAP { \
+ vm_mm: &init_mm, \
+ vm_page_prot: PAGE_SHARED, \
+ vm_flags: VM_READ | VM_WRITE | VM_EXEC, \
+ vm_avl_height: 1, \
+}
+
X #define INIT_THREAD { \
X refcount: ATOMIC_INIT(1), \
X EXTRA_THREAD_STRUCT_INIT \
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/scatterlist.h linux/include/asm-arm/scatterlist.h
--- v2.4.12/linux/include/asm-arm/scatterlist.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -5,7 +5,6 @@
X
X struct scatterlist {
X char *address; /* virtual address */
- char *alt_address; /* indirect dma address, or NULL */
X dma_addr_t dma_address; /* dma address */
X unsigned int length; /* length */
X };
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/setup.h linux/include/asm-arm/setup.h
--- v2.4.12/linux/include/asm-arm/setup.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/setup.h Thu Oct 11 09:04:57 2001


@@ -126,7 +126,7 @@
X

X struct tag_ramdisk {
X u32 flags; /* bit 0 = load, bit 1 = prompt */
- u32 size; /* decompressed ramdisk size */
+ u32 size; /* decompressed ramdisk size in _kilo_ bytes */
X u32 start; /* starting block of floppy-based RAM disk image */
X };
X

@@ -135,7 +135,7 @@
X

X struct tag_initrd {
X u32 start; /* physical start address */
- u32 size; /* size of compressed ramdisk image */
+ u32 size; /* size of compressed ramdisk image in bytes */
X };
X
X /* board serial number. "64 bits should be enough for everybody" */
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/signal.h linux/include/asm-arm/signal.h
--- v2.4.12/linux/include/asm-arm/signal.h Thu Nov 18 19:37:03 1999
+++ linux/include/asm-arm/signal.h Thu Oct 11 09:04:57 2001
@@ -75,13 +75,16 @@
X /*
X * SA_FLAGS values:
X *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
+ * is running in 26-bit.
+ * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_RESETHAND clears the handler when the signal is delivered.
X *
X * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
X * Unix names RESETHAND and NODEFER respectively.
@@ -89,6 +92,8 @@
X #define SA_NOCLDSTOP 0x00000001
X #define SA_NOCLDWAIT 0x00000002 /* not supported yet */
X #define SA_SIGINFO 0x00000004
+#define SA_THIRTYTWO 0x02000000
+#define SA_RESTORER 0x04000000
X #define SA_ONSTACK 0x08000000
X #define SA_RESTART 0x10000000
X #define SA_NODEFER 0x40000000
@@ -98,9 +103,6 @@
X #define SA_ONESHOT SA_RESETHAND
X #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
X
-#define SA_RESTORER 0x04000000
-#define SA_THIRTYTWO 0x02000000 /* deliver signal in 32-bit mode even if
- task is running 26 bits. */
X
X /*
X * sigaltstack controls
diff -u --recursive --new-file v2.4.12/linux/include/asm-arm/uaccess.h linux/include/asm-arm/uaccess.h
--- v2.4.12/linux/include/asm-arm/uaccess.h Mon Aug 27 12:41:47 2001
+++ linux/include/asm-arm/uaccess.h Thu Oct 11 09:04:57 2001
@@ -63,11 +63,81 @@
X * error occurs, and leave it unchanged on success. Note that these
X * versions are void (ie, don't return a value as such).
X */
-#define get_user(x,p) __get_user_check((x),(p),sizeof(*(p)))
+
+extern int __get_user_1(void *);
+extern int __get_user_2(void *);
+extern int __get_user_4(void *);
+extern int __get_user_8(void *);
+extern int __get_user_bad(void);
+
+#define __get_user_x(__r1,__p,__e,__s,__i...) \
+ __asm__ __volatile__ ("bl __get_user_" #__s \
+ : "=&r" (__e), "=r" (__r1) \
+ : "0" (__p) \
+ : __i)
+
+#define get_user(x,p) \
+ ({ \
+ const register typeof(*(p)) *__p asm("r0") = (p); \
+ register typeof(*(p)) __r1 asm("r1"); \
+ register int __e asm("r0"); \
+ switch (sizeof(*(p))) { \
+ case 1: \
+ __get_user_x(__r1, __p, __e, 1, "lr"); \
+ break; \
+ case 2: \
+ __get_user_x(__r1, __p, __e, 2, "r2", "lr"); \
+ break; \
+ case 4: \
+ __get_user_x(__r1, __p, __e, 4, "lr"); \
+ break; \
+ case 8: \
+ __get_user_x(__r1, __p, __e, 8, "lr"); \
+ break; \
+ default: __e = __get_user_bad(); break; \
+ } \
+ x = __r1; \
+ __e; \
+ })
+
X #define __get_user(x,p) __get_user_nocheck((x),(p),sizeof(*(p)))
X #define __get_user_error(x,p,e) __get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
X
-#define put_user(x,p) __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
+extern int __put_user_1(void *, unsigned int);
+extern int __put_user_2(void *, unsigned int);
+extern int __put_user_4(void *, unsigned int);
+extern int __put_user_8(void *, unsigned long long);
+extern int __put_user_bad(void);
+
+#define __put_user_x(__r1,__p,__e,__s,__i...) \
+ __asm__ __volatile__ ("bl __put_user_" #__s \
+ : "=&r" (__e) \
+ : "0" (__p), "r" (__r1) \
+ : __i)
+
+#define put_user(x,p) \
+ ({ \
+ const register typeof(*(p)) *__p asm("r0") = (p); \
+ const register typeof(*(p)) __r1 asm("r1") = (x); \
+ register int __e asm("r0"); \
+ switch (sizeof(*(p))) { \
+ case 1: \
+ __put_user_x(__r1, __p, __e, 1, "r2", "lr"); \
+ break; \
+ case 2: \
+ __put_user_x(__r1, __p, __e, 2, "r2", "lr"); \
+ break; \
+ case 4: \
+ __put_user_x(__r1, __p, __e, 4, "r2", "lr"); \
+ break; \
+ case 8: \
+ __put_user_x(__r1, __p, __e, 8, "ip", "lr"); \
+ break; \
+ default: __e = __put_user_bad(); break; \
+ } \
+ __e; \
+ })
+
X #define __put_user(x,p) __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
X #define __put_user_error(x,p,e) __put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
X
@@ -142,6 +212,7 @@
X /*
X * These are the work horses of the get/put_user functions
X */
+#if 0
X #define __get_user_check(x,ptr,size) \
X ({ \
X long __gu_err = -EFAULT, __gu_val = 0; \
@@ -153,6 +224,7 @@
X (x) = (__typeof__(*(ptr)))__gu_val; \
X __gu_err; \
X })
+#endif
X
X #define __get_user_nocheck(x,ptr,size) \
X ({ \
@@ -195,8 +267,6 @@
X (void) 0; \
X })
X
-extern long __get_user_bad(void);
-
X #define __get_user_size(x,ptr,size,retval) \
X do { \
X switch (size) { \
@@ -206,8 +276,6 @@
X default: (x) = __get_user_bad(); \
X } \
X } while (0)
-
-extern long __put_user_bad(void);
X
X #define __put_user_size(x,ptr,size,retval) \
X do { \
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/page.h linux/include/asm-i386/page.h
--- v2.4.12/linux/include/asm-i386/page.h Thu Oct 18 13:47:37 2001
+++ linux/include/asm-i386/page.h Tue Oct 23 21:59:05 2001


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

X #include <asm/mmx.h>
X
-#define clear_page(page) mmx_clear_page(page)
+#define clear_page(page) mmx_clear_page((void *)(page))
X #define copy_page(to,from) mmx_copy_page(to,from)
X
X #else
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/pci.h linux/include/asm-i386/pci.h
--- v2.4.12/linux/include/asm-i386/pci.h Thu Oct 18 13:48:29 2001
+++ linux/include/asm-i386/pci.h Tue Oct 23 22:00:02 2001
@@ -34,6 +34,12 @@
X
X struct pci_dev;
X
+/* The PCI address space does equal the physical memory
+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
X /* Allocate and map kernel buffer using consistent mode DMA for a device.
X * hwdev should be valid struct pci_dev pointer for PCI devices,
X * NULL for PCI-like buses (ISA, EISA).
@@ -84,6 +90,27 @@
X /* Nothing to do */
X }
X
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+ unsigned long offset, size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ return (page - mem_map) * PAGE_SIZE + offset;
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+ size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+ /* Nothing to do */
+}
+
X /* Map a set of buffers described by scatterlist in streaming
X * mode for DMA. This is the scather-gather version of the
X * above pci_map_single interface. Here the scatter gather list
@@ -102,8 +129,26 @@
X static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
X int nents, int direction)
X {
+ int i;
+
X if (direction == PCI_DMA_NONE)
X BUG();
+
+ /*
+ * temporary 2.4 hack
+ */
+ for (i = 0; i < nents; i++ ) {
+ if (sg[i].address && sg[i].page)
+ BUG();
+ else if (!sg[i].address && !sg[i].page)
+ BUG();
+
+ if (sg[i].address)
+ sg[i].dma_address = virt_to_bus(sg[i].address);
+ else
+ sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
+ }
+
X return nents;
X }
X
@@ -157,7 +202,7 @@
X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */
-static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
X {
X /*
X * we fall back to GFP_DMA when the mask isn't all 1s,
@@ -170,13 +215,42 @@


X return 1;
X }
X

+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask) (1)
+
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{
+ return ((dma64_addr_t) page_to_bus(page) +
+ (dma64_addr_t) offset);
+}
+
+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ unsigned long poff = (dma_addr >> PAGE_SHIFT);
+
+ return mem_map + poff;
+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+ /* Nothing to do. */
+}
+
X /* These macros should be used after a pci_map_sg call has been done
X * to get bus addresses of each of the SG entries and their lengths.
X * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
+ * returns.
X */
-#define sg_dma_address(sg) (virt_to_bus((sg)->address))
+#define sg_dma_address(sg) ((sg)->dma_address)
X #define sg_dma_len(sg) ((sg)->length)
X
X /* Return the index of the PCI controller for device. */
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/scatterlist.h linux/include/asm-i386/scatterlist.h
--- v2.4.12/linux/include/asm-i386/scatterlist.h Mon Dec 30 03:01:10 1996
+++ linux/include/asm-i386/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -2,9 +2,12 @@
X #define _I386_SCATTERLIST_H
X
X struct scatterlist {
- char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
+ char * address; /* Location data is to be transferred to, NULL for
+ * highmem page */
+ struct page * page; /* Location for highmem page, if any */
+ unsigned int offset;/* for highmem, page offset */
+
+ dma_addr_t dma_address;
X unsigned int length;
X };
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.4.12/linux/include/asm-i386/smp.h Thu Oct 18 13:47:38 2001
+++ linux/include/asm-i386/smp.h Tue Oct 23 21:59:06 2001
@@ -109,7 +109,7 @@
X return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID));
X }
X
-extern __inline int logical_smp_processor_id(void)
+static __inline int logical_smp_processor_id(void)
X {
X /* we don't want to mark this access volatile - bad code generation */
X return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v2.4.12/linux/include/asm-i386/system.h Thu Oct 18 13:47:37 2001
+++ linux/include/asm-i386/system.h Tue Oct 23 21:59:05 2001
@@ -281,10 +281,19 @@
X * I expect future Intel CPU's to have a weaker ordering,
X * but I'd also expect them to finally get their act together
X * and add some real memory barriers if so.
+ *
+ * Some non intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
X */
+
X #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
X #define rmb() mb()
+
+#ifdef CONFIG_X86_OOSTORE
+#define wmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#else
X #define wmb() __asm__ __volatile__ ("": : :"memory")
+#endif
X
X #ifdef CONFIG_SMP
X #define smp_mb() mb()
@@ -339,5 +348,7 @@
X #define HAVE_DISABLE_HLT
X void disable_hlt(void);
X void enable_hlt(void);
+
+extern int is_sony_vaio_laptop;
X
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/types.h linux/include/asm-i386/types.h
--- v2.4.12/linux/include/asm-i386/types.h Thu Jan 27 08:58:15 2000
+++ linux/include/asm-i386/types.h Fri Oct 12 15:35:54 2001
@@ -27,6 +27,8 @@
X */
X #ifdef __KERNEL__
X
+#include <linux/config.h>
+
X typedef signed char s8;
X typedef unsigned char u8;
X
@@ -41,9 +43,14 @@
X
X #define BITS_PER_LONG 32
X
-/* Dma addresses are 32-bits wide. */
+/* DMA addresses come in generic and 64-bit flavours. */
X
+#ifdef CONFIG_HIGHMEM
+typedef u64 dma_addr_t;
+#else
X typedef u32 dma_addr_t;
+#endif
+typedef u64 dma64_addr_t;
X
X #endif /* __KERNEL__ */
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.4.12/linux/include/asm-i386/unistd.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-i386/unistd.h Wed Oct 17 10:03:03 2001
@@ -229,6 +229,7 @@
X #define __NR_fcntl64 221
X #define __NR_security 223 /* syscall for security modules */
X #define __NR_gettid 224
+#define __NR_readahead 225
X
X /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-ia64/pci.h linux/include/asm-ia64/pci.h
--- v2.4.12/linux/include/asm-ia64/pci.h Wed May 16 10:31:27 2001
+++ linux/include/asm-ia64/pci.h Fri Oct 12 15:35:54 2001


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 48'
echo 'File patch-2.4.13 is continued in part 49'
echo "49" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:19 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part49

#!/bin/sh -x
# this is part 49 of a 53 - part archive


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

if test "$Scheck" != 49; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

@@ -52,7 +52,7 @@


X * you would pass 0x00ffffff as the mask to this function.
X */

X static inline int
-pci_dma_supported (struct pci_dev *hwdev, dma_addr_t mask)
+pci_dma_supported (struct pci_dev *hwdev, u64 mask)


X {
X return 1;
X }

diff -u --recursive --new-file v2.4.12/linux/include/asm-ia64/scatterlist.h linux/include/asm-ia64/scatterlist.h
--- v2.4.12/linux/include/asm-ia64/scatterlist.h Fri Aug 11 19:09:06 2000
+++ linux/include/asm-ia64/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -8,11 +8,6 @@
X
X struct scatterlist {
X char *address; /* location data is to be transferred to */
- /*
- * Location of actual buffer if ADDRESS points to a DMA
- * indirection buffer, NULL otherwise:
- */
- char *alt_address;
X char *orig_address; /* Save away the original buffer address (used by pci-dma.c) */
X unsigned int length; /* buffer length */
X };
diff -u --recursive --new-file v2.4.12/linux/include/asm-m68k/scatterlist.h linux/include/asm-m68k/scatterlist.h
--- v2.4.12/linux/include/asm-m68k/scatterlist.h Tue May 11 09:57:14 1999
+++ linux/include/asm-m68k/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */


- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

X unsigned int length;
X unsigned long dvma_address;
X };
diff -u --recursive --new-file v2.4.12/linux/include/asm-mips/pci.h linux/include/asm-mips/pci.h
--- v2.4.12/linux/include/asm-mips/pci.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-mips/pci.h Fri Oct 12 15:35:54 2001
@@ -215,7 +215,7 @@


X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */

-extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)


X {
X /*
X * we fall back to GFP_DMA when the mask isn't all 1s,

diff -u --recursive --new-file v2.4.12/linux/include/asm-mips/scatterlist.h linux/include/asm-mips/scatterlist.h
--- v2.4.12/linux/include/asm-mips/scatterlist.h Tue Dec 16 12:46:12 1997
+++ linux/include/asm-mips/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */


- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

X unsigned int length;
X

X __u32 dvma_address;
diff -u --recursive --new-file v2.4.12/linux/include/asm-mips64/pci.h linux/include/asm-mips64/pci.h
--- v2.4.12/linux/include/asm-mips64/pci.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-mips64/pci.h Fri Oct 12 15:35:54 2001
@@ -220,7 +220,7 @@
X }
X #endif /* CONFIG_MAPPED_PCI_IO */
X

-static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
X {
X /*
X * we fall back to GFP_DMA when the mask isn't all 1s,

diff -u --recursive --new-file v2.4.12/linux/include/asm-mips64/scatterlist.h linux/include/asm-mips64/scatterlist.h
--- v2.4.12/linux/include/asm-mips64/scatterlist.h Thu Feb 24 22:53:35 2000
+++ linux/include/asm-mips64/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */


- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

X unsigned int length;
X

X __u32 dvma_address;
diff -u --recursive --new-file v2.4.12/linux/include/asm-parisc/pci.h linux/include/asm-parisc/pci.h
--- v2.4.12/linux/include/asm-parisc/pci.h Wed May 16 10:31:27 2001
+++ linux/include/asm-parisc/pci.h Fri Oct 12 15:35:54 2001
@@ -113,7 +113,7 @@
X ** See Documentation/DMA-mapping.txt
X */
X struct pci_dma_ops {
- int (*dma_supported)(struct pci_dev *dev, dma_addr_t mask);
+ int (*dma_supported)(struct pci_dev *dev, u64 mask);
X void *(*alloc_consistent)(struct pci_dev *dev, size_t size, dma_addr_t *iova);
X void (*free_consistent)(struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t iova);
X dma_addr_t (*map_single)(struct pci_dev *dev, void *addr, size_t size, int direction);
diff -u --recursive --new-file v2.4.12/linux/include/asm-parisc/scatterlist.h linux/include/asm-parisc/scatterlist.h
--- v2.4.12/linux/include/asm-parisc/scatterlist.h Tue Dec 5 12:29:39 2000
+++ linux/include/asm-parisc/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */


- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

X unsigned int length;
X

X /* an IOVA can be 64-bits on some PA-Risc platforms. */
diff -u --recursive --new-file v2.4.12/linux/include/asm-ppc/pci.h linux/include/asm-ppc/pci.h
--- v2.4.12/linux/include/asm-ppc/pci.h Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/pci.h Sun Oct 21 10:13:07 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.pci.h 1.12 05/21/01 01:31:30 cort
+ * BK Id: SCCS/s.pci.h 1.16 10/15/01 22:51:33 paulus
X */
X #ifndef __PPC_PCI_H
X #define __PPC_PCI_H
@@ -41,7 +41,7 @@
X extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr);
X extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
X
-/* Dynamic DMA Mapping stuff
+/* Dynamic DMA Mapping stuff, stolen from i386
X * ++ajoshi
X */
X
@@ -53,39 +53,139 @@


X
X struct pci_dev;
X
+/* The PCI address space does equal the physical memory
+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+

+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
X extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
X dma_addr_t *dma_handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
X extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
X void *vaddr, dma_addr_t dma_handle);
-extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
X size_t size, int direction)
X {


X if (direction == PCI_DMA_NONE)
X BUG();

X return virt_to_bus(ptr);
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 if (direction == PCI_DMA_NONE)
X BUG();

X /* nothing to do */
X }

-extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+
+
+/*


+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+ unsigned long offset, size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();

+ return (page - mem_map) * PAGE_SIZE + PCI_DRAM_OFFSET + offset;


+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+ size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+ /* Nothing to do */
+}
+

+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,


X int nents, int direction)
X {
+ int i;
+
X if (direction == PCI_DMA_NONE)
X BUG();
+
+ /*
+ * temporary 2.4 hack
+ */
+ for (i = 0; i < nents; i++) {
+ if (sg[i].address && sg[i].page)
+ BUG();
+ else if (!sg[i].address && !sg[i].page)
+ BUG();
+
+ if (sg[i].address)
+ sg[i].dma_address = virt_to_bus(sg[i].address);
+ else
+ sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
+ }
+
X return nents;
X }

-extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,


X int nents, int direction)
X {

X if (direction == PCI_DMA_NONE)
X BUG();

X /* nothing to do */
X }

-extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
X dma_addr_t dma_handle,
X size_t size, int direction)
X {
@@ -94,7 +194,13 @@


X /* nothing to do */
X }

X
-extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
X struct scatterlist *sg,
X int nelems, int direction)
X {
@@ -108,11 +214,49 @@


X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */

-extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)


+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
X {
X return 1;
X }

X
+/*
+ * At present there are very few 32-bit PPC machines that can have
+ * memory above the 4GB point, and we don't support that.
+ */
+#define pci_dac_dma_supported(pci_dev, mask) (0)


+
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{

+ return (dma64_addr_t) page_to_bus(page) + offset;
+}
+


+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{

+ return mem_map + (unsigned long)(dma_addr >> PAGE_SHIFT);


+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+ /* Nothing to do. */
+}
+

+/* These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns.
+ */
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+


X /* Return the index of the PCI controller for device PDEV. */
X extern int pci_controller_num(struct pci_dev *pdev);

X
@@ -122,9 +266,6 @@
X
X /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
X #define HAVE_PCI_MMAP 1
-
-#define sg_dma_address(sg) (virt_to_bus((sg)->address))
-#define sg_dma_len(sg) ((sg)->length)
X

X #endif /* __KERNEL__ */
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-ppc/ppcboot.h linux/include/asm-ppc/ppcboot.h
--- v2.4.12/linux/include/asm-ppc/ppcboot.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ppc/ppcboot.h Mon Oct 15 13:35:26 2001
@@ -69,7 +69,7 @@
X unsigned long bi_vco; /* VCO Out from PLL, in MHz */
X #endif
X unsigned long bi_baudrate; /* Console Baudrate */
-#if defined(CONFIG_PPC405)
+#if defined(CONFIG_405GP)
X unsigned char bi_s_version[4]; /* Version of this structure */
X unsigned char bi_r_version[32]; /* Version of the ROM (IBM) */
X unsigned int bi_procfreq; /* CPU (Internal) Freq, in Hz */
diff -u --recursive --new-file v2.4.12/linux/include/asm-ppc/scatterlist.h linux/include/asm-ppc/scatterlist.h
--- v2.4.12/linux/include/asm-ppc/scatterlist.h Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/scatterlist.h Sun Oct 21 10:13:07 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.scatterlist.h 1.5 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.scatterlist.h 1.9 10/15/01 22:51:33 paulus


X */
X #ifdef __KERNEL__

X #ifndef _PPC_SCATTERLIST_H
@@ -8,12 +8,24 @@
X #include <asm/dma.h>


X
X struct scatterlist {
- char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

- unsigned int length;
+ char *address; /* Location data is to be transferred to,
+ * or NULL for highmem page */


+ struct page * page; /* Location for highmem page, if any */
+ unsigned int offset; /* for highmem, page offset */
+

+ dma_addr_t dma_address; /* phys/bus dma address */
+ unsigned int length; /* length */
X };
X
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
X
X #endif /* !(_PPC_SCATTERLIST_H) */


X #endif /* __KERNEL__ */

diff -u --recursive --new-file v2.4.12/linux/include/asm-ppc/types.h linux/include/asm-ppc/types.h
--- v2.4.12/linux/include/asm-ppc/types.h Mon Aug 27 12:41:48 2001
+++ linux/include/asm-ppc/types.h Sun Oct 21 10:13:07 2001
@@ -1,5 +1,5 @@
X /*
- * BK Id: SCCS/s.types.h 1.8 07/07/01 13:37:26 paulus
+ * BK Id: SCCS/s.types.h 1.10 10/15/01 22:51:33 paulus
X */
X #ifndef _PPC_TYPES_H
X #define _PPC_TYPES_H
@@ -46,6 +46,7 @@
X
X /* DMA addresses are 32-bits wide */
X typedef u32 dma_addr_t;


+typedef u64 dma64_addr_t;
X
X #endif /* __KERNEL__ */
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/chandev.h linux/include/asm-s390/chandev.h
--- v2.4.12/linux/include/asm-s390/chandev.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/chandev.h Thu Oct 11 09:43:38 2001
@@ -139,6 +139,10 @@
X * not operational the previous status is sent in the prevstatus variable.
X * This can be used in cases when the default handling isn't quite adequete
X * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
X */
X int chandev_register_and_probe(chandev_probefunc probefunc,
X chandev_shutdownfunc shutdownfunc,
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/current.h linux/include/asm-s390/current.h
--- v2.4.12/linux/include/asm-s390/current.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/current.h Thu Oct 11 09:43:38 2001
@@ -19,7 +19,7 @@
X {
X struct task_struct *current;
X __asm__("lhi %0,-8192\n\t"
- "nr %0,15"
+ "al %0,0xc40"
X : "=&r" (current) : : "cc" );
X return current;
X }
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/dasd.h linux/include/asm-s390/dasd.h
--- v2.4.12/linux/include/asm-s390/dasd.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/dasd.h Thu Oct 11 09:43:38 2001
@@ -36,6 +36,7 @@
X unsigned int dasd_io_time2[32]; /* histogram of time from start to irq */
X unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
X unsigned int dasd_io_time3[32]; /* histogram of time from irq to end */
+ unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
X } dasd_profile_info_t;
X
X /*
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/debug.h linux/include/asm-s390/debug.h
--- v2.4.12/linux/include/asm-s390/debug.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/debug.h Thu Oct 11 09:43:38 2001
@@ -44,6 +44,7 @@
X
X #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */
X #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */
X #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */
X #define DEBUG_MAX_PROCF_LEN 16 /* max length for a proc file name */
X #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/gdb-stub.h linux/include/asm-s390/gdb-stub.h
--- v2.4.12/linux/include/asm-s390/gdb-stub.h Fri May 12 11:41:44 2000
+++ linux/include/asm-s390/gdb-stub.h Thu Oct 11 09:43:38 2001
@@ -10,9 +10,13 @@
X #define __S390_GDB_STUB__
X #include <linux/config.h>
X #if CONFIG_REMOTE_DEBUG
-#include <asm/s390-gdbregs.h>
X #include <asm/ptrace.h>
X extern int gdb_stub_initialised;
-extern void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval);
+extern void gdb_stub_handle_exception(struct gdb_pt_regs *regs,int sigval);
+struct net_device;
+struct net_device *gdb_dev;
+void gdb_do_timers(void);
+extern int putDebugChar(char c); /* write a single character */
+extern char getDebugChar(void); /* read and return a single char */
X #endif
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/lowcore.h linux/include/asm-s390/lowcore.h
--- v2.4.12/linux/include/asm-s390/lowcore.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/lowcore.h Thu Oct 11 09:43:38 2001


@@ -41,7 +41,7 @@
X

X #define __LC_SAVE_AREA 0xC00
X #define __LC_KERNEL_STACK 0xC40
-#define __LC_KERNEL_LEVEL 0xC44
+#define __LC_ASYNC_STACK 0xC44
X #define __LC_CPUID 0xC60
X #define __LC_CPUADDR 0xC68
X #define __LC_IPLDEV 0xC7C
@@ -86,6 +86,12 @@
X #include <asm/atomic.h>
X #include <asm/sigp.h>
X
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
X
X struct _lowcore
X {
@@ -107,7 +113,7 @@
X __u16 cpu_addr; /* 0x084 */
X __u16 ext_int_code; /* 0x086 */
X __u16 svc_ilc; /* 0x088 */
- __u16 scv_code; /* 0x08a */
+ __u16 svc_code; /* 0x08a */
X __u16 pgm_ilc; /* 0x08c */
X __u16 pgm_code; /* 0x08e */
X __u32 trans_exc_code; /* 0x090 */
@@ -147,7 +153,7 @@
X /* System info area */
X __u32 save_area[16]; /* 0xc00 */
X __u32 kernel_stack; /* 0xc40 */
- __u32 kernel_level; /* 0xc44 */
+ __u32 async_stack; /* 0xc44 */
X /* entry.S sensitive area start */
X __u8 pad10[0xc60-0xc48]; /* 0xc5c */
X struct cpuinfo_S390 cpu_data; /* 0xc60 */
@@ -157,9 +163,7 @@
X /* SMP info area: defined by DJB */
X __u64 jiffy_timer_cc; /* 0xc80 */
X atomic_t ext_call_fast; /* 0xc88 */
- atomic_t ext_call_queue; /* 0xc8c */
- atomic_t ext_call_count; /* 0xc90 */
- __u8 pad11[0xe00-0xc94]; /* 0xc94 */
+ __u8 pad11[0xe00-0xc8c]; /* 0xc8c */
X
X /* 0xe00 is used as indicator for dump tools */
X /* whether the kernel died with panic() or not */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/pgalloc.h linux/include/asm-s390/pgalloc.h
--- v2.4.12/linux/include/asm-s390/pgalloc.h Mon Apr 23 15:28:07 2001
+++ linux/include/asm-s390/pgalloc.h Thu Oct 11 09:43:38 2001
@@ -84,6 +84,8 @@
X #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
X #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
X #define pmd_free(x) do { } while (0)
+#define pmd_free_slow(x) do { } while (0)
+#define pmd_free_fast(x) do { } while (0)
X #define pgd_populate(mm, pmd, pte) BUG()
X
X extern inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/pgtable.h linux/include/asm-s390/pgtable.h
--- v2.4.12/linux/include/asm-s390/pgtable.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/pgtable.h Thu Oct 11 09:43:38 2001
@@ -58,13 +58,6 @@


X #endif /* !__ASSEMBLY__ */
X

X /*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified. Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/*
X * PMD_SHIFT determines the size of the area a second-level page
X * table can map
X */
@@ -162,6 +155,7 @@
X
X /* Bits in the page table entry */
X #define _PAGE_PRESENT 0x001 /* Software */
+#define _PAGE_MKCLEAR 0x002 /* Software */
X #define _PAGE_RO 0x200 /* HW read-only */
X #define _PAGE_INVALID 0x400 /* HW invalid */
X
@@ -226,6 +220,25 @@
X #define __S111 PAGE_SHARED
X
X /*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+ if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+ == _PAGE_MKCLEAR)
+ {
+ pte_val(pteval) &= ~_PAGE_MKCLEAR;
+
+ asm volatile ("sske %0,%1"
+ : : "d" (0), "a" (pte_val(pteval)));
+ }
+
+ *pteptr = pteval;
+}
+
+/*
X * Permanent address of a page.
X */
X #define page_address(page) ((page)->virtual)
@@ -323,23 +336,22 @@
X
X extern inline pte_t pte_mkclean(pte_t pte)
X {
- /* We can't clear the changed bit atomically. The iske/and/sske
- * sequence has a race condition with the page referenced bit.
- * At the moment pte_mkclean is always followed by a pte_mkold.
- * So its safe to ignore the problem for now. Hope this will
- * never change ... */
- asm volatile ("sske %0,%1"
- : : "d" (0), "a" (pte_val(pte)));
+ /* The only user of pte_mkclean is the fork() code.
+ We must *not* clear the *physical* page dirty bit
+ just because fork() wants to clear the dirty bit in
+ *one* of the page's mappings. So we just do nothing. */
X return pte;
X }
X
X extern inline pte_t pte_mkdirty(pte_t pte)
X {
- /* We can't set the changed bit atomically either. For now we
+ /* We can't set the changed bit atomically. For now we
X * set (!) the page referenced bit. */
X asm volatile ("sske %0,%1"
X : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
X "a" (pte_val(pte)));
+
+ pte_val(pte) &= ~_PAGE_MKCLEAR;
X return pte;
X }
X
@@ -411,7 +423,23 @@
X pte_val(__pte) = physpage + pgprot_val(pgprot);
X return __pte;
X }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot) \
+({ \
+ struct page *__page = (pg); \
+ unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
+ pte_t __pte = mk_pte_phys(__physpage, (pgprot)); \
+ \
+ if (__page != ZERO_PAGE(__physpage)) { \
+ int __users = page_count(__page); \
+ __users -= !!__page->buffers + !!__page->mapping; \
+ \
+ if (__users == 1) \
+ pte_val(__pte) |= _PAGE_MKCLEAR; \
+ } \
+ \
+ __pte; \
+})
X
X #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
X
@@ -472,6 +500,11 @@
X /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
X #define PageSkip(page) (0)
X #define kern_addr_valid(addr) (1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
X
X #endif /* _S390_PAGE_H */
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/ptrace.h linux/include/asm-s390/ptrace.h
--- v2.4.12/linux/include/asm-s390/ptrace.h Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/ptrace.h Thu Oct 11 09:43:38 2001
@@ -191,6 +191,7 @@
X __u32 trap;
X __u32 crs[16];
X s390_fp_regs fp_regs;
+ __u32 old_ilc;
X };
X #endif
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/scatterlist.h linux/include/asm-s390/scatterlist.h
--- v2.4.12/linux/include/asm-s390/scatterlist.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */


- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */

X unsigned int length;
X };
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/sigp.h linux/include/asm-s390/sigp.h
--- v2.4.12/linux/include/asm-s390/sigp.h Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/sigp.h Thu Oct 11 09:43:38 2001
@@ -62,34 +62,9 @@
X ec_restart,
X ec_halt,
X ec_power_off,
- ec_ptlb,
+ ec_call_function,
X ec_bit_last
X } ec_bit_sig;
-
-/* Signals which come with a parameter area, synchronous */
-typedef enum
-{
- ec_callback_async,
- ec_callback_sync
-} ec_cmd_sig;
-
-/* state information for synchronous signals */
-typedef enum
-{
- ec_pending,
- ec_executing,
- ec_done
-} ec_state;
-
-/* header for the queuing of signals with a parameter area */
-typedef struct ec_ext_call
-{
- ec_cmd_sig cmd;
- atomic_t status;
- struct ec_ext_call *next;
- void (*func)(void *info);
- void *info;
-} ec_ext_call;
X
X /*
X * Signal processor
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/smp.h linux/include/asm-s390/smp.h
--- v2.4.12/linux/include/asm-s390/smp.h Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/smp.h Thu Oct 11 09:43:38 2001
@@ -26,6 +26,8 @@
X __u16 cpu;
X } sigp_info;
X
+extern unsigned long cpu_online_map;
+
X #define NO_PROC_ID 0xFF /* No processor magic marker */
X
X /*
@@ -64,12 +66,5 @@
X
X void smp_local_timer_interrupt(struct pt_regs * regs);
X
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
- int spin,sigp_info *info);
X #endif
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/softirq.h linux/include/asm-s390/softirq.h
--- v2.4.12/linux/include/asm-s390/softirq.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390/softirq.h Thu Oct 11 09:43:38 2001
@@ -18,22 +18,25 @@
X #include <asm/lowcore.h>
X
X #define __cpu_bh_enable(cpu) \
- do { barrier(); local_bh_count(cpu)--; } while (0)
+ do { barrier(); local_bh_count(cpu)--; } while (0)
X #define cpu_bh_disable(cpu) \
- do { local_bh_count(cpu)++; barrier(); } while (0)
+ do { local_bh_count(cpu)++; barrier(); } while (0)
X
X #define local_bh_disable() cpu_bh_disable(smp_processor_id())
X #define __local_bh_enable() __cpu_bh_enable(smp_processor_id())
X
X #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
X
+extern void do_call_softirq(void);
+
X #define local_bh_enable() \
X do { \
- unsigned int *ptr = &local_bh_count(smp_processor_id()); \
- barrier(); \
- if (!--*ptr) \
+ unsigned int *ptr = &local_bh_count(smp_processor_id()); \
+ barrier(); \
+ if (!--*ptr) \
X if (softirq_pending(smp_processor_id())) \
- do_softirq(); \
+ /* Use the async. stack for softirq */ \
+ do_call_softirq(); \
X } while (0)
X
X #endif /* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/spinlock.h linux/include/asm-s390/spinlock.h
--- v2.4.12/linux/include/asm-s390/spinlock.h Wed Apr 11 19:02:28 2001
+++ linux/include/asm-s390/spinlock.h Thu Oct 11 09:43:38 2001
@@ -32,20 +32,19 @@
X __asm__ __volatile(" bras 1,1f\n"
X "0: diag 0,0,68\n"
X "1: slr 0,0\n"
- " cs 0,1,%1\n"
+ " cs 0,1,0(%0)\n"
X " jl 0b\n"
- : "=m" (lp->lock)
- : "0" (lp->lock) : "0", "1", "cc" );
+ : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
X }
X
X extern inline int spin_trylock(spinlock_t *lp)


X {
X unsigned long result;

- __asm__ __volatile(" slr %1,%1\n"
+ __asm__ __volatile(" slr %0,%0\n"
X " basr 1,0\n"
- "0: cs %1,1,%0"
- : "=m" (lp->lock), "=&d" (result)
- : "0" (lp->lock) : "1", "cc" );
+ "0: cs %0,1,0(%1)"
+ : "=&d" (result)
+ : "a" (&lp->lock) : "1", "cc", "memory" );
X return !result;
X }
X
@@ -53,7 +52,7 @@
X {
X __asm__ __volatile(" xc 0(4,%0),0(%0)\n"
X " bcr 15,0"
- : /* no output */ : "a" (lp) : "memory", "cc" );
+ : : "a" (&lp->lock) : "memory", "cc" );
X }
X
X /*
@@ -76,24 +75,24 @@
X #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
X
X #define read_lock(rw) \
- asm volatile(" l 2,%0\n" \
+ asm volatile(" l 2,0(%0)\n" \
X " j 1f\n" \
X "0: diag 0,0,68\n" \
- "1: la 2,0(2)\n" /* clear high (=write) bit */ \
- " la 3,1(2)\n" /* one more reader */ \
- " cs 2,3,%0\n" /* try to write new value */ \
+ "1: la 2,0(2)\n" /* clear high (=write) bit */ \
+ " la 3,1(2)\n" /* one more reader */ \
+ " cs 2,3,0(%0)\n" /* try to write new value */ \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "2", "3", "cc" );
+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define read_unlock(rw) \
- asm volatile(" l 2,%0\n" \
+ asm volatile(" l 2,0(%0)\n" \
X " j 1f\n" \
X "0: diag 0,0,68\n" \
X "1: lr 3,2\n" \
X " ahi 3,-1\n" /* one less reader */ \
- " cs 2,3,%0\n" \
+ " cs 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "2", "3", "cc" );
+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define write_lock(rw) \
X asm volatile(" lhi 3,1\n" \
@@ -101,9 +100,9 @@
X " j 1f\n" \
X "0: diag 0,0,68\n" \
X "1: slr 2,2\n" /* old lock value must be 0 */ \
- " cs 2,3,%0\n" \
+ " cs 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "2", "3", "cc" );
+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define write_unlock(rw) \
X asm volatile(" slr 3,3\n" /* new lock value = 0 */ \
@@ -111,8 +110,8 @@
X "0: diag 0,0,68\n" \
X "1: lhi 2,1\n" \
X " sll 2,31\n" /* old lock value must be 0x80000000 */ \
- " cs 2,3,%0\n" \
+ " cs 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "2", "3", "cc" );
+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #endif /* __ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/uaccess.h linux/include/asm-s390/uaccess.h
--- v2.4.12/linux/include/asm-s390/uaccess.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/uaccess.h Thu Oct 11 09:43:38 2001
@@ -78,6 +78,35 @@
X * use the right size if we just have the right pointer type.
X */
X
+extern inline int __put_user_asm_8(__u64 x, void *ptr)


+{
+ int err;
+

+ __asm__ __volatile__ ( " sr %1,%1\n"
+ " la 2,%2\n"
+ " la 4,%0\n"
+ " sacf 512\n"
+ "0: mvc 0(8,4),0(2)\n"
+ " sacf 0\n"
+ "1:\n"
+ ".section .fixup,\"ax\"\n"
+ "2: sacf 0\n"
+ " lhi %1,%h3\n"
+ " bras 4,3f\n"
+ " .long 1b\n"
+ "3: l 4,0(4)\n"
+ " br 4\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 0b,2b\n"
+ ".previous"
+ : "=m" (*((__u32*) ptr)), "=&d" (err)
+ : "m" (x), "K" (-EFAULT)
+ : "cc", "2", "4" );


+ return err;
+}
+

X extern inline int __put_user_asm_4(__u32 x, void *ptr)
X {
X int err;
@@ -179,6 +208,9 @@
X case 4: \
X __pu_err = __put_user_asm_4((__u32) x,(ptr));\
X break; \
+ case 8: \
+ __pu_err = __put_user_asm_8((__u64) x,(ptr));\
+ break; \
X default: \
X __pu_err = __put_user_bad(); \
X break; \
@@ -200,6 +232,31 @@
X
X extern int __put_user_bad(void);
X
+#define __get_user_asm_8(x, ptr, err) \
+({ \
+ __asm__ __volatile__ ( " sr %1,%1\n" \
+ " la 2,%0\n" \
+ " la 4,%2\n" \
+ " sacf 512\n" \
+ "0: mvc 0(8,2),0(4)\n" \
+ " sacf 0\n" \
+ "1:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "2: sacf 0\n" \
+ " lhi %1,%h3\n" \
+ " bras 4,3f\n" \
+ " .long 1b\n" \
+ "3: l 4,0(4)\n" \
+ " br 4\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 0b,2b\n" \
+ ".previous" \
+ : "=m" (x) , "=&d" (err) \
+ : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) \
+ : "cc", "2", "4" ); \
+})
X
X #define __get_user_asm_4(x, ptr, err) \
X ({ \
@@ -290,6 +347,9 @@
X case 4: \
X __get_user_asm_4(x,ptr,__gu_err); \
X break; \
+ case 8: \
+ __get_user_asm_8(x,ptr,__gu_err); \
+ break; \
X default: \
X (x) = 0; \
X __gu_err = __get_user_bad(); \
@@ -372,7 +432,7 @@
X "0: mvcle 2,4,0\n"
X " jo 0b\n"
X " sacf 0\n"
- " lr %0,3\n"
+ " lr %0,5\n"
X ".section __ex_table,\"a\"\n"
X " .align 4\n"
X " .long 0b,__copy_from_user_fixup\n"
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/ucontext.h linux/include/asm-s390/ucontext.h
--- v2.4.12/linux/include/asm-s390/ucontext.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/ucontext.h Thu Oct 11 09:43:38 2001
@@ -13,10 +13,8 @@
X unsigned long uc_flags;
X struct ucontext *uc_link;
X stack_t uc_stack;
+ _sigregs uc_mcontext;
X sigset_t uc_sigmask; /* mask last for extensibility */
- struct sigcontext *sc; /* Added for pthread support */
X };
-
-
X
X #endif /* !_ASM_S390_UCONTEXT_H */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/unistd.h linux/include/asm-s390/unistd.h
--- v2.4.12/linux/include/asm-s390/unistd.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/unistd.h Thu Oct 11 09:43:38 2001
@@ -178,6 +178,8 @@
X #define __NR_capset 185
X #define __NR_sigaltstack 186
X #define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
X #define __NR_vfork 190
X #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
X #define __NR_mmap2 192
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390/vtoc.h linux/include/asm-s390/vtoc.h
--- v2.4.12/linux/include/asm-s390/vtoc.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390/vtoc.h Thu Oct 11 09:43:38 2001
@@ -39,135 +39,6 @@
X
X #define VTOC_ERROR "VTOC error:"
X
-enum failure {unable_to_open,
- unable_to_seek,
- unable_to_write,
- unable_to_read};
-
-unsigned char ASCtoEBC[256] =
-{
- /*00 NL SH SX EX ET NQ AK BL */
- 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08 BS HT LF VT FF CR SO SI */
- 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10 DL D1 D2 D3 D4 NK SN EB */
- 0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18 CN EM SB EC FS GS RS US */
- 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20 SP ! " # $ % & ' */
- 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28 ( ) * + , - . / */
- 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30 0 1 2 3 4 5 6 7 */
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38 8 9 : ; < = > ? */
- 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40 @ A B C D E F G */
- 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48 H I J K L M N O */
- 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50 P Q R S T U V W */
- 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58 X Y Z [ \ ] ^ _ */
- 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60 ` a b c d e f g */
- 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68 h i j k l m n o */
- 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70 p q r s t u v w */
- 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78 x y z { | } ~ DL */
- 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-
-unsigned char EBCtoASC[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40 SP RSP ä ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58 ß ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60 - / ---- Ä ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90 ° j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0 ^ ---- § ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8 H I ---- ö ---- */
- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8 Q R ---- ü */
- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8 Y Z ---- Ö ---- ---- ---- */
- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
X
X typedef struct ttr
X {
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/chandev.h linux/include/asm-s390x/chandev.h
--- v2.4.12/linux/include/asm-s390x/chandev.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/chandev.h Thu Oct 11 09:43:38 2001
@@ -139,6 +139,10 @@
X * not operational the previous status is sent in the prevstatus variable.
X * This can be used in cases when the default handling isn't quite adequete
X * e.g. if a ssch is needed to reinitialize long running channel programs.
+ *
+ * This returns the number of devices found or -ENOMEM if the code didn't
+ * have enough memory to allocate the chandev control block
+ * or -EPERM if a duplicate entry is found.
X */
X int chandev_register_and_probe(chandev_probefunc probefunc,
X chandev_shutdownfunc shutdownfunc,
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/current.h linux/include/asm-s390x/current.h
--- v2.4.12/linux/include/asm-s390x/current.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/current.h Thu Oct 11 09:43:38 2001
@@ -19,7 +19,7 @@
X {
X struct task_struct *current;
X __asm__("lghi %0,-16384\n\t"
- "ngr %0,15"
+ "alg %0,0xd40"
X : "=&r" (current) : : "cc" );
X return current;
X }
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/dasd.h linux/include/asm-s390x/dasd.h
--- v2.4.12/linux/include/asm-s390x/dasd.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/dasd.h Thu Oct 11 09:43:38 2001
@@ -36,6 +36,7 @@
X unsigned int dasd_io_time2[32]; /* histogram of time from start to irq */
X unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */
X unsigned int dasd_io_time3[32]; /* histogram of time from irq to end */
+ unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
X } dasd_profile_info_t;
X
X /*
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/debug.h linux/include/asm-s390x/debug.h
--- v2.4.12/linux/include/asm-s390x/debug.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/debug.h Thu Oct 11 09:43:38 2001
@@ -44,6 +44,7 @@
X
X #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */
X #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */
+#define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */
X #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */
X #define DEBUG_MAX_PROCF_LEN 16 /* max length for a proc file name */
X #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/lowcore.h linux/include/asm-s390x/lowcore.h
--- v2.4.12/linux/include/asm-s390x/lowcore.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/lowcore.h Thu Oct 11 09:43:38 2001
@@ -1,3 +1,4 @@
+
X /*
X * include/asm-s390/lowcore.h
X *
@@ -39,7 +40,7 @@
X
X #define __LC_SAVE_AREA 0xC00
X #define __LC_KERNEL_STACK 0xD40
-#define __LC_KERNEL_LEVEL 0xD48
+#define __LC_ASYNC_STACK 0xD48
X #define __LC_CPUID 0xD90
X #define __LC_CPUADDR 0xD98
X #define __LC_IPLDEV 0xDB8
@@ -85,6 +86,12 @@
X #include <asm/atomic.h>
X #include <asm/sigp.h>
X
+void restart_int_handler(void);
+void ext_int_handler(void);
+void system_call(void);
+void pgm_check_handler(void);
+void mcck_int_handler(void);
+void io_int_handler(void);
X
X struct _lowcore
X {
@@ -96,7 +103,7 @@
X __u16 cpu_addr; /* 0x084 */
X __u16 ext_int_code; /* 0x086 */
X __u16 svc_ilc; /* 0x088 */
- __u16 scv_code; /* 0x08a */
+ __u16 svc_code; /* 0x08a */
X __u16 pgm_ilc; /* 0x08c */
X __u16 pgm_code; /* 0x08e */
X __u32 data_exc_code; /* 0x090 */
@@ -142,7 +149,7 @@
X __u64 save_area[16]; /* 0xc00 */
X __u8 pad9[0xd40-0xc80]; /* 0xc80 */
X __u64 kernel_stack; /* 0xd40 */
- __u64 kernel_level; /* 0xd48 */
+ __u64 async_stack; /* 0xd48 */
X /* entry.S sensitive area start */
X __u8 pad10[0xd80-0xd50]; /* 0xd64 */
X struct cpuinfo_S390 cpu_data; /* 0xd80 */
@@ -153,10 +160,7 @@
X /* SMP info area: defined by DJB */
X __u64 jiffy_timer_cc; /* 0xdc0 */
X __u64 ext_call_fast; /* 0xdc8 */
- __u64 ext_call_queue; /* 0xdd0 */
- __u64 ext_call_count; /* 0xdd8 */
-
- __u8 pad12[0xe00-0xde0]; /* 0xde0 */
+ __u8 pad12[0xe00-0xdd0]; /* 0xdd0 */
X
X /* 0xe00 is used as indicator for dump tools */
X /* whether the kernel died with panic() or not */
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/mathemu.h linux/include/asm-s390x/mathemu.h
--- v2.4.12/linux/include/asm-s390x/mathemu.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/mathemu.h Wed Dec 31 16:00:00 1969
@@ -1,48 +0,0 @@
-/*
- * arch/s390/kernel/mathemu.h
- * IEEE floating point emulation.
- *
- * S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Martin Schwidefsky (schwi...@de.ibm.com)
- */
-
-#ifndef __MATHEMU__
-#define __MATHEMU__
-
-extern int math_emu_b3(__u8 *, struct pt_regs *);
-extern int math_emu_ed(__u8 *, struct pt_regs *);
-extern void math_emu_ldr(__u8 *);
-extern void math_emu_ler(__u8 *);
-extern void math_emu_std(__u8 *, struct pt_regs *);
-extern void math_emu_ld(__u8 *, struct pt_regs *);
-extern void math_emu_ste(__u8 *, struct pt_regs *);
-extern void math_emu_le(__u8 *, struct pt_regs *);
-extern int math_emu_lfpc(__u8 *, struct pt_regs *);
-extern int math_emu_stfpc(__u8 *, struct pt_regs *);
-extern int math_emu_srnm(__u8 *, struct pt_regs *);
-
-
-extern __u64 __adddf3(__u64,__u64);
-extern __u64 __subdf3(__u64,__u64);
-extern __u64 __muldf3(__u64,__u64);
-extern __u64 __divdf3(__u64,__u64);
-extern long __cmpdf2(__u64,__u64);
-extern __u64 __negdf2(__u64);
-extern __u64 __absdf2(__u64);
-extern __u32 __addsf3(__u32,__u32);
-extern __u32 __subsf3(__u32,__u32);
-extern __u32 __mulsf3(__u32,__u32);
-extern __u32 __divsf3(__u32,__u32);
-extern __u32 __negsf2(__u32);
-extern __u32 __abssf2(__u32);
-extern long __cmpsf2(__u32,__u32);
-extern __u32 __truncdfsf2(__u64);
-extern __u32 __fixsfsi(__u32);
-extern __u32 __fixdfsi(__u64);
-extern __u64 __floatsidf(__u32);
-extern __u32 __floatsisf(__u32);
-extern __u64 __extendsfdf2(__u32);
-
-#endif /* __MATHEMU__ */
-
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/page.h linux/include/asm-s390x/page.h
--- v2.4.12/linux/include/asm-s390x/page.h Sun Aug 12 13:28:00 2001
+++ linux/include/asm-s390x/page.h Thu Oct 11 09:43:38 2001
@@ -110,11 +110,6 @@
X /* to align the pointer to the (next) page boundary */
X #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
X
-/*
- *
- *
- */
-
X #define __PAGE_OFFSET 0x0UL
X #define PAGE_OFFSET 0x0UL
X #define __pa(x) (unsigned long)(x)
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/param.h linux/include/asm-s390x/param.h
--- v2.4.12/linux/include/asm-s390x/param.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/param.h Thu Oct 11 09:43:38 2001
@@ -11,6 +11,9 @@
X

X #ifndef HZ
X #define HZ 100

+#ifdef __KERNEL__
+#define hz_to_std(a) (a)
+#endif
X #endif
X
X #define EXEC_PAGESIZE 4096
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/pgtable.h linux/include/asm-s390x/pgtable.h
--- v2.4.12/linux/include/asm-s390x/pgtable.h Sun Aug 12 13:28:01 2001
+++ linux/include/asm-s390x/pgtable.h Thu Oct 11 09:43:38 2001
@@ -54,13 +54,6 @@


X #endif /* !__ASSEMBLY__ */
X

X /*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified. Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/*
X * PMD_SHIFT determines the size of the area a second-level page
X * table can map
X */
@@ -164,6 +157,7 @@
X
X /* Bits in the page table entry */
X #define _PAGE_PRESENT 0x001 /* Software */
+#define _PAGE_MKCLEAR 0x002 /* Software */
X #define _PAGE_RO 0x200 /* HW read-only */
X #define _PAGE_INVALID 0x400 /* HW invalid */
X
@@ -180,7 +174,8 @@
X */
X #define _REGION_THIRD 0x4
X #define _REGION_THIRD_LEN 0x3
-#define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40)
+#define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
+#define _KERN_REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN)
X
X /* Bits in the storage key */
X #define _PAGE_CHANGED 0x02 /* HW changed bit */
@@ -220,6 +215,25 @@
X #define __S111 PAGE_SHARED
X
X /*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+ if ((pte_val(pteval) & (_PAGE_MKCLEAR|_PAGE_INVALID))
+ == _PAGE_MKCLEAR)
+ {
+ pte_val(pteval) &= ~_PAGE_MKCLEAR;
+
+ asm volatile ("sske %0,%1"
+ : : "d" (0), "a" (pte_val(pteval)));
+ }
+
+ *pteptr = pteval;
+}
+
+/*
X * Permanent address of a page.
X */
X #define page_address(page) ((page)->virtual)
@@ -341,13 +355,10 @@
X
X extern inline pte_t pte_mkclean(pte_t pte)
X {
- /* We can't clear the changed bit atomically. The iske/and/sske
- * sequence has a race condition with the page referenced bit.
- * At the moment pte_mkclean is always followed by a pte_mkold.
- * So its safe to ignore the problem for now. Hope this will
- * never change ... */
- asm volatile ("sske %0,%1"
- : : "d" (0), "a" (pte_val(pte)));
+ /* The only user of pte_mkclean is the fork() code.
+ We must *not* clear the *physical* page dirty bit
+ just because fork() wants to clear the dirty bit in
+ *one* of the page's mappings. So we just do nothing. */
X return pte;
X }
X
@@ -358,6 +369,8 @@
X asm volatile ("sske %0,%1"
X : : "d" (_PAGE_CHANGED|_PAGE_REFERENCED),
X "a" (pte_val(pte)));


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 49'
echo 'File patch-2.4.13 is continued in part 50'
echo "50" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:20 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part50

#!/bin/sh -x
# this is part 50 of a 53 - part archive


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

if test "$Scheck" != 50; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+
+ pte_val(pte) &= ~_PAGE_MKCLEAR;
X return pte;
X }
X

@@ -429,7 +442,23 @@


X pte_val(__pte) = physpage + pgprot_val(pgprot);
X return __pte;
X }
-#define mk_pte(page,pgprot) mk_pte_phys(__pa(((page)-mem_map)<<PAGE_SHIFT),pgprot)
+
+#define mk_pte(pg, pgprot) \
+({ \
+ struct page *__page = (pg); \
+ unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \
+ pte_t __pte = mk_pte_phys(__physpage, (pgprot)); \
+ \
+ if (__page != ZERO_PAGE(__physpage)) { \
+ int __users = page_count(__page); \
+ __users -= !!__page->buffers + !!__page->mapping; \
+ \
+ if (__users == 1) \
+ pte_val(__pte) |= _PAGE_MKCLEAR; \
+ } \
+ \
+ __pte; \
+})
X
X #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
X

@@ -491,6 +520,11 @@


X /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
X #define PageSkip(page) (0)
X #define kern_addr_valid(addr) (1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
X
X #endif /* _S390_PAGE_H */
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/scatterlist.h linux/include/asm-s390x/scatterlist.h
--- v2.4.12/linux/include/asm-s390x/scatterlist.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/scatterlist.h Fri Oct 12 15:35:54 2001


@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
X unsigned int length;
X };
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/sigp.h linux/include/asm-s390x/sigp.h
--- v2.4.12/linux/include/asm-s390x/sigp.h Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/sigp.h Thu Oct 11 09:43:38 2001
@@ -62,33 +62,10 @@


X ec_restart,
X ec_halt,
X ec_power_off,

+ ec_call_function,
X ec_bit_last
X } ec_bit_sig;

X
-/* Signals which come with a parameter area */
-typedef enum
-{
- ec_callback_sync,
- ec_callback_async
-} ec_cmd_sig;
-
-/* state information for signals */


-typedef enum
-{
- ec_pending,
- ec_executing,
- ec_done
-} ec_state;
-

-/* header for the queuing of callbacks */


-typedef struct ec_ext_call
-{
- ec_cmd_sig cmd;
- atomic_t status;
- struct ec_ext_call *next;
- void (*func)(void *info);
- void *info;
-} ec_ext_call;
X
X /*
X * Signal processor

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/smp.h linux/include/asm-s390x/smp.h
--- v2.4.12/linux/include/asm-s390x/smp.h Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/smp.h Thu Oct 11 09:43:38 2001


@@ -26,6 +26,8 @@
X __u16 cpu;
X } sigp_info;
X
+extern unsigned long cpu_online_map;
+
X #define NO_PROC_ID 0xFF /* No processor magic marker */
X
X /*
@@ -64,12 +66,5 @@
X
X void smp_local_timer_interrupt(struct pt_regs * regs);
X
-sigp_ccode smp_ext_call(int cpu, void (*cb)(void *info), void *info, int wait);
-void smp_ext_call_others(void (*cb)(void *info), void *info, int wait);
-sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig);
-void smp_ext_bitcall_others(ec_bit_sig sig);
-
-int smp_signal_others(sigp_order_code order_code,__u32 parameter,
- int spin,sigp_info *info);
X #endif
X #endif

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/softirq.h linux/include/asm-s390x/softirq.h
--- v2.4.12/linux/include/asm-s390x/softirq.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390x/softirq.h Thu Oct 11 09:43:38 2001

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/spinlock.h linux/include/asm-s390x/spinlock.h
--- v2.4.12/linux/include/asm-s390x/spinlock.h Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/spinlock.h Thu Oct 11 09:43:38 2001


@@ -32,20 +32,19 @@
X __asm__ __volatile(" bras 1,1f\n"

X "0: # diag 0,0,68\n"


X "1: slr 0,0\n"
- " cs 0,1,%1\n"
+ " cs 0,1,0(%0)\n"
X " jl 0b\n"
- : "=m" (lp->lock)
- : "0" (lp->lock) : "0", "1", "cc" );
+ : : "a" (&lp->lock) : "0", "1", "cc", "memory" );
X }
X
X extern inline int spin_trylock(spinlock_t *lp)
X {

X unsigned int result;


- __asm__ __volatile(" slr %1,%1\n"
+ __asm__ __volatile(" slr %0,%0\n"
X " basr 1,0\n"
- "0: cs %1,1,%0"
- : "=m" (lp->lock), "=&d" (result)
- : "0" (lp->lock) : "1", "cc" );
+ "0: cs %0,1,0(%1)"
+ : "=&d" (result)
+ : "a" (&lp->lock) : "1", "cc", "memory" );
X return !result;
X }
X
@@ -53,7 +52,7 @@
X {
X __asm__ __volatile(" xc 0(4,%0),0(%0)\n"
X " bcr 15,0"
- : /* no output */ : "a" (lp) : "memory", "cc" );
+ : : "a" (&lp->lock) : "memory", "cc" );
X }
X
X /*

@@ -76,46 +75,42 @@


X #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
X
X #define read_lock(rw) \

- asm volatile(" la 1,%0\n" \
- " lg 2,0(1)\n" \
+ asm volatile(" lg 2,0(%0)\n" \
X " j 1f\n" \
X "0: # diag 0,0,68\n" \
X "1: nihh 2,0x7fff\n" /* clear high (=write) bit */ \
X " la 3,1(2)\n" /* one more reader */ \
- " csg 2,3,0(1)\n" /* try to write new value */ \
+ " csg 2,3,0(%0)\n" /* try to write new value */ \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );


+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define read_unlock(rw) \

- asm volatile(" la 1,%0\n" \
- " lg 2,0(1)\n" \
+ asm volatile(" lg 2,0(%0)\n" \
X " j 1f\n" \
X "0: # diag 0,0,68\n" \
X "1: lgr 3,2\n" \
X " bctgr 3,0\n" /* one less reader */ \
- " csg 2,3,0(1)\n" \
+ " csg 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );


+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define write_lock(rw) \

- asm volatile(" la 1,%0\n" \
- " llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
+ asm volatile(" llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
X " j 1f\n" \
X "0: # diag 0,0,68\n" \
X "1: slgr 2,2\n" /* old lock value must be 0 */ \
- " csg 2,3,0(1)\n" \
+ " csg 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );


+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #define write_unlock(rw) \

- asm volatile(" la 1,%0\n" \
- " slgr 3,3\n" /* new lock value = 0 */ \
+ asm volatile(" slgr 3,3\n" /* new lock value = 0 */ \
X " j 1f\n" \
X "0: # diag 0,0,68\n" \
X "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
- " csg 2,3,0(1)\n" \
+ " csg 2,3,0(%0)\n" \
X " jl 0b" \
- : "+m" ((rw)->lock) : : "1", "2", "3", "cc" );


+ : : "a" (&(rw)->lock) : "2", "3", "cc", "memory" );
X
X #endif /* __ASM_SPINLOCK_H */

X
diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/ucontext.h linux/include/asm-s390x/ucontext.h
--- v2.4.12/linux/include/asm-s390x/ucontext.h Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/ucontext.h Thu Oct 11 09:43:38 2001


@@ -13,10 +13,8 @@
X unsigned long uc_flags;
X struct ucontext *uc_link;
X stack_t uc_stack;
+ _sigregs uc_mcontext;
X sigset_t uc_sigmask; /* mask last for extensibility */
- struct sigcontext *sc; /* Added for pthread support */
X };
-
-
X
X #endif /* !_ASM_S390_UCONTEXT_H */

diff -u --recursive --new-file v2.4.12/linux/include/asm-s390x/unistd.h linux/include/asm-s390x/unistd.h
--- v2.4.12/linux/include/asm-s390x/unistd.h Sun Aug 12 13:28:01 2001
+++ linux/include/asm-s390x/unistd.h Thu Oct 11 09:43:38 2001
@@ -154,6 +154,8 @@


X #define __NR_capset 185
X #define __NR_sigaltstack 186
X #define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
X #define __NR_vfork 190

X #define __NR_getrlimit 191 /* SuS compliant getrlimit */
X #define __NR_lchown 198
@@ -199,7 +201,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name) \
X : _svc_clobber ); \
@@ -212,7 +214,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name), \
X "d" (__arg1) \
@@ -227,7 +229,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name), \
X "d" (__arg1), \
@@ -244,7 +246,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name), \
X "d" (__arg1), \
@@ -264,7 +266,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name), \
X "d" (__arg1), \
@@ -287,7 +289,7 @@
X long __res; \
X __asm__ __volatile__ ( \
X " svc %b1\n" \
- " lr %0,2" \
+ " lgr %0,2" \
X : "=d" (__res) \
X : "i" (__NR_##name), \
X "d" (__arg1), \
diff -u --recursive --new-file v2.4.12/linux/include/asm-sh/ioctl.h linux/include/asm-sh/ioctl.h
--- v2.4.12/linux/include/asm-sh/ioctl.h Mon Oct 18 11:16:13 1999
+++ linux/include/asm-sh/ioctl.h Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: ioctl.h,v 1.1 1999/09/18 17:29:53 gniibe Exp $
+/* $Id: ioctl.h,v 1.1 2000/04/14 16:48:21 mjd Exp $
X *
X * linux/ioctl.h for Linux by H.H. Bergman.
X */
diff -u --recursive --new-file v2.4.12/linux/include/asm-sh/namei.h linux/include/asm-sh/namei.h
--- v2.4.12/linux/include/asm-sh/namei.h Sun Apr 2 15:49:07 2000
+++ linux/include/asm-sh/namei.h Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.1 1999/09/18 17:30:11 gniibe Exp $
+/* $Id: namei.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $
X * linux/include/asm-sh/namei.h
X *
X * Included from linux/fs/namei.c
diff -u --recursive --new-file v2.4.12/linux/include/asm-sh/pci.h linux/include/asm-sh/pci.h
--- v2.4.12/linux/include/asm-sh/pci.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sh/pci.h Fri Oct 12 15:35:54 2001
@@ -191,7 +191,7 @@


X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */

-static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
X {

X return 1;
X }
diff -u --recursive --new-file v2.4.12/linux/include/asm-sh/scatterlist.h linux/include/asm-sh/scatterlist.h
--- v2.4.12/linux/include/asm-sh/scatterlist.h Sun Mar 5 09:33:55 2000
+++ linux/include/asm-sh/scatterlist.h Fri Oct 12 15:35:54 2001


@@ -3,8 +3,6 @@
X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
X unsigned int length;
X };
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-sh/uaccess.h linux/include/asm-sh/uaccess.h
--- v2.4.12/linux/include/asm-sh/uaccess.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sh/uaccess.h Mon Oct 15 13:36:48 2001
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.12 2001/07/27 06:09:47 gniibe Exp $
+/* $Id: uaccess.h,v 1.13 2001/10/01 02:22:01 gniibe Exp $
X *
X * User space memory access functions
X *
@@ -150,6 +150,7 @@
X case 1: __put_user_asm("b"); break; \
X case 2: __put_user_asm("w"); break; \
X case 4: __put_user_asm("l"); break; \
+case 8: __put_user_u64(__pu_val,__pu_addr,__pu_err); break; \
X default: __put_user_unknown(); break; \
X } __pu_err; })
X
@@ -165,6 +166,7 @@
X case 1: __put_user_asm("b"); break; \
X case 2: __put_user_asm("w"); break; \
X case 4: __put_user_asm("l"); break; \
+case 8: __put_user_u64(__pu_val,__pu_addr,__pu_err); break; \
X default: __put_user_unknown(); break; \
X } } __pu_err; })
X
@@ -189,6 +191,53 @@
X :"=&r" (__pu_err) \
X :"r" (__pu_val), "m" (__m(__pu_addr)), "i" (-EFAULT) \
X :"memory"); })
+
+#if defined(__LITTLE_ENDIAN__)
+#define __put_user_u64(val,addr,retval) \
+({ \
+__asm__ __volatile__( \
+ "1:\n\t" \
+ "mov.l %R1,%2\n\t" \
+ "mov.l %S1,%T2\n\t" \
+ "mov #0,%0\n" \
+ "2:\n" \


+ ".section .fixup,\"ax\"\n" \

+ "3:\n\t" \
+ "nop\n\t" \
+ "mov.l 4f,%0\n\t" \
+ "jmp @%0\n\t" \
+ " mov %3,%0\n" \
+ "4: .long 2b\n\t" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".long 1b, 3b\n\t" \
+ ".previous" \
+ : "=r" (retval) \
+ : "r" (val), "m" (__m(addr)), "i" (-EFAULT) \
+ : "memory"); })
+#else
+({ \
+__asm__ __volatile__( \
+ "1:\n\t" \
+ "mov.l %S1,%2\n\t" \
+ "mov.l %R1,%T2\n\t" \
+ "mov #0,%0\n" \
+ "2:\n" \


+ ".section .fixup,\"ax\"\n" \

+ "3:\n\t" \
+ "nop\n\t" \
+ "mov.l 4f,%0\n\t" \
+ "jmp @%0\n\t" \
+ " mov %3,%0\n" \
+ "4: .long 2b\n\t" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".long 1b, 3b\n\t" \
+ ".previous" \
+ : "=r" (retval) \
+ : "r" (val), "m" (__m(addr)), "i" (-EFAULT) \
+ : "memory"); })
+#endif
X
X extern void __put_user_unknown(void);
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc/highmem.h linux/include/asm-sparc/highmem.h
--- v2.4.12/linux/include/asm-sparc/highmem.h Sun Feb 18 19:49:55 2001
+++ linux/include/asm-sparc/highmem.h Wed Oct 17 14:16:39 2001
@@ -111,14 +111,11 @@
X
X static inline void kunmap_atomic(void *kvaddr, enum km_type type)
X {
-#if HIGHMEM_DEBUG
X unsigned long vaddr = (unsigned long) kvaddr;
X unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
X
-#if 0
- if (vaddr < FIXADDR_START) // FIXME
+ if (vaddr < FIX_KMAP_BEGIN) // FIXME
X return;
-#endif
X
X if (vaddr != FIX_KMAP_BEGIN + idx * PAGE_SIZE)
X BUG();
@@ -130,6 +127,7 @@
X flush_cache_all();
X #endif
X
+#ifdef HIGHMEM_DEBUG
X /*
X * force other mappings to Oops if they'll try to access
X * this pte without first remap it
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc/pci.h linux/include/asm-sparc/pci.h
--- v2.4.12/linux/include/asm-sparc/pci.h Wed May 16 10:31:27 2001
+++ linux/include/asm-sparc/pci.h Fri Oct 12 15:35:54 2001
@@ -108,7 +108,7 @@


X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */
-extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
X {

X return 1;
X }
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc/pgalloc.h linux/include/asm-sparc/pgalloc.h
--- v2.4.12/linux/include/asm-sparc/pgalloc.h Wed Jul 25 17:10:25 2001
+++ linux/include/asm-sparc/pgalloc.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: pgalloc.h,v 1.13 2001/07/17 16:17:33 anton Exp $ */
+/* $Id: pgalloc.h,v 1.15 2001/10/18 09:06:37 davem Exp $ */
X #ifndef _SPARC_PGALLOC_H
X #define _SPARC_PGALLOC_H
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc/scatterlist.h linux/include/asm-sparc/scatterlist.h
--- v2.4.12/linux/include/asm-sparc/scatterlist.h Mon Jan 31 23:37:19 2000
+++ linux/include/asm-sparc/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -1,4 +1,4 @@
-/* $Id: scatterlist.h,v 1.5 2000/01/29 16:27:07 jj Exp $ */
+/* $Id: scatterlist.h,v 1.6 2001/10/09 02:24:35 davem Exp $ */
X #ifndef _SPARC_SCATTERLIST_H
X #define _SPARC_SCATTERLIST_H
X
@@ -6,8 +6,6 @@


X
X struct scatterlist {
X char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
X unsigned int length;
X

X __u32 dvma_address; /* A place to hang host-specific addresses at. */
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- v2.4.12/linux/include/asm-sparc/unistd.h Thu Oct 11 08:02:26 2001
+++ linux/include/asm-sparc/unistd.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.71 2001/10/09 10:54:39 davem Exp $ */
+/* $Id: unistd.h,v 1.72 2001/10/18 08:27:05 davem Exp $ */
X #ifndef _SPARC_UNISTD_H
X #define _SPARC_UNISTD_H
X
@@ -220,7 +220,7 @@
X #define __NR_oldlstat 202 /* Linux Specific */
X #define __NR_uselib 203 /* Linux Specific */
X #define __NR_readdir 204 /* Linux Specific */
-/* #define __NR_ioperm 205 Linux Specific - i386 specific, unused */
+#define __NR_readahead 205 /* Linux Specific */
X #define __NR_socketcall 206 /* Linux Specific */
X #define __NR_syslog 207 /* Linux Specific */
X /* #define __NR_olduname 208 Linux Specific */
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/cache.h linux/include/asm-sparc64/cache.h
--- v2.4.12/linux/include/asm-sparc64/cache.h Fri Aug 6 11:58:00 1999
+++ linux/include/asm-sparc64/cache.h Wed Oct 17 14:16:39 2001
@@ -9,7 +9,8 @@
X
X #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
X
-#define SMP_CACHE_BYTES 64 /* L2 cache line size. */
+#define SMP_CACHE_BYTES_SHIFT 6
+#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
X
X #ifdef MODULE
X #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/hardirq.h linux/include/asm-sparc64/hardirq.h
--- v2.4.12/linux/include/asm-sparc64/hardirq.h Wed Jul 25 17:10:25 2001
+++ linux/include/asm-sparc64/hardirq.h Wed Oct 17 14:16:39 2001
@@ -12,6 +12,7 @@
X #include <linux/spinlock.h>
X
X /* entry.S is sensitive to the offsets of these fields */
+/* rtrap.S is sensitive to the size of this structure */
X typedef struct {
X unsigned int __softirq_pending;
X unsigned int __unused_1;
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/pci.h linux/include/asm-sparc64/pci.h
--- v2.4.12/linux/include/asm-sparc64/pci.h Wed May 16 10:31:27 2001
+++ linux/include/asm-sparc64/pci.h Fri Oct 12 15:35:54 2001
@@ -28,6 +28,12 @@
X /* Dynamic DMA mapping stuff.
X */
X
+/* The PCI address space does not equal the physical memory


+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */

+#define PCI_DMA_BUS_IS_PHYS (0)
+
X #include <asm/scatterlist.h>
X
X struct pci_dev;
@@ -64,6 +70,11 @@
X */
X extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
X
+/* No highmem on sparc64, plus we have an IOMMU, so mapping pages is easy. */
+#define pci_map_page(dev, page, off, size, dir) \
+ pci_map_single(dev, (page_address(page) + (off)), size, dir)
+#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir)
+
X /* Map a set of buffers described by scatterlist in streaming
X * mode for DMA. This is the scather-gather version of the
X * above pci_map_single interface. Here the scatter gather list
@@ -79,13 +90,15 @@
X * Device ownership issues as mentioned above for pci_map_single are
X * the same here.
X */
-extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
+extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents, int direction);
X
X /* Unmap a set of streaming mode DMA translations.
X * Again, cpu read rules concerning calls here are the same as for
X * pci_unmap_single() above.
X */
-extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
+extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nhwents, int direction);
X
X /* Make physical memory consistent for a single
X * streaming mode DMA translation after a transfer.
@@ -96,7 +109,8 @@
X * next point you give the PCI dma address back to the card, the
X * device again owns the buffer.
X */
-extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
+extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
+ size_t size, int direction);
X
X /* Make physical memory consistent for a set of streaming
X * mode DMA translations after a transfer.
@@ -111,7 +125,51 @@


X * only drive the low 24-bits during PCI bus mastering, then
X * you would pass 0x00ffffff as the mask to this function.
X */

-extern int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask);
+extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/* PCI IOMMU mapping bypass support. */
+
+/* PCI 64-bit addressing works for all slots on all controller
+ * types on sparc64. However, it requires that the device
+ * can drive enough of the 64 bits.
+ */
+#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0)
+#define PCI64_ADDR_BASE 0xfffc000000000000
+
+/* Usage of the pci_dac_foo interfaces is only valid if this
+ * test passes.
+ */
+#define pci_dac_dma_supported(pci_dev, mask) \
+ ((((mask) & PCI64_REQUIRED_MASK) == PCI64_REQUIRED_MASK) ? 1 : 0)


+
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{

+ return (PCI64_ADDR_BASE +
+ __pa(page_address(page)) + offset);


+}
+
+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{

+ unsigned long paddr = (dma_addr & PAGE_MASK) - PCI64_ADDR_BASE;
+
+ return virt_to_page(__va(paddr));


+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+ return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{

+ /* DAC cycle addressing does not make use of the
+ * PCI controller's streaming cache, so nothing to do.
+ */
+}
X

X /* Return the index of the PCI controller for device PDEV. */
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/pgalloc.h linux/include/asm-sparc64/pgalloc.h
--- v2.4.12/linux/include/asm-sparc64/pgalloc.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-sparc64/pgalloc.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: pgalloc.h,v 1.23 2001/09/25 20:21:48 kanoj Exp $ */
+/* $Id: pgalloc.h,v 1.26 2001/10/18 09:06:37 davem Exp $ */
X #ifndef _SPARC64_PGALLOC_H
X #define _SPARC64_PGALLOC_H
X
@@ -32,29 +32,14 @@
X
X extern void __flush_dcache_page(void *addr, int flush_icache);
X extern void __flush_icache_page(unsigned long);
-#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */
-#define flush_dcache_page(page) \
-do { if ((page)->mapping && \
- !((page)->mapping->i_mmap) && \
- !((page)->mapping->i_mmap_shared)) \
- set_bit(PG_dcache_dirty, &(page)->flags); \
- else \
- __flush_dcache_page((page)->virtual, \
- ((tlb_type == spitfire) && \
- (page)->mapping != NULL)); \
-} while(0)
-#else /* L1DCACHE_SIZE > PAGE_SIZE */
-#define flush_dcache_page(page) \
-do { if ((page)->mapping && \
- !((page)->mapping->i_mmap) && \
- !((page)->mapping->i_mmap_shared)) \
- set_bit(PG_dcache_dirty, &(page)->flags); \
- else \
- if ((tlb_type == spitfire) && \
- (page)->mapping != NULL) \
- __flush_icache_page(__get_phys((unsigned long)((page)->virtual))); \
-} while(0)
-#endif /* L1DCACHE_SIZE > PAGE_SIZE */
+extern void flush_dcache_page_impl(struct page *page);
+#ifdef CONFIG_SMP
+extern void smp_flush_dcache_page_impl(struct page *page);
+#else
+#define smp_flush_dcache_page_impl flush_dcache_page_impl
+#endif
+
+extern void flush_dcache_page(struct page *page);
X
X extern void __flush_dcache_range(unsigned long start, unsigned long end);
X
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- v2.4.12/linux/include/asm-sparc64/pgtable.h Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sparc64/pgtable.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.146 2001/09/11 02:20:23 kanoj Exp $
+/* $Id: pgtable.h,v 1.147 2001/10/17 18:26:58 davem Exp $
X * pgtable.h: SpitFire page table operations.
X *
X * Copyright 1996,1997 David S. Miller (da...@caip.rutgers.edu)
@@ -47,6 +47,29 @@
X #ifndef __ASSEMBLY__
X
X #define PG_dcache_dirty PG_arch_1
+
+#define dcache_dirty_cpu(page) \
+ (((page)->flags >> 24) & (NR_CPUS - 1UL))
+
+#define set_dcache_dirty(PAGE) \
+do { unsigned long mask = smp_processor_id(); \
+ unsigned long non_cpu_bits = (1UL << 24UL) - 1UL; \
+ mask = (mask << 24) | (1UL << PG_dcache_dirty); \
+ __asm__ __volatile__("1:\n\t" \
+ "ldx [%2], %%g7\n\t" \
+ "and %%g7, %1, %%g5\n\t" \
+ "or %%g5, %0, %%g5\n\t" \
+ "casx [%2], %%g7, %%g5\n\t" \
+ "cmp %%g7, %%g5\n\t" \
+ "bne,pn %%xcc, 1b\n\t" \
+ " nop" \
+ : /* no outputs */ \
+ : "r" (mask), "r" (non_cpu_bits), "r" (&(PAGE)->flags) \
+ : "g5", "g7"); \
+} while (0)
+
+#define clear_dcache_dirty(PAGE) \
+ clear_bit(PG_dcache_dirty, &(PAGE)->flags)
X
X /* Certain architectures need to do special things when pte's
X * within a page table are directly modified. Thus, the following
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/scatterlist.h linux/include/asm-sparc64/scatterlist.h
--- v2.4.12/linux/include/asm-sparc64/scatterlist.h Mon Dec 20 22:05:52 1999
+++ linux/include/asm-sparc64/scatterlist.h Fri Oct 12 15:35:54 2001
@@ -1,21 +1,27 @@
-/* $Id: scatterlist.h,v 1.9 1999/12/17 12:32:15 jj Exp $ */
+/* $Id: scatterlist.h,v 1.10 2001/10/09 02:24:35 davem Exp $ */
X #ifndef _SPARC64_SCATTERLIST_H
X #define _SPARC64_SCATTERLIST_H
X
X #include <asm/page.h>


X
X struct scatterlist {
- char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
- unsigned int length;

+ /* This will disappear in 2.5.x */
+ char *address;

X
- __u32 dvma_address; /* A place to hang host-specific addresses at. */
- __u32 dvma_length;


+ /* These two are only valid if ADDRESS member of this

+ * struct is NULL.
+ */


+ struct page *page;
+ unsigned int offset;
+

+ unsigned int length;


+
+ dma_addr_t dma_address;
+ __u32 dma_length;
X };
X

-#define sg_dma_address(sg) ((sg)->dvma_address)
-#define sg_dma_len(sg) ((sg)->dvma_length)
+#define sg_dma_address(sg) ((sg)->dma_address)


+#define sg_dma_len(sg) ((sg)->dma_length)
X
X #define ISA_DMA_THRESHOLD (~0UL)

X
diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/types.h linux/include/asm-sparc64/types.h
--- v2.4.12/linux/include/asm-sparc64/types.h Mon Jan 31 23:37:19 2000
+++ linux/include/asm-sparc64/types.h Fri Oct 12 15:35:54 2001
@@ -1,4 +1,4 @@
-/* $Id: types.h,v 1.3 2000/01/28 13:43:15 jj Exp $ */
+/* $Id: types.h,v 1.4 2001/10/09 02:24:35 davem Exp $ */
X #ifndef _SPARC64_TYPES_H
X #define _SPARC64_TYPES_H
X
@@ -45,9 +45,10 @@


X
X #define BITS_PER_LONG 64
X

-/* Dma addresses are 32-bits wide for now. */
+/* Dma addresses come in generic and 64-bit flavours. */
X

X typedef u32 dma_addr_t;
+typedef u64 dma64_addr_t;
X
X #endif /* __KERNEL__ */
X

diff -u --recursive --new-file v2.4.12/linux/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- v2.4.12/linux/include/asm-sparc64/unistd.h Thu Oct 11 08:02:26 2001
+++ linux/include/asm-sparc64/unistd.h Sun Oct 21 10:36:54 2001
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.48 2001/10/09 10:54:39 davem Exp $ */
+/* $Id: unistd.h,v 1.49 2001/10/18 08:27:05 davem Exp $ */
X #ifndef _SPARC64_UNISTD_H
X #define _SPARC64_UNISTD_H
X
@@ -220,7 +220,7 @@
X #define __NR_oldlstat 202 /* Linux Specific */
X #define __NR_uselib 203 /* Linux Specific */
X #define __NR_readdir 204 /* Linux Specific */
-/* #define __NR_ioperm 205 Linux Specific - i386 specific, unused */
+#define __NR_readahead 205 /* Linux Specific */
X #define __NR_socketcall 206 /* Linux Specific */
X #define __NR_syslog 207 /* Linux Specific */
X /* #define __NR_olduname 208 Linux Specific */
diff -u --recursive --new-file v2.4.12/linux/include/linux/b1lli.h linux/include/linux/b1lli.h
--- v2.4.12/linux/include/linux/b1lli.h Sat May 19 17:54:14 2001
+++ linux/include/linux/b1lli.h Thu Oct 11 09:47:33 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: b1lli.h,v 1.8.8.2 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1lli.h,v 1.8.8.3 2001/09/23 22:25:05 kai Exp $
X *
X * ISDN lowlevel-module for AVM B1-card.
X *
X * Copyright 1996 by Carsten Paeth (ca...@calle.in-berlin.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
X *
X */
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/b1pcmcia.h linux/include/linux/b1pcmcia.h
--- v2.4.12/linux/include/linux/b1pcmcia.h Sat May 19 17:54:14 2001
+++ linux/include/linux/b1pcmcia.h Thu Oct 11 09:47:33 2001


@@ -1,10 +1,12 @@
-/*

- * $Id: b1pcmcia.h,v 1.1.8.1 2001/05/17 20:41:52 kai Exp $
+/* $Id: b1pcmcia.h,v 1.1.8.2 2001/09/23 22:25:05 kai Exp $
X *
X * Exported functions of module b1pcmcia to be called by
X * avm_cs card services module.
X *
X * Copyright 1999 by Carsten Paeth (ca...@calle.in-berlin.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
X *
X */
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v2.4.12/linux/include/linux/blkdev.h Thu Oct 18 13:49:40 2001
+++ linux/include/linux/blkdev.h Tue Oct 23 22:01:01 2001
@@ -19,7 +19,6 @@
X struct request {
X struct list_head queue;
X int elevator_sequence;
- struct list_head table;
X
X volatile int rq_status; /* should split this into a few status bits */
X #define RQ_INACTIVE (-1)
@@ -202,5 +201,28 @@
X
X #define blk_finished_io(nsects) do { } while (0)
X #define blk_started_io(nsects) do { } while (0)
+
+static inline unsigned int blksize_bits(unsigned int size)
+{
+ unsigned int bits = 8;
+ do {
+ bits++;
+ size >>= 1;
+ } while (size > 256);
+ return bits;
+}
+
+static inline unsigned int block_size(kdev_t dev)
+{
+ int retval = BLOCK_SIZE;
+ int major = MAJOR(dev);
+
+ if (blksize_size[major]) {
+ int minor = MINOR(dev);
+ if (blksize_size[major][minor])
+ retval = blksize_size[major][minor];


+ }
+ return retval;
+}

X
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/linux/console_struct.h linux/include/linux/console_struct.h
--- v2.4.12/linux/include/linux/console_struct.h Mon Oct 16 12:53:18 2000
+++ linux/include/linux/console_struct.h Thu Oct 11 11:17:22 2001
@@ -68,7 +68,7 @@
X unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
X unsigned char vc_utf_count;
X int vc_utf_char;
- unsigned int vc_tab_stop[5]; /* Tab stops. 160 columns. */
+ unsigned int vc_tab_stop[8]; /* Tab stops. 256 columns. */
X unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */
X unsigned short * vc_translate;
X unsigned char vc_G0_charset;
diff -u --recursive --new-file v2.4.12/linux/include/linux/ethtool.h linux/include/linux/ethtool.h
--- v2.4.12/linux/include/linux/ethtool.h Mon Aug 27 12:41:48 2001
+++ linux/include/linux/ethtool.h Wed Oct 17 14:16:39 2001
@@ -53,7 +53,10 @@
X #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
X #define ETHTOOL_GREGS 0x00000004 /* Get NIC registers, privileged. */
X #define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
-#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */
+#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options, priv. */
+#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */
+#define ETHTOOL_NWAY_RST 0X00000009 /* Restart autonegotiation, priv. */
X
X /* compatibility with older code */
X #define SPARC_ETH_GSET ETHTOOL_GSET
@@ -71,6 +74,7 @@
X #define SUPPORTED_AUI (1 << 8)
X #define SUPPORTED_MII (1 << 9)
X #define SUPPORTED_FIBRE (1 << 10)
+#define SUPPORTED_10base2 (1 << 11)
X
X /* Indicates what features are advertised by the interface. */
X #define ADVERTISED_10baseT_Half (1 << 0)
@@ -84,6 +88,7 @@
X #define ADVERTISED_AUI (1 << 8)
X #define ADVERTISED_MII (1 << 9)
X #define ADVERTISED_FIBRE (1 << 10)
+#define ADVERTISED_10base2 (1 << 11)
X
X /* The following are all involved in forcing a particular link
X * mode for the device for setting things. When getting the
diff -u --recursive --new-file v2.4.12/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.4.12/linux/include/linux/ext2_fs.h Thu Oct 18 13:48:05 2001
+++ linux/include/linux/ext2_fs.h Tue Oct 23 21:59:31 2001
@@ -558,14 +558,15 @@
X unsigned int block_group,
X struct buffer_head ** bh);
X
-/* bitmap.c */
-extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
-
X /* dir.c */
-
-/* file.c */
-extern int ext2_read (struct inode *, struct file *, char *, int);
-extern int ext2_write (struct inode *, struct file *, char *, int);
+extern int ext2_add_link (struct dentry *, struct inode *);
+extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern int ext2_make_empty(struct inode *, struct inode *);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
+extern int ext2_empty_dir (struct inode *);
+extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
+extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
X
X /* fsync.c */
X extern int ext2_sync_file (struct file *, struct dentry *, int);
@@ -576,26 +577,21 @@
X extern void ext2_free_inode (struct inode *);
X extern unsigned long ext2_count_free_inodes (struct super_block *);
X extern void ext2_check_inodes_bitmap (struct super_block *);
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
X
X /* inode.c */
-
-extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
-extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
-
X extern void ext2_read_inode (struct inode *);
X extern void ext2_write_inode (struct inode *, int);
X extern void ext2_put_inode (struct inode *);
X extern void ext2_delete_inode (struct inode *);
X extern int ext2_sync_inode (struct inode *);
X extern void ext2_discard_prealloc (struct inode *);
+extern void ext2_truncate (struct inode *);
X
X /* ioctl.c */
X extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
X unsigned long);
X
-/* namei.c */
-extern struct inode_operations ext2_dir_inode_operations;
-
X /* super.c */
X extern void ext2_error (struct super_block *, const char *, const char *, ...)
X __attribute__ ((format (printf, 3, 4)));
@@ -611,32 +607,25 @@
X extern struct super_block * ext2_read_super (struct super_block *,void *,int);
X extern int ext2_statfs (struct super_block *, struct statfs *);
X
-/* truncate.c */
-extern void ext2_truncate (struct inode *);
-
X /*
X * Inodes and files operations
X */
X
X /* dir.c */
X extern struct file_operations ext2_dir_operations;
-extern int ext2_add_link (struct dentry *, struct inode *);
-extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
-extern int ext2_make_empty(struct inode *, struct inode *);
-extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
-extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
-extern int ext2_empty_dir (struct inode *);
-extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
-extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
X
X /* file.c */
X extern struct inode_operations ext2_file_inode_operations;
X extern struct file_operations ext2_file_operations;
X
+/* inode.c */
+extern struct address_space_operations ext2_aops;
+
+/* namei.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
X /* symlink.c */
X extern struct inode_operations ext2_fast_symlink_inode_operations;
-
-extern struct address_space_operations ext2_aops;


X
X #endif /* __KERNEL__ */
X

diff -u --recursive --new-file v2.4.12/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.12/linux/include/linux/fs.h Thu Oct 18 13:47:38 2001
+++ linux/include/linux/fs.h Tue Oct 23 21:59:06 2001
@@ -214,7 +214,8 @@
X BH_Mapped, /* 1 if the buffer has a disk mapping */
X BH_New, /* 1 if the buffer is new and not yet written out */
X BH_Async, /* 1 if the buffer is under end_buffer_io_async I/O */
- BH_Wait_IO, /* 1 if we should throttle on this buffer */
+ BH_Wait_IO, /* 1 if we should write out this buffer */
+ BH_launder, /* 1 if we should throttle on this buffer */
X
X BH_PrivateStart,/* not a state bit, but the first bit available
X * for private allocation by other entities
@@ -604,6 +605,7 @@
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 posix_locks_deadlock(struct file_lock *, struct file_lock *);
X extern int __get_lease(struct inode *inode, unsigned int flags);
X extern time_t lease_get_mtime(struct inode *);
X extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
diff -u --recursive --new-file v2.4.12/linux/include/linux/genhd.h linux/include/linux/genhd.h
--- v2.4.12/linux/include/linux/genhd.h Thu Oct 18 13:49:34 2001
+++ linux/include/linux/genhd.h Tue Oct 23 22:00:42 2001
@@ -58,8 +58,8 @@
X # include <linux/devfs_fs_kernel.h>
X
X struct hd_struct {
- long start_sect;
- long nr_sects;
+ unsigned long start_sect;
+ unsigned long nr_sects;
X devfs_handle_t de; /* primary (master) devfs entry */
X int number; /* stupid old code wastes space */
X };
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-dev.h linux/include/linux/i2c-dev.h
--- v2.4.12/linux/include/linux/i2c-dev.h Sun Aug 12 13:28:01 2001
+++ linux/include/linux/i2c-dev.h Thu Oct 11 08:05:47 2001
@@ -19,7 +19,7 @@
X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X */
X
-/* $Id: i2c-dev.h,v 1.8 2000/08/12 16:37:15 mds Exp $ */
+/* $Id: i2c-dev.h,v 1.9 2001/08/15 03:04:58 mds Exp $ */
X
X #ifndef I2C_DEV_H
X #define I2C_DEV_H
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-elektor.h linux/include/linux/i2c-elektor.h
--- v2.4.12/linux/include/linux/i2c-elektor.h Fri Jan 28 19:36:23 2000
+++ linux/include/linux/i2c-elektor.h Thu Oct 11 08:05:47 2001
@@ -22,22 +22,26 @@
X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi> and even
X Frodo Looijaard <fro...@dds.nl> */
X
-/* $Id: i2c-elektor.h,v 1.4 2000/01/18 23:54:07 frodo Exp $ */
+/* $Id: i2c-elektor.h,v 1.5 2001/06/05 01:46:33 mds Exp $ */
X
X #ifndef I2C_PCF_ELEKTOR_H
X #define I2C_PCF_ELEKTOR_H 1
X
X /*
- * This struct contains the hw-dependent functions of PCF8584 adapters to
- * manipulate the registers, and to init any hw-specific features.
- */
+ * This struct contains the hw-dependent functions of PCF8584 adapters to
+ * manipulate the registers, and to init any hw-specific features.
+ * vdovikin: removed: this module in real supports only one device,
+ * due to missing arguments in some functions, called from the algo-pcf module.
+ * Sometimes it's need to be rewriten -
+ * but for now just remove this for simpler reading */
X
+/*
X struct i2c_pcf_isa {
X int pi_base;
X int pi_irq;
X int pi_clock;
X int pi_own;
X };
-
+*/
X
X #endif /* PCF_ELEKTOR_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-id.h linux/include/linux/i2c-id.h
--- v2.4.12/linux/include/linux/i2c-id.h Sun Sep 23 11:41:01 2001
+++ linux/include/linux/i2c-id.h Thu Oct 11 08:05:47 2001
@@ -20,7 +20,7 @@
X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
X /* ------------------------------------------------------------------------- */
X
-/* $Id: i2c-id.h,v 1.25 2000/10/12 07:27:29 simon Exp $ */
+/* $Id: i2c-id.h,v 1.35 2001/08/12 17:22:20 mds Exp $ */
X
X #ifndef I2C_ID_H
X #define I2C_ID_H
@@ -65,7 +65,7 @@
X #define I2C_DRIVERID_BT829 19 /* pc to tv encoder */
X #define I2C_DRIVERID_TDA9850 20 /* audio mixer */
X #define I2C_DRIVERID_TDA9855 21 /* audio mixer */
-#define I2C_DRIVERID_SAA7110 22 /* */
+#define I2C_DRIVERID_SAA7110 22 /* video decoder */
X #define I2C_DRIVERID_MGATVO 23 /* Matrox TVOut */
X #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */
X #define I2C_DRIVERID_PCF8583 25 /* real time clock */
@@ -84,7 +84,12 @@
X #define I2C_DRIVERID_VES1820 37 /* VLSI DVB-C decoder */
X #define I2C_DRIVERID_SAA7113 38 /* video decoder */
X #define I2C_DRIVERID_TDA8444 39 /* octuple 6-bit DAC */
-
+#define I2C_DRIVERID_BT819 40 /* video decoder */
+#define I2C_DRIVERID_BT856 41 /* video encoder */
+#define I2C_DRIVERID_VPX32XX 42 /* video decoder+vbi/vtxt */
+#define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */
+#define I2C_DRIVERID_SP5055 44 /* Satellite tuner */
+#define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */
X
X #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
X #define I2C_DRIVERID_EXP1 0xF1
@@ -94,6 +99,35 @@
X #define I2C_DRIVERID_I2CDEV 900
X #define I2C_DRIVERID_I2CPROC 901
X
+/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
+ These were originally in sensors.h in the lm_sensors package */
+#define I2C_DRIVERID_LM78 1002
+#define I2C_DRIVERID_LM75 1003
+#define I2C_DRIVERID_GL518 1004
+#define I2C_DRIVERID_EEPROM 1005
+#define I2C_DRIVERID_W83781D 1006
+#define I2C_DRIVERID_LM80 1007
+#define I2C_DRIVERID_ADM1021 1008
+#define I2C_DRIVERID_ADM9240 1009
+#define I2C_DRIVERID_LTC1710 1010
+#define I2C_DRIVERID_SIS5595 1011
+#define I2C_DRIVERID_ICSPLL 1012
+#define I2C_DRIVERID_BT869 1013
+#define I2C_DRIVERID_MAXILIFE 1014
+#define I2C_DRIVERID_MATORB 1015
+#define I2C_DRIVERID_GL520 1016
+#define I2C_DRIVERID_THMC50 1017
+#define I2C_DRIVERID_DDCMON 1018
+#define I2C_DRIVERID_VIA686A 1019
+#define I2C_DRIVERID_ADM1025 1020
+#define I2C_DRIVERID_LM87 1021
+#define I2C_DRIVERID_PCF8574 1022
+#define I2C_DRIVERID_MTP008 1023
+#define I2C_DRIVERID_DS1621 1024
+#define I2C_DRIVERID_ADM1024 1025
+#define I2C_DRIVERID_IT87 1026
+#define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
+
X /*
X * ---- Adapter types ----------------------------------------------------
X *
@@ -109,7 +143,6 @@
X #define I2C_ALGO_ISA 0x050000 /* lm_sensors ISA pseudo-adapter */
X #define I2C_ALGO_SAA7146 0x060000 /* SAA 7146 video decoder bus */
X #define I2C_ALGO_ACB 0x070000 /* ACCESS.bus algorithm */
-#define I2C_ALGO_IIC 0x080000 /* ITE IIC bus */
X
X #define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */
X
@@ -140,8 +173,10 @@
X #define I2C_HW_B_G400 0x09 /* Matrox G400 */
X #define I2C_HW_B_I810 0x0a /* Intel I810 */
X #define I2C_HW_B_VOO 0x0b /* 3dfx Voodoo 3 / Banshee */
+#define I2C_HW_B_PPORT 0x0c /* Primitive parallel port adapter */
X #define I2C_HW_B_RIVA 0x10 /* Riva based graphics cards */
X #define I2C_HW_B_IOC 0x11 /* IOC bit-wiggling */
+#define I2C_HW_B_TSUNA 0x12 /* DEC Tsunami chipset */
X
X /* --- PCF 8584 based algorithms */
X #define I2C_HW_P_LP 0x00 /* Parallel port interface */
@@ -153,9 +188,6 @@
X
X /* --- MPC8xx PowerPC adapters */
X #define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */
-
-/* --- ITE based algorithms */
-#define I2C_HW_I_IIC 0x00 /* controller on the ITE */
X
X /* --- SMBus only adapters */
X #define I2C_HW_SMBUS_PIIX4 0x00
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c-proc.h linux/include/linux/i2c-proc.h
--- v2.4.12/linux/include/linux/i2c-proc.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/i2c-proc.h Thu Oct 11 08:05:47 2001
@@ -0,0 +1,396 @@
+/*
+ sensors.h - Part of lm_sensors, Linux kernel modules for hardware
+ monitoring
+ Copyright (c) 1998, 1999 Frodo Looijaard <fro...@dds.nl>
+
+ 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.
+*/
+
+#ifndef SENSORS_SENSORS_H
+#define SENSORS_SENSORS_H
+
+#ifdef __KERNEL__
+
+/* Next two must be included before sysctl.h can be included, in 2.0 kernels */
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+
+/* The type of callback functions used in sensors_{proc,sysctl}_real */
+typedef void (*i2c_real_callback) (struct i2c_client * client,
+ int operation, int ctl_name,
+ int *nrels_mag, long *results);
+
+/* Values for the operation field in the above function type */
+#define SENSORS_PROC_REAL_INFO 1
+#define SENSORS_PROC_REAL_READ 2
+#define SENSORS_PROC_REAL_WRITE 3
+
+/* These funcion reads or writes a 'real' value (encoded by the combination
+ of an integer and a magnitude, the last is the power of ten the value
+ should be divided with) to a /proc/sys directory. To use these functions,
+ you must (before registering the ctl_table) set the extra2 field to the
+ client, and the extra1 field to a function of the form:
+ void func(struct i2c_client *client, int operation, int ctl_name,
+ int *nrels_mag, long *results)
+ This last function can be called for three values of operation. If
+ operation equals SENSORS_PROC_REAL_INFO, the magnitude should be returned
+ in nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
+ be read into results. nrels_mag should return the number of elements
+ read; the maximum number is put in it on entry. Finally, if operation
+ equals SENSORS_PROC_REAL_WRITE, the values in results should be
+ written to the chip. nrels_mag contains on entry the number of elements
+ found.
+ In all cases, client points to the client we wish to interact with,
+ and ctl_name is the SYSCTL id of the file we are accessing. */
+extern int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
+ void *oldval, size_t * oldlenp,
+ void *newval, size_t newlen,
+ void **context);
+extern int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
+ void *buffer, size_t * lenp);
+
+
+
+/* These rather complex functions must be called when you want to add or
+ delete an entry in /proc/sys/dev/sensors/chips (not yet implemented). It
+ also creates a new directory within /proc/sys/dev/sensors/.
+ ctl_template should be a template of the newly created directory. It is
+ copied in memory. The extra2 field of each file is set to point to client.
+ If any driver wants subdirectories within the newly created directory,
+ these functions must be updated! */
+extern int i2c_register_entry(struct i2c_client *client,
+ const char *prefix,
+ ctl_table * ctl_template,
+ struct module *controlling_mod);
+
+extern void i2c_deregister_entry(int id);
+
+
+/* A structure containing detect information.
+ Force variables overrule all other variables; they force a detection on
+ that place. If a specific chip is given, the module blindly assumes this
+ chip type is present; if a general force (kind == 0) is given, the module
+ will still try to figure out what type of chip is present. This is useful
+ if for some reasons the detect for SMBus or ISA address space filled
+ fails.
+ probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+ A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+ the ISA bus, -1 for any I2C bus), the second is the address.
+ kind: The kind of chip. 0 equals any chip.
+*/
+struct i2c_force_data {
+ unsigned short *force;
+ unsigned short kind;
+};
+
+/* A structure containing the detect information.
+ normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
+ A list of I2C addresses which should normally be examined.
+ normal_i2c_range: filled in by the module writer. Terminated by
+ SENSORS_I2C_END
+ A list of pairs of I2C addresses, each pair being an inclusive range of
+ addresses which should normally be examined.
+ normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
+ A list of ISA addresses which should normally be examined.
+ normal_isa_range: filled in by the module writer. Terminated by
+ SENSORS_ISA_END
+ A list of triples. The first two elements are ISA addresses, being an
+ range of addresses which should normally be examined. The third is the
+ modulo parameter: only addresses which are 0 module this value relative
+ to the first address of the range are actually considered.
+ probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+ A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+ the ISA bus, -1 for any I2C bus), the second is the address. These
+ addresses are also probed, as if they were in the 'normal' list.
+ probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END
+ values.
+ A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+ the ISA bus, -1 for any I2C bus), the second and third are addresses.
+ These form an inclusive range of addresses that are also probed, as
+ if they were in the 'normal' list.
+ ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
+ A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
+ the ISA bus, -1 for any I2C bus), the second is the I2C address. These
+ addresses are never probed. This parameter overrules 'normal' and
+ 'probe', but not the 'force' lists.
+ ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END
+ values.
+ A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
+ the ISA bus, -1 for any I2C bus), the second and third are addresses.
+ These form an inclusive range of I2C addresses that are never probed.
+ This parameter overrules 'normal' and 'probe', but not the 'force' lists.
+ force_data: insmod parameters. A list, ending with an element of which
+ the force field is NULL.
+*/
+struct i2c_address_data {
+ unsigned short *normal_i2c;
+ unsigned short *normal_i2c_range;
+ unsigned int *normal_isa;
+ unsigned int *normal_isa_range;
+ unsigned short *probe;
+ unsigned short *probe_range;
+ unsigned short *ignore;
+ unsigned short *ignore_range;
+ struct i2c_force_data *forces;
+};
+
+/* Internal numbers to terminate lists */
+#define SENSORS_I2C_END 0xfffe
+#define SENSORS_ISA_END 0xfffefffe
+
+/* The numbers to use to set an ISA or I2C bus address */
+#define SENSORS_ISA_BUS 9191
+#define SENSORS_ANY_I2C_BUS 0xffff
+
+/* The length of the option lists */
+#define SENSORS_MAX_OPTS 48
+
+/* Default fill of many variables */
+#define SENSORS_DEFAULTS {SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 50'
echo 'File patch-2.4.13 is continued in part 51'
echo "51" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:21 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part51

#!/bin/sh -x
# this is part 51 of a 53 - part archive


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

if test "$Scheck" != 51; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END, \
+ SENSORS_I2C_END, SENSORS_I2C_END, SENSORS_I2C_END}
+
+/* This is ugly. We need to evaluate SENSORS_MAX_OPTS before it is
+ stringified */
+#define SENSORS_MODPARM_AUX1(x) "1-" #x "h"
+#define SENSORS_MODPARM_AUX(x) SENSORS_MODPARM_AUX1(x)
+#define SENSORS_MODPARM SENSORS_MODPARM_AUX(SENSORS_MAX_OPTS)
+
+/* SENSORS_MODULE_PARM creates a module parameter, and puts it in the
+ module header */
+#define SENSORS_MODULE_PARM(var,desc) \
+ static unsigned short var[SENSORS_MAX_OPTS] = SENSORS_DEFAULTS; \
+ MODULE_PARM(var,SENSORS_MODPARM); \
+ MODULE_PARM_DESC(var,desc)
+
+/* SENSORS_MODULE_PARM creates a 'force_*' module parameter, and puts it in
+ the module header */
+#define SENSORS_MODULE_PARM_FORCE(name) \
+ SENSORS_MODULE_PARM(force_ ## name, \
+ "List of adapter,address pairs which are unquestionably" \
+ " assumed to contain a `" # name "' chip")
+
+
+/* This defines several insmod variables, and the addr_data structure */
+#define SENSORS_INSMOD \
+ SENSORS_MODULE_PARM(probe, \
+ "List of adapter,address pairs to scan additionally"); \
+ SENSORS_MODULE_PARM(probe_range, \
+ "List of adapter,start-addr,end-addr triples to scan " \
+ "additionally"); \
+ SENSORS_MODULE_PARM(ignore, \
+ "List of adapter,address pairs not to scan"); \
+ SENSORS_MODULE_PARM(ignore_range, \
+ "List of adapter,start-addr,end-addr triples not to " \
+ "scan"); \
+ static struct i2c_address_data addr_data = \
+ {normal_i2c, normal_i2c_range, \
+ normal_isa, normal_isa_range, \
+ probe, probe_range, \
+ ignore, ignore_range, \
+ forces}
+
+/* The following functions create an enum with the chip names as elements.
+ The first element of the enum is any_chip. These are the only macros
+ a module will want to use. */
+
+#define SENSORS_INSMOD_0 \
+ enum chips { any_chip }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ static struct i2c_force_data forces[] = {{force,any_chip},{NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_1(chip1) \
+ enum chips { any_chip, chip1 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ static struct i2c_force_data forces[] = {{force,any_chip},\
+ {force_ ## chip1,chip1}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_2(chip1,chip2) \
+ enum chips { any_chip, chip1, chip2 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_3(chip1,chip2,chip3) \
+ enum chips { any_chip, chip1, chip2, chip3 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ SENSORS_MODULE_PARM_FORCE(chip3); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {force_ ## chip3,chip3}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_4(chip1,chip2,chip3,chip4) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ SENSORS_MODULE_PARM_FORCE(chip3); \
+ SENSORS_MODULE_PARM_FORCE(chip4); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {force_ ## chip3,chip3}, \
+ {force_ ## chip4,chip4}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_5(chip1,chip2,chip3,chip4,chip5) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ SENSORS_MODULE_PARM_FORCE(chip3); \
+ SENSORS_MODULE_PARM_FORCE(chip4); \
+ SENSORS_MODULE_PARM_FORCE(chip5); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {force_ ## chip3,chip3}, \
+ {force_ ## chip4,chip4}, \
+ {force_ ## chip5,chip5}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_6(chip1,chip2,chip3,chip4,chip5,chip6) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ SENSORS_MODULE_PARM_FORCE(chip3); \
+ SENSORS_MODULE_PARM_FORCE(chip4); \
+ SENSORS_MODULE_PARM_FORCE(chip5); \
+ SENSORS_MODULE_PARM_FORCE(chip6); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {force_ ## chip3,chip3}, \
+ {force_ ## chip4,chip4}, \
+ {force_ ## chip5,chip5}, \
+ {force_ ## chip6,chip6}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+#define SENSORS_INSMOD_7(chip1,chip2,chip3,chip4,chip5,chip6,chip7) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, chip7 }; \
+ SENSORS_MODULE_PARM(force, \
+ "List of adapter,address pairs to boldly assume " \
+ "to be present"); \
+ SENSORS_MODULE_PARM_FORCE(chip1); \
+ SENSORS_MODULE_PARM_FORCE(chip2); \
+ SENSORS_MODULE_PARM_FORCE(chip3); \
+ SENSORS_MODULE_PARM_FORCE(chip4); \
+ SENSORS_MODULE_PARM_FORCE(chip5); \
+ SENSORS_MODULE_PARM_FORCE(chip6); \
+ SENSORS_MODULE_PARM_FORCE(chip7); \
+ static struct i2c_force_data forces[] = {{force,any_chip}, \
+ {force_ ## chip1,chip1}, \
+ {force_ ## chip2,chip2}, \
+ {force_ ## chip3,chip3}, \
+ {force_ ## chip4,chip4}, \
+ {force_ ## chip5,chip5}, \
+ {force_ ## chip6,chip6}, \
+ {force_ ## chip7,chip7}, \
+ {NULL}}; \
+ SENSORS_INSMOD
+
+typedef int i2c_found_addr_proc(struct i2c_adapter *adapter,
+ int addr, unsigned short flags,
+ int kind);
+
+/* Detect function. It iterates over all possible addresses itself. For
+ SMBus addresses, it will only call found_proc if some client is connected
+ to the SMBus (unless a 'force' matched); for ISA detections, this is not
+ done. */
+extern int i2c_detect(struct i2c_adapter *adapter,
+ struct i2c_address_data *address_data,
+ i2c_found_addr_proc * found_proc);
+
+
+/* This macro is used to scale user-input to sensible values in almost all
+ chip drivers. */
+extern inline int SENSORS_LIMIT(long value, long low, long high)
+{
+ if (value < low)
+ return low;
+ else if (value > high)
+ return high;
+ else
+ return value;
+}
+
+#endif /* def __KERNEL__ */
+
+
+/* The maximum length of the prefix */
+#define SENSORS_PREFIX_MAX 20
+
+/* Sysctl IDs */
+#ifdef DEV_HWMON
+#define DEV_SENSORS DEV_HWMON
+#else /* ndef DEV_HWMOM */
+#define DEV_SENSORS 2 /* The id of the lm_sensors directory within the
+ dev table */
+#endif /* def DEV_HWMON */
+
+#define SENSORS_CHIPS 1
+struct i2c_chips_data {
+ int sysctl_id;
+ char name[SENSORS_PREFIX_MAX + 13];
+};
+
+#endif /* def SENSORS_SENSORS_H */
+
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2c.h linux/include/linux/i2c.h
--- v2.4.12/linux/include/linux/i2c.h Tue Mar 6 19:44:37 2001
+++ linux/include/linux/i2c.h Thu Oct 11 08:05:47 2001
@@ -23,11 +23,14 @@


X /* With some changes from Kyösti Mälkki <kma...@cc.hut.fi> and

X Frodo Looijaard <fro...@dds.nl> */
X

-/* $Id: i2c.h,v 1.42 2000/09/06 20:14:06 frodo Exp $ */
+/* $Id: i2c.h,v 1.46 2001/08/31 00:04:07 phil Exp $ */
X
X #ifndef I2C_H
X #define I2C_H
X
+#define I2C_DATE "20010830"
+#define I2C_VERSION "2.6.1"
+
X #include <linux/i2c-id.h> /* id values of adapters et. al. */
X #include <linux/types.h>
X
@@ -202,7 +205,7 @@
X char name[32]; /* textual description */
X unsigned int id;
X
- /* If a adapter algorithm can't to I2C-level access, set master_xfer
+ /* If an adapter algorithm can't to I2C-level access, set master_xfer
X to NULL. If an adapter algorithm can do SMBus access, set
X smbus_xfer. If set to NULL, the SMBus protocol is simulated
X using common I2C messages */
@@ -344,7 +347,7 @@
X you can cheat by simply not registering. Not recommended, of course! */
X extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
X
-/* Detect function. It itterates over all possible addresses itself.
+/* Detect function. It iterates over all possible addresses itself.
X * It will only call found_proc if some client is connected at the
X * specific address (unless a 'force' matched);
X */
@@ -360,7 +363,7 @@
X extern int i2c_control(struct i2c_client *,unsigned int, unsigned long);
X
X /* This call returns a unique low identifier for each registered adapter,
- * or -1 if the adapter was not regisitered.
+ * or -1 if the adapter was not registered.
X */
X extern int i2c_adapter_id(struct i2c_adapter *adap);
X
@@ -454,8 +457,9 @@
X * corresponding header files.
X */
X /* -> bit-adapter specific ioctls */
-#define I2C_RETRIES 0x0701 /* number times a device address should */
- /* be polled when not acknowledging */
+#define I2C_RETRIES 0x0701 /* number of times a device address */
+ /* should be polled when not */
+ /* acknowledging */
X #define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
X
X
@@ -548,6 +552,13 @@
X probe, probe_range, \
X ignore, ignore_range, \
X force}
+
+/* Detect whether we are on the isa bus. If this returns true, all i2c
+ access will fail! */
+#define i2c_is_isa_client(clientptr) \
+ ((clientptr)->adapter->algo->id == I2C_ALGO_ISA)
+#define i2c_is_isa_adapter(adapptr) \
+ ((adapptr)->algo->id == I2C_ALGO_ISA)
X
X #endif /* def __KERNEL__ */
X #endif /* I2C_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2o-dev.h linux/include/linux/i2o-dev.h
--- v2.4.12/linux/include/linux/i2o-dev.h Wed Apr 12 09:38:53 2000
+++ linux/include/linux/i2o-dev.h Thu Oct 11 11:17:22 2001
@@ -34,11 +34,11 @@
X #define I2OLCTGET _IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct)
X #define I2OPARMSET _IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget)
X #define I2OPARMGET _IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget)
-#define I2OSWDL _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
-#define I2OSWUL _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
+#define I2OSWDL _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
+#define I2OSWUL _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
X #define I2OSWDEL _IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer)
X #define I2OVALIDATE _IOR(I2O_MAGIC_NUMBER,8,u32)
-#define I2OHTML _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
+#define I2OHTML _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
X #define I2OEVTREG _IOW(I2O_MAGIC_NUMBER,10,struct i2o_evt_id)
X #define I2OEVTGET _IOR(I2O_MAGIC_NUMBER,11,struct i2o_evt_info)
X
@@ -68,7 +68,7 @@
X void *buf; /* Pointer to software buffer */
X unsigned int *swlen; /* Length of software data */
X unsigned int *maxfrag; /* Maximum fragment count */
- unsigned int *curfrag; /* Current fragment count */
+ unsigned int *curfrag; /* Current fragment count */
X };
X
X struct i2o_html
@@ -98,7 +98,7 @@
X {
X struct i2o_evt_id id;
X unsigned char evt_data[I2O_EVT_DATA_SIZE];
- unsigned int data_size;
+ unsigned int data_size;
X };
X
X struct i2o_evt_get
@@ -119,8 +119,8 @@
X #define I2O_BUS_PCI 4
X #define I2O_BUS_PCMCIA 5
X #define I2O_BUS_NUBUS 6
-#define I2O_BUS_CARDBUS 7
-#define I2O_BUS_UNKNOWN 0x80
+#define I2O_BUS_CARDBUS 7
+#define I2O_BUS_UNKNOWN 0x80
X
X #ifndef __KERNEL__
X
@@ -130,127 +130,139 @@


X
X #endif /* __KERNEL__ */
X

-typedef struct _i2o_pci_bus {
- u8 PciFunctionNumber;
- u8 PciDeviceNumber;
- u8 PciBusNumber;
- u8 reserved;
- u16 PciVendorID;
- u16 PciDeviceID;
+typedef struct _i2o_pci_bus
+{
+ u8 PciFunctionNumber;
+ u8 PciDeviceNumber;
+ u8 PciBusNumber;
+ u8 reserved;
+ u16 PciVendorID;
+ u16 PciDeviceID;
X } i2o_pci_bus;
X
-typedef struct _i2o_local_bus {
- u16 LbBaseIOPort;
- u16 reserved;
- u32 LbBaseMemoryAddress;
+typedef struct _i2o_local_bus
+{
+ u16 LbBaseIOPort;
+ u16 reserved;
+ u32 LbBaseMemoryAddress;
X } i2o_local_bus;
X
-typedef struct _i2o_isa_bus {
- u16 IsaBaseIOPort;
- u8 CSN;
- u8 reserved;
- u32 IsaBaseMemoryAddress;
+typedef struct _i2o_isa_bus
+{
+ u16 IsaBaseIOPort;
+ u8 CSN;
+ u8 reserved;
+ u32 IsaBaseMemoryAddress;
X } i2o_isa_bus;
X
-typedef struct _i2o_eisa_bus_info {
- u16 EisaBaseIOPort;
- u8 reserved;
- u8 EisaSlotNumber;
- u32 EisaBaseMemoryAddress;
+typedef struct _i2o_eisa_bus_info
+{
+ u16 EisaBaseIOPort;
+ u8 reserved;
+ u8 EisaSlotNumber;
+ u32 EisaBaseMemoryAddress;
X } i2o_eisa_bus;
X
-typedef struct _i2o_mca_bus {
- u16 McaBaseIOPort;
- u8 reserved;
- u8 McaSlotNumber;
- u32 McaBaseMemoryAddress;
+typedef struct _i2o_mca_bus
+{
+ u16 McaBaseIOPort;
+ u8 reserved;
+ u8 McaSlotNumber;
+ u32 McaBaseMemoryAddress;
X } i2o_mca_bus;
X
-typedef struct _i2o_other_bus {
+typedef struct _i2o_other_bus
+{
X u16 BaseIOPort;
X u16 reserved;
X u32 BaseMemoryAddress;
X } i2o_other_bus;
X
-typedef struct _i2o_hrt_entry {
- u32 adapter_id;
- u32 parent_tid:12;
- u32 state:4;
- u32 bus_num:8;
- u32 bus_type:8;
- union {
- i2o_pci_bus pci_bus;
- i2o_local_bus local_bus;
- i2o_isa_bus isa_bus;
- i2o_eisa_bus eisa_bus;
- i2o_mca_bus mca_bus;
- i2o_other_bus other_bus;
+typedef struct _i2o_hrt_entry
+{
+ u32 adapter_id;
+ u32 parent_tid:12;
+ u32 tate:4;
+ u32 bus_num:8;
+ u32 bus_type:8;
+ union
+ {
+ i2o_pci_bus pci_bus;
+ i2o_local_bus local_bus;
+ i2o_isa_bus isa_bus;
+ i2o_eisa_bus eisa_bus;
+ i2o_mca_bus mca_bus;
+ i2o_other_bus other_bus;
X } bus;
X } i2o_hrt_entry;
X
-typedef struct _i2o_hrt {
- u16 num_entries;
- u8 entry_len;
- u8 hrt_version;
- u32 change_ind;
+typedef struct _i2o_hrt
+{
+ u16 num_entries;
+ u8 entry_len;
+ u8 hrt_version;
+ u32 change_ind;
X i2o_hrt_entry hrt_entry[1];
X } i2o_hrt;
X
-typedef struct _i2o_lct_entry {
- u32 entry_size:16;
- u32 tid:12;
- u32 reserved:4;
- u32 change_ind;
- u32 device_flags;
- u32 class_id:12;
- u32 version:4;
- u32 vendor_id:16;
- u32 sub_class;
- u32 user_tid:12;
- u32 parent_tid:12;
- u32 bios_info:8;
- u8 identity_tag[8];
- u32 event_capabilities;
+typedef struct _i2o_lct_entry
+{
+ u32 entry_size:16;
+ u32 tid:12;
+ u32 reserved:4;
+ u32 change_ind;
+ u32 device_flags;
+ u32 class_id:12;
+ u32 version:4;
+ u32 vendor_id:16;
+ u32 sub_class;
+ u32 user_tid:12;
+ u32 parent_tid:12;
+ u32 bios_info:8;
+ u8 identity_tag[8];
+ u32 event_capabilities;
X } i2o_lct_entry;
X
-typedef struct _i2o_lct {
- u32 table_size:16;
- u32 boot_tid:12;
- u32 lct_ver:4;
- u32 iop_flags;
- u32 change_ind;
+typedef struct _i2o_lct
+{
+ u32 table_size:16;
+ u32 boot_tid:12;
+ u32 lct_ver:4;
+ u32 iop_flags;
+ u32 change_ind;
X i2o_lct_entry lct_entry[1];
X } i2o_lct;
X
-typedef struct _i2o_status_block {
- u16 org_id;
- u16 reserved;
- u16 iop_id:12;
- u16 reserved1:4;
- u16 host_unit_id;
- u16 segment_number:12;
- u16 i2o_version:4;
- u8 iop_state;
- u8 msg_type;
- u16 inbound_frame_size;
- u8 init_code;
- u8 reserved2;
- u32 max_inbound_frames;
- u32 cur_inbound_frames;
- u32 max_outbound_frames;
- char product_id[24];
- u32 expected_lct_size;
- u32 iop_capabilities;
- u32 desired_mem_size;
- u32 current_mem_size;
- u32 current_mem_base;
- u32 desired_io_size;
- u32 current_io_size;
- u32 current_io_base;
- u32 reserved3:24;
- u32 cmd_status:8;
+typedef struct _i2o_status_block
+{
+ u16 org_id;
+ u16 reserved;
+ u16 iop_id:12;
+ u16 reserved1:4;
+ u16 host_unit_id;
+ u16 segment_number:12;
+ u16 i2o_version:4;
+ u8 iop_state;
+ u8 msg_type;
+ u16 inbound_frame_size;
+ u8 init_code;
+ u8 reserved2;
+ u32 max_inbound_frames;
+ u32 cur_inbound_frames;
+ u32 max_outbound_frames;
+ char product_id[24];
+ u32 expected_lct_size;
+ u32 iop_capabilities;
+ u32 desired_mem_size;
+ u32 current_mem_size;
+ u32 current_mem_base;
+ u32 desired_io_size;
+ u32 current_io_size;
+ u32 current_io_base;
+ u32 reserved3:24;
+ u32 cmd_status:8;
X } i2o_status_block;
-
+
X /* Event indicator mask flags */
X #define I2O_EVT_IND_STATE_CHANGE 0x80000000
X #define I2O_EVT_IND_GENERAL_WARNING 0x40000000
@@ -269,7 +281,7 @@
X #define I2O_EVT_IND_EXEC_ADAPTER_FAULT 0x00000004
X #define I2O_EVT_IND_EXEC_POWER_FAIL 0x00000008
X #define I2O_EVT_IND_EXEC_RESET_PENDING 0x00000010
-#define I2O_EVT_IND_EXEC_RESET_IMMINENT 0x00000020
+#define I2O_EVT_IND_EXEC_RESET_IMMINENT 0x00000020
X #define I2O_EVT_IND_EXEC_HW_FAIL 0x00000040
X #define I2O_EVT_IND_EXEC_XCT_CHANGE 0x00000080
X #define I2O_EVT_IND_EXEC_NEW_LCT_ENTRY 0x00000100
@@ -280,14 +292,14 @@
X #define I2O_EVT_IND_BSA_VOLUME_LOAD 0x00000001
X #define I2O_EVT_IND_BSA_VOLUME_UNLOAD 0x00000002
X #define I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ 0x00000004
-#define I2O_EVT_IND_BSA_CAPACITY_CHANGE 0x00000008
+#define I2O_EVT_IND_BSA_CAPACITY_CHANGE 0x00000008
X #define I2O_EVT_IND_BSA_SCSI_SMART 0x00000010
X
X /* Event data for generic events */
X #define I2O_EVT_STATE_CHANGE_NORMAL 0x00
X #define I2O_EVT_STATE_CHANGE_SUSPENDED 0x01
X #define I2O_EVT_STATE_CHANGE_RESTART 0x02
-#define I2O_EVT_STATE_CHANGE_NA_RECOVER 0x03
+#define I2O_EVT_STATE_CHANGE_NA_RECOVER 0x03
X #define I2O_EVT_STATE_CHANGE_NA_NO_RECOVER 0x04
X #define I2O_EVT_STATE_CHANGE_QUIESCE_REQUEST 0x05
X #define I2O_EVT_STATE_CHANGE_FAILED 0x10
@@ -295,7 +307,7 @@
X
X #define I2O_EVT_GEN_WARNING_NORMAL 0x00
X #define I2O_EVT_GEN_WARNING_ERROR_THRESHOLD 0x01
-#define I2O_EVT_GEN_WARNING_MEDIA_FAULT 0x02
+#define I2O_EVT_GEN_WARNING_MEDIA_FAULT 0x02
X
X #define I2O_EVT_CAPABILITY_OTHER 0x01
X #define I2O_EVT_CAPABILITY_CHANGED 0x02
@@ -309,89 +321,89 @@
X /* Class ID and Code Assignments
X * (LCT.ClassID.Version field)
X */
-#define I2O_CLASS_VERSION_10 0x00
-#define I2O_CLASS_VERSION_11 0x01
+#define I2O_CLASS_VERSION_10 0x00
+#define I2O_CLASS_VERSION_11 0x01
X
X /* Class code names
X * (from v1.5 Table 6-1 Class Code Assignments.)
X */
-
-#define I2O_CLASS_EXECUTIVE 0x000
-#define I2O_CLASS_DDM 0x001
-#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010
-#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011
-#define I2O_CLASS_LAN 0x020
-#define I2O_CLASS_WAN 0x030
-#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040
-#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041
-#define I2O_CLASS_SCSI_PERIPHERAL 0x051
-#define I2O_CLASS_ATE_PORT 0x060
-#define I2O_CLASS_ATE_PERIPHERAL 0x061
-#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
-#define I2O_CLASS_FLOPPY_DEVICE 0x071
-#define I2O_CLASS_BUS_ADAPTER_PORT 0x080
-#define I2O_CLASS_PEER_TRANSPORT_AGENT 0x090
-#define I2O_CLASS_PEER_TRANSPORT 0x091
+
+#define I2O_CLASS_EXECUTIVE 0x000
+#define I2O_CLASS_DDM 0x001
+#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010
+#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011
+#define I2O_CLASS_LAN 0x020
+#define I2O_CLASS_WAN 0x030
+#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040
+#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041
+#define I2O_CLASS_SCSI_PERIPHERAL 0x051
+#define I2O_CLASS_ATE_PORT 0x060
+#define I2O_CLASS_ATE_PERIPHERAL 0x061
+#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
+#define I2O_CLASS_FLOPPY_DEVICE 0x071
+#define I2O_CLASS_BUS_ADAPTER_PORT 0x080
+#define I2O_CLASS_PEER_TRANSPORT_AGENT 0x090
+#define I2O_CLASS_PEER_TRANSPORT 0x091
X
X /*
X * Rest of 0x092 - 0x09f reserved for peer-to-peer classes
X */
-
-#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
+
+#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
X
X /*
X * Subclasses
X */
X
-#define I2O_SUBCLASS_i960 0x001
-#define I2O_SUBCLASS_HDM 0x020
-#define I2O_SUBCLASS_ISM 0x021
-
+#define I2O_SUBCLASS_i960 0x001
+#define I2O_SUBCLASS_HDM 0x020
+#define I2O_SUBCLASS_ISM 0x021
+
X /* Operation functions */
X
-#define I2O_PARAMS_FIELD_GET 0x0001
-#define I2O_PARAMS_LIST_GET 0x0002
-#define I2O_PARAMS_MORE_GET 0x0003
-#define I2O_PARAMS_SIZE_GET 0x0004
-#define I2O_PARAMS_TABLE_GET 0x0005
-#define I2O_PARAMS_FIELD_SET 0x0006
-#define I2O_PARAMS_LIST_SET 0x0007
-#define I2O_PARAMS_ROW_ADD 0x0008
-#define I2O_PARAMS_ROW_DELETE 0x0009
-#define I2O_PARAMS_TABLE_CLEAR 0x000A
+#define I2O_PARAMS_FIELD_GET 0x0001
+#define I2O_PARAMS_LIST_GET 0x0002
+#define I2O_PARAMS_MORE_GET 0x0003
+#define I2O_PARAMS_SIZE_GET 0x0004
+#define I2O_PARAMS_TABLE_GET 0x0005
+#define I2O_PARAMS_FIELD_SET 0x0006
+#define I2O_PARAMS_LIST_SET 0x0007
+#define I2O_PARAMS_ROW_ADD 0x0008
+#define I2O_PARAMS_ROW_DELETE 0x0009
+#define I2O_PARAMS_TABLE_CLEAR 0x000A
X
X /*
X * I2O serial number conventions / formats
X * (circa v1.5)
X */
X
-#define I2O_SNFORMAT_UNKNOWN 0
-#define I2O_SNFORMAT_BINARY 1
-#define I2O_SNFORMAT_ASCII 2
-#define I2O_SNFORMAT_UNICODE 3
-#define I2O_SNFORMAT_LAN48_MAC 4
-#define I2O_SNFORMAT_WAN 5
+#define I2O_SNFORMAT_UNKNOWN 0
+#define I2O_SNFORMAT_BINARY 1
+#define I2O_SNFORMAT_ASCII 2
+#define I2O_SNFORMAT_UNICODE 3
+#define I2O_SNFORMAT_LAN48_MAC 4
+#define I2O_SNFORMAT_WAN 5
X
X /*
X * Plus new in v2.0 (Yellowstone pdf doc)
X */
X
-#define I2O_SNFORMAT_LAN64_MAC 6
-#define I2O_SNFORMAT_DDM 7
-#define I2O_SNFORMAT_IEEE_REG64 8
-#define I2O_SNFORMAT_IEEE_REG128 9
-#define I2O_SNFORMAT_UNKNOWN2 0xff
+#define I2O_SNFORMAT_LAN64_MAC 6
+#define I2O_SNFORMAT_DDM 7
+#define I2O_SNFORMAT_IEEE_REG64 8
+#define I2O_SNFORMAT_IEEE_REG128 9
+#define I2O_SNFORMAT_UNKNOWN2 0xff
X
X /*
X * I2O Get Status State values
X */
X
-#define ADAPTER_STATE_INITIALIZING 0x01
-#define ADAPTER_STATE_RESET 0x02
-#define ADAPTER_STATE_HOLD 0x04
-#define ADAPTER_STATE_READY 0x05
-#define ADAPTER_STATE_OPERATIONAL 0x08
-#define ADAPTER_STATE_FAILED 0x10
-#define ADAPTER_STATE_FAULTED 0x11
-
+#define ADAPTER_STATE_INITIALIZING 0x01
+#define ADAPTER_STATE_RESET 0x02
+#define ADAPTER_STATE_HOLD 0x04
+#define ADAPTER_STATE_READY 0x05
+#define ADAPTER_STATE_OPERATIONAL 0x08
+#define ADAPTER_STATE_FAILED 0x10
+#define ADAPTER_STATE_FAULTED 0x11
+
X #endif /* _I2O_DEV_H */
diff -u --recursive --new-file v2.4.12/linux/include/linux/i2o.h linux/include/linux/i2o.h
--- v2.4.12/linux/include/linux/i2o.h Mon Aug 27 12:41:48 2001
+++ linux/include/linux/i2o.h Fri Oct 19 08:32:28 2001


@@ -17,24 +17,25 @@
X

X #ifndef _I2O_H
X #define _I2O_H
-#ifdef __KERNEL__ /* This file to be included by kernel only */
+
+#ifdef __KERNEL__ /* This file to be included by kernel only */
X
X #include <linux/i2o-dev.h>
X
-/* How many different OSM's are we allowing */
+/* How many different OSM's are we allowing */
X #define MAX_I2O_MODULES 64
X
X /* How many OSMs can register themselves for device status updates? */
X #define I2O_MAX_MANAGERS 4
X
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
X #include <linux/config.h>
X #include <linux/notifier.h>
-#include <linux/ioport.h>
+#include <linux/ioport.h> /* Needed for struct resource */
X #include <asm/atomic.h>
X
X /*
- * message structures
+ * Message structures
X */
X struct i2o_message
X {
@@ -43,7 +44,7 @@
X u16 size;
X u32 target_tid:12;
X u32 init_tid:12;
- u32 function:8;
+ u32 function:8;
X u32 initiator_context;
X /* List follows */
X };
@@ -54,18 +55,19 @@
X */
X struct i2o_device
X {
- i2o_lct_entry lct_data; /* Device LCT information */
- u32 flags;
- int i2oversion; /* I2O version supported. Actually there
- * should be high and low version */
+ i2o_lct_entry lct_data; /* Device LCT information */
+ u32 flags;
+ int i2oversion; /* I2O version supported. Actually
+ * there should be high and low
+ * version */
X
- struct proc_dir_entry* proc_entry; /* /proc dir */
+ struct proc_dir_entry *proc_entry; /* /proc dir */
X
X /* Primary user */
X struct i2o_handler *owner;
X
X /* Management users */
- struct i2o_handler *managers[I2O_MAX_MANAGERS];
+ struct i2o_handler *managers[I2O_MAX_MANAGERS];
X int num_managers;
X
X struct i2o_controller *controller; /* Controlling IOP */
@@ -76,24 +78,23 @@
X
X /*
X * Resource data for each PCI I2O controller
- */
+ */
X struct i2o_pci
X {
- struct pci_dev *pdev; /* PCI device */
- int irq;
- int queue_buggy:1; /* Don't send a lot of messages */
- int short_req:1; /* Use small block sizes */
- int dpt:1; /* Don't quiesce */
+ int irq;
+ int queue_buggy:1; /* Don't send a lot of messages */
+ int short_req:1; /* Use small block sizes */
+ int dpt:1; /* Don't quiesce */
X #ifdef CONFIG_MTRR
- int mtrr_reg0;
- int mtrr_reg1;
+ int mtrr_reg0;
+ int mtrr_reg1;
X #endif
X };
X
X /*
X * Transport types supported by I2O stack
X */
-#define I2O_TYPE_PCI 0x01 /* PCI I2O controller */
+#define I2O_TYPE_PCI 0x01 /* PCI I2O controller */
X
X
X /*
@@ -101,6 +102,8 @@
X */
X struct i2o_controller
X {
+ struct pci_dev *pdev; /* PCI device */
+
X char name[16];
X int unit;
X int type;
@@ -126,35 +129,35 @@
X
X u32 mem_offset; /* MFA offset */
X u32 mem_phys; /* MFA physical */
-
+
X int battery:1; /* Has a battery backup */
X int io_alloc:1; /* An I/O resource was allocated */
X int mem_alloc:1; /* A memory resource was allocated */
-
+
X struct resource io_resource; /* I/O resource allocated to the IOP */
X struct resource mem_resource; /* Mem resource allocated to the IOP */
X
- struct proc_dir_entry* proc_entry; /* /proc dir */
+ struct proc_dir_entry *proc_entry; /* /proc dir */
X
- union
- { /* Bus information */
+ union { /* Bus information */
X struct i2o_pci pci;
X } bus;
X
X /* Bus specific destructor */
- void (*destructor)(struct i2o_controller *);
+ void (*destructor)(struct i2o_controller *);
X
X /* Bus specific attach/detach */
- int (*bind)(struct i2o_controller *, struct i2o_device *);
+ int (*bind)(struct i2o_controller *, struct i2o_device *);
X
X /* Bus specific initiator */
X int (*unbind)(struct i2o_controller *, struct i2o_device *);
X
X /* Bus specific enable/disable */
- void (*bus_enable)(struct i2o_controller *c);
- void (*bus_disable)(struct i2o_controller *c);
+ void (*bus_enable)(struct i2o_controller *);
+ void (*bus_disable)(struct i2o_controller *);
X
- void *page_frame; /* Message buffers */
+ void *page_frame; /* Message buffers */
+ dma_addr_t page_frame_map; /* Cache map */
X };
X
X /*
@@ -169,7 +172,8 @@
X struct i2o_handler
X {
X /* Message reply handler */
- void (*reply)(struct i2o_handler *, struct i2o_controller *, struct i2o_message *);
+ void (*reply)(struct i2o_handler *, struct i2o_controller *,
+ struct i2o_message *);
X
X /* New device notification handler */
X void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
@@ -181,7 +185,7 @@
X void (*reboot_notify)(void);
X
X char *name; /* OSM name */
- int context; /* Low 8 bits of the transaction info */
+ int context; /* Low 8 bits of the transaction info */
X u32 class; /* I2O classes that this driver handles */
X /* User data follows */
X };
@@ -201,12 +205,12 @@
X {
X int (*install)(struct i2o_controller *);
X int (*activate)(struct i2o_controller *);
- struct i2o_controller* (*find)(int);
+ struct i2o_controller *(*find)(int);
X void (*unlock)(struct i2o_controller *);
- void (*run_queue)(struct i2o_controller *c);
+ void (*run_queue)(struct i2o_controller * c);
X int (*delete)(struct i2o_controller *);
X };
-#endif // MODULE
+#endif /* MODULE */
X
X /*
X * I2O System table entry
@@ -222,9 +226,9 @@
X u32 iop_id:12;
X u32 reserved2:20;
X u16 seg_num:12;
- u16 i2o_version:4;
- u8 iop_state;
- u8 msg_type;
+ u16 i2o_version:4;
+ u8 iop_state;
+ u8 msg_type;
X u16 frame_size;
X u16 reserved3;
X u32 last_changed;
@@ -235,14 +239,14 @@
X
X struct i2o_sys_tbl
X {
- u8 num_entries;
- u8 version;
- u16 reserved1;
+ u8 num_entries;
+ u8 version;
+ u16 reserved1;
X u32 change_ind;
X u32 reserved2;
X u32 reserved3;
X struct i2o_sys_tbl_entry iops[0];
-};
+};
X
X /*
X * Messenger inlines
@@ -265,9 +269,9 @@
X
X static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
X {
- *c->reply_port= Val;
+ *c->reply_port = Val;
X }
-
+
X
X static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
X {
@@ -283,13 +287,13 @@
X static inline void i2o_post_message(struct i2o_controller *c, u32 m)
X {
X /* The second line isnt spurious - thats forcing PCI posting */
- I2O_POST_WRITE32(c,m);
+ I2O_POST_WRITE32(c, m);
X (void) I2O_IRQ_READ32(c);
X }
X
X static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
X {
- I2O_REPLY_WRITE32(c,m);
+ I2O_REPLY_WRITE32(c, m);
X }
X
X extern struct i2o_controller *i2o_find_controller(int);
@@ -304,23 +308,27 @@
X extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *);
X extern int i2o_release_device(struct i2o_device *, struct i2o_handler *);
X extern int i2o_device_notify_on(struct i2o_device *, struct i2o_handler *);
-extern int i2o_device_notify_off(struct i2o_device *, struct i2o_handler *);
+extern int i2o_device_notify_off(struct i2o_device *,
+ struct i2o_handler *);
X
X extern int i2o_post_this(struct i2o_controller *, u32 *, int);
X extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
-extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int, void *, void *);
+extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int,
+ void *, void *);
X
-extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *, int);
-extern int i2o_query_table(int, struct i2o_controller *, int, int, int, void *,
- int, void *, int);
-extern int i2o_clear_table(struct i2o_controller *, int, int);
-extern int i2o_row_add_table(struct i2o_controller *, int, int, int, void *,
- int);
-extern int i2o_issue_params(int, struct i2o_controller *, int, void *,
- int, void *, int);
+extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *,
+ int);
+extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *,
+ int);
+extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
+ void *, int, void *, int);
+extern int i2o_clear_table(struct i2o_controller *, int, int);
+extern int i2o_row_add_table(struct i2o_controller *, int, int, int,
+ void *, int);
+extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
+ void *, int);
X
-extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32);
+extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32);
X extern int i2o_event_ack(struct i2o_controller *, u32 *);
X
X extern void i2o_report_status(const char *, const char *, u32 *);
@@ -339,7 +347,7 @@
X
X /*
X * Executive Class
- */
+ */
X #define I2O_CMD_ADAPTER_ASSIGN 0xB3
X #define I2O_CMD_ADAPTER_READ 0xB2
X #define I2O_CMD_ADAPTER_RELEASE 0xB5
@@ -524,7 +532,7 @@
X #define I2O_CLAIM_MANAGEMENT 0x02000000
X #define I2O_CLAIM_AUTHORIZED 0x03000000
X #define I2O_CLAIM_SECONDARY 0x04000000
-
+
X /* Message header defines for VersionOffset */
X #define I2OVER15 0x0001
X #define I2OVER20 0x0002
diff -u --recursive --new-file v2.4.12/linux/include/linux/locks.h linux/include/linux/locks.h
--- v2.4.12/linux/include/linux/locks.h Thu Oct 18 13:48:23 2001
+++ linux/include/linux/locks.h Tue Oct 23 21:59:57 2001
@@ -26,7 +26,7 @@
X __wait_on_buffer(bh);
X }
X
-extern void unlock_buffer(struct buffer_head *bh);
+extern void FASTCALL(unlock_buffer(struct buffer_head *bh));
X
X /*
X * super-block locking. Again, interrupts may only unlock
diff -u --recursive --new-file v2.4.12/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.4.12/linux/include/linux/mm.h Thu Oct 18 13:47:42 2001
+++ linux/include/linux/mm.h Tue Oct 23 21:59:10 2001
@@ -279,6 +279,7 @@
X #define PG_checked 12 /* kill me in 2.5.<early>. */
X #define PG_arch_1 13
X #define PG_reserved 14
+#define PG_launder 15 /* written out by VM pressure.. */
X
X /* Make it prettier to test the above... */
X #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
@@ -292,6 +293,8 @@
X #define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
X #define PageChecked(page) test_bit(PG_checked, &(page)->flags)
X #define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)
+#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)
+#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)
X
X extern void __set_page_dirty(struct page *);
X
@@ -308,6 +311,7 @@
X * parallel wait_on_page).
X */
X #define UnlockPage(page) do { \
+ clear_bit(PG_launder, &(page)->flags); \
X smp_mb__before_clear_bit(); \
X if (!test_and_clear_bit(PG_locked, &(page)->flags)) BUG(); \
X smp_mb__after_clear_bit(); \
@@ -550,17 +554,16 @@
X #define __GFP_IO 0x40 /* Can start low memory physical IO? */
X #define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */
X #define __GFP_FS 0x100 /* Can call down to low-level FS? */
-#define __GFP_WAITBUF 0x200 /* Can we wait for buffers to complete? */
X
X #define GFP_NOHIGHIO (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
X #define GFP_NOIO (__GFP_HIGH | __GFP_WAIT)
-#define GFP_NOFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF)
+#define GFP_NOFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO)
X #define GFP_ATOMIC (__GFP_HIGH)
-#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
-#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS | __GFP_HIGHMEM)
-#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
-#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
-#define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
+#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM)
+#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+#define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
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.12/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h
--- v2.4.12/linux/include/linux/msdos_fs.h Thu May 24 15:36:34 2001
+++ linux/include/linux/msdos_fs.h Fri Oct 12 13:48:42 2001
@@ -92,6 +92,15 @@
X #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
X #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
X
+/*
+ * vfat shortname flags
+ */
+#define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */
+#define VFAT_SFN_DISPLAY_WIN95 0x0002 /* emulate win95 rule for display */
+#define VFAT_SFN_DISPLAY_WINNT 0x0004 /* emulate winnt rule for display */
+#define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */
+#define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */
+
X /*
X * Conversion from and to little-endian byte order. (no-op on i386/i486)
X *
@@ -132,7 +141,7 @@
X };
X
X struct fat_boot_fsinfo {
- __u32 signature1; /* 0x61417272L */
+ __u32 signature1; /* 0x41615252L */
X __u32 reserved1[120]; /* Nothing as far as I can tell */
X __u32 signature2; /* 0x61417272L */
X __u32 free_clusters; /* Free cluster count. -1 if unknown */


@@ -188,6 +197,8 @@
X

X #ifdef __KERNEL__
X
+#include <linux/nls.h>
+
X struct fat_cache {
X kdev_t device; /* device number. 0 means unused. */
X int start_cluster; /* first cluster of the chain. */
@@ -196,21 +207,111 @@
X struct fat_cache *next; /* next cache entry */
X };
X
-/* misc.c */
-extern int fat_is_binary(char conversion,char *extension);
+static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
+{
+#ifdef __BIG_ENDIAN
+ while (len--) {
+ *dst++ = src[0] | (src[1] << 8);
+ src += 2;
+ }
+#else
+ memcpy(dst, src, len * 2);
+#endif
+}
+
+static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
+{
+#ifdef __BIG_ENDIAN
+ while (len--) {
+ dst[0] = *src & 0x00FF;
+ dst[1] = (*src & 0xFF00) >> 8;
+ dst += 2;
+ src++;
+ }
+#else
+ memcpy(dst, src, len * 2);
+#endif
+}
+
+/* fat/buffer.c */
+extern struct buffer_head *fat_bread(struct super_block *sb, int block);
+extern struct buffer_head *fat_getblk(struct super_block *sb, int block);
+extern void fat_brelse(struct super_block *sb, struct buffer_head *bh);
+extern void fat_mark_buffer_dirty(struct super_block *sb, struct buffer_head *bh);
+extern void fat_set_uptodate(struct super_block *sb, struct buffer_head *bh,
+ int val);
+extern int fat_is_uptodate(struct super_block *sb, struct buffer_head *bh);
+extern void fat_ll_rw_block(struct super_block *sb, int opr, int nbreq,
+ struct buffer_head *bh[32]);
+
+/* fat/cache.c */
+extern int fat_access(struct super_block *sb, int nr, int new_value);
+extern int fat_bmap(struct inode *inode, int sector);
+extern void fat_cache_init(void);
+extern void fat_cache_lookup(struct inode *inode, int cluster, int *f_clu,
+ int *d_clu);
+extern void fat_cache_add(struct inode *inode, int f_clu, int d_clu);
+extern void fat_cache_inval_inode(struct inode *inode);
+extern void fat_cache_inval_dev(kdev_t device);
+extern int fat_get_cluster(struct inode *inode, int cluster);
+extern int fat_free(struct inode *inode, int skip);
+
+/* fat/dir.c */
+extern struct file_operations fat_dir_operations;
+extern int fat_search_long(struct inode *inode, const char *name, int name_len,
+ int anycase, loff_t *spos, loff_t *lpos);
+extern int fat_readdir(struct file *filp, void *dirent, filldir_t filldir);
+extern int fat_dir_ioctl(struct inode * inode, struct file * filp,
+ unsigned int cmd, unsigned long arg);
+extern int fat_dir_empty(struct inode *dir);
+extern int fat_add_entries(struct inode *dir, int slots, struct buffer_head **bh,
+ struct msdos_dir_entry **de, int *ino);
+extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat);
+
+/* fat/file.c */
+extern struct file_operations fat_file_operations;
+extern struct inode_operations fat_file_inode_operations;
+extern ssize_t fat_file_read(struct file *filp, char *buf, size_t count,
+ loff_t *ppos);
+extern int fat_get_block(struct inode *inode, long iblock,
+ struct buffer_head *bh_result, int create);
+extern ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
+ loff_t *ppos);
+extern void fat_truncate(struct inode *inode);
+
+/* fat/inode.c */
+extern void fat_hash_init(void);
+extern void fat_attach(struct inode *inode, int i_pos);
+extern void fat_detach(struct inode *inode);
+extern struct inode *fat_iget(struct super_block *sb, int i_pos);
+extern struct inode *fat_build_inode(struct super_block *sb,
+ struct msdos_dir_entry *de, int ino, int *res);
+extern void fat_delete_inode(struct inode *inode);
+extern void fat_clear_inode(struct inode *inode);
+extern void fat_put_super(struct super_block *sb);
+extern struct super_block *
+fat_read_super(struct super_block *sb, void *data, int silent,
+ struct inode_operations *fs_dir_inode_ops);
+extern int fat_statfs(struct super_block *sb, struct statfs *buf);
+extern void fat_write_inode(struct inode *inode, int wait);
+extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
+
+/* fat/misc.c */
+extern void fat_fs_panic(struct super_block *s, const char *msg);
+extern int fat_is_binary(char conversion, char *extension);
X extern void lock_fat(struct super_block *sb);
X extern void unlock_fat(struct super_block *sb);
+extern void fat_clusters_flush(struct super_block *sb);
X extern int fat_add_cluster(struct inode *inode);
X extern struct buffer_head *fat_extend_dir(struct inode *inode);
-extern int date_dos2unix(__u16 time, __u16 date);
-extern void fat_fs_panic(struct super_block *s,const char *msg);
-extern void fat_lock_creation(void);
-extern void fat_unlock_creation(void);
-extern void fat_date_unix2dos(int unix_date,__u16 *time, __u16 *date);
-extern int fat__get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh,
- struct msdos_dir_entry **de,int *ino);
-static __inline__ int fat_get_entry(struct inode *dir,loff_t *pos,
- struct buffer_head **bh,struct msdos_dir_entry **de,int *ino)
+extern int date_dos2unix(unsigned short time, unsigned short date);
+extern void fat_date_unix2dos(int unix_date, unsigned short *time,
+ unsigned short *date);
+extern int fat__get_entry(struct inode *dir, loff_t *pos, struct buffer_head **bh,
+ struct msdos_dir_entry **de, int *ino);
+static __inline__ int fat_get_entry(struct inode *dir, loff_t *pos,
+ struct buffer_head **bh,
+ struct msdos_dir_entry **de, int *ino)
X {
X /* Fast stuff first */
X if (*bh && *de &&
@@ -222,103 +323,33 @@
X }
X return fat__get_entry(dir,pos,bh,de,ino);
X }
-extern int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de,int *ino);
-extern int fat_parent_ino(struct inode *dir,int locked);
X extern int fat_subdirs(struct inode *dir);
-void fat_clusters_flush(struct super_block *sb);
-
-/* fat.c */
-extern int fat_access(struct super_block *sb,int nr,int new_value);
-extern int fat_free(struct inode *inode,int skip);
-void fat_cache_inval_inode(struct inode *inode);
-void fat_cache_inval_dev(kdev_t device);
-extern void fat_cache_init(void);
-void fat_cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu);
-void fat_cache_add(struct inode *inode,int f_clu,int d_clu);
-int fat_get_cluster(struct inode *inode,int cluster);
+extern int fat_scan(struct inode *dir, const char *name,
+ struct buffer_head **res_bh,
+ struct msdos_dir_entry **res_de, int *ino);
X
-/* inode.c */
-extern void fat_hash_init(void);
-extern int fat_bmap(struct inode *inode,int block);
-extern int fat_get_block(struct inode *, long, struct buffer_head *, int);
-extern int fat_notify_change(struct dentry *, struct iattr *);
-extern void fat_clear_inode(struct inode *inode);
-extern void fat_delete_inode(struct inode *inode);
-extern void fat_put_super(struct super_block *sb);
-extern void fat_attach(struct inode *inode, int ino);
-extern void fat_detach(struct inode *inode);
-extern struct inode *fat_iget(struct super_block*,int);
-extern struct inode *fat_build_inode(struct super_block*,struct msdos_dir_entry*,int,int*);
-extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent, struct inode_operations *dir_ops);
+/* msdos/namei.c - these are for Umsdos */
X extern void msdos_put_super(struct super_block *sb);
-extern int fat_statfs(struct super_block *sb,struct statfs *buf);
-extern void fat_write_inode(struct inode *inode, int);
-
-/* dir.c */
-extern struct file_operations fat_dir_operations;
-extern int fat_search_long(struct inode *dir, const char *name, int len,
- int anycase, loff_t *spos, loff_t *lpos);
-extern int fat_readdir(struct file *filp,
- void *dirent, filldir_t);
-extern int fat_dir_ioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg);
-int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
- struct msdos_dir_entry **de, int *ino);
-int fat_dir_empty(struct inode *dir);
-int fat_new_dir(struct inode *inode, struct inode *parent, int is_vfat);
-
-/* file.c */
-extern struct inode_operations fat_file_inode_operations;
-extern struct inode_operations fat_file_inode_operations_1024;
-extern struct inode_operations fat_file_inode_operations_readpage;
-extern struct file_operations fat_file_operations;
-extern ssize_t fat_file_read(struct file *, char *, size_t, loff_t *);
-extern ssize_t fat_file_write(struct file *, const char *, size_t, loff_t *);
-extern void fat_truncate(struct inode *inode);
-
-/* msdos.c */
-extern struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent);
-
-/* msdos.c - these are for Umsdos */
-extern void msdos_read_inode(struct inode *inode);
-extern struct dentry *msdos_lookup(struct inode *dir,struct dentry *);
-extern int msdos_create(struct inode *dir,struct dentry *dentry,int mode);
-extern int msdos_rmdir(struct inode *dir,struct dentry *dentry);
-extern int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode);
-extern int msdos_unlink(struct inode *dir,struct dentry *dentry);
-extern int msdos_rename(struct inode *old_dir,struct dentry *old_dentry,
- struct inode *new_dir,struct dentry *new_dentry);
-
-/* nls.c */
-extern struct fat_nls_table *fat_load_nls(int codepage);
-
-/* tables.c */
-extern unsigned char fat_uni2esc[];
-extern unsigned char fat_esc2uni[];
-
-/* fatfs_syms.c */
-extern void cleanup_fat_fs(void);
-
-/* nls.c */
-extern int fat_register_nls(struct fat_nls_table * fmt);
-extern int fat_unregister_nls(struct fat_nls_table * fmt);
-extern struct fat_nls_table *fat_find_nls(int codepage);
-extern struct fat_nls_table *fat_load_nls(int codepage);
-extern void fat_unload_nls(int codepage);
-extern int init_fat_nls(void);
+extern struct dentry *msdos_lookup(struct inode *dir, struct dentry *);
+extern int msdos_create(struct inode *dir, struct dentry *dentry, int mode);
+extern int msdos_rmdir(struct inode *dir, struct dentry *dentry);
+extern int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+extern int msdos_unlink(struct inode *dir, struct dentry *dentry);
+extern int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);
+extern struct super_block *msdos_read_super(struct super_block *sb,
+ void *data, int silent);
X
X /* vfat/namei.c - these are for dmsdos */
-extern int vfat_create(struct inode *dir,struct dentry *dentry,int mode);
-extern int vfat_unlink(struct inode *dir,struct dentry *dentry);
-extern int vfat_mkdir(struct inode *dir,struct dentry *dentry,int mode);
-extern int vfat_rmdir(struct inode *dir,struct dentry *dentry);
-extern int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
- struct inode *new_dir,struct dentry *new_dentry);
-extern struct super_block *vfat_read_super(struct super_block *sb,void *data,
+extern struct dentry *vfat_lookup(struct inode *dir, struct dentry *);
+extern int vfat_create(struct inode *dir, struct dentry *dentry, int mode);
+extern int vfat_rmdir(struct inode *dir, struct dentry *dentry);
+extern int vfat_unlink(struct inode *dir, struct dentry *dentry);
+extern int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+extern int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);
+extern struct super_block *vfat_read_super(struct super_block *sb, void *data,
X int silent);
-extern void vfat_read_inode(struct inode *inode);
-extern struct dentry *vfat_lookup(struct inode *dir,struct dentry *);
X
X /* vfat/vfatfs_syms.c */
X extern struct file_system_type vfat_fs_type;
diff -u --recursive --new-file v2.4.12/linux/include/linux/msdos_fs_sb.h linux/include/linux/msdos_fs_sb.h
--- v2.4.12/linux/include/linux/msdos_fs_sb.h Thu May 24 15:36:34 2001
+++ linux/include/linux/msdos_fs_sb.h Fri Oct 12 13:48:42 2001
@@ -12,6 +12,7 @@
X unsigned short fs_umask;
X unsigned short codepage; /* Codepage for shortname conversions */
X char *iocharset; /* Charset used for filename input/display */
+ unsigned short shortname; /* flags for shortname display/create rule */
X unsigned char name_check; /* r = relaxed, n = normal, s = strict */
X unsigned char conversion; /* b = binary, t = text, a = auto */
X unsigned quiet:1, /* set = fake successful chmods and chowns */
@@ -28,11 +29,6 @@
X nocase:1; /* Does this need case conversion? 0=need case conversion*/
X };
X
-struct vfat_unicode {


- unsigned char uni1;
- unsigned char uni2;
-};
-

X struct msdos_sb_info {
X unsigned short cluster_size; /* sectors/cluster */
X unsigned short cluster_bits; /* sectors/cluster */
@@ -45,7 +41,6 @@
X unsigned long clusters; /* number of clusters */
X unsigned long root_cluster; /* first cluster of the root directory */
X unsigned long fsinfo_sector; /* FAT32 fsinfo offset from start of disk */
- wait_queue_head_t fat_wait;
X struct semaphore fat_lock;
X int prev_free; /* previously returned free cluster number */
X int free_clusters; /* -1 if undefined */
diff -u --recursive --new-file v2.4.12/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.4.12/linux/include/linux/pci.h Thu Oct 18 13:48:29 2001
+++ linux/include/linux/pci.h Tue Oct 23 22:00:02 2001


@@ -353,7 +353,7 @@
X

X struct pci_driver *driver; /* which driver has allocated this device */
X void *driver_data; /* data private to the driver */
- dma_addr_t dma_mask; /* Mask of the bits of bus address this
+ u64 dma_mask; /* Mask of the bits of bus address this
X device implements. Normally this is
X 0xffffffff. You only need to change
X this if your device has broken DMA
@@ -559,7 +559,8 @@
X int pci_enable_device(struct pci_dev *dev);
X void pci_disable_device(struct pci_dev *dev);
X void pci_set_master(struct pci_dev *dev);
-int pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
+int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask);
X int pci_assign_resource(struct pci_dev *dev, int i);
X
X /* Power management related routines */
@@ -641,7 +642,8 @@
X static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
X static inline void pci_disable_device(struct pci_dev *dev) { }
X static inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; }
-static inline int pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask) { return -EIO; }
+static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
+static inline int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
X static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
X static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
X static inline void pci_unregister_driver(struct pci_driver *drv) { }
diff -u --recursive --new-file v2.4.12/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.12/linux/include/linux/pci_ids.h Thu Oct 11 08:02:26 2001
+++ linux/include/linux/pci_ids.h Tue Oct 16 21:56:29 2001
@@ -1594,6 +1594,17 @@
X #define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b
X #define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
X #define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
+#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
+#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
+#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
+#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484
+#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
+#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
+#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487
+#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
+#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
+#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
+#define PCI_DEVICE_ID_INTEL_80310 0x530d
X #define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120
X #define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121
X #define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122
diff -u --recursive --new-file v2.4.12/linux/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- v2.4.12/linux/include/linux/reiserfs_fs.h Tue Oct 9 17:06:53 2001
+++ linux/include/linux/reiserfs_fs.h Fri Oct 12 14:20:42 2001
@@ -12,11 +12,12 @@
X #ifndef _LINUX_REISER_FS_H
X #define _LINUX_REISER_FS_H
X
-
X #include <linux/types.h>
X #ifdef __KERNEL__
X #include <linux/slab.h>
X #include <linux/tqueue.h>
+#include <asm/unaligned.h>
+#include <linux/bitops.h>
X #include <asm/hardirq.h>
X #endif
X
@@ -293,11 +294,57 @@
X } __attribute__ ((__packed__));
X
X struct offset_v2 {
- __u64 k_offset:60;
- __u64 k_type: 4;
+#ifdef __LITTLE_ENDIAN
+ /* little endian version */
+ __u64 k_offset:60;
+ __u64 k_type: 4;
+#else
+ /* big endian version */
+ __u64 k_type: 4;
+ __u64 k_offset:60;
+#endif
X } __attribute__ ((__packed__));
X
+#ifndef __LITTLE_ENDIAN
+typedef union {
+ struct offset_v2 offset_v2;
+ __u64 linear;
+} __attribute__ ((__packed__)) offset_v2_esafe_overlay;
+
+static inline __u16 offset_v2_k_type( struct offset_v2 *v2 )
+{
+ offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+ tmp.linear = le64_to_cpu( tmp.linear );
+ return tmp.offset_v2.k_type;
+}
+
+static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type )
+{
+ offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2;
+ tmp->linear = le64_to_cpu(tmp->linear);
+ tmp->offset_v2.k_type = type;
+ tmp->linear = le64_to_cpu(tmp->linear);
+}
+
+static inline loff_t offset_v2_k_offset( struct offset_v2 *v2 )
+{
+ offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+ tmp.linear = le64_to_cpu( tmp.linear );
+ return tmp.offset_v2.k_offset;
+}
X
+static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){
+ offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2;
+ tmp->linear = le64_to_cpu(tmp->linear);
+ tmp->offset_v2.k_offset = offset;
+ tmp->linear = le64_to_cpu(tmp->linear);
+}
+#else
+# define offset_v2_k_type(v2) ((v2)->k_type)
+# define set_offset_v2_k_type(v2,val) (offset_v2_k_type(v2) = (val))
+# define offset_v2_k_offset(v2) ((v2)->k_offset)
+# define set_offset_v2_k_offset(v2,val) (offset_v2_k_offset(v2) = (val))
+#endif
X
X /* Key of an item determines its location in the S+tree, and
X is composed of 4 components */
@@ -387,8 +434,8 @@
X __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory
X entries in the directory item. */
X } __attribute__ ((__packed__)) u;
- __u16 ih_item_len; /* total size of the item body */
- __u16 ih_item_location; /* an offset to the item body within the block */


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 51'
echo 'File patch-2.4.13 is continued in part 52'
echo "52" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:22 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part52

#!/bin/sh -x
# this is part 52 of a 53 - part archive


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

if test "$Scheck" != 52; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

+ __u16 ih_item_len; /* total size of the item body */
+ __u16 ih_item_location; /* an offset to the item body within the block */
X /* I thought we were going to use this
X for having lots of item types? Why
X don't you use this for item type
@@ -423,11 +470,19 @@
X
X
X // FIXME: now would that work for other than i386 archs
-#define unreachable_item(ih) (ih->ih_version & (1 << 15))
+#define unreachable_item(ih) (ih_version(ih) & (1 << 15))
X
X #define get_ih_free_space(ih) (ih_version (ih) == ITEM_VERSION_2 ? 0 : ih_free_space (ih))
X #define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == ITEM_VERSION_2) ? 0 : (val)))
X
+/* these operate on indirect items, where you've got an array of ints
+** at a possibly unaligned location. These are a noop on ia32
+**
+** p is the array of __u32, i is the index into the array, v is the value
+** to store there.
+*/
+#define get_block_num(p, i) le32_to_cpu(get_unaligned((p) + (i)))
+#define put_block_num(p, i, v) put_unaligned(cpu_to_le32(v), (p) + (i))
X
X //
X // there are 5 item types currently
@@ -490,8 +545,9 @@
X //
X static inline loff_t le_key_k_offset (int version, struct key * key)
X {
- return (version == ITEM_VERSION_1) ? key->u.k_offset_v1.k_offset :
- le64_to_cpu (key->u.k_offset_v2.k_offset);
+ return (version == ITEM_VERSION_1) ?
+ le32_to_cpu( key->u.k_offset_v1.k_offset ) :
+ offset_v2_k_offset( &(key->u.k_offset_v2) );
X }
X static inline loff_t le_ih_k_offset (struct item_head * ih)
X {
@@ -501,8 +557,9 @@
X
X static inline loff_t le_key_k_type (int version, struct key * key)
X {
- return (version == ITEM_VERSION_1) ? uniqueness2type (key->u.k_offset_v1.k_uniqueness) :
- le16_to_cpu (key->u.k_offset_v2.k_type);
+ return (version == ITEM_VERSION_1) ?
+ uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
+ offset_v2_k_type( &(key->u.k_offset_v2) );
X }
X static inline loff_t le_ih_k_type (struct item_head * ih)
X {
@@ -512,8 +569,9 @@
X
X static inline void set_le_key_k_offset (int version, struct key * key, loff_t offset)
X {
- (version == ITEM_VERSION_1) ? (key->u.k_offset_v1.k_offset = offset) :
- (key->u.k_offset_v2.k_offset = cpu_to_le64 (offset));
+ (version == ITEM_VERSION_1) ?
+ (key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
+ (set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
X }
X static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
X {
@@ -524,8 +582,9 @@
X
X static inline void set_le_key_k_type (int version, struct key * key, int type)
X {
- (version == ITEM_VERSION_1) ? (key->u.k_offset_v1.k_uniqueness = type2uniqueness (type)) :
- (key->u.k_offset_v2.k_type = cpu_to_le16 (type));
+ (version == ITEM_VERSION_1) ?
+ (key->u.k_offset_v1.k_uniqueness = cpu_to_le32(type2uniqueness(type))):
+ (set_offset_v2_k_type( &(key->u.k_offset_v2), type ));
X }
X static inline void set_le_ih_k_type (struct item_head * ih, int type)
X {
@@ -553,26 +612,30 @@
X //
X static inline loff_t cpu_key_k_offset (struct cpu_key * key)
X {
- return (key->version == ITEM_VERSION_1) ? key->on_disk_key.u.k_offset_v1.k_offset :
+ return (key->version == ITEM_VERSION_1) ?
+ key->on_disk_key.u.k_offset_v1.k_offset :
X key->on_disk_key.u.k_offset_v2.k_offset;
X }
X
X static inline loff_t cpu_key_k_type (struct cpu_key * key)
X {
- return (key->version == ITEM_VERSION_1) ? uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) :
+ return (key->version == ITEM_VERSION_1) ?
+ uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) :
X key->on_disk_key.u.k_offset_v2.k_type;
X }
X
X static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
X {
- (key->version == ITEM_VERSION_1) ? (key->on_disk_key.u.k_offset_v1.k_offset = offset) :
+ (key->version == ITEM_VERSION_1) ?
+ (key->on_disk_key.u.k_offset_v1.k_offset = offset) :
X (key->on_disk_key.u.k_offset_v2.k_offset = offset);
X }
X
X
X static inline void set_cpu_key_k_type (struct cpu_key * key, int type)
X {
- (key->version == ITEM_VERSION_1) ? (key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)) :
+ (key->version == ITEM_VERSION_1) ?
+ (key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)):
X (key->on_disk_key.u.k_offset_v2.k_type = type);
X }
X
@@ -638,7 +701,17 @@
X struct key blk_right_delim_key; /* kept only for compatibility */
X };
X
-#define BLKH_SIZE (sizeof(struct block_head))
+#define BLKH_SIZE (sizeof(struct block_head))
+#define blkh_level(p_blkh) (le16_to_cpu((p_blkh)->blk_level))
+#define blkh_nr_item(p_blkh) (le16_to_cpu((p_blkh)->blk_nr_item))
+#define blkh_free_space(p_blkh) (le16_to_cpu((p_blkh)->blk_free_space))
+#define blkh_reserved(p_blkh) (le16_to_cpu((p_blkh)->blk_reserved))
+#define set_blkh_level(p_blkh,val) ((p_blkh)->blk_level = cpu_to_le16(val))
+#define set_blkh_nr_item(p_blkh,val) ((p_blkh)->blk_nr_item = cpu_to_le16(val))
+#define set_blkh_free_space(p_blkh,val) ((p_blkh)->blk_free_space = cpu_to_le16(val))
+#define set_blkh_reserved(p_blkh,val) ((p_blkh)->blk_reserved = cpu_to_le16(val))
+#define blkh_right_delim_key(p_blkh) ((p_blkh)->blk_right_delim_key)
+#define set_blkh_right_delim_key(p_blkh,val) ((p_blkh)->blk_right_delim_key = val)
X
X /*
X * values for blk_level field of the struct block_head
@@ -652,25 +725,26 @@
X #define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level.*/
X
X /* Given the buffer head of a formatted node, resolve to the block head of that node. */
-#define B_BLK_HEAD(p_s_bh) ((struct block_head *)((p_s_bh)->b_data))
+#define B_BLK_HEAD(p_s_bh) ((struct block_head *)((p_s_bh)->b_data))
X /* Number of items that are in buffer. */
-#define B_NR_ITEMS(p_s_bh) (le16_to_cpu ( B_BLK_HEAD(p_s_bh)->blk_nr_item ))
-#define B_LEVEL(bh) (le16_to_cpu ( B_BLK_HEAD(bh)->blk_level ))
-#define B_FREE_SPACE(bh) (le16_to_cpu ( B_BLK_HEAD(bh)->blk_free_space ))
-
-#define PUT_B_NR_ITEMS(p_s_bh) do { B_BLK_HEAD(p_s_bh)->blk_nr_item = cpu_to_le16(val); } while (0)
-#define PUT_B_LEVEL(bh, val) do { B_BLK_HEAD(bh)->blk_level = cpu_to_le16(val); } while (0)
-#define PUT_B_FREE_SPACE(bh) do { B_BLK_HEAD(bh)->blk_free_space = cpu_to_le16(val); } while (0)
+#define B_NR_ITEMS(p_s_bh) (blkh_nr_item(B_BLK_HEAD(p_s_bh)))
+#define B_LEVEL(p_s_bh) (blkh_level(B_BLK_HEAD(p_s_bh)))
+#define B_FREE_SPACE(p_s_bh) (blkh_free_space(B_BLK_HEAD(p_s_bh)))
+
+#define PUT_B_NR_ITEMS(p_s_bh,val) do { set_blkh_nr_item(B_BLK_HEAD(p_s_bh),val); } while (0)
+#define PUT_B_LEVEL(p_s_bh,val) do { set_blkh_level(B_BLK_HEAD(p_s_bh),val); } while (0)
+#define PUT_B_FREE_SPACE(p_s_bh,val) do { set_blkh_free_space(B_BLK_HEAD(p_s_bh),val); } while (0)
+
X
-/* Get right delimiting key. */
-#define B_PRIGHT_DELIM_KEY(p_s_bh) ( &(B_BLK_HEAD(p_s_bh)->blk_right_delim_key) )
+/* Get right delimiting key. -- little endian */
+#define B_PRIGHT_DELIM_KEY(p_s_bh) (&(blk_right_delim_key(B_BLK_HEAD(p_s_bh))
X
X /* Does the buffer contain a disk leaf. */
-#define B_IS_ITEMS_LEVEL(p_s_bh) ( B_BLK_HEAD(p_s_bh)->blk_level == DISK_LEAF_NODE_LEVEL )
+#define B_IS_ITEMS_LEVEL(p_s_bh) (B_LEVEL(p_s_bh) == DISK_LEAF_NODE_LEVEL)
X
X /* Does the buffer contain a disk internal node */
-#define B_IS_KEYS_LEVEL(p_s_bh) ( B_BLK_HEAD(p_s_bh)->blk_level > DISK_LEAF_NODE_LEVEL &&\
- B_BLK_HEAD(p_s_bh)->blk_level <= MAX_HEIGHT )
+#define B_IS_KEYS_LEVEL(p_s_bh) (B_LEVEL(p_s_bh) > DISK_LEAF_NODE_LEVEL \
+ && B_LEVEL(p_s_bh) <= MAX_HEIGHT)
X
X
X
@@ -709,8 +783,32 @@
X policy. Someday. -Hans */
X } __attribute__ ((__packed__));
X
-#define SD_V1_SIZE (sizeof(struct stat_data_v1))
-
+#define SD_V1_SIZE (sizeof(struct stat_data_v1))
+#define stat_data_v1(ih) (ih_version (ih) == ITEM_VERSION_1)
+#define sd_v1_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
+#define set_sd_v1_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
+#define sd_v1_nlink(sdp) (le16_to_cpu((sdp)->sd_nlink))
+#define set_sd_v1_nlink(sdp,v) ((sdp)->sd_nlink = cpu_to_le16(v))
+#define sd_v1_uid(sdp) (le16_to_cpu((sdp)->sd_uid))
+#define set_sd_v1_uid(sdp,v) ((sdp)->sd_uid = cpu_to_le16(v))
+#define sd_v1_gid(sdp) (le16_to_cpu((sdp)->sd_gid))
+#define set_sd_v1_gid(sdp,v) ((sdp)->sd_gid = cpu_to_le16(v))
+#define sd_v1_size(sdp) (le32_to_cpu((sdp)->sd_size))
+#define set_sd_v1_size(sdp,v) ((sdp)->sd_size = cpu_to_le32(v))
+#define sd_v1_atime(sdp) (le32_to_cpu((sdp)->sd_atime))
+#define set_sd_v1_atime(sdp,v) ((sdp)->sd_atime = cpu_to_le32(v))
+#define sd_v1_mtime(sdp) (le32_to_cpu((sdp)->sd_mtime))
+#define set_sd_v1_mtime(sdp,v) ((sdp)->sd_mtime = cpu_to_le32(v))
+#define sd_v1_ctime(sdp) (le32_to_cpu((sdp)->sd_ctime))
+#define set_sd_v1_ctime(sdp,v) ((sdp)->sd_ctime = cpu_to_le32(v))
+#define sd_v1_rdev(sdp) (le32_to_cpu((sdp)->u.sd_rdev))
+#define set_sd_v1_rdev(sdp,v) ((sdp)->u.sd_rdev = cpu_to_le32(v))
+#define sd_v1_blocks(sdp) (le32_to_cpu((sdp)->u.sd_blocks))
+#define set_sd_v1_blocks(sdp,v) ((sdp)->u.sd_blocks = cpu_to_le32(v))
+#define sd_v1_first_direct_byte(sdp) \
+ (le32_to_cpu((sdp)->sd_first_direct_byte))
+#define set_sd_v1_first_direct_byte(sdp,v) \
+ ((sdp)->sd_first_direct_byte = cpu_to_le32(v))
X
X /* Stat Data on disk (reiserfs version of UFS disk inode minus the
X address blocks) */
@@ -743,8 +841,32 @@
X // this is 40 bytes long
X //
X #define SD_SIZE (sizeof(struct stat_data))
-
-#define stat_data_v1(ih) (ih_version (ih) == ITEM_VERSION_1)
+#define SD_V2_SIZE SD_SIZE
+#define stat_data_v2(ih) (ih_version (ih) == ITEM_VERSION_2)
+#define sd_v2_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
+#define set_sd_v2_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
+/* sd_reserved */
+/* set_sd_reserved */
+#define sd_v2_nlink(sdp) (le32_to_cpu((sdp)->sd_nlink))
+#define set_sd_v2_nlink(sdp,v) ((sdp)->sd_nlink = cpu_to_le32(v))
+#define sd_v2_size(sdp) (le64_to_cpu((sdp)->sd_size))
+#define set_sd_v2_size(sdp,v) ((sdp)->sd_size = cpu_to_le64(v))
+#define sd_v2_uid(sdp) (le32_to_cpu((sdp)->sd_uid))
+#define set_sd_v2_uid(sdp,v) ((sdp)->sd_uid = cpu_to_le32(v))
+#define sd_v2_gid(sdp) (le32_to_cpu((sdp)->sd_gid))
+#define set_sd_v2_gid(sdp,v) ((sdp)->sd_gid = cpu_to_le32(v))
+#define sd_v2_atime(sdp) (le32_to_cpu((sdp)->sd_atime))
+#define set_sd_v2_atime(sdp,v) ((sdp)->sd_atime = cpu_to_le32(v))
+#define sd_v2_mtime(sdp) (le32_to_cpu((sdp)->sd_mtime))
+#define set_sd_v2_mtime(sdp,v) ((sdp)->sd_mtime = cpu_to_le32(v))
+#define sd_v2_ctime(sdp) (le32_to_cpu((sdp)->sd_ctime))
+#define set_sd_v2_ctime(sdp,v) ((sdp)->sd_ctime = cpu_to_le32(v))
+#define sd_v2_blocks(sdp) (le32_to_cpu((sdp)->sd_blocks))
+#define set_sd_v2_blocks(sdp,v) ((sdp)->sd_blocks = cpu_to_le32(v))
+#define sd_v2_rdev(sdp) (le32_to_cpu((sdp)->u.sd_rdev))
+#define set_sd_v2_rdev(sdp,v) ((sdp)->u.sd_rdev = cpu_to_le32(v))
+#define sd_v2_generation(sdp) (le32_to_cpu((sdp)->u.sd_generation))
+#define set_sd_v2_generation(sdp,v) ((sdp)->u.sd_generation = cpu_to_le32(v))
X
X
X /***************************************************************************/
@@ -793,7 +915,18 @@
X __u16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether
X entry is hidden (unlinked) */
X } __attribute__ ((__packed__));
-#define DEH_SIZE sizeof(struct reiserfs_de_head)
+#define DEH_SIZE sizeof(struct reiserfs_de_head)
+#define deh_offset(p_deh) (le32_to_cpu((p_deh)->deh_offset))
+#define deh_dir_id(p_deh) (le32_to_cpu((p_deh)->deh_dir_id))
+#define deh_objectid(p_deh) (le32_to_cpu((p_deh)->deh_objectid))
+#define deh_location(p_deh) (le16_to_cpu((p_deh)->deh_location))
+#define deh_state(p_deh) (le16_to_cpu((p_deh)->deh_state))
+
+#define put_deh_offset(p_deh,v) ((p_deh)->deh_offset = cpu_to_le32((v)))
+#define put_deh_dir_id(p_deh,v) ((p_deh)->deh_dir_id = cpu_to_le32((v)))
+#define put_deh_objectid(p_deh,v) ((p_deh)->deh_objectid = cpu_to_le32((v)))
+#define put_deh_location(p_deh,v) ((p_deh)->deh_location = cpu_to_le16((v)))
+#define put_deh_state(p_deh,v) ((p_deh)->deh_state = cpu_to_le16((v)))
X
X /* empty directory contains two entries "." and ".." and their headers */
X #define EMPTY_DIR_SIZE \
@@ -805,34 +938,31 @@
X #define DEH_Statdata 0 /* not used now */
X #define DEH_Visible 2
X
-/* bitops which deals with unaligned addrs;
- needed for alpha port. --zam */
-#ifdef __alpha__
-# define ADDR_UNALIGNED_BITS (5)
+/* 64 bit systems (and the S/390) need to be aligned explicitly -jdm */
+#if BITS_PER_LONG == 64 || defined(__s390__) || defined(__hppa__)
+# define ADDR_UNALIGNED_BITS (3)
X #endif
X
+/* These are only used to manipulate deh_state.
+ * Because of this, we'll use the ext2_ bit routines,
+ * since they are little endian */
X #ifdef ADDR_UNALIGNED_BITS
X
X # define aligned_address(addr) ((void *)((long)(addr) & ~((1UL << ADDR_UNALIGNED_BITS) - 1)))
X # define unaligned_offset(addr) (((int)((long)(addr) & ((1 << ADDR_UNALIGNED_BITS) - 1))) << 3)
X
-# define set_bit_unaligned(nr, addr) set_bit((nr) + unaligned_offset(addr), aligned_address(addr))
-# define clear_bit_unaligned(nr, addr) clear_bit((nr) + unaligned_offset(addr), aligned_address(addr))
-# define test_bit_unaligned(nr, addr) test_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define set_bit_unaligned(nr, addr) ext2_set_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define clear_bit_unaligned(nr, addr) ext2_clear_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define test_bit_unaligned(nr, addr) ext2_test_bit((nr) + unaligned_offset(addr), aligned_address(addr))
X
X #else
X
-# define set_bit_unaligned(nr, addr) set_bit(nr, addr)
-# define clear_bit_unaligned(nr, addr) clear_bit(nr, addr)
-# define test_bit_unaligned(nr, addr) test_bit(nr, addr)
+# define set_bit_unaligned(nr, addr) ext2_set_bit(nr, addr)
+# define clear_bit_unaligned(nr, addr) ext2_clear_bit(nr, addr)
+# define test_bit_unaligned(nr, addr) ext2_test_bit(nr, addr)
X
X #endif
X
-#define deh_dir_id(deh) (__le32_to_cpu ((deh)->deh_dir_id))
-#define deh_objectid(deh) (__le32_to_cpu ((deh)->deh_objectid))
-#define deh_offset(deh) (__le32_to_cpu ((deh)->deh_offset))
-
-
X #define mark_de_with_sd(deh) set_bit_unaligned (DEH_Statdata, &((deh)->deh_state))
X #define mark_de_without_sd(deh) clear_bit_unaligned (DEH_Statdata, &((deh)->deh_state))
X #define mark_de_visible(deh) set_bit_unaligned (DEH_Visible, &((deh)->deh_state))
@@ -844,7 +974,9 @@
X
X /* compose directory item containing "." and ".." entries (entries are
X not aligned to 4 byte boundary) */
-static inline void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid,
+/* the last four params are LE */
+static inline void make_empty_dir_item_v1 (char * body,
+ __u32 dirid, __u32 objid,
X __u32 par_dirid, __u32 par_objid)
X {
X struct reiserfs_de_head * deh;
@@ -853,29 +985,32 @@
X deh = (struct reiserfs_de_head *)body;
X
X /* direntry header of "." */
- deh[0].deh_offset = cpu_to_le32 (DOT_OFFSET);
- deh[0].deh_dir_id = cpu_to_le32 (dirid);
- deh[0].deh_objectid = cpu_to_le32 (objid);
- deh[0].deh_location = cpu_to_le16 (EMPTY_DIR_SIZE_V1 - strlen ("."));
- deh[0].deh_state = 0;
+ put_deh_offset( &(deh[0]), DOT_OFFSET );
+ /* these two are from make_le_item_head, and are are LE */
+ deh[0].deh_dir_id = dirid;
+ deh[0].deh_objectid = objid;
+ deh[0].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." ));
X mark_de_visible(&(deh[0]));
X
X /* direntry header of ".." */
- deh[1].deh_offset = cpu_to_le32 (DOT_DOT_OFFSET);
+ put_deh_offset( &(deh[1]), DOT_DOT_OFFSET);
X /* key of ".." for the root directory */
- deh[1].deh_dir_id = cpu_to_le32 (par_dirid);
- deh[1].deh_objectid = cpu_to_le32 (par_objid);
- deh[1].deh_location = cpu_to_le16 (le16_to_cpu (deh[0].deh_location) - strlen (".."));
- deh[1].deh_state = 0;
+ /* these two are from the inode, and are are LE */
+ deh[1].deh_dir_id = par_dirid;
+ deh[1].deh_objectid = par_objid;
+ deh[1].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) );
X mark_de_visible(&(deh[1]));
X
X /* copy ".." and "." */
- memcpy (body + deh[0].deh_location, ".", 1);
- memcpy (body + deh[1].deh_location, "..", 2);
+ memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+ memcpy (body + deh_location( &(deh[1]) ), "..", 2);
X }
X
X /* compose directory item containing "." and ".." entries */
-static inline void make_empty_dir_item (char * body, __u32 dirid, __u32 objid,
+static inline void make_empty_dir_item (char * body,
+ __u32 dirid, __u32 objid,
X __u32 par_dirid, __u32 par_objid)
X {
X struct reiserfs_de_head * deh;
@@ -884,31 +1019,33 @@
X deh = (struct reiserfs_de_head *)body;
X
X /* direntry header of "." */
- deh[0].deh_offset = cpu_to_le32 (DOT_OFFSET);
- deh[0].deh_dir_id = cpu_to_le32 (dirid);
- deh[0].deh_objectid = cpu_to_le32 (objid);
- deh[0].deh_location = cpu_to_le16 (EMPTY_DIR_SIZE - ROUND_UP (strlen (".")));
- deh[0].deh_state = 0;
+ put_deh_offset( &(deh[0]), DOT_OFFSET );
+ /* these two are from make_le_item_head, and are are LE */
+ deh[0].deh_dir_id = dirid;
+ deh[0].deh_objectid = objid;
+ deh[0].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) );
X mark_de_visible(&(deh[0]));
X
X /* direntry header of ".." */
- deh[1].deh_offset = cpu_to_le32 (DOT_DOT_OFFSET);
+ put_deh_offset( &(deh[1]), DOT_DOT_OFFSET );
X /* key of ".." for the root directory */
- deh[1].deh_dir_id = cpu_to_le32 (par_dirid);
- deh[1].deh_objectid = cpu_to_le32 (par_objid);
- deh[1].deh_location = cpu_to_le16 (le16_to_cpu (deh[0].deh_location) - ROUND_UP (strlen ("..")));
- deh[1].deh_state = 0;
+ /* these two are from the inode, and are are LE */
+ deh[1].deh_dir_id = par_dirid;
+ deh[1].deh_objectid = par_objid;
+ deh[1].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) );
X mark_de_visible(&(deh[1]));
X
X /* copy ".." and "." */
- memcpy (body + deh[0].deh_location, ".", 1);
- memcpy (body + deh[1].deh_location, "..", 2);
+ memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+ memcpy (body + deh_location( &(deh[1]) ), "..", 2);
X }
X
X
X /* array of the entry headers */
X /* get item body */
-#define B_I_PITEM(bh,ih) ( (bh)->b_data + (ih)->ih_item_location )
+#define B_I_PITEM(bh,ih) ( (bh)->b_data + ih_location(ih) )
X #define B_I_DEH(bh,ih) ((struct reiserfs_de_head *)(B_I_PITEM(bh,ih)))
X
X /* length of the directory entry in directory item. This define
@@ -919,7 +1056,7 @@
X See picture above.*/
X /*
X #define I_DEH_N_ENTRY_LENGTH(ih,deh,i) \
-((i) ? (((deh)-1)->deh_location - (deh)->deh_location) : ((ih)->ih_item_len) - (deh)->deh_location)
+((i) ? (deh_location((deh)-1) - deh_location((deh))) : (ih_item_len((ih)) - deh_location((deh))))
X */
X static inline int entry_length (struct buffer_head * bh, struct item_head * ih,
X int pos_in_item)
@@ -928,18 +1065,19 @@
X
X deh = B_I_DEH (bh, ih) + pos_in_item;
X if (pos_in_item)
- return (le16_to_cpu ((deh - 1)->deh_location) - le16_to_cpu (deh->deh_location));
- return (le16_to_cpu (ih->ih_item_len) - le16_to_cpu (deh->deh_location));
+ return deh_location(deh-1) - deh_location(deh);
+
+ return ih_item_len(ih) - deh_location(deh);
X }
X
X
X
X /* number of entries in the directory item, depends on ENTRY_COUNT being at the start of directory dynamic data. */
-#define I_ENTRY_COUNT(ih) ((ih)->u.ih_entry_count)
+#define I_ENTRY_COUNT(ih) (ih_entry_count((ih)))
X
X
X /* name by bh, ih and entry_num */
-#define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih->ih_item_location + (B_I_DEH(bh,ih)+(entry_num))->deh_location))
+#define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih_location(ih) + deh_location(B_I_DEH(bh,ih)+(entry_num))))
X
X // two entries per block (at least)
X //#define REISERFS_MAX_NAME_LEN(block_size)
@@ -976,7 +1114,7 @@
X /* these defines are useful when a particular member of a reiserfs_dir_entry is needed */
X
X /* pointer to file name, stored in entry */
-#define B_I_DEH_ENTRY_FILE_NAME(bh,ih,deh) (B_I_PITEM (bh, ih) + (deh)->deh_location)
+#define B_I_DEH_ENTRY_FILE_NAME(bh,ih,deh) (B_I_PITEM (bh, ih) + deh_location(deh))
X
X /* length of name */
X #define I_DEH_N_ENTRY_FILE_NAME_LENGTH(ih,deh,entry_num) \
@@ -1014,14 +1152,18 @@
X };
X
X #define DC_SIZE (sizeof(struct disk_child))
+#define dc_block_number(dc_p) (le32_to_cpu((dc_p)->dc_block_number))
+#define dc_size(dc_p) (le16_to_cpu((dc_p)->dc_size))
+#define put_dc_block_number(dc_p, val) do { (dc_p)->dc_block_number = cpu_to_le32(val); } while(0)
+#define put_dc_size(dc_p, val) do { (dc_p)->dc_size = cpu_to_le16(val); } while(0)
X
X /* Get disk child by buffer header and position in the tree node. */
X #define B_N_CHILD(p_s_bh,n_pos) ((struct disk_child *)\
X ((p_s_bh)->b_data+BLKH_SIZE+B_NR_ITEMS(p_s_bh)*KEY_SIZE+DC_SIZE*(n_pos)))
X
X /* Get disk child number by buffer header and position in the tree node. */
-#define B_N_CHILD_NUM(p_s_bh,n_pos) (le32_to_cpu (B_N_CHILD(p_s_bh,n_pos)->dc_block_number))
-#define PUT_B_N_CHILD_NUM(p_s_bh,n_pos, val) do { B_N_CHILD(p_s_bh,n_pos)->dc_block_number = cpu_to_le32(val); } while (0)
+#define B_N_CHILD_NUM(p_s_bh,n_pos) (dc_block_number(B_N_CHILD(p_s_bh,n_pos)))
+#define PUT_B_N_CHILD_NUM(p_s_bh,n_pos, val) (put_dc_block_number(B_N_CHILD(p_s_bh,n_pos), val ))
X
X /* maximal value of field child_size in structure disk_child */
X /* child size is the combined size of all items and their headers */
@@ -1459,10 +1601,10 @@
X
X
X /* number of blocks pointed to by the indirect item */
-#define I_UNFM_NUM(p_s_ih) ( (p_s_ih)->ih_item_len / UNFM_P_SIZE )
+#define I_UNFM_NUM(p_s_ih) ( ih_item_len(p_s_ih) / UNFM_P_SIZE )
X
X /* the used space within the unformatted node corresponding to pos within the item pointed to by ih */
-#define I_POS_UNFM_SIZE(ih,pos,size) (((pos) == I_UNFM_NUM(ih) - 1 ) ? (size) - (ih)->u.ih_free_space : (size))
+#define I_POS_UNFM_SIZE(ih,pos,size) (((pos) == I_UNFM_NUM(ih) - 1 ) ? (size) - ih_free_space(ih) : (size))
X
X /* number of bytes contained by the direct item or the unformatted nodes the indirect item points to */
X
@@ -1477,16 +1619,16 @@
X #define B_N_PKEY(bh,item_num) ( &(B_N_PITEM_HEAD(bh,item_num)->ih_key) )
X
X /* get item body */
-#define B_N_PITEM(bh,item_num) ( (bh)->b_data + B_N_PITEM_HEAD((bh),(item_num))->ih_item_location)
+#define B_N_PITEM(bh,item_num) ( (bh)->b_data + ih_location(B_N_PITEM_HEAD((bh),(item_num))))
X
X /* get the stat data by the buffer header and the item order */
X #define B_N_STAT_DATA(bh,nr) \
-( (struct stat_data *)((bh)->b_data+B_N_PITEM_HEAD((bh),(nr))->ih_item_location ) )
+( (struct stat_data *)((bh)->b_data + ih_location(B_N_PITEM_HEAD((bh),(nr))) ) )
X
- /* following defines use reiserfs buffer header and item header */
+ /* following defines use reiserfs buffer header and item header */
X
X /* get stat-data */
-#define B_I_STAT_DATA(bh, ih) ( (struct stat_data * )((bh)->b_data + (ih)->ih_item_location) )
+#define B_I_STAT_DATA(bh, ih) ( (struct stat_data * )((bh)->b_data + ih_location(ih)) )
X
X // this is 3976 for size==4096
X #define MAX_DIRECT_ITEM_LEN(size) ((size) - BLKH_SIZE - 2*IH_SIZE - SD_SIZE - UNFM_P_SIZE)
@@ -1494,7 +1636,7 @@
X /* indirect items consist of entries which contain blocknrs, pos
X indicates which entry, and B_I_POS_UNFM_POINTER resolves to the
X blocknr contained by the entry pos points to */
-#define B_I_POS_UNFM_POINTER(bh,ih,pos) (*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)))
+#define B_I_POS_UNFM_POINTER(bh,ih,pos) le32_to_cpu(*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)))
X #define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0)
X
X /* Reiserfs buffer cache statistics. */
@@ -1596,6 +1738,8 @@
X */
X #define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT])
X
+void reiserfs_commit_for_inode(struct inode *) ;
+void reiserfs_update_inode_transaction(struct inode *) ;
X void reiserfs_wait_on_write_block(struct super_block *s) ;
X void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ;
X void reiserfs_allow_writes(struct super_block *s) ;
@@ -1692,7 +1836,7 @@
X {
X int type;
X
- type = le16_to_cpu (key->u.k_offset_v2.k_type);
+ type = offset_v2_k_type( &(key->u.k_offset_v2));
X if (type != TYPE_DIRECT && type != TYPE_INDIRECT && type != TYPE_DIRENTRY)
X return ITEM_VERSION_1;
X
@@ -1943,9 +2087,9 @@
X #endif
X
X /* hashes.c */
-__u32 keyed_hash (const char *msg, int len);
-__u32 yura_hash (const char *msg, int len);
-__u32 r5_hash (const char *msg, int len);
+__u32 keyed_hash (const signed char *msg, int len);
+__u32 yura_hash (const signed char *msg, int len);
+__u32 r5_hash (const signed char *msg, int len);
X
X /* version.c */
X char *reiserfs_get_version_string(void) ;
diff -u --recursive --new-file v2.4.12/linux/include/linux/reiserfs_fs_i.h linux/include/linux/reiserfs_fs_i.h
--- v2.4.12/linux/include/linux/reiserfs_fs_i.h Thu Oct 18 13:47:37 2001
+++ linux/include/linux/reiserfs_fs_i.h Tue Oct 23 21:59:06 2001
@@ -40,6 +40,12 @@
X is a comment you should make.... -Hans */
X //nopack-attribute
X int nopack;
+
+ /* we use these for fsync or O_SYNC to decide which transaction needs
+ ** to be committed in order for this inode to be properly flushed
+ */
+ unsigned long i_trans_id ;
+ unsigned long i_trans_index ;
X };
X
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/reiserfs_fs_sb.h linux/include/linux/reiserfs_fs_sb.h
--- v2.4.12/linux/include/linux/reiserfs_fs_sb.h Thu Oct 18 13:47:38 2001
+++ linux/include/linux/reiserfs_fs_sb.h Tue Oct 23 21:59:06 2001
@@ -65,6 +65,57 @@
X } __attribute__ ((__packed__));
X
X #define SB_SIZE (sizeof(struct reiserfs_super_block))
+/* struct reiserfs_super_block accessors/mutators
+ * since this is a disk structure, it will always be in
+ * little endian format. */
+#define sb_block_count(sbp) (le32_to_cpu((sbp)->s_block_count))
+#define set_sb_block_count(sbp,v) ((sbp)->s_block_count = cpu_to_le32(v))
+#define sb_free_blocks(sbp) (le32_to_cpu((sbp)->s_free_blocks))
+#define set_sb_free_blocks(sbp,v) ((sbp)->s_free_blocks = cpu_to_le32(v))
+#define sb_root_block(sbp) (le32_to_cpu((sbp)->s_root_block))
+#define set_sb_root_block(sbp,v) ((sbp)->s_root_block = cpu_to_le32(v))
+#define sb_journal_block(sbp) (le32_to_cpu((sbp)->s_journal_block))
+#define set_sb_journal_block(sbp,v) ((sbp)->s_journal_block = cpu_to_le32(v))
+#define sb_journal_dev(sbp) (le32_to_cpu((sbp)->s_journal_dev))
+#define set_sb_journal_dev(sbp,v) ((sbp)->s_journal_dev = cpu_to_le32(v))
+#define sb_orig_journal_size(sbp) (le32_to_cpu((sbp)->s_orig_journal_size))
+#define set_sb_orig_journal_size(sbp,v) \
+ ((sbp)->s_orig_journal_size = cpu_to_le32(v))
+#define sb_journal_trans_max(sbp) (le32_to_cpu((sbp)->s_journal_trans_max))
+#define set_journal_trans_max(sbp,v) \
+ ((sbp)->s_journal_trans_max = cpu_to_le32(v))
+#define sb_journal_block_count(sbp) (le32_to_cpu((sbp)->journal_block_count))
+#define sb_set_journal_block_count(sbp,v) \
+ ((sbp)->s_journal_block_count = cpu_to_le32(v))
+#define sb_journal_max_batch(sbp) (le32_to_cpu((sbp)->s_journal_max_batch))
+#define set_sb_journal_max_batch(sbp,v) \
+ ((sbp)->s_journal_max_batch = cpu_to_le32(v))
+#define sb_jourmal_max_commit_age(sbp) \
+ (le32_to_cpu((sbp)->s_journal_max_commit_age))
+#define set_sb_journal_max_commit_age(sbp,v) \
+ ((sbp)->s_journal_max_commit_age = cpu_to_le32(v))
+#define sb_jourmal_max_trans_age(sbp) \
+ (le32_to_cpu((sbp)->s_journal_max_trans_age))
+#define set_sb_journal_max_trans_age(sbp,v) \
+ ((sbp)->s_journal_max_trans_age = cpu_to_le32(v))
+#define sb_blocksize(sbp) (le16_to_cpu((sbp)->s_blocksize))
+#define set_sb_blocksize(sbp,v) ((sbp)->s_blocksize = cpu_to_le16(v))
+#define sb_oid_maxsize(sbp) (le16_to_cpu((sbp)->s_oid_maxsize))
+#define set_sb_oid_maxsize(sbp,v) ((sbp)->s_oid_maxsize = cpu_to_le16(v))
+#define sb_oid_cursize(sbp) (le16_to_cpu((sbp)->s_oid_cursize))
+#define set_sb_oid_cursize(sbp,v) ((sbp)->s_oid_cursize = cpu_to_le16(v))
+#define sb_state(sbp) (le16_to_cpu((sbp)->s_state))
+#define set_sb_state(sbp,v) ((sbp)->s_state = cpu_to_le16(v))
+#define sb_hash_function_code(sbp) \
+ (le32_to_cpu((sbp)->s_hash_function_code))
+#define set_sb_hash_function_code(sbp,v) \
+ ((sbp)->s_hash_function_code = cpu_to_le32(v))
+#define sb_tree_height(sbp) (le16_to_cpu((sbp)->s_tree_height))
+#define set_sb_tree_height(sbp,v) ((sbp)->s_tree_height = cpu_to_le16(v))
+#define sb_bmap_nr(sbp) (le16_to_cpu((sbp)->s_bmap_nr))
+#define set_sb_bmap_nr(sbp,v) ((sbp)->s_bmap_nr = cpu_to_le16(v))
+#define sb_version(sbp) (le16_to_cpu((sbp)->s_version))
+#define set_sb_version(sbp,v) ((sbp)->s_version = cpu_to_le16(v))
X
X /* this is the super from 3.5.X, where X >= 10 */
X struct reiserfs_super_block_v1
@@ -180,7 +231,6 @@
X unsigned long t_trans_id ; /* sanity check, equals the current trans id */
X struct super_block *t_super ; /* super for this FS when journal_begin was
X called. saves calls to reiserfs_get_super */
-
X } ;
X
X /*
@@ -262,7 +312,7 @@
X #define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick. magic string to find desc blocks in the journal */
X
X
-typedef __u32 (*hashf_t) (const char *, int);
+typedef __u32 (*hashf_t) (const signed char *, int);
X
X /* reiserfs union of in-core super block data */
X struct reiserfs_sb_info
@@ -377,25 +427,22 @@
X
X
X // on-disk super block fields converted to cpu form
-#define SB_DISK_SUPER_BLOCK(s) ((s)->u.reiserfs_sb.s_rs)
-#define SB_BLOCK_COUNT(s) le32_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_block_count))
-#define SB_FREE_BLOCKS(s) le32_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_free_blocks))
-#define SB_REISERFS_MAGIC(s) (SB_DISK_SUPER_BLOCK(s)->s_magic)
-#define SB_ROOT_BLOCK(s) le32_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_root_block))
-#define SB_TREE_HEIGHT(s) le16_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_tree_height))
-#define SB_REISERFS_STATE(s) le16_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_state))
-#define SB_VERSION(s) le16_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_version))
-#define SB_BMAP_NR(s) le16_to_cpu ((SB_DISK_SUPER_BLOCK(s)->s_bmap_nr))
-
-#define PUT_SB_BLOCK_COUNT(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_block_count = cpu_to_le32(val); } while (0)
-#define PUT_SB_FREE_BLOCKS(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_free_blocks = cpu_to_le32(val); } while (0)
-#define PUT_SB_ROOT_BLOCK(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_root_block = cpu_to_le32(val); } while (0)
-#define PUT_SB_TREE_HEIGHT(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_tree_height = cpu_to_le16(val); } while (0)
-#define PUT_SB_REISERFS_STATE(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_state = cpu_to_le16(val); } while (0)
-#define PUT_SB_VERSION(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_version = cpu_to_le16(val); } while (0)
-#define PUT_SB_BMAP_NR(s, val) do { SB_DISK_SUPER_BLOCK(s)->s_bmap_nr = cpu_to_le16 (val); } while (0)
+#define SB_DISK_SUPER_BLOCK(s) ((s)->u.reiserfs_sb.s_rs)
+#define SB_BLOCK_COUNT(s) sb_block_count (SB_DISK_SUPER_BLOCK(s))
+#define SB_FREE_BLOCKS(s) sb_free_blocks (SB_DISK_SUPER_BLOCK(s))
+#define SB_REISERFS_MAGIC(s) (SB_DISK_SUPER_BLOCK(s)->s_magic)
+#define SB_ROOT_BLOCK(s) sb_root_block (SB_DISK_SUPER_BLOCK(s))
+#define SB_TREE_HEIGHT(s) sb_tree_height (SB_DISK_SUPER_BLOCK(s))
+#define SB_REISERFS_STATE(s) sb_state (SB_DISK_SUPER_BLOCK(s))
+#define SB_VERSION(s) sb_version (SB_DISK_SUPER_BLOCK(s))
+#define SB_BMAP_NR(s) sb_bmap_nr(SB_DISK_SUPER_BLOCK(s))
+
+#define PUT_SB_BLOCK_COUNT(s, val) do { set_sb_block_count( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_FREE_BLOCKS(s, val) do { set_sb_free_blocks( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_ROOT_BLOCK(s, val) do { set_sb_root_block( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_TREE_HEIGHT(s, val) do { set_sb_tree_height( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_REISERFS_STATE(s, val) do { set_sb_state( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_VERSION(s, val) do { set_sb_version( SB_DISK_SUPER_BLOCK(s), val); } while (0)
+#define PUT_SB_BMAP_NR(s, val) do { set_sb_bmap_nr( SB_DISK_SUPER_BLOCK(s), val); } while (0)
X
X #endif /* _LINUX_REISER_FS_SB */
-
-
-
diff -u --recursive --new-file v2.4.12/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.4.12/linux/include/linux/slab.h Thu Oct 18 13:47:42 2001
+++ linux/include/linux/slab.h Tue Oct 23 21:59:10 2001
@@ -24,7 +24,7 @@
X #define SLAB_NFS GFP_NFS
X #define SLAB_DMA GFP_DMA
X
-#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_WAITBUF|__GFP_FS)
+#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS)
X #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */
X
X /* flags to pass to kmem_cache_create().
diff -u --recursive --new-file v2.4.12/linux/include/linux/sonypi.h linux/include/linux/sonypi.h
--- v2.4.12/linux/include/linux/sonypi.h Sun Sep 23 11:41:01 2001
+++ linux/include/linux/sonypi.h Thu Oct 11 11:17:22 2001
@@ -67,9 +67,12 @@
X #define SONYPI_EVENT_FNKEY_S 29
X #define SONYPI_EVENT_FNKEY_B 30
X #define SONYPI_EVENT_BLUETOOTH_PRESSED 31
-#define SONYPI_EVENT_PKEY_P1 32
-#define SONYPI_EVENT_PKEY_P2 33
-#define SONYPI_EVENT_PKEY_P3 34
+#define SONYPI_EVENT_PKEY_P1 32
+#define SONYPI_EVENT_PKEY_P2 33
+#define SONYPI_EVENT_PKEY_P3 34
+#define SONYPI_EVENT_BACK_PRESSED 35
+#define SONYPI_EVENT_LID_CLOSED 36
+#define SONYPI_EVENT_LID_OPENED 37
X
X
X /* brightness etc. ioctls */
diff -u --recursive --new-file v2.4.12/linux/include/linux/spinlock.h linux/include/linux/spinlock.h
--- v2.4.12/linux/include/linux/spinlock.h Thu Oct 18 13:47:37 2001
+++ linux/include/linux/spinlock.h Tue Oct 23 21:59:06 2001
@@ -30,6 +30,10 @@
X #define write_unlock_irqrestore(lock, flags) do { write_unlock(lock); local_irq_restore(flags); } while (0)
X #define write_unlock_irq(lock) do { write_unlock(lock); local_irq_enable(); } while (0)
X #define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)
+#define spin_trylock_bh(lock) ({ int __r; local_bh_disable();\
+ __r = spin_trylock(lock); \
+ if (!__r) local_bh_enable(); \
+ __r; })
X
X #ifdef CONFIG_SMP
X #include <asm/spinlock.h>
diff -u --recursive --new-file v2.4.12/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.4.12/linux/include/linux/swap.h Thu Oct 18 13:47:37 2001
+++ linux/include/linux/swap.h Tue Oct 23 21:59:06 2001
@@ -102,9 +102,7 @@
X extern void FASTCALL(lru_cache_del(struct page *));
X
X extern void FASTCALL(deactivate_page(struct page *));
-extern void FASTCALL(deactivate_page_nolock(struct page *));
X extern void FASTCALL(activate_page(struct page *));
-extern void FASTCALL(activate_page_nolock(struct page *));
X
X extern void swap_setup(void);
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/udf_fs.h linux/include/linux/udf_fs.h
--- v2.4.12/linux/include/linux/udf_fs.h Tue Jul 3 17:08:22 2001
+++ linux/include/linux/udf_fs.h Thu Oct 11 08:59:24 2001
@@ -37,8 +37,8 @@
X #define UDF_PREALLOCATE
X #define UDF_DEFAULT_PREALLOC_BLOCKS 8
X
-#define UDFFS_DATE "2001/06/13"
-#define UDFFS_VERSION "0.9.4.1"
+#define UDFFS_DATE "2001/10/10"
+#define UDFFS_VERSION "0.9.5"
X
X #if !defined(UDFFS_RW)
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/udf_fs_sb.h linux/include/linux/udf_fs_sb.h
--- v2.4.12/linux/include/linux/udf_fs_sb.h Thu Oct 18 13:47:34 2001
+++ linux/include/linux/udf_fs_sb.h Thu Oct 11 08:59:24 2001
@@ -18,10 +18,6 @@
X #if !defined(_LINUX_UDF_FS_SB_H)
X #define _LINUX_UDF_FS_SB_H
X
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
X #pragma pack(1)
X
X #define UDF_MAX_BLOCK_LOADED 8
@@ -89,7 +85,7 @@
X __u16 s_partition;
X
X /* Sector headers */
- __u32 s_session;
+ __s32 s_session;
X __u32 s_anchor[4];
X __u32 s_lastblock;
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- v2.4.12/linux/include/linux/ufs_fs.h Thu Oct 18 13:47:37 2001
+++ linux/include/linux/ufs_fs.h Tue Oct 23 21:59:05 2001
@@ -532,6 +532,14 @@
X /* dir.c */
X extern struct inode_operations ufs_dir_inode_operations;
X extern int ufs_check_dir_entry (const char *, struct inode *, struct ufs_dir_entry *, struct buffer_head *, unsigned long);
+extern int ufs_add_link (struct dentry *, struct inode *);
+extern ino_t ufs_inode_by_name(struct inode *, struct dentry *);
+extern int ufs_make_empty(struct inode *, struct inode *);
+extern struct ufs_dir_entry * ufs_find_entry (struct dentry *, struct buffer_head **);
+extern int ufs_delete_entry (struct inode *, struct ufs_dir_entry *, struct buffer_head *);
+extern int ufs_empty_dir (struct inode *);
+extern struct ufs_dir_entry * ufs_dotdot (struct inode *, struct buffer_head **);
+extern void ufs_set_link(struct inode *, struct ufs_dir_entry *, struct buffer_head *, struct inode *);


X
X /* file.c */

X extern struct inode_operations ufs_file_inode_operations;
@@ -541,7 +549,7 @@
X
X /* ialloc.c */
X extern void ufs_free_inode (struct inode *inode);
-extern struct inode * ufs_new_inode (const struct inode *, int, int *);
+extern struct inode * ufs_new_inode (const struct inode *, int);


X
X /* inode.c */

X extern int ufs_frag_map (struct inode *, int);
diff -u --recursive --new-file v2.4.12/linux/include/linux/usb.h linux/include/linux/usb.h
--- v2.4.12/linux/include/linux/usb.h Thu Oct 18 13:49:59 2001
+++ linux/include/linux/usb.h Tue Oct 23 22:02:02 2001
@@ -855,7 +855,7 @@
X
X extern struct list_head usb_driver_list;
X extern struct list_head usb_bus_list;
-extern rwlock_t usb_bus_list_lock;
+extern struct semaphore usb_bus_list_lock;
X
X /*
X * USB device fs stuff
diff -u --recursive --new-file v2.4.12/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.4.12/linux/include/linux/videodev.h Sun Aug 12 13:28:01 2001
+++ linux/include/linux/videodev.h Thu Oct 11 11:17:22 2001
@@ -185,7 +185,7 @@
X {
X __u32 x,y; /* Offsets into image */
X __u32 width, height; /* Area to capture */
- __u16 decimation; /* Decimation divder */
+ __u16 decimation; /* Decimation divider */
X __u16 flags; /* Flags for capture */
X #define VIDEO_CAPTURE_ODD 0 /* Temporal */
X #define VIDEO_CAPTURE_EVEN 1
@@ -377,15 +377,5 @@
X #define VID_HARDWARE_PWC 31 /* Philips webcams */
X #define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */
X #define VID_HARDWARE_CPIA2 33
-
-/*
- * Initialiser list
- */
-
-struct video_init
-{
- char *name;
- int (*init)(struct video_init *);
-};
X
X #endif
diff -u --recursive --new-file v2.4.12/linux/include/linux/vt_buffer.h linux/include/linux/vt_buffer.h
--- v2.4.12/linux/include/linux/vt_buffer.h Thu Oct 18 13:49:26 2001
+++ linux/include/linux/vt_buffer.h Tue Oct 23 22:01:00 2001
@@ -26,9 +26,6 @@
X #define scr_memmovew(d, s, c) memmove(d, s, c)
X #define VT_BUF_HAVE_MEMCPYW
X #define VT_BUF_HAVE_MEMMOVEW
-#define scr_memcpyw_from(d, s, c) memcpy(d, s, c)
-#define scr_memcpyw_to(d, s, c) memcpy(d, s, c)
-#define VT_BUF_HAVE_MEMCPYF
X #endif
X
X #ifndef VT_BUF_HAVE_MEMSETW
@@ -61,22 +58,6 @@
X while (count--)
X scr_writew(scr_readw(--s), --d);
X }
-}
-#endif
-
-#ifndef VT_BUF_HAVE_MEMCPYF
-static inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
-{
- count /= 2;
- while (count--)
- *d++ = scr_readw(s++);
-}
-
-static inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
-{
- count /= 2;
- while (count--)
- scr_writew(*s++, d++);
X }
X #endif
X
diff -u --recursive --new-file v2.4.12/linux/include/linux/wireless.h linux/include/linux/wireless.h
--- v2.4.12/linux/include/linux/wireless.h Thu Oct 18 13:47:51 2001
+++ linux/include/linux/wireless.h Tue Oct 23 21:59:18 2001
@@ -1,7 +1,7 @@
X /*
X * This file define a set of standard wireless extensions
X *
- * Version : 11 28.3.01
+ * Version : 12 5.10.01
X *
X * Authors : Jean Tourrilhes - HPL - <j...@hpl.hp.com>
X */
@@ -63,7 +63,7 @@
X * (there is some stuff that will be added in the future...)
X * I just plan to increment with each new version.
X */
-#define WIRELESS_EXT 11
+#define WIRELESS_EXT 12
X
X /*
X * Changes :
@@ -116,6 +116,13 @@
X * ----------
X * - Add WE version in range (help backward/forward compatibility)
X * - Add retry ioctls (work like PM)
+ *
+ * V11 to V12
+ * ----------
+ * - Add SIOCSIWSTATS to get /proc/net/wireless programatically
+ * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
+ * - Add new statistics (frag, retry, beacon)
+ * - Add average quality (for user space calibration)
X */
X
X /* -------------------------- IOCTL LIST -------------------------- */
@@ -137,6 +144,8 @@
X #define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
X #define SIOCSIWPRIV 0x8B0C /* Unused */
X #define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
+#define SIOCSIWSTATS 0x8B0E /* Unused */
+#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
X
X /* Mobile IP support */
X #define SIOCSIWSPY 0x8B10 /* set spy addresses */
@@ -177,11 +186,33 @@
X #define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
X #define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
X
+/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
+
+/* These 16 ioctl are wireless device private.
+ * Each driver is free to use them for whatever purpose it chooses,
+ * however the driver *must* export the description of those ioctls
+ * with SIOCGIWPRIV and *must* use arguments as defined below.
+ * If you don't follow those rules, DaveM is going to hate you (reason :
+ * it make mixed 32/64bit operation impossible).
+ */
+#define SIOCIWFIRSTPRIV 0x8BE0
+#define SIOCIWLASTPRIV 0x8BFF
+/* Previously, we were using SIOCDEVPRIVATE, but we now have our
+ * separate range because of collisions with other tools such as
+ * 'mii-tool'.
+ * We now have 32 commands, so a bit more space ;-).
+ * Also, all 'odd' commands are only usable by root and don't return the
+ * content of ifr/iwr to user (but you are not obliged to use the set/get
+ * convention, just use every other two command).
+ * And I repeat : you are not obliged to use them with iwspy, but you
+ * must be compliant with it.
+ */
+
X /* ------------------------- IOCTL STUFF ------------------------- */
X
X /* The first and the last (range) */
X #define SIOCIWFIRST 0x8B00
-#define SIOCIWLAST 0x8B30
+#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
X
X /* Even : get (world access), odd : set (root access) */
X #define IW_IS_SET(cmd) (!((cmd) & 0x1))
@@ -191,7 +222,7 @@
X /*
X * The following is used with SIOCGIWPRIV. It allow a driver to define
X * the interface (name, type of data) for its private ioctl.
- * Privates ioctl are SIOCDEVPRIVATE -> SIOCDEVPRIVATE + 0xF
+ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
X */
X
X #define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
@@ -334,23 +365,38 @@
X */
X struct iw_quality
X {
- __u8 qual; /* link quality (%retries, SNR or better...) */
- __u8 level; /* signal level */
- __u8 noise; /* noise level */
+ __u8 qual; /* link quality (%retries, SNR,
+ %missed beacons or better...) */
+ __u8 level; /* signal level (dBm) */
+ __u8 noise; /* noise level (dBm) */
X __u8 updated; /* Flags to know if updated */
X };
X
X /*
X * Packet discarded in the wireless adapter due to
X * "wireless" specific problems...
+ * Note : the list of counter and statistics in net_device_stats
+ * is already pretty exhaustive, and you should use that first.
+ * This is only additional stats...
X */
X struct iw_discarded
X {
- __u32 nwid; /* Wrong nwid */
- __u32 code; /* Unable to code/decode */
+ __u32 nwid; /* Rx : Wrong nwid/essid */
+ __u32 code; /* Rx : Unable to code/decode (WEP) */
+ __u32 fragment; /* Rx : Can't perform MAC reassembly */
+ __u32 retries; /* Tx : Max MAC retries num reached */
X __u32 misc; /* Others cases */
X };
X
+/*
+ * Packet/Time period missed in the wireless adapter due to
+ * "wireless" specific problems...
+ */
+struct iw_missed
+{
+ __u32 beacon; /* Missed beacons/superframe */
+};
+
X /* ------------------------ WIRELESS STATS ------------------------ */
X /*
X * Wireless statistics (used for /proc/net/wireless)
@@ -363,6 +409,7 @@
X struct iw_quality qual; /* Quality of the link
X * (instant/mean/max) */
X struct iw_discarded discard; /* Packet discarded counts */
+ struct iw_missed miss; /* Packet missed counts */
X };
X
X /* ------------------------ IOCTL REQUEST ------------------------ */
@@ -493,6 +540,19 @@
X __s32 max_retry; /* Maximal number of retries */
X __s32 min_r_time; /* Minimal retry lifetime */
X __s32 max_r_time; /* Maximal retry lifetime */
+
+ /* Average quality of link & SNR */
+ struct iw_quality avg_qual; /* Quality of the link */
+ /* This should contain the average/typical values of the quality
+ * indicator. This should be the threshold between a "good" and
+ * a "bad" link (example : monitor going from green to orange).
+ * Currently, user space apps like quality monitors don't have any
+ * way to calibrate the measurement. With this, they can split
+ * the range between 0 and max_qual in different quality level
+ * (using a geometric subdivision centered on the average).
+ * I expect that people doing the user space apps will feedback
+ * us on which value we need to put in each driver...
+ */
X };
X
X /*
diff -u --recursive --new-file v2.4.12/linux/include/net/route.h linux/include/net/route.h
--- v2.4.12/linux/include/net/route.h Thu Oct 18 13:48:05 2001
+++ linux/include/net/route.h Tue Oct 23 21:59:33 2001
@@ -37,9 +37,12 @@
X #endif
X
X #define RTO_ONLINK 0x01
-#define RTO_TPROXY 0x80000000
X
X #define RTO_CONN 0
+/* RTO_CONN is not used (being alias for 0), but preserved not to break
+ * some modules referring to it. */
+
+#define RT_CONN_FLAGS(sk) (RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute)
X
X struct rt_key
X {
diff -u --recursive --new-file v2.4.12/linux/include/pcmcia/cs_types.h linux/include/pcmcia/cs_types.h
--- v2.4.12/linux/include/pcmcia/cs_types.h Fri Feb 16 16:02:37 2001
+++ linux/include/pcmcia/cs_types.h Thu Oct 11 09:43:29 2001
@@ -36,8 +36,13 @@
X #include <sys/types.h>
X #endif
X
-typedef u_short socket_t;
+#ifdef __arm__
+typedef u_int ioaddr_t;
+#else
X typedef u_short ioaddr_t;
+#endif
+
+typedef u_short socket_t;
X typedef u_int event_t;
X typedef u_char cisdata_t;
X typedef u_short page_t;
diff -u --recursive --new-file v2.4.12/linux/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- v2.4.12/linux/include/pcmcia/ss.h Fri Feb 16 16:02:37 2001
+++ linux/include/pcmcia/ss.h Thu Oct 11 09:43:29 2001
@@ -30,6 +30,8 @@
X #ifndef _LINUX_SS_H
X #define _LINUX_SS_H
X
+#include <pcmcia/cs_types.h>
+
X /* Definitions for card status flags for GetStatus */
X #define SS_WRPROT 0x0001
X #define SS_CARDLOCK 0x0002
@@ -52,6 +54,7 @@
X u_int features;
X u_int irq_mask;
X u_int map_size;
+ ioaddr_t io_offset;
X u_char pci_irq;
X struct pci_dev *cb_dev;
X struct bus_operations *bus;
@@ -101,7 +104,7 @@
X u_char map;
X u_char flags;
X u_short speed;
- u_short start, stop;
+ ioaddr_t start, stop;
X } pccard_io_map;
X
X typedef struct pccard_mem_map {
diff -u --recursive --new-file v2.4.12/linux/init/main.c linux/init/main.c
--- v2.4.12/linux/init/main.c Tue Oct 9 17:06:53 2001
+++ linux/init/main.c Fri Oct 12 10:17:15 2001
@@ -777,8 +777,12 @@
X int i, pid;
X
X pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
- if (pid>0)
- while (pid != wait(&i));
+ if (pid > 0) {
+ while (pid != wait(&i)) {
+ current->policy |= SCHED_YIELD;
+ schedule();
+ }
+ }
X if (MAJOR(real_root_dev) != RAMDISK_MAJOR
X || MINOR(real_root_dev) != 0) {
X error = change_root(real_root_dev,"/initrd");
diff -u --recursive --new-file v2.4.12/linux/ipc/shm.c linux/ipc/shm.c
--- v2.4.12/linux/ipc/shm.c Sun Sep 23 11:41:01 2001
+++ linux/ipc/shm.c Wed Oct 17 14:16:39 2001
@@ -348,6 +348,7 @@
X
X static void shm_get_stat (unsigned long *rss, unsigned long *swp)
X {
+ struct shmem_inode_info *info;
X int i;
X
X *rss = 0;
@@ -361,10 +362,11 @@
X if(shp == NULL)
X continue;
X inode = shp->shm_file->f_dentry->d_inode;
- spin_lock (&inode->u.shmem_i.lock);
+ info = SHMEM_I(inode);
+ spin_lock (&info->lock);
X *rss += inode->i_mapping->nrpages;
- *swp += inode->u.shmem_i.swapped;
- spin_unlock (&inode->u.shmem_i.lock);
+ *swp += info->swapped;
+ spin_unlock (&info->lock);
X }
X }
X
diff -u --recursive --new-file v2.4.12/linux/kernel/context.c linux/kernel/context.c
--- v2.4.12/linux/kernel/context.c Sat May 19 17:47:55 2001
+++ linux/kernel/context.c Thu Oct 11 11:17:22 2001
@@ -19,6 +19,7 @@
X #include <linux/init.h>
X #include <linux/unistd.h>
X #include <linux/signal.h>
+#include <linux/completion.h>
X
X static DECLARE_TASK_QUEUE(tq_context);
X static DECLARE_WAIT_QUEUE_HEAD(context_task_wq);
@@ -63,7 +64,7 @@


X return ret;
X }
X

-static int context_thread(void *dummy)
+static int context_thread(void *startup)
X {
X struct task_struct *curtask = current;
X DECLARE_WAITQUEUE(wait, curtask);
@@ -79,6 +80,8 @@
X recalc_sigpending(curtask);
X spin_unlock_irq(&curtask->sigmask_lock);
X
+ complete((struct completion *)startup);
+
X /* Install a handler so SIGCLD is delivered */
X sa.sa.sa_handler = SIG_IGN;
X sa.sa.sa_flags = 0;
@@ -150,7 +153,10 @@
X
X int start_context_thread(void)
X {
- kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);
+ static struct completion startup __initdata = COMPLETION_INITIALIZER(startup);
+
+ kernel_thread(context_thread, &startup, CLONE_FS | CLONE_FILES);
+ wait_for_completion(&startup);
X return 0;
X }
X
diff -u --recursive --new-file v2.4.12/linux/kernel/exit.c linux/kernel/exit.c
--- v2.4.12/linux/kernel/exit.c Sun Sep 23 11:41:01 2001
+++ linux/kernel/exit.c Mon Oct 22 09:27:55 2001


@@ -149,28 +149,21 @@
X }

X
X /*
- * When we die, we re-parent all our children.
- * Try to give them to another thread in our process
- * group, and if no such member exists, give it to
+ * When we die, we re-parent all our children to
X * the global child reaper process (ie "init")
X */
X static inline void forget_original_parent(struct task_struct * father)
X {
- struct task_struct * p, *reaper;
+ struct task_struct * p;
X
X read_lock(&tasklist_lock);
X
- /* Next in our thread group */
- reaper = next_thread(father);
- if (reaper == father)
- reaper = child_reaper;
-
X for_each_task(p) {
X if (p->p_opptr == father) {
X /* We dont want people slaying init */
X p->exit_signal = SIGCHLD;
X p->self_exec_id++;
- p->p_opptr = reaper;
+ p->p_opptr = child_reaper;
X if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
X }
X }
diff -u --recursive --new-file v2.4.12/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.12/linux/kernel/ksyms.c Tue Oct 9 17:06:53 2001
+++ linux/kernel/ksyms.c Wed Oct 17 14:32:50 2001
@@ -59,7 +59,7 @@
X
X extern void *sys_call_table;
X
-extern int sys_tz;
+extern struct timezone sys_tz;
X extern int request_dma(unsigned int dmanr, char * deviceID);
X extern void free_dma(unsigned int dmanr);
X extern spinlock_t dma_spin_lock;
@@ -223,6 +223,7 @@
X EXPORT_SYMBOL(posix_test_lock);
X EXPORT_SYMBOL(posix_block_lock);
X EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(posix_locks_deadlock);
X EXPORT_SYMBOL(locks_mandatory_area);
X EXPORT_SYMBOL(dput);
X EXPORT_SYMBOL(have_submounts);
diff -u --recursive --new-file v2.4.12/linux/kernel/sched.c linux/kernel/sched.c
--- v2.4.12/linux/kernel/sched.c Tue Oct 9 17:06:53 2001
+++ linux/kernel/sched.c Wed Oct 17 14:14:37 2001
@@ -1297,6 +1297,7 @@
X
X current->session = 1;
X current->pgrp = 1;
+ current->tty = NULL;
X
X /* Become as one with the init task */
X
diff -u --recursive --new-file v2.4.12/linux/lib/vsprintf.c linux/lib/vsprintf.c
--- v2.4.12/linux/lib/vsprintf.c Sun Sep 23 11:41:01 2001
+++ linux/lib/vsprintf.c Thu Oct 11 11:17:22 2001
@@ -18,6 +18,7 @@
X #include <linux/types.h>
X #include <linux/string.h>
X #include <linux/ctype.h>
+#include <linux/kernel.h>
X
X #include <asm/div64.h>
X
@@ -519,36 +520,44 @@
X int num = 0;
X int qualifier;
X int base;
- unsigned int field_width;
+ int field_width = -1;
X int is_sign = 0;
X
- for (; *fmt; fmt++) {
+ while(*fmt && *str) {
X /* skip any white space in format */
+ /* white space in format matchs any amount of
+ * white space, including none, in the input.
+ */
X if (isspace(*fmt)) {
- continue;
+ while (isspace(*fmt))
+ ++fmt;
+ while (isspace(*str))
+ ++str;
X }
X
X /* anything that is not a conversion must match exactly */
- if (*fmt != '%') {
+ if (*fmt != '%' && *fmt) {
X if (*fmt++ != *str++)
- return num;
+ break;
X continue;
X }
+
+ if (!*fmt)
+ break;
X ++fmt;
X
X /* skip this conversion.
X * advance both strings to next white space
X */
X if (*fmt == '*') {
- while (!isspace(*fmt))
+ while (!isspace(*fmt) && *fmt)
X fmt++;
- while(!isspace(*str))
+ while (!isspace(*str) && *str)
X str++;
X continue;
X }
X
X /* get field width */
- field_width = 0xffffffffUL;
X if (isdigit(*fmt))
X field_width = skip_atoi(&fmt);
X
@@ -561,25 +570,32 @@
X base = 10;
X is_sign = 0;
X
- switch(*fmt) {
+ if (!*fmt || !*str)
+ break;
+
+ switch(*fmt++) {
X case 'c':
X {
X char *s = (char *) va_arg(args,char*);
+ if (field_width == -1)
+ field_width = 1;
X do {
X *s++ = *str++;
- } while(field_width-- > 0);
+ } while(field_width-- > 0 && *str);
X num++;
X }
X continue;
X case 's':
X {
X char *s = (char *) va_arg(args, char *);
+ if(field_width == -1)
+ field_width = INT_MAX;
X /* first, skip leading white space in buffer */
X while (isspace(*str))
X str++;
X
X /* now copy until next white space */
- while (!isspace(*str) && field_width--) {
+ while (*str && !isspace(*str) && field_width--) {
X *s++ = *str++;
X }
X *s = '\0';
@@ -620,6 +636,9 @@
X */
X while (isspace(*str))
X str++;
+
+ if (!*str || !isdigit(*str))
+ break;
X
X switch(qualifier) {
X case 'h':
diff -u --recursive --new-file v2.4.12/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.12/linux/mm/filemap.c Tue Oct 9 17:06:53 2001
+++ linux/mm/filemap.c Tue Oct 23 17:52:48 2001
@@ -667,8 +667,7 @@
X static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
X static int page_cache_read(struct file * file, unsigned long offset)
X {
- struct inode *inode = file->f_dentry->d_inode;
- struct address_space *mapping = inode->i_mapping;
+ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
X struct page **hash = page_hash(mapping, offset);
X struct page *page;
X
@@ -1521,6 +1520,53 @@


X return retval;
X }
X

+static ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr)
+{
+ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+ unsigned long max;
+
+ if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
+ return -EINVAL;
+
+ /* Limit it to the size of the file.. */
+ max = (mapping->host->i_size + ~PAGE_CACHE_MASK) >> PAGE_CACHE_SHIFT;
+ if (index > max)
+ return 0;
+ max -= index;
+ if (nr > max)
+ nr = max;
+
+ /* And limit it to a sane percentage of the inactive list.. */
+ max = nr_inactive_pages / 2;
+ if (nr > max)
+ nr = max;
+
+ while (nr) {
+ page_cache_read(file, index);
+ index++;
+ nr--;


+ }
+ return 0;
+}

+
+asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
+{
+ ssize_t ret;
+ struct file *file;
+
+ ret = -EBADF;
+ file = fget(fd);
+ if (file) {
+ if (file->f_mode & FMODE_READ) {
+ unsigned long start = offset >> PAGE_CACHE_SHIFT;
+ unsigned long len = (count + ((long)offset & ~PAGE_CACHE_MASK)) >> PAGE_CACHE_SHIFT;
+ ret = do_readahead(file, start, len);
+ }
+ fput(file);


+ }
+ return ret;
+}

+
X /*
X * Read-ahead and flush behind for MADV_SEQUENTIAL areas. Since we are


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'
fi

echo 'End of part 52'
echo 'File patch-2.4.13 is continued in part 53'
echo "53" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 24, 2001, 8:00:23 PM10/24/01
to
Archive-name: v2.4/patch-2.4.13/part53

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


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

if test "$Scheck" != 53; 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.13'
else
echo 'x - continuing with patch-2.4.13'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.13' &&

X * sure this is sequential access, we don't need a flexible read-ahead
@@ -1589,12 +1635,13 @@
X {
X int error;
X struct file *file = area->vm_file;


- struct inode *inode = file->f_dentry->d_inode;
- struct address_space *mapping = inode->i_mapping;
+ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;

+ struct inode *inode = mapping->host;
X struct page *page, **hash, *old_page;
- unsigned long size, pgoff;
+ unsigned long size, pgoff, endoff;
X
X pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+ endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
X
X retry_all:
X /*
@@ -1605,6 +1652,10 @@
X if ((pgoff >= size) && (area->vm_mm == current->mm))
X return NULL;
X
+ /* The "size" of the file, as far as mmap is concerned, isn't bigger than the mapping */
+ if (size > endoff)
+ size = endoff;
+
X /*
X * Do we have something in the page cache already?
X */
@@ -1851,15 +1902,14 @@
X
X int generic_file_mmap(struct file * file, struct vm_area_struct * vma)


X {
- struct inode *inode = file->f_dentry->d_inode;

+ struct address_space *mapping = file->f_dentry->d_inode->i_mapping;

+ struct inode *inode = mapping->host;
X
X if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
- if (!inode->i_mapping->a_ops->writepage)
+ if (!mapping->a_ops->writepage)
X return -EINVAL;
X }
- if (!inode->i_sb || !S_ISREG(inode->i_mode))
- return -EACCES;
- if (!inode->i_mapping->a_ops->readpage)
+ if (!mapping->a_ops->readpage)
X return -ENOEXEC;
X UPDATE_ATIME(inode);
X vma->vm_ops = &generic_file_vm_ops;
@@ -2309,7 +2359,7 @@
X unsigned long pgoff)
X {
X unsigned char present = 0;
- struct address_space * as = &vma->vm_file->f_dentry->d_inode->i_data;
+ struct address_space * as = vma->vm_file->f_dentry->d_inode->i_mapping;
X struct page * page, ** hash = page_hash(as, pgoff);
X
X spin_lock(&pagecache_lock);
diff -u --recursive --new-file v2.4.12/linux/mm/highmem.c linux/mm/highmem.c
--- v2.4.12/linux/mm/highmem.c Sun Sep 23 11:41:01 2001
+++ linux/mm/highmem.c Mon Oct 22 15:01:57 2001
@@ -327,7 +327,6 @@
X struct list_head *tmp;


X struct page *page;
X

-repeat_alloc:
X page = alloc_page(GFP_NOHIGHIO);
X if (page)
X return page;
@@ -337,6 +336,7 @@
X */
X wakeup_bdflush();
X
+repeat_alloc:
X /*
X * Try to allocate from the emergency pool.
X */
@@ -365,7 +365,6 @@
X struct list_head *tmp;


X struct buffer_head *bh;
X

-repeat_alloc:
X bh = kmem_cache_alloc(bh_cachep, SLAB_NOHIGHIO);
X if (bh)
X return bh;
@@ -375,6 +374,7 @@
X */
X wakeup_bdflush();
X
+repeat_alloc:
X /*
X * Try to allocate from the emergency pool.
X */
diff -u --recursive --new-file v2.4.12/linux/mm/memory.c linux/mm/memory.c
--- v2.4.12/linux/mm/memory.c Tue Oct 9 17:06:53 2001
+++ linux/mm/memory.c Mon Oct 15 12:09:50 2001
@@ -1122,10 +1122,8 @@
X spin_unlock(&mm->page_table_lock);
X page = lookup_swap_cache(entry);
X if (!page) {
- lock_kernel();
X swapin_readahead(entry);
X page = read_swap_cache_async(entry);
- unlock_kernel();
X if (!page) {
X spin_lock(&mm->page_table_lock);
X /*
diff -u --recursive --new-file v2.4.12/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.4.12/linux/mm/page_alloc.c Tue Oct 9 17:06:53 2001
+++ linux/mm/page_alloc.c Tue Oct 23 21:40:32 2001
@@ -394,7 +394,7 @@
X }
X
X /* Don't let big-order allocations loop */
- if (order)
+ if (order > 1)
X return NULL;
X
X /* Yield for kswapd, and try again */
@@ -467,20 +467,23 @@
X {
X pg_data_t *pgdat = pgdat_list;
X unsigned int sum = 0;
- zonelist_t *zonelist;
- zone_t **zonep, *zone;
X
X do {
- zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
- zonep = zonelist->zones;
+ zonelist_t *zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
+ zone_t **zonep = zonelist->zones;
+ zone_t *zone;
X
- for (zone = *zonep++; zone; zone = *zonep++)
- sum += zone->free_pages;
+ for (zone = *zonep++; zone; zone = *zonep++) {
+ unsigned long size = zone->size;
+ unsigned long high = zone->pages_high;
+ if (size > high)
+ sum += size - high;
+ }
X
X pgdat = pgdat->node_next;
X } while (pgdat);
X
- return sum + nr_active_pages + nr_inactive_pages;
+ return sum;
X }
X
X #if CONFIG_HIGHMEM
@@ -497,6 +500,8 @@
X }
X #endif
X
+#define K(x) ((x) << (PAGE_SHIFT-10))
+
X /*
X * Show free area list (used inside shift_scroll-lock stuff)
X * We also calculate the percentage fragmentation. We do this by counting the
@@ -519,21 +524,17 @@
X printk("Zone:%s freepages:%6lukB min:%6luKB low:%6lukB "
X "high:%6lukB\n",
X zone->name,
- (zone->free_pages)
- << ((PAGE_SHIFT-10)),
- zone->pages_min
- << ((PAGE_SHIFT-10)),
- zone->pages_low
- << ((PAGE_SHIFT-10)),
- zone->pages_high
- << ((PAGE_SHIFT-10)));
+ K(zone->free_pages),
+ K(zone->pages_min),
+ K(zone->pages_low),
+ K(zone->pages_high));
X
X tmpdat = tmpdat->node_next;
X }
X
X printk("Free pages: %6dkB (%6dkB HighMem)\n",
- nr_free_pages() << (PAGE_SHIFT-10),
- nr_free_highpages() << (PAGE_SHIFT-10));
+ K(nr_free_pages()),
+ K(nr_free_highpages()));
X
X printk("( Active: %d, inactive: %d, free: %d )\n",
X nr_active_pages,
@@ -564,7 +565,7 @@
X }
X spin_unlock_irqrestore(&zone->lock, flags);
X }
- printk("= %lukB)\n", total * (PAGE_SIZE>>10));
+ printk("= %lukB)\n", K(total));
X }
X
X #ifdef SWAP_CACHE_INFO
diff -u --recursive --new-file v2.4.12/linux/mm/shmem.c linux/mm/shmem.c
--- v2.4.12/linux/mm/shmem.c Thu Oct 11 08:02:26 2001
+++ linux/mm/shmem.c Wed Oct 17 14:19:20 2001
@@ -386,10 +386,10 @@
X spin_unlock (&info->lock);
X return 0;
X found:
+ delete_from_swap_cache(page);
X add_to_page_cache(page, info->inode->i_mapping, offset + idx);
X SetPageDirty(page);
X SetPageUptodate(page);
- UnlockPage(page);
X info->swapped--;
X spin_unlock(&info->lock);
X return 1;
@@ -531,10 +531,8 @@
X if (!page) {
X swp_entry_t swap = *entry;
X spin_unlock (&info->lock);
- lock_kernel();
X swapin_readahead(*entry);
X page = read_swap_cache_async(*entry);
- unlock_kernel();
X if (!page) {
X if (entry->val != swap.val)
X goto repeat;
@@ -1237,45 +1235,54 @@
X
X static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
X {
- char *this_char, *value;
+ char *this_char, *value, *rest;
X
X this_char = NULL;
X if ( options )
X this_char = strtok(options,",");
X for ( ; this_char; this_char = strtok(NULL,",")) {
- if ((value = strchr(this_char,'=')) != NULL)
+ if ((value = strchr(this_char,'=')) != NULL) {
X *value++ = 0;
+ } else {
+ printk(KERN_ERR
+ "shmem_parse_options: No value for option '%s'\n",
+ this_char);


+ return 1;
+ }
+

X if (!strcmp(this_char,"size")) {
X unsigned long long size;
- if (!value || !*value || !blocks)
- return 1;
- size = memparse(value,&value);
- if (*value)
- return 1;
+ size = memparse(value,&rest);
+ if (*rest)
+ goto bad_val;
X *blocks = size >> PAGE_CACHE_SHIFT;
X } else if (!strcmp(this_char,"nr_blocks")) {
- if (!value || !*value || !blocks)
- return 1;
- *blocks = memparse(value,&value);
- if (*value)
- return 1;
+ *blocks = memparse(value,&rest);
+ if (*rest)
+ goto bad_val;
X } else if (!strcmp(this_char,"nr_inodes")) {
- if (!value || !*value || !inodes)
- return 1;
- *inodes = memparse(value,&value);
- if (*value)
- return 1;
+ *inodes = memparse(value,&rest);
+ if (*rest)
+ goto bad_val;
X } else if (!strcmp(this_char,"mode")) {
- if (!value || !*value || !mode)
- return 1;
- *mode = simple_strtoul(value,&value,8);
- if (*value)
- return 1;
- }
- else
+ if (!mode)
+ continue;
+ *mode = simple_strtoul(value,&rest,8);
+ if (*rest)
+ goto bad_val;
+ } else {
+ printk(KERN_ERR "shmem_parse_options: Bad option %s\n",
+ this_char);


X return 1;
+ }
X }

X return 0;
+
+bad_val:
+ printk(KERN_ERR "shmem_parse_options: Bad value '%s' for option '%s'\n",
+ value, this_char);
+ return 1;
+
X }
X
X static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
diff -u --recursive --new-file v2.4.12/linux/mm/swap.c linux/mm/swap.c
--- v2.4.12/linux/mm/swap.c Sun Sep 23 11:41:01 2001
+++ linux/mm/swap.c Mon Oct 22 14:27:41 2001
@@ -48,7 +48,7 @@
X * called on a page which is not on any of the lists, the
X * page is left alone.
X */
-void deactivate_page_nolock(struct page * page)
+static inline void deactivate_page_nolock(struct page * page)
X {
X if (PageActive(page)) {
X del_page_from_active_list(page);
@@ -66,7 +66,7 @@
X /*
X * Move an inactive page to the active list.
X */
-void activate_page_nolock(struct page * page)
+static inline void activate_page_nolock(struct page * page)
X {
X if (PageInactive(page)) {
X del_page_from_inactive_list(page);
@@ -130,11 +130,15 @@
X */
X void __init swap_setup(void)
X {
- /* Use a smaller cluster for memory <16MB or <32MB */
- if (num_physpages < ((16 * 1024 * 1024) >> PAGE_SHIFT))
+ unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
+
+ /* Use a smaller cluster for small-memory machines */
+ if (megs < 16)
X page_cluster = 2;
- else if (num_physpages < ((32 * 1024 * 1024) >> PAGE_SHIFT))
- page_cluster = 3;
X else
- page_cluster = 4;
+ page_cluster = 3;
+ /*
+ * Right now other parts of the system means that we
+ * _really_ don't want to cluster much more
+ */
X }
diff -u --recursive --new-file v2.4.12/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.4.12/linux/mm/swapfile.c Tue Oct 9 17:06:53 2001
+++ linux/mm/swapfile.c Mon Oct 15 12:09:50 2001
@@ -209,7 +209,7 @@
X * share this swap entry, so be cautious and let do_wp_page work out
X * what to do if a write is requested later.
X */
-/* BKL, mmlist_lock and vma->vm_mm->page_table_lock are held */
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
X static inline void unuse_pte(struct vm_area_struct * vma, unsigned long address,
X pte_t *dir, swp_entry_t entry, struct page* page)
X {
@@ -225,7 +225,7 @@
X ++vma->vm_mm->rss;
X }
X
-/* BKL, mmlist_lock and vma->vm_mm->page_table_lock are held */
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
X static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
X unsigned long address, unsigned long size, unsigned long offset,
X swp_entry_t entry, struct page* page)
@@ -253,7 +253,7 @@
X } while (address && (address < end));
X }
X
-/* BKL, mmlist_lock and vma->vm_mm->page_table_lock are held */
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
X static inline void unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
X unsigned long address, unsigned long size,
X swp_entry_t entry, struct page* page)
@@ -284,7 +284,7 @@
X } while (address && (address < end));
X }
X
-/* BKL, mmlist_lock and vma->vm_mm->page_table_lock are held */
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
X static void unuse_vma(struct vm_area_struct * vma, pgd_t *pgdir,
X swp_entry_t entry, struct page* page)
X {
@@ -424,10 +424,6 @@
X
X /*
X * Don't hold on to start_mm if it looks like exiting.
- * Can mmput ever block? if so, then we cannot risk
- * it between deleting the page from the swap cache,
- * and completing the search through mms (and cannot
- * use it to avoid the long hold on mmlist_lock there).
X */
X if (atomic_read(&start_mm->mm_users) == 1) {
X mmput(start_mm);
@@ -436,18 +432,15 @@
X }
X
X /*
- * Wait for and lock page. Remove it from swap cache
- * so try_to_swap_out won't bump swap count. Mark dirty
- * so try_to_swap_out will preserve it without us having
- * to mark any present ptes as dirty: so we can skip
- * searching processes once swap count has all gone.
+ * Wait for and lock page. When do_swap_page races with
+ * try_to_unuse, do_swap_page can handle the fault much
+ * faster than try_to_unuse can locate the entry. This
+ * apparently redundant "wait_on_page" lets try_to_unuse
+ * defer to do_swap_page in such a case - in some tests,
+ * do_swap_page and try_to_unuse repeatedly compete.
X */
+ wait_on_page(page);
X lock_page(page);
- if (PageSwapCache(page))
- delete_from_swap_cache(page);
- SetPageDirty(page);
- UnlockPage(page);
- flush_page_to_ram(page);
X
X /*
X * Remove all references to entry, without blocking.
@@ -455,20 +448,22 @@
X * to search, but use it as a reminder to search shmem.
X */
X swcount = *swap_map;
- if (swcount) {
+ if (swcount > 1) {
+ flush_page_to_ram(page);
X if (start_mm == &init_mm)
X shmem_unuse(entry, page);
X else
X unuse_process(start_mm, entry, page);
X }
- if (*swap_map) {
+ if (*swap_map > 1) {
X int set_start_mm = (*swap_map >= swcount);
X struct list_head *p = &start_mm->mmlist;
X struct mm_struct *new_start_mm = start_mm;
X struct mm_struct *mm;
X
X spin_lock(&mmlist_lock);
- while (*swap_map && (p = p->next) != &start_mm->mmlist) {
+ while (*swap_map > 1 &&
+ (p = p->next) != &start_mm->mmlist) {
X mm = list_entry(p, struct mm_struct, mmlist);
X swcount = *swap_map;
X if (mm == &init_mm) {
@@ -486,7 +481,6 @@
X mmput(start_mm);
X start_mm = new_start_mm;
X }
- page_cache_release(page);
X
X /*
X * How could swap count reach 0x7fff when the maximum
@@ -505,23 +499,52 @@
X swap_list_lock();
X swap_device_lock(si);
X nr_swap_pages++;
- *swap_map = 0;
+ *swap_map = 1;
X swap_device_unlock(si);
X swap_list_unlock();
X reset_overflow = 1;
X }
X
X /*
+ * If a reference remains (rare), we would like to leave
+ * the page in the swap cache; but try_to_swap_out could
+ * then re-duplicate the entry once we drop page lock,
+ * so we might loop indefinitely; also, that page could
+ * not be swapped out to other storage meanwhile. So:
+ * delete from cache even if there's another reference,
+ * after ensuring that the data has been saved to disk -
+ * since if the reference remains (rarer), it will be
+ * read from disk into another page. Splitting into two
+ * pages would be incorrect if swap supported "shared
+ * private" pages, but they are handled by tmpfs files.
+ * Note shmem_unuse already deleted its from swap cache.
+ */
+ swcount = *swap_map;
+ if ((swcount > 0) != PageSwapCache(page))
+ BUG();
+ if ((swcount > 1) && PageDirty(page)) {
+ rw_swap_page(WRITE, page);
+ lock_page(page);
+ }
+ if (PageSwapCache(page))
+ delete_from_swap_cache(page);
+
+ /*
+ * So we could skip searching mms once swap count went
+ * to 1, we did not mark any present ptes as dirty: must
+ * mark page dirty so try_to_swap_out will preserve it.
+ */
+ SetPageDirty(page);
+ UnlockPage(page);
+ page_cache_release(page);
+
+ /*
X * Make sure that we aren't completely killing
X * interactive performance. Interruptible check on
X * signal_pending() would be nice, but changes the spec?
X */
X if (current->need_resched)
X schedule();
- else {
- unlock_kernel();
- lock_kernel();
- }
X }
X
X mmput(start_mm);
@@ -577,7 +600,9 @@
X total_swap_pages -= p->pages;
X p->flags = SWP_USED;
X swap_list_unlock();
+ unlock_kernel();
X err = try_to_unuse(type);
+ lock_kernel();
X if (err) {
X /* re-insert swap space back into swap_list */
X swap_list_lock();
diff -u --recursive --new-file v2.4.12/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.4.12/linux/mm/vmscan.c Tue Oct 9 17:06:53 2001
+++ linux/mm/vmscan.c Tue Oct 23 21:48:55 2001
@@ -47,20 +47,24 @@
X {
X pte_t pte;
X swp_entry_t entry;
- int right_classzone;
X
X /* Don't look at this pte if it's been accessed recently. */
X if (ptep_test_and_clear_young(page_table)) {
X flush_tlb_page(vma, address);
+ mark_page_accessed(page);


X return 0;
X }
X

- if (TryLockPage(page))
+ /* Don't bother unmapping pages that are active */
+ if (PageActive(page))
X return 0;
X
- right_classzone = 1;
+ /* Don't bother replenishing zones not under pressure.. */
X if (!memclass(page->zone, classzone))
- right_classzone = 0;
+ return 0;
+
+ if (TryLockPage(page))
+ return 0;
X
X /* From this point on, the odds are that we're going to
X * nuke this pte, so read and clear the pte. This hook
@@ -89,7 +93,7 @@
X {
X int freeable = page_count(page) - !!page->buffers <= 2;
X page_cache_release(page);
- return freeable & right_classzone;
+ return freeable;
X }
X }
X
@@ -283,10 +287,10 @@
X return count;
X }
X
-static int FASTCALL(swap_out(unsigned int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
-static int swap_out(unsigned int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
+static int FASTCALL(swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone));
+static int swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone)
X {
- int counter;
+ int counter, nr_pages = SWAP_CLUSTER_MAX;
X struct mm_struct *mm;
X
X /* Then, look at the other mm's */
@@ -326,13 +330,13 @@


X return 0;
X }
X

-static int FASTCALL(shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned int gfp_mask));
-static int shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned int gfp_mask)
+static int FASTCALL(shrink_cache(int nr_pages, int max_mapped, zone_t * classzone, unsigned int gfp_mask));
+static int shrink_cache(int nr_pages, int max_mapped, zone_t * classzone, unsigned int gfp_mask)
X {
X struct list_head * entry;
X
X spin_lock(&pagemap_lru_lock);
- while (max_scan && (entry = inactive_list.prev) != &inactive_list) {
+ while (max_mapped && (entry = inactive_list.prev) != &inactive_list) {
X struct page * page;
X
X if (unlikely(current->need_resched)) {
@@ -345,31 +349,35 @@
X
X page = list_entry(entry, struct page, lru);
X
- if (unlikely(!PageInactive(page) && !PageActive(page)))
+ if (unlikely(!PageInactive(page)))
X BUG();
X
X list_del(entry);
X list_add(entry, &inactive_list);
- if (PageTestandClearReferenced(page))
- continue;
-
- max_scan--;
X
- if (unlikely(!memclass(page->zone, classzone)))
+ if (!memclass(page->zone, classzone))
X continue;
X
X /* Racy check to avoid trylocking when not worthwhile */
X if (!page->buffers && page_count(page) != 1)
- continue;
+ goto page_mapped;
X
X /*
X * The page is locked. IO in progress?
X * Move it to the back of the list.
X */
- if (unlikely(TryLockPage(page)))
+ if (unlikely(TryLockPage(page))) {
+ if (PageLaunder(page) && (gfp_mask & __GFP_FS)) {
+ page_cache_get(page);
+ spin_unlock(&pagemap_lru_lock);
+ wait_on_page(page);
+ page_cache_release(page);
+ spin_lock(&pagemap_lru_lock);
+ }
X continue;
+ }
X
- if (PageDirty(page) && is_page_cache_freeable(page)) {
+ if (PageDirty(page) && is_page_cache_freeable(page) && page->mapping) {
X /*
X * It is not critical here to write it only if
X * the page is unmapped beause any direct writer
@@ -383,6 +391,7 @@
X writepage = page->mapping->a_ops->writepage;
X if ((gfp_mask & __GFP_FS) && writepage) {
X ClearPageDirty(page);
+ SetPageLaunder(page);
X page_cache_get(page);
X spin_unlock(&pagemap_lru_lock);
X
@@ -462,7 +471,10 @@
X if (!is_page_cache_freeable(page) || PageDirty(page)) {
X spin_unlock(&pagecache_lock);
X UnlockPage(page);
- continue;
+page_mapped:
+ if (--max_mapped)
+ continue;
+ break;
X }
X
X /* point of no return */
@@ -522,8 +534,8 @@
X spin_unlock(&pagemap_lru_lock);
X }
X
-static int FASTCALL(shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
-static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
+static int FASTCALL(shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages));
+static int shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages)
X {
X int max_scan;
X int chunk_size = nr_pages;
@@ -537,7 +549,7 @@
X /* try to keep the active list 2/3 of the size of the cache */
X ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
X refill_inactive(ratio);
-
+
X max_scan = nr_inactive_pages / priority;
X nr_pages = shrink_cache(nr_pages, max_scan, classzone, gfp_mask);
X if (nr_pages <= 0)
@@ -552,18 +564,18 @@
X return nr_pages;
X }
X
-int try_to_free_pages(zone_t * classzone, unsigned int gfp_mask, unsigned int order)
+int try_to_free_pages(zone_t *classzone, unsigned int gfp_mask, unsigned int order)
X {
X int ret = 0;
X int priority = DEF_PRIORITY;
X int nr_pages = SWAP_CLUSTER_MAX;
X
X do {
- nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages);
+ nr_pages = shrink_caches(classzone, priority, gfp_mask, nr_pages);
X if (nr_pages <= 0)
X return 1;
X
- ret |= swap_out(priority, classzone, gfp_mask, SWAP_CLUSTER_MAX << 2);
+ ret |= swap_out(priority, gfp_mask, classzone);
X } while (--priority);
X
X return ret;
diff -u --recursive --new-file v2.4.12/linux/net/ax25/ax25_ip.c linux/net/ax25/ax25_ip.c
--- v2.4.12/linux/net/ax25/ax25_ip.c Tue Jul 3 17:08:22 2001
+++ linux/net/ax25/ax25_ip.c Fri Oct 12 14:22:49 2001
@@ -56,9 +56,14 @@
X
X int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len)
X {
- /* header is an AX.25 UI frame from us to them */
- unsigned char *buff = skb_push(skb, AX25_HEADER_LEN);
+ unsigned char *buff;
+
+ /* they sometimes come back to us... */
+ if (type == ETH_P_AX25)
+ return 0;
X
+ /* header is an AX.25 UI frame from us to them */
+ buff = skb_push(skb, AX25_HEADER_LEN);
X *buff++ = 0x00; /* KISS DATA */
X
X if (daddr != NULL)
@@ -90,7 +95,7 @@
X *buff++ = AX25_P_ARP;
X break;
X default:
- printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%x2.2\n", type);
+ printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%2.2x\n", type);
X *buff++ = 0;
X break;
X }
diff -u --recursive --new-file v2.4.12/linux/net/bridge/br.c linux/net/bridge/br.c
--- v2.4.12/linux/net/bridge/br.c Tue Oct 9 17:06:53 2001
+++ linux/net/bridge/br.c Wed Oct 17 14:16:39 2001
@@ -5,7 +5,7 @@
X * Authors:
X * Lennert Buytenhek <buy...@gnu.org>
X *
- * $Id: br.c,v 1.45 2000/10/22 18:26:07 davem Exp $
+ * $Id: br.c,v 1.46 2001/10/02 02:22:36 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
diff -u --recursive --new-file v2.4.12/linux/net/core/dev.c linux/net/core/dev.c
--- v2.4.12/linux/net/core/dev.c Tue Oct 9 17:06:53 2001
+++ linux/net/core/dev.c Fri Oct 12 14:21:18 2001
@@ -1804,7 +1804,7 @@
X
X if (stats != (struct iw_statistics *) NULL) {
X size = sprintf(buffer,
- "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d\n",
+ "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
X dev->name,
X stats->status,
X stats->qual.qual,
@@ -1815,7 +1815,10 @@
X stats->qual.updated & 4 ? '.' : ' ',
X stats->discard.nwid,
X stats->discard.code,
- stats->discard.misc);
+ stats->discard.fragment,
+ stats->discard.retries,
+ stats->discard.misc,
+ stats->miss.beacon);
X stats->qual.updated = 0;
X }
X else
@@ -1839,8 +1842,8 @@
X struct net_device * dev;
X
X size = sprintf(buffer,
- "Inter-| sta-| Quality | Discarded packets\n"
- " face | tus | link level noise | nwid crypt misc\n"
+ "Inter-| sta-| Quality | Discarded packets | Missed\n"
+ " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
X );
X
X pos += size;
@@ -1871,6 +1874,33 @@
X return len;
X }
X #endif /* CONFIG_PROC_FS */
+
+/*
+ * Allow programatic access to /proc/net/wireless even if /proc
+ * doesn't exist... Also more efficient...
+ */
+static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
+{
+ /* Get stats from the driver */
+ struct iw_statistics *stats = (dev->get_wireless_stats ?
+ dev->get_wireless_stats(dev) :
+ (struct iw_statistics *) NULL);
+
+ if (stats != (struct iw_statistics *) NULL) {
+ struct iwreq * wrq = (struct iwreq *)ifr;
+
+ /* Copy statistics to the user buffer */
+ if(copy_to_user(wrq->u.data.pointer, stats,
+ sizeof(struct iw_statistics)))
+ return -EFAULT;
+
+ /* Check if we need to clear the update flag */
+ if(wrq->u.data.flags != 0)
+ stats->qual.updated = 0;
+ return(0);
+ } else
+ return -EOPNOTSUPP;
+}


X #endif /* WIRELESS_EXT */
X

X /**
@@ -2169,6 +2199,11 @@
X dev->name[IFNAMSIZ-1] = 0;
X notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
X return 0;
+
+#ifdef WIRELESS_EXT
+ case SIOCGIWSTATS:
+ return dev_iwstats(dev, ifr);
+#endif /* WIRELESS_EXT */
X
X /*
X * Unknown or private ioctl
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.4.12/linux/net/ipv4/ip_output.c Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/ip_output.c Wed Oct 17 14:16:39 2001
@@ -5,7 +5,7 @@
X *
X * The Internet Protocol (IP) output module.
X *
- * Version: $Id: ip_output.c,v 1.98 2001/09/01 00:31:50 davem Exp $
+ * Version: $Id: ip_output.c,v 1.99 2001/10/15 12:34:50 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -367,7 +367,7 @@
X * out.
X */
X if (ip_route_output(&rt, daddr, sk->saddr,
- RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
+ RT_CONN_FLAGS(sk),
X sk->bound_dev_if))
X goto no_route;
X __sk_dst_set(sk, &rt->u.dst);
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- v2.4.12/linux/net/ipv4/ipconfig.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv4/ipconfig.c Wed Oct 17 14:16:39 2001


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

- * $Id: ipconfig.c,v 1.38 2001/09/25 23:23:07 davem Exp $
+ * $Id: ipconfig.c,v 1.39 2001/10/13 01:47:31 davem Exp $
X *
X * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
X * user-supplied information to configure own IP address and routes.
@@ -95,7 +95,7 @@
X */
X
X /* This is used by platforms which might be able to set the ipconfig
- * variabled using firmware environment vars. If this is set, it will
+ * variables using firmware environment vars. If this is set, it will
X * ignore such firmware variables.
X */
X int ic_set_manually __initdata = 0; /* IPconfig parameters set manually */
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/ipip.c linux/net/ipv4/ipip.c
--- v2.4.12/linux/net/ipv4/ipip.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv4/ipip.c Wed Oct 17 14:16:39 2001


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

X * Linux NET3: IP/IP protocol decoder.
X *
- * Version: $Id: ipip.c,v 1.49 2001/09/25 22:35:47 davem Exp $
+ * Version: $Id: ipip.c,v 1.50 2001/10/02 02:22:36 davem Exp $


X *
X * Authors:

X * Sam Lantinga (slo...@cs.ucdavis.edu) 02/01/95
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v2.4.12/linux/net/ipv4/route.c Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/route.c Wed Oct 17 14:16:39 2001
@@ -5,7 +5,7 @@
X *
X * ROUTE - implementation of the IP router.
X *
- * Version: $Id: route.c,v 1.99 2001/09/18 22:29:09 davem Exp $
+ * Version: $Id: route.c,v 1.100 2001/10/15 12:34:50 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -2002,9 +2002,7 @@
X rth->key.fwmark == key->fwmark &&
X #endif
X !((rth->key.tos ^ key->tos) &
- (IPTOS_RT_MASK | RTO_ONLINK)) &&
- ((key->tos & RTO_TPROXY) ||
- !(rth->rt_flags & RTCF_TPROXY))) {
+ (IPTOS_RT_MASK | RTO_ONLINK))) {
X rth->u.dst.lastuse = jiffies;
X dst_hold(&rth->u.dst);
X rth->u.dst.__use++;
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/syncookies.c linux/net/ipv4/syncookies.c
--- v2.4.12/linux/net/ipv4/syncookies.c Wed May 16 10:31:27 2001
+++ linux/net/ipv4/syncookies.c Wed Oct 17 14:16:39 2001
@@ -9,7 +9,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X *
- * $Id: syncookies.c,v 1.14 2001/05/05 01:01:55 davem Exp $
+ * $Id: syncookies.c,v 1.15 2001/10/15 12:34:50 davem Exp $
X *
X * Missing: IPv6 support.
X */
@@ -178,7 +178,7 @@
X opt &&
X opt->srr ? opt->faddr : req->af.v4_req.rmt_addr,
X req->af.v4_req.loc_addr,
- sk->protinfo.af_inet.tos | RTO_CONN,
+ RT_CONN_FLAGS(sk),
X 0)) {
X tcp_openreq_free(req);
X goto out;
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.4.12/linux/net/ipv4/tcp_ipv4.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv4/tcp_ipv4.c Sun Oct 21 10:36:54 2001
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_ipv4.c,v 1.231 2001/09/26 23:38:47 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.234 2001/10/18 09:49:08 davem Exp $
X *
X * IPv4 specific functions
X *
@@ -162,6 +162,37 @@
X local_bh_enable();
X }
X
+static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, unsigned short snum)
+{
+ sk->num = snum;
+ if ((sk->bind_next = tb->owners) != NULL)
+ tb->owners->bind_pprev = &sk->bind_next;
+ tb->owners = sk;
+ sk->bind_pprev = &tb->owners;
+ sk->prev = (struct sock *) tb;
+}
+
+static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
+{
+ struct sock *sk2 = tb->owners;
+ int sk_reuse = sk->reuse;
+
+ for( ; sk2 != NULL; sk2 = sk2->bind_next) {
+ if (sk != sk2 &&
+ sk->bound_dev_if == sk2->bound_dev_if) {
+ if (!sk_reuse ||
+ !sk2->reuse ||
+ sk2->state == TCP_LISTEN) {
+ if (!sk2->rcv_saddr ||
+ !sk->rcv_saddr ||
+ (sk2->rcv_saddr == sk->rcv_saddr))


+ break;
+ }
+ }
+ }

+ return sk2 != NULL;
+}
+
X /* Obtain a reference to a local port for the given sock,
X * if snum is zero it means select any available local port.
X */
@@ -216,26 +247,9 @@
X if (tb->fastreuse != 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
X goto success;
X } else {
- struct sock *sk2 = tb->owners;
- int sk_reuse = sk->reuse;
-
- for( ; sk2 != NULL; sk2 = sk2->bind_next) {
- if (sk != sk2 &&
- sk->bound_dev_if == sk2->bound_dev_if) {
- if (!sk_reuse ||
- !sk2->reuse ||
- sk2->state == TCP_LISTEN) {
- if (!sk2->rcv_saddr ||
- !sk->rcv_saddr ||
- (sk2->rcv_saddr == sk->rcv_saddr))


- break;
- }
- }
- }

- /* If we found a conflict, fail. */
- ret = 1;
- if (sk2 != NULL)
- goto fail_unlock;
+ ret = 1;
+ if (tcp_bind_conflict(sk, tb))
+ goto fail_unlock;
X }
X }
X ret = 1;
@@ -251,17 +265,10 @@
X ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
X tb->fastreuse = 0;
X success:
- sk->num = snum;
- if (sk->prev == NULL) {
- if ((sk->bind_next = tb->owners) != NULL)
- tb->owners->bind_pprev = &sk->bind_next;
- tb->owners = sk;
- sk->bind_pprev = &tb->owners;
- sk->prev = (struct sock *) tb;
- } else {
- BUG_TRAP(sk->prev == (struct sock *) tb);
- }
- ret = 0;
+ if (sk->prev == NULL)
+ tcp_bind_hash(sk, tb, snum);
+ BUG_TRAP(sk->prev == (struct sock *) tb);


+ ret = 0;
X

X fail_unlock:
X spin_unlock(&head->lock);
@@ -660,7 +667,7 @@
X }
X
X tmp = ip_route_connect(&rt, nexthop, sk->saddr,
- RT_TOS(sk->protinfo.af_inet.tos)|RTO_CONN|sk->localroute, sk->bound_dev_if);
+ RT_CONN_FLAGS(sk), sk->bound_dev_if);
X if (tmp < 0)
X return tmp;


X
@@ -676,7 +683,7 @@

X daddr = rt->rt_dst;
X
X err = -ENOBUFS;
- buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_KERNEL);
+ buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
X
X if (buff == NULL)
X goto failure;
@@ -1147,8 +1154,7 @@
X opt->faddr :
X req->af.v4_req.rmt_addr),
X req->af.v4_req.loc_addr,
- RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
- sk->bound_dev_if)) {
+ RT_CONN_FLAGS(sk), sk->bound_dev_if)) {
X IP_INC_STATS_BH(IpOutNoRoutes);
X return NULL;
X }
@@ -1776,8 +1782,7 @@
X daddr = sk->protinfo.af_inet.opt->faddr;
X
X err = ip_route_output(&rt, daddr, sk->saddr,
- RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
- sk->bound_dev_if);
+ RT_CONN_FLAGS(sk), sk->bound_dev_if);
X if (!err) {
X __sk_dst_set(sk, &rt->u.dst);
X sk->route_caps = rt->u.dst.dev->features;
diff -u --recursive --new-file v2.4.12/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v2.4.12/linux/net/ipv4/udp.c Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/udp.c Wed Oct 17 14:16:39 2001
@@ -5,7 +5,7 @@
X *
X * The User Datagram Protocol (UDP).
X *
- * Version: $Id: udp.c,v 1.99 2001/09/01 00:31:50 davem Exp $
+ * Version: $Id: udp.c,v 1.100 2001/10/15 12:34:50 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -724,7 +724,7 @@
X sk_dst_reset(sk);
X
X err = ip_route_connect(&rt, usin->sin_addr.s_addr, sk->saddr,
- sk->protinfo.af_inet.tos|sk->localroute, sk->bound_dev_if);
+ RT_CONN_FLAGS(sk), sk->bound_dev_if);
X if (err)
X return err;
X if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
diff -u --recursive --new-file v2.4.12/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.4.12/linux/net/ipv6/af_inet6.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv6/af_inet6.c Wed Oct 17 14:16:39 2001
@@ -7,7 +7,7 @@
X *
X * Adapted from linux/net/ipv4/af_inet.c
X *
- * $Id: af_inet6.c,v 1.64 2001/06/13 16:25:03 davem Exp $
+ * $Id: af_inet6.c,v 1.65 2001/10/02 02:22:36 davem Exp $
X *
X * Fixes:
X * piggy, Karl Knutson : Socket protocol table
diff -u --recursive --new-file v2.4.12/linux/net/ipv6/netfilter/ip6t_mac.c linux/net/ipv6/netfilter/ip6t_mac.c
--- v2.4.12/linux/net/ipv6/netfilter/ip6t_mac.c Tue Jun 20 14:32:27 2000
+++ linux/net/ipv6/netfilter/ip6t_mac.c Fri Oct 12 15:30:00 2001


@@ -20,7 +20,7 @@
X

X /* Is mac pointer valid? */
X return (skb->mac.raw >= skb->head
- && skb->mac.raw < skb->head + skb->len - ETH_HLEN
+ && (skb->mac.raw + ETH_HLEN) <= skb->data
X /* If so, compare... */
X && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN)
X == 0) ^ info->invert));
diff -u --recursive --new-file v2.4.12/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.4.12/linux/net/ipv6/tcp_ipv6.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv6/tcp_ipv6.c Wed Oct 17 14:16:39 2001
@@ -5,7 +5,7 @@
X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *
- * $Id: tcp_ipv6.c,v 1.139 2001/09/26 23:38:47 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.140 2001/10/15 12:34:50 davem Exp $
X *
X * Based on:
X * linux/net/ipv4/tcp.c
@@ -339,13 +339,18 @@
X return tcp_v6_lookup_listener(daddr, hnum, dif);
X }
X
-#define tcp_v6_lookup(sa, sp, da, dp, dif) \
-({ struct sock *___sk; \
- local_bh_disable(); \
- ___sk = __tcp_v6_lookup((sa),(sp),(da),ntohs(dp),(dif)); \
- local_bh_enable(); \
- ___sk; \
-})
+__inline__ struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
+ struct in6_addr *daddr, u16 dport,
+ int dif)
+{
+ struct sock *sk;
+
+ local_bh_disable();
+ sk = __tcp_v6_lookup(saddr, sport, daddr, ntohs(dport), dif);
+ local_bh_enable();
+
+ return sk;
+}
X
X
X /*
@@ -656,7 +661,7 @@
X tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
X
X err = -ENOBUFS;
- buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_KERNEL);
+ buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
X
X if (buff == NULL)
X goto failure;
diff -u --recursive --new-file v2.4.12/linux/net/socket.c linux/net/socket.c
--- v2.4.12/linux/net/socket.c Tue Oct 9 17:06:53 2001
+++ linux/net/socket.c Wed Oct 17 14:38:28 2001
@@ -440,10 +440,11 @@


X struct inode * inode;

X struct socket * sock;
X
- inode = new_inode(sock_mnt->mnt_sb);
+ inode = get_empty_inode();
X if (!inode)
X return NULL;
X
+ inode->i_sb = sock_mnt->mnt_sb;
X sock = socki_lookup(inode);
X
X inode->i_mode = S_IFSOCK|S_IRWXUGO;
diff -u --recursive --new-file v2.4.12/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- v2.4.12/linux/net/sunrpc/sched.c Tue Oct 9 17:06:53 2001
+++ linux/net/sunrpc/sched.c Thu Oct 11 08:12:52 2001
@@ -30,7 +30,7 @@
X /*
X * We give RPC the same get_free_pages priority as NFS
X */
-#define GFP_RPC GFP_NFS
+#define GFP_RPC GFP_NOFS
X
X static void __rpc_default_timer(struct rpc_task *task);
X static void rpciod_killall(void);
@@ -744,7 +744,7 @@
X * for readahead):
X *
X * sync user requests: GFP_KERNEL
- * async requests: GFP_RPC (== GFP_NFS)
+ * async requests: GFP_RPC (== GFP_NOFS)
X * swap requests: GFP_ATOMIC (or new GFP_SWAPPER)
X */
X void *
@@ -1067,8 +1067,6 @@
X spin_unlock_irq(&current->sigmask_lock);
X
X strcpy(current->comm, "rpciod");
-
- current->flags |= PF_MEMALLOC;
X
X dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
X while (rpciod_users) {
diff -u --recursive --new-file v2.4.12/linux/net/sunrpc/stats.c linux/net/sunrpc/stats.c
--- v2.4.12/linux/net/sunrpc/stats.c Tue Dec 7 10:03:12 1999
+++ linux/net/sunrpc/stats.c Thu Oct 11 11:17:22 2001
@@ -202,3 +202,4 @@
X rpc_proc_exit();
X }
X #endif
+MODULE_LICENSE("GPL");


SHAR_EOF
true || echo 'restore of patch-2.4.13 failed'

echo 'File patch-2.4.13 is complete' &&
chmod 644 patch-2.4.13 ||


echo 'restore of patch-2.4.13 failed'

Cksum="`cksum < 'patch-2.4.13'`"
if ! test "1307573558 3031474" = "$Cksum" ; then
echo 'patch-2.4.13: original Checksum 1307573558 3031474, 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

0 new messages