summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2003-09-04 19:49:13 -0700
committerGreg Kroah-Hartman <greg@kroah.com>2003-09-04 19:49:13 -0700
commit24467ec6c2fa857c332d4bfdd2c92f2507d16a86 (patch)
treee9b561d5c7fb0b1dd7af2b4c6ec778b82002ae11
parent7c9481c3d31dab43cf053ebeab556264e608b4ae (diff)
parent863003968458edf00e2ebdad49f68040203d886d (diff)
Merge kroah.com:/home/linux/BK/bleed-2.5
into kroah.com:/home/linux/BK/gregkh-2.6
-rw-r--r--Documentation/DocBook/scsidrivers.tmpl34
-rw-r--r--Documentation/kmod.txt68
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/Makefile49
-rw-r--r--arch/arm/kernel/Makefile5
-rw-r--r--arch/arm/kernel/entry-armo.S633
-rw-r--r--arch/arm/kernel/entry-armv.S4
-rw-r--r--arch/arm/kernel/entry-common.S5
-rw-r--r--arch/arm/kernel/head.S1
-rw-r--r--arch/arm/mach-l7200/core.c1
-rw-r--r--arch/arm/mach-rpc/riscpc.c2
-rw-r--r--arch/arm/mm/Makefile12
-rw-r--r--arch/arm/mm/mm-armv.c8
-rw-r--r--arch/arm/mm/proc-arm1020.S1
-rw-r--r--arch/arm/mm/proc-arm2_3.S360
-rw-r--r--arch/arm/mm/proc-arm6_7.S1
-rw-r--r--arch/arm/mm/proc-arm720.S1
-rw-r--r--arch/arm/mm/proc-arm920.S1
-rw-r--r--arch/arm/mm/proc-arm922.S1
-rw-r--r--arch/arm/mm/proc-arm926.S1
-rw-r--r--arch/arm/mm/proc-sa110.S3
-rw-r--r--arch/arm/mm/proc-sa1100.S3
-rw-r--r--arch/arm/mm/proc-xscale.S3
-rw-r--r--arch/i386/Kconfig3
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/non-fatal.c2
-rw-r--r--arch/i386/kernel/time_hpet.c3
-rw-r--r--arch/i386/pci/pcbios.c3
-rw-r--r--arch/ppc/Kconfig13
-rw-r--r--arch/ppc/Makefile2
-rw-r--r--arch/ppc/boot/simple/Makefile7
-rw-r--r--arch/ppc/boot/simple/misc.c13
-rw-r--r--arch/ppc/configs/ebony_defconfig560
-rw-r--r--arch/ppc/configs/ocotea_defconfig574
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/cputable.c11
-rw-r--r--arch/ppc/kernel/head_44x.S1056
-rw-r--r--arch/ppc/kernel/misc.S28
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c5
-rw-r--r--arch/ppc/mm/44x_mmu.c162
-rw-r--r--arch/ppc/mm/Makefile1
-rw-r--r--arch/ppc/mm/cachemap.c5
-rw-r--r--arch/ppc/mm/init.c1
-rw-r--r--arch/ppc/mm/mmu_decl.h3
-rw-r--r--arch/ppc/mm/pgtable.c40
-rw-r--r--arch/ppc/ocp/ocp-probe.c3
-rw-r--r--arch/ppc/platforms/4xx/Kconfig57
-rw-r--r--arch/ppc/platforms/4xx/Makefile4
-rw-r--r--arch/ppc/platforms/4xx/ebony.c536
-rwxr-xr-xarch/ppc/platforms/4xx/ebony.h96
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.c31
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.h102
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.c37
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.h123
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c459
-rw-r--r--arch/ppc/platforms/4xx/ocotea.h84
-rw-r--r--arch/ppc/syslib/Makefile4
-rw-r--r--arch/ppc/syslib/ibm440gp_common.c77
-rw-r--r--arch/ppc/syslib/ibm440gp_common.h45
-rw-r--r--arch/ppc/syslib/ibm44x_common.c37
-rw-r--r--arch/sparc64/kernel/semaphore.c2
-rw-r--r--crypto/Makefile3
-rw-r--r--crypto/autoload.c37
-rw-r--r--crypto/internal.h10
-rw-r--r--crypto/tcrypt.c1
-rw-r--r--drivers/atm/lanai.c427
-rw-r--r--drivers/block/amiflop.c69
-rw-r--r--drivers/block/as-iosched.c73
-rw-r--r--drivers/block/cciss.c72
-rw-r--r--drivers/block/deadline-iosched.c73
-rw-r--r--drivers/block/elevator.c26
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/genhd.c4
-rw-r--r--drivers/block/ll_rw_blk.c42
-rw-r--r--drivers/block/noop-iosched.c19
-rw-r--r--drivers/block/scsi_ioctl.c2
-rw-r--r--drivers/block/xd.c4
-rw-r--r--drivers/bluetooth/hci_ldisc.c1
-rw-r--r--drivers/cdrom/aztcd.c1
-rw-r--r--drivers/cdrom/cdu31a.c1
-rw-r--r--drivers/cdrom/cm206.c2
-rw-r--r--drivers/cdrom/gscd.c1
-rw-r--r--drivers/cdrom/mcd.c1
-rw-r--r--drivers/cdrom/mcdx.c1
-rw-r--r--drivers/cdrom/optcd.c1
-rw-r--r--drivers/cdrom/sbpcd.c3
-rw-r--r--drivers/cdrom/sjcd.c1
-rw-r--r--drivers/cdrom/sonycd535.c1
-rw-r--r--drivers/char/agp/backend.c1
-rw-r--r--drivers/char/agp/frontend.c1
-rw-r--r--drivers/char/busmouse.c1
-rw-r--r--drivers/char/lp.c1
-rw-r--r--drivers/char/n_hdlc.c1
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/nvram.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c7
-rw-r--r--drivers/char/pty.c2
-rw-r--r--drivers/char/riscom8.c1
-rw-r--r--drivers/char/rtc.c8
-rw-r--r--drivers/char/synclink.c43
-rw-r--r--drivers/char/synclinkmp.c7
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c7
-rw-r--r--drivers/char/watchdog/wdt.c2
-rw-r--r--drivers/ide/Kconfig7
-rw-r--r--drivers/ide/ide-cd.c1
-rw-r--r--drivers/ide/ide-default.c6
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-floppy.c1
-rw-r--r--drivers/ide/ide-io.c6
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-tape.c1
-rw-r--r--drivers/ide/ide.c14
-rw-r--r--drivers/ide/pci/generic.c1
-rw-r--r--drivers/ide/pci/generic.h13
-rw-r--r--drivers/ide/pci/pdc202xx_old.c3
-rw-r--r--drivers/input/serio/i8042.c10
-rw-r--r--drivers/input/serio/serport.c1
-rw-r--r--drivers/isdn/capi/capi.c10
-rw-r--r--drivers/isdn/capi/capidrv.c30
-rw-r--r--drivers/isdn/capi/capilib.c2
-rw-r--r--drivers/isdn/capi/kcapi.c42
-rw-r--r--drivers/isdn/hardware/avm/avmcard.h4
-rw-r--r--drivers/isdn/hardware/avm/b1.c31
-rw-r--r--drivers/isdn/hardware/avm/c4.c11
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c24
-rw-r--r--drivers/isdn/hardware/eicon/platform.h2
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c2
-rw-r--r--drivers/isdn/hisax/callc.c2
-rw-r--r--drivers/isdn/hisax/diva.c10
-rw-r--r--drivers/isdn/hisax/elsa.c2
-rw-r--r--drivers/isdn/hisax/elsa_ser.c6
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c9
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c4
-rw-r--r--drivers/isdn/hisax/hfc_pci.c16
-rw-r--r--drivers/isdn/hisax/hfc_sx.c4
-rw-r--r--drivers/isdn/hisax/hisax.h2
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c6
-rw-r--r--drivers/isdn/hisax/ipacx.c1
-rw-r--r--drivers/isdn/hisax/isar.c2
-rw-r--r--drivers/isdn/hisax/isdnl1.h4
-rw-r--r--drivers/isdn/hisax/isdnl2.c19
-rw-r--r--drivers/isdn/hisax/l3_1tr6.c14
-rw-r--r--drivers/isdn/hisax/l3dss1.c56
-rw-r--r--drivers/isdn/hisax/l3ni1.c14
-rw-r--r--drivers/isdn/hisax/netjet.c2
-rw-r--r--drivers/isdn/hisax/q931.c7
-rw-r--r--drivers/isdn/hisax/sedlbauer.c4
-rw-r--r--drivers/isdn/hisax/st5481_b.c6
-rw-r--r--drivers/isdn/hisax/st5481_d.c6
-rw-r--r--drivers/isdn/i4l/isdn_audio.c25
-rw-r--r--drivers/isdn/i4l/isdn_common.c20
-rw-r--r--drivers/isdn/i4l/isdn_net_lib.c2
-rw-r--r--drivers/isdn/i4l/isdn_net_lib.h82
-rw-r--r--drivers/isdn/i4l/isdn_tty.c24
-rw-r--r--drivers/isdn/i4l/isdn_ttyfax.c2
-rw-r--r--drivers/isdn/icn/icn.c152
-rw-r--r--drivers/isdn/sc/card.h1
-rw-r--r--drivers/isdn/sc/command.c5
-rw-r--r--drivers/isdn/sc/init.c21
-rw-r--r--drivers/isdn/sc/message.c11
-rw-r--r--drivers/isdn/sc/shmem.c27
-rw-r--r--drivers/isdn/sc/timer.c24
-rw-r--r--drivers/macintosh/via-pmu.c4
-rw-r--r--drivers/media/video/bttv-driver.c1
-rw-r--r--drivers/message/fusion/mptscsih.c7
-rw-r--r--drivers/net/3c509.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c2
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/Makefile.lib1
-rw-r--r--drivers/net/Space.c326
-rw-r--r--drivers/net/acenic.c10
-rwxr-xr-xdrivers/net/amd8111e.c2
-rw-r--r--drivers/net/appletalk/cops.c132
-rw-r--r--drivers/net/appletalk/ltpc.c251
-rw-r--r--drivers/net/b44.c2
-rw-r--r--drivers/net/bmac.c2
-rw-r--r--drivers/net/dgrs.c4
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/eepro100.c2
-rw-r--r--drivers/net/epic100.c2
-rw-r--r--drivers/net/ethertap.c124
-rw-r--r--drivers/net/fealnx.c2
-rw-r--r--drivers/net/hamachi.c2
-rw-r--r--drivers/net/hamradio/6pack.c1
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/irda/irtty-sir.c1
-rw-r--r--drivers/net/lasi_82596.c2
-rw-r--r--drivers/net/loopback.c72
-rw-r--r--drivers/net/lp486e.c2
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/pcnet32.c47
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/ppp_synctty.c1
-rw-r--r--drivers/net/r8169.c4
-rw-r--r--drivers/net/rcpci45.c2
-rw-r--r--drivers/net/sb1000.c4
-rw-r--r--drivers/net/sis190.c15
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/slip.c1
-rw-r--r--drivers/net/smc-mca.c33
-rw-r--r--drivers/net/starfire.c2
-rw-r--r--drivers/net/sundance.c2
-rw-r--r--drivers/net/sungem.c33
-rw-r--r--drivers/net/sunhme.c4
-rw-r--r--drivers/net/sunqe.c2
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/net/tlan.c4
-rw-r--r--drivers/net/tulip/de4x5.c842
-rw-r--r--drivers/net/tun.c1
-rw-r--r--drivers/net/typhoon.c2
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/wan/Kconfig4
-rw-r--r--drivers/net/wan/cosa.c30
-rw-r--r--drivers/net/wan/dlci.c129
-rw-r--r--drivers/net/wan/sbni.c57
-rw-r--r--drivers/net/wan/sdla.c196
-rw-r--r--drivers/net/wireless/airo.c7
-rw-r--r--drivers/net/wireless/hermes.h14
-rw-r--r--drivers/net/yellowfin.c2
-rw-r--r--drivers/scsi/53c700.c2
-rw-r--r--drivers/scsi/AM53C974.c8
-rw-r--r--drivers/scsi/Kconfig107
-rw-r--r--drivers/scsi/Makefile3
-rw-r--r--drivers/scsi/NCR5380.c2
-rw-r--r--drivers/scsi/advansys.c12
-rw-r--r--drivers/scsi/arm/acornscsi.c6
-rw-r--r--drivers/scsi/arm/fas216.c4
-rw-r--r--drivers/scsi/cpqfcTSinit.c2
-rw-r--r--drivers/scsi/cpqfcTSworker.c2
-rw-r--r--drivers/scsi/dc395x.c1157
-rw-r--r--drivers/scsi/gdth.c12
-rw-r--r--drivers/scsi/gdth_proc.c4
-rw-r--r--drivers/scsi/ide-scsi.c1
-rw-r--r--drivers/scsi/imm.c1
-rw-r--r--drivers/scsi/imm.h1
-rw-r--r--drivers/scsi/ips.c10
-rw-r--r--drivers/scsi/ncr53c8xx.c13
-rw-r--r--drivers/scsi/osst.c2
-rw-r--r--drivers/scsi/pcmcia/Kconfig2
-rw-r--r--drivers/scsi/qla1280.c14
-rw-r--r--drivers/scsi/scsi.c23
-rw-r--r--drivers/scsi/scsi_devinfo.c8
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/scsi/scsi_ioctl.c28
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsi_logging.h40
-rw-r--r--drivers/scsi/scsi_priv.h26
-rw-r--r--drivers/scsi/scsi_proc.c106
-rw-r--r--drivers/scsi/scsi_scan.c18
-rw-r--r--drivers/scsi/scsi_sysctl.c53
-rw-r--r--drivers/scsi/sd.c41
-rw-r--r--drivers/scsi/sg.c38
-rw-r--r--drivers/scsi/sr.c4
-rw-r--r--drivers/scsi/sr_ioctl.c2
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--drivers/scsi/sym53c8xx.c13
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_conf.h5
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_defs.h4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_fw.c4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c451
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h34
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c47
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_misc.h19
-rw-r--r--drivers/scsi/sym53c8xx_defs.h15
-rw-r--r--drivers/serial/8250_acpi.c3
-rw-r--r--drivers/usb/input/hiddev.c2
-rw-r--r--fs/bio.c11
-rw-r--r--fs/cifs/CHANGES11
-rw-r--r--fs/cifs/cifssmb.c4
-rw-r--r--fs/cifs/dir.c20
-rw-r--r--fs/cifs/file.c35
-rw-r--r--fs/cifs/inode.c24
-rw-r--r--fs/cifs/link.c7
-rw-r--r--fs/cifs/misc.c4
-rw-r--r--fs/proc/proc_misc.c57
-rw-r--r--include/asm-alpha/semaphore.h8
-rw-r--r--include/asm-arm/assembler.h79
-rw-r--r--include/asm-arm/atomic.h2
-rw-r--r--include/asm-arm/cacheflush.h273
-rw-r--r--include/asm-arm/cpu-multi26.h47
-rw-r--r--include/asm-arm/domain.h (renamed from include/asm-arm/proc-armv/domain.h)2
-rw-r--r--include/asm-arm/elf.h27
-rw-r--r--include/asm-arm/locks.h (renamed from include/asm-arm/proc-armv/locks.h)2
-rw-r--r--include/asm-arm/memory.h4
-rw-r--r--include/asm-arm/page.h35
-rw-r--r--include/asm-arm/param.h3
-rw-r--r--include/asm-arm/pgalloc.h103
-rw-r--r--include/asm-arm/pgtable.h207
-rw-r--r--include/asm-arm/proc-armo/assembler.h106
-rw-r--r--include/asm-arm/proc-armo/cache.h28
-rw-r--r--include/asm-arm/proc-armo/elf.h15
-rw-r--r--include/asm-arm/proc-armo/locks.h161
-rw-r--r--include/asm-arm/proc-armo/page.h40
-rw-r--r--include/asm-arm/proc-armo/pgalloc.h44
-rw-r--r--include/asm-arm/proc-armo/pgtable.h106
-rw-r--r--include/asm-arm/proc-armo/processor.h63
-rw-r--r--include/asm-arm/proc-armo/ptrace.h98
-rw-r--r--include/asm-arm/proc-armo/shmparam.h19
-rw-r--r--include/asm-arm/proc-armo/system.h128
-rw-r--r--include/asm-arm/proc-armo/tlbflush.h63
-rw-r--r--include/asm-arm/proc-armo/uaccess.h138
-rw-r--r--include/asm-arm/proc-armv/assembler.h74
-rw-r--r--include/asm-arm/proc-armv/cache.h278
-rw-r--r--include/asm-arm/proc-armv/elf.h30
-rw-r--r--include/asm-arm/proc-armv/page.h37
-rw-r--r--include/asm-arm/proc-armv/pgalloc.h110
-rw-r--r--include/asm-arm/proc-armv/pgtable.h217
-rw-r--r--include/asm-arm/proc-armv/processor.h51
-rw-r--r--include/asm-arm/proc-armv/ptrace.h143
-rw-r--r--include/asm-arm/proc-armv/shmparam.h20
-rw-r--r--include/asm-arm/proc-armv/system.h215
-rw-r--r--include/asm-arm/proc-armv/tlbflush.h410
-rw-r--r--include/asm-arm/proc-armv/uaccess.h189
-rw-r--r--include/asm-arm/proc-fns.h5
-rw-r--r--include/asm-arm/processor.h26
-rw-r--r--include/asm-arm/ptrace.h116
-rw-r--r--include/asm-arm/semaphore.h6
-rw-r--r--include/asm-arm/shmparam.h2
-rw-r--r--include/asm-arm/system.h229
-rw-r--r--include/asm-arm/thread_info.h26
-rw-r--r--include/asm-arm/tlbflush.h395
-rw-r--r--include/asm-arm/uaccess.h211
-rw-r--r--include/asm-arm26/semaphore.h4
-rw-r--r--include/asm-cris/semaphore.h2
-rw-r--r--include/asm-h8300/semaphore.h2
-rw-r--r--include/asm-i386/hpet.h5
-rw-r--r--include/asm-i386/termios.h1
-rw-r--r--include/asm-ia64/semaphore.h2
-rw-r--r--include/asm-m68k/semaphore.h4
-rw-r--r--include/asm-m68knommu/semaphore.h4
-rw-r--r--include/asm-mips/semaphore.h2
-rw-r--r--include/asm-parisc/semaphore.h4
-rw-r--r--include/asm-ppc/ibm44x.h435
-rw-r--r--include/asm-ppc/ibm4xx.h18
-rw-r--r--include/asm-ppc/io.h13
-rw-r--r--include/asm-ppc/irq.h8
-rw-r--r--include/asm-ppc/mmu.h62
-rw-r--r--include/asm-ppc/page.h28
-rw-r--r--include/asm-ppc/pgalloc.h7
-rw-r--r--include/asm-ppc/pgtable.h96
-rw-r--r--include/asm-ppc/ppc_asm.h6
-rw-r--r--include/asm-ppc/processor.h159
-rw-r--r--include/asm-ppc/serial.h2
-rw-r--r--include/asm-ppc/tlbflush.h12
-rw-r--r--include/asm-s390/semaphore.h2
-rw-r--r--include/asm-sh/semaphore.h1
-rw-r--r--include/asm-sparc/semaphore.h2
-rw-r--r--include/asm-sparc/termios.h1
-rw-r--r--include/asm-sparc64/termios.h1
-rw-r--r--include/asm-v850/semaphore.h2
-rw-r--r--include/asm-x86_64/semaphore.h2
-rw-r--r--include/linux/blkdev.h11
-rw-r--r--include/linux/device.h5
-rw-r--r--include/linux/elevator.h16
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/genhd.h2
-rw-r--r--include/linux/hiddev.h2
-rw-r--r--include/linux/ide.h1
-rw-r--r--include/linux/if_frad.h4
-rw-r--r--include/linux/initrd.h2
-rw-r--r--include/linux/isdn.h9
-rw-r--r--include/linux/isdn/capilli.h2
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/kmod.h2
-rw-r--r--include/linux/miscdevice.h5
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--include/linux/page-flags.h2
-rw-r--r--include/linux/rtc.h1
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/sctp.h9
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/sysctl.h8
-rw-r--r--include/linux/tty_ldisc.h3
-rw-r--r--include/linux/usb.h2
-rw-r--r--include/linux/vcache.h26
-rw-r--r--include/net/profile.h312
-rw-r--r--include/net/sctp/sctp.h23
-rw-r--r--include/net/sctp/sm.h12
-rw-r--r--include/net/sctp/structs.h171
-rw-r--r--include/net/sctp/user.h8
-rw-r--r--include/scsi/scsi_device.h2
-rw-r--r--include/scsi/scsi_request.h2
-rw-r--r--init/Kconfig2
-rw-r--r--kernel/configs.c133
-rw-r--r--kernel/futex.c427
-rw-r--r--kernel/sysctl.c1
-rw-r--r--mm/Makefile2
-rw-r--r--mm/fremap.c31
-rw-r--r--mm/memory.c2
-rw-r--r--mm/mremap.c2
-rw-r--r--mm/page_alloc.c4
-rw-r--r--mm/rmap.c3
-rw-r--r--mm/slab.c6
-rw-r--r--mm/vcache.c90
-rw-r--r--net/Kconfig1
-rw-r--r--net/README26
-rw-r--r--net/appletalk/ddp.c5
-rw-r--r--net/atm/addr.c29
-rw-r--r--net/atm/br2684.c137
-rw-r--r--net/atm/common.c33
-rw-r--r--net/atm/common.h13
-rw-r--r--net/atm/pppoatm.c7
-rw-r--r--net/atm/proc.c7
-rw-r--r--net/atm/pvc.c2
-rw-r--r--net/atm/resources.c28
-rw-r--r--net/atm/resources.h14
-rw-r--r--net/atm/svc.c2
-rw-r--r--net/ax25/af_ax25.c3
-rw-r--r--net/bluetooth/l2cap.c1
-rw-r--r--net/bluetooth/rfcomm/core.c2
-rw-r--r--net/bluetooth/rfcomm/sock.c1
-rw-r--r--net/bluetooth/sco.c1
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/core/Makefile1
-rw-r--r--net/core/dev.c82
-rw-r--r--net/core/dv.c1
-rw-r--r--net/core/link_watch.c1
-rw-r--r--net/core/netfilter.c4
-rw-r--r--net/core/profile.c294
-rw-r--r--net/core/rtnetlink.c3
-rw-r--r--net/decnet/dn_dev.c1
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/icmp.c18
-rw-r--r--net/ipv4/ipmr.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c1
-rw-r--r--net/ipv4/udp.c75
-rw-r--r--net/ipv6/addrconf.c1
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/ah6.c1
-rw-r--r--net/ipx/af_ipx.c5
-rw-r--r--net/lapb/lapb_iface.c3
-rw-r--r--net/llc/af_llc.c5
-rw-r--r--net/llc/llc_main.c2
-rw-r--r--net/netlink/af_netlink.c141
-rw-r--r--net/rxrpc/sysctl.c1
-rw-r--r--net/sctp/associola.c23
-rw-r--r--net/sctp/bind_addr.c40
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/ipv6.c29
-rw-r--r--net/sctp/primitive.c14
-rw-r--r--net/sctp/protocol.c27
-rw-r--r--net/sctp/sm_make_chunk.c179
-rw-r--r--net/sctp/sm_statefuns.c3
-rw-r--r--net/sctp/socket.c481
-rw-r--r--net/sctp/sysctl.c4
-rw-r--r--net/socket.c4
-rw-r--r--net/sunrpc/stats.c1
-rw-r--r--net/unix/af_unix.c139
-rw-r--r--security/selinux/Kconfig5
-rw-r--r--security/selinux/hooks.c14
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--sound/oss/Kconfig8
462 files changed, 11106 insertions, 9816 deletions
diff --git a/Documentation/DocBook/scsidrivers.tmpl b/Documentation/DocBook/scsidrivers.tmpl
index 1dbafa7c2bd9..81e1561caf14 100644
--- a/Documentation/DocBook/scsidrivers.tmpl
+++ b/Documentation/DocBook/scsidrivers.tmpl
@@ -16,20 +16,40 @@
</affiliation>
</author>
</authorgroup>
- <pubdate>2002-04-27</pubdate>
+ <pubdate>2003-08-11</pubdate>
<copyright>
<year>2002</year>
+ <year>2003</year>
<holder>Douglas Gilbert</holder>
</copyright>
+
<legalnotice>
<para>
- Permission is granted to copy, distribute and/or modify this
- document under the terms of the GNU Free Documentation License,
- Version 1.1 or any later version published by the Free Software
- Foundation; with no Invariant Sections, with no Front-Cover Texts,
- and with no Back-Cover Texts. A copy of the license is included
- in the section entitled "GNU Free Documentation License".
+ This documentation 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.
+ </para>
+
+ <para>
+ 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.
+ </para>
+
+ <para>
+ 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
+ </para>
+
+ <para>
+ For more details see the file COPYING in the source
+ distribution of Linux.
</para>
</legalnotice>
diff --git a/Documentation/kmod.txt b/Documentation/kmod.txt
deleted file mode 100644
index be1a9a5183ee..000000000000
--- a/Documentation/kmod.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Kmod: The Kernel Module Loader
-Kirk Petersen
-
-Kmod is a simple replacement for kerneld. It consists of a
-request_module() replacement and a kernel thread called kmod. When the
-kernel requests a module, the kmod wakes up and execve()s modprobe,
-passing it the name that was requested.
-
-If you have the /proc filesystem mounted, you can set the path of
-modprobe (where the kernel looks for it) by doing:
-
- echo "/sbin/modprobe" > /proc/sys/kernel/modprobe
-
-To periodically unload unused modules, put something like the following
-in root's crontab entry:
-
- 0-59/5 * * * * /sbin/rmmod -a
-
-Kmod only loads modules. Kerneld could do more (although
-nothing in the standard kernel used its other features). If you
-require features such as request_route, we suggest that you take
-a similar approach. A simple request_route function could be called,
-and a kroute kernel thread could be sent off to do the work. But
-we should probably keep this to a minimum.
-
-Kerneld also had a mechanism for storing device driver settings. This
-can easily be done with modprobe. When a module is unloaded, modprobe
-could look at a per-driver-configurable location (/proc/sys/drivers/blah)
-for device driver settings and save them to a file. When a module
-is loaded, simply cat that file back to that location in the proc
-filesystem. Or perhaps a script could be a setting in /etc/modules.conf.
-There are many user-land methods that will work (I prefer using /proc,
-myself).
-
-If kerneld worked, why replace it?
-
-- kerneld used SysV IPC, which can now be made into a module. Besides,
- SysV IPC is ugly and should therefore be avoided (well, certainly for
- kernel level stuff)
-
-- both kmod and kerneld end up doing the same thing (calling modprobe),
- so why not skip the middle man?
-
-- removing kerneld related stuff from ipc/msg.c made it 40% smaller
-
-- kmod reports errors through the normal kernel mechanisms, which avoids
- the chicken and egg problem of kerneld and modular Unix domain sockets
-
-
-Keith Owens <kaos@ocs.com.au> December 1999
-
-The combination of kmod and modprobe can loop, especially if modprobe uses a
-system call that requires a module. If modules.dep does not exist and modprobe
-was started with the -s option (kmod does this), modprobe tries to syslog() a
-message. syslog() needs Unix sockets, if Unix sockets are modular then kmod
-runs "modprobe -s net-pf-1". This runs a second copy of modprobe which
-complains that modules.dep does not exist, tries to use syslog() and starts yet
-another copy of modprobe. This is not the only possible kmod/modprobe loop,
-just the most common.
-
-To detect loops caused by "modprobe needs a service which is in a module", kmod
-limits the number of concurrent kmod issued modprobes. See MAX_KMOD_CONCURRENT
-in kernel/kmod.c. When this limit is exceeded, the kernel issues message "kmod:
-runaway modprobe loop assumed and stopped".
-
-Note for users building a heavily modularised system. It is a good idea to
-create modules.dep after installing the modules and before booting a kernel for
-the first time. "depmod -ae m.n.p" where m.n.p is the new kernel version.
diff --git a/MAINTAINERS b/MAINTAINERS
index 76557f42ec2e..d9d91b3b4eca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1088,7 +1088,7 @@ S: Maintained
KERNEL JANITORS
P: Several
-L: kernel-janitor-discuss@lists.sf.net
+L: kernel-janitors@osdl.org
W: http://www.kerneljanitors.org/
W: http://sf.net/projects/kernel-janitor/
W: http://developer.osdl.org/rddunlap/kj-patches/
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7ae52271f680..c2181d7de0a7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -30,12 +30,6 @@ endif
check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
comma = ,
-# Select CPU dependent flags. Note that order of declaration is important;
-# the options further down the list override previous items.
-#
-apcs-$(CONFIG_CPU_32) :=-mapcs-32
-apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3
-
# This selects which instruction set is used.
# Note that GCC does not numerically define an architecture version
# macro, but instead defines a whole series of macros which makes
@@ -55,37 +49,21 @@ tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
tune-$(CONFIG_CPU_XSCALE) :=$(call check_gcc,-mtune=xscale,-mtune=strongarm110)
-# Force -mno-fpu to be passed to the assembler. Some versions of gcc don't
-# do this with -msoft-float
-CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
-CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
-AFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu
+CFLAGS_BOOT :=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
+CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
+AFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu
#Default value
DATAADDR := .
-ifeq ($(CONFIG_CPU_26),y)
-PROCESSOR := armo
-head-y := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o
-LDFLAGS_BLOB += --oformat elf26-littlearm
- ifeq ($(CONFIG_ROM_KERNEL),y)
- DATAADDR := 0x02080000
- textaddr-y := 0x03800000
- else
- textaddr-y := 0x02080000
- endif
-endif
-
-ifeq ($(CONFIG_CPU_32),y)
PROCESSOR := armv
head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o
- ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
- LDFLAGS_BLOB += --oformat elf32-bigarm
- else
- LDFLAGS_BLOB += --oformat elf32-littlearm
- endif
-textaddr-y := 0xC0008000
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+ LDFLAGS_BLOB += --oformat elf32-bigarm
+else
+ LDFLAGS_BLOB += --oformat elf32-littlearm
endif
+textaddr-y := 0xC0008000
machine-$(CONFIG_ARCH_ARCA5K) := arc
machine-$(CONFIG_ARCH_RPC) := rpc
@@ -160,16 +138,10 @@ include/asm-arm/.arch: $(wildcard include/config/arch/*.h)
@ln -sf arch-$(INCDIR) include/asm-arm/arch
@touch $@
-include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h)
- @echo ' Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink'
- @rm -f include/asm-arm/proc
- @ln -sf proc-$(PROCESSOR) include/asm-arm/proc
- @touch $@
-
prepare: maketools
.PHONY: maketools FORCE
-maketools: include/asm-arm/.arch include/asm-arm/.proc \
+maketools: include/asm-arm/.arch \
include/asm-arm/constants.h include/linux/version.h FORCE
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
@@ -185,7 +157,6 @@ zinstall install: vmlinux
MRPROPER_FILES += \
include/asm-arm/arch include/asm-arm/.arch \
- include/asm-arm/proc include/asm-arm/.proc \
include/asm-arm/constants.h* \
include/asm-arm/mach-types.h
@@ -217,7 +188,7 @@ zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
)
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
- include/asm-arm/.arch include/asm-arm/.proc \
+ include/asm-arm/.arch \
include/config/MARKER
include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 53c7a6c717d8..1cf609a45cbb 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -2,13 +2,11 @@
# Makefile for the linux kernel.
#
-ENTRY_OBJ = entry-$(PROCESSOR).o
-
AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
# Object file lists.
-obj-y := arch.o compat.o dma.o $(ENTRY_OBJ) entry-common.o irq.o \
+obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
@@ -34,6 +32,5 @@ extra-y := $(head-y) init_task.o vmlinux.lds.s
# Spell out some dependencies that `make dep' doesn't spot
$(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h
-$(obj)/entry-armo.o: $(obj)/entry-header.S include/asm-arm/constants.h
$(obj)/entry-common.o: $(obj)/entry-header.S include/asm-arm/constants.h \
$(obj)/calls.S
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
deleted file mode 100644
index f081ad9af786..000000000000
--- a/arch/arm/kernel/entry-armo.S
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * linux/arch/arm/kernel/entry-armo.S
- *
- * Copyright (C) 1995,1996,1997,1998 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Low-level vector interface routines
- *
- * Design issues:
- * - We have several modes that each vector can be called from,
- * each with its own set of registers. On entry to any vector,
- * we *must* save the registers used in *that* mode.
- *
- * - This code must be as fast as possible.
- *
- * There are a few restrictions on the vectors:
- * - the SWI vector cannot be called from *any* non-user mode
- *
- * - the FP emulator is *never* called from *any* non-user mode undefined
- * instruction.
- *
- * Ok, so this file may be a mess, but its as efficient as possible while
- * adhering to the above criteria.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include "entry-header.S"
-
- .text
-
-#ifdef IOC_BASE
-/* IOC / IOMD based hardware */
- .equ ioc_base_high, IOC_BASE & 0xff000000
- .equ ioc_base_low, IOC_BASE & 0x00ff0000
- .macro disable_fiq
- mov r12, #ioc_base_high
- .if ioc_base_low
- orr r12, r12, #ioc_base_low
- .endif
- strb r12, [r12, #0x38] @ Disable FIQ register
- .endm
-
- .macro get_irqnr_and_base, irqnr, base
- mov r4, #ioc_base_high @ point at IOC
- .if ioc_base_low
- orr r4, r4, #ioc_base_low
- .endif
- ldrb \irqnr, [r4, #0x24] @ get high priority first
- adr \base, irq_prio_h
- teq \irqnr, #0
- ldreqb \irqnr, [r4, #0x14] @ get low priority
- adreq \base, irq_prio_l
- .endm
-
-/*
- * Interrupt table (incorporates priority)
- */
- .macro irq_prio_table
-irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .endm
-#else
-#error Unknown architecture
-#endif
-
-/*=============================================================================
- * For entry-common.S
- */
-
-#if 0
-/*
- * Uncomment these if you wish to get more debugging into about data aborts.
- */
-#define FAULT_CODE_LDRSTRPOST 0x80
-#define FAULT_CODE_LDRSTRPRE 0x40
-#define FAULT_CODE_LDRSTRREG 0x20
-#define FAULT_CODE_LDMSTM 0x10
-#define FAULT_CODE_LDCSTC 0x08
-#endif
-#define FAULT_CODE_PREFETCH 0x04
-#define FAULT_CODE_WRITE 0x02
-#define FAULT_CODE_FORCECOW 0x01
-
-#define SVC_SAVE_ALL \
- str sp, [sp, #-16]! ;\
- str lr, [sp, #8] ;\
- str lr, [sp, #4] ;\
- stmfd sp!, {r0 - r12} ;\
- mov r0, #-1 ;\
- str r0, [sp, #S_OLD_R0] ;\
- zero_fp
-
-#define SVC_IRQ_SAVE_ALL \
- str sp, [sp, #-16]! ;\
- str lr, [sp, #4] ;\
- ldr lr, .LCirq ;\
- ldr lr, [lr] ;\
- str lr, [sp, #8] ;\
- stmfd sp!, {r0 - r12} ;\
- mov r0, #-1 ;\
- str r0, [sp, #S_OLD_R0] ;\
- zero_fp
-
-#define SVC_RESTORE_ALL \
- ldmfd sp, {r0 - pc}^
-
-/*=============================================================================
- * Undefined FIQs
- *-----------------------------------------------------------------------------
- */
-_unexp_fiq: ldr sp, .LCfiq
- mov r12, #IOC_BASE
- strb r12, [r12, #0x38] @ Disable FIQ register
- teqp pc, #0x0c000003
- mov r0, r0
- stmfd sp!, {r0 - r3, ip, lr}
- adr r0, Lfiqmsg
- bl printk
- ldmfd sp!, {r0 - r3, ip, lr}
- teqp pc, #0x0c000001
- mov r0, r0
- movs pc, lr
-
-Lfiqmsg: .ascii "*** Unexpected FIQ\n\0"
- .align
-
-.LCfiq: .word __temp_fiq
-.LCirq: .word __temp_irq
-
-/*=============================================================================
- * Undefined instruction handler
- *-----------------------------------------------------------------------------
- * Handles floating point instructions
- */
-vector_undefinstr:
- tst lr,#3
- bne __und_svc
- save_user_regs
- zero_fp
- teqp pc, #PSR_I_BIT | MODE_SVC
-.Lbug_undef:
- ldr r4, .LC2
- ldr pc, [r4] @ Call FP module USR entry point
-
- .globl fpundefinstr
-fpundefinstr: @ Called by FP module on undefined instr
- mov r0, lr
- mov r1, sp
- teqp pc, #MODE_SVC
- bl do_undefinstr
- b ret_from_exception @ Normal FP exit
-
-__und_svc: SVC_SAVE_ALL @ Non-user mode
- mask_pc r0, lr
- and r2, lr, #3
- sub r0, r0, #4
- mov r1, sp
- bl do_undefinstr
- SVC_RESTORE_ALL
-
-#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
- /* The FPE is always present */
- .equ fpe_not_present, 0
-#else
-/* We get here if an undefined instruction happens and the floating
- * point emulator is not present. If the offending instruction was
- * a WFS, we just perform a normal return as if we had emulated the
- * operation. This is a hack to allow some basic userland binaries
- * to run so that the emulator module proper can be loaded. --philb
- */
-fpe_not_present:
- adr r10, wfs_mask_data
- ldmia r10, {r4, r5, r6, r7, r8}
- ldr r10, [sp, #S_PC] @ Load PC
- sub r10, r10, #4
- mask_pc r10, r10
- ldrt r10, [r10] @ get instruction
- and r5, r10, r5
- teq r5, r4 @ Is it WFS?
- beq ret_from_exception
- and r5, r10, r8
- teq r5, r6 @ Is it LDF/STF on sp or fp?
- teqne r5, r7
- bne fpundefinstr
- tst r10, #0x00200000 @ Does it have WB
- beq ret_from_exception
- and r4, r10, #255 @ get offset
- and r6, r10, #0x000f0000
- tst r10, #0x00800000 @ +/-
- ldr r5, [sp, r6, lsr #14] @ Load reg
- rsbeq r4, r4, #0
- add r5, r5, r4, lsl #2
- str r5, [sp, r6, lsr #14] @ Save reg
- b ret_from_exception
-
-wfs_mask_data: .word 0x0e200110 @ WFS/RFS
- .word 0x0fef0fff
- .word 0x0d0d0100 @ LDF [sp]/STF [sp]
- .word 0x0d0b0100 @ LDF [fp]/STF [fp]
- .word 0x0f0f0f00
-#endif
-
-.LC2: .word fp_enter
-
-/*=============================================================================
- * Prefetch abort handler
- *-----------------------------------------------------------------------------
- */
-
-vector_prefetch:
- sub lr, lr, #4
- tst lr, #3
- bne __pabt_invalid
- save_user_regs
- teqp pc, #0x00000003 @ NOT a problem - doesn't change mode
- mask_pc r0, lr @ Address of abort
- mov r1, sp @ Tasks registers
- bl do_PrefetchAbort
- teq r0, #0 @ If non-zero, we believe this abort..
- bne ret_from_exception
-#ifdef DEBUG_UNDEF
- adr r0, t
- bl printk
-#endif
- ldr lr, [sp,#S_PC] @ program to test this on. I think its
- b .Lbug_undef @ broken at the moment though!)
-
-__pabt_invalid: SVC_SAVE_ALL
- mov r0, sp @ Prefetch aborts are definitely *not*
- mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant
- and r2, lr, #3 @ recover from this problem.
- b bad_mode
-
-#ifdef DEBUG_UNDEF
-t: .ascii "*** undef ***\r\n\0"
- .align
-#endif
-
-/*=============================================================================
- * Address exception handler
- *-----------------------------------------------------------------------------
- * These aren't too critical.
- * (they're not supposed to happen).
- * In order to debug the reason for address exceptions in non-user modes,
- * we have to obtain all the registers so that we can see what's going on.
- */
-
-vector_addrexcptn:
- sub lr, lr, #8
- tst lr, #3
- bne Laddrexcptn_not_user
- save_user_regs
- teq pc, #0x00000003
- mask_pc r0, lr @ Point to instruction
- mov r1, sp @ Point to registers
- mov r2, #0x400
- mov lr, pc
- bl do_excpt
- b ret_from_exception
-
-Laddrexcptn_not_user:
- SVC_SAVE_ALL
- and r2, lr, #3
- teq r2, #3
- bne Laddrexcptn_illegal_mode
- teqp pc, #0x00000003 @ NOT a problem - doesn't change mode
- mask_pc r0, lr
- mov r1, sp
- orr r2, r2, #0x400
- bl do_excpt
- ldmia sp, {r0 - lr} @ I cant remember the reason I changed this...
- add sp, sp, #15*4
- movs pc, lr
-
-Laddrexcptn_illegal_mode:
- mov r0, sp
- str lr, [sp, #-4]!
- orr r1, r2, #0x0c000000
- teqp r1, #0 @ change into mode (wont be user mode)
- mov r0, r0
- mov r1, r8 @ Any register from r8 - r14 can be banked
- mov r2, r9
- mov r3, r10
- mov r4, r11
- mov r5, r12
- mov r6, r13
- mov r7, r14
- teqp pc, #0x04000003 @ back to svc
- mov r0, r0
- stmfd sp!, {r1-r7}
- ldmia r0, {r0-r7}
- stmfd sp!, {r0-r7}
- mov r0, sp
- mov r1, #BAD_ADDREXCPTN
- b bad_mode
-
-/*=============================================================================
- * Interrupt (IRQ) handler
- *-----------------------------------------------------------------------------
- * Note: if in user mode, then *no* kernel routine is running, so do not have
- * to save svc lr
- * (r13 points to irq temp save area)
- */
-
-vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case...
- sub lr, lr, #4
- str lr, [r13]
- tst lr, #3
- bne __irq_svc
- teqp pc, #0x08000003
- mov r0, r0
- ldr lr, .LCirq
- ldr lr, [lr]
- save_user_regs
-
-1: get_irqnr_and_base r6, r5
- teq r6, #0
- ldrneb r0, [r5, r6] @ get IRQ number
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- adr lr, 1b
- orr lr, lr, #0x08000003 @ Force SVC
- bne asm_do_IRQ
-
- mov why, #0
- get_current_task r5
- b ret_to_user
-
- irq_prio_table
-
-__irq_svc: teqp pc, #0x08000003
- mov r0, r0
- SVC_IRQ_SAVE_ALL
- and r2, lr, #3
- teq r2, #3
- bne __irq_invalid
-1: get_irqnr_and_base r6, r5
- teq r6, #0
- ldrneb r0, [r5, r6] @ get IRQ number
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- adr lr, 1b
- orr lr, lr, #0x08000003 @ Force SVC
- bne asm_do_IRQ @ Returns to 1b
- SVC_RESTORE_ALL
-
-__irq_invalid: mov r0, sp
- mov r1, #BAD_IRQ
- b bad_mode
-
-/*=============================================================================
- * Data abort handler code
- *-----------------------------------------------------------------------------
- *
- * This handles both exceptions from user and SVC modes, computes the address
- * range of the problem, and does any correction that is required. It then
- * calls the kernel data abort routine.
- *
- * This is where I wish that the ARM would tell you which address aborted.
- */
-
-vector_data: sub lr, lr, #8 @ Correct lr
- tst lr, #3
- bne Ldata_not_user
- save_user_regs
- teqp pc, #0x00000003 @ NOT a problem - doesn't change mode
- mask_pc r0, lr
- bl Ldata_do
- b ret_from_exception
-
-Ldata_not_user:
- SVC_SAVE_ALL
- and r2, lr, #3
- teq r2, #3
- bne Ldata_illegal_mode
- tst lr, #0x08000000
- teqeqp pc, #0x00000003 @ NOT a problem - doesn't change mode
- mask_pc r0, lr
- bl Ldata_do
- SVC_RESTORE_ALL
-
-Ldata_illegal_mode:
- mov r0, sp
- mov r1, #BAD_DATA
- b bad_mode
-
-Ldata_do: mov r3, sp
- ldr r4, [r0] @ Get instruction
- mov r2, #0
- tst r4, #1 << 20 @ Check to see if it is a write instruction
- orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
- mov r1, r4, lsr #22 @ Now branch to the relevant processing routine
- and r1, r1, #15 << 2
- add pc, pc, r1
- movs pc, lr
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_ldrstr_post @ ldr rd, [rn], #m
- b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal
- b Ldata_ldrstr_post @ ldr rd, [rn], rm
- b Ldata_ldrstr_regindex @ ldr rd, [rn, rm]
- b Ldata_ldmstm @ ldm*a rn, <rlist>
- b Ldata_ldmstm @ ldm*b rn, <rlist>
- b Ldata_unknown
- b Ldata_unknown
- b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
- b Ldata_ldcstc_pre @ ldc rd, [rn, #m]
- b Ldata_unknown
-Ldata_unknown: @ Part of jumptable
- mov r0, r1
- mov r1, r4
- mov r2, r3
- b baddataabort
-
-Ldata_ldrstr_post:
- mov r0, r4, lsr #14 @ Get Rn
- and r0, r0, #15 << 2 @ Mask out reg.
- teq r0, #15 << 2
- ldr r0, [r3, r0] @ Get register
- biceq r0, r0, #PCMASK
- mov r1, r0
-#ifdef FAULT_CODE_LDRSTRPOST
- orr r2, r2, #FAULT_CODE_LDRSTRPOST
-#endif
- b do_DataAbort
-
-Ldata_ldrstr_numindex:
- mov r0, r4, lsr #14 @ Get Rn
- and r0, r0, #15 << 2 @ Mask out reg.
- teq r0, #15 << 2
- ldr r0, [r3, r0] @ Get register
- mov r1, r4, lsl #20
- biceq r0, r0, #PCMASK
- tst r4, #1 << 23
- addne r0, r0, r1, lsr #20
- subeq r0, r0, r1, lsr #20
- mov r1, r0
-#ifdef FAULT_CODE_LDRSTRPRE
- orr r2, r2, #FAULT_CODE_LDRSTRPRE
-#endif
- b do_DataAbort
-
-Ldata_ldrstr_regindex:
- mov r0, r4, lsr #14 @ Get Rn
- and r0, r0, #15 << 2 @ Mask out reg.
- teq r0, #15 << 2
- ldr r0, [r3, r0] @ Get register
- and r7, r4, #15
- biceq r0, r0, #PCMASK
- teq r7, #15 @ Check for PC
- ldr r7, [r3, r7, lsl #2] @ Get Rm
- and r8, r4, #0x60 @ Get shift types
- biceq r7, r7, #PCMASK
- mov r9, r4, lsr #7 @ Get shift amount
- and r9, r9, #31
- teq r8, #0
- moveq r7, r7, lsl r9
- teq r8, #0x20 @ LSR shift
- moveq r7, r7, lsr r9
- teq r8, #0x40 @ ASR shift
- moveq r7, r7, asr r9
- teq r8, #0x60 @ ROR shift
- moveq r7, r7, ror r9
- tst r4, #1 << 23
- addne r0, r0, r7
- subeq r0, r0, r7 @ Apply correction
- mov r1, r0
-#ifdef FAULT_CODE_LDRSTRREG
- orr r2, r2, #FAULT_CODE_LDRSTRREG
-#endif
- b do_DataAbort
-
-Ldata_ldmstm:
- mov r7, #0x11
- orr r7, r7, r7, lsl #8
- and r0, r4, r7
- and r1, r4, r7, lsl #1
- add r0, r0, r1, lsr #1
- and r1, r4, r7, lsl #2
- add r0, r0, r1, lsr #2
- and r1, r4, r7, lsl #3
- add r0, r0, r1, lsr #3
- add r0, r0, r0, lsr #8
- add r0, r0, r0, lsr #4
- and r7, r0, #15 @ r7 = no. of registers to transfer.
- mov r5, r4, lsr #14 @ Get Rn
- and r5, r5, #15 << 2
- ldr r0, [r3, r5] @ Get reg
- eor r6, r4, r4, lsl #2
- tst r6, #1 << 23 @ Check inc/dec ^ writeback
- rsbeq r7, r7, #0
- add r7, r0, r7, lsl #2 @ Do correction (signed)
- subne r1, r7, #1
- subeq r1, r0, #1
- moveq r0, r7
- tst r4, #1 << 21 @ Check writeback
- strne r7, [r3, r5]
- eor r6, r4, r4, lsl #1
- tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec
- addeq r0, r0, #4
- addeq r1, r1, #4
- teq r5, #15*4 @ CHECK FOR PC
- biceq r1, r1, #PCMASK
- biceq r0, r0, #PCMASK
-#ifdef FAULT_CODE_LDMSTM
- orr r2, r2, #FAULT_CODE_LDMSTM
-#endif
- b do_DataAbort
-
-Ldata_ldcstc_pre:
- mov r0, r4, lsr #14 @ Get Rn
- and r0, r0, #15 << 2 @ Mask out reg.
- teq r0, #15 << 2
- ldr r0, [r3, r0] @ Get register
- mov r1, r4, lsl #24 @ Get offset
- biceq r0, r0, #PCMASK
- tst r4, #1 << 23
- addne r0, r0, r1, lsr #24
- subeq r0, r0, r1, lsr #24
- mov r1, r0
-#ifdef FAULT_CODE_LDCSTC
- orr r2, r2, #FAULT_CODE_LDCSTC
-#endif
- b do_DataAbort
-
-
-/*
- * This is the return code to user mode for abort handlers
- */
-ENTRY(ret_from_exception)
- get_current_task tsk
- mov why, #0
- b ret_to_user
-
- .data
-ENTRY(fp_enter)
- .word fpe_not_present
- .text
-/*
- * Register switch for older 26-bit only ARMs
- */
-ENTRY(__switch_to)
- stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously
-
-/*
- *=============================================================================
- * Low-level interface code
- *-----------------------------------------------------------------------------
- * Trap initialisation
- *-----------------------------------------------------------------------------
- *
- * Note - FIQ code has changed. The default is a couple of words in 0x1c, 0x20
- * that call _unexp_fiq. Nowever, we now copy the FIQ routine to 0x1c (removes
- * some excess cycles).
- *
- * What we need to put into 0-0x1c are branches to branch to the kernel.
- */
-
- __INIT
-
-.Ljump_addresses:
- swi SYS_ERROR0
- .word vector_undefinstr - 12
- .word vector_swi - 16
- .word vector_prefetch - 20
- .word vector_data - 24
- .word vector_addrexcptn - 28
- .word vector_IRQ - 32
- .word _unexp_fiq - 36
- b . + 8
-/*
- * initialise the trap system
- */
-ENTRY(__trap_init)
- stmfd sp!, {r4 - r7, lr}
- adr r1, .Ljump_addresses
- ldmia r1, {r1 - r7, ip, lr}
- orr r2, lr, r2, lsr #2
- orr r3, lr, r3, lsr #2
- orr r4, lr, r4, lsr #2
- orr r5, lr, r5, lsr #2
- orr r6, lr, r6, lsr #2
- orr r7, lr, r7, lsr #2
- orr ip, lr, ip, lsr #2
- mov r0, #0
- stmia r0, {r1 - r7, ip}
- ldmfd sp!, {r4 - r7, pc}^
-
- .bss
-__temp_irq: .space 4 @ saved lr_irq
-__temp_fiq: .space 128
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index dfb295004ea1..0a5c2ea51b99 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -15,10 +15,12 @@
*/
#include <linux/config.h>
#include <linux/init.h>
-#include "entry-header.S"
+
#include <asm/thread_info.h>
#include <asm/glue.h>
+#include <asm/ptrace.h>
+#include "entry-header.S"
#ifdef IOC_BASE
/* IOC / IOMD based hardware */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 11cc623c3726..dc43ce1eaebd 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -8,8 +8,11 @@
* published by the Free Software Foundation.
*/
#include <linux/config.h>
-#include "entry-header.S"
+
#include <asm/thread_info.h>
+#include <asm/ptrace.h>
+
+#include "entry-header.S"
/*
* We rely on the fact that R0 is at the bottom of the stack (due to
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 04a32ea49695..4b233763aa0c 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -16,6 +16,7 @@
#include <asm/assembler.h>
#include <asm/mach-types.h>
#include <asm/procinfo.h>
+#include <asm/ptrace.h>
#include <asm/mach/arch.h>
/*
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 419e6ce52fe2..2570c1f0943f 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -11,7 +11,6 @@
#include <asm/hardware.h>
#include <asm/page.h>
-#include <asm/proc/domain.h>
#include <asm/mach/map.h>
#include <asm/arch/hardware.h>
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index 8c1538aaacd0..e705c3cc5b8f 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -21,7 +21,7 @@
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/page.h>
-#include <asm/proc/domain.h>
+#include <asm/domain.h>
#include <asm/setup.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 747343d21eb7..321b0242e523 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -4,21 +4,13 @@
# Object file lists.
-obj-y := init.o extable.o fault-common.o
-obj-m :=
-obj-n :=
-obj- :=
-ifeq ($(CONFIG_CPU_32),y)
-obj-y += consistent.o fault-armv.o ioremap.o mm-armv.o
+obj-y := consistent.o extable.o fault-armv.o fault-common.o \
+ init.o ioremap.o mm-armv.o
obj-$(CONFIG_MODULES) += proc-syms.o
-endif
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
obj-$(CONFIG_DISCONTIGMEM) += discontig.o
-# Select the processor-specific files
-p-$(CONFIG_CPU_26) += proc-arm2_3.o
-
# ARMv3
p-$(CONFIG_CPU_ARM610) += proc-arm6_7.o tlb-v3.o cache-v3.o copypage-v3.o
p-$(CONFIG_CPU_ARM710) += proc-arm6_7.o tlb-v3.o cache-v3.o copypage-v3.o
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index dd12fb4d8b0a..fe4dacb950e7 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -34,8 +34,8 @@ struct cachepolicy {
};
static struct cachepolicy cache_policies[] __initdata = {
- { "uncached", CR1_W|CR1_C, PMD_SECT_UNCACHED },
- { "buffered", CR1_C, PMD_SECT_BUFFERED },
+ { "uncached", CR_W|CR_C, PMD_SECT_UNCACHED },
+ { "buffered", CR_C, PMD_SECT_BUFFERED },
{ "writethrough", 0, PMD_SECT_WT },
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
{ "writeback", 0, PMD_SECT_WB },
@@ -102,8 +102,8 @@ __early_param("ecc=", early_ecc);
static int __init noalign_setup(char *__unused)
{
- cr_alignment &= ~CR1_A;
- cr_no_alignment &= ~CR1_A;
+ cr_alignment &= ~CR_A;
+ cr_no_alignment &= ~CR_A;
set_cr(cr_alignment);
return 1;
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 31bca78f8768..1712b9682de9 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -30,6 +30,7 @@
#include <asm/assembler.h>
#include <asm/constants.h>
#include <asm/procinfo.h>
+#include <asm/ptrace.h>
#include <asm/hardware.h>
/*
diff --git a/arch/arm/mm/proc-arm2_3.S b/arch/arm/mm/proc-arm2_3.S
deleted file mode 100644
index 860a95fb21f3..000000000000
--- a/arch/arm/mm/proc-arm2_3.S
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * linux/arch/arm/mm/proc-arm2,3.S
- *
- * Copyright (C) 1997-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * MMU functions for ARM2,3
- *
- * These are the low level assembler for performing cache
- * and memory functions on ARM2, ARM250 and ARM3 processors.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/assembler.h>
-#include <asm/constants.h>
-#include <asm/procinfo.h>
-
-/*
- * MEMC workhorse code. It's both a horse which things it's a pig.
- */
-/*
- * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
- * Params : pgd Page tables/MEMC mapping
- * : phys_pte physical address, or PTE
- * : addr virtual address
- */
-ENTRY(cpu_memc_update_entry)
- tst r1, #PAGE_PRESENT @ is the page present
- orreq r1, r1, #PAGE_OLD | PAGE_CLEAN
- moveq r2, #0x01f00000
- mov r3, r1, lsr #13 @ convert to physical page nr
- and r3, r3, #0x3fc
- adr ip, memc_phys_table_32
- ldr r3, [ip, r3]
- tst r1, #PAGE_OLD | PAGE_NOT_USER
- biceq r3, r3, #0x200
- tsteq r1, #PAGE_READONLY | PAGE_CLEAN
- biceq r3, r3, #0x300
- mov r2, r2, lsr #15 @ virtual -> nr
- orr r3, r3, r2, lsl #15
- and r2, r2, #0x300
- orr r3, r3, r2, lsl #2
- and r2, r3, #255
- sub r0, r0, #256 * 4
- str r3, [r0, r2, lsl #2]
- strb r3, [r3]
- movs pc, lr
-/*
- * Params : r0 = preserved
- * : r1 = memc table base (preserved)
- * : r2 = page table entry
- * : r3 = preserved
- * : r4 = unused
- * : r5 = memc physical address translation table
- * : ip = virtual address (preserved)
- */
-update_pte:
- mov r4, r2, lsr #13
- and r4, r4, #0x3fc
- ldr r4, [r5, r4] @ covert to MEMC page
-
- tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read
- biceq r4, r4, #0x200
- tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
- biceq r4, r4, #0x300
-
- orr r4, r4, ip
- and r2, ip, #0x01800000
- orr r4, r4, r2, lsr #13
-
- and r2, r4, #255
- str r4, [r1, r2, lsl #2]
- movs pc, lr
-
-/*
- * Params : r0 = preserved
- * : r1 = memc table base (preserved)
- * : r2 = page table base
- * : r3 = preserved
- * : r4 = unused
- * : r5 = memc physical address translation table
- * : ip = virtual address (updated)
- */
-update_pte_table:
- stmfd sp!, {r0, lr}
- bic r0, r2, #3
-1: ldr r2, [r0], #4 @ get entry
- tst r2, #PAGE_PRESENT @ page present
- blne update_pte @ process pte
- add ip, ip, #32768 @ increment virt addr
- ldr r2, [r0], #4 @ get entry
- tst r2, #PAGE_PRESENT @ page present
- blne update_pte @ process pte
- add ip, ip, #32768 @ increment virt addr
- ldr r2, [r0], #4 @ get entry
- tst r2, #PAGE_PRESENT @ page present
- blne update_pte @ process pte
- add ip, ip, #32768 @ increment virt addr
- ldr r2, [r0], #4 @ get entry
- tst r2, #PAGE_PRESENT @ page present
- blne update_pte @ process pte
- add ip, ip, #32768 @ increment virt addr
- tst ip, #32768 * 31 @ finished?
- bne 1b
- ldmfd sp!, {r0, pc}^
-
-/*
- * Function: cpu_memc_update_all(pgd_t *pgd)
- * Params : pgd Page tables/MEMC mapping
- * Notes : this is optimised for 32k pages
- */
-ENTRY(cpu_memc_update_all)
- stmfd sp!, {r4, r5, lr}
- bl clear_tables
- sub r1, r0, #256 * 4 @ start of MEMC tables
- adr r5, memc_phys_table_32 @ Convert to logical page number
- mov ip, #0 @ virtual address
-1: ldmia r0!, {r2, r3}
- tst r2, #PAGE_PRESENT
- addeq ip, ip, #1048576
- blne update_pte_table
- mov r2, r3
- tst r2, #PAGE_PRESENT
- addeq ip, ip, #1048576
- blne update_pte_table
- teq ip, #32 * 1048576
- bne 1b
- ldmfd sp!, {r4, r5, pc}^
-
-/*
- * Build the table to map from physical page number to memc page number
- */
- .type memc_phys_table_32, #object
-memc_phys_table_32:
- .irp b7, 0x00, 0x80
- .irp b6, 0x00, 0x02
- .irp b5, 0x00, 0x04
- .irp b4, 0x00, 0x01
-
- .irp b3, 0x00, 0x40
- .irp b2, 0x00, 0x20
- .irp b1, 0x00, 0x10
- .irp b0, 0x00, 0x08
- .long 0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
- .endr
- .endr
- .endr
- .endr
-
- .endr
- .endr
- .endr
- .endr
- .size memc_phys_table_32, . - memc_phys_table_32
-
-/*
- * helper for cpu_memc_update_all, this clears out all
- * mappings, setting them close to the top of memory,
- * and inaccessible (0x01f00000).
- * Params : r0 = page table pointer
- */
-clear_tables: ldr r1, _arm3_switch_mm - 4
- ldr r2, [r1]
- sub r1, r0, #256 * 4 @ start of MEMC tables
- add r2, r1, r2, lsl #2 @ end of tables
- mov r3, #0x03f00000 @ Default mapping (null mapping)
- orr r3, r3, #0x00000f00
- orr r4, r3, #1
- orr r5, r3, #2
- orr ip, r3, #3
-1: stmia r1!, {r3, r4, r5, ip}
- add r3, r3, #4
- add r4, r4, #4
- add r5, r5, #4
- add ip, ip, #4
- stmia r1!, {r3, r4, r5, ip}
- add r3, r3, #4
- add r4, r4, #4
- add r5, r5, #4
- add ip, ip, #4
- teq r1, r2
- bne 1b
- mov pc, lr
-
-/*
- * Function: *_switch_mm(pgd_t *pgd)
- * Params : pgd New page tables/MEMC mapping
- * Purpose : update MEMC hardware with new mapping
- */
- .word page_nr
-_arm3_switch_mm:
- mcr p15, 0, r1, c1, c0, 0 @ flush cache
-_arm2_switch_mm:
- stmfd sp!, {lr}
- ldr r1, _arm3_switch_mm - 4
- ldr r2, [r1]
- sub r0, r0, #256 * 4 @ start of MEMC tables
- add r1, r0, r2, lsl #2 @ end of tables
-1: ldmia r0!, {r2, r3, ip, lr}
- strb r2, [r2]
- strb r3, [r3]
- strb ip, [ip]
- strb lr, [lr]
- ldmia r0!, {r2, r3, ip, lr}
- strb r2, [r2]
- strb r3, [r3]
- strb ip, [ip]
- strb lr, [lr]
- teq r0, r1
- bne 1b
- ldmfd sp!, {pc}^
-
-/*
- * Function: *_proc_init (void)
- * Purpose : Initialise the cache control registers
- */
-_arm3_proc_init:
- mov r0, #0x001f0000
- orr r0, r0, #0x0000ff00
- orr r0, r0, #0x000000ff
- mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable
- mcr p15, 0, r0, c4, c0 @ ARM3 Updateable
- mov r0, #0
- mcr p15, 0, r0, c5, c0 @ ARM3 Disruptive
- mcr p15, 0, r0, c1, c0 @ ARM3 Flush
- mov r0, #3
- mcr p15, 0, r0, c2, c0 @ ARM3 Control
-_arm2_proc_init:
- movs pc, lr
-
-/*
- * Function: *_proc_fin (void)
- * Purpose : Finalise processor (disable caches)
- */
-_arm3_proc_fin: mov r0, #2
- mcr p15, 0, r0, c2, c0
-_arm2_proc_fin: orrs pc, lr, #PSR_I_BIT|PSR_F_BIT
-
-/*
- * Function: *_xchg_1 (int new, volatile void *ptr)
- * Params : new New value to store at...
- * : ptr pointer to byte-wide location
- * Purpose : Performs an exchange operation
- * Returns : Original byte data at 'ptr'
- */
-_arm2_xchg_1: mov r2, pc
- orr r2, r2, #PSR_I_BIT
- teqp r2, #0
- ldrb r2, [r1]
- strb r0, [r1]
- mov r0, r2
- movs pc, lr
-
-_arm3_xchg_1: swpb r0, r0, [r1]
- movs pc, lr
-
-/*
- * Function: *_xchg_4 (int new, volatile void *ptr)
- * Params : new New value to store at...
- * : ptr pointer to word-wide location
- * Purpose : Performs an exchange operation
- * Returns : Original word data at 'ptr'
- */
-_arm2_xchg_4: mov r2, pc
- orr r2, r2, #PSR_I_BIT
- teqp r2, #0
- ldr r2, [r1]
- str r0, [r1]
- mov r0, r2
- movs pc, lr
-
-_arm3_xchg_4: swp r0, r0, [r1]
- movs pc, lr
-
-cpu_arm2_name:
- .asciz "ARM 2"
-cpu_arm250_name:
- .asciz "ARM 250"
-cpu_arm3_name:
- .asciz "ARM 3"
-
- __INIT
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .globl arm2_processor_functions
-arm2_processor_functions:
- .word _arm2_proc_init
- .word _arm2_proc_fin
- .word _arm2_switch_mm
- .word _arm2_xchg_1
- .word _arm2_xchg_4
-
- .globl arm250_processor_functions
-arm250_processor_functions:
- .word _arm2_proc_init
- .word _arm2_proc_fin
- .word _arm2_switch_mm
- .word _arm3_xchg_1
- .word _arm3_xchg_4
-
- .globl arm3_processor_functions
-arm3_processor_functions:
- .word _arm3_proc_init
- .word _arm3_proc_fin
- .word _arm3_switch_mm
- .word _arm3_xchg_1
- .word _arm3_xchg_4
-
-arm2_arch_name: .asciz "armv1"
-arm3_arch_name: .asciz "armv2"
-arm2_elf_name: .asciz "v1"
-arm3_elf_name: .asciz "v2"
- .align
-
- .section ".proc.info", #alloc, #execinstr
-
- .long 0x41560200
- .long 0xfffffff0
- .long 0
- mov pc, lr
- .long arm2_arch_name
- .long arm2_elf_name
- .long 0
- .long cpu_arm2_name
- .long arm2_processor_functions
- .long 0
- .long 0
- .long 0
-
- .long 0x41560250
- .long 0xfffffff0
- .long 0
- mov pc, lr
- .long arm3_arch_name
- .long arm3_elf_name
- .long 0
- .long cpu_arm250_name
- .long arm250_processor_functions
- .long 0
- .long 0
- .long 0
-
- .long 0x41560300
- .long 0xfffffff0
- .long 0
- mov pc, lr
- .long arm3_arch_name
- .long arm3_elf_name
- .long 0
- .long cpu_arm3_name
- .long arm3_processor_functions
- .long 0
- .long 0
- .long 0
-
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 30997a078052..4a679dc0e965 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -15,6 +15,7 @@
#include <asm/assembler.h>
#include <asm/constants.h>
#include <asm/procinfo.h>
+#include <asm/ptrace.h>
ENTRY(cpu_arm6_dcache_clean_area)
ENTRY(cpu_arm7_dcache_clean_area)
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index fa6f22d1c169..b334b5eadd55 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -35,6 +35,7 @@
#include <asm/assembler.h>
#include <asm/constants.h>
#include <asm/procinfo.h>
+#include <asm/ptrace.h>
#include <asm/hardware.h>
/*
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 678cb15acfda..b9100180f670 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -31,6 +31,7 @@
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
#include "proc-macros.S"
/*
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index c547a7b0b4f1..3e9c98425751 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -32,6 +32,7 @@
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
#include "proc-macros.S"
/*
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index a445460fca44..7b5dee0f540b 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -31,6 +31,7 @@
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
#include "proc-macros.S"
/*
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 50ae23f081e1..73d4fc433b38 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -18,7 +18,8 @@
#include <asm/constants.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
-#include <asm/proc/pgtable.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
/*
* the cache line size of the I and D cache
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 28c8425afaf7..7feb2663658a 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -23,7 +23,8 @@
#include <asm/constants.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
-#include <asm/proc/pgtable.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
/*
* the cache line size of the I and D cache
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 1c8027a6ea2c..44c41098c85b 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -25,8 +25,9 @@
#include <asm/assembler.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
-#include <asm/proc/pgtable.h>
+#include <asm/pgtable.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
#include "proc-macros.S"
/*
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index fa32ee149abc..928c42588f10 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -419,6 +419,9 @@ config HPET_TIMER
Choose N to continue using the legacy 8254 timer.
+config HPET_EMULATE_RTC
+ def_bool HPET_TIMER && RTC=y
+
config SMP
bool "Symmetric multi-processing support"
---help---
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 94ff91ebe2e0..6651e1941eaa 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -2080,4 +2080,4 @@ MODULE_PARM_DESC(idle_period,
MODULE_PARM(smp, "i");
MODULE_PARM_DESC(smp,
"Set this to enable APM use on an SMP platform. Use with caution on older systems");
-
+MODULE_ALIAS_MISCDEV(APM_MINOR_DEV);
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c
index f657dc87ccbc..099f9d2efe13 100644
--- a/arch/i386/kernel/cpu/mcheck/non-fatal.c
+++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c
@@ -1,5 +1,5 @@
/*
- * P4 specific Machine Check Exception Reporting
+ * Non Fatal Machine Check Exception Reporting
*/
#include <linux/init.h>
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 7c0d0e7407a0..3ea82f9731f4 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -187,7 +187,6 @@ __setup("hpet=", hpet_setup);
#include <linux/rtc.h>
extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-extern void get_rtc_time(struct rtc_time *rtc_tm);
#define DEFAULT_RTC_INT_FREQ 64
#define RTC_NUM_INTS 1
@@ -354,7 +353,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
hpet_rtc_timer_reinit();
if (UIE_on | AIE_on) {
- get_rtc_time(&curr_time);
+ rtc_get_rtc_time(&curr_time);
}
if (UIE_on) {
if (curr_time.tm_sec != prev_update_sec) {
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
index 9e8ff72c542f..8db66f34640f 100644
--- a/arch/i386/pci/pcbios.c
+++ b/arch/i386/pci/pcbios.c
@@ -430,7 +430,8 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret),
- "=b" (map)
+ "=b" (map),
+ "+m" (opt)
: "0" (PCIBIOS_GET_ROUTING_OPTIONS),
"1" (0),
"D" ((long) &opt),
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 22d91c235e70..7e5aa4fa045c 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -66,6 +66,9 @@ config 6xx
config 40x
bool "40x"
+config 44x
+ bool "44x"
+
config POWER3
bool "POWER3"
@@ -74,6 +77,11 @@ config 8xx
endchoice
+config PTE_64BIT
+ bool
+ depends on 44x
+ default y
+
source arch/ppc/platforms/4xx/Kconfig
config 8260
@@ -766,8 +774,8 @@ config MCA
RS/6000 machines are currently not supported by Linux.
config PCI
- bool "PCI support" if 4xx || 8260
- default y if !4xx && !8260 && !8xx && !APUS
+ bool "PCI support" if 40x || 8260
+ default y if !40x && !8260 && !8xx && !APUS
default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS
default PCI_QSPAN if !4xx && !8260 && 8xx
help
@@ -1143,6 +1151,7 @@ config BOOT_LOAD_BOOL
config BOOT_LOAD
hex "Link/load address for booting" if BOOT_LOAD_BOOL
default "0x00400000" if 40x || 8xx || 8260
+ default "0x01000000" if 44x
default "0x00800000"
config PIN_TLB
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 5db110d1c75b..52d06170c376 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -29,7 +29,7 @@ CFLAGS += $(cflags-y)
head-y := arch/ppc/kernel/head.o
head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o
head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
-head-$(CONFIG_440) := arch/ppc/kernel/head_44x.o
+head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index 28231b85cfdb..3ead7056e3a7 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -48,11 +48,16 @@ zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE
zimage-$(CONFIG_EBONY) := zImage-TREE
zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE
- extra.o-$(CONFIG_EBONY) := direct.o
end-$(CONFIG_EBONY) := ebony
entrypoint-$(CONFIG_EBONY) := 0x01000000
tftpimage-$(CONFIG_EBONY) := /tftpboot/zImage.$(end-y)
+ zimage-$(CONFIG_OCOTEA) := zImage-TREE
+zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE
+ end-$(CONFIG_OCOTEA) := ocotea
+ entrypoint-$(CONFIG_OCOTEA) := 0x01000000
+ tftpimage-$(CONFIG_OCOTEA) := /tftpboot/zImage.$(end-y)
+
extra.o-$(CONFIG_EV64260) := direct.o misc-ev64260.o
tftpimage-$(CONFIG_EV64260) := /tftpboot/zImage.ev64260
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index c14e633386ea..6597200b829d 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -25,6 +25,9 @@
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/bootinfo.h>
+#ifdef CONFIG_44x
+#include <asm/ibm4xx.h>
+#endif
#include "nonstdio.h"
#include "zlib.h"
@@ -80,6 +83,16 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
serial_fixups();
com_port = serial_init(0, NULL);
+#ifdef CONFIG_44x
+ /* Reset MAL */
+ mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
+ /* Wait for reset */
+ while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
+ /* Reset EMAC */
+ *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000;
+ __asm__ __volatile__("eieio");
+#endif
+
#if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4)
/*
* Call get_mem_size(), which is memory controller dependent,
diff --git a/arch/ppc/configs/ebony_defconfig b/arch/ppc/configs/ebony_defconfig
new file mode 100644
index 000000000000..b466152a06d5
--- /dev/null
+++ b/arch/ppc/configs/ebony_defconfig
@@ -0,0 +1,560 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC32=y
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_POWER3 is not set
+# CONFIG_8xx is not set
+CONFIG_PTE_64BIT=y
+CONFIG_4xx=y
+
+#
+# IBM 4xx options
+#
+CONFIG_EBONY=y
+# CONFIG_OCOTEA is not set
+CONFIG_440GP=y
+CONFIG_440=y
+CONFIG_PIN_TLB=y
+CONFIG_BOOKE=y
+CONFIG_IBM_OCP=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+
+#
+# General setup
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on"
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Generic Driver Options
+#
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_LBD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices (depends on LLC=y)
+#
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_FAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+CONFIG_BDI_SWITCH=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+CONFIG_OCP=y
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff --git a/arch/ppc/configs/ocotea_defconfig b/arch/ppc/configs/ocotea_defconfig
new file mode 100644
index 000000000000..0f398257ef7b
--- /dev/null
+++ b/arch/ppc/configs/ocotea_defconfig
@@ -0,0 +1,574 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC32=y
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_POWER3 is not set
+# CONFIG_8xx is not set
+CONFIG_PTE_64BIT=y
+CONFIG_4xx=y
+
+#
+# IBM 4xx options
+#
+# CONFIG_EBONY is not set
+CONFIG_OCOTEA=y
+CONFIG_440GX=y
+CONFIG_440A=y
+CONFIG_PIN_TLB=y
+CONFIG_BOOKE=y
+CONFIG_IBM_OCP=y
+CONFIG_IBM_EMAC4=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+
+#
+# General setup
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on console=ttyS0,115200"
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Generic Driver Options
+#
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_OAKNET is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices (depends on LLC=y)
+#
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_FAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+CONFIG_BDI_SWITCH=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+CONFIG_OCP=y
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index a00393bbdf33..77760d6fafd7 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -12,6 +12,7 @@ endif
# Start off with 'head.o', change as needed.
extra-y := head.o
extra-$(CONFIG_40x) := head_4xx.o
+extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-y += vmlinux.lds.s
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 2d67a182b106..71c2c441a14f 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -433,7 +433,7 @@ struct cpu_spec cpu_specs[] = {
},
#endif /* CONFIG_40x */
-#ifdef CONFIG_440
+#ifdef CONFIG_44x
{ /* 440GP Rev. B */
0xf0000fff, 0x40000440, "440GP Rev. B",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
@@ -448,7 +448,14 @@ struct cpu_spec cpu_specs[] = {
32, 32,
0, /*__setup_cpu_440 */
},
-#endif /* CONFIG_440 */
+ { /* 440GX Rev. A */
+ 0xf0000fff, 0x50000850, "440GX Rev. A",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 32, 32,
+ 0, /*__setup_cpu_440 */
+ },
+#endif /* CONFIG_44x */
#if !CLASSIC_PPC
{ /* default match */
0x00000000, 0x00000000, "(generic PPC)",
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
new file mode 100644
index 000000000000..125f131a3c30
--- /dev/null
+++ b/arch/ppc/kernel/head_44x.S
@@ -0,0 +1,1056 @@
+/*
+ * arch/ppc/kernel/head_44x.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software, Inc.
+ *
+ * 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 <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/ibm44x.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/offsets.h>
+
+/*
+ * Macros
+ */
+
+#define SET_IVOR(vector_number, vector_label) \
+ li r26,vector_label@l; \
+ mtspr SPRN_IVOR##vector_number,r26; \
+ sync
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/*
+ * Set up the initial MMU state
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ *
+ * We first invalidate all TLB entries but the one
+ * we are running from. We then load the KERNELBASE
+ * mappings so we can begin to use kernel addresses
+ * natively and so the interrupt vector locations are
+ * permanently pinned (necessary since Book E
+ * implementations always have translation enabled).
+ *
+ * TODO: Use the known TLB entry we are running from to
+ * determine which physical region we are located
+ * in. This can be used to determine where in RAM
+ * (on a shared CPU system) or PCI memory space
+ * (on a DRAMless system) we are located.
+ * For now, we assume a perfect world which means
+ * we are located at the base of DRAM (physical 0).
+ */
+
+/*
+ * Search TLB for entry that we are currently using.
+ * Invalidate all entries but the one we are using.
+ */
+ /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+ mfspr r3,SPRN_MMUCR /* Get MMUCR */
+ lis r4,PPC44x_MMUCR_STS@h
+ ori r4,r4,PPC44x_MMUCR_TID@l /* Create mask */
+ andc r3,r3,r4 /* Clear out TID/STS bits */
+ mfspr r4,SPRN_PID /* Get PID */
+ or r3,r3,r4 /* Set TID bits */
+ mfmsr r5 /* Get MSR */
+ andi. r5,r5,MSR_IS@l /* TS=1? */
+ beq wmmucr /* If not, leave STS=0 */
+ oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */
+wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */
+ sync
+
+ bl invstr /* Find our address */
+invstr: mflr r5 /* Make it accessible */
+ tlbsx r23,0,r5 /* Find entry we are in */
+ li r4,0 /* Start at TLB entry 0 */
+ li r3,0 /* Set PAGEID inval value */
+1: cmpw r23,r4 /* Is this our entry? */
+ beq skpinv /* If so, skip the inval */
+ tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
+skpinv: addi r4,r4,1 /* Increment */
+ cmpwi r4,64 /* Are we done? */
+ bne 1b /* If not, repeat */
+ isync /* If so, context change */
+
+/*
+ * Configure and load pinned entries into TLB slots 62 and 63.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+
+ /* Kernel is at the base of RAM */
+ li r4, 0 /* Load the kernel physical address */
+
+ /* Load the kernel PID = 0 */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Load the kernel TID = 0 */
+ mfspr r5,SPRN_MMUCR
+ lis r6, PPC44x_MMUCR_TID@h
+ ori r6,r6,PPC44x_MMUCR_TID@l
+ andc r5,r5,r6
+ mtspr SPRN_MMUCR,r5
+ sync
+
+ /* pageid fields */
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M))
+
+ /* xlat fields */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ /* ERPN is 0 for first 4GB page */
+
+ /* attrib fields */
+ /* Added guarded bit to protect against speculative loads/stores */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+ li r0,62 /* TLB slot 62 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ mfmsr r0
+ mtspr SRR1, r0
+ lis r0,3f@h
+ ori r0,r0,3f@l
+ mtspr SRR0,r0
+ sync
+ rfi
+
+ /* If necessary, invalidate original entry we used */
+3: cmpwi r23,62
+ beq 4f
+ li r6,0
+ tlbwe r6,r23,PPC44x_TLB_PAGEID
+ sync
+
+4: ori r3,r3,PPC44x_TLB_TS /* TS = 1 */
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ /*
+ * Add temporary UART mapping for early debug. This
+ * mapping must be identical to that used by the early
+ * bootloader code since the same asm/serial.h parameters
+ * are used for polled operation.
+ */
+ /* pageid fields */
+ lis r3,0xe000
+ ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M))
+
+ /* xlat fields */
+ lis r4,0x4000 /* RPN is 0x40000000 */
+ ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
+
+ /* attrib fields */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+
+ li r0,60 /* TLB slot 60 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ ori r3,r3,PPC44x_TLB_TS /* Translation state 1 */
+
+ li r0,61 /* TLB slot 61 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+ /* Force context change */
+ isync
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@h
+ ori r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ lis r3,MSR_KERNEL@h
+ ori r3,r3,MSR_KERNEL@l
+ mtspr SRR0,r4
+ mtspr SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+#define NORMAL_EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
+ mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG2,r1; \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ beq 1f; \
+ mfspr r1,SPRG3; /* if from user, start at top of */\
+ lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
+ addi r1,r1,THREAD_SIZE; \
+1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r1); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r10,SPRG2; \
+ mfspr r12,SRR0; \
+ stw r10,GPR1(r11); \
+ mfspr r9,SRR1; \
+ stw r10,0(r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Exception prolog for critical exceptions. This is a little different
+ * from the normal exception prolog above since a critical exception
+ * can potentially occur at any point during normal exception processing.
+ * Thus we cannot use the same SPRG registers as the normal prolog above.
+ * Instead we use a couple of words of memory at low physical addresses.
+ * This is OK since we don't support SMP on these processors.
+ */
+/* XXX but we don't have RAM mapped at 0 in space 0 -- paulus. */
+#define CRITICAL_EXCEPTION_PROLOG \
+ stw r10,crit_r10@l(0); /* save two registers to work with */\
+ stw r11,crit_r11@l(0); \
+ mfspr r10,SPRG0; \
+ stw r10,crit_sprg0@l(0); \
+ mfspr r10,SPRG1; \
+ stw r10,crit_sprg1@l(0); \
+ mfspr r10,SPRG4R; \
+ stw r10,crit_sprg4@l(0); \
+ mfspr r10,SPRG5R; \
+ stw r10,crit_sprg5@l(0); \
+ mfspr r10,SPRG6R; \
+ stw r10,crit_sprg6@l(0); \
+ mfspr r10,SPRG7R; \
+ stw r10,crit_sprg7@l(0); \
+ mfspr r10,SPRN_PID; \
+ stw r10,crit_pid@l(0); \
+ mfspr r10,SRR0; \
+ stw r10,crit_srr0@l(0); \
+ mfspr r10,SRR1; \
+ stw r10,crit_srr1@l(0); \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ lis r11,critical_stack_top@h; \
+ ori r11,r11,critical_stack_top@l; \
+ beq 1f; \
+ /* COMING FROM USER MODE */ \
+ mfspr r11,SPRG3; /* if from user, start at top of */\
+ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+ addi r11,r11,THREAD_SIZE; \
+1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r11); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
+ stw r12,_DEAR(r11); /* since they may have had stuff */\
+ mfspr r9,SPRN_ESR; /* in them at the point where the */\
+ stw r9,_ESR(r11); /* exception was taken */\
+ mfspr r12,CSRR0; \
+ stw r1,GPR1(r11); \
+ mfspr r9,CSRR1; \
+ stw r1,0(r11); \
+ tovirt(r1,r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Exception vectors.
+ */
+#define START_EXCEPTION(label) \
+ .align 5; \
+label:
+
+#define FINISH_EXCEPTION(func) \
+ bl transfer_to_handler_full; \
+ .long func; \
+ .long ret_from_except_full
+
+#define EXCEPTION(n, label, hdlr, xfer) \
+ START_EXCEPTION(label); \
+ NORMAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define CRITICAL_EXCEPTION(n, label, hdlr) \
+ START_EXCEPTION(label); \
+ CRITICAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,TRAP(r11); \
+ lis r10,msr@h; \
+ ori r10,r10,msr@l; \
+ copyee(r10, r9); \
+ bl tfer; \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+interrupt_base:
+ /* Critical Input Interrupt */
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+
+ /* Machine Check Interrupt */
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRG0, r10 /* Save some working registers */
+ mtspr SPRG1, r11
+ mtspr SPRG4W, r12
+ mtspr SPRG5W, r13
+ mtspr SPRG6W, r14
+ mfcr r11
+ mtspr SPRG7W, r11
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_ST@h
+ beq 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r11, r10, 0x8000
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR /* Set TID to 0 */
+ li r13,PPC44x_MMUCR_TID@l
+ andc r12,r12,r13
+ mtspr SPRN_MMUCR,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load MMUCR with our PID and STS=<current TS> */
+ mfspr r12,SPRN_MMUCR /* Get MMUCR */
+ lis r13,PPC44x_MMUCR_STS@h
+ ori r13,r13,PPC44x_MMUCR_TID@l /* Create mask */
+ andc r12,r12,r13 /* Clear out TID/STS bits */
+ mfspr r13,SPRN_PID /* Get PID */
+ or r12,r12,r13 /* Set TID bits */
+ mfspr r14,SPRN_SRR1 /* Get SRR1 */
+ andi. r14,r14,MSR_IS@l /* TS=1? */
+ beq 4f /* If not, leave STS=0 */
+ oris r12,r12,PPC44x_MMUCR_STS@h /* Set STS=1 */
+ mtspr SPRN_MMUCR,r12
+4:
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+
+ andi. r13, r11, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, 4(r12) /* Update Linux page table */
+
+ /* FIXME: Staticly setting some permissions */
+ li r13, 0x003f /* Set UX,UW,UR,SX,SW,SR */
+ andi. r11,r11,0xffff /* Clear MS 16 bits */
+ /* FIXME: Force attributes */
+ ori r11,r11, 0x0100 /* Set G */
+ /* FIXME: Already set in PTE */
+ rlwimi r11,r13,0,26,31 /* Insert static perms */
+
+ lis r13,0xffff
+ ori r13,r13,0x0fff /* Set U0-U3 mask */
+ and r11,r11,r13 /* Clear U0-U3 */
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx r14, 0, r10
+
+ tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRG7R
+ mtcr r11
+ mfspr r14, SPRG6R
+ mfspr r13, SPRG5R
+ mfspr r12, SPRG4R
+
+ mfspr r11, SPRG1
+ mfspr r10, SPRG0
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRG7R
+ mtcr r11
+ mfspr r14, SPRG6R
+ mfspr r13, SPRG5R
+ mfspr r12, SPRG4R
+
+ mfspr r11, SPRG1
+ mfspr r10, SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ START_EXCEPTION(InstructionStorage)
+ NORMAL_EXCEPTION_PROLOG
+ mr r4,r12 /* Pass SRR0 as arg2 */
+ li r5,0 /* Pass zero as arg3 */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x0400, do_page_fault)
+
+ /* External Input Interrupt */
+ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+ /* Alignment Interrupt */
+ START_EXCEPTION(Alignment)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
+ stw r4,_DEAR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x0600, AlignmentException)
+
+ /* Program Interrupt */
+ START_EXCEPTION(Program)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_ESR /* Grab the ESR and save it */
+ stw r4,_ESR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x700, ProgramCheckException)
+
+ /* Floating Point Unavailable Interrupt */
+ EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+ /* Auxillary Processor Unavailable Interrupt */
+ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+
+ /* Decrementer Interrupt */
+ START_EXCEPTION(Decrementer)
+ NORMAL_EXCEPTION_PROLOG
+ lis r0,TSR_DIS@h /* Setup the DEC interrupt mask */
+ mtspr SPRN_TSR,r0 /* Clear the DEC interrupt */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_LITE(0x1000, timer_interrupt)
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+
+ /* Watchdog Timer Interrupt */
+ /* TODO: Add watchdog support */
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRG0, r10 /* Save some working registers */
+ mtspr SPRG1, r11
+ mtspr SPRG4W, r12
+ mtspr SPRG5W, r13
+ mtspr SPRG6W, r14
+ mfcr r11
+ mtspr SPRG7W, r11
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r11, r10, 0x8000
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR /* Set TID to 0 */
+ li r13,PPC44x_MMUCR_TID@l
+ andc r12,r12,r13
+ mtspr SPRN_MMUCR,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ li r13,PPC44x_MMUCR_TID@l /* Create mask */
+ andc r12,r12,r13 /* Clear out TID/STS bits */
+ mfspr r13,SPRN_PID /* Get PID */
+ or r12,r12,r13
+ mtspr SPRN_MMUCR,r12
+4:
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRG7R
+ mtcr r11
+ mfspr r14, SPRG6R
+ mfspr r13, SPRG5R
+ mfspr r12, SPRG4R
+ mfspr r11, SPRG1
+ mfspr r10, SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRG0, r10 /* Save some working registers */
+ mtspr SPRG1, r11
+ mtspr SPRG4W, r12
+ mtspr SPRG5W, r13
+ mtspr SPRG6W, r14
+ mfcr r11
+ mtspr SPRG7W, r11
+ mfspr r10, SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r11, r10, 0x8000
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR /* Set TID to 0 */
+ li r13,PPC44x_MMUCR_TID@l
+ andc r12,r12,r13
+ mtspr SPRN_MMUCR,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ li r13,PPC44x_MMUCR_TID@l /* Create mask */
+ andc r12,r13,r13 /* Clear out TID/STS bits */
+ mfspr r13,SPRN_PID /* Get PID */
+ or r12,r12,r13
+ mtspr SPRN_MMUCR,r12
+
+4:
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRG7R
+ mtcr r11
+ mfspr r14, SPRG6R
+ mfspr r13, SPRG5R
+ mfspr r12, SPRG4R
+ mfspr r11, SPRG1
+ mfspr r10, SPRG0
+ b InstructionStorage
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved. This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+ /* Debug Interrupt */
+ CRITICAL_EXCEPTION(0x2000, Debug, DebugException)
+#if 0
+ START_EXCEPTION(Debug)
+ /* This first instruction was already executed by the exception
+ * handler and must be the first instruction of every exception
+ * handler.
+ */
+ mtspr SPRN_SPRG0,r10 /* Save some working registers... */
+ mtspr SPRN_SPRG1,r11
+ mtspr SPRN_SPRG4W,r12
+ mfcr r10 /* ..and the cr because we change it */
+
+ mfspr r11,SPRN_CSRR1 /* MSR at the time of fault */
+ andi. r11,r11,MSR_PR
+ bne+ 2f /* trapped from problem state */
+
+ mfspr r11,SPRN_CSRR0 /* Faulting instruction address */
+ lis r12, KERNELBASE@h
+ ori r12, r12, KERNELBASE@l
+ cmplw r11,r12
+ blt+ 2f /* addr below exception vectors */
+
+ lis r12, Debug@h
+ ori r12, r12, Debug@l
+ cmplw r11,r12
+ bgt+ 2f /* addr above TLB exception vectors */
+
+ lis r11,DBSR_IC@h /* Remove the trap status */
+ mtspr SPRN_DBSR,r11
+
+ mfspr r11,SPRN_CSRR1
+ rlwinm r11,r11,0,23,21 /* clear MSR_DE */
+ mtspr SPRN_CSRR1, r11 /* restore MSR at rcfi without DE */
+
+ mtcrf 0xff,r10 /* restore registers */
+ mfspr r12,SPRN_SPRG4R
+ mfspr r11,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG0
+
+ sync
+ rfci /* return to the exception handler */
+ b . /* prevent prefetch past rfci */
+
+2:
+ mtcrf 0xff,r10 /* restore registers */
+ mfspr r12,SPRN_SPRG4R
+ mfspr r11,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG0
+
+ CRIT_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,CRIT_EXC;
+ li r9,MSR_KERNEL
+ FINISH_EXCEPTION(DebugException)
+#endif
+
+/*
+ * Local functions
+ */
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ stw r4,_DEAR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x0300, do_page_fault)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r10 - EA of fault
+ * r11 - available to use
+ * r12 - Pointer to the 64-bit PTE
+ * r13 - available to use
+ * r14 - available to use
+ * MMUCR - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ /* Load the next available TLB index */
+ lis r13, tlb_44x_index@h
+ ori r13, r13, tlb_44x_index@l
+ lwz r14, 0(r13)
+ /* Load the TLB high watermark */
+ lis r13, tlb_44x_hwater@h
+ ori r13, r13, tlb_44x_hwater@l
+ lwz r11, 0(r13)
+
+
+ /* Increment, rollover, and store TLB index */
+ addi r14, r14, 1
+ cmpw 0, r14, r11 /* reserve entries 62-63 for kernel */
+ ble 7f
+ li r14, 0
+7:
+ /* Load the next available TLB index */
+ lis r13, tlb_44x_index@h
+ ori r13, r13, tlb_44x_index@l
+ stw r14, 0(r13)
+
+6:
+ lwz r13, 0(r12) /* Get MS word of PTE */
+ lwz r11, 4(r12) /* Get LS word of PTE */
+ rlwimi r13, r11, 0, 0 , 19 /* Insert RPN */
+ tlbwe r13, r14, PPC44x_TLB_XLAT /* Write XLAT */
+
+ /*
+ * Create PAGEID. This is the faulting address plus
+ * a set of static bits. The static bits are page
+ * size and valid. Bits 20 and 21 should be zero
+ * for a page size of 4KB.
+ */
+ li r12, 0x0210 /* Set size and valid */
+ mfspr r13, SPRN_SRR1 /* Get SRR1 */
+ andi. r13, r13, MSR_IS@l
+ beq 7f
+ ori r12, r12, PPC44x_TLB_TS@l /* Set TS=1 */
+7: rlwimi r10, r12, 0, 20, 31 /* Insert statics */
+ tlbwe r10, r14, PPC44x_TLB_PAGEID /* Write PAGEID */
+
+ /* FIXME: Staticly setting some permissions */
+ li r13, 0x002d /* Set UX,UR,SX,SR */
+ andi. r11, r11, 0xffff /* Clear MS 16 bits */
+ andi. r12, r11, 0x0002 /* _PAGE_HWWRITE? */
+ beq 8f
+ ori r13, r13, 0x0002 /* Set SW */
+ /* FIXME: Force attributes */
+8: ori r11, r11, 0x0100 /* Set G */
+ /* FIXME: Already set in PTE */
+ rlwimi r11, r13, 0, 26, 31 /* Insert static perms */
+
+ lis r13,0xffff
+ ori r13,r13,0x0fff /* Set U0-U3 mask */
+ and r11,r11,r13 /* Clear U0-U3 */
+ tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRG7R
+ mtcr r11
+ mfspr r14, SPRG6R
+ mfspr r13, SPRG5R
+ mfspr r12, SPRG4R
+ mfspr r11, SPRG1
+ mfspr r10, SPRG0
+ rfi /* Force context change */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The 44x core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The 44x core does not have an FPU.
+ */
+_GLOBAL(giveup_fpu)
+ blr
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+_GLOBAL(sdata)
+_GLOBAL(empty_zero_page)
+ .space 4096
+
+/*
+ * To support >32-bit physical addresses, we use an 8KB pgdir.
+ */
+_GLOBAL(swapper_pg_dir)
+ .space 8192
+
+/* Stack for handling critical exceptions from kernel mode */
+ .section .bss
+critical_stack_bottom:
+ .space 4096
+critical_stack_top:
+ .previous
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+_GLOBAL(cmd_line)
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
+
+/*
+ * This area is used for temporarily saving registers during the
+ * critical exception prolog.
+ */
+crit_save:
+_GLOBAL(crit_r10)
+ .space 4
+_GLOBAL(crit_r11)
+ .space 4
+_GLOBAL(crit_sprg0)
+ .space 4
+_GLOBAL(crit_sprg1)
+ .space 4
+_GLOBAL(crit_sprg4)
+ .space 4
+_GLOBAL(crit_sprg5)
+ .space 4
+_GLOBAL(crit_sprg6)
+ .space 4
+_GLOBAL(crit_sprg7)
+ .space 4
+_GLOBAL(crit_pid)
+ .space 4
+_GLOBAL(crit_srr0)
+ .space 4
+_GLOBAL(crit_srr1)
+ .space 4
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index c076529683c9..a41d10ee1614 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -405,16 +405,20 @@ _GLOBAL(_tlbia)
sync /* Flush to memory before changing mapping */
tlbia
isync /* Flush shadow TLB */
-#elif defined(CONFIG_440)
+#elif defined(CONFIG_44x)
lis r3,0
sync
1:
- tlbwe r3,r3,PPC440_TLB_PAGEID
+ tlbwe r3,r3,PPC44x_TLB_PAGEID
addi r3,r3,1
- cmpwi 0,r3,61
+ /* Load high watermark */
+ lis r4,tlb_44x_hwater@h
+ ori r4,r4,tlb_44x_hwater@l
+ lwz r5,0(r4)
+ cmpw 0,r3,r5
ble 1b
isync
-#else /* !(CONFIG_40x || CONFIG_440) */
+#else /* !(CONFIG_40x || CONFIG_44x) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,18
lwz r8,TI_CPU(r8)
@@ -465,17 +469,17 @@ _GLOBAL(_tlbie)
tlbwe r3, r3, TLB_TAG
isync
10:
-#elif defined(CONFIG_440)
+#elif defined(CONFIG_44x)
mfspr r4,SPRN_MMUCR /* Get MMUCR */
- lis r5,PPC440_MMUCR_STS@h
- ori r5,r5,PPC440_MMUCR_TID@l /* Create mask */
+ lis r5,PPC44x_MMUCR_STS@h
+ ori r5,r5,PPC44x_MMUCR_TID@l /* Create mask */
andc r4,r4,r5 /* Clear out TID/STS bits */
mfspr r5,SPRN_PID /* Get PID */
or r4,r4,r5 /* Set TID bits */
mfmsr r6 /* Get MSR */
andi. r6,r6,MSR_IS@l /* TS=1? */
beq 11f /* If not, leave STS=0 */
- oris r4,r4,PPC440_MMUCR_STS@h /* Set STS=1 */
+ oris r4,r4,PPC44x_MMUCR_STS@h /* Set STS=1 */
11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */
tlbsx. r3, 0, r3
@@ -486,10 +490,10 @@ _GLOBAL(_tlbie)
* the V bit in the TLB_PAGEID, loading this
* value will invalidate the TLB entry.
*/
- tlbwe r3, r3, PPC440_TLB_PAGEID
+ tlbwe r3, r3, PPC44x_TLB_PAGEID
isync
10:
-#else /* !(CONFIG_40x || CONFIG_440) */
+#else /* !(CONFIG_40x || CONFIG_44x) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,18
lwz r8,TI_CPU(r8)
@@ -658,9 +662,9 @@ _GLOBAL(invalidate_dcache_range)
#ifdef CONFIG_NOT_COHERENT_CACHE
/*
* 40x cores have 8K or 16K dcache and 32 byte line size.
- * 440 has a 32K dcache and 32 byte line size.
+ * 44x has a 32K dcache and 32 byte line size.
* 8xx has 1, 2, 4, 8K variants.
- * For now, cover the worst case of the 440.
+ * For now, cover the worst case of the 44x.
* Must be called with external interrupts disabled.
*/
#define CACHE_NWAYS 64
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index a70d77b33147..d7daa458535f 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -155,6 +155,9 @@ EXPORT_SYMBOL(_outsl_ns);
EXPORT_SYMBOL(iopa);
EXPORT_SYMBOL(mm_ptov);
EXPORT_SYMBOL(ioremap);
+#ifdef CONFIG_44x
+EXPORT_SYMBOL(ioremap64);
+#endif
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
@@ -353,7 +356,7 @@ EXPORT_SYMBOL(debugger_fault_handler);
EXPORT_SYMBOL(cpm_install_handler);
EXPORT_SYMBOL(cpm_free_handler);
#endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_40x)
+#if defined(CONFIG_8xx) || defined(CONFIG_4xx)
EXPORT_SYMBOL(__res);
#endif
#if defined(CONFIG_8xx)
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
new file mode 100644
index 000000000000..8c71ed6caca6
--- /dev/null
+++ b/arch/ppc/mm/44x_mmu.c
@@ -0,0 +1,162 @@
+/*
+ * Modifications by Matt Porter (mporter@mvista.com) to support
+ * PPC44x Book E processors.
+ *
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include "mmu_decl.h"
+#include "mem_pieces.h"
+
+extern char etext[], _stext[];
+extern struct mem_pieces phys_avail;
+
+/* Used by the 44x TLB replacement exception handler.
+ * Just needed it declared someplace.
+ */
+unsigned int tlb_44x_index = 0;
+unsigned int tlb_44x_hwater = 61;
+
+/*
+ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
+ */
+static void __init
+ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
+{
+ unsigned long attrib;
+
+ __asm__ __volatile__("\
+ clrrwi %2,%2,10\n\
+ ori %2,%2,%4\n\
+ clrrwi %1,%1,10\n\
+ li %0,0\n\
+ ori %0,%0,%5\n\
+ tlbwe %2,%3,%6\n\
+ tlbwe %1,%3,%7\n\
+ tlbwe %0,%3,%8"
+ :
+ : "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
+ "i" (PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)),
+ "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ "i" (PPC44x_TLB_PAGEID),
+ "i" (PPC44x_TLB_XLAT),
+ "i" (PPC44x_TLB_ATTRIB));
+}
+
+/*
+ * Configure PPC44x TLB for AS0 exception processing.
+ */
+static void __init
+ppc44x_tlb_config(void)
+{
+ unsigned int pinned_tlbs = 1;
+ int i;
+
+ /*
+ * If lowmem is not on a pin tlb entry size boundary,
+ * then reserve the last page of system memory. This
+ * eliminates the possibility of a speculative dcache
+ * fetch past the end of system memory that would
+ * result in a machine check exception.
+ */
+ if (total_lowmem | (PPC44x_PIN_SIZE - 1))
+ mem_pieces_remove(&phys_avail, total_lowmem - PAGE_SIZE, PAGE_SIZE, 1);
+
+ /* Determine number of entries necessary to cover lowmem */
+ pinned_tlbs = (unsigned int)
+ (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT);
+
+ /* Write upper watermark to save location */
+ tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
+
+ /* If necessary, set additional pinned TLBs */
+ if (pinned_tlbs > 1)
+ for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
+ unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE;
+ ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
+ }
+}
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+
+ ppc44x_tlb_config();
+}
+
+/* TODO: Add large page lowmem mapping support */
+unsigned long __init mmu_mapin_ram(void)
+{
+ unsigned long v, s, f = _PAGE_GUARDED;
+ phys_addr_t p;
+
+ v = KERNELBASE;
+ p = PPC_MEMSTART;
+
+ for (s = 0; s < total_lowmem; s += PAGE_SIZE) {
+ if ((char *) v >= _stext && (char *) v < etext)
+ f |= _PAGE_RAM_TEXT;
+ else
+ f |= _PAGE_RAM;
+ map_page(v, p, f);
+ v += PAGE_SIZE;
+ p += PAGE_SIZE;
+ }
+
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:mmu_mapin_ram done", 0x401);
+
+ return s;
+}
diff --git a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile
index 01d5f46c0764..0ed5eb8aad03 100644
--- a/arch/ppc/mm/Makefile
+++ b/arch/ppc/mm/Makefile
@@ -11,4 +11,5 @@ obj-y := fault.o init.o mem_pieces.o extable.o \
obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o
obj-$(CONFIG_40x) += 4xx_mmu.o
+obj-$(CONFIG_44x) += 44x_mmu.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o
diff --git a/arch/ppc/mm/cachemap.c b/arch/ppc/mm/cachemap.c
index b8b9efa7fa5e..e16f8f0cc47d 100644
--- a/arch/ppc/mm/cachemap.c
+++ b/arch/ppc/mm/cachemap.c
@@ -48,7 +48,7 @@
#include <asm/smp.h>
#include <asm/machdep.h>
-int map_page(unsigned long va, unsigned long pa, int flags);
+int map_page(unsigned long va, phys_addr_t pa, int flags);
/* This function will allocate the requested contiguous pages and
* map them into the kernel's vmalloc() space. This is done so we
@@ -61,7 +61,8 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
{
int order, err;
struct page *page, *free, *end;
- unsigned long pa, flags, offset;
+ phys_addr_t pa;
+ unsigned long flags, offset;
struct vm_struct *area = NULL;
unsigned long va = 0;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index e535c560fabb..2d775dad695f 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -6,6 +6,7 @@
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1996 Paul Mackerras
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
*
* Derived from "arch/i386/mm/init.c"
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
index cd7389ea8e1e..3099b7088d45 100644
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -20,9 +20,10 @@
*
*/
#include <asm/tlbflush.h>
+#include <asm/mmu.h>
extern void mapin_ram(void);
-extern int map_page(unsigned long va, unsigned long pa, int flags);
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
extern void setbat(int index, unsigned long virt, unsigned long phys,
unsigned int size, int flags);
extern void reserve_phys_mem(unsigned long start, unsigned long size);
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 3768c66520cb..de3d8224114d 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -55,11 +55,18 @@ void setbat(int index, unsigned long virt, unsigned long phys,
#define p_mapped_by_bats(x) (0UL)
#endif /* HAVE_BATS */
+#ifdef CONFIG_44x
+/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
+#define PGDIR_ORDER 1
+#else
+#define PGDIR_ORDER 0
+#endif
+
pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *ret;
- if ((ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL)
+ if ((ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER)) != NULL)
clear_page(ret);
return ret;
}
@@ -110,16 +117,33 @@ void pte_free(struct page *pte)
__free_page(pte);
}
+#ifndef CONFIG_44x
+void *
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+#else /* CONFIG_44x */
void *
-ioremap(unsigned long addr, unsigned long size)
+ioremap64(unsigned long long addr, unsigned long size)
{
return __ioremap(addr, size, _PAGE_NO_CACHE);
}
void *
-__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ phys_addr_t addr64 = fixup_bigphys_addr(addr, size);;
+
+ return ioremap64(addr64, size);
+}
+#endif /* CONFIG_44x */
+
+void *
+__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
{
- unsigned long p, v, i;
+ unsigned long v, i;
+ phys_addr_t p;
int err;
/*
@@ -144,7 +168,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
*/
if ( mem_init_done && (p < virt_to_phys(high_memory)) )
{
- printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p,
+ printk("__ioremap(): phys addr "PTE_FMT" is RAM lr %p\n", p,
__builtin_return_address(0));
return NULL;
}
@@ -195,7 +219,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
}
out:
- return (void *) (v + (addr & ~PAGE_MASK));
+ return (void *) (v + ((unsigned long)addr & ~PAGE_MASK));
}
void iounmap(void *addr)
@@ -211,7 +235,7 @@ void iounmap(void *addr)
}
int
-map_page(unsigned long va, unsigned long pa, int flags)
+map_page(unsigned long va, phys_addr_t pa, int flags)
{
pmd_t *pd;
pte_t *pg;
@@ -261,7 +285,7 @@ void __init mapin_ram(void)
* virt, phys, size must all be page-aligned.
* This should only be called before ioremap is called.
*/
-void __init io_block_mapping(unsigned long virt, unsigned long phys,
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
unsigned int size, int flags)
{
int i;
diff --git a/arch/ppc/ocp/ocp-probe.c b/arch/ppc/ocp/ocp-probe.c
index 88fd2af05b18..624ca8a00135 100644
--- a/arch/ppc/ocp/ocp-probe.c
+++ b/arch/ppc/ocp/ocp-probe.c
@@ -62,7 +62,6 @@ ocp_setup_dev(struct ocp_def *odef, unsigned int index)
(unsigned long) dev->paddr, dev->irq, dev->pm);
/* now put in global tree */
- strcpy(dev->dev.name, dev->name);
sprintf(dev->dev.bus_id, "%d", index);
dev->dev.parent = ocp_bus;
dev->dev.bus = &ocp_bus_type;
@@ -80,7 +79,7 @@ static struct device * __devinit ocp_alloc_primary_bus(void)
return NULL;
memset(b, 0, sizeof(struct device));
strcpy(b->bus_id, "ocp");
- strcpy(b->name, "Host/OCP Bridge");
+
device_register(b);
return b;
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 759a88325c4a..9cc0b4fc9528 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -1,6 +1,6 @@
config 4xx
bool
- depends on 40x
+ depends on 40x || 44x
default y
menu "IBM 4xx options"
@@ -57,6 +57,23 @@ config WALNUT
endchoice
+choice
+ prompt "Machine Type"
+ depends on 44x
+ default EBONY
+
+config EBONY
+ bool "Ebony"
+ help
+ This option enables support for the IBM PPC440GP evaluation board.
+
+config OCOTEA
+ bool "Ocotea"
+ help
+ This option enables support for the IBM PPC440GX evaluation board.
+
+endchoice
+
config EP405PC
bool "EP405PC Support"
depends on EP405
@@ -70,6 +87,26 @@ config NP405H
depends on ASH
default y
+config 440GP
+ bool
+ depends on EBONY
+ default y
+
+config 440GX
+ bool
+ depends on OCOTEA
+ default y
+
+config 440
+ bool
+ depends on 440GP
+ default y
+
+config 440A
+ bool
+ depends on 440GX
+ default y
+
# All 405-based cores up until the 405GPR and 405EP have this errata.
config IBM405_ERR77
bool
@@ -82,9 +119,25 @@ config IBM405_ERR51
depends on 40x && !405GPR
default y
+
+config PIN_TLB
+ bool
+ depends on 44x
+ default y
+
+config BOOKE
+ bool
+ depends on 44x
+ default y
+
config IBM_OCP
bool
- depends on ASH || BEECH || CEDAR || CPCI405 || EP405 || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ depends on ASH || BEECH || CEDAR || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ default y
+
+config IBM_EMAC4
+ bool
+ depends on 440GX
default y
config NP405L
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index e7233f9bd9ea..5ea683316b61 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -5,8 +5,10 @@ obj-$(CONFIG_ASH) += ash.o
obj-$(CONFIG_BEECH) += beech.o
obj-$(CONFIG_CEDAR) += cedar.o
obj-$(CONFIG_CPCI405) += cpci405.o
+obj-$(CONFIG_EBONY) += ebony.o
obj-$(CONFIG_EP405) += ep405.o
obj-$(CONFIG_OAK) += oak.o
+obj-$(CONFIG_OCOTEA) += ocotea.o
obj-$(CONFIG_REDWOOD_4) += redwood.o
obj-$(CONFIG_REDWOOD_5) += redwood5.o
obj-$(CONFIG_REDWOOD_6) += redwood6.o
@@ -21,4 +23,6 @@ obj-$(CONFIG_NP405H) += ibmnp405h.o
obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o
obj-$(CONFIG_NP4GS3) += ibmnp4gs.o
obj-$(CONFIG_405LP) += ibm405lp.o
+obj-$(CONFIG_EBONY) += ibm440gp.o
+obj-$(CONFIG_OCOTEA) += ibm440gx.o
obj-$(CONFIG_405GPR) += ibm405gpr.o
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
new file mode 100644
index 000000000000..e2577b8f7c63
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -0,0 +1,536 @@
+/*
+ * arch/ppc/platforms/ebony.c
+ *
+ * Ebony board specific routines
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+
+/*
+ * Ebony IRQ triggering/polarity settings
+ */
+static u_char ebony_IRQ_initsenses[] __initdata = {
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 0: UART 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 1: UART 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 2: IIC 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 3: IIC 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 4: PCI Inb Mess */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 5: PCI Cmd Wrt */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 6: PCI PM */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 7: PCI MSI 0 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 8: PCI MSI 1 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 9: PCI MSI 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 10: MAL TX EOB */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 11: MAL RX EOB */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 12: DMA Chan 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 13: DMA Chan 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 14: DMA Chan 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 15: DMA Chan 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 16: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 17: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 18: GPT Timer 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 19: GPT Timer 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 20: GPT Timer 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 21: GPT Timer 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 22: GPT Timer 4 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 23: Ext Int 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 24: Ext Int 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 25: Ext Int 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 26: Ext Int 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 27: Ext Int 4 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* 28: Ext Int 5 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 29: Ext Int 6 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 30: UIC1 NC Int */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 31: UIC1 Crit Int */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 32: MAL SERR */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 33: MAL TXDE */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 34: MAL RXDE */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 35: ECC Unc Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 36: ECC Corr Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 37: Ext Bus Ctrl */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 38: Ext Bus Mstr */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 39: OPB->PLB */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 40: PCI MSI 3 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 41: PCI MSI 4 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 42: PCI MSI 5 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 43: PCI MSI 6 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 44: PCI MSI 7 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 45: PCI MSI 8 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 46: PCI MSI 9 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 47: PCI MSI 10 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 48: PCI MSI 11 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 49: PLB Perf Mon */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 50: Ext Int 7 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 51: Ext Int 8 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 52: Ext Int 9 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 53: Ext Int 10 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 54: Ext Int 11 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 55: Ext Int 12 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 56: Ser ROM Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 57: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 58: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 59: PCI Async Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 60: EMAC 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 61: EMAC 0 WOL */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 62: EMAC 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 63: EMAC 1 WOL */
+};
+
+extern void abort(void);
+
+/* Global Variables */
+bd_t __res;
+
+static void __init
+ebony_calibrate_decr(void)
+{
+ unsigned int freq;
+
+ /*
+ * Determine system clock speed
+ *
+ * If we are on Rev. B silicon, then use
+ * default external system clock. If we are
+ * on Rev. C silicon then errata forces us to
+ * use the internal clock.
+ */
+ switch (PVR_REV(mfspr(PVR))) {
+ case PVR_REV(PVR_440GP_RB):
+ freq = EBONY_440GP_RB_SYSCLK;
+ break;
+ case PVR_REV(PVR_440GP_RC1):
+ default:
+ freq = EBONY_440GP_RC_SYSCLK;
+ break;
+ }
+
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+ /* Enable decrementer interrupt */
+ mtspr(SPRN_TCR, TCR_DIE);
+}
+
+static int
+ebony_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: IBM\n");
+ seq_printf(m, "machine\t\t: Ebony\n");
+
+ return 0;
+}
+
+static inline int
+ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */
+ { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */
+ { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */
+ { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */
+ };
+
+ const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define PCIX_WRITEL(value, offset) \
+ (writel(value, (u32)pcix_reg_base+offset))
+
+/*
+ * FIXME: This is only here to "make it work". This will move
+ * to a ibm_pcix.c which will contain a generic IBM PCIX bridge
+ * configuration library. -Matt
+ */
+static void __init
+ebony_setup_pcix(void)
+{
+ void *pcix_reg_base;
+
+ pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE);
+
+ /* Disable all windows */
+ PCIX_WRITEL(0, PCIX0_POM0SA);
+ PCIX_WRITEL(0, PCIX0_POM1SA);
+ PCIX_WRITEL(0, PCIX0_POM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SA);
+ PCIX_WRITEL(0, PCIX0_PIM1SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SA);
+
+ /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */
+ PCIX_WRITEL(0x00000003, PCIX0_POM0LAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
+ PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
+ PCIX_WRITEL(0x80000001, PCIX0_POM0SA);
+
+ /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+ PCIX_WRITEL(0x80000007, PCIX0_PIM0SA);
+
+ eieio();
+}
+
+static void __init
+ebony_setup_hose(void)
+{
+ struct pci_controller *hose;
+
+ /* Configure windows on the PCI-X host bridge */
+ ebony_setup_pcix();
+
+ hose = pcibios_alloc_controller();
+
+ if (!hose)
+ return;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET;
+
+ pci_init_resource(&hose->io_resource,
+ EBONY_PCI_LOWER_IO,
+ EBONY_PCI_UPPER_IO,
+ IORESOURCE_IO,
+ "PCI host bridge");
+
+ pci_init_resource(&hose->mem_resources[0],
+ EBONY_PCI_LOWER_MEM,
+ EBONY_PCI_UPPER_MEM,
+ IORESOURCE_MEM,
+ "PCI host bridge");
+
+ hose->io_space.start = EBONY_PCI_LOWER_IO;
+ hose->io_space.end = EBONY_PCI_UPPER_IO;
+ hose->mem_space.start = EBONY_PCI_LOWER_MEM;
+ hose->mem_space.end = EBONY_PCI_UPPER_MEM;
+ isa_io_base =
+ (unsigned long)ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE);
+ hose->io_base_virt = (void *)isa_io_base;
+
+ setup_indirect_pci(hose,
+ EBONY_PCI_CFGA_PLB32,
+ EBONY_PCI_CFGD_PLB32);
+ hose->set_cfg_type = 1;
+
+ hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = ebony_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+ebony_early_serial_map(void)
+{
+ struct uart_port port;
+
+ /* Setup ioremapped serial port access */
+ memset(&port, 0, sizeof(port));
+ port.membase = ioremap64(PPC440GP_UART0_ADDR, 8);
+ port.irq = 0;
+ port.uartclk = BASE_BAUD * 16;
+ port.regshift = 0;
+ port.iotype = SERIAL_IO_MEM;
+ port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ port.line = 0;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
+ port.irq = 1;
+ port.line = 1;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+}
+
+static void __init
+ebony_setup_arch(void)
+{
+ unsigned char * vpd_base;
+ struct ibm440gp_clocks clocks;
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+ /* Retrieve MAC addresses */
+ vpd_base = ioremap64(EBONY_VPD_BASE, EBONY_VPD_SIZE);
+ memcpy(__res.bi_enetaddr[0],EBONY_NA0_ADDR(vpd_base),6);
+ memcpy(__res.bi_enetaddr[1],EBONY_NA1_ADDR(vpd_base),6);
+
+ /*
+ * Determine various clocks.
+ * To be completely correct we should get SysClk
+ * from FPGA, because it can be changed by on-board switches
+ * --ebs
+ */
+ ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200);
+ __res.bi_opb_busfreq = clocks.opb;
+
+ /* Use IIC in standard (100 kHz) mode */
+ __res.bi_iic_fast[0] = __res.bi_iic_fast[1] = 0;
+
+ /* Setup TODC access */
+ TODC_INIT(TODC_TYPE_DS1743,
+ 0,
+ 0,
+ ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE),
+ 8);
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ /* Setup PCI host bridge */
+ ebony_setup_hose();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+#ifdef CONFIG_ROOT_NFS
+ ROOT_DEV = Root_NFS;
+#else
+ ROOT_DEV = Root_HDA1;
+#endif
+
+#ifdef CONFIG_VT
+ conswitchp = &dummy_con;
+#endif
+
+ ebony_early_serial_map();
+
+ ibm4xxPIC_InitSenses = ebony_IRQ_initsenses;
+ ibm4xxPIC_NumInitSenses = sizeof(ebony_IRQ_initsenses);
+
+ /* Identify the system */
+ printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n");
+}
+
+static void
+ebony_restart(char *cmd)
+{
+ local_irq_disable();
+ abort();
+}
+
+static void
+ebony_power_off(void)
+{
+ local_irq_disable();
+ for(;;);
+}
+
+static void
+ebony_halt(void)
+{
+ local_irq_disable();
+ for(;;);
+}
+
+/*
+ * Read the 440GP memory controller to get size of system memory.
+ */
+static unsigned long __init
+ebony_find_end_of_memory(void)
+{
+ u32 i, bank_config;
+ u32 mem_size = 0;
+
+ for (i=0; i<4; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR);
+ break;
+ case 1:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR);
+ break;
+ case 2:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR);
+ break;
+ case 3:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR);
+ break;
+ }
+
+ bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+
+ if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE))
+ continue;
+ switch (SDRAM_CONFIG_BANK_SIZE(bank_config))
+ {
+ case SDRAM_CONFIG_SIZE_8M:
+ mem_size += PPC44x_MEM_SIZE_8M;
+ break;
+ case SDRAM_CONFIG_SIZE_16M:
+ mem_size += PPC44x_MEM_SIZE_16M;
+ break;
+ case SDRAM_CONFIG_SIZE_32M:
+ mem_size += PPC44x_MEM_SIZE_32M;
+ break;
+ case SDRAM_CONFIG_SIZE_64M:
+ mem_size += PPC44x_MEM_SIZE_64M;
+ break;
+ case SDRAM_CONFIG_SIZE_128M:
+ mem_size += PPC44x_MEM_SIZE_128M;
+ break;
+ case SDRAM_CONFIG_SIZE_256M:
+ mem_size += PPC44x_MEM_SIZE_256M;
+ break;
+ case SDRAM_CONFIG_SIZE_512M:
+ mem_size += PPC44x_MEM_SIZE_512M;
+ break;
+ }
+ }
+ return mem_size;
+}
+
+static void __init
+ebony_init_irq(void)
+{
+ int i;
+
+ ppc4xx_pic_init();
+
+ for (i = 0; i < NR_IRQS; i++)
+ irq_desc[i].handler = ppc4xx_pic;
+}
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+ SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */
+};
+
+static void
+ebony_progress(char *s, unsigned short hex)
+{
+ volatile char c;
+ volatile unsigned long com_port;
+ u16 shift;
+
+ com_port = (unsigned long)rs_table[0].iomem_base;
+ shift = rs_table[0].iomem_reg_shift;
+
+ while ((c = *s++) != 0) {
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = c;
+
+ }
+
+ /* Send LF/CR to pretty up output */
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = '\r';
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = '\n';
+}
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6, unsigned long r7)
+{
+ parse_bootinfo((struct bi_record *) (r3 + KERNELBASE));
+
+ ppc_md.setup_arch = ebony_setup_arch;
+ ppc_md.show_cpuinfo = ebony_show_cpuinfo;
+ ppc_md.init_IRQ = ebony_init_irq;
+ ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
+
+ ppc_md.find_end_of_memory = ebony_find_end_of_memory;
+
+ ppc_md.restart = ebony_restart;
+ ppc_md.power_off = ebony_power_off;
+ ppc_md.halt = ebony_halt;
+
+ ppc_md.calibrate_decr = ebony_calibrate_decr;
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ ppc_md.progress = ebony_progress;
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef CONFIG_KGDB
+ ppc_md.early_serial_map = ebony_early_serial_map;
+#endif
+}
+
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
new file mode 100755
index 000000000000..c852552f167e
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -0,0 +1,96 @@
+/*
+ * arch/ppc/platforms/ebony.h
+ *
+ * Ebony board definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_EBONY_H__
+#define __ASM_EBONY_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ibm440gp.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0 0xE0000800
+
+/* Macros to get at Ebony VPD info */
+#define EBONY_VPD_BASE 0x00000001fffffe00ULL
+#define EBONY_VPD_SIZE 0x24
+#define EBONY_NA0_OFFSET 0x0c
+#define EBONY_NA1_OFFSET 0x18
+#define EBONY_NA0_ADDR(base) (base + EBONY_NA0_OFFSET)
+#define EBONY_NA1_ADDR(base) (base + EBONY_NA1_OFFSET)
+
+/* Default clock rates for Rev. B and Rev. C silicon */
+#define EBONY_440GP_RB_SYSCLK 33000000
+#define EBONY_440GP_RC_SYSCLK 400000000
+
+/* RTC/NVRAM location */
+#define EBONY_RTC_ADDR 0x0000000148000000ULL
+#define EBONY_RTC_SIZE 0x2000
+
+/* Flash */
+#define EBONY_FPGA_ADDR 0x0000000148300000
+#define EBONY_BOOT_SMALL_FLASH(x) (x & 0x20)
+#define EBONY_ONBRD_FLASH_EN(x) (x & 0x02)
+#define EBONY_FLASH_SEL(x) (x & 0x01)
+#define EBONY_SMALL_FLASH_LOW1 0x00000001ff800000
+#define EBONY_SMALL_FLASH_LOW2 0x00000001ff880000
+#define EBONY_SMALL_FLASH_HIGH1 0x00000001fff00000
+#define EBONY_SMALL_FLASH_HIGH2 0x00000001fff80000
+#define EBONY_SMALL_FLASH_SIZE 0x80000
+#define EBONY_LARGE_FLASH_LOW 0x00000001ff800000
+#define EBONY_LARGE_FLASH_HIGH 0x00000001ffc00000
+#define EBONY_LARGE_FLASH_SIZE 0x400000
+
+#define EBONY_SMALL_FLASH_BASE 0x00000001fff80000
+#define EBONY_LARGE_FLASH_BASE 0x00000001ff800000
+
+/*
+ * Serial port defines
+ */
+
+/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE (u8 *) 0xE0000200
+#define UART1_IO_BASE (u8 *) 0xE0000300
+
+#define BASE_BAUD 33000000/3/16
+#define UART0_INT 0
+#define UART1_INT 1
+
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base: UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1)
+
+/* PCI support */
+#define EBONY_PCI_LOWER_IO 0x00000000
+#define EBONY_PCI_UPPER_IO 0x0000ffff
+#define EBONY_PCI_LOWER_MEM 0x80002000
+#define EBONY_PCI_UPPER_MEM 0xffffefff
+
+#define EBONY_PCI_CFGREGS_BASE 0x000000020ec00000
+#define EBONY_PCI_CFGA_PLB32 0x0ec00000
+#define EBONY_PCI_CFGD_PLB32 0x0ec00004
+
+#define EBONY_PCI_IO_BASE 0x0000000208000000ULL
+#define EBONY_PCI_IO_SIZE 0x00010000
+#define EBONY_PCI_MEM_OFFSET 0x00000000
+
+#endif /* __ASM_EBONY_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c
new file mode 100644
index 000000000000..7bdd7455afcd
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gp.c
@@ -0,0 +1,31 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440gp.c
+ *
+ * PPC440GP I/O descriptions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * 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 <platforms/4xx/ibm440gp.h>
+#include <asm/ocp.h>
+#include <linux/init.h>
+
+struct ocp_def core_ocp[] __initdata = {
+ {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GP_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART0_ADDR, UART0_INT, IBM_CPM_UART0},
+ {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART1_ADDR, UART1_INT, IBM_CPM_UART1},
+ {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0},
+ {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1},
+ {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GP_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0},
+ {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GP_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA},
+ {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA},
+};
diff --git a/arch/ppc/platforms/4xx/ibm440gp.h b/arch/ppc/platforms/4xx/ibm440gp.h
new file mode 100644
index 000000000000..b8c1a4fb66e7
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gp.h
@@ -0,0 +1,102 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440gp.h
+ *
+ * PPC440GP definitions
+ *
+ * Roland Dreier <roland@digitalvampire.org>
+ *
+ * Copyright 2002 Roland Dreier
+ *
+ * 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 file contains code that was originally in the files ibm44x.h
+ * and ebony.h, which were written by Matt Porter of MontaVista Software Inc.
+ */
+
+#ifdef __KERNEL__
+#ifndef __PPC_PLATFORMS_IBM440GP_H
+#define __PPC_PLATFORMS_IBM440GP_H
+
+#include <linux/config.h>
+
+#define EMAC_NUMS 2
+#define UART_NUMS 2
+#define ZMII_NUMS 1
+#define IIC_NUMS 2
+#define IIC0_IRQ 2
+#define IIC1_IRQ 3
+#define GPIO_NUMS 1
+
+/* UART location */
+#define PPC440GP_UART0_ADDR 0x0000000140000200ULL
+#define PPC440GP_UART1_ADDR 0x0000000140000300ULL
+
+/* EMAC location */
+#define PPC440GP_EMAC0_ADDR 0x0000000140000800ULL
+#define PPC440GP_EMAC1_ADDR 0x0000000140000900ULL
+#define PPC440GP_EMAC_SIZE 0x70
+
+/* EMAC IRQ's */
+#define BL_MAC_WOL 61 /* WOL */
+#define BL_MAC_WOL1 63 /* WOL */
+#define BL_MAL_SERR 32 /* MAL SERR */
+#define BL_MAL_TXDE 33 /* MAL TXDE */
+#define BL_MAL_RXDE 34 /* MAL RXDE */
+#define BL_MAL_TXEOB 10 /* MAL TX EOB */
+#define BL_MAL_RXEOB 11 /* MAL RX EOB */
+#define BL_MAC_ETH0 60 /* MAC */
+#define BL_MAC_ETH1 62 /* MAC */
+
+/* ZMII location */
+#define PPC440GP_ZMII_ADDR 0x0000000140000780ULL
+#define PPC440GP_ZMII_SIZE 0x0c
+
+/* I2C location */
+#define PPC440GP_IIC0_ADDR 0x40000400
+#define PPC440GP_IIC1_ADDR 0x40000500
+
+/* GPIO location */
+#define PPC440GP_GPIO0_ADDR 0x0000000140000700ULL
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
+#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
+#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
+#define IBM_CPM_CPU 0x02000000 /* processor core */
+#define IBM_CPM_DMA 0x01000000 /* DMA controller */
+#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
+#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
+#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
+#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
+#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
+#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
+#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
+#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
+#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
+#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
+#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
+#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
+
+#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+ | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+ | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+ | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI)
+
+#define PPC440GP_OPB_BASE_START 0x0000000140000000ULL
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE 2
+
+#include <asm/ibm44x.h>
+#include <syslib/ibm440gp_common.h>
+
+#endif /* __PPC_PLATFORMS_IBM440GP_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
new file mode 100644
index 000000000000..42677b8b1ecf
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gx.c
@@ -0,0 +1,37 @@
+/*
+ * arch/ppc/platforms/ibm440gx.c
+ *
+ * PPC440GX I/O descriptions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * 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/init.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <asm/ocp.h>
+#include <platforms/4xx/ibm440gx.h>
+
+struct ocp_def core_ocp[] __initdata = {
+ {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GX_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART0_ADDR, UART0_IRQ, IBM_CPM_UART0},
+ {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART1_ADDR, UART1_IRQ, IBM_CPM_UART1},
+ {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0},
+ {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1},
+ {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GX_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0},
+ {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA},
+ {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GX_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA},
+ {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA},
+};
diff --git a/arch/ppc/platforms/4xx/ibm440gx.h b/arch/ppc/platforms/4xx/ibm440gx.h
new file mode 100644
index 000000000000..7299b4c42319
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gx.h
@@ -0,0 +1,123 @@
+/*
+ * arch/ppc/platforms/ibm440gx.h
+ *
+ * PPC440GX definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002 Roland Dreier
+ * Copyright 2003 MontaVista Software, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __PPC_PLATFORMS_IBM440GX_H
+#define __PPC_PLATFORMS_IBM440GX_H
+
+#include <linux/config.h>
+
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440GX_UART0_ADDR 0x0000000140000200ULL
+#define PPC440GX_UART1_ADDR 0x0000000140000300ULL
+#define UART0_IRQ 0
+#define UART1_IRQ 1
+
+/* EMAC */
+#define PPC440GX_EMAC0_ADDR 0x0000000140000800ULL
+#define PPC440GX_EMAC1_ADDR 0x0000000140000900ULL
+#define PPC440GX_EMAC2_ADDR 0x0000000140000C00ULL
+#define PPC440GX_EMAC3_ADDR 0x0000000140000E00ULL
+#define PPC440GX_EMAC_SIZE 0xFC
+#define EMAC_NUMS 2
+#define BL_MAC_WOL 61 /* WOL */
+#define BL_MAC_WOL1 63 /* WOL */
+#define BL_MAC_WOL2 65 /* WOL */
+#define BL_MAC_WOL3 67 /* WOL */
+#define BL_MAL_SERR 32 /* MAL SERR */
+#define BL_MAL_TXDE 33 /* MAL TXDE */
+#define BL_MAL_RXDE 34 /* MAL RXDE */
+#define BL_MAL_TXEOB 10 /* MAL TX EOB */
+#define BL_MAL_RXEOB 11 /* MAL RX EOB */
+#define BL_MAC_ETH0 60 /* MAC */
+#define BL_MAC_ETH1 62 /* MAC */
+#define BL_MAC_ETH2 64 /* MAC */
+#define BL_MAC_ETH3 66 /* MAC */
+#define BL_TAH0 68 /* TAH 0 */
+#define BL_TAH1 69 /* TAH 1 */
+
+/* TAH */
+#define PPC440GX_TAH0_ADDR 0x0000000140000B00ULL
+#define PPC440GX_TAH1_ADDR 0x0000000140000D00ULL
+#define PPC440GX_TAH_SIZE 0xFC
+
+/* ZMII */
+#define PPC440GX_ZMII_ADDR 0x0000000140000780ULL
+#define PPC440GX_ZMII_SIZE 0x0c
+
+/* RGMII */
+#define PPC440GX_RGMII_ADDR 0x0000000140000790ULL
+#define PPC440GX_RGMII_SIZE 0x0c
+
+/* IIC */
+#define PPC440GX_IIC0_ADDR 0x40000400
+#define PPC440GX_IIC1_ADDR 0x40000500
+#define IIC0_IRQ 2
+#define IIC1_IRQ 3
+
+/* GPIO */
+#define PPC440GX_GPIO0_ADDR 0x0000000140000700ULL
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
+#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
+#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
+#define IBM_CPM_RGMII 0x10000000 /* RGMII */
+#define IBM_CPM_TAHOE0 0x08000000 /* TAHOE 0 */
+#define IBM_CPM_TAHOE1 0x04000000 /* TAHOE 1 */
+#define IBM_CPM_CPU 0x02000000 /* processor core */
+#define IBM_CPM_DMA 0x01000000 /* DMA controller */
+#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
+#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
+#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
+#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
+#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
+#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
+#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
+#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
+#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
+#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
+#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
+#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
+#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */
+#define IBM_CPM_EMAC1 0x00000010 /* EMAC 1 */
+#define IBM_CPM_EMAC2 0x00000008 /* EMAC 2 */
+#define IBM_CPM_EMAC3 0x00000004 /* EMAC 3 */
+
+#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+ | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+ | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+ | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
+ | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
+ | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
+ | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
+
+/* OPB */
+#define PPC440GX_OPB_BASE_START 0x0000000140000000ULL
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE 2
+
+#endif /* __PPC_PLATFORMS_IBM440GX_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
new file mode 100644
index 000000000000..7acf4aedcc84
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -0,0 +1,459 @@
+/*
+ * arch/ppc/platforms/ocotea.c
+ *
+ * Ocotea board specific routines
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ *
+ * 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+
+extern void abort(void);
+
+/* Global Variables */
+bd_t __res;
+
+static void __init
+ocotea_calibrate_decr(void)
+{
+ unsigned int freq;
+
+ freq = OCOTEA_SYSCLK;
+
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+ /* Enable decrementer interrupt */
+ mtspr(SPRN_TCR, TCR_DIE);
+}
+
+static int
+ocotea_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: IBM\n");
+ seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n");
+
+ return 0;
+}
+static inline int
+ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */
+ { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */
+ { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */
+ { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */
+ };
+
+ const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define PCIX_READW(offset) \
+ (readw((u32)pcix_reg_base+offset))
+
+#define PCIX_WRITEW(value, offset) \
+ (writew(value, (u32)pcix_reg_base+offset))
+
+#define PCIX_WRITEL(value, offset) \
+ (writel(value, (u32)pcix_reg_base+offset))
+
+/*
+ * FIXME: This is only here to "make it work". This will move
+ * to a ibm_pcix.c which will contain a generic IBM PCIX bridge
+ * configuration library. -Matt
+ */
+static void __init
+ocotea_setup_pcix(void)
+{
+ void *pcix_reg_base;
+
+ pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE);
+
+ /* Enable PCIX0 I/O, Mem, and Busmaster cycles */
+ PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND);
+
+ /* Disable all windows */
+ PCIX_WRITEL(0, PCIX0_POM0SA);
+ PCIX_WRITEL(0, PCIX0_POM1SA);
+ PCIX_WRITEL(0, PCIX0_POM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SAH);
+ PCIX_WRITEL(0, PCIX0_PIM1SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SAH);
+
+ /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */
+ PCIX_WRITEL(0x00000003, PCIX0_POM0LAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
+ PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
+ PCIX_WRITEL(0x80000001, PCIX0_POM0SA);
+
+ /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+ PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA);
+
+ eieio();
+}
+
+static void __init
+ocotea_setup_hose(void)
+{
+ struct pci_controller *hose;
+
+ /* Configure windows on the PCI-X host bridge */
+ ocotea_setup_pcix();
+
+ hose = pcibios_alloc_controller();
+
+ if (!hose)
+ return;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET;
+
+ pci_init_resource(&hose->io_resource,
+ OCOTEA_PCI_LOWER_IO,
+ OCOTEA_PCI_UPPER_IO,
+ IORESOURCE_IO,
+ "PCI host bridge");
+
+ pci_init_resource(&hose->mem_resources[0],
+ OCOTEA_PCI_LOWER_MEM,
+ OCOTEA_PCI_UPPER_MEM,
+ IORESOURCE_MEM,
+ "PCI host bridge");
+
+ hose->io_space.start = OCOTEA_PCI_LOWER_IO;
+ hose->io_space.end = OCOTEA_PCI_UPPER_IO;
+ hose->mem_space.start = OCOTEA_PCI_LOWER_MEM;
+ hose->mem_space.end = OCOTEA_PCI_UPPER_MEM;
+ isa_io_base =
+ (unsigned long)ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE);
+ hose->io_base_virt = (void *)isa_io_base;
+
+ setup_indirect_pci(hose,
+ OCOTEA_PCI_CFGA_PLB32,
+ OCOTEA_PCI_CFGD_PLB32);
+ hose->set_cfg_type = 1;
+
+ hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = ocotea_map_irq;
+}
+
+
+TODC_ALLOC();
+
+static void __init
+ocotea_early_serial_map(void)
+{
+ struct uart_port port;
+
+ /* Setup ioremapped serial port access */
+ memset(&port, 0, sizeof(port));
+ port.membase = ioremap64(PPC440GX_UART0_ADDR, 8);
+ port.irq = 0;
+ port.uartclk = BASE_BAUD * 16;
+ port.regshift = 0;
+ port.iotype = SERIAL_IO_MEM;
+ port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ port.line = 0;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
+ port.irq = 1;
+ port.line = 1;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+}
+
+static void __init
+ocotea_setup_arch(void)
+{
+ unsigned char *addr;
+ unsigned long long mac64;
+
+ /* Retrieve MAC addresses from flash */
+ addr = ioremap64(OCOTEA_MAC_BASE, OCOTEA_MAC_SIZE);
+ mac64 = simple_strtoull(addr, 0, 16);
+ memcpy(__res.bi_enetaddr[0], (char *)&mac64+2, 6);
+ mac64 = simple_strtoull(addr+OCOTEA_MAC1_OFFSET, 0, 16);
+ memcpy(__res.bi_enetaddr[1], (char *)&mac64+2, 6);
+ iounmap(addr);
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+ /* Setup TODC access */
+ TODC_INIT(TODC_TYPE_DS1743,
+ 0,
+ 0,
+ ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE),
+ 8);
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ /* Setup PCI host bridge */
+ ocotea_setup_hose();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+#ifdef CONFIG_ROOT_NFS
+ ROOT_DEV = Root_NFS;
+#else
+ ROOT_DEV = Root_HDA1;
+#endif
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ ocotea_early_serial_map();
+
+ /* Identify the system */
+ printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n");
+}
+
+static void
+ocotea_restart(char *cmd)
+{
+ local_irq_disable();
+ abort();
+}
+
+static void
+ocotea_power_off(void)
+{
+ local_irq_disable();
+ for(;;);
+}
+
+static void
+ocotea_halt(void)
+{
+ local_irq_disable();
+ for(;;);
+}
+
+/*
+ * Read the 440GX memory controller to get size of system memory.
+ */
+static unsigned long __init
+ocotea_find_end_of_memory(void)
+{
+ u32 i, bank_config;
+ u32 mem_size = 0;
+
+ for (i=0; i<4; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR);
+ break;
+ case 1:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR);
+ break;
+ case 2:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR);
+ break;
+ case 3:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR);
+ break;
+ }
+
+ bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+
+ if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE))
+ continue;
+ switch (SDRAM_CONFIG_BANK_SIZE(bank_config))
+ {
+ case SDRAM_CONFIG_SIZE_8M:
+ mem_size += PPC44x_MEM_SIZE_8M;
+ break;
+ case SDRAM_CONFIG_SIZE_16M:
+ mem_size += PPC44x_MEM_SIZE_16M;
+ break;
+ case SDRAM_CONFIG_SIZE_32M:
+ mem_size += PPC44x_MEM_SIZE_32M;
+ break;
+ case SDRAM_CONFIG_SIZE_64M:
+ mem_size += PPC44x_MEM_SIZE_64M;
+ break;
+ case SDRAM_CONFIG_SIZE_128M:
+ mem_size += PPC44x_MEM_SIZE_128M;
+ break;
+ case SDRAM_CONFIG_SIZE_256M:
+ mem_size += PPC44x_MEM_SIZE_256M;
+ break;
+ case SDRAM_CONFIG_SIZE_512M:
+ mem_size += PPC44x_MEM_SIZE_512M;
+ break;
+ }
+ }
+ return mem_size;
+}
+
+static void __init
+ocotea_init_irq(void)
+{
+ int i;
+
+ /* Enable PPC440GP interrupt compatibility mode */
+ SDR_WRITE(DCRN_SDR_MFR,SDR_READ(DCRN_SDR_MFR) | DCRN_SDR_MFR_PCM);
+
+ ppc4xx_pic_init();
+
+ for (i = 0; i < NR_IRQS; i++)
+ irq_desc[i].handler = ppc4xx_pic;
+}
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+struct serial_state rs_table[RS_TABLE_SIZE] = {
+ SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */
+};
+
+static void
+ocotea_progress(char *s, unsigned short hex)
+{
+ volatile char c;
+ volatile unsigned long com_port;
+ u16 shift;
+
+ com_port = (unsigned long)rs_table[0].iomem_base;
+ shift = rs_table[0].iomem_reg_shift;
+
+ while ((c = *s++) != 0) {
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = c;
+
+ }
+
+ /* Send LF/CR to pretty up output */
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = '\r';
+ while ((*((volatile unsigned char *)com_port +
+ (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = '\n';
+}
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+#if 0
+static void __init
+ocotea_map_io(void)
+{
+ io_block_mapping(0xe0000000, 0x0000000140000000,
+ 0x00001000, _PAGE_IO);
+}
+#endif
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6, unsigned long r7)
+{
+ parse_bootinfo((struct bi_record *) (r3 + KERNELBASE));
+
+ ppc_md.setup_arch = ocotea_setup_arch;
+ ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
+ ppc_md.init_IRQ = ocotea_init_irq;
+ ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
+
+ ppc_md.find_end_of_memory = ocotea_find_end_of_memory;
+
+ ppc_md.restart = ocotea_restart;
+ ppc_md.power_off = ocotea_power_off;
+ ppc_md.halt = ocotea_halt;
+
+ ppc_md.calibrate_decr = ocotea_calibrate_decr;
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ ppc_md.progress = ocotea_progress;
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef CONFIG_KGDB
+ ppc_md.early_serial_map = ocotea_early_serial_map;
+#endif
+}
diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h
new file mode 100644
index 000000000000..2f2b5ab2f2b1
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ocotea.h
@@ -0,0 +1,84 @@
+/*
+ * arch/ppc/platforms/ocotea.h
+ *
+ * Ocotea board definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_OCOTEA_H__
+#define __ASM_OCOTEA_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ibm440gx.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0 0xE0000800
+
+/* Location of MAC addresses in firmware */
+#define OCOTEA_MAC_BASE (OCOTEA_SMALL_FLASH_HIGH+0xc0500)
+#define OCOTEA_MAC_SIZE 0x200
+#define OCOTEA_MAC1_OFFSET 0x100
+
+/* Default clock rate */
+#define OCOTEA_SYSCLK 25000000
+
+/* RTC/NVRAM location */
+#define OCOTEA_RTC_ADDR 0x0000000148000000ULL
+#define OCOTEA_RTC_SIZE 0x2000
+
+/* Flash */
+#define OCOTEA_FPGA_ADDR 0x0000000148300000ULL
+#define OCOTEA_BOOT_LARGE_FLASH(x) (x & 0x40)
+#define OCOTEA_SMALL_FLASH_LOW 0x00000001ff900000ULL
+#define OCOTEA_SMALL_FLASH_HIGH 0x00000001fff00000ULL
+#define OCOTEA_SMALL_FLASH_SIZE 0x100000
+#define OCOTEA_LARGE_FLASH_LOW 0x00000001ff800000ULL
+#define OCOTEA_LARGE_FLASH_HIGH 0x00000001ffc00000ULL
+#define OCOTEA_LARGE_FLASH_SIZE 0x400000
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE 2
+
+/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE (u8 *) 0xE0000200
+#define UART1_IO_BASE (u8 *) 0xE0000300
+
+#define BASE_BAUD 11059200/16
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_IRQ, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base: UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1)
+
+/* PCI support */
+#define OCOTEA_PCI_LOWER_IO 0x00000000
+#define OCOTEA_PCI_UPPER_IO 0x0000ffff
+#define OCOTEA_PCI_LOWER_MEM 0x80000000
+#define OCOTEA_PCI_UPPER_MEM 0xffffefff
+
+#define OCOTEA_PCI_CFGREGS_BASE 0x000000020ec00000ULL
+#define OCOTEA_PCI_CFGA_PLB32 0x0ec00000
+#define OCOTEA_PCI_CFGD_PLB32 0x0ec00004
+
+#define OCOTEA_PCI_IO_BASE 0x0000000208000000ULL
+#define OCOTEA_PCI_IO_SIZE 0x00010000
+#define OCOTEA_PCI_MEM_OFFSET 0x00000000
+
+#endif /* __ASM_OCOTEA_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index c4621a145929..59dd330444bc 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -13,6 +13,8 @@ CFLAGS_prom_init.o += -mrelocatable-lib
CFLAGS_btext.o += -mrelocatable-lib
obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o
+obj-$(CONFIG_44x) += ibm44x_common.o
+obj-$(CONFIG_440GP) += ibm440gp_common.o
ifeq ($(CONFIG_4xx),y)
obj-$(CONFIG_4xx) += ppc4xx_pic.o
obj-$(CONFIG_40x) += ppc4xx_setup.o
@@ -33,6 +35,7 @@ obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o
obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o
obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
todc_time.o
+obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o
obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \
indirect_pci.o todc_time.o pci_auto.o
obj-$(CONFIG_GEMINI) += open_pic.o i8259.o indirect_pci.o
@@ -46,6 +49,7 @@ obj-$(CONFIG_MENF1) += todc_time.o i8259.o mpc10x_common.o \
pci_auto.o indirect_pci.o
obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \
i8259.o pci_auto.o pplus_common.o
+obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o
obj-$(CONFIG_PAL4) += cpc700_pic.o
obj-$(CONFIG_PCORE) += mpc10x_common.o todc_time.o i8259.o \
indirect_pci.o pci_auto.o
diff --git a/arch/ppc/syslib/ibm440gp_common.c b/arch/ppc/syslib/ibm440gp_common.c
new file mode 100644
index 000000000000..cc1382db846b
--- /dev/null
+++ b/arch/ppc/syslib/ibm440gp_common.c
@@ -0,0 +1,77 @@
+/*
+ * arch/ppc/syslib/ibm440gp_common.c
+ *
+ * PPC440GP system library
+ *
+ * Matt Porter <mporter@mvista.com>
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003 Zultys Technologies
+ *
+ * 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/types.h>
+#include <asm/ibm44x.h>
+#include <asm/mmu.h>
+
+/*
+ * Calculate 440GP clocks
+ */
+void __init ibm440gp_get_clocks(struct ibm440gp_clocks* p,
+ unsigned int sys_clk,
+ unsigned int ser_clk)
+{
+ u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0);
+ u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0);
+ u32 opdv, epdv;
+
+ if (cpc0_sys0 & 0x2){
+ /* Bypass system PLL */
+ p->cpu = p->plb = sys_clk;
+ }
+ else {
+ u32 fbdv, fwdva, fwdvb, m, vco;
+
+ fbdv = (cpc0_sys0 >> 18) & 0x0f;
+ if (!fbdv)
+ fbdv = 16;
+
+ fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7);
+ fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7);
+
+ /* Feedback path */
+ if (cpc0_sys0 & 0x00000080){
+ /* PerClk */
+ m = fwdvb * opdv * epdv;
+ }
+ else {
+ /* CPU clock */
+ m = fbdv * fwdva;
+ }
+ vco = sys_clk * m;
+ p->cpu = vco / fwdva;
+ p->plb = vco / fwdvb;
+ }
+
+ opdv = ((cpc0_sys0 >> 10) & 0x3) + 1;
+ epdv = ((cpc0_sys0 >> 8) & 0x3) + 1;
+
+ p->opb = p->plb / opdv;
+ p->ebc = p->opb / epdv;
+
+ if (cpc0_cr0 & 0x00400000){
+ /* External UART clock */
+ p->uart = ser_clk;
+ }
+ else {
+ /* Internal UART clock */
+ u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1;
+ p->uart = p->plb / uart_div;
+ }
+}
diff --git a/arch/ppc/syslib/ibm440gp_common.h b/arch/ppc/syslib/ibm440gp_common.h
new file mode 100644
index 000000000000..63dbd4a9c434
--- /dev/null
+++ b/arch/ppc/syslib/ibm440gp_common.h
@@ -0,0 +1,45 @@
+/*
+ * arch/ppc/syslib/ibm440gp_common.h
+ *
+ * PPC440GP system library
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003 Zultys Technologies
+ *
+ * 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.
+ *
+ */
+#ifdef __KERNEL__
+#ifndef __PPC_SYSLIB_IBM440GP_COMMON_H
+#define __PPC_SYSLIB_IBM440GP_COMMON_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+/*
+ * All clocks are in Hz
+ */
+struct ibm440gp_clocks {
+ unsigned int cpu; /* CPUCoreClk */
+ unsigned int plb; /* PLBClk */
+ unsigned int opb; /* OPBClk */
+ unsigned int ebc; /* PerClk */
+ unsigned int uart;
+};
+
+/*
+ * Please, refer to the Figure 13.1 in 440GP user manual
+ *
+ * if internal UART clock is used, ser_clk is ignored
+ */
+void ibm440gp_get_clocks(struct ibm440gp_clocks*, unsigned int sys_clk,
+ unsigned int ser_clk) __init;
+
+#endif /* __ASSEMBLY__ */
+#endif /* __PPC_SYSLIB_IBM440GP_COMMON_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
new file mode 100644
index 000000000000..a0cefdc7c1da
--- /dev/null
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -0,0 +1,37 @@
+/*
+ * arch/ppc/syslib/ibm44x_common.c
+ *
+ * PPC44x system library
+ *
+ * Matt Porter <mporter@mvista.com>
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * 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/types.h>
+#include <asm/ibm44x.h>
+#include <asm/mmu.h>
+
+phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
+{
+ phys_addr_t page_4gb = 0;
+
+ /*
+ * Trap the least significant 32-bit portions of an
+ * address in the 440's 36-bit address space. Fix
+ * them up with the appropriate ERPN
+ */
+ if ((addr >= PPC44x_IO_LO) && (addr < PPC44x_IO_HI))
+ page_4gb = PPC44x_IO_PAGE;
+ else if ((addr >= PPC44x_PCICFG_LO) && (addr < PPC44x_PCICFG_HI))
+ page_4gb = PPC44x_PCICFG_PAGE;
+ else if ((addr >= PPC44x_PCIMEM_LO) && (addr < PPC44x_PCIMEM_HI))
+ page_4gb = PPC44x_PCIMEM_PAGE;
+
+ return (page_4gb | addr);
+};
diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c
index 4ce2f9369019..a9e66d666ceb 100644
--- a/arch/sparc64/kernel/semaphore.c
+++ b/arch/sparc64/kernel/semaphore.c
@@ -110,6 +110,7 @@ static void __down(struct semaphore * sem)
void down(struct semaphore *sem)
{
+ might_sleep();
/* This atomically does:
* old_val = sem->count;
* new_val = sem->count - 1;
@@ -219,6 +220,7 @@ int down_interruptible(struct semaphore *sem)
{
int ret = 0;
+ might_sleep();
/* This atomically does:
* old_val = sem->count;
* new_val = sem->count - 1;
diff --git a/crypto/Makefile b/crypto/Makefile
index f3325db1ee76..8326b4fb5be4 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -2,11 +2,10 @@
# Cryptographic API
#
-autoload-crypto-$(CONFIG_KMOD) = autoload.o
proc-crypto-$(CONFIG_PROC_FS) = proc.o
obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
- $(autoload-crypto-y) $(proc-crypto-y)
+ $(proc-crypto-y)
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
diff --git a/crypto/autoload.c b/crypto/autoload.c
deleted file mode 100644
index 7cda40b39ddf..000000000000
--- a/crypto/autoload.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Algorithm autoloader.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- */
-#include <linux/kernel.h>
-#include <linux/crypto.h>
-#include <linux/string.h>
-#include <linux/kmod.h>
-#include "internal.h"
-
-/*
- * A far more intelligent version of this is planned. For now, just
- * try an exact match on the name of the algorithm.
- */
-void crypto_alg_autoload(const char *name)
-{
- request_module("%s", name);
-}
-
-struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
- struct crypto_alg *alg = crypto_alg_lookup(name);
- if (alg == NULL) {
- crypto_alg_autoload(name);
- alg = crypto_alg_lookup(name);
- }
- return alg;
-}
diff --git a/crypto/internal.h b/crypto/internal.h
index 10880d149afe..8ba30b772ee3 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -15,6 +15,7 @@
#include <linux/highmem.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/kmod.h>
#include <asm/hardirq.h>
#include <asm/kmap_types.h>
@@ -48,15 +49,12 @@ static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
struct crypto_alg *crypto_alg_lookup(const char *name);
-#ifdef CONFIG_KMOD
-void crypto_alg_autoload(const char *name);
-struct crypto_alg *crypto_alg_mod_lookup(const char *name);
-#else
+/* A far more intelligent version of this is planned. For now, just
+ * try an exact match on the name of the algorithm. */
static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
{
- return crypto_alg_lookup(name);
+ return try_then_request_module(crypto_alg_lookup(name), name);
}
-#endif
#ifdef CONFIG_CRYPTO_HMAC
int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index a66c2f086e25..338f48c1228f 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -15,7 +15,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 1247846c538f..2fdb6f766e44 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -15,12 +15,6 @@
*
* Things not working yet:
*
- * o We're only set up to compile as a module currently. i.e.
- * you should put the source in drivers/atm/lanai.c and then
- * just do "make drivers/atm/lanai.o" from the main
- * source directory. This will produce a drivers/atm/lanai.o
- * file suitable for insmod'ing
- *
* o We don't support the Speedstream 3060 yet - this card has
* an on-board DSL modem chip by Alcatel and the driver will
* need some extra code added to handle it
@@ -245,9 +239,6 @@ struct lanai_vcc {
struct atm_vcc *atmvcc; /* atm_vcc who is transmitter */
int endptr; /* last endptr from service entry */
struct sk_buff_head backlog;
- struct sk_buff *inprogress; /* We're streaming this PDU */
- unsigned char *pptr; /* Where we are in above */
- int inprogleft; /* Bytes left to send "inprogress" */
void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int);
} tx;
};
@@ -268,8 +259,6 @@ struct lanai_dev_stats {
unsigned pcierr_m_target_abort;
unsigned pcierr_s_target_abort;
unsigned pcierr_master_parity;
- unsigned service_novcc_rx;
- unsigned service_novcc_tx;
unsigned service_notx;
unsigned service_norx;
unsigned service_rxnotaal5;
@@ -297,7 +286,7 @@ struct lanai_dev {
struct lanai_buffer aal0buf; /* AAL0 RX buffers */
u32 conf1, conf2; /* CONFIG[12] registers */
u32 status; /* STATUS register */
- spinlock_t txlock;
+ spinlock_t endtxlock;
spinlock_t servicelock;
struct atm_vcc *cbrvcc;
int number;
@@ -501,7 +490,6 @@ static inline void reg_write(const struct lanai_dev *lanai, u32 val,
RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base,
(int) reg, val);
writel(val, reg_addr(lanai, reg));
- mdelay(1);
}
static inline void conf1_write(const struct lanai_dev *lanai)
@@ -537,63 +525,6 @@ static inline void reset_board(const struct lanai_dev *lanai)
udelay(5);
}
-/* -------------------- VCC LIST LOCK: */
-
-/*
- * The linux-atm code disables local IRQs while managing the list of
- * VCCs on a card. This is good, but it doesn't save us against
- * SMP. Unfortunately, fixing this will require changes in the
- * API which will have to wait a little bit. It's a hard race to
- * trigger accidentally, so it isn't TOO horrible so far.
- *
- * One possible solution would be to have an rwlock which is
- * always grabbed _irq-style on writing. This would automatically
- * be grabbed (for writing) by the higher layers on things that
- * would result in a change in the vcc list (_open, _close,
- * probably _change_qos) - thus it would also protect the
- * higher-level list of vccs on each device (atm_dev->vccs).
- * The driver would be responsible for grabbing it as a read_lock
- * anytime it wants to consult its table of vccs - for instance
- * when handling an incoming PDU. This also explains why we would
- * probably want the write_lock while in _change_qos - to prevent
- * handling of PDUs while possibly in an inconsistent state.
- * Also, _send would grab the lock for reading.
- *
- * One problem with this is that _open and _close could no longer
- * do anything that might provoke a schedule. First, it would
- * force us to use GFP_ATOMIC memory (which is bad), but also
- * some devices pretty much require scheduling due to long
- * delays (see lanai_close for an example). So in this case
- * we need a way to schedule without losing the spinlock.
- * The cleanest way to do this is probably have a way to mark a
- * VCC as "in progress" so that the interrupt handler can
- * still disregard any traffic for it while _open or _close
- * are sleeping on it. Then it will need to be _open and
- * _close's job to relinquish the write_lock. Thus, the
- * lock could be dropped around the times that scheduling
- * might occur. Perhaps the _READY flag can be used for
- * this purpose.
- *
- * One short note about this "upper layer grabs, driver
- * relinquishes" write lock - since this needs to be
- * an _irq lock we're going to have problem saving
- * and restoring flags (_irqsave/_irqrestore). This
- * shouldn't be a problem, however - we must just
- * require that those syscalls are never called with
- * interrupts disabled so we can use the non-flags-saving
- * versions.
- *
- * Anyway, all of the above is vaporware currently - fixing
- * this right will require changes in the API and all of
- * the drivers - this will wait until 2.5.x most likely.
- * The following NOP macros are just here to mark where
- * the locks will be needed in the future.
- */
-#define vcclist_read_lock() do {} while (0)
-#define vcclist_read_unlock() do {} while (0)
-#define vcclist_write_lock() do {} while (0)
-#define vcclist_write_unlock() do {} while (0)
-
/* -------------------- CARD SRAM UTILITIES: */
/* The SRAM is mapped into normal PCI memory space - the only catch is
@@ -851,36 +782,39 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
if (lvcc->vbase == 0) /* We were never bound to a VCI */
return;
/* 15.2.1 - wait for queue to drain */
- spin_lock_irqsave(&lanai->txlock, flags);
- if (lvcc->tx.inprogress != NULL) {
- lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress);
- lvcc->tx.inprogress = NULL;
- }
while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
lanai_free_skb(lvcc->tx.atmvcc, skb);
+ read_lock_irqsave(&vcc_sklist_lock, flags);
__clear_bit(lvcc->vci, lanai->backlog_vccs);
- spin_unlock_irqrestore(&lanai->txlock, flags);
- timeout = jiffies + ((lanai_buf_size(&lvcc->tx.buf) * HZ) >> 17);
+ read_unlock_irqrestore(&vcc_sklist_lock, flags);
+ /*
+ * We need to wait for the VCC to drain but don't wait forever. We
+ * give each 1K of buffer size 1/128th of a second to clear out.
+ * TODO: maybe disable CBR if we're about to timeout?
+ */
+ timeout = jiffies +
+ (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);
write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
- goto start;
- while (time_before_eq(jiffies, timeout)) {
- schedule_timeout(HZ / 25);
- start:
+ for (;;) {
read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
if (read == write && /* Is TX buffer empty? */
(lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
(cardvcc_read(lvcc, vcc_txcbr_next) &
TXCBR_NEXT_BOZO) == 0))
- goto done;
+ break;
if (read != lastread) { /* Has there been any progress? */
lastread = read;
timeout += HZ / 10;
}
+ if (unlikely(time_after(jiffies, timeout))) {
+ printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on "
+ "backlog closing vci %d\n",
+ lvcc->tx.atmvcc->dev->number, lvcc->vci);
+ DPRINTK("read, write = %d, %d\n", read, write);
+ break;
+ }
+ schedule_timeout(HZ / 25);
}
- printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on backlog closing "
- "vci %d\n", lvcc->tx.atmvcc->dev->number, lvcc->vci);
- DPRINTK("read, write = %d, %d\n", read, write);
- done:
/* 15.2.2 - clear out all tx registers */
cardvcc_write(lvcc, 0, vcc_txreadptr);
cardvcc_write(lvcc, 0, vcc_txwriteptr);
@@ -1226,8 +1160,7 @@ static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
/* test if VCC is currently backlogged */
static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc)
{
- return lvcc->tx.inprogress != NULL ||
- !skb_queue_empty(&lvcc->tx.backlog);
+ return !skb_queue_empty(&lvcc->tx.backlog);
}
/* Bit fields in the segmentation buffer descriptor */
@@ -1264,11 +1197,11 @@ static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
}
/* Add 32-bit AAL5 trailer and leave room for its CRC */
-static inline void vcc_tx_add_aal5trailer(struct lanai_vcc *lvcc,
+static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
int len, int cpi, int uu)
{
APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
- "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
+ "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);
lvcc->tx.buf.ptr += 2;
lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
@@ -1311,7 +1244,7 @@ static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
}
/* Update "butt" register to specify new WritePtr */
-static inline void lanai_endtx(const struct lanai_dev *lanai,
+static inline void lanai_endtx(struct lanai_dev *lanai,
const struct lanai_vcc *lvcc)
{
int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
@@ -1320,6 +1253,14 @@ static inline void lanai_endtx(const struct lanai_dev *lanai,
"lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n",
ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
lvcc->tx.buf.end);
+
+ /*
+ * Since the "butt register" is a shared resounce on the card we
+ * serialize all accesses to it through this spinlock. This is
+ * mostly just paranoia sicne the register is rarely "busy" anyway
+ * but is needed for correctness.
+ */
+ spin_lock(&lanai->endtxlock);
/*
* We need to check if the "butt busy" bit is set before
* updating the butt register. In theory this should
@@ -1334,131 +1275,86 @@ static inline void lanai_endtx(const struct lanai_dev *lanai,
}
udelay(5);
}
+ /*
+ * Before we tall the card to start work we need to be sure 100% of
+ * the info in the service buffer has been written before we tell
+ * the card about it
+ */
+ wmb();
reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
+ spin_unlock(&lanai->endtxlock);
+}
+
+/*
+ * Add one AAL5 PDU to lvcc's transmit buffer. Caller garauntees there's
+ * space available. "pdusize" is the number of bytes the PDU will take
+ */
+static void lanai_send_one_aal5(struct lanai_dev *lanai,
+ struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
+{
+ int pad;
+ APRINTK(pdusize == aal5_size(skb->len),
+ "lanai_send_one_aal5: wrong size packet (%d != %d)\n",
+ pdusize, aal5_size(skb->len));
+ vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);
+ pad = pdusize - skb->len - 8;
+ APRINTK(pad >= 0, "pad is negative (%d)\n", pad);
+ APRINTK(pad < 48, "pad is too big (%d)\n", pad);
+ vcc_tx_memcpy(lvcc, skb->data, skb->len);
+ vcc_tx_memzero(lvcc, pad);
+ vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
+ lanai_endtx(lanai, lvcc);
+ lanai_free_skb(lvcc->tx.atmvcc, skb);
+ atomic_inc(&lvcc->tx.atmvcc->stats->tx);
}
/* Try to fill the buffer - don't call unless there is backlog */
static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, int endptr)
{
- int pad, n;
+ int n;
struct sk_buff *skb;
int space = vcc_tx_space(lvcc, endptr);
APRINTK(vcc_is_backlogged(lvcc),
"vcc_tx_unqueue() called with empty backlog (vci=%d)\n",
lvcc->vci);
- if (space < 64)
- return; /* No space for even 1 cell+descriptor */
- if (lvcc->tx.inprogress != NULL) {
- APRINTK((lvcc->tx.inprogleft % 48) == 0,
- "vcc_tx_unqueue_aal5: bad progleft=%d\n",
- lvcc->tx.inprogleft);
- if (lvcc->tx.inprogleft + 16 > space) { /* Can't send all? */
- n = aal5_spacefor(space - 16); /* Bytes to send */
- vcc_tx_add_aal5_descriptor(lvcc,
- DESCRIPTOR_AAL5_STREAM, n);
- pad = lvcc->tx.pptr + n - lvcc->tx.inprogress->tail;
- if (pad < 0)
- pad = 0;
- vcc_tx_memcpy(lvcc, lvcc->tx.pptr, n - pad);
- vcc_tx_memzero(lvcc, pad);
- lvcc->tx.pptr += n;
- lvcc->tx.inprogleft -= n;
- goto end; /* Buffer is now full */
- }
- /* OK, there's at least space for all of "inprogress" skb */
- vcc_tx_add_aal5_descriptor(lvcc, 0,
- lvcc->tx.inprogleft);
- pad = lvcc->tx.pptr + lvcc->tx.inprogleft -
- lvcc->tx.inprogress->tail;
- if (pad >= lvcc->tx.inprogleft) { /* Nothing but pad left */
- APRINTK(lvcc->tx.inprogleft == 48,
- "vcc_tx_unqueue_aal5: bad pure-pad=%d\n",
- lvcc->tx.inprogleft);
- pad = 48;
- } else
- vcc_tx_memcpy(lvcc, lvcc->tx.pptr,
- lvcc->tx.inprogleft - pad);
- vcc_tx_memzero(lvcc, pad - 8);
- vcc_tx_add_aal5trailer(lvcc, lvcc->tx.inprogress->len, 0, 0);
- lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress);
- lvcc->tx.inprogress = NULL;
- space -= lvcc->tx.inprogleft + 16;
- atomic_inc(&lvcc->tx.atmvcc->stats->tx);
- }
while (space >= 64) {
- if ((skb = skb_dequeue(&lvcc->tx.backlog)) == NULL)
- break;
+ skb = skb_dequeue(&lvcc->tx.backlog);
+ if (skb == NULL)
+ goto no_backlog;
n = aal5_size(skb->len);
- if (n + 16 > space) { /* Can only send part */
- int m = aal5_spacefor(space - 16); /* Bytes to send */
- vcc_tx_add_aal5_descriptor(lvcc,
- DESCRIPTOR_AAL5_STREAM, m);
- lvcc->tx.pptr = skb->data + m;
- pad = lvcc->tx.pptr - skb->tail;
- if (pad < 0)
- pad = 0;
- vcc_tx_memcpy(lvcc, skb->data, m - pad);
- vcc_tx_memzero(lvcc, pad);
- lvcc->tx.inprogleft = n - m;
- lvcc->tx.inprogress = skb;
- goto end;
+ if (n + 16 > space) {
+ /* No room for this packet - put it back on queue */
+ skb_queue_head(&lvcc->tx.backlog, skb);
+ return;
}
- vcc_tx_add_aal5_descriptor(lvcc, 0, n);
- pad = n - skb->len - 8;
- vcc_tx_memcpy(lvcc, skb->data, skb->len);
- vcc_tx_memzero(lvcc, pad);
- lanai_free_skb(lvcc->tx.atmvcc, skb);
- vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0);
+ lanai_send_one_aal5(lanai, lvcc, skb, n);
space -= n + 16;
- atomic_inc(&lvcc->tx.atmvcc->stats->tx);
}
- if (skb_queue_empty(&lvcc->tx.backlog))
+ if (!vcc_is_backlogged(lvcc)) {
+ no_backlog:
__clear_bit(lvcc->vci, lanai->backlog_vccs);
- end:
- lanai_endtx(lanai, lvcc);
+ }
}
/* Given an skb that we want to transmit either send it now or queue */
static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
struct sk_buff *skb)
{
- int space, n, pad;
+ int space, n;
if (vcc_is_backlogged(lvcc)) /* Already backlogged */
goto queue_it;
- space = vcc_tx_space(lvcc, TXREADPTR_GET_PTR(cardvcc_read(lvcc,
- vcc_txreadptr)));
- if (space < 64) { /* No space at all */
- __set_bit(lvcc->vci, lanai->backlog_vccs);
- goto queue_it;
- }
- if (space >= 16 + (n = aal5_size(skb->len))) {
- /* We can send the whole thing now */
- vcc_tx_add_aal5_descriptor(lvcc, 0, n);
- pad = n - skb->len;
- vcc_tx_memcpy(lvcc, skb->data, skb->len);
- vcc_tx_memzero(lvcc, pad - 8);
- vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0);
- lanai_free_skb(lvcc->tx.atmvcc, skb);
- atomic_inc(&lvcc->tx.atmvcc->stats->tx);
- } else { /* Space for only part of skb */
- int bytes = aal5_spacefor(space - 16); /* Bytes to send */
- vcc_tx_add_aal5_descriptor(lvcc,
- DESCRIPTOR_AAL5_STREAM, bytes);
- pad = bytes - skb->len;
- if (pad < 0)
- pad = 0;
- vcc_tx_memcpy(lvcc, skb->data, bytes - pad);
- vcc_tx_memzero(lvcc, pad);
- lvcc->tx.inprogress = skb;
- lvcc->tx.inprogleft = n - bytes;
- lvcc->tx.pptr = skb->data + bytes;
+ space = vcc_tx_space(lvcc,
+ TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));
+ n = aal5_size(skb->len);
+ APRINTK(n + 16 >= 64, "vcc_tx_aal5: n too small (%d)\n", n);
+ if (space < n + 16) { /* No space for this PDU */
__set_bit(lvcc->vci, lanai->backlog_vccs);
+ queue_it:
+ skb_queue_tail(&lvcc->tx.backlog, skb);
+ return;
}
- lanai_endtx(lanai, lvcc);
- return;
- queue_it:
- skb_queue_tail(&lvcc->tx.backlog, skb);
+ lanai_send_one_aal5(lanai, lvcc, skb, n);
}
static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,
@@ -1476,28 +1372,6 @@ static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
lanai_free_skb(lvcc->tx.atmvcc, skb);
}
-/* Try to undequeue 1 backlogged vcc */
-static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
-{
- struct lanai_vcc *lvcc = lanai->vccs[vci];
- int endptr;
- if (lvcc == NULL || !vcc_is_backlogged(lvcc)) {
- __clear_bit(vci, lanai->backlog_vccs);
- return;
- }
- endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
- lvcc->tx.unqueue(lanai, lvcc, endptr);
-}
-
-/* Try a dequeue on all backlogged connections */
-static inline void vcc_tx_dequeue_all(struct lanai_dev *lanai)
-{
- unsigned long flags;
- spin_lock_irqsave(&lanai->txlock, flags);
- vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);
- spin_unlock_irqrestore(&lanai->txlock, flags);
-}
-
/* -------------------- VCC RX BUFFER UTILITIES: */
/* unlike the _tx_ cousins, this doesn't update ptr */
@@ -1510,6 +1384,8 @@ static inline void vcc_rx_memcpy(unsigned char *dest,
m = 0;
memcpy(dest, lvcc->rx.buf.ptr, n - m);
memcpy(dest + n - m, lvcc->rx.buf.start, m);
+ /* Make sure that these copies don't get reordered */
+ barrier();
}
/* Receive AAL5 data on a VCC with a particular endptr */
@@ -1527,6 +1403,11 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
/* Recover the second-to-last word to get true pdu length */
if ((x = &end[-2]) < lvcc->rx.buf.start)
x = &lvcc->rx.buf.end[-2];
+ /*
+ * Before we actually read from the buffer, make sure the memory
+ * changes have arrived
+ */
+ rmb();
size = be32_to_cpup(x) & 0xffff;
if (unlikely(n != aal5_size(size))) {
/* Make sure size matches padding */
@@ -1542,9 +1423,9 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
goto out;
}
skb_put(skb, size);
+ vcc_rx_memcpy(skb->data, lvcc, size);
ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
do_gettimeofday(&skb->stamp);
- vcc_rx_memcpy(skb->data, lvcc, size);
lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
atomic_inc(&lvcc->rx.atmvcc->stats->rx);
out:
@@ -1555,7 +1436,7 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
static void vcc_rx_aal0(struct lanai_dev *lanai)
{
printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n");
- /* Remember to get vcclist_read_lock while looking up VC */
+ /* Remember to get read_lock(&vcc_sklist_lock) while looking up VC */
/* Remember to increment lvcc->rx.atmvcc->stats->rx */
}
@@ -1606,7 +1487,6 @@ static inline struct lanai_vcc *new_lanai_vcc(void)
memset(&lvcc->stats, 0, sizeof lvcc->stats);
lvcc->rx.buf.start = lvcc->tx.buf.start = NULL;
skb_queue_head_init(&lvcc->tx.backlog);
- lvcc->tx.inprogress = NULL;
#ifdef DEBUG
lvcc->tx.unqueue = NULL;
lvcc->vci = -1;
@@ -1617,14 +1497,14 @@ static inline struct lanai_vcc *new_lanai_vcc(void)
static int lanai_get_sized_buffer(struct lanai_dev *lanai,
struct lanai_buffer *buf, int max_sdu, int multiplier,
- int min, const char *name)
+ const char *name)
{
int size;
if (unlikely(max_sdu < 1))
max_sdu = 1;
max_sdu = aal5_size(max_sdu);
size = (max_sdu + 16) * multiplier + 16;
- lanai_buf_allocate(buf, size, min, lanai->pci);
+ lanai_buf_allocate(buf, size, max_sdu + 32, lanai->pci);
if (unlikely(buf->start == NULL))
return -ENOMEM;
if (unlikely(lanai_buf_size(buf) < size))
@@ -1640,8 +1520,7 @@ static inline int lanai_setup_rx_vci_aal5(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, const struct atm_qos *qos)
{
return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,
- qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, qos->rxtp.max_sdu + 32,
- "RX");
+ qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, "RX");
}
/* Setup a TX buffer for a currently unbound AAL5 vci */
@@ -1659,7 +1538,7 @@ static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
multiplier = AAL5_TX_MULTIPLIER;
}
return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,
- multiplier, 80, "TX");
+ multiplier, "TX");
}
static inline void host_vcc_bind(struct lanai_dev *lanai,
@@ -1759,21 +1638,21 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
{
vci_t vci = SERVICE_GET_VCI(s);
struct lanai_vcc *lvcc;
- vcclist_read_lock();
+ read_lock(&vcc_sklist_lock);
lvcc = lanai->vccs[vci];
if (unlikely(lvcc == NULL)) {
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
DPRINTK("(itf %d) got service entry 0x%X for nonexistent "
"vcc %d\n", lanai->number, (unsigned int) s, vci);
if (s & SERVICE_TX)
- lanai->stats.service_novcc_tx++;
+ lanai->stats.service_notx++;
else
- lanai->stats.service_novcc_rx++;
+ lanai->stats.service_norx++;
return 0;
}
if (s & SERVICE_TX) { /* segmentation interrupt */
if (unlikely(lvcc->tx.atmvcc == NULL)) {
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
DPRINTK("(itf %d) got service entry 0x%X for non-TX "
"vcc %d\n", lanai->number, (unsigned int) s, vci);
lanai->stats.service_notx++;
@@ -1781,18 +1660,18 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
}
__set_bit(vci, lanai->transmit_ready);
lvcc->tx.endptr = SERVICE_GET_END(s);
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
return 1;
}
if (unlikely(lvcc->rx.atmvcc == NULL)) {
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
DPRINTK("(itf %d) got service entry 0x%X for non-RX "
"vcc %d\n", lanai->number, (unsigned int) s, vci);
lanai->stats.service_norx++;
return 0;
}
if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
"vcc %d\n", lanai->number, (unsigned int) s, vci);
lanai->stats.service_rxnotaal5++;
@@ -1801,12 +1680,12 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
}
if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
return 0;
}
if (s & SERVICE_TRASH) {
int bytes;
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
DPRINTK("got trashed rx pdu on vci %d\n", vci);
atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
lvcc->stats.x.aal5.service_trash++;
@@ -1819,7 +1698,7 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
return 0;
}
if (s & SERVICE_STREAM) {
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
lvcc->stats.x.aal5.service_stream++;
printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
@@ -1832,7 +1711,7 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
lvcc->stats.x.aal5.service_rxcrc++;
lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
return 0;
}
@@ -1840,9 +1719,8 @@ static int handle_service(struct lanai_dev *lanai, u32 s)
static void iter_transmit(struct lanai_dev *lanai, vci_t vci)
{
struct lanai_vcc *lvcc = lanai->vccs[vci];
- if (!vcc_is_backlogged(lvcc))
- return;
- lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
+ if (vcc_is_backlogged(lvcc))
+ lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
}
/* Run service queue -- called from interrupt context or with
@@ -1862,13 +1740,11 @@ static void run_service(struct lanai_dev *lanai)
}
reg_write(lanai, wreg, ServRead_Reg);
if (ntx != 0) {
- spin_lock(&lanai->txlock);
- vcclist_read_lock();
+ read_lock(&vcc_sklist_lock);
vci_bitfield_iterate(lanai, lanai->transmit_ready,
iter_transmit);
CLEAR_BITMAP(&lanai->transmit_ready, NUM_VCI);
- vcclist_read_unlock();
- spin_unlock(&lanai->txlock);
+ read_unlock(&vcc_sklist_lock);
}
}
@@ -1885,22 +1761,47 @@ static void get_statistics(struct lanai_dev *lanai)
/* -------------------- POLLING TIMER: */
+#ifndef DEBUG_RW
+/* Try to undequeue 1 backlogged vcc */
+static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
+{
+ struct lanai_vcc *lvcc = lanai->vccs[vci];
+ int endptr;
+ if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||
+ !vcc_is_backlogged(lvcc)) {
+ __clear_bit(vci, lanai->backlog_vccs);
+ return;
+ }
+ endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
+ lvcc->tx.unqueue(lanai, lvcc, endptr);
+}
+#endif /* !DEBUG_RW */
+
static void lanai_timed_poll(unsigned long arg)
{
-#ifndef DEBUG_RW
struct lanai_dev *lanai = (struct lanai_dev *) arg;
+#ifndef DEBUG_RW
unsigned long flags;
#ifdef USE_POWERDOWN
if (lanai->conf1 & CONFIG1_POWERDOWN)
return;
-#endif
- spin_lock_irqsave(&lanai->servicelock, flags);
- run_service(lanai);
- spin_unlock_irqrestore(&lanai->servicelock, flags);
- vcc_tx_dequeue_all(lanai);
+#endif /* USE_POWERDOWN */
+ local_irq_save(flags);
+ /* If we can grab the spinlock, check if any services need to be run */
+ if (spin_trylock(&lanai->servicelock)) {
+ run_service(lanai);
+ spin_unlock(&lanai->servicelock);
+ }
+ /* ...and see if any backlogged VCs can make progress */
+ /* unfortunately linux has no read_trylock() currently */
+ read_lock(&vcc_sklist_lock);
+ vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);
+ read_unlock(&vcc_sklist_lock);
+ local_irq_restore(flags);
+
get_statistics(lanai);
+#endif /* !DEBUG_RW */
mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD);
-#endif /* DEBUG_RW */
}
static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
@@ -1914,7 +1815,7 @@ static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
{
- del_timer(&lanai->timer);
+ del_timer_sync(&lanai->timer);
}
/* -------------------- INTERRUPT SERVICE: */
@@ -2265,13 +2166,13 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
#endif
lanai->cbrvcc = NULL;
memset(&lanai->stats, 0, sizeof lanai->stats);
- spin_lock_init(&lanai->txlock);
+ spin_lock_init(&lanai->endtxlock);
spin_lock_init(&lanai->servicelock);
atmdev->ci_range.vpi_bits = 0;
atmdev->ci_range.vci_bits = 0;
while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)
atmdev->ci_range.vci_bits++;
- atmdev->link_rate = ((25600000 / 8 - 8000) / 54);
+ atmdev->link_rate = ATM_25_PCR;
/* 3.2: PCI initialization */
if ((result = lanai_pci_start(lanai)) != 0)
@@ -2342,6 +2243,7 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
goto error_vcctable;
}
MOD_INC_USE_COUNT; /* At this point we can't fail */
+ mb(); /* Make sure that all that made it */
intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
/* 3.11: initialize loop mode (i.e. turn looping off) */
lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |
@@ -2466,16 +2368,11 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
atmvcc->vpi = vpi;
atmvcc->vci = vci;
set_bit(ATM_VF_ADDR, &atmvcc->flags);
- lvcc = lanai->vccs[vci];
if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)
return -EINVAL;
-#if 0
- DPRINTK(DEV_LABEL "(itf %d): open %d.%d flags=0x%lX\n",
- lanai->number, (int) vpi, vci, (unsigned long) atmvcc->flags);
-#else
DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number,
(int) vpi, vci);
-#endif
+ lvcc = lanai->vccs[vci];
if (lvcc == NULL) {
lvcc = new_lanai_vcc();
if (unlikely(lvcc == NULL))
@@ -2517,6 +2414,11 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
}
}
host_vcc_bind(lanai, lvcc, vci);
+ /*
+ * Make sure everything made it to RAM before we tell the card about
+ * the VCC
+ */
+ wmb();
if (atmvcc == lvcc->rx.atmvcc)
host_vcc_start_rx(lvcc);
if (atmvcc == lvcc->tx.atmvcc) {
@@ -2549,9 +2451,6 @@ static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
run_service(lanai);
spin_unlock_irqrestore(&lanai->servicelock, flags);
return 0; }
- case 2200001:
- vcc_tx_dequeue_all(lanai);
- return 0;
case 2200002:
get_statistics(lanai);
return 0;
@@ -2644,18 +2543,18 @@ static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
ATM_SKB(skb)->vcc = atmvcc;
switch (atmvcc->qos.aal) {
case ATM_AAL5:
- spin_lock_irqsave(&lanai->txlock, flags);
+ read_lock_irqsave(&vcc_sklist_lock, flags);
vcc_tx_aal5(lanai, lvcc, skb);
- spin_unlock_irqrestore(&lanai->txlock, flags);
+ read_unlock_irqrestore(&vcc_sklist_lock, flags);
return 0;
case ATM_AAL0:
if (unlikely(skb->len != ATM_CELL_SIZE-1))
goto einval;
/* NOTE - this next line is technically invalid - we haven't unshared skb */
cpu_to_be32s((u32 *) skb->data);
- spin_lock_irqsave(&lanai->txlock, flags);
+ read_lock_irqsave(&vcc_sklist_lock, flags);
vcc_tx_aal0(lanai, lvcc, skb);
- spin_unlock_irqrestore(&lanai->txlock, flags);
+ read_unlock_irqrestore(&vcc_sklist_lock, flags);
return 0;
}
DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal,
@@ -2725,10 +2624,6 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
"master_parity=%u\n", lanai->stats.pcierr_s_target_abort,
lanai->stats.pcierr_master_parity);
if (left-- == 0)
- return sprintf(page, "service list errors: no_vcc_rx=%u, "
- "no_vcc_tx=%u,\n", lanai->stats.service_novcc_rx,
- lanai->stats.service_novcc_tx);
- if (left-- == 0)
return sprintf(page, " no_tx=%u, "
"no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx,
lanai->stats.service_notx,
@@ -2737,7 +2632,7 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
return sprintf(page, "resets: dma=%u, card=%u\n",
lanai->stats.dma_reenable, lanai->stats.card_reset);
/* At this point, "left" should be the VCI we're looking for */
- vcclist_read_lock();
+ read_lock(&vcc_sklist_lock);
for (; ; left++) {
if (left >= NUM_VCI) {
left = 0;
@@ -2773,7 +2668,7 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
page[left++] = '\n';
page[left] = '\0';
out:
- vcclist_read_unlock();
+ read_unlock(&vcc_sklist_lock);
return left;
}
#endif /* CONFIG_PROC_FS */
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index b34ee99f5870..42c1e5663094 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1731,7 +1731,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
int __init amiga_floppy_init(void)
{
- int i;
+ int i, ret;
if (!AMIGAHW_PRESENT(AMI_FLOPPY))
return -ENXIO;
@@ -1743,41 +1743,39 @@ int __init amiga_floppy_init(void)
* We request DSKPTR, DSKLEN and DSKDATA only, because the other
* floppy registers are too spreaded over the custom register space
*/
+ ret = -EBUSY;
if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
printk("fd: cannot get floppy registers\n");
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- return -EBUSY;
+ goto out_blkdev;
}
+
+ ret = -ENOMEM;
if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
NULL) {
printk("fd: cannot get chip mem buffer\n");
- release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- return -ENOMEM;
+ goto out_memregion;
}
+
+ ret = -EBUSY;
if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
printk("fd: cannot get irq for dma\n");
- amiga_chip_free(raw_buf);
- release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- return -EBUSY;
+ goto out_irq;
}
+
if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
printk("fd: cannot get irq for timer\n");
- free_irq(IRQ_AMIGA_DSKBLK, NULL);
- amiga_chip_free(raw_buf);
- release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- return -EBUSY;
- }
- if (fd_probe_drives() < 1) { /* No usable drives */
- free_irq(IRQ_AMIGA_CIAA_TB, NULL);
- free_irq(IRQ_AMIGA_DSKBLK, NULL);
- amiga_chip_free(raw_buf);
- release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- return -ENXIO;
+ goto out_irq2;
}
+
+ ret = -ENOMEM;
+ floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock);
+ if (!floppy_queue)
+ goto out_queue;
+
+ ret = -ENXIO;
+ if (fd_probe_drives() < 1) /* No usable drives */
+ goto out_probe;
+
blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
floppy_find, NULL, NULL);
@@ -1804,17 +1802,6 @@ int __init amiga_floppy_init(void)
post_write_timer.data = 0;
post_write_timer.function = post_write;
- floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock);
- if (!floppy_queue) {
- free_irq(IRQ_AMIGA_CIAA_TB, NULL);
- free_irq(IRQ_AMIGA_DSKBLK, NULL);
- amiga_chip_free(raw_buf);
- release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
- unregister_blkdev(FLOPPY_MAJOR,"fd");
- blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
- return -ENOMEM;
- }
-
for (i = 0; i < 128; i++)
mfmdecode[i]=255;
for (i = 0; i < 16; i++)
@@ -1826,6 +1813,20 @@ int __init amiga_floppy_init(void)
/* init ms timer */
ciaa.crb = 8; /* one-shot, stop */
return 0;
+
+out_probe:
+ blk_cleanup_queue(floppy_queue);
+out_queue:
+ free_irq(IRQ_AMIGA_CIAA_TB, NULL);
+out_irq2:
+ free_irq(IRQ_AMIGA_DSKBLK, NULL);
+out_irq:
+ amiga_chip_free(raw_buf);
+out_memregion:
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
+out_blkdev:
+ unregister_blkdev(FLOPPY_MAJOR,"fd");
+ return ret;
}
#ifdef MODULE
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index e520c51d78cf..3d9c58788373 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -255,7 +255,7 @@ static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
{
as_del_arq_hash(arq);
- if (q->last_merge == &arq->request->queuelist)
+ if (q->last_merge == arq->request)
q->last_merge = NULL;
}
@@ -910,12 +910,7 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
struct as_rq *arq = RQ_DATA(rq);
struct as_io_context *aic;
- if (unlikely(!blk_fs_request(rq)))
- return;
-
- WARN_ON(blk_fs_request(rq) && arq->state == AS_RQ_NEW);
-
- if (arq->state != AS_RQ_DISPATCHED)
+ if (unlikely(arq->state != AS_RQ_DISPATCHED))
return;
if (ad->changed_batch && ad->nr_dispatched == 1) {
@@ -1035,7 +1030,7 @@ static void as_remove_request(request_queue_t *q, struct request *rq)
{
struct as_rq *arq = RQ_DATA(rq);
- if (unlikely(!blk_fs_request(rq)))
+ if (unlikely(arq->state == AS_RQ_NEW))
return;
if (!arq) {
@@ -1341,9 +1336,9 @@ static void as_requeue_request(request_queue_t *q, struct request *rq)
atomic_inc(&arq->io_context->aic->nr_dispatched);
} else
WARN_ON(blk_fs_request(rq)
- && (!(rq->flags & REQ_HARDBARRIER)) );
+ && (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) );
- list_add_tail(&rq->queuelist, ad->dispatch);
+ list_add(&rq->queuelist, ad->dispatch);
/* Stop anticipating - let this request get through */
as_antic_stop(ad);
@@ -1352,45 +1347,39 @@ static void as_requeue_request(request_queue_t *q, struct request *rq)
}
static void
-as_insert_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+as_insert_request(request_queue_t *q, struct request *rq, int where)
{
struct as_data *ad = q->elevator.elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (unlikely(rq->flags & REQ_HARDBARRIER)) {
- q->last_merge = NULL;
-
- while (ad->next_arq[REQ_SYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
-
- while (ad->next_arq[REQ_ASYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
- }
-
- if (unlikely(!blk_fs_request(rq))) {
- if (!insert_here)
- insert_here = ad->dispatch->prev;
-
- list_add(&rq->queuelist, insert_here);
-
- /* Stop anticipating - let this request get through */
- if (!list_empty(ad->dispatch)
- && (ad->antic_status == ANTIC_WAIT_REQ
- || ad->antic_status == ANTIC_WAIT_NEXT))
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
+ while (ad->next_arq[REQ_SYNC])
+ as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+
+ while (ad->next_arq[REQ_ASYNC])
+ as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+ list_add_tail(&rq->queuelist, ad->dispatch);
+ break;
+ case ELEVATOR_INSERT_FRONT:
+ list_add(&rq->queuelist, ad->dispatch);
as_antic_stop(ad);
-
- return;
+ break;
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ as_add_request(ad, arq);
+ break;
+ default:
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
}
if (rq_mergeable(rq)) {
as_add_arq_hash(ad, arq);
if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
-
- as_add_request(ad, arq);
}
/*
@@ -1438,7 +1427,7 @@ as_latter_request(request_queue_t *q, struct request *rq)
}
static int
-as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+as_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct as_data *ad = q->elevator.elevator_data;
sector_t rb_key = bio->bi_sector + bio_sectors(bio);
@@ -1450,7 +1439,7 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
*/
ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) {
- __rq = list_entry_rq(q->last_merge);
+ __rq = q->last_merge;
goto out_insert;
}
@@ -1482,11 +1471,11 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = &__rq->queuelist;
+ q->last_merge = __rq;
out_insert:
if (ret)
as_hot_arq_hash(ad, RQ_DATA(__rq));
- *insert = &__rq->queuelist;
+ *req = __rq;
return ret;
}
@@ -1514,7 +1503,7 @@ static void as_merged_request(request_queue_t *q, struct request *req)
*/
}
- q->last_merge = &req->queuelist;
+ q->last_merge = req;
}
static void
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 34b490615ce3..ce0927b36889 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2447,11 +2447,8 @@ static int __init cciss_init_one(struct pci_dev *pdev,
if( i < 0 )
return (-1);
if (cciss_pci_init(hba[i], pdev) != 0)
- {
- release_io_mem(hba[i]);
- free_hba(i);
- return (-1);
- }
+ goto clean1;
+
sprintf(hba[i]->devname, "cciss%d", i);
hba[i]->ctlr = i;
hba[i]->pdev = pdev;
@@ -2463,28 +2460,23 @@ static int __init cciss_init_one(struct pci_dev *pdev,
printk("cciss: not using DAC cycles\n");
else {
printk("cciss: no suitable DMA available\n");
- free_hba(i);
- return -ENODEV;
+ goto clean1;
}
if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) {
- release_io_mem(hba[i]);
- free_hba(i);
- return -1;
+ printk(KERN_ERR "cciss: Unable to register device %s\n",
+ hba[i]->devname);
+ goto clean1;
}
/* make sure the board interrupts are off */
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
if( request_irq(hba[i]->intr, do_cciss_intr,
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
- hba[i]->devname, hba[i]))
- {
- printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
+ hba[i]->devname, hba[i])) {
+ printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
hba[i]->intr, hba[i]->devname);
- unregister_blkdev( COMPAQ_CISS_MAJOR+i, hba[i]->devname);
- release_io_mem(hba[i]);
- free_hba(i);
- return(-1);
+ goto clean2;
}
hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(
@@ -2495,35 +2487,15 @@ static int __init cciss_init_one(struct pci_dev *pdev,
&(hba[i]->errinfo_pool_dhandle));
if((hba[i]->cmd_pool_bits == NULL)
|| (hba[i]->cmd_pool == NULL)
- || (hba[i]->errinfo_pool == NULL))
- {
-err_all:
- if(hba[i]->cmd_pool_bits)
- kfree(hba[i]->cmd_pool_bits);
- if(hba[i]->cmd_pool)
- pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(CommandList_struct),
- hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
- if(hba[i]->errinfo_pool)
- pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof( ErrorInfo_struct),
- hba[i]->errinfo_pool,
- hba[i]->errinfo_pool_dhandle);
- free_irq(hba[i]->intr, hba[i]);
- unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
- release_io_mem(hba[i]);
- free_hba(i);
+ || (hba[i]->errinfo_pool == NULL)) {
printk( KERN_ERR "cciss: out of memory");
- return(-1);
+ goto clean4;
}
- /*
- * someone needs to clean up this failure handling mess
- */
spin_lock_init(&hba[i]->lock);
q = blk_init_queue(do_cciss_request, &hba[i]->lock);
if (!q)
- goto err_all;
+ goto clean4;
hba[i]->queue = q;
q->queuedata = hba[i];
@@ -2576,6 +2548,26 @@ err_all:
add_disk(disk);
}
return(1);
+
+clean4:
+ if(hba[i]->cmd_pool_bits)
+ kfree(hba[i]->cmd_pool_bits);
+ if(hba[i]->cmd_pool)
+ pci_free_consistent(hba[i]->pdev,
+ NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
+ if(hba[i]->errinfo_pool)
+ pci_free_consistent(hba[i]->pdev,
+ NR_CMDS * sizeof( ErrorInfo_struct),
+ hba[i]->errinfo_pool,
+ hba[i]->errinfo_pool_dhandle);
+ free_irq(hba[i]->intr, hba[i]);
+clean2:
+ unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
+clean1:
+ release_io_mem(hba[i]);
+ free_hba(i);
+ return(-1);
}
static void __devexit cciss_remove_one (struct pci_dev *pdev)
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 66b11e3822e9..8bb37f65d536 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -33,13 +33,7 @@ static const int deadline_hash_shift = 5;
#define DL_HASH_ENTRIES (1 << deadline_hash_shift)
#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
#define list_entry_hash(ptr) list_entry((ptr), struct deadline_rq, hash)
-#define ON_HASH(drq) (drq)->hash_valid_count
-
-#define DL_INVALIDATE_HASH(dd) \
- do { \
- if (!++(dd)->hash_valid_count) \
- (dd)->hash_valid_count = 1; \
- } while (0)
+#define ON_HASH(drq) (drq)->on_hash
struct deadline_data {
/*
@@ -58,7 +52,6 @@ struct deadline_data {
struct deadline_rq *next_drq[2];
struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
- unsigned long hash_valid_count; /* barrier hash count */
unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */
unsigned int starved; /* times reads have starved writes */
@@ -90,7 +83,7 @@ struct deadline_rq {
* request hash, key is the ending offset (for back merge lookup)
*/
struct list_head hash;
- unsigned long hash_valid_count;
+ char on_hash;
/*
* expire fifo
@@ -110,7 +103,7 @@ static kmem_cache_t *drq_pool;
*/
static inline void __deadline_del_drq_hash(struct deadline_rq *drq)
{
- drq->hash_valid_count = 0;
+ drq->on_hash = 0;
list_del_init(&drq->hash);
}
@@ -125,7 +118,7 @@ deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
{
deadline_del_drq_hash(drq);
- if (q->last_merge == &drq->request->queuelist)
+ if (q->last_merge == drq->request)
q->last_merge = NULL;
}
@@ -136,7 +129,7 @@ deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
BUG_ON(ON_HASH(drq));
- drq->hash_valid_count = dd->hash_valid_count;
+ drq->on_hash = 1;
list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]);
}
@@ -169,8 +162,7 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
BUG_ON(!ON_HASH(drq));
- if (!rq_mergeable(__rq)
- || drq->hash_valid_count != dd->hash_valid_count) {
+ if (!rq_mergeable(__rq)) {
__deadline_del_drq_hash(drq);
continue;
}
@@ -324,7 +316,7 @@ static void deadline_remove_request(request_queue_t *q, struct request *rq)
}
static int
-deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct deadline_data *dd = q->elevator.elevator_data;
struct request *__rq;
@@ -335,7 +327,7 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
*/
ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) {
- __rq = list_entry_rq(q->last_merge);
+ __rq = q->last_merge;
goto out_insert;
}
@@ -371,11 +363,11 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = &__rq->queuelist;
+ q->last_merge = __rq;
out_insert:
if (ret)
deadline_hot_drq_hash(dd, RQ_DATA(__rq));
- *insert = &__rq->queuelist;
+ *req = __rq;
return ret;
}
@@ -398,7 +390,7 @@ static void deadline_merged_request(request_queue_t *q, struct request *req)
deadline_add_drq_rb(dd, drq);
}
- q->last_merge = &req->queuelist;
+ q->last_merge = req;
}
static void
@@ -621,39 +613,35 @@ dispatch:
}
static void
-deadline_insert_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+deadline_insert_request(request_queue_t *q, struct request *rq, int where)
{
struct deadline_data *dd = q->elevator.elevator_data;
struct deadline_rq *drq = RQ_DATA(rq);
- if (unlikely(rq->flags & REQ_HARDBARRIER)) {
- DL_INVALIDATE_HASH(dd);
- q->last_merge = NULL;
-
- while (deadline_dispatch_requests(dd))
- ;
-
- list_add_tail(&rq->queuelist, dd->dispatch);
- return;
- }
-
- if (unlikely(!blk_fs_request(rq))) {
- if (!insert_here)
- insert_here = dd->dispatch->prev;
-
- list_add(&rq->queuelist, insert_here);
- return;
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
+ while (deadline_dispatch_requests(dd))
+ ;
+ list_add_tail(&rq->queuelist, dd->dispatch);
+ break;
+ case ELEVATOR_INSERT_FRONT:
+ list_add(&rq->queuelist, dd->dispatch);
+ break;
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ deadline_add_request(dd, drq);
+ break;
+ default:
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
}
if (rq_mergeable(rq)) {
deadline_add_drq_hash(dd, drq);
if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
-
- deadline_add_request(dd, drq);
}
static int deadline_queue_empty(request_queue_t *q)
@@ -744,7 +732,6 @@ static int deadline_init(request_queue_t *q, elevator_t *e)
dd->dispatch = &q->queue_head;
dd->fifo_expire[READ] = read_expire;
dd->fifo_expire[WRITE] = write_expire;
- dd->hash_valid_count = 1;
dd->writes_starved = writes_starved;
dd->front_merges = 1;
dd->fifo_batch = fifo_batch;
@@ -775,7 +762,7 @@ deadline_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
drq->request = rq;
INIT_LIST_HEAD(&drq->hash);
- drq->hash_valid_count = 0;
+ drq->on_hash = 0;
INIT_LIST_HEAD(&drq->fifo);
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 246c39a4962e..fcb00cfa4fd7 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -81,7 +81,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
{
if (q->last_merge)
- return elv_try_merge(list_entry_rq(q->last_merge), bio);
+ return elv_try_merge(q->last_merge, bio);
return ELEVATOR_NO_MERGE;
}
@@ -117,12 +117,12 @@ int elevator_global_init(void)
return 0;
}
-int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio)
+int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = &q->elevator;
if (e->elevator_merge_fn)
- return e->elevator_merge_fn(q, entry, bio);
+ return e->elevator_merge_fn(q, req, bio);
return ELEVATOR_NO_MERGE;
}
@@ -140,7 +140,7 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
{
elevator_t *e = &q->elevator;
- if (q->last_merge == &next->queuelist)
+ if (q->last_merge == next)
q->last_merge = NULL;
if (e->elevator_merge_req_fn)
@@ -156,29 +156,25 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
if (q->elevator.elevator_requeue_req_fn)
q->elevator.elevator_requeue_req_fn(q, rq);
else
- __elv_add_request(q, rq, 0, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
}
-void __elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
- struct list_head *insert = &q->queue_head;
-
- if (at_end)
- insert = insert->prev;
if (plug)
blk_plug_device(q);
- q->elevator.elevator_add_req_fn(q, rq, insert);
+ q->elevator.elevator_add_req_fn(q, rq, where);
}
-void elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+void elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
- __elv_add_request(q, rq, at_end, plug);
+ __elv_add_request(q, rq, where, plug);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -200,7 +196,7 @@ struct request *elv_next_request(request_queue_t *q)
*/
rq->flags |= REQ_STARTED;
- if (&rq->queuelist == q->last_merge)
+ if (rq == q->last_merge)
q->last_merge = NULL;
if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
@@ -238,7 +234,7 @@ void elv_remove_request(request_queue_t *q, struct request *rq)
* deleted without ever being given to driver (merged with another
* request).
*/
- if (&rq->queuelist == q->last_merge)
+ if (rq == q->last_merge)
q->last_merge = NULL;
if (e->elevator_remove_req_fn)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 10566621eb81..b25acb42542e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4607,3 +4607,5 @@ MODULE_LICENSE("GPL");
__setup ("floppy=", floppy_setup);
module_init(floppy_init)
#endif
+
+MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 16a58ad04008..0cbabe9103d4 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -372,7 +372,7 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
disk_stat_read(disk, write_merges),
(unsigned long long)disk_stat_read(disk, write_sectors),
jiffies_to_msec(disk_stat_read(disk, write_ticks)),
- disk_stat_read(disk, in_flight),
+ disk->in_flight,
jiffies_to_msec(disk_stat_read(disk, io_ticks)),
jiffies_to_msec(disk_stat_read(disk, time_in_queue)));
}
@@ -492,7 +492,7 @@ static int diskstats_show(struct seq_file *s, void *v)
disk_stat_read(gp, writes), disk_stat_read(gp, write_merges),
(unsigned long long)disk_stat_read(gp, write_sectors),
jiffies_to_msec(disk_stat_read(gp, write_ticks)),
- disk_stat_read(gp, in_flight),
+ gp->in_flight,
jiffies_to_msec(disk_stat_read(gp, io_ticks)),
jiffies_to_msec(disk_stat_read(gp, time_in_queue)));
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index c403ba8429b3..541b45c519ef 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -703,7 +703,7 @@ void blk_queue_invalidate_tags(request_queue_t *q)
blk_queue_end_tag(q, rq);
rq->flags &= ~REQ_STARTED;
- __elv_add_request(q, rq, 0, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
}
}
@@ -1632,11 +1632,16 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
if(reinsert) {
blk_requeue_request(q, rq);
} else {
+ int where = ELEVATOR_INSERT_BACK;
+
+ if (at_head)
+ where = ELEVATOR_INSERT_FRONT;
+
if (blk_rq_tagged(rq))
blk_queue_end_tag(q, rq);
drive_stat_acct(rq, rq->nr_sectors, 1);
- __elv_add_request(q, rq, !at_head, 0);
+ __elv_add_request(q, rq, where, 0);
}
q->request_fn(q);
spin_unlock_irqrestore(q->queue_lock, flags);
@@ -1660,7 +1665,7 @@ void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
}
if (new_io) {
disk_round_stats(rq->rq_disk);
- disk_stat_inc(rq->rq_disk, in_flight);
+ rq->rq_disk->in_flight++;
}
}
@@ -1669,8 +1674,7 @@ void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
* queue lock is held and interrupts disabled, as we muck with the
* request queue list.
*/
-static inline void add_request(request_queue_t * q, struct request * req,
- struct list_head *insert_here)
+static inline void add_request(request_queue_t * q, struct request * req)
{
drive_stat_acct(req, req->nr_sectors, 1);
@@ -1681,7 +1685,7 @@ static inline void add_request(request_queue_t * q, struct request * req,
* elevator indicated where it wants this request to be
* inserted at elevator_merge time
*/
- __elv_add_request_pos(q, req, insert_here);
+ __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0);
}
/*
@@ -1704,10 +1708,10 @@ void disk_round_stats(struct gendisk *disk)
unsigned long now = jiffies;
disk_stat_add(disk, time_in_queue,
- disk_stat_read(disk, in_flight) * (now - disk->stamp));
+ disk->in_flight * (now - disk->stamp));
disk->stamp = now;
- if (disk_stat_read(disk, in_flight))
+ if (disk->in_flight)
disk_stat_add(disk, io_ticks, (now - disk->stamp_idle));
disk->stamp_idle = now;
}
@@ -1819,7 +1823,7 @@ static int attempt_merge(request_queue_t *q, struct request *req,
if (req->rq_disk) {
disk_round_stats(req->rq_disk);
- disk_stat_dec(req->rq_disk, in_flight);
+ req->rq_disk->in_flight--;
}
__blk_put_request(q, next);
@@ -1880,7 +1884,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req, *freereq = NULL;
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, ra;
- struct list_head *insert_here;
sector_t sector;
sector = bio->bi_sector;
@@ -1903,7 +1906,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
ra = bio->bi_rw & (1 << BIO_RW_AHEAD);
again:
- insert_here = NULL;
spin_lock_irq(q->queue_lock);
if (elv_queue_empty(q)) {
@@ -1913,17 +1915,13 @@ again:
if (barrier)
goto get_rq;
- el_ret = elv_merge(q, &insert_here, bio);
+ el_ret = elv_merge(q, &req, bio);
switch (el_ret) {
case ELEVATOR_BACK_MERGE:
- req = list_entry_rq(insert_here);
-
BUG_ON(!rq_mergeable(req));
- if (!q->back_merge_fn(q, req, bio)) {
- insert_here = &req->queuelist;
+ if (!q->back_merge_fn(q, req, bio))
break;
- }
req->biotail->bi_next = bio;
req->biotail = bio;
@@ -1934,14 +1932,10 @@ again:
goto out;
case ELEVATOR_FRONT_MERGE:
- req = list_entry_rq(insert_here);
-
BUG_ON(!rq_mergeable(req));
- if (!q->front_merge_fn(q, req, bio)) {
- insert_here = req->queuelist.prev;
+ if (!q->front_merge_fn(q, req, bio))
break;
- }
bio->bi_next = req->bio;
req->cbio = req->bio = bio;
@@ -2029,7 +2023,7 @@ get_rq:
req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies;
- add_request(q, req, insert_here);
+ add_request(q, req);
out:
if (freereq)
__blk_put_request(q, freereq);
@@ -2480,7 +2474,7 @@ void end_that_request_last(struct request *req)
break;
}
disk_round_stats(disk);
- disk_stat_dec(disk, in_flight);
+ disk->in_flight--;
}
__blk_put_request(req->q, req);
/* Do this LAST! The structure may be freed immediately afterwards */
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
index 2eadd041914b..7511b955de70 100644
--- a/drivers/block/noop-iosched.c
+++ b/drivers/block/noop-iosched.c
@@ -17,17 +17,15 @@
/*
* See if we can find a request that this buffer can be coalesced with.
*/
-int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
+int elevator_noop_merge(request_queue_t *q, struct request **req,
struct bio *bio)
{
struct list_head *entry = &q->queue_head;
struct request *__rq;
int ret;
- if ((ret = elv_try_last_merge(q, bio))) {
- *insert = q->last_merge;
+ if ((ret = elv_try_last_merge(q, bio)))
return ret;
- }
while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry);
@@ -41,8 +39,8 @@ int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
continue;
if ((ret = elv_try_merge(__rq, bio))) {
- *insert = &__rq->queuelist;
- q->last_merge = &__rq->queuelist;
+ *req = __rq;
+ q->last_merge = __rq;
return ret;
}
}
@@ -57,8 +55,13 @@ void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
}
void elevator_noop_add_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+ int where)
{
+ struct list_head *insert = q->queue_head.prev;
+
+ if (where == ELEVATOR_INSERT_FRONT)
+ insert = &q->queue_head;
+
list_add_tail(&rq->queuelist, &q->queue_head);
/*
@@ -67,7 +70,7 @@ void elevator_noop_add_request(request_queue_t *q, struct request *rq,
if (rq->flags & REQ_HARDBARRIER)
q->last_merge = NULL;
else if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
struct request *elevator_noop_next_request(request_queue_t *q)
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
index 94574b14f30b..3d18a7a70108 100644
--- a/drivers/block/scsi_ioctl.c
+++ b/drivers/block/scsi_ioctl.c
@@ -68,7 +68,7 @@ static int blk_do_rq(request_queue_t *q, struct block_device *bdev,
rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
- elv_add_request(q, rq, 1, 1);
+ elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
generic_unplug_device(q);
wait_for_completion(&wait);
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 8b4972feca71..dc06ce7adfa6 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -1103,5 +1103,5 @@ __setup ("xd_geo=", xd_manual_geo_init);
#endif /* MODULE */
-module_init(xd_init)
-
+module_init(xd_init);
+MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index dfd1e73e611a..4943401d71b0 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -574,3 +574,4 @@ module_exit(hci_uart_cleanup);
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_HCI);
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 969945a7bdb4..8503b193aea5 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -2499,3 +2499,4 @@ static int azt_bcd2bin(unsigned char bcd)
}
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 379b454684dd..5a30990de102 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -3500,3 +3500,4 @@ module_init(cdu31a_init);
module_exit(cdu31a_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index 22464a5fd19a..c462db3b81ce 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -1616,7 +1616,7 @@ static int __init cm206_setup(char *s)
__setup("cm206=", cm206_setup);
#endif /* !MODULE */
-
+MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
/*
* Local variables:
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
index b24979c1104b..111f020de66e 100644
--- a/drivers/cdrom/gscd.c
+++ b/drivers/cdrom/gscd.c
@@ -1029,3 +1029,4 @@ MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
MODULE_LICENSE("GPL");
module_init(gscd_init);
module_exit(gscd_exit);
+MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
index e17822236df4..33b35e30e619 100644
--- a/drivers/cdrom/mcd.c
+++ b/drivers/cdrom/mcd.c
@@ -1559,3 +1559,4 @@ module_exit(mcd_exit);
MODULE_AUTHOR("Martin Harriss");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index 70719df8305d..ba4700ddbb0f 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -1970,3 +1970,4 @@ static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
}
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
index c435e22f9fde..7e9758fe7045 100644
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -2102,3 +2102,4 @@ module_init(optcd_init);
module_exit(optcd_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR);
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index c57a5d82fef1..df865505d369 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -5954,6 +5954,9 @@ static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
}
MODULE_LICENSE("GPL");
+/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but
+ AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */
+MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR);
/*==========================================================================*/
/*
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index ae6a8237d063..1c8362764e1a 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -1813,3 +1813,4 @@ module_init(sjcd_init);
module_exit(sjcd_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR);
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
index 2422038cc059..1467c9311000 100644
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -1684,3 +1684,4 @@ module_exit(sony535_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR);
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 0ba95771e9e1..8280faa7ee9e 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -331,6 +331,7 @@ __setup("agp=", agp_setup);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION("AGP GART driver");
MODULE_LICENSE("GPL and additional rights");
+MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
module_init(agp_init);
module_exit(agp_exit);
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 6ff8d157fc6d..ef1fa6db9570 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -1097,4 +1097,3 @@ void agp_frontend_cleanup(void)
{
misc_deregister(&agp_miscdev);
}
-
diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c
index 126d77f8a215..b0416f721054 100644
--- a/drivers/char/busmouse.c
+++ b/drivers/char/busmouse.c
@@ -452,4 +452,5 @@ EXPORT_SYMBOL(busmouse_add_buttons);
EXPORT_SYMBOL(register_busmouse);
EXPORT_SYMBOL(unregister_busmouse);
+MODULE_ALIAS_MISCDEV(BUSMOUSE_MINOR);
MODULE_LICENSE("GPL");
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 46be7a8ac3d3..56ffc3965d76 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -965,4 +965,5 @@ __setup("lp=", lp_setup);
module_init(lp_init_module);
module_exit(lp_cleanup_module);
+MODULE_ALIAS("char-major-" __stringify(LP_MAJOR));
MODULE_LICENSE("GPL");
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 8ff16b5d21ac..3dcbbf2188be 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -982,3 +982,4 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
MODULE_PARM(debuglevel, "i");
MODULE_PARM(maxframe, "i");
+MODULE_ALIAS_LDISC(N_HDLC);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 4eae5e465df5..9c7be47fb6a4 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1428,4 +1428,4 @@ static int r3964_receive_room(struct tty_struct *tty)
MODULE_LICENSE("GPL");
-
+MODULE_ALIAS_LDISC(N_R3964);
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 96daf9d5d80e..7b6ee59edf08 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -923,3 +923,4 @@ EXPORT_SYMBOL(__nvram_check_checksum);
EXPORT_SYMBOL(nvram_check_checksum);
EXPORT_SYMBOL(__nvram_set_checksum);
EXPORT_SYMBOL(nvram_set_checksum);
+MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 3ecc2b9a666e..e14a3ce8928d 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/pcmcia/synclink_cs.c
*
- * $Id: synclink_cs.c,v 4.13 2003/06/18 15:29:32 paulkf Exp $
+ * $Id: synclink_cs.c,v 4.15 2003/09/05 15:26:02 paulkf Exp $
*
* Device driver for Microgate SyncLink PC Card
* multiprotocol serial adapter.
@@ -491,7 +491,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
MODULE_LICENSE("GPL");
static char *driver_name = "SyncLink PC Card driver";
-static char *driver_version = "$Revision: 4.13 $";
+static char *driver_version = "$Revision: 4.15 $";
static struct tty_driver *serial_driver;
@@ -838,6 +838,9 @@ static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index f91f50897543..85fa5d9503cb 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -354,7 +354,7 @@ int __init pty_init(void)
pty_slave_driver->init_termios = tty_std_termios;
pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS |
- TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+ TTY_DRIVER_REAL_RAW;
pty_slave_driver->other = pty_driver;
tty_set_operations(pty_slave_driver, &pty_ops);
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 0ee79ab3d93a..96221c5601c3 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1036,7 +1036,6 @@ static int rc_open(struct tty_struct * tty, struct file * filp)
int error;
struct riscom_port * port;
struct riscom_board * bp;
- unsigned long flags;
board = RC_BOARD(tty->index);
if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 309a173c821d..fcdc4eb0b9ac 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -137,7 +137,6 @@ static int rtc_ioctl(struct inode *inode, struct file *file,
static unsigned int rtc_poll(struct file *file, poll_table *wait);
#endif
-void get_rtc_time (struct rtc_time *rtc_tm);
static void get_rtc_alm_time (struct rtc_time *alm_tm);
#if RTC_IRQ
static void rtc_dropped_irq(unsigned long data);
@@ -482,7 +481,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
}
case RTC_RD_TIME: /* Read the time/date from RTC */
{
- get_rtc_time(&wtime);
+ rtc_get_rtc_time(&wtime);
break;
}
case RTC_SET_TIME: /* Set the RTC */
@@ -1119,7 +1118,7 @@ static int rtc_proc_output (char *buf)
p = buf;
- get_rtc_time(&tm);
+ rtc_get_rtc_time(&tm);
/*
* There is no way to tell if the luser has the RTC set for local
@@ -1206,7 +1205,7 @@ static inline unsigned char rtc_is_updating(void)
return uip;
}
-void get_rtc_time(struct rtc_time *rtc_tm)
+void rtc_get_rtc_time(struct rtc_time *rtc_tm)
{
unsigned long uip_watchdog = jiffies;
unsigned char ctrl;
@@ -1346,3 +1345,4 @@ static void set_rtc_irq_bit(unsigned char bit)
MODULE_AUTHOR("Paul Gortmaker");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(RTC_MINOR);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index bf80e670091d..e55e9abb184d 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.12 2003/06/18 15:29:32 paulkf Exp $
+ * $Id: synclink.c,v 4.16 2003/09/05 15:26:02 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -261,6 +261,7 @@ struct mgsl_struct {
int rx_enabled;
int rx_overflow;
+ int rx_rcc_underrun;
int tx_enabled;
int tx_active;
@@ -910,7 +911,7 @@ MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.12 $";
+static char *driver_version = "$Revision: 4.16 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
@@ -983,6 +984,9 @@ static inline int mgsl_paranoia_check(struct mgsl_struct *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
@@ -1125,7 +1129,16 @@ void mgsl_bh_receive(struct mgsl_struct *info)
printk( "%s(%d):mgsl_bh_receive(%s)\n",
__FILE__,__LINE__,info->device_name);
- while( (get_rx_frame)(info) );
+ do
+ {
+ if (info->rx_rcc_underrun) {
+ unsigned long flags;
+ spin_lock_irqsave(&info->irq_spinlock,flags);
+ usc_start_receiver(info);
+ spin_unlock_irqrestore(&info->irq_spinlock,flags);
+ return;
+ }
+ } while(get_rx_frame(info));
}
void mgsl_bh_transmit(struct mgsl_struct *info)
@@ -1567,6 +1580,21 @@ void mgsl_isr_misc( struct mgsl_struct *info )
printk("%s(%d):mgsl_isr_misc status=%04X\n",
__FILE__,__LINE__,status);
+ if ((status & MISCSTATUS_RCC_UNDERRUN) &&
+ (info->params.mode == MGSL_MODE_HDLC)) {
+
+ /* turn off receiver and rx DMA */
+ usc_EnableReceiver(info,DISABLE_UNCONDITIONAL);
+ usc_DmaCmd(info, DmaCmd_ResetRxChannel);
+ usc_UnlatchRxstatusBits(info, RXSTATUS_ALL);
+ usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS);
+ usc_DisableInterrupts(info, RECEIVE_DATA + RECEIVE_STATUS);
+
+ /* schedule BH handler to restart receiver */
+ info->pending_bh |= BH_RECEIVE;
+ info->rx_rcc_underrun = 1;
+ }
+
usc_ClearIrqPendingBits( info, MISC );
usc_UnlatchMiscstatusBits( info, status );
@@ -3625,7 +3653,7 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
if (info->icount.rxover)
ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+ ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
} else {
ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
@@ -5190,7 +5218,11 @@ void usc_set_sdlc_mode( struct mgsl_struct *info )
usc_EnableMasterIrqBit( info );
usc_ClearIrqPendingBits( info, RECEIVE_STATUS + RECEIVE_DATA +
- TRANSMIT_STATUS + TRANSMIT_DATA );
+ TRANSMIT_STATUS + TRANSMIT_DATA + MISC);
+
+ /* arm RCC underflow interrupt */
+ usc_OutReg(info, SICR, (u16)(usc_InReg(info,SICR) | BIT3));
+ usc_EnableInterrupts(info, MISC);
info->mbre_bit = 0;
outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */
@@ -5628,6 +5660,7 @@ void usc_stop_receiver( struct mgsl_struct *info )
info->rx_enabled = 0;
info->rx_overflow = 0;
+ info->rx_rcc_underrun = 0;
} /* end of stop_receiver() */
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index ae3d9c41b668..587dcb3a669d 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1,5 +1,5 @@
/*
- * $Id: synclinkmp.c,v 4.12 2003/06/18 15:29:33 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.14 2003/09/05 15:26:03 paulkf Exp $
*
* Device driver for Microgate SyncLink Multiport
* high speed multiprotocol serial adapter.
@@ -496,7 +496,7 @@ MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.12 $";
+static char *driver_version = "$Revision: 4.14 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -713,6 +713,9 @@ static inline int sanity_check(SLMP_INFO *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index b855ef565272..98cac9f1211e 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -57,12 +57,7 @@ static spinlock_t wafwdt_lock;
*/
static int wdt_stop = 0x843;
-module_param(wdt_stop, int, 0);
-MODULE_PARM_DESC(wdt_stop, "Wafer 5823 WDT 'stop' io port (default 0x843)");
-
static int wdt_start = 0x443;
-module_param(wdt_start, int, 0);
-MODULE_PARM_DESC(wdt_start, "Wafer 5823 WDT 'start' io port (default 0x443)");
static int timeout = WD_TIMO; /* in seconds */
module_param(timeout, int, 0);
@@ -269,7 +264,7 @@ static int __init wafwdt_init(void)
spin_lock_init(&wafwdt_lock);
- if (timeout < 1 || timeout > 63) {
+ if (timeout < 1 || timeout > 255) {
timeout = WD_TIMO;
printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n",
timeout);
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index e1760847f6d3..989a5a89a2ab 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -579,4 +579,6 @@ module_exit(wdt_exit);
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS_MISCDEV(TEMP_MINOR);
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 17f00f61c3ac..1dcd06f98144 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -835,6 +835,13 @@ config BLK_DEV_IDEDMA_PMAC
to transfer data to and from memory. Saying Y is safe and improves
performance.
+config BLK_DEV_IDE_PMAC_BLINK
+ bool "Blink laptop LED on drive activity"
+ depends on BLK_DEV_IDE_PMAC && ADB_PMU
+ help
+ This option enables the use of the sleep LED as a hard drive
+ activity LED.
+
config BLK_DEV_IDEDMA_PMAC_AUTO
bool "Use DMA by default"
depends on BLK_DEV_IDEDMA_PMAC
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 578476e1e931..fd5874b891db 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3318,7 +3318,6 @@ static ide_driver_t ide_cdrom_driver = {
.version = IDECD_VERSION,
.media = ide_cdrom,
.busy = 0,
- .supports_dma = 1,
.supports_dsc_overlap = 1,
.cleanup = ide_cdrom_cleanup,
.do_request = ide_do_rw_cdrom,
diff --git a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
index 40ecc4de0c05..0c251121a740 100644
--- a/drivers/ide/ide-default.c
+++ b/drivers/ide/ide-default.c
@@ -40,18 +40,12 @@ static int idedefault_attach(ide_drive_t *drive);
/*
* IDE subdriver functions, registered with ide.c
- *
- * idedefault *must* support DMA because it will be
- * attached before the other drivers are loaded and
- * we don't want to lose the DMA status at probe
- * time.
*/
ide_driver_t idedefault_driver = {
.name = "ide-default",
.version = IDEDEFAULT_VERSION,
.attach = idedefault_attach,
- .supports_dma = 1,
.drives = LIST_HEAD_INIT(idedefault_driver.drives)
};
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 1217e840ac02..8bf402224197 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1689,7 +1689,8 @@ static void idedisk_setup (ide_drive_t *drive)
write_cache(drive, (id->cfs_enable_2 & 0x3000));
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
- HWIF(drive)->ide_dma_queued_on(drive);
+ if (drive->using_dma)
+ HWIF(drive)->ide_dma_queued_on(drive);
#endif
}
@@ -1716,7 +1717,6 @@ static ide_driver_t idedisk_driver = {
.version = IDEDISK_VERSION,
.media = ide_disk,
.busy = 0,
- .supports_dma = 1,
.supports_dsc_overlap = 0,
.cleanup = idedisk_cleanup,
.flushcache = do_idedisk_flushcache,
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 112dc8b8676d..4a2a7273b8b4 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1854,7 +1854,6 @@ static ide_driver_t idefloppy_driver = {
.version = IDEFLOPPY_VERSION,
.media = ide_floppy,
.busy = 0,
- .supports_dma = 1,
.supports_dsc_overlap = 0,
.cleanup = idefloppy_cleanup,
.do_request = idefloppy_do_request,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2b94c9450336..0d9fff1f883d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1387,7 +1387,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
DECLARE_COMPLETION(wait);
- int insert_end = 1, err;
+ int where = ELEVATOR_INSERT_BACK, err;
int must_wait = (action == ide_wait || action == ide_head_wait);
#ifdef CONFIG_BLK_DEV_PDC4030
@@ -1419,10 +1419,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
spin_lock_irqsave(&ide_lock, flags);
if (action == ide_preempt || action == ide_head_wait) {
hwgroup->rq = NULL;
- insert_end = 0;
+ where = ELEVATOR_INSERT_FRONT;
rq->flags |= REQ_PREEMPT;
}
- __elv_add_request(drive->queue, rq, insert_end, 0);
+ __elv_add_request(drive->queue, rq, where, 0);
ide_do_request(hwgroup, IDE_NO_IRQ);
spin_unlock_irqrestore(&ide_lock, flags);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index cb18ac6fa2b7..ef80249cda49 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -958,6 +958,10 @@ static int ide_init_queue(ide_drive_t *drive)
/* needs drive->queue to be set */
ide_toggle_bounce(drive, 1);
+ /* enable led activity for disk drives only */
+ if (drive->media == ide_disk && hwif->led_act)
+ blk_queue_activity_fn(q, hwif->led_act, drive);
+
return 0;
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index e2bdaa457727..6c8c067df5a7 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -6316,7 +6316,6 @@ static ide_driver_t idetape_driver = {
.version = IDETAPE_VERSION,
.media = ide_tape,
.busy = 1,
- .supports_dma = 1,
.supports_dsc_overlap = 1,
.cleanup = idetape_cleanup,
.do_request = idetape_do_request,
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8ff22ad3f648..b6b7c97bf090 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1359,8 +1359,6 @@ static int set_io_32bit(ide_drive_t *drive, int arg)
static int set_using_dma (ide_drive_t *drive, int arg)
{
- if (!DRIVER(drive)->supports_dma)
- return -EPERM;
if (!drive->id || !(drive->id->capability & 1))
return -EPERM;
if (HWIF(drive)->ide_dma_check == NULL)
@@ -2406,6 +2404,13 @@ static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg)
return ide_abort(drive, msg);
}
+static ide_startstop_t default_start_power_step(ide_drive_t *drive,
+ struct request *rq)
+{
+ rq->pm->pm_step = ide_pm_state_completed;
+ return ide_stopped;
+}
+
static void setup_driver_defaults (ide_driver_t *d)
{
if (d->cleanup == NULL) d->cleanup = default_cleanup;
@@ -2420,6 +2425,8 @@ static void setup_driver_defaults (ide_driver_t *d)
if (d->capacity == NULL) d->capacity = default_capacity;
if (d->special == NULL) d->special = default_special;
if (d->attach == NULL) d->attach = default_attach;
+ if (d->start_power_step == NULL)
+ d->start_power_step = default_start_power_step;
}
int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int version)
@@ -2443,9 +2450,6 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
if ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO)) {
/* DMA timings and setup moved to ide-probe.c */
- if (!driver->supports_dma && HWIF(drive)->ide_dma_off_quietly)
-// HWIF(drive)->ide_dma_off_quietly(drive);
- HWIF(drive)->ide_dma_off(drive);
drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
drive->nice1 = 1;
}
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index fdfc45505db7..0bce7cd0427d 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -140,6 +140,7 @@ static struct pci_device_id generic_pci_tbl[] = {
{ PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
{ 0, },
};
diff --git a/drivers/ide/pci/generic.h b/drivers/ide/pci/generic.h
index 38b8c72f5966..3898e2f85f95 100644
--- a/drivers/ide/pci/generic.h
+++ b/drivers/ide/pci/generic.h
@@ -127,6 +127,19 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD,
.extra = 0,
+ },{ /* 9 */
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8237_SATA,
+ .name = "VIA8237SATA",
+ .init_chipset = init_chipset_generic,
+ .init_iops = NULL,
+ .init_hwif = init_hwif_generic,
+ .init_dma = init_dma_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+ .bootable = OFF_BOARD,
+ .extra = 0,
},{
.vendor = 0,
.device = 0,
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 4bcd3bb1a1f5..3ab58903e6a0 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -748,9 +748,6 @@ static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
hwif->tuneproc = &config_chipset_for_pio;
hwif->quirkproc = &pdc202xx_quirkproc;
- if (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265)
- hwif->no_lba48 = (hwif->channel) ? 0 : 1;
-
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
hwif->busproc = &pdc202xx_tristate;
hwif->resetproc = &pdc202xx_reset;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 8ba89df109fa..c7e6774242c3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -582,6 +582,7 @@ void i8042_controller_cleanup(void)
static int __init i8042_check_mux(struct i8042_values *values)
{
unsigned char param;
+ static int i8042_check_mux_cookie;
int i;
/*
@@ -589,9 +590,9 @@ static int __init i8042_check_mux(struct i8042_values *values)
*/
if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ,
- "i8042", i8042_request_irq_cookie))
+ "i8042", &i8042_check_mux_cookie))
return -1;
- free_irq(values->irq, i8042_request_irq_cookie);
+ free_irq(values->irq, &i8042_check_mux_cookie);
/*
* Get rid of bytes in the queue.
@@ -654,6 +655,7 @@ static int __init i8042_check_mux(struct i8042_values *values)
static int __init i8042_check_aux(struct i8042_values *values)
{
unsigned char param;
+ static int i8042_check_aux_cookie;
/*
* Check if AUX irq is available. If it isn't, then there is no point
@@ -661,9 +663,9 @@ static int __init i8042_check_aux(struct i8042_values *values)
*/
if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ,
- "i8042", i8042_request_irq_cookie))
+ "i8042", &i8042_check_aux_cookie))
return -1;
- free_irq(values->irq, i8042_request_irq_cookie);
+ free_irq(values->irq, &i8042_check_aux_cookie);
/*
* Get rid of bytes in the queue.
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 65b8dbcc0bce..c66ccbf9c037 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -24,6 +24,7 @@
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Input device TTY line discipline");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_MOUSE);
#define SERPORT_BUSY 1
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 2bf1a17b6c0f..8404fefda237 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -412,7 +412,7 @@ gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
{
struct sk_buff *nskb;
- unsigned int datalen;
+ int datalen;
u16 errcode, datahandle;
datalen = skb->len - CAPIMSG_LEN(skb->data);
@@ -552,12 +552,12 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
struct capincci *np;
u32 ncci;
- if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) {
+ if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0)
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
}
- if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_IND) {
+ if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
}
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
@@ -688,7 +688,7 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
}
mlen = CAPIMSG_LEN(skb->data);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
- if (mlen + CAPIMSG_DATALEN(skb->data) != count) {
+ if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
kfree_skb(skb);
return -EINVAL;
}
@@ -700,7 +700,7 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
}
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
- if (CAPIMSG_COMMAND(skb->data) == CAPI_DISCONNECT_B3_RESP) {
+ if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
}
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 8ea64ec7eea3..cdd1b90334ce 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -48,7 +48,7 @@ MODULE_PARM(debugmode, "i");
struct capidrv_contr {
struct capidrv_contr *next;
-
+ struct module *owner;
u32 contrnr;
char name[20];
@@ -1816,7 +1816,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
capidrv_bchan *bchan;
capidrv_ncci *nccip;
int len = skb->len;
- size_t msglen;
+ int msglen;
u16 errcode;
u16 datahandle;
@@ -1844,7 +1844,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
0 /* Flags */
);
- if (capidrv_add_ack(nccip, datahandle, doack ? skb->len : -1) < 0)
+ if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
return 0;
capi_cmsg2message(&sendcmsg, sendcmsg.buf);
@@ -1990,16 +1990,19 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
char id[20];
int i;
- MOD_INC_USE_COUNT;
-
sprintf(id, "capidrv-%d", contr);
if (!(card = (capidrv_contr *) kmalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
printk(KERN_WARNING
"capidrv: (%s) Could not allocate contr-struct.\n", id);
- MOD_DEC_USE_COUNT;
return -1;
}
memset(card, 0, sizeof(capidrv_contr));
+ card->owner = THIS_MODULE;
+ if (!try_module_get(card->owner)) {
+ printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
+ kfree(card);
+ return -1;
+ }
init_timer(&card->listentimer);
strcpy(card->name, id);
card->contrnr = contr;
@@ -2008,8 +2011,8 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
if (!card->bchans) {
printk(KERN_WARNING
"capidrv: (%s) Could not allocate bchan-structs.\n", id);
+ module_put(card->owner);
kfree(card);
- MOD_DEC_USE_COUNT;
return -1;
}
card->interface.channels = profp->nbchannel;
@@ -2042,8 +2045,8 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
if (!register_isdn(&card->interface)) {
printk(KERN_ERR "capidrv: Unable to register contr %s\n", id);
kfree(card->bchans);
+ module_put(card->owner);
kfree(card);
- MOD_DEC_USE_COUNT;
return -1;
}
card->myid = card->interface.channels;
@@ -2153,12 +2156,9 @@ static int capidrv_delcontr(u16 contr)
}
spin_unlock_irqrestore(&global_lock, flags);
+ module_put(card->owner);
printk(KERN_INFO "%s: now down.\n", card->name);
-
kfree(card);
-
- MOD_DEC_USE_COUNT;
-
return 0;
}
@@ -2245,8 +2245,6 @@ static int __init capidrv_init(void)
u32 ncontr, contr;
u16 errcode;
- MOD_INC_USE_COUNT;
-
if ((p = strchr(revision, ':')) != 0 && p[1]) {
strncpy(rev, p + 2, sizeof(rev));
rev[sizeof(rev)-1] = 0;
@@ -2262,7 +2260,6 @@ static int __init capidrv_init(void)
global.ap.recv_message = capidrv_recv_message;
errcode = capi20_register(&global.ap);
if (errcode) {
- MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -2271,7 +2268,6 @@ static int __init capidrv_init(void)
errcode = capi20_get_profile(0, &profile);
if (errcode != CAPI_NOERROR) {
capi20_release(&global.ap);
- MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -2285,8 +2281,6 @@ static int __init capidrv_init(void)
proc_init();
printk(KERN_NOTICE "capidrv: Rev %s: loaded\n", rev);
- MOD_DEC_USE_COUNT;
-
return 0;
}
diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c
index f9b33ffb8290..00d8795b9cc7 100644
--- a/drivers/isdn/capi/capilib.c
+++ b/drivers/isdn/capi/capilib.c
@@ -29,7 +29,7 @@ struct capilib_ncci {
static inline void mq_init(struct capilib_ncci * np)
{
- int i;
+ u_int i;
np->msgidqueue = 0;
np->msgidlast = 0;
np->nmsg = 0;
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index c59fe4fc0211..b78f7b1dc021 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -72,7 +72,7 @@ static struct sk_buff_head recv_queue;
static struct work_struct tq_state_notify;
static struct work_struct tq_recv_notify;
-/* -------- ref counting -------------------------------------- */
+/* -------- controller ref counting -------------------------------------- */
static inline struct capi_ctr *
capi_ctr_get(struct capi_ctr *card)
@@ -89,6 +89,21 @@ capi_ctr_put(struct capi_ctr *card)
DBG("MOD_COUNT DEC");
}
+/* -------- own ref counting -------------------------------------- */
+
+static inline void
+kcapi_get_ref(void)
+{
+ if (!try_module_get(THIS_MODULE))
+ printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+}
+
+static inline void
+kcapi_put_ref(void)
+{
+ module_put(THIS_MODULE);
+}
+
/* ------------------------------------------------------------- */
static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
@@ -209,10 +224,10 @@ static int notify_push(unsigned int cmd, u32 controller,
{
struct capi_notifier *np;
- MOD_INC_USE_COUNT;
+ kcapi_get_ref();
np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC);
if (!np) {
- MOD_DEC_USE_COUNT;
+ kcapi_put_ref();
return -1;
}
memset(np, 0, sizeof(struct capi_notifier));
@@ -226,9 +241,9 @@ static int notify_push(unsigned int cmd, u32 controller,
* of devices. Devices can only removed in
* user process, not in bh.
*/
- MOD_INC_USE_COUNT;
+ kcapi_get_ref();
if (schedule_work(&tq_state_notify) == 0)
- MOD_DEC_USE_COUNT;
+ kcapi_put_ref();
return 0;
}
@@ -286,9 +301,9 @@ static void notify_handler(void *dummy)
while ((np = notify_dequeue()) != 0) {
notify_doit(np);
kfree(np);
- MOD_DEC_USE_COUNT;
+ kcapi_put_ref();
}
- MOD_DEC_USE_COUNT;
+ kcapi_put_ref();
}
/* -------- Receiver ------------------------------------------ */
@@ -626,19 +641,18 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
EXPORT_SYMBOL(capi20_put_message);
-u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
+u16 capi20_get_manufacturer(u32 contr, u8 *buf)
{
struct capi_ctr *card;
if (contr == 0) {
- strlcpy(buf, capi_manufakturer, sizeof(buf));
+ strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR;
}
card = get_capi_ctr_by_nr(contr);
if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
-
- strlcpy(buf, card->manu, sizeof(buf));
+ strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR;
}
@@ -662,19 +676,19 @@ u16 capi20_get_version(u32 contr, struct capi_version *verp)
EXPORT_SYMBOL(capi20_get_version);
-u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
+u16 capi20_get_serial(u32 contr, u8 *serial)
{
struct capi_ctr *card;
if (contr == 0) {
- strlcpy(serial, driver_serial, sizeof(serial));
+ strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR;
}
card = get_capi_ctr_by_nr(contr);
if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
- strlcpy((void *) serial, card->serial, sizeof(serial));
+ strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR;
}
diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h
index 84b73da5d1bf..1a0ca874e882 100644
--- a/drivers/isdn/hardware/avm/avmcard.h
+++ b/drivers/isdn/hardware/avm/avmcard.h
@@ -95,8 +95,8 @@ typedef struct avmcard {
struct avmctrl_info *ctrlinfo;
- int nr_controllers;
- int nlogcontr;
+ u_int nr_controllers;
+ u_int nlogcontr;
struct list_head list;
} avmcard;
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index b056d619af93..22894a9a72e1 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -148,30 +148,31 @@ void b1_getrevision(avmcard *card)
card->revision = inb(card->port + B1_REVISION);
}
+#define FWBUF_SIZE 256
int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
{
- unsigned char buf[256];
+ unsigned char buf[FWBUF_SIZE];
unsigned char *dp;
int i, left;
unsigned int base = card->port;
dp = t4file->data;
left = t4file->len;
- while (left > sizeof(buf)) {
+ while (left > FWBUF_SIZE) {
if (t4file->user) {
- if (copy_from_user(buf, dp, sizeof(buf)))
+ if (copy_from_user(buf, dp, FWBUF_SIZE))
return -EFAULT;
} else {
- memcpy(buf, dp, sizeof(buf));
+ memcpy(buf, dp, FWBUF_SIZE);
}
- for (i = 0; i < sizeof(buf); i++)
+ for (i = 0; i < FWBUF_SIZE; i++)
if (b1_save_put_byte(base, buf[i]) < 0) {
printk(KERN_ERR "%s: corrupted firmware file ?\n",
card->name);
return -EIO;
}
- left -= sizeof(buf);
- dp += sizeof(buf);
+ left -= FWBUF_SIZE;
+ dp += FWBUF_SIZE;
}
if (left) {
if (t4file->user) {
@@ -192,7 +193,7 @@ int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
int b1_load_config(avmcard *card, capiloaddatapart * config)
{
- unsigned char buf[256];
+ unsigned char buf[FWBUF_SIZE];
unsigned char *dp;
unsigned int base = card->port;
int i, j, left;
@@ -205,21 +206,21 @@ int b1_load_config(avmcard *card, capiloaddatapart * config)
b1_put_byte(base, SEND_CONFIG);
b1_put_word(base, left);
}
- while (left > sizeof(buf)) {
+ while (left > FWBUF_SIZE) {
if (config->user) {
- if (copy_from_user(buf, dp, sizeof(buf)))
+ if (copy_from_user(buf, dp, FWBUF_SIZE))
return -EFAULT;
} else {
- memcpy(buf, dp, sizeof(buf));
+ memcpy(buf, dp, FWBUF_SIZE);
}
- for (i = 0; i < sizeof(buf); ) {
+ for (i = 0; i < FWBUF_SIZE; ) {
b1_put_byte(base, SEND_CONFIG);
for (j=0; j < 4; j++) {
b1_put_byte(base, buf[i++]);
}
}
- left -= sizeof(buf);
- dp += sizeof(buf);
+ left -= FWBUF_SIZE;
+ dp += FWBUF_SIZE;
}
if (left) {
if (config->user) {
@@ -785,7 +786,7 @@ static int __init b1_init(void)
char rev[32];
if ((p = strchr(revision, ':')) != 0 && p[1]) {
- strlcpy(rev, p + 2, sizeof(rev));
+ strlcpy(rev, p + 2, 32);
if ((p = strchr(rev, '$')) != 0 && p > rev)
*(p-1) = 0;
} else
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index ac0a85458616..c4817536e324 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -189,7 +189,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
{
u32 val;
unsigned char *dp;
- int left;
+ u_int left;
u32 loadoff = 0;
dp = t4file->data;
@@ -664,7 +664,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
u32 status = c4inmeml(card->mbase+DOORBELL);
if (status & DBELL_RESET_HOST) {
- int i;
+ u_int i;
c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);
if (card->nlogcontr == 0)
return IRQ_HANDLED;
@@ -791,7 +791,8 @@ static int c4_send_config(avmcard *card, capiloaddatapart * config)
{
u8 val[4];
unsigned char *dp;
- int left, retval;
+ u_int left;
+ int retval;
if ((retval = queue_sendconfigword(card, 1)) != 0)
return retval;
@@ -880,7 +881,7 @@ void c4_reset_ctr(struct capi_ctr *ctrl)
{
avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
avmctrl_info *cinfo;
- int i;
+ u_int i;
c4_reset(card);
@@ -896,7 +897,7 @@ static void c4_remove(struct pci_dev *pdev)
{
avmcard *card = pci_get_drvdata(pdev);
avmctrl_info *cinfo;
- int i;
+ u_int i;
c4_reset(card);
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index ebd22420ca36..216c644c9350 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -22,8 +22,8 @@
#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
-static DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
-static APPL *application = (APPL *) NULL;
+DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
+APPL *application = (APPL *) NULL;
byte max_appl = MAX_APPL;
static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;
@@ -45,7 +45,7 @@ static dword notify_handle;
static void DIRequest(ENTITY * e);
static DESCRIPTOR MAdapter;
static DESCRIPTOR DAdapter;
-static byte max_adapter = 0;
+byte max_adapter = 0;
static byte ControllerMap[MAX_DESCRIPTORS + 1];
@@ -111,7 +111,7 @@ static void no_printf(unsigned char *x, ...)
/*
* Controller mapping
*/
-static byte MapController(byte Controller)
+byte MapController(byte Controller)
{
byte i;
byte MappedController = 0;
@@ -750,8 +750,6 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
void **xbuffer_ptr, **xbuffer_internal;
diva_os_spin_lock_magic_t old_irql;
- DIVA_LOCK_MODULE;
-
if (diva_os_in_irq()) {
DBG_ERR(("CAPI_REGISTER - in irq context !"))
return;
@@ -777,6 +775,11 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
return; /* appl already registered */
}
+ if (!try_module_get(ctrl->owner)) {
+ printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+ return;
+ }
+
/* alloc memory */
bnum = rp->level3cnt * rp->datablkcnt;
@@ -784,6 +787,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
if (!(DataNCCI = diva_os_malloc(0, bnum * sizeof(word)))) {
DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+ module_put(ctrl->owner);
return;
}
memset(DataNCCI, 0, bnum * sizeof(word));
@@ -791,6 +795,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
if (!(DataFlags = diva_os_malloc(0, bnum * sizeof(word)))) {
DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
diva_os_free(0, DataNCCI);
+ module_put(ctrl->owner);
return;
}
memset(DataFlags, 0, bnum * sizeof(word));
@@ -799,6 +804,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
diva_os_free(0, DataNCCI);
diva_os_free(0, DataFlags);
+ module_put(ctrl->owner);
return;
}
memset(ReceiveBuffer, 0, bnum * rp->datablklen);
@@ -808,6 +814,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
diva_os_free(0, DataNCCI);
diva_os_free(0, DataFlags);
diva_os_free(0, ReceiveBuffer);
+ module_put(ctrl->owner);
return;
}
memset(xbuffer_used, 0, xnum);
@@ -818,6 +825,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
diva_os_free(0, DataFlags);
diva_os_free(0, ReceiveBuffer);
diva_os_free(0, xbuffer_used);
+ module_put(ctrl->owner);
return;
}
memset(xbuffer_ptr, 0, xnum * sizeof(void *));
@@ -829,6 +837,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
diva_os_free(0, ReceiveBuffer);
diva_os_free(0, xbuffer_used);
diva_os_free(0, xbuffer_ptr);
+ module_put(ctrl->owner);
return;
}
memset(xbuffer_internal, 0, xnum * sizeof(void *));
@@ -848,6 +857,7 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
diva_os_free(0, xbuffer_used);
diva_os_free(0, xbuffer_ptr);
diva_os_free(0, xbuffer_internal);
+ module_put(ctrl->owner);
return;
}
}
@@ -935,7 +945,7 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
}
diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");
- DIVA_UNLOCK_MODULE;
+ module_put(ctrl->owner);
}
/*
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index ba6da6581303..bfb939de6c88 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -201,8 +201,10 @@ void diva_os_remove_irq (void* context, byte irq);
/*
** module locking
*/
+/*
#define DIVA_LOCK_MODULE MOD_INC_USE_COUNT
#define DIVA_UNLOCK_MODULE MOD_DEC_USE_COUNT
+*/
/*
** Spin Lock framework
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index b37a16780800..a099990777ae 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -692,7 +692,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt);
- if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) { /* D-Channel Busy */
+ if ((int)(cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) { /* D-Channel Busy */
test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
stptr = cs->stlist;
while (stptr != NULL) {
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 533f4148bc67..ecd9cd18f375 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -1758,7 +1758,7 @@ HiSax_command(isdn_ctrl * ic)
/* protocol specific io commands */
case (ISDN_CMD_PROT_IO):
for (st = csta->stlist; st; st = st->next)
- if (st->protocol == (ic->arg & 0xFF))
+ if ((u_int)st->protocol == (ic->arg & 0xFF))
return(st->l3.l4l3_proto(st, ic));
return(-EINVAL);
break;
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index b9996317376b..66ab32452a2b 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -751,17 +751,17 @@ setup_diva(struct IsdnCard *card)
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
if (pdev->function == ISAPNP_FUNCTION(0xA1)) {
- if (diva_ipac_isa_probe(cs->card, cs))
+ if (diva_ipac_isa_probe(card->cs, card))
return 0;
return 1;
} else {
- if (diva_isac_isa_probe(cs->card, cs))
+ if (diva_isac_isa_probe(card->cs, card))
return 0;
return 1;
- } else {
- printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
- return(0);
}
+ } else {
+ printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
+ return(0);
}
pdev++;
pnp_c=NULL;
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 37d6321ff4ca..219374604e7c 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -838,7 +838,7 @@ elsa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
cs->hw.elsa.status |= ELSA_BAD_PWR;
}
switch (cs->subtyp) {
- case ELSA_PCFPRO: bytecnt = 16; break;
+ case ELSA_PCFPRO: bytecnt = 16; break;
}
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index ebfa936d6796..2332436a43ed 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -255,7 +255,7 @@ inline int
write_modem(struct BCState *bcs) {
int ret=0;
struct IsdnCardState *cs = bcs->cs;
- int count, len, fp;
+ u_int count, len, fp;
unsigned long flags;
if (!bcs->tx_skb)
@@ -435,8 +435,8 @@ close_elsastate(struct BCState *bcs)
}
void
-modem_write_cmd(struct IsdnCardState *cs, u8 *buf, int len) {
- int count, fp;
+modem_write_cmd(struct IsdnCardState *cs, u8 *buf, u_int len) {
+ u_int count, fp;
u8 *msg = buf;
unsigned long flags;
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 9435ea9976bd..5fe4f4ec687d 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -264,8 +264,9 @@ static void
hfc_fill_fifo(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
- int idx, fcnt;
- int count;
+ u_int idx;
+ int fcnt;
+ u_int count;
u8 cip;
if (!bcs->tx_skb)
@@ -636,8 +637,8 @@ int receive_dmsg(struct IsdnCardState *cs)
static void
hfc_fill_dfifo(struct IsdnCardState *cs)
{
- int idx, fcnt;
- int count;
+ int fcnt;
+ u_int idx, count;
u8 cip;
if (!cs->tx_skb)
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index c1c106f59a2a..0cbb11c62ebe 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -249,8 +249,8 @@ static void
hfc_fill_fifo(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
- int idx, fcnt;
- int count;
+ int fcnt;
+ u_int idx, count;
int z1, z2;
u8 cip;
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 014fc9bb44e7..c23175e5f948 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -487,8 +487,8 @@ main_rec_hfcpci(struct BCState *bcs)
static void
hfcpci_fill_dfifo(struct IsdnCardState *cs)
{
- int fcnt;
- int count, new_z1, maxlen;
+ int fcnt, new_z1, maxlen;
+ u_int count;
dfifo_type *df;
u8 *src, *dst, new_f1;
@@ -533,7 +533,7 @@ hfcpci_fill_dfifo(struct IsdnCardState *cs)
src = cs->tx_skb->data; /* source pointer */
dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); /* end fifo */
- if (maxlen > count)
+ if (maxlen > (int)count)
maxlen = count; /* limit size */
memcpy(dst, src, maxlen); /* first copy */
@@ -559,8 +559,8 @@ static void
hfcpci_fill_fifo(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
- int maxlen, fcnt;
- int count, new_z1;
+ int maxlen, fcnt, new_z1;
+ u_int count;
bzfifo_type *bz;
u8 *bdata;
u8 new_f1, *src, *dst;
@@ -591,7 +591,7 @@ hfcpci_fill_fifo(struct BCState *bcs)
fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */
while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) {
- if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) {
+ if ((int)bcs->tx_skb->len < (B_FIFO_SIZE - fcnt)) {
/* data is suitable for fifo */
count = bcs->tx_skb->len;
@@ -601,7 +601,7 @@ hfcpci_fill_fifo(struct BCState *bcs)
src = bcs->tx_skb->data; /* source pointer */
dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); /* end of fifo */
- if (maxlen > count)
+ if (maxlen > (int)count)
maxlen = count; /* limit size */
memcpy(dst, src, maxlen); /* first copy */
@@ -661,7 +661,7 @@ hfcpci_fill_fifo(struct BCState *bcs)
src = bcs->tx_skb->data; /* source pointer */
dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL);
maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1); /* end fifo */
- if (maxlen > count)
+ if (maxlen > (int)count)
maxlen = count; /* limit size */
memcpy(dst, src, maxlen); /* first copy */
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 66b09ddbe379..461c5fce51b1 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -145,7 +145,7 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u8 fifo, int trans_max
count = z2 - z1;
if (count <= 0)
count += fifo_size; /* free bytes */
- if (count < skb->len+1) return(0); /* no room */
+ if (count < (int)(skb->len+1)) return(0); /* no room */
count = fifo_size - count; /* bytes still not send */
if (count > 2 * trans_max) return(0); /* delay too long */
count = skb->len;
@@ -182,7 +182,7 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u8 fifo, int trans_max
if (cs->debug & L1_DEB_ISAC_FIFO)
debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)",
fifo, skb->len, count);
- if (count < skb->len) {
+ if (count < (int)skb->len) {
if (cs->debug & L1_DEB_ISAC_FIFO)
debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo);
return(0);
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index f32fe99a733a..e4d7a1962a74 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -265,7 +265,7 @@ struct Layer1 {
struct Layer2 {
int tei;
int sap;
- int maxlen;
+ u_int maxlen;
unsigned long flag;
unsigned int vs, va, vr;
int rc;
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 614dcd007d61..820aa5281c84 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -38,6 +38,8 @@
#define __debug_variable debug
#include "hisax_debug.h"
+// #define CONFIG_PNP_CARD 1
+
#ifdef CONFIG_HISAX_DEBUG
static int debug = 0;
MODULE_PARM(debug, "i");
@@ -365,8 +367,8 @@ static void hdlc_fill_fifo(struct fritz_bcs *bcs)
{
struct fritz_adapter *adapter = bcs->adapter;
struct sk_buff *skb = bcs->tx_skb;
- int count;
- int fifo_size = 32;
+ u_int count;
+ u_int fifo_size = 32;
unsigned long flags;
unsigned char *p;
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index ce64f0b1c02e..4af5224e745d 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -736,5 +736,6 @@ ipacx_setup(struct IsdnCardState *cs, struct dc_hw_ops *ipacx_dc_ops,
cs->bc_hw_ops = ipacx_bc_ops;
val = ipacx_read_reg(cs, IPACX_ID) & 0x3f;
printk(KERN_INFO "HiSax: IPACX Design Id: %#x\n", val);
+ return 0;
}
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index c4c15b3efbc2..f5b65950be33 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -677,7 +677,7 @@ isar_fill_fifo(struct BCState *bcs)
if (!(bcs->hw.isar.reg->bstat &
(bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
return;
- if (bcs->tx_skb->len > bcs->hw.isar.mml) {
+ if (bcs->tx_skb->len > (u_int)bcs->hw.isar.mml) {
msb = 0;
count = bcs->hw.isar.mml;
} else {
diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h
index 857f54ede027..2de24d2c067f 100644
--- a/drivers/isdn/hisax/isdnl1.h
+++ b/drivers/isdn/hisax/isdnl1.h
@@ -354,7 +354,7 @@ xmit_xdu_d(struct IsdnCardState *cs, void (*reset_xmit)(struct IsdnCardState *cs
}
static inline unsigned char *
-xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more)
+xmit_fill_fifo_b(struct BCState *bcs, u_int fifo_size, int *count, int *more)
{
struct IsdnCardState *cs = bcs->cs;
unsigned char *p;
@@ -391,7 +391,7 @@ xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more)
}
static inline unsigned char *
-xmit_fill_fifo_d(struct IsdnCardState *cs, int fifo_size, int *count, int *more)
+xmit_fill_fifo_d(struct IsdnCardState *cs, u_int fifo_size, int *count, int *more)
{
unsigned char *p;
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 87142482cf05..791b9d567a78 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -103,7 +103,7 @@ static char *strL2Event[] =
"EV_L2_FRAME_ERROR",
};
-static int l2addrsize(struct Layer2 *l2);
+static u_int l2addrsize(struct Layer2 *l2);
static void
set_peer_busy(struct Layer2 *l2) {
@@ -178,14 +178,14 @@ clear_exception(struct Layer2 *l2)
clear_peer_busy(l2);
}
-inline int
+inline u_int
l2headersize(struct Layer2 *l2, int ui)
{
return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
(test_bit(FLG_LAPD, &l2->flag) ? 2 : 1));
}
-inline int
+inline u_int
l2addrsize(struct Layer2 *l2)
{
return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);
@@ -295,7 +295,7 @@ IsRNR(u8 * data, struct PStack *st)
int
iframe_error(struct PStack *st, struct sk_buff *skb)
{
- int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1);
+ u_int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1);
int rsp = *skb->data & 0x2;
if (test_bit(FLG_ORIG, &st->l2.flag))
@@ -360,7 +360,7 @@ UI_error(struct PStack *st, struct sk_buff *skb)
int
FRMR_error(struct PStack *st, struct sk_buff *skb)
{
- int headers = l2addrsize(&st->l2) + 1;
+ u_int headers = l2addrsize(&st->l2) + 1;
u8 *datap = skb->data + headers;
int rsp = *skb->data & 0x2;
@@ -1066,8 +1066,8 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
struct PStack *st = fi->userdata;
struct sk_buff *skb = arg;
struct Layer2 *l2 = &(st->l2);
- int PollFlag, ns, i;
- unsigned int nr;
+ int PollFlag, i;
+ unsigned int nr, ns;
i = l2addrsize(l2);
if (test_bit(FLG_MOD128, &l2->flag)) {
@@ -1251,8 +1251,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
struct sk_buff *skb, *oskb;
struct Layer2 *l2 = &st->l2;
u8 header[MAX_HEADER_LEN];
- int i;
- int unsigned p1;
+ int unsigned p1, i;
unsigned long flags;
if (!cansend(st))
@@ -1632,7 +1631,7 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
{
struct sk_buff *skb = arg;
u8 *datap;
- int ret = 1, len;
+ u_int ret = 1, len;
int c = 0;
switch (pr) {
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
index b99fb2f65b65..cff09671f592 100644
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -302,7 +302,8 @@ static void
l3_1tr6_info(struct l3_process *pc, u8 pr, void *arg)
{
u8 *p;
- int i, tmpcharge = 0;
+ u_int i;
+ int tmpcharge = 0;
char a_charge[8], tmp[32];
struct sk_buff *skb = arg;
@@ -400,7 +401,8 @@ l3_1tr6_disc(struct l3_process *pc, u8 pr, void *arg)
{
struct sk_buff *skb = arg;
u8 *p;
- int i, tmpcharge = 0;
+ u_int i;
+ int tmpcharge = 0;
char a_charge[8], tmp[32];
StopAllL3Timer(pc);
@@ -753,7 +755,8 @@ static struct stateentry manstatelist[] =
static void
up1tr6(struct PStack *st, int pr, void *arg)
{
- int i, mt, cr;
+ u_int i;
+ int mt, cr;
struct l3_process *proc;
struct sk_buff *skb = arg;
char tmp[80];
@@ -868,7 +871,8 @@ up1tr6(struct PStack *st, int pr, void *arg)
static void
down1tr6(struct PStack *st, int pr, void *arg)
{
- int i, cr;
+ u_int i;
+ int cr;
struct l3_process *proc;
struct Channel *chan;
char tmp[80];
@@ -915,7 +919,7 @@ down1tr6(struct PStack *st, int pr, void *arg)
static void
man1tr6(struct PStack *st, int pr, void *arg)
{
- int i;
+ u_int i;
struct l3_process *proc = arg;
if (!proc) {
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index a2cae62f6bcc..b7ae0a6546e1 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -736,7 +736,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
p += l;
mt = *p++;
oldpos = 0;
- while ((p - skb->data) < skb->len) {
+ while ((p - skb->data) < (int)skb->len) {
if ((*p & 0xf0) == 0x90) { /* shift codeset */
old_codeset = codeset;
codeset = *p & 7;
@@ -2923,7 +2923,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
u8 tmp[16];
u8 *p = tmp;
int l;
- int i;
+ u_int i;
struct l3_process *proc = st->l3.global;
proc->callref = skb->data[2]; /* cr flag */
@@ -2961,7 +2961,8 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void
dss1up(struct PStack *st, int pr, void *arg)
{
- int i, mt, cr, cause, callState;
+ u_int i;
+ int mt, cr, cause, callState;
char *ptr;
u8 *p;
struct sk_buff *skb = arg;
@@ -2998,7 +2999,7 @@ dss1up(struct PStack *st, int pr, void *arg)
return;
}
cr = getcallref(skb->data);
- if (skb->len < ((skb->data[1] & 0x0f) + 3)) {
+ if (skb->len < (u_int)((skb->data[1] & 0x0f) + 3)) {
l3_debug(st, "dss1up frame too short(%d)", skb->len);
dev_kfree_skb(skb);
return;
@@ -3135,7 +3136,8 @@ dss1up(struct PStack *st, int pr, void *arg)
static void
dss1down(struct PStack *st, int pr, void *arg)
{
- int i, cr;
+ u_int i;
+ int cr;
struct l3_process *proc;
struct Channel *chan;
@@ -3186,29 +3188,29 @@ dss1down(struct PStack *st, int pr, void *arg)
static void
dss1man(struct PStack *st, int pr, void *arg)
{
- int i;
- struct l3_process *proc = arg;
-
- if (!proc) {
- printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
- return;
- }
- for (i = 0; i < MANSLLEN; i++)
+ u_int i;
+ struct l3_process *proc = arg;
+
+ if (!proc) {
+ printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
+ return;
+ }
+ for (i = 0; i < MANSLLEN; i++)
if ((pr == manstatelist[i].primitive) &&
- ((1 << proc->state) & manstatelist[i].state))
- break;
- if (i == MANSLLEN) {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
- proc->callref & 0x7f, proc->state, pr);
- }
- } else {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "cr %d dss1man state %d prim %#x",
- proc->callref & 0x7f, proc->state, pr);
- }
- manstatelist[i].rout(proc, pr, arg);
- }
+ ((1 << proc->state) & manstatelist[i].state))
+ break;
+ if (i == MANSLLEN) {
+ if (st->l3.debug & L3_DEB_STATE) {
+ l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
+ proc->callref & 0x7f, proc->state, pr);
+ }
+ } else {
+ if (st->l3.debug & L3_DEB_STATE) {
+ l3_debug(st, "cr %d dss1man state %d prim %#x",
+ proc->callref & 0x7f, proc->state, pr);
+ }
+ manstatelist[i].rout(proc, pr, arg);
+ }
}
void
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 94ea0d0f7f47..fc3ba29ee2c7 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -685,7 +685,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
p += l;
mt = *p++;
oldpos = 0;
- while ((p - skb->data) < skb->len) {
+ while ((u_int)(p - skb->data) < skb->len) {
if ((*p & 0xf0) == 0x90) { /* shift codeset */
old_codeset = codeset;
codeset = *p & 7;
@@ -2859,7 +2859,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
u8 tmp[16];
u8 *p = tmp;
int l;
- int i;
+ u_int i;
struct l3_process *proc = st->l3.global;
if ( skb )
@@ -2900,7 +2900,8 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void
ni1up(struct PStack *st, int pr, void *arg)
{
- int i, mt, cr, cause, callState;
+ u_int i;
+ int mt, cr, cause, callState;
char *ptr;
u8 *p;
struct sk_buff *skb = arg;
@@ -2941,7 +2942,7 @@ ni1up(struct PStack *st, int pr, void *arg)
return;
}
cr = getcallref(skb->data);
- if (skb->len < ((skb->data[1] & 0x0f) + 3)) {
+ if (skb->len < (u_int)((skb->data[1] & 0x0f) + 3)) {
l3_debug(st, "ni1up frame too short(%d)", skb->len);
dev_kfree_skb(skb);
return;
@@ -3086,7 +3087,8 @@ ni1up(struct PStack *st, int pr, void *arg)
static void
ni1down(struct PStack *st, int pr, void *arg)
{
- int i, cr;
+ u_int i;
+ int cr;
struct l3_process *proc;
struct Channel *chan;
@@ -3137,7 +3139,7 @@ ni1down(struct PStack *st, int pr, void *arg)
static void
ni1man(struct PStack *st, int pr, void *arg)
{
- int i;
+ u_int i;
struct l3_process *proc = arg;
if (!proc) {
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index f832b1e26d62..311d3e9a6191 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -729,7 +729,7 @@ void netjet_fill_dma(struct BCState *bcs)
static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
u_int mask, val, *p=buf;
- u_int i, s_cnt;
+ int i, s_cnt;
if (cnt <= 0)
return;
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
index 0c186f82ea92..0e6682e6f7db 100644
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -446,7 +446,7 @@ prcause(char *dest, u8 * p)
{
u8 *end;
char *dp = dest;
- int i, cause;
+ u_int i, cause;
end = p + p[1] + 1;
p += 2;
@@ -871,7 +871,8 @@ static int
disptext_ni1(char *dest, u8 * p)
{
char *dp = dest;
- int l, tag, len, i;
+ int l, tag, len;
+ u_int i;
p++;
l = *p++ - 1;
@@ -1200,7 +1201,7 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
char *dp;
unsigned char pd, cr_l, cr, mt;
unsigned char sapi, tei, ftyp;
- int i, cset = 0, cs_old = 0, cs_fest = 0;
+ u_int i, cset = 0, cs_old = 0, cs_fest = 0;
int size, finish = 0;
if (skb->len < 3)
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index 1ffff0814392..af0f6019c51f 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -760,7 +760,7 @@ setup_sedlbauer(struct IsdnCard *card)
printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0));
pnp_device_detach(pd);
- goto err;
+ return 0;
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
@@ -777,7 +777,7 @@ setup_sedlbauer(struct IsdnCard *card)
}
} else {
printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
- goto err;
+ return 0;
}
}
pdev++;
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 7aade575701f..b4cfed146b24 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -31,9 +31,9 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
struct st5481_b_out *b_out = &bcs->b_out;
struct st5481_adapter *adapter = bcs->adapter;
struct urb *urb;
- unsigned int packet_size,offset;
- int len,buf_size,bytes_sent;
- int i;
+ u_int packet_size, bytes_sent;
+ int len, offset, buf_size;
+ u_int i;
struct sk_buff *skb;
if (test_and_set_bit(buf_nr, &b_out->busy)) {
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 06b91cba17bb..786c5642e95e 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -294,8 +294,8 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
{
struct st5481_d_out *d_out = &adapter->d_out;
struct urb *urb;
- unsigned int num_packets, packet_offset;
- int len, buf_size, bytes_sent;
+ unsigned int num_packets;
+ int len, buf_size, bytes_sent, packet_offset;
struct sk_buff *skb;
struct usb_iso_packet_descriptor *desc;
@@ -341,7 +341,7 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
desc = &urb->iso_frame_desc[num_packets];
desc->offset = packet_offset;
desc->length = SIZE_ISO_PACKETS_D_OUT;
- if (len - packet_offset < desc->length)
+ if (len - packet_offset < (int)desc->length)
desc->length = len - packet_offset;
num_packets++;
packet_offset += desc->length;
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index 47b90e49b8d8..5c9fc1ad38fb 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -517,7 +517,6 @@ isdn_audio_eval_dtmf(modem_info * info)
dtmf_state *s;
int silence;
int i;
- unsigned long flags;
int grp[2];
char what;
char *p;
@@ -551,7 +550,7 @@ isdn_audio_eval_dtmf(modem_info * info)
*p++ = 0x10;
*p = what;
skb_trim(skb, 2);
- if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
+ if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) {
printk(KERN_WARNING
"isdn_audio: insufficient skb_headroom, dropping\n");
kfree_skb(skb);
@@ -559,11 +558,7 @@ isdn_audio_eval_dtmf(modem_info * info)
}
ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
ISDN_AUDIO_SKB_LOCK(skb) = 0;
- save_flags(flags);
- cli();
isdn_tty_queue_tail(info, skb, 2);
- restore_flags(flags);
- /* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
mod_timer(&info->read_timer, jiffies + 4);
} else
@@ -653,7 +648,6 @@ void
isdn_audio_put_dle_code(modem_info * info, u_char code)
{
struct sk_buff *skb;
- unsigned long flags;
char *p;
skb = dev_alloc_skb(2);
@@ -666,7 +660,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
p = (char *) skb_put(skb, 2);
p[0] = 0x10;
p[1] = code;
- if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
+ if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) {
printk(KERN_WARNING
"isdn_audio: insufficient skb_headroom, dropping\n");
kfree_skb(skb);
@@ -674,10 +668,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
}
ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
ISDN_AUDIO_SKB_LOCK(skb) = 0;
- save_flags(flags);
- cli();
isdn_tty_queue_tail(info, skb, 2);
- restore_flags(flags);
/* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched))
mod_timer(&info->read_timer, jiffies + 4);
@@ -691,7 +682,7 @@ isdn_audio_eval_silence(modem_info * info)
what = ' ';
- if (s->idx > (info->emu.vpar[2] * 800)) {
+ if (s->idx > (u_int)(info->emu.vpar[2] * 800)) {
s->idx = 0;
if (!s->state) { /* silence from beginning of rec */
what = 's';
@@ -699,9 +690,9 @@ isdn_audio_eval_silence(modem_info * info)
what = 'q';
}
}
- if ((what == 's') || (what == 'q')) {
- printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
- (what=='s') ? "silence":"quiet");
- isdn_audio_put_dle_code(info, what);
- }
+ if ((what == 's') || (what == 'q')) {
+ printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
+ (what=='s') ? "silence":"quiet");
+ isdn_audio_put_dle_code(info, what);
+ }
}
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 08562d0329f1..3de5bef85bdd 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -598,6 +598,7 @@ drv_register(struct fsm_inst *fi, int pr, void *arg)
iif->statcallb = isdn_status_callback;
isdn_info_update();
+ return(0);
}
static int
@@ -609,6 +610,7 @@ drv_stat_run(struct fsm_inst *fi, int pr, void *arg)
drv->features = drv->interface->features;
isdn_v110_add_features(drv);
set_global_features();
+ return(0);
}
static int
@@ -616,6 +618,7 @@ drv_stat_stop(struct fsm_inst *fi, int pr, void *arg)
{
fsm_change_state(fi, ST_DRV_LOADED);
set_global_features();
+ return(0);
}
static int
@@ -646,6 +649,7 @@ drv_stat_stavail(struct fsm_inst *fi, int pr, void *arg)
drv->stavail += c->arg;
spin_unlock_irqrestore(&stat_lock, flags);
wake_up_interruptible(&drv->st_waitq);
+ return 0;
}
static int
@@ -1318,20 +1322,18 @@ static ssize_t
isdn_status_read(struct file *file, char *buf, size_t count, loff_t * off)
{
int retval;
- int len = 0;
+ size_t len = 0;
char *p;
if (off != &file->f_pos)
return -ESPIPE;
- lock_kernel();
if (!file->private_data) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto out;
- }
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
interruptible_sleep_on(&(dev->info_waitq));
}
+ lock_kernel();
p = isdn_statstr();
file->private_data = 0;
if ((len = strlen(p)) <= count) {
@@ -1362,12 +1364,10 @@ isdn_status_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
- lock_kernel();
-
poll_wait(file, &(dev->info_waitq), wait);
+ lock_kernel();
if (file->private_data)
mask |= POLLIN | POLLRDNORM;
-
unlock_kernel();
return mask;
}
@@ -1464,7 +1464,7 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off)
struct isdn_slot *slot = file->private_data;
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
- int len = 0;
+ size_t len = 0;
if (off != &file->f_pos)
return -ESPIPE;
diff --git a/drivers/isdn/i4l/isdn_net_lib.c b/drivers/isdn/i4l/isdn_net_lib.c
index ad29b9628883..6acdd8ca0dc1 100644
--- a/drivers/isdn/i4l/isdn_net_lib.c
+++ b/drivers/isdn/i4l/isdn_net_lib.c
@@ -758,7 +758,7 @@ static int
isdn_net_getphone(isdn_net_ioctl_phone * phone, char *phones)
{
isdn_net_dev *idev = isdn_net_findif(phone->name);
- int count = 0;
+ u_int count = 0;
char *buf = (char *)__get_free_page(GFP_KERNEL);
struct isdn_net_phone *n;
diff --git a/drivers/isdn/i4l/isdn_net_lib.h b/drivers/isdn/i4l/isdn_net_lib.h
index 0258036dc0fb..345ac53e4eb5 100644
--- a/drivers/isdn/i4l/isdn_net_lib.h
+++ b/drivers/isdn/i4l/isdn_net_lib.h
@@ -133,47 +133,47 @@ struct isdn_net_local_s {
/* per ISDN channel (ISDN interface) data */
struct isdn_net_dev_s {
- struct isdn_slot *isdn_slot; /* Index to isdn device/channel */
- struct isdn_slot *exclusive; /* NULL if non excl */
- int pre_device; /* Preselected isdn-device */
- int pre_channel; /* Preselected isdn-channel */
-
- struct timer_list dial_timer; /* dial events timer */
- struct fsm_inst fi; /* call control state machine */
- int dial_event; /* event in case of timer expiry */
- int dial; /* # of phone number just dialed */
- int outgoing; /* Flag: outgoing call */
- int dialretry; /* Counter for Dialout-retries */
-
- int cps; /* current speed of this interface */
- int transcount; /* byte-counter for cps-calculation */
- int last_jiffies; /* when transcount was reset */
- int sqfull; /* Flag: netdev-queue overloaded */
- ulong sqfull_stamp; /* Start-Time of overload */
-
- int huptimer; /* Timeout-counter for auto-hangup */
- int charge; /* Counter for charging units */
- int charge_state; /* ChargeInfo state machine */
- unsigned long chargetime; /* Timer for Charging info */
- int chargeint; /* Interval between charge-infos */
-
- int pppbind; /* ippp device for bindings */
-
- struct sk_buff_head super_tx_queue; /* List of supervisory frames to */
- /* be transmitted asap */
- int frame_cnt; /* number of frames currently */
- /* queued in HL driver */
- struct tasklet_struct tlet;
-
- isdn_net_local *mlp; /* Ptr to master device for all devs*/
-
- struct list_head slaves; /* member of local->slaves */
- struct list_head online; /* member of local->online */
-
- char name[10]; /* Name of device */
- struct list_head global_list; /* global list of all isdn_net_devs */
- void *ind_priv; /* interface types can put their
- private data here */
+ struct isdn_slot *isdn_slot; /* Index to isdn device/channel */
+ struct isdn_slot *exclusive; /* NULL if non excl */
+ int pre_device; /* Preselected isdn-device */
+ int pre_channel; /* Preselected isdn-channel */
+
+ struct timer_list dial_timer; /* dial events timer */
+ struct fsm_inst fi; /* call control state machine */
+ int dial_event; /* event in case of timer expiry */
+ int dial; /* # of phone number just dialed */
+ int outgoing; /* Flag: outgoing call */
+ int dialretry; /* Counter for Dialout-retries */
+
+ int cps; /* current speed of this interface */
+ int transcount; /* byte-counter for cps-calculation */
+ u_long last_jiffies; /* when transcount was reset */
+ int sqfull; /* Flag: netdev-queue overloaded */
+ u_long sqfull_stamp; /* Start-Time of overload */
+
+ int huptimer; /* Timeout-counter for auto-hangup */
+ int charge; /* Counter for charging units */
+ int charge_state; /* ChargeInfo state machine */
+ u_long chargetime; /* Timer for Charging info */
+ int chargeint; /* Interval between charge-infos */
+
+ int pppbind; /* ippp device for bindings */
+
+ struct sk_buff_head super_tx_queue; /* List of supervisory frames to */
+ /* be transmitted asap */
+ int frame_cnt; /* number of frames currently */
+ /* queued in HL driver */
+ struct tasklet_struct tlet;
+
+ isdn_net_local *mlp; /* Ptr to master device for all devs*/
+
+ struct list_head slaves; /* member of local->slaves */
+ struct list_head online; /* member of local->online */
+
+ char name[10]; /* Name of device */
+ struct list_head global_list; /* global list of all isdn_net_devs */
+ void *ind_priv; /* interface types can put their
+ private data here */
};
/* ====================================================================== */
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 0bd61b05421c..389fbffc3289 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -132,7 +132,7 @@ static int
isdn_tty_readbchan(struct modem_info *info, u_char * buf, u_char * fp, int len)
{
int count;
- int count_pull;
+ u_int count_pull;
int count_put;
int dflag;
struct sk_buff *skb;
@@ -179,7 +179,7 @@ isdn_tty_readbchan(struct modem_info *info, u_char * buf, u_char * fp, int len)
#endif
/* No DLE's in buff, so simply copy it */
dflag = 1;
- if ((count_pull = skb->len) > len) {
+ if ((int)(count_pull = skb->len) > len) {
count_pull = len;
dflag = 0;
}
@@ -315,7 +315,7 @@ isdn_tty_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb)
skb_pull(skb, 4);
}
#ifdef CONFIG_ISDN_AUDIO
- if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
+ if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) {
printk(KERN_WARNING
"isdn_audio: insufficient skb_headroom, dropping\n");
kfree_skb(skb);
@@ -1728,9 +1728,6 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
modem_info *info;
int retval, line;
- /* FIXME. This is not unload-race free AFAICS */
-
- MOD_INC_USE_COUNT;
line = tty->index;
if (line < 0 || line > ISDN_MAX_CHANNELS)
@@ -1738,6 +1735,8 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
info = &isdn_mdm.info[line];
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
return -ENODEV;
+ if (!try_module_get(info->owner))
+ printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
info->count);
@@ -1753,6 +1752,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open return after startup\n");
#endif
+ module_put(info->owner);
return retval;
}
retval = isdn_tty_block_til_ready(tty, filp, info);
@@ -1760,6 +1760,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n");
#endif
+ module_put(info->owner);
return retval;
}
#ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1779,7 +1780,9 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
ulong flags;
ulong timeout;
- if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close"))
+ if (!info)
+ return;
+ if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close"))
goto out;
save_flags(flags);
@@ -1859,7 +1862,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
printk(KERN_DEBUG "isdn_tty_close normal exit\n");
#endif
out:
- MOD_DEC_USE_COUNT;
+ module_put(info->owner);
}
/*
@@ -2036,6 +2039,7 @@ isdn_tty_init(void)
return -3;
}
#endif
+ info->owner = THIS_MODULE;
init_MUTEX(&info->write_sem);
sprintf(info->last_cause, "0000");
sprintf(info->last_num, "none");
@@ -2457,7 +2461,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
(!skb_queue_empty(&info->rpqueue)))) {
skb = alloc_skb(strlen(msg)
#ifdef CONFIG_ISDN_AUDIO
- + sizeof(isdn_audio_skb)
+ + sizeof(isdnaudio_header)
#endif
, GFP_ATOMIC);
if (!skb) {
@@ -2465,7 +2469,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
return;
}
#ifdef CONFIG_ISDN_AUDIO
- skb_reserve(skb, sizeof(isdn_audio_skb));
+ skb_reserve(skb, sizeof(isdnaudio_header));
#endif
sp = skb_put(skb, strlen(msg));
#ifdef CONFIG_ISDN_AUDIO
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index dbccc7d31133..950123d31171 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -265,7 +265,7 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
__u8 RightMask;
__u8 fBit;
__u8 Data;
- int i;
+ u_int i;
if (!info->fax->bor) {
for (i = 0; i < skb->len; i++) {
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 7a0be06ce59a..925db4617f64 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -43,6 +43,8 @@ MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
static char
*revision = "$Revision: 1.65.6.8 $";
+static spinlock_t icn_lock = SPIN_LOCK_UNLOCKED;
+
static int icn_addcard(int, char *, char *);
/*
@@ -59,16 +61,15 @@ icn_free_queue(icn_card * card, int channel)
unsigned long flags;
skb_queue_purge(queue);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
card->xlen[channel] = 0;
card->sndcount[channel] = 0;
if ((skb = card->xskb[channel])) {
card->xskb[channel] = NULL;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
dev_kfree_skb(skb);
} else
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
/* Put a value into a shift-register, highest bit first.
@@ -146,8 +147,7 @@ icn_lock_channel(icn_card * card, int channel)
#ifdef MAP_DEBUG
printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if ((dev.channel == channel) && (card == dev.mcard)) {
dev.chanlock++;
retval = 1;
@@ -160,7 +160,7 @@ icn_lock_channel(icn_card * card, int channel)
printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
#endif
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
return retval;
}
@@ -175,11 +175,10 @@ icn_release_channel(void)
#ifdef MAP_DEBUG
printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (dev.chanlock > 0)
dev.chanlock--;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
/*
@@ -195,19 +194,18 @@ icn_trymaplock_channel(icn_card * card, int channel)
printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
dev.chanlock);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if ((!dev.chanlock) ||
((dev.channel == channel) && (dev.mcard == card))) {
dev.chanlock++;
icn_map_channel(card, channel);
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
#ifdef MAP_DEBUG
printk(KERN_DEBUG "trymaplock %d OK\n", channel);
#endif
return 1;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
#ifdef MAP_DEBUG
printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
#endif
@@ -226,13 +224,12 @@ icn_maprelease_channel(icn_card * card, int channel)
#ifdef MAP_DEBUG
printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (dev.chanlock > 0)
dev.chanlock--;
if (!dev.chanlock)
icn_map_channel(card, channel);
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
/* Get Data from the B-Channel, assemble fragmented packets and put them
@@ -308,14 +305,13 @@ icn_pollbchan_send(int channel, icn_card * card)
(card->sndcount[channel] ||
skb_queue_len(&card->spqueue[channel]) ||
card->xskb[channel])) {
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (card->xmit_lock[channel]) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
break;
}
card->xmit_lock[channel]++;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
skb = card->xskb[channel];
if (!skb) {
skb = skb_dequeue(&card->spqueue[channel]);
@@ -345,11 +341,10 @@ icn_pollbchan_send(int channel, icn_card * card)
sbnext; /* switch to next buffer */
icn_maprelease_channel(card, mch & 2);
if (!skb->len) {
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (card->xskb[channel])
card->xskb[channel] = NULL;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
dev_kfree_skb(skb);
if (card->xlen[channel]) {
cmd.command = ISDN_STAT_BSENT;
@@ -359,10 +354,9 @@ icn_pollbchan_send(int channel, icn_card * card)
card->interface.statcallb(&cmd);
}
} else {
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
card->xskb[channel] = skb;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
card->xmit_lock[channel] = 0;
if (!icn_trymaplock_channel(card, mch))
@@ -393,11 +387,10 @@ icn_pollbchan(unsigned long data)
}
if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
/* schedule b-channel polling again */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD);
card->flags |= ICN_FLAGS_RBTIMER;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
} else
card->flags &= ~ICN_FLAGS_RBTIMER;
}
@@ -464,9 +457,8 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
cmd.driver = card->myid;
cmd.arg = channel;
switch (action) {
- case 11:
- save_flags(flags);
- cli();
+ case 11:
+ spin_lock_irqsave(&icn_lock, flags);
icn_free_queue(card,channel);
card->rcvidx[channel] = 0;
@@ -483,11 +475,10 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
ncmd.driver = card->myid;
ncmd.arg = channel;
ncmd.command = ISDN_STAT_BHUP;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
card->interface.statcallb(&cmd);
} else
- restore_flags(flags);
-
+ spin_unlock_irqrestore(&icn_lock, flags);
break;
case 1:
icn_free_queue(card,channel);
@@ -498,10 +489,9 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
card->flags &= ~((channel) ?
ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
icn_free_queue(card, channel);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[channel] = 0;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
break;
case 3:
{
@@ -557,10 +547,9 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
case 8:
card->flags &= ~ICN_FLAGS_B1ACTIVE;
icn_free_queue(card, 0);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[0] = 0;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
cmd.arg = 0;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
@@ -571,10 +560,9 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
cmd.command = ISDN_STAT_BHUP;
card->flags &= ~ICN_FLAGS_B2ACTIVE;
icn_free_queue(card, 1);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
card->rcvidx[1] = 0;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
cmd.arg = 1;
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
@@ -592,8 +580,7 @@ icn_putmsg(icn_card * card, unsigned char c)
{
ulong flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
*card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
if (card->msg_buf_write == card->msg_buf_read) {
if (++card->msg_buf_read > card->msg_buf_end)
@@ -601,7 +588,7 @@ icn_putmsg(icn_card * card, unsigned char c)
}
if (card->msg_buf_write > card->msg_buf_end)
card->msg_buf_write = card->msg_buf;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
static void
@@ -683,20 +670,18 @@ icn_polldchan(unsigned long data)
if (!(card->flags & ICN_FLAGS_RBTIMER)) {
/* schedule b-channel polling */
card->flags |= ICN_FLAGS_RBTIMER;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
del_timer(&card->rb_timer);
card->rb_timer.function = icn_pollbchan;
card->rb_timer.data = (unsigned long) card;
card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
add_timer(&card->rb_timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
/* schedule again */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
/* Append a packet to the transmit buffer-queue.
@@ -725,8 +710,7 @@ icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
return 0;
if (card->sndcount[channel] > ICN_MAX_SQUEUE)
return 0;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
/* Push ACK flag as one
@@ -738,7 +722,7 @@ icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
} else
len = 0;
card->sndcount[channel] += len;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
return len;
}
@@ -860,11 +844,10 @@ icn_loadboot(u_char * buffer, icn_card * card)
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 0\n");
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
icn_map_channel(card, 0); /* Select Bank 0 */
icn_lock_channel(card, 0); /* Lock Bank 0 */
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
SLEEP(1);
memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
@@ -875,12 +858,11 @@ icn_loadboot(u_char * buffer, icn_card * card)
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 8\n");
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
icn_release_channel();
icn_map_channel(card, 2); /* Select Bank 8 */
icn_lock_channel(card, 2); /* Lock Bank 8 */
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
SLEEP(1);
memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
@@ -900,11 +882,10 @@ icn_loadboot(u_char * buffer, icn_card * card)
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 0\n");
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
icn_map_channel(card, 0); /* Select Bank 0 */
icn_lock_channel(card, 0); /* Lock Bank 0 */
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
SLEEP(1);
ret = (icn_check_loader(1));
@@ -931,8 +912,7 @@ icn_loadproto(u_char * buffer, icn_card * card)
if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))
return ret;
timer = 0;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (card->secondhalf) {
icn_map_channel(card, 2);
icn_lock_channel(card, 2);
@@ -940,7 +920,7 @@ icn_loadproto(u_char * buffer, icn_card * card)
icn_map_channel(card, 0);
icn_lock_channel(card, 0);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
while (left) {
if (sbfree) { /* If there is a free buffer... */
cnt = left;
@@ -995,8 +975,7 @@ icn_loadproto(u_char * buffer, icn_card * card)
printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
card->secondhalf);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
init_timer(&card->st_timer);
card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
card->st_timer.function = icn_polldchan;
@@ -1011,7 +990,7 @@ icn_loadproto(u_char * buffer, icn_card * card)
add_timer(&card->other->st_timer);
card->other->flags |= ICN_FLAGS_RUNNING;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
icn_maprelease_channel(card, 0);
return 0;
@@ -1069,8 +1048,7 @@ icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
} else
memcpy(msg, buf, count);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
lastmap_card = dev.mcard;
lastmap_channel = dev.channel;
icn_map_channel(card, mch);
@@ -1092,7 +1070,7 @@ icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
if (lastmap_card)
icn_map_channel(lastmap_card, lastmap_channel);
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
if (len) {
mdelay(1);
if (loop++ > 20)
@@ -1118,8 +1096,7 @@ icn_stopcard(icn_card * card)
unsigned long flags;
isdn_ctrl cmd;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (card->flags & ICN_FLAGS_RUNNING) {
card->flags &= ~ICN_FLAGS_RUNNING;
del_timer(&card->st_timer);
@@ -1130,7 +1107,7 @@ icn_stopcard(icn_card * card)
if (card->doubleS0)
icn_stopcard(card->other);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
}
static void
@@ -1154,7 +1131,7 @@ icn_disable_cards(void)
icn_card *card = cards;
while (card) {
- if (check_region(card->port, ICN_PORTLEN)) {
+ if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) {
printk(KERN_WARNING
"icn: (%s) ports 0x%03x-0x%03x in use.\n",
CID,
@@ -1163,6 +1140,7 @@ icn_disable_cards(void)
} else {
OUTB_P(0, ICN_RUN); /* Reset Controller */
OUTB_P(0, ICN_MAPRAM); /* Disable RAM */
+ release_region(card->port, ICN_PORTLEN);
}
card = card->next;
}
@@ -1184,22 +1162,22 @@ icn_command(isdn_ctrl * c, icn_card * card)
switch (c->arg) {
case ICN_IOCTL_SETMMIO:
if (dev.memaddr != (a & 0x0ffc000)) {
- if (check_mem_region(a & 0x0ffc000, 0x4000)) {
+ if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
printk(KERN_WARNING
"icn: memory at 0x%08lx in use.\n",
a & 0x0ffc000);
return -EINVAL;
}
+ release_mem_region(a & 0x0ffc000, 0x4000);
icn_stopallcards();
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (dev.mvalid) {
iounmap(dev.shmem);
release_mem_region(dev.memaddr, 0x4000);
}
dev.mvalid = 0;
dev.memaddr = a & 0x0ffc000;
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
printk(KERN_INFO
"icn: (%s) mmio set to 0x%08lx\n",
CID,
@@ -1214,15 +1192,15 @@ icn_command(isdn_ctrl * c, icn_card * card)
a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
|| a == 0x348 || a == 0x358 || a == 0x368) {
if (card->port != (unsigned short) a) {
- if (check_region((unsigned short) a, ICN_PORTLEN)) {
+ if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
printk(KERN_WARNING
"icn: (%s) ports 0x%03x-0x%03x in use.\n",
CID, (int) a, (int) a + ICN_PORTLEN);
return -EINVAL;
}
+ release_region((unsigned short) a, ICN_PORTLEN);
icn_stopcard(card);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&icn_lock, flags);
if (card->rvalid)
release_region(card->port, ICN_PORTLEN);
card->port = (unsigned short) a;
@@ -1231,7 +1209,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
card->other->port = (unsigned short) a;
card->other->rvalid = 0;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&icn_lock, flags);
printk(KERN_INFO
"icn: (%s) port set to 0x%03x\n",
CID, card->port);
diff --git a/drivers/isdn/sc/card.h b/drivers/isdn/sc/card.h
index 48d7cad5249b..bdb27fae6f20 100644
--- a/drivers/isdn/sc/card.h
+++ b/drivers/isdn/sc/card.h
@@ -94,6 +94,7 @@ typedef struct {
int StartOnReset; /* Indicates startproc after reset */
int EngineUp; /* Indicates CommEngine Up */
int trace_mode; /* Indicate if tracing is on */
+ spinlock_t lock; /* local lock */
} board;
#endif /* CARD_H */
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index 54ed228d4ecd..dddc408f3b3e 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -419,14 +419,13 @@ int reset(int card)
adapter[card]->EngineUp = 0;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
init_timer(&adapter[card]->reset_timer);
adapter[card]->reset_timer.function = check_reset;
adapter[card]->reset_timer.data = card;
adapter[card]->reset_timer.expires = jiffies + CHECKRESET_TIME;
add_timer(&adapter[card]->reset_timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
outb(0x1,adapter[card]->ioport[SFT_RESET]);
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 01954e019ac1..1ed94d4331c5 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -97,11 +97,12 @@ static int __init sc_init(void)
* No, I/O Base has been provided
*/
for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
- if(check_region(io[b] + i * 0x400, 1)) {
+ if(!request_region(io[b] + i * 0x400, 1, "sc test")) {
pr_debug("check_region for 0x%x failed\n", io[b] + i * 0x400);
io[b] = 0;
break;
- }
+ } else
+ release_region(io[b] + i * 0x400, 1);
}
/*
@@ -136,11 +137,12 @@ static int __init sc_init(void)
last_base = i + IOBASE_OFFSET;
pr_debug(" checking 0x%x...", i);
for ( j = 0 ; j < MAX_IO_REGS - 1 ; j++) {
- if(check_region(i + j * 0x400, 1)) {
+ if(!request_region(i + j * 0x400, 1, "sc test")) {
pr_debug("Failed\n");
found_io = 0;
break;
- }
+ } else
+ release_region(i + j * 0x400, 1);
}
if(found_io) {
@@ -177,9 +179,10 @@ static int __init sc_init(void)
* Just look for a signature and ID the
* board model
*/
- if(!check_region(ram[b], SRAM_PAGESIZE)) {
- pr_debug("check_region for RAM base 0x%x succeeded\n", ram[b]);
+ if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) {
+ pr_debug("request_region for RAM base 0x%x succeeded\n", ram[b]);
model = identify_board(ram[b], io[b]);
+ release_region(ram[b], SRAM_PAGESIZE);
}
}
else {
@@ -189,9 +192,10 @@ static int __init sc_init(void)
*/
for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) {
pr_debug("Checking RAM address 0x%x...\n", i);
- if(!check_region(i, SRAM_PAGESIZE)) {
+ if(request_region(i, SRAM_PAGESIZE, "sc test")) {
pr_debug(" check_region succeeded\n");
model = identify_board(i, io[b]);
+ release_region(i, SRAM_PAGESIZE);
if (model >= 0) {
pr_debug(" Identified a %s\n",
boardname[model]);
@@ -201,7 +205,7 @@ static int __init sc_init(void)
pr_debug(" Unidentifed or inaccessible\n");
continue;
}
- pr_debug(" check_region failed\n");
+ pr_debug(" request failed\n");
}
}
/*
@@ -310,6 +314,7 @@ static int __init sc_init(void)
continue;
}
memset(adapter[cinst], 0, sizeof(board));
+ spin_lock_init(&adapter[cinst]->lock);
if(!register_isdn(interface)) {
/*
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index 003d6bd606dd..e32b0604504a 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -55,8 +55,7 @@ int receivemessage(int card, RspMessage *rspmsg)
/*
* Map in the DPM to the base page and copy the message
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb((adapter[card]->shmem_magic >> 14) | 0x80,
adapter[card]->ioport[adapter[card]->shmem_pgport]);
dpm = (DualPortMemory *) adapter[card]->rambase;
@@ -64,8 +63,7 @@ int receivemessage(int card, RspMessage *rspmsg)
MSG_LEN);
dpm->rsp_tail = (dpm->rsp_tail+1) % MAX_MESSAGES;
inb(adapter[card]->ioport[FIFO_READ]);
- restore_flags(flags);
-
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
/*
* Tell the board that the message is received
*/
@@ -152,15 +150,14 @@ int sendmessage(int card,
/*
* Disable interrupts and map in shared memory
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb((adapter[card]->shmem_magic >> 14) | 0x80,
adapter[card]->ioport[adapter[card]->shmem_pgport]);
dpm = (DualPortMemory *) adapter[card]->rambase; /* Fix me */
memcpy_toio(&(dpm->req_queue[dpm->req_head]),&sndmsg,MSG_LEN);
dpm->req_head = (dpm->req_head+1) % MAX_MESSAGES;
outb(sndmsg.sequence_no, adapter[card]->ioport[FIFO_WRITE]);
- restore_flags(flags);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
pr_debug("%s: Sent Message seq:%d pid:%d time:%d "
"cnt:%d (type,class,code):(%d,%d,%d) "
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index efa0a8753332..663ffa0d1333 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -53,18 +53,17 @@ void *memcpy_toshmem(int card, void *dest, const void *src, size_t n)
/*
* Block interrupts and load the page
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
adapter[card]->ioport[adapter[card]->shmem_pgport]);
- pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
- ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
ret = memcpy_toio(adapter[card]->rambase +
((unsigned long) dest % 0x4000), src, n);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
+ pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
+ ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
pr_debug("%s: copying %d bytes from %#x to %#x\n",adapter[card]->devicename, n,
(unsigned long) src, adapter[card]->rambase + ((unsigned long) dest %0x4000));
- restore_flags(flags);
return ret;
}
@@ -97,19 +96,18 @@ void *memcpy_fromshmem(int card, void *dest, const void *src, size_t n)
/*
* Block interrupts and load the page
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
adapter[card]->ioport[adapter[card]->shmem_pgport]);
- pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
- ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
ret = memcpy_fromio(dest,(void *)(adapter[card]->rambase +
((unsigned long) src % 0x4000)), n);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
+ pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
+ ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
/* pr_debug("%s: copying %d bytes from %#x to %#x\n",
adapter[card]->devicename, n,
adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
- restore_flags(flags);
return ret;
}
@@ -138,16 +136,15 @@ void *memset_shmem(int card, void *dest, int c, size_t n)
/*
* Block interrupts and load the page
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
adapter[card]->ioport[adapter[card]->shmem_pgport]);
- pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
- ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
ret = memset_io(adapter[card]->rambase +
((unsigned long) dest % 0x4000), c, n);
- restore_flags(flags);
+ pr_debug("%s: set page to %#x\n",adapter[card]->devicename,
+ ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
return ret;
}
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index f5f26a6d9450..7774488cf1f1 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -62,8 +62,7 @@ void check_reset(unsigned long data)
/* Setup the io ports */
setup_ports(card);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
outb(adapter[card]->ioport[adapter[card]->shmem_pgport],
(adapter[card]->shmem_magic>>14) | 0x80);
sig = (unsigned long) *((unsigned long *)(adapter[card]->rambase + SIG_OFFSET));
@@ -71,18 +70,16 @@ void check_reset(unsigned long data)
/* check the signature */
if(sig == SIGNATURE) {
flushreadfifo(card);
- restore_flags(flags);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
/* See if we need to do a startproc */
if (adapter[card]->StartOnReset)
startproc(card);
- }
- else {
+ } else {
pr_debug("%s: No signature yet, waiting another %d jiffies.\n",
adapter[card]->devicename, CHECKRESET_TIME);
mod_timer(&adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
}
- restore_flags(flags);
-
}
/*
@@ -122,10 +119,9 @@ void check_phystat(unsigned long data)
adapter[card]->phystat = adapter[card]->nphystat;
/* Reinitialize the timer */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&adapter[card]->lock, flags);
mod_timer(&adapter[card]->stat_timer, jiffies+CHECKSTAT_TIME);
- restore_flags(flags);
+ spin_unlock_irqrestore(&adapter[card]->lock, flags);
/* Send a new cePhyStatus message */
sendmessage(card, CEPID,ceReqTypePhy,ceReqClass2,
@@ -146,11 +142,5 @@ void check_phystat(unsigned long data)
*/
void trace_timer(unsigned long data)
{
- unsigned long flags;
-
- /*
- * Disable interrupts and swap the first page
- */
- save_flags(flags);
- cli();
+ /* not implemented */
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index bb6409ccace2..40ca8ea7f3a2 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1391,10 +1391,10 @@ next:
if (pmu_battery_count)
query_battery_state();
pmu_pass_intr(data, len);
- } else
+ } else {
pmu_pass_intr(data, len);
-
#endif /* CONFIG_PMAC_PBOOK */
+ }
goto next;
}
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 76f91782da48..3f3ef3025c13 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -115,6 +115,7 @@ MODULE_PARM(v4l2,"i");
MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
/* kernel args */
#ifndef MODULE
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index a5a449a4a7d9..680507243d4a 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -475,6 +475,8 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
(struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+ if (sges_left == 0)
+ return FAILED;
} else if (SCpnt->request_bufflen) {
dma_addr_t buf_dma_addr;
scPrivate *my_priv;
@@ -3328,9 +3330,8 @@ mptscsih_slave_configure(Scsi_Device *device)
device, device->id, device->lun, device->channel));
dsprintk((KERN_INFO "sdtr %d wdtr %d ppr %d inq length=%d\n",
device->sdtr, device->wdtr, device->ppr, device->inquiry_len));
- dsprintk(("tagged %d queue %d simple %d ordered %d\n",
- device->tagged_supported, device->tagged_queue,
- device->simple_tags, device->ordered_tags));
+ dsprintk(("tagged %d simple %d ordered %d\n",
+ device->tagged_supported, device->simple_tags, device->ordered_tags));
/* set target parameters, queue depths, set dv flags ? */
if (hd && (hd->Targets != NULL)) {
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index df5f96439afa..74fd4100332b 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -604,7 +604,7 @@ out1:
pnp_device_detach(idev);
#endif
out:
- kfree(dev);
+ free_netdev(dev);
return err;
}
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 4e3eabe1e5ea..572de917454d 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1468,7 +1468,7 @@ free_ring:
free_region:
if (vp->must_free_region)
release_region(ioaddr, vci->io_size);
- kfree (dev);
+ free_netdev(dev);
printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
return retval;
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a49241c1ae23..fc3c04c6c7bc 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1768,7 +1768,7 @@ err_out_mwi:
err_out_disable:
pci_disable_device(pdev);
err_out_free:
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bd556e7dfff4..2e3fabd23b9a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -132,8 +132,8 @@ config TUN
If you don't know what to use this for, you don't need it.
config ETHERTAP
- tristate "Ethertap network tap (OBSOLETE)"
- depends on NETDEVICES && EXPERIMENTAL
+ tristate "Ethertap network tap"
+ depends on NETDEVICES && EXPERIMENTAL && NETLINK_DEV
---help---
If you say Y here (and have said Y to "Kernel/User network link
driver", above) and create a character special file /dev/tap0 with
diff --git a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib
index 7df0a28a5ea3..b2ade8a877ff 100644
--- a/drivers/net/Makefile.lib
+++ b/drivers/net/Makefile.lib
@@ -5,6 +5,7 @@ obj-$(CONFIG_A2065) += crc32.o
obj-$(CONFIG_ARM_AM79C961A) += crc32.o
obj-$(CONFIG_AT1700) += crc32.o
obj-$(CONFIG_ATP) += crc32.o
+obj-$(CONFIG_BMAC) += crc32.o
obj-$(CONFIG_DE2104X) += crc32.o
obj-$(CONFIG_DE4X5) += crc32.o
obj-$(CONFIG_DECLANCE) += crc32.o
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 838c59729c71..be24e20a5cb1 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -32,14 +32,13 @@
*/
#include <linux/config.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/trdevice.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netlink.h>
#include <linux/divert.h>
-#define NEXT_DEV NULL
-
-
/* A unified ethernet device probe. This is the easiest way to have every
ethernet adaptor have the name "eth[0123...]".
*/
@@ -62,7 +61,6 @@ extern int eth16i_probe(struct net_device *);
extern int depca_probe(struct net_device *);
extern int i82596_probe(struct net_device *);
extern int ewrk3_probe(struct net_device *);
-extern int de4x5_probe(struct net_device *);
extern int el1_probe(struct net_device *);
extern int wavelan_probe(struct net_device *);
extern int arlan_probe(struct net_device *);
@@ -89,7 +87,6 @@ extern int apne_probe(struct net_device *);
extern int bionet_probe(struct net_device *);
extern int pamsnet_probe(struct net_device *);
extern int cs89x0_probe(struct net_device *dev);
-extern int ethertap_probe(struct net_device *dev);
extern int hplance_probe(struct net_device *dev);
extern int bagetlance_probe(struct net_device *);
extern int mvme147lance_probe(struct net_device *dev);
@@ -100,6 +97,9 @@ extern int macsonic_probe(struct net_device *dev);
extern int mac8390_probe(struct net_device *dev);
extern int mac89x0_probe(struct net_device *dev);
extern int mc32_probe(struct net_device *dev);
+extern struct net_device *sdla_init(void);
+extern struct net_device *cops_probe(int unit);
+extern struct net_device *ltpc_probe(void);
/* Detachable devices ("pocket adaptors") */
extern int de620_probe(struct net_device *);
@@ -108,7 +108,7 @@ extern int de620_probe(struct net_device *);
extern int iph5526_probe(struct net_device *dev);
/* SBNI adapters */
-extern int sbni_probe(struct net_device *);
+extern int sbni_probe(void);
struct devprobe
{
@@ -153,12 +153,9 @@ static int __init probe_list(struct net_device *dev, struct devprobe *plist)
* This is a bit of an artificial separation as there are PCI drivers
* that also probe for EISA cards (in the PCI group) and there are ISA
* drivers that probe for EISA cards (in the ISA group). These are the
- * EISA only driver probes, and also the legacy PCI probes
+ * legacy EISA only driver probes, and also the legacy PCI probes
*/
static struct devprobe eisa_probes[] __initdata = {
-#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */
- {de4x5_probe, 0},
-#endif
#ifdef CONFIG_ULTRA32
{ultra32_probe, 0},
#endif
@@ -357,135 +354,43 @@ static struct devprobe mips_probes[] __initdata = {
* per bus interface. This drives the legacy devices only for now.
*/
-static int __init ethif_probe(struct net_device *dev)
+static int __init ethif_probe(void)
{
- unsigned long base_addr = dev->base_addr;
+ struct net_device *dev;
+ int err = -ENODEV;
+
+ dev = alloc_etherdev(0);
+ if (!dev)
+ return -ENOMEM;
+
+ netdev_boot_setup_check(dev);
/*
* Backwards compatibility - historically an I/O base of 1 was
* used to indicate not to probe for this ethN interface
*/
- if (base_addr == 1)
- return 1; /* ENXIO */
+ if (dev->base_addr == 1) {
+ free_netdev(dev);
+ return -ENXIO;
+ }
/*
* The arch specific probes are 1st so that any on-board ethernet
* will be probed before other ISA/EISA/MCA/PCI bus cards.
*/
- if (probe_list(dev, m68k_probes) == 0)
- return 0;
- if (probe_list(dev, mips_probes) == 0)
- return 0;
- if (probe_list(dev, eisa_probes) == 0)
- return 0;
- if (probe_list(dev, mca_probes) == 0)
- return 0;
- if (probe_list(dev, isa_probes) == 0)
- return 0;
- if (probe_list(dev, parport_probes) == 0)
- return 0;
- return -ENODEV;
-}
-
-#ifdef CONFIG_ETHERTAP
-static struct net_device tap0_dev = {
- .name = "tap0",
- .base_addr = NETLINK_TAPBASE,
- .next = NEXT_DEV,
- .init = ethertap_probe,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&tap0_dev)
-#endif
-
-#ifdef CONFIG_SDLA
-extern int sdla_init(struct net_device *);
-static struct net_device sdla0_dev = {
- .name = "sdla0",
- .next = NEXT_DEV,
- .init = sdla_init,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&sdla0_dev)
-#endif
-
-#if defined(CONFIG_LTPC)
-extern int ltpc_probe(struct net_device *);
-static struct net_device dev_ltpc = {
- .name = "lt0",
- .next = NEXT_DEV,
- .init = ltpc_probe
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&dev_ltpc)
-#endif /* LTPC */
-
-#if defined(CONFIG_COPS)
-extern int cops_probe(struct net_device *);
-static struct net_device cops2_dev = {
- .name = "lt2",
- .next = NEXT_DEV,
- .init = cops_probe,
-};
-static struct net_device cops1_dev = {
- .name = "lt1",
- .next = &cops2_dev,
- .init = cops_probe,
-};
-static struct net_device cops0_dev = {
- .name = "lt0",
- .next = &cops1_dev,
- .init = cops_probe,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&cops0_dev)
-#endif /* COPS */
-
-static struct net_device eth7_dev = {
- .name = "eth%d",
- .next = NEXT_DEV,
- .init = ethif_probe,
-};
-static struct net_device eth6_dev = {
- .name = "eth%d",
- .next = &eth7_dev,
- .init = ethif_probe,
-};
-static struct net_device eth5_dev = {
- .name = "eth%d",
- .next = &eth6_dev,
- .init = ethif_probe,
-};
-static struct net_device eth4_dev = {
- .name = "eth%d",
- .next = &eth5_dev,
- .init = ethif_probe,
-};
-static struct net_device eth3_dev = {
- .name = "eth%d",
- .next = &eth4_dev,
- .init = ethif_probe,
-};
-static struct net_device eth2_dev = {
- .name = "eth%d",
- .next = &eth3_dev,
- .init = ethif_probe,
-};
-static struct net_device eth1_dev = {
- .name = "eth%d",
- .next = &eth2_dev,
- .init = ethif_probe,
-};
-static struct net_device eth0_dev = {
- .name = "eth%d",
- .next = &eth1_dev,
- .init = ethif_probe,
-};
-
-#undef NEXT_DEV
-#define NEXT_DEV (&eth0_dev)
-
+ if (probe_list(dev, m68k_probes) == 0 ||
+ probe_list(dev, mips_probes) == 0 ||
+ probe_list(dev, eisa_probes) == 0 ||
+ probe_list(dev, mca_probes) == 0 ||
+ probe_list(dev, isa_probes) == 0 ||
+ probe_list(dev, parport_probes) == 0)
+ err = register_netdev(dev);
+
+ if (err)
+ free_netdev(dev);
+ return err;
+}
#ifdef CONFIG_TR
/* Token-ring device probe */
@@ -494,129 +399,82 @@ extern int sk_isa_probe(struct net_device *);
extern int proteon_probe(struct net_device *);
extern int smctr_probe(struct net_device *);
-static int
-trif_probe(struct net_device *dev)
+static __init int trif_probe(void)
{
- if (1
+ struct net_device *dev;
+ int err = -ENODEV;
+
+ dev = alloc_trdev(0);
+ if (!dev)
+ return -ENOMEM;
+
+ netdev_boot_setup_check(dev);
+ if (
#ifdef CONFIG_IBMTR
- && ibmtr_probe(dev)
+ ibmtr_probe(dev) == 0 ||
#endif
#ifdef CONFIG_SKISA
- && sk_isa_probe(dev)
+ sk_isa_probe(dev) == 0 ||
#endif
#ifdef CONFIG_PROTEON
- && proteon_probe(dev)
+ proteon_probe(dev) == 0 ||
#endif
#ifdef CONFIG_SMCTR
- && smctr_probe(dev)
+ smctr_probe(dev) == 0 ||
#endif
- && 1 ) {
- return 1; /* -ENODEV or -EAGAIN would be more accurate. */
- }
- return 0;
-}
-static struct net_device tr7_dev = {
- .name = "tr%d",
- .next = NEXT_DEV,
- .init = trif_probe,
-};
-static struct net_device tr6_dev = {
- .name = "tr%d",
- .next = &tr7_dev,
- .init = trif_probe,
-};
-static struct net_device tr5_dev = {
- .name = "tr%d",
- .next = &tr6_dev,
- .init = trif_probe,
-};
-static struct net_device tr4_dev = {
- .name = "tr%d",
- .next = &tr5_dev,
- .init = trif_probe,
-};
-static struct net_device tr3_dev = {
- .name = "tr%d",
- .next = &tr4_dev,
- .init = trif_probe,
-};
-static struct net_device tr2_dev = {
- .name = "tr%d",
- .next = &tr3_dev,
- .init = trif_probe,
-};
-static struct net_device tr1_dev = {
- .name = "tr%d",
- .next = &tr2_dev,
- .init = trif_probe,
-};
-static struct net_device tr0_dev = {
- .name = "tr%d",
- .next = &tr1_dev,
- .init = trif_probe,
-};
-#undef NEXT_DEV
-#define NEXT_DEV (&tr0_dev)
+ 0 )
+ err = register_netdev(dev);
+
+ if (err)
+ free_netdev(dev);
+ return err;
-#endif
-
-#ifdef CONFIG_SBNI
-static struct net_device sbni7_dev = {
- .name = "sbni7",
- .next = NEXT_DEV,
- .init = sbni_probe,
-};
-static struct net_device sbni6_dev = {
- .name = "sbni6",
- .next = &sbni7_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni5_dev = {
- .name = "sbni5",
- .next = &sbni6_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni4_dev = {
- .name = "sbni4",
- .next = &sbni5_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni3_dev = {
- .name = "sbni3",
- .next = &sbni4_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni2_dev = {
- .name = "sbni2",
- .next = &sbni3_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni1_dev = {
- .name = "sbni1",
- .next = &sbni2_dev,
- .init = sbni_probe,
-};
-static struct net_device sbni0_dev = {
- .name = "sbni0",
- .next = &sbni1_dev,
- .init = sbni_probe,
-};
+}
+#endif
-#undef NEXT_DEV
-#define NEXT_DEV (&sbni0_dev)
-#endif
/*
* The loopback device is global so it can be directly referenced
* by the network code. Also, it must be first on device list.
*/
+extern int loopback_init(void);
-extern int loopback_init(struct net_device *dev);
-struct net_device loopback_dev = {
- .name = "lo",
- .next = NEXT_DEV,
- .init = loopback_init
-};
+/* Statically configured drivers -- order matters here. */
+void __init probe_old_netdevs(void)
+{
+ int num;
+
+ if (loopback_init()) {
+ printk(KERN_ERR "Network loopback device setup failed\n");
+ }
+
+
+#ifdef CONFIG_SBNI
+ for (num = 0; num < 8; ++num)
+ if (sbni_probe())
+ break;
+#endif
+#ifdef CONFIG_TR
+ for (num = 0; num < 8; ++num)
+ if (trif_probe())
+ break;
+#endif
+ for (num = 0; num < 8; ++num)
+ if (ethif_probe())
+ break;
+#ifdef CONFIG_COPS
+ cops_probe(0);
+ cops_probe(1);
+ cops_probe(2);
+#endif
+#ifdef CONFIG_LTPC
+ ltpc_probe();
+#endif
+#ifdef CONFIG_SDLA
+ sdla_init();
+#endif
+
+}
/*
* The @dev_base list is protected by @dev_base_lock and the rtln
@@ -637,6 +495,6 @@ struct net_device loopback_dev = {
* unregister_netdevice(), which must be called with the rtnl
* semaphore held.
*/
-struct net_device *dev_base = &loopback_dev;
+struct net_device *dev_base;
rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index d6a4fdcec957..3350a70c2103 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -685,7 +685,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
}
if (pci_enable_device(pdev)) {
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -733,7 +733,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
if (register_netdev(dev)) {
printk(KERN_ERR "acenic: device registration failed\n");
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -793,7 +793,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
printk(KERN_ERR "%s: Driver compiled without Tigon I"
" support - NIC disabled\n", dev->name);
ace_init_cleanup(dev);
- kfree(dev);
+ free_netdev(dev);
continue;
}
#endif
@@ -803,7 +803,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
* ace_allocate_descriptors() calls
* ace_init_cleanup() on error.
*/
- kfree(dev);
+ free_netdev(dev);
continue;
}
@@ -820,7 +820,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
/*
* ace_init() calls ace_init_cleanup() on error.
*/
- kfree(dev);
+ free_netdev(dev);
continue;
}
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 19464a83fdfb..bc9e1bfc7220 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1927,7 +1927,7 @@ err_iounmap:
iounmap((void *) lp->mmio);
err_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_free_reg:
pci_release_regions(pdev);
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index cb8dac24f286..579cf0d2ee5b 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -92,12 +92,8 @@ static int board_type = DAYNA; /* Module exported */
static int board_type = TANGENT;
#endif
-#ifdef MODULE
static int io = 0x240; /* Default IO for Dayna */
static int irq = 5; /* Default IRQ */
-#else
-static int io; /* Default IO for Dayna */
-#endif
/*
* COPS Autoprobe information.
@@ -146,7 +142,7 @@ static int io; /* Default IO for Dayna */
* Zero terminated list of IO ports to probe.
*/
-static unsigned int cops_portlist[] = {
+static unsigned int ports[] = {
0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
0
@@ -184,7 +180,6 @@ struct cops_local
};
/* Index to functions, as function prototypes. */
-extern int cops_probe (struct net_device *dev);
static int cops_probe1 (struct net_device *dev, int ioaddr);
static int cops_irq (int ioaddr, int board);
@@ -208,6 +203,12 @@ static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev);
static struct net_device_stats *cops_get_stats (struct net_device *dev);
+static void cleanup_card(struct net_device *dev)
+{
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, COPS_IO_EXTENT);
+}
/*
* Check for a network adaptor of this type, and return '0' iff one exists.
@@ -215,31 +216,54 @@ static struct net_device_stats *cops_get_stats (struct net_device *dev);
* If dev->base_addr in [1..0x1ff], always return failure.
* otherwise go with what we pass in.
*/
-int __init cops_probe(struct net_device *dev)
+struct net_device * __init cops_probe(int unit)
{
- int i;
- int base_addr = dev->base_addr;
+ struct net_device *dev;
+ unsigned *port;
+ int base_addr;
+ int err = 0;
+
+ dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ if (unit >= 0) {
+ sprintf(dev->name, "lt%d", unit);
+ netdev_boot_setup_check(dev);
+ irq = dev->irq;
+ base_addr = dev->base_addr;
+ } else {
+ base_addr = dev->base_addr = io;
+ }
SET_MODULE_OWNER(dev);
- if(base_addr == 0 && io)
- base_addr=io;
-
- if(base_addr > 0x1ff) /* Check a single specified location. */
- return cops_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- /* FIXME Does this really work for cards which generate irq?
- * It's definitely N.G. for polled Tangent. sh
- * Dayna cards don't autoprobe well at all, but if your card is
- * at IRQ 5 & IO 0x240 we find it every time. ;) JS
- */
- for(i=0; cops_portlist[i]; i++)
- if(cops_probe1(dev, cops_portlist[i]) == 0)
- return 0;
-
- return -ENODEV;
+ if (base_addr > 0x1ff) { /* Check a single specified location. */
+ err = cops_probe1(dev, base_addr);
+ } else if (base_addr != 0) { /* Don't probe at all. */
+ err = -ENXIO;
+ } else {
+ /* FIXME Does this really work for cards which generate irq?
+ * It's definitely N.G. for polled Tangent. sh
+ * Dayna cards don't autoprobe well at all, but if your card is
+ * at IRQ 5 & IO 0x240 we find it every time. ;) JS
+ */
+ for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
+ ;
+ if (!*port)
+ err = -ENODEV;
+ }
+ if (err)
+ goto out;
+ err = register_netdev(dev);
+ if (err)
+ goto out1;
+ return dev;
+out1:
+ cleanup_card(dev);
+out:
+ kfree(dev);
+ return ERR_PTR(err);
}
/*
@@ -268,16 +292,15 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
* interrupts are typically not reported by the boards, and we must
* used AutoIRQ to find them.
*/
+ dev->irq = irq;
switch (dev->irq)
{
case 0:
/* COPS AutoIRQ routine */
dev->irq = cops_irq(ioaddr, board);
- if(!dev->irq) {
- retval = -EINVAL; /* No IRQ found on this port */
- goto err_out;
- }
-
+ if (dev->irq)
+ break;
+ /* No IRQ found on this port, fallthrough */
case 1:
retval = -EINVAL;
goto err_out;
@@ -302,22 +325,13 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
}
/* Reserve any actual interrupt. */
- if(dev->irq) {
+ if (dev->irq) {
retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
if (retval)
goto err_out;
}
- dev->base_addr = ioaddr;
-
- /* Initialize the private device structure. */
- dev->priv = kmalloc(sizeof(struct cops_local), GFP_KERNEL);
- if(dev->priv == NULL) {
- if (dev->irq)
- free_irq(dev->irq, dev);
- retval = -ENOMEM;
- goto err_out;
- }
+ dev->base_addr = ioaddr;
lp = (struct cops_local *)dev->priv;
memset(lp, 0, sizeof(struct cops_local));
@@ -326,9 +340,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Copy local board variable to lp struct. */
lp->board = board;
- /* Fill in the fields of the device structure with LocalTalk values. */
- ltalk_setup(dev);
-
dev->hard_start_xmit = cops_send_packet;
dev->tx_timeout = cops_timeout;
dev->watchdog_timeo = HZ * 2;
@@ -1013,7 +1024,7 @@ static struct net_device_stats *cops_get_stats(struct net_device *dev)
}
#ifdef MODULE
-static struct net_device cops0_dev = { .init = cops_probe };
+static struct net_device *cops_dev;
MODULE_LICENSE("GPL");
MODULE_PARM(io, "i");
@@ -1022,33 +1033,20 @@ MODULE_PARM(board_type, "i");
int init_module(void)
{
- int result, err;
-
- if(io == 0)
+ if (io == 0)
printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
cardname);
-
- /* Copy the parameters from insmod into the device structure. */
- cops0_dev.base_addr = io;
- cops0_dev.irq = irq;
-
- err=dev_alloc_name(&cops0_dev, "lt%d");
- if(err < 0)
- return err;
-
- if((result = register_netdev(&cops0_dev)) != 0)
- return result;
-
+ cops_dev = cops_probe(-1);
+ if (IS_ERR(cops_dev))
+ return PTR_ERR(cops_dev);
return 0;
}
void cleanup_module(void)
{
- unregister_netdev(&cops0_dev);
- kfree(cops0_dev.priv);
- if(cops0_dev.irq)
- free_irq(cops0_dev.irq, &cops0_dev);
- release_region(cops0_dev.base_addr, COPS_IO_EXTENT);
+ unregister_netdev(cops_dev);
+ cleanup_card(cops_dev);
+ free_netdev(cops_dev);
}
#endif /* MODULE */
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index ddbd4f765b12..1b10bc14867c 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -879,34 +879,6 @@ static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev,
return 0;
}
-static int ltpc_init(struct net_device *dev)
-{
- /* Initialize the device structure. */
-
- /* Fill in the fields of the device structure with ethernet-generic values. */
- ltalk_setup(dev);
- dev->hard_start_xmit = ltpc_xmit;
- dev->hard_header = ltpc_hard_header;
-
- dev->priv = kmalloc(sizeof(struct ltpc_private), GFP_KERNEL);
- if(!dev->priv)
- {
- printk(KERN_INFO "%s: could not allocate statistics buffer\n", dev->name);
- return -ENOMEM;
- }
-
- memset(dev->priv, 0, sizeof(struct ltpc_private));
- dev->get_stats = ltpc_get_stats;
-
- /* add the ltpc-specific things */
- dev->do_ioctl = &ltpc_ioctl;
-
- dev->set_multicast_list = &set_multicast_list;
- dev->mc_list = NULL;
-
- return 0;
-}
-
static int ltpc_poll_counter;
static void ltpc_poll(unsigned long l)
@@ -983,35 +955,40 @@ static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
/* initialization stuff */
-static int __init ltpc_probe_dma(int base)
+static int __init ltpc_probe_dma(int base, int dma)
{
- int dma = 0;
+ int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3;
unsigned long timeout;
unsigned long f;
- if (!request_dma(1,"ltpc")) {
- f=claim_dma_lock();
- disable_dma(1);
- clear_dma_ff(1);
- set_dma_mode(1,DMA_MODE_WRITE);
- set_dma_addr(1,virt_to_bus(ltdmabuf));
- set_dma_count(1,sizeof(struct lt_mem));
- enable_dma(1);
- release_dma_lock(f);
- dma|=1;
+ if (want & 1) {
+ if (request_dma(1,"ltpc")) {
+ want &= ~1;
+ } else {
+ f=claim_dma_lock();
+ disable_dma(1);
+ clear_dma_ff(1);
+ set_dma_mode(1,DMA_MODE_WRITE);
+ set_dma_addr(1,virt_to_bus(ltdmabuf));
+ set_dma_count(1,sizeof(struct lt_mem));
+ enable_dma(1);
+ release_dma_lock(f);
+ }
}
- if (!request_dma(3,"ltpc")) {
- f=claim_dma_lock();
- disable_dma(3);
- clear_dma_ff(3);
- set_dma_mode(3,DMA_MODE_WRITE);
- set_dma_addr(3,virt_to_bus(ltdmabuf));
- set_dma_count(3,sizeof(struct lt_mem));
- enable_dma(3);
- release_dma_lock(f);
- dma|=2;
+ if (want & 2) {
+ if (request_dma(3,"ltpc")) {
+ want &= ~2;
+ } else {
+ f=claim_dma_lock();
+ disable_dma(3);
+ clear_dma_ff(3);
+ set_dma_mode(3,DMA_MODE_WRITE);
+ set_dma_addr(3,virt_to_bus(ltdmabuf));
+ set_dma_count(3,sizeof(struct lt_mem));
+ enable_dma(3);
+ release_dma_lock(f);
+ }
}
-
/* set up request */
/* FIXME -- do timings better! */
@@ -1037,65 +1014,62 @@ static int __init ltpc_probe_dma(int base)
/* release the other dma channel (if we opened both of them) */
- if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){
- dma&=1;
+ if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) {
+ want &= ~2;
free_dma(3);
}
-
- if ( (dma&0x1) && (get_dma_residue(1)==sizeof(struct lt_mem)) ){
- dma&=0x2;
+
+ if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) {
+ want &= ~1;
free_dma(1);
}
- /* fix up dma number */
- dma|=1;
+ if (!want)
+ return 0;
- return dma;
+ return (want & 2) ? 3 : 1;
}
-int __init ltpc_probe(struct net_device *dev)
+struct net_device * __init ltpc_probe(void)
{
- int err;
+ struct net_device *dev;
+ int err = -ENOMEM;
int x=0,y=0;
int autoirq;
unsigned long f;
- int portfound=0;
unsigned long timeout;
+ dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup);
+ if (!dev)
+ goto out;
+
SET_MODULE_OWNER(dev);
/* probe for the I/O port address */
+
if (io != 0x240 && request_region(0x220,8,"ltpc")) {
x = inb_p(0x220+6);
if ( (x!=0xff) && (x>=0xf0) ) {
io = 0x220;
- portfound=1;
- }
- else {
- release_region(0x220,8);
+ goto got_port;
}
+ release_region(0x220,8);
}
-
if (io != 0x220 && request_region(0x240,8,"ltpc")) {
y = inb_p(0x240+6);
if ( (y!=0xff) && (y>=0xf0) ){
io = 0x240;
- portfound=1;
- }
- else {
- release_region(0x240,8);
+ goto got_port;
}
+ release_region(0x240,8);
}
- if(io && !portfound && request_region(io,8,"ltpc")){
- portfound = 1;
- }
- if(!portfound) {
- /* give up in despair */
- printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y);
- return -1;
- }
+ /* give up in despair */
+ printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y);
+ err = -ENODEV;
+ goto out1;
+ got_port:
/* probe for the IRQ line */
if (irq < 2) {
unsigned long irq_mask;
@@ -1111,22 +1085,21 @@ int __init ltpc_probe(struct net_device *dev)
if (autoirq == 0) {
printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io);
- }
- else {
+ } else {
irq = autoirq;
}
}
/* allocate a DMA buffer */
ltdmabuf = (unsigned char *) dma_mem_alloc(1000);
-
- if (ltdmabuf) ltdmacbuf = &ltdmabuf[800];
-
if (!ltdmabuf) {
printk(KERN_ERR "ltpc: mem alloc failed\n");
- return -1;
+ err = -ENOMEM;
+ goto out2;
}
+ ltdmacbuf = &ltdmabuf[800];
+
if(debug & DEBUG_VERBOSE) {
printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf);
}
@@ -1154,25 +1127,29 @@ int __init ltpc_probe(struct net_device *dev)
already been specified */
/* well, 0 is a legal DMA channel, but the LTPC card doesn't
use it... */
- if (dma == 0) {
- dma = ltpc_probe_dma(io);
- if (!dma) { /* no dma channel */
- printk(KERN_ERR "No DMA channel found on ltpc card.\n");
- return -1;
- }
+ dma = ltpc_probe_dma(io, dma);
+ if (!dma) { /* no dma channel */
+ printk(KERN_ERR "No DMA channel found on ltpc card.\n");
+ err = -ENODEV;
+ goto out3;
}
/* print out friendly message */
-
if(irq)
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma);
else
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
- /* seems more logical to do this *after* probing the card... */
- err = ltpc_init(dev);
- if (err) return err;
+ /* Fill in the fields of the device structure with ethernet-generic values. */
+ dev->hard_start_xmit = ltpc_xmit;
+ dev->hard_header = ltpc_hard_header;
+ dev->get_stats = ltpc_get_stats;
+ /* add the ltpc-specific things */
+ dev->do_ioctl = &ltpc_ioctl;
+
+ dev->set_multicast_list = &set_multicast_list;
+ dev->mc_list = NULL;
dev->base_addr = io;
dev->irq = irq;
dev->dma = dma;
@@ -1212,6 +1189,7 @@ int __init ltpc_probe(struct net_device *dev)
} else {
if( irq )
printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n");
+ dev->irq = 0;
/* polled mode -- 20 times per second */
/* this is really, really slow... should it poll more often? */
init_timer(&ltpc_timer);
@@ -1221,8 +1199,23 @@ int __init ltpc_probe(struct net_device *dev)
ltpc_timer.expires = jiffies + HZ/20;
add_timer(&ltpc_timer);
}
+ err = register_netdev(dev);
+ if (err)
+ goto out4;
return 0;
+out4:
+ del_timer_sync(&ltpc_timer);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+out3:
+ free_pages((unsigned long)ltdmabuf, get_order(1000));
+out2:
+ release_region(io, 8);
+out1:
+ kfree(dev);
+out:
+ return ERR_PTR(err);
}
#ifndef MODULE
@@ -1259,7 +1252,7 @@ static int __init ltpc_setup(char *str)
__setup("ltpc=", ltpc_setup);
#endif /* MODULE */
-static struct net_device dev_ltpc;
+static struct net_device *dev_ltpc;
#ifdef MODULE
@@ -1272,79 +1265,47 @@ MODULE_PARM(dma, "i");
int __init init_module(void)
{
- int err, result;
-
if(io == 0)
printk(KERN_NOTICE
"ltpc: Autoprobing is not recommended for modules\n");
- /* Find a name for this unit */
- dev_ltpc.init = ltpc_probe;
- err=dev_alloc_name(&dev_ltpc,"lt%d");
-
- if(err<0)
- return err;
-
- if ((result = register_netdev(&dev_ltpc)) != 0) {
- printk(KERN_DEBUG "could not register Localtalk-PC device\n");
- return result;
- } else {
- if(debug & DEBUG_VERBOSE) printk("0 from register_netdev\n");
- return 0;
- }
+ dev_ltpc = ltpc_probe();
+ if (IS_ERR(dev_ltpc))
+ return PTR_ERR(dev_ltpc);
+ return 0;
}
#endif
static void __exit ltpc_cleanup(void)
{
- unsigned long timeout;
+
+ if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
+ unregister_netdev(dev_ltpc);
ltpc_timer.data = 0; /* signal the poll routine that we're done */
+ del_timer_sync(&ltpc_timer);
+
if(debug & DEBUG_VERBOSE) printk("freeing irq\n");
- if(dev_ltpc.irq) {
- free_irq(dev_ltpc.irq,&dev_ltpc);
- dev_ltpc.irq = 0;
- }
-
- if(del_timer(&ltpc_timer))
- {
- /* either the poll was never started, or a poll is in process */
- if(debug & DEBUG_VERBOSE) printk("waiting\n");
- /* if it's in process, wait a bit for it to finish */
- timeout = jiffies+HZ;
- add_timer(&ltpc_timer);
- while(del_timer(&ltpc_timer) && time_after(timeout, jiffies))
- {
- add_timer(&ltpc_timer);
- schedule();
- }
- }
+ if (dev_ltpc->irq)
+ free_irq(dev_ltpc->irq, dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("freeing dma\n");
- if(dev_ltpc.dma) {
- free_dma(dev_ltpc.dma);
- dev_ltpc.dma = 0;
- }
+ if (dev_ltpc->dma)
+ free_dma(dev_ltpc->dma);
if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n");
- if(dev_ltpc.base_addr) {
- release_region(dev_ltpc.base_addr,8);
- dev_ltpc.base_addr = 0;
- }
+ if (dev_ltpc->base_addr)
+ release_region(dev_ltpc->base_addr,8);
+
+ free_netdev(dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("free_pages\n");
free_pages( (unsigned long) ltdmabuf, get_order(1000));
- ltdmabuf=NULL;
- ltdmacbuf=NULL;
-
- if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
-
- unregister_netdev(&dev_ltpc);
if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n");
}
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index b759af47913d..ef10d16fd679 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1834,7 +1834,7 @@ err_out_iounmap:
iounmap((void *) bp->regs);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_free_res:
pci_release_regions(pdev);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index ed7874f4fe4e..27bc8ed937cf 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1462,7 +1462,7 @@ out2:
release_OF_resource(bp->node, 0);
out1:
pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
- kfree(dev);
+ free_netdev(dev);
}
static int bmac_open(struct net_device *dev)
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 00ddd19e0fd2..d28d864cbaa5 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1275,7 +1275,7 @@ dgrs_found_device(
SET_MODULE_OWNER(dev);
if (register_netdev(dev) != 0) {
- kfree(dev);
+ free_netdev(dev);
return -EIO;
}
@@ -1322,7 +1322,7 @@ dgrs_found_device(
ret = -EIO;
if (register_netdev(devN)) {
- kfree(devN);
+ free_netdev(devN);
goto fail;
}
privN->chan = i+1;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index d0fba4cb4df4..76f1d66eb6c1 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -319,7 +319,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_dev:
#endif
- kfree (dev);
+ free_netdev (dev);
err_out_res:
pci_release_regions (pdev);
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 2a14f46f6014..02c2db84f603 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -894,7 +894,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
err_free_unlock:
rtnl_unlock();
- kfree(dev);
+ free_netdev(dev);
return -1;
}
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 93fdb1469a0c..00bbf4b7baea 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -565,7 +565,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
return -ENODEV;
}
diff --git a/drivers/net/ethertap.c b/drivers/net/ethertap.c
index 5f8162612c25..0656fefa9670 100644
--- a/drivers/net/ethertap.c
+++ b/drivers/net/ethertap.c
@@ -33,7 +33,6 @@
* Index to functions.
*/
-int ethertap_probe(struct net_device *dev);
static int ethertap_open(struct net_device *dev);
static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int ethertap_close(struct net_device *dev);
@@ -45,7 +44,11 @@ static void set_multicast_list(struct net_device *dev);
static int ethertap_debug;
-static struct net_device *tap_map[32]; /* Returns the tap device for a given netlink */
+static int max_taps = 1;
+MODULE_PARM(max_taps, "i");
+MODULE_PARM_DESC(max_taps,"Max number of ethernet tap devices");
+
+static struct net_device **tap_map; /* Returns the tap device for a given netlink */
/*
* Board-specific info in dev->priv.
@@ -64,25 +67,29 @@ struct net_local
* To call this a probe is a bit misleading, however for real
* hardware it would have to check what was present.
*/
-
-int __init ethertap_probe(struct net_device *dev)
+static int __init ethertap_probe(int unit)
{
+ struct net_device *dev;
+ int err = -ENOMEM;
+
+ dev = alloc_netdev(sizeof(struct net_local), "tap%d",
+ ether_setup);
+
+ if (!dev)
+ goto out;
+
SET_MODULE_OWNER(dev);
+ sprintf(dev->name, "tap%d", unit);
+ dev->base_addr = unit + NETLINK_TAPBASE;
+
+ netdev_boot_setup_check(dev);
+
memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6);
if (dev->mem_start & 0xf)
ethertap_debug = dev->mem_start & 0x7;
/*
- * Initialize the device structure.
- */
-
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- /*
* The tap specific entries in the device structure.
*/
@@ -94,17 +101,19 @@ int __init ethertap_probe(struct net_device *dev)
dev->set_multicast_list = set_multicast_list;
#endif
- /*
- * Setup the generic properties
- */
-
- ether_setup(dev);
-
dev->tx_queue_len = 0;
dev->flags|=IFF_NOARP;
- tap_map[dev->base_addr]=dev;
+ err = register_netdev(dev);
+ if (err)
+ goto out_free;
+
+ tap_map[unit]=dev;
return 0;
+out_free:
+ free_netdev(dev);
+out:
+ return err;
}
/*
@@ -116,11 +125,12 @@ static int ethertap_open(struct net_device *dev)
struct net_local *lp = (struct net_local*)dev->priv;
if (ethertap_debug > 2)
- printk("%s: Doing ethertap_open()...", dev->name);
+ printk(KERN_DEBUG "%s: Doing ethertap_open()...", dev->name);
lp->nl = netlink_kernel_create(dev->base_addr, ethertap_rx);
if (lp->nl == NULL)
return -ENOBUFS;
+
netif_start_queue(dev);
return 0;
}
@@ -302,7 +312,7 @@ static void ethertap_rx(struct sock *sk, int len)
}
if (ethertap_debug > 3)
- printk("%s: ethertap_rx()\n", dev->name);
+ printk(KERN_DEBUG "%s: ethertap_rx()\n", dev->name);
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
ethertap_rx_skb(skb, dev);
@@ -314,7 +324,7 @@ static int ethertap_close(struct net_device *dev)
struct sock *sk = lp->nl;
if (ethertap_debug > 2)
- printk("%s: Shutting down.\n", dev->name);
+ printk(KERN_DEBUG "%s: Shutting down.\n", dev->name);
netif_stop_queue(dev);
@@ -332,45 +342,49 @@ static struct net_device_stats *ethertap_get_stats(struct net_device *dev)
return &lp->stats;
}
-#ifdef MODULE
-
-static int unit;
-MODULE_PARM(unit,"i");
-MODULE_PARM_DESC(unit,"Ethertap device number");
-static struct net_device dev_ethertap =
+int __init ethertap_init(void)
{
- .name = " ",
- .init = ethertap_probe
-};
+ int i, err = 0;
-int init_module(void)
-{
- dev_ethertap.base_addr=unit+NETLINK_TAPBASE;
- sprintf(dev_ethertap.name,"tap%d",unit);
- if (dev_get(dev_ethertap.name))
- {
- printk(KERN_INFO "%s already loaded.\n", dev_ethertap.name);
- return -EBUSY;
+ /* netlink can only hande 16 entries unless modified */
+ if (max_taps > MAX_LINKS - NETLINK_TAPBASE)
+ return -E2BIG;
+
+ tap_map = kmalloc(sizeof(struct net_device *)*max_taps, GFP_KERNEL);
+ if (!tap_map)
+ return -ENOMEM;
+
+ for (i = 0; i < max_taps; i++) {
+ err = ethertap_probe(i);
+ if (err) {
+ while (--i > 0) {
+ unregister_netdev(tap_map[i]);
+ free_netdev(tap_map[i]);
+ }
+ break;
+ }
}
- if (register_netdev(&dev_ethertap) != 0)
- return -EIO;
- return 0;
+ if (err)
+ kfree(tap_map);
+ return err;
}
+module_init(ethertap_init);
-void cleanup_module(void)
+void __exit ethertap_cleanup(void)
{
- tap_map[dev_ethertap.base_addr]=NULL;
- unregister_netdev(&dev_ethertap);
-
- /*
- * Free up the private structure.
- */
-
- kfree(dev_ethertap.priv);
- dev_ethertap.priv = NULL; /* gets re-allocated by ethertap_probe */
+ int i;
+
+ for (i = 0; i < max_taps; i++) {
+ struct net_device *dev = tap_map[i];
+ if (dev) {
+ tap_map[i] = NULL;
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ }
+ kfree(tap_map);
}
+module_exit(ethertap_cleanup);
-#endif /* MODULE */
MODULE_LICENSE("GPL");
-
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index de914dfc56f8..ee1e45180f86 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -689,7 +689,7 @@ err_out_free_tx:
err_out_free_rx:
pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_unmap:
#ifndef USE_IO_OPS
iounmap((void *)ioaddr);
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 36e7074c2bd8..ab87588a7ff3 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -785,7 +785,7 @@ err_out_unmap_tx:
pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring,
hmp->tx_ring_dma);
err_out_cleardev:
- kfree (dev);
+ free_netdev (dev);
err_out_iounmap:
iounmap((char *)ioaddr);
err_out_release:
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 0152d6be4065..ea53fe75059a 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -1064,6 +1064,7 @@ static void decode_data(unsigned char inbyte, struct sixpack *sp)
MODULE_AUTHOR("Andreas Könsgen <ajk@ccac.rwth-aachen.de>");
MODULE_DESCRIPTION("6pack driver for AX.25");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_6PACK);
module_init(sixpack_init_driver);
module_exit(sixpack_exit_driver);
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 2711caa9cb97..c78732698118 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -935,7 +935,7 @@ MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
MODULE_PARM(ax25_maxdev, "i");
MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices");
MODULE_LICENSE("GPL");
-
+MODULE_ALIAS_LDISC(N_AX25);
module_init(mkiss_init_driver);
module_exit(mkiss_exit_driver);
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index c3b4e5f1353d..d93767489ff0 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1512,7 +1512,7 @@ out_stop:
out_res:
pci_release_regions(pdev);
out_free:
- kfree(dev);
+ free_netdev(dev);
return err;
}
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 99d7afc609bc..0d6837d8deb6 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -651,5 +651,6 @@ module_exit(irtty_sir_cleanup);
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("IrDA TTY device driver");
+MODULE_ALIAS_LDISC(N_IRDA);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index b3045c467da8..6f8c223bf68e 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -1543,7 +1543,7 @@ lan_init_chip(struct parisc_device *dev)
retval = register_netdev(netdevice);
if (retval) {
printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval);
- kfree(netdevice);
+ free_netdev(netdevice);
return -ENODEV;
};
if (dev->id.sversion == 0x72) {
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 7382804af6b0..5dd2b3393edc 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -55,6 +55,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
+
#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
/* KISS: just allocate small chunks and copy bits.
@@ -152,10 +153,12 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->last_rx = jiffies;
- stats->rx_bytes+=skb->len;
- stats->tx_bytes+=skb->len;
- stats->rx_packets++;
- stats->tx_packets++;
+ if (likely(stats)) {
+ stats->rx_bytes+=skb->len;
+ stats->tx_bytes+=skb->len;
+ stats->rx_packets++;
+ stats->tx_packets++;
+ }
netif_rx(skb);
@@ -167,36 +170,35 @@ static struct net_device_stats *get_stats(struct net_device *dev)
return (struct net_device_stats *)dev->priv;
}
-/* Initialize the rest of the LOOPBACK device. */
-int __init loopback_init(struct net_device *dev)
-{
- dev->mtu = (16 * 1024) + 20 + 20 + 12;
- dev->hard_start_xmit = loopback_xmit;
- dev->hard_header = eth_header;
- dev->hard_header_cache = eth_header_cache;
- dev->header_cache_update= eth_header_cache_update;
- dev->hard_header_len = ETH_HLEN; /* 14 */
- dev->addr_len = ETH_ALEN; /* 6 */
- dev->tx_queue_len = 0;
- dev->type = ARPHRD_LOOPBACK; /* 0x0001 */
- dev->rebuild_header = eth_rebuild_header;
- dev->flags = IFF_LOOPBACK;
- dev->features = NETIF_F_SG|NETIF_F_FRAGLIST|NETIF_F_NO_CSUM|NETIF_F_HIGHDMA;
-
- /* Current netfilter will die with oom linearizing large skbs,
- * however this will be cured before 2.5.x is done.
- */
- dev->features |= NETIF_F_TSO;
-
- dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_device_stats));
- dev->get_stats = get_stats;
+struct net_device loopback_dev = {
+ .name = "lo",
+ .mtu = (16 * 1024) + 20 + 20 + 12,
+ .hard_start_xmit = loopback_xmit,
+ .hard_header = eth_header,
+ .hard_header_cache = eth_header_cache,
+ .header_cache_update = eth_header_cache_update,
+ .hard_header_len = ETH_HLEN, /* 14 */
+ .addr_len = ETH_ALEN, /* 6 */
+ .tx_queue_len = 0,
+ .type = ARPHRD_LOOPBACK, /* 0x0001*/
+ .rebuild_header = eth_rebuild_header,
+ .flags = IFF_LOOPBACK,
+ .features = NETIF_F_SG|NETIF_F_FRAGLIST
+ |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA|NETIF_F_TSO,
+};
- /*
- * Fill in the generic fields of the device structure.
- */
-
- return(0);
+/* Setup and register the of the LOOPBACK device. */
+int __init loopback_init(void)
+{
+ struct net_device_stats *stats;
+
+ /* Can survive without statistics */
+ stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+ if (stats) {
+ memset(stats, 0, sizeof(struct net_device_stats));
+ loopback_dev.priv = stats;
+ loopback_dev.get_stats = &get_stats;
+ }
+
+ return register_netdev(&loopback_dev);
};
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index fe1e255a576c..3e687d9cbd41 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -1324,7 +1324,7 @@ static int __init lp486e_init_module(void) {
dev->base_addr = io;
dev->init = lp486e_probe;
if (register_netdev(dev) != 0) {
- kfree(dev);
+ free_netdev(dev);
return -EIO;
}
dev_lp486e = dev;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index b95d3030e465..14fbbef63fb6 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -766,7 +766,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
i = pci_request_regions(pdev, dev->name);
if (i) {
- kfree(dev);
+ free_netdev(dev);
return i;
}
@@ -774,7 +774,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
void *mmio = ioremap (ioaddr, iosize);
if (!mmio) {
pci_release_regions(pdev);
- kfree(dev);
+ free_netdev(dev);
return -ENOMEM;
}
ioaddr = (unsigned long) mmio;
@@ -838,7 +838,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
if (i) {
pci_release_regions(pdev);
unregister_netdev(dev);
- kfree(dev);
+ free_netdev(dev);
pci_set_drvdata(pdev, NULL);
return i;
}
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index ad6281ef7a83..2d519b696533 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -529,6 +529,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
struct net_device *dev;
struct pcnet32_access *a = NULL;
u8 promaddr[6];
+ int ret = -ENODEV;
/* reset the chip */
pcnet32_wio_reset(ioaddr);
@@ -540,19 +541,15 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
pcnet32_dwio_reset(ioaddr);
if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
a = &pcnet32_dwio;
- } else {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
- }
+ } else
+ goto err_release_region;
}
chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16);
if (pcnet32_debug > 2)
printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version);
- if ((chip_version & 0xfff) != 0x003) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
- }
+ if ((chip_version & 0xfff) != 0x003)
+ goto err_release_region;
/* initialize variables */
fdx = mii = fset = dxsuflo = ltint = 0;
@@ -614,8 +611,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
default:
printk(KERN_INFO PFX "PCnet version %#x, no PCnet32 chip.\n",
chip_version);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ goto err_release_region;
}
/*
@@ -635,8 +631,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
dev = alloc_etherdev(0);
if(!dev) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_release_region;
}
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -708,8 +704,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
dev->base_addr = ioaddr;
/* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) {
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_free_netdev;
}
memset(lp, 0, sizeof(*lp));
@@ -741,9 +737,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
if (!a) {
printk(KERN_ERR PFX "No access methods\n");
- pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_free_consistent;
}
lp->a = *a;
@@ -785,14 +780,12 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
mdelay (1);
dev->irq = probe_irq_off (irq_mask);
- if (dev->irq)
- printk(", probed IRQ %d.\n", dev->irq);
- else {
+ if (!dev->irq) {
printk(", failed to detect IRQ line.\n");
- pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
- release_region(ioaddr, PCNET32_TOTAL_SIZE);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_free_consistent;
}
+ printk(", probed IRQ %d.\n", dev->irq);
}
/* Set the mii phy_id so that we can query the link state */
@@ -821,6 +814,14 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name);
cards_found++;
return 0;
+
+err_free_consistent:
+ pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
+err_free_netdev:
+ free_netdev(dev);
+err_release_region:
+ release_region(ioaddr, PCNET32_TOTAL_SIZE);
+ return ret;
}
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 09bcc8a0f26f..f6a58b4bc292 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -84,7 +84,7 @@ static int flag_time = HZ;
MODULE_PARM(flag_time, "i");
MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)");
MODULE_LICENSE("GPL");
-
+MODULE_ALIAS_LDISC(N_PPP);
/*
* Prototypes.
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index c96dbc2bd150..6b30d5f28c10 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2670,3 +2670,4 @@ EXPORT_SYMBOL(ppp_unregister_compressor);
EXPORT_SYMBOL(all_ppp_units); /* for debugging */
EXPORT_SYMBOL(all_channels); /* for debugging */
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(PPP_MAJOR);
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 06feb5870fc8..fc93451e6858 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -759,3 +759,4 @@ ppp_sync_cleanup(void)
module_init(ppp_sync_init);
module_exit(ppp_sync_cleanup);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_SYNC_PPP);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a0b4b659aa0e..c11b83e6adeb 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -454,7 +454,7 @@ err_out_disable:
pci_disable_device(pdev);
err_out:
- kfree(dev);
+ free_netdev(dev);
return rc;
}
@@ -514,7 +514,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ioaddr);
pci_release_regions(pdev);
pci_disable_device(pdev);
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
index f5cdead40f14..e7e1a9f2d71a 100644
--- a/drivers/net/rcpci45.c
+++ b/drivers/net/rcpci45.c
@@ -269,7 +269,7 @@ err_out_free_msgbuf:
pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf,
pDpa->msgbuf_dma);
err_out_free_dev:
- kfree (dev);
+ free_netdev (dev);
err_out:
card_idx--;
return error;
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index d0153f60a036..5326dee62c74 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -213,9 +213,11 @@ sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id)
error = register_netdev(dev);
if (error)
- goto out_release_regions;
+ goto out_free_netdev;
return 0;
+ out_free_netdev:
+ free_netdev(dev);
out_release_regions:
release_region(ioaddr[1], 16);
out_release_region0:
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 1c79e7b9c34e..9f421480b233 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -470,7 +470,7 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
rc = pci_set_dma_mask(pdev, 0xffffffffULL);
if (rc)
- goto err_out;
+ goto err_out_disable;
mmio_start = pci_resource_start(pdev, 0);
mmio_end = pci_resource_end(pdev, 0);
@@ -482,18 +482,18 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
printk(KERN_ERR PFX
"region #0 not an MMIO resource, aborting\n");
rc = -ENODEV;
- goto err_out;
+ goto err_out_disable;
}
// check for weird/broken PCI region reporting
if (mmio_len < SiS190_MIN_IO_SIZE) {
printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
rc = -ENODEV;
- goto err_out;
+ goto err_out_disable;
}
rc = pci_request_regions(pdev, dev->name);
if (rc)
- goto err_out;
+ goto err_out_disable;
// enable PCI bus-mastering
pci_set_master(pdev);
@@ -521,9 +521,10 @@ SiS190_init_board(struct pci_dev *pdev, struct net_device **dev_out,
err_out_free_res:
pci_release_regions(pdev);
-err_out:
+err_out_disable:
pci_disable_device(pdev);
- kfree(dev);
+err_out:
+ free_netdev(dev);
return rc;
}
@@ -603,7 +604,7 @@ SiS190_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ioaddr);
pci_release_regions(pdev);
pci_disable_device(pdev);
- kfree(dev);
+ free_netdev(dev);
return rc;
}
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index b5853f1a9fbd..6422eb2a4208 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -503,7 +503,7 @@ static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_dev
pci_set_drvdata(pci_dev, NULL);
pci_release_regions(pci_dev);
err_out:
- kfree(net_dev);
+ free_netdev(net_dev);
return ret;
}
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 867cc1c3a5d6..3e60ed4c3969 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -1513,3 +1513,4 @@ out:
#endif
MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_SLIP);
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index e33c7a2a2f7f..c5a085707302 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -132,7 +132,7 @@ int __init ultramca_probe(struct device *gen_dev)
struct mca_device *mca_dev = to_mca_device(gen_dev);
char slot = mca_dev->slot;
unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
- int i;
+ int i, rc;
int adapter = mca_dev->index;
int tbase = 0;
int tirq = 0;
@@ -209,8 +209,9 @@ int __init ultramca_probe(struct device *gen_dev)
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, gen_dev);
- if((i = register_netdev(dev)) != 0)
- return i;
+ rc = register_netdev(dev);
+ if (rc)
+ goto err_free_netdev;
printk(KERN_INFO "%s: %s found in slot %d\n",
dev->name, smc_mca_adapter_names[adapter], slot + 1);
@@ -262,11 +263,15 @@ int __init ultramca_probe(struct device *gen_dev)
}
}
- if (dev->mem_start == 0) /* sanity check, shouldn't happen */
- return -ENODEV;
+ /* sanity check, shouldn't happen */
+ if (dev->mem_start == 0) {
+ rc = -ENODEV;
+ goto err_unregister_netdev;
+ }
- if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name))
- return -EBUSY;
+ rc = request_region(ioaddr, ULTRA_IO_EXTENT, dev->name);
+ if (rc)
+ goto err_unregister_netdev;
reg4 = inb(ioaddr + 4) & 0x7f;
outb(reg4, ioaddr + 4);
@@ -296,10 +301,10 @@ int __init ultramca_probe(struct device *gen_dev)
/* Allocate dev->priv and fill in 8390 specific dev fields.
*/
- if (ethdev_init(dev)) {
+ rc = ethdev_init(dev);
+ if (rc) {
printk (", no memory for dev->priv.\n");
- release_region(ioaddr, ULTRA_IO_EXTENT);
- return -ENOMEM;
+ goto err_release_region;
}
gen_dev->driver_data = dev;
@@ -334,6 +339,14 @@ int __init ultramca_probe(struct device *gen_dev)
NS8390_init(dev, 0);
return 0;
+
+err_release_region:
+ release_region(ioaddr, ULTRA_IO_EXTENT);
+err_unregister_netdev:
+ unregister_netdev(dev);
+err_free_netdev:
+ free_netdev(dev);
+ return rc;
}
static int ultramca_open(struct net_device *dev)
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index dcf1db7ea6ef..c2bddf1f1700 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1070,7 +1070,7 @@ err_out_cleardev:
err_out_free_res:
pci_release_regions (pdev);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
return -ENODEV;
}
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 5bd8be316547..aad877c5400b 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -734,7 +734,7 @@ err_out_res:
#endif
pci_release_regions(pdev);
err_out_netdev:
- kfree (dev);
+ free_netdev (dev);
return -ENODEV;
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index a452e5942b52..a346fd1d4dba 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2416,13 +2416,6 @@ static int gem_nway_reset(struct net_device *dev)
return 0;
}
-static u32 gem_get_link(struct net_device *dev)
-{
- struct gem *gp = dev->priv;
-
- return (gp->lstate == link_up);
-}
-
static u32 gem_get_msglevel(struct net_device *dev)
{
struct gem *gp = dev->priv;
@@ -2441,7 +2434,6 @@ static struct ethtool_ops gem_ethtool_ops = {
.get_settings = gem_get_settings,
.set_settings = gem_set_settings,
.nway_reset = gem_nway_reset,
- .get_link = gem_get_link,
.get_msglevel = gem_get_msglevel,
.set_msglevel = gem_set_msglevel,
};
@@ -2630,7 +2622,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
- return err;
+ goto err_disable_device;
}
pci_using_dac = 0;
}
@@ -2641,20 +2633,23 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
printk(KERN_ERR PFX "Cannot find proper PCI device "
"base address, aborting.\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto err_disable_device;
}
dev = alloc_etherdev(sizeof(*gp));
if (!dev) {
printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_disable_device;
}
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
gp = dev->priv;
- if (pci_request_regions(pdev, dev->name)) {
+ err = pci_request_regions(pdev, dev->name);
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources, "
"aborting.\n");
goto err_out_free_netdev;
@@ -2688,6 +2683,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (gp->regs == 0UL) {
printk(KERN_ERR PFX "Cannot map device registers, "
"aborting.\n");
+ err = -EIO;
goto err_out_free_res;
}
@@ -2711,8 +2707,10 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
/* By default, we start with autoneg */
gp->want_autoneg = 1;
- if (gem_check_invariants(gp))
+ if (gem_check_invariants(gp)) {
+ err = -ENODEV;
goto err_out_iounmap;
+ }
/* It is guaranteed that the returned buffer will be at least
* PAGE_SIZE aligned.
@@ -2723,6 +2721,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (!gp->init_block) {
printk(KERN_ERR PFX "Cannot allocate init block, "
"aborting.\n");
+ err = -ENOMEM;
goto err_out_iounmap;
}
@@ -2735,6 +2734,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
if (register_netdev(dev)) {
printk(KERN_ERR PFX "Cannot register net device, "
"aborting.\n");
+ err = -ENOMEM;
goto err_out_free_consistent;
}
@@ -2804,9 +2804,10 @@ err_out_free_res:
pci_release_regions(pdev);
err_out_free_netdev:
- kfree(dev);
-
- return -ENODEV;
+ free_netdev(dev);
+err_disable_device:
+ pci_disable_device(pdev);
+ return err;
}
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 8c786ab7b3c5..b91f7d0199bf 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2895,7 +2895,7 @@ err_out_iounmap:
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
err_out_free_netdev:
- kfree(dev);
+ free_netdev(dev);
err_out:
return err;
@@ -3247,7 +3247,7 @@ err_out_clear_quattro:
if (qp != NULL)
qp->happy_meals[qfe_slot] = NULL;
- kfree(dev);
+ free_netdev(dev);
err_out:
return err;
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index b5d8879c2035..5116b5152e8a 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -949,7 +949,7 @@ out1:
i = 4;
out:
while (i--)
- kfree(qe_devs[i]);
+ free_netdev(qe_devs[i]);
return res;
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index c31dc44a6fd2..3ebedccf00b3 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7740,7 +7740,7 @@ err_out_iounmap:
iounmap((void *) tp->regs);
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_free_res:
pci_release_regions(pdev);
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 5a45900a816e..c5b6999712fb 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -670,7 +670,7 @@ err_out_uninit:
pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
priv->dmaStorageDMA );
err_out_free_dev:
- kfree(dev);
+ free_netdev(dev);
err_out_regions:
if (pdev)
pci_release_regions(pdev);
@@ -695,7 +695,7 @@ static void TLan_Eisa_Cleanup(void)
release_region( dev->base_addr, 0x10);
unregister_netdev( dev );
TLan_Eisa_Devices = priv->nextDevice;
- kfree( dev );
+ free_netdev( dev );
tlan_have_eisa--;
}
}
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 96fe51d22763..df234c48d9aa 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -437,6 +437,9 @@
present.
<france@handhelds.org>
0.547 08-Nov-01 Use library crc32 functions by <Matt_Domsch@dell.com>
+ 0.548 30-Aug-03 Big 2.6 cleanup. Ported to PCI/EISA probing and
+ generic DMA APIs. Fixed DE425 support on Alpha.
+ <maz@wild-wind.fr.eu.org>
=========================================================================
*/
@@ -450,6 +453,7 @@
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/eisa.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -461,6 +465,8 @@
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/ctype.h>
+#include <linux/dma-mapping.h>
+#include <linux/moduleparam.h>
#include <asm/bitops.h>
#include <asm/io.h>
@@ -625,13 +631,13 @@ struct parameters {
#define DE4X5_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
#define DE4X5_EISA_TOTAL_SIZE 0x100 /* I/O address extent */
-#define MAX_EISA_SLOTS 16
-#define EISA_SLOT_INC 0x1000
#define EISA_ALLOWED_IRQ_LIST {5, 9, 10, 11}
#define DE4X5_SIGNATURE {"DE425","DE434","DE435","DE450","DE500"}
#define DE4X5_NAME_LENGTH 8
+static c_char *de4x5_signatures[] = DE4X5_SIGNATURE;
+
/*
** Ethernet PROM defines for DC21040
*/
@@ -644,7 +650,6 @@ struct parameters {
#define PCI_MAX_BUS_NUM 8
#define DE4X5_PCI_TOTAL_SIZE 0x80 /* I/O address extent */
#define DE4X5_CLASS_CODE 0x00020000 /* Network controller, Ethernet */
-#define NO_MORE_PCI -2 /* PCI bus search all done */
/*
** Memory Alignment. Each descriptor is 4 longwords long. To force a
@@ -819,7 +824,6 @@ struct de4x5_private {
struct timer_list timer; /* Timer info for kernel */
int tmp; /* Temporary global per card */
struct {
- void *priv; /* Original kmalloc'd mem addr */
u_long lock; /* Lock the cache accesses */
s32 csr0; /* Saved Bus Mode Register */
s32 csr6; /* Saved Operating Mode Reg. */
@@ -833,7 +837,7 @@ struct de4x5_private {
struct sk_buff *skb; /* Save the (re-ordered) skb's */
} cache;
struct de4x5_srom srom; /* A copy of the SROM */
- struct net_device *next_module; /* Link to the next module */
+ int cfrv; /* Card CFRV copy */
int rx_ovf; /* Check for 'RX overflow' tag */
int useSROM; /* For non-DEC card use SROM */
int useMII; /* Infoblock using the MII */
@@ -850,29 +854,13 @@ struct de4x5_private {
u_char *rst; /* Pointer to Type 5 reset info */
u_char ibn; /* Infoblock number */
struct parameters params; /* Command line/ #defined params */
- struct pci_dev *pdev; /* Device cookie for DMA alloc */
+ struct device *gendev; /* Generic device */
dma_addr_t dma_rings; /* DMA handle for rings */
int dma_size; /* Size of the DMA area */
char *rx_bufs; /* rx bufs on alpha, sparc, ... */
};
/*
-** Kludge to get around the fact that the CSR addresses have different
-** offsets in the PCI and EISA boards. Also note that the ethernet address
-** PROM is accessed differently.
-*/
-static struct de4x5_bus_type {
- int bus;
- int bus_num;
- int device;
- int chipset;
- struct de4x5_srom srom;
- int autosense;
- int useSROM;
- struct pci_dev *pdev;
-} bus;
-
-/*
** To get around certain poxy cards that don't provide an SROM
** for the second and more DECchip, I have to key off the first
** chip's address. I'll assume there's not a bad SROM iff:
@@ -919,7 +907,7 @@ static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
/*
** Private functions
*/
-static int de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev);
+static int de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev);
static int de4x5_init(struct net_device *dev);
static int de4x5_sw_reset(struct net_device *dev);
static int de4x5_rx(struct net_device *dev);
@@ -962,11 +950,11 @@ static int de4x5_reset_phy(struct net_device *dev);
static void reset_init_sia(struct net_device *dev, s32 sicr, s32 strr, s32 sigr);
static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec);
static int test_tp(struct net_device *dev, s32 msec);
-static int EISA_signature(char *name, s32 eisa_id);
-static int PCI_signature(char *name, struct de4x5_bus_type *lp);
-static void DevicePresent(u_long iobase);
+static int EISA_signature(char *name, struct device *device);
+static int PCI_signature(char *name, struct de4x5_private *lp);
+static void DevicePresent(struct net_device *dev, u_long iobase);
static void enet_addr_rst(u_long aprom_addr);
-static int de4x5_bad_srom(struct de4x5_bus_type *lp);
+static int de4x5_bad_srom(struct de4x5_private *lp);
static short srom_rd(u_long address, u_char offset);
static void srom_latch(u_int command, u_long address);
static void srom_command(u_int command, u_long address);
@@ -994,12 +982,7 @@ static void SetMulticastFilter(struct net_device *dev);
static int get_hw_addr(struct net_device *dev);
static void srom_repair(struct net_device *dev, int card);
static int test_bad_enet(struct net_device *dev, int status);
-static int an_exception(struct de4x5_bus_type *lp);
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
-static void eisa_probe(struct net_device *dev, u_long iobase);
-#endif
-static void pci_probe(struct net_device *dev, u_long iobase);
-static void srom_search(struct pci_dev *pdev);
+static int an_exception(struct de4x5_private *lp);
static char *build_setup_frame(struct net_device *dev, int mode);
static void disable_ast(struct net_device *dev);
static void enable_ast(struct net_device *dev, u32 time_out);
@@ -1008,7 +991,6 @@ static int gep_rd(struct net_device *dev);
static void gep_wr(s32 data, struct net_device *dev);
static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec);
static void yawn(struct net_device *dev, int state);
-static void link_modules(struct net_device *dev, struct net_device *tmp);
static void de4x5_parse_params(struct net_device *dev);
static void de4x5_dbg_open(struct net_device *dev);
static void de4x5_dbg_mii(struct net_device *dev, int k);
@@ -1028,40 +1010,25 @@ static int type4_infoblock(struct net_device *dev, u_char count, u_char *p);
static int type5_infoblock(struct net_device *dev, u_char count, u_char *p);
static int compact_infoblock(struct net_device *dev, u_char count, u_char *p);
-#ifdef MODULE
-static struct net_device *unlink_modules(struct net_device *p);
-static struct net_device *insert_device(struct net_device *dev, u_long iobase,
- int (*init)(struct net_device *));
-static int count_adapters(void);
-static int loading_module = 1;
-MODULE_PARM(de4x5_debug, "i");
-MODULE_PARM(dec_only, "i");
-MODULE_PARM(args, "s");
+/*
+** Note now that module autoprobing is allowed under EISA and PCI. The
+** IRQ lines will not be auto-detected; instead I'll rely on the BIOSes
+** to "do the right thing".
+*/
+
+static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */
+
+module_param(io, int, 0);
+module_param(de4x5_debug, int, 0);
+module_param(dec_only, int, 0);
+module_param(args, charp, 0);
+
+MODULE_PARM_DESC(io, "de4x5 I/O base address");
MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask");
MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)");
MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details");
MODULE_LICENSE("GPL");
-# else
-static int loading_module;
-#endif /* MODULE */
-
-static char name[DE4X5_NAME_LENGTH + 1];
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
-static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
-static int lastEISA;
-# ifdef DE4X5_FORCE_EISA /* Force an EISA bus probe or not */
-static int forceEISA = 1;
-# else
-static int forceEISA;
-# endif
-#endif
-static int num_de4x5s;
-static int cfrv, useSROM;
-static int lastPCI = -1;
-static struct net_device *lastModule;
-static struct pci_dev *pdev;
-
/*
** List the SROM infoleaf functions and chipsets
*/
@@ -1115,37 +1082,22 @@ static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = {
}
-/*
-** Autoprobing in modules is allowed here. See the top of the file for
-** more info.
-*/
-int __init
-de4x5_probe(struct net_device *dev)
-{
- u_long iobase = dev->base_addr;
-
- pci_probe(dev, iobase);
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
- if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) {
- eisa_probe(dev, iobase);
- }
-#endif
-
- return (dev->priv ? 0 : -ENODEV);
-}
-
static int __init
-de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
+de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
{
- struct de4x5_bus_type *lp = &bus;
+ char name[DE4X5_NAME_LENGTH + 1];
+ struct de4x5_private *lp = dev->priv;
+ struct pci_dev *pdev = NULL;
int i, status=0;
- char *tmp;
-
+
+ gendev->driver_data = dev;
+
/* Ensure we're not sleeping */
if (lp->bus == EISA) {
outb(WAKEUP, PCI_CFPM);
} else {
- pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP);
+ pdev = to_pci_dev (gendev);
+ pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP);
}
mdelay(10);
@@ -1158,11 +1110,11 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
/*
** Now find out what kind of DC21040/DC21041/DC21140 board we have.
*/
- useSROM = FALSE;
+ lp->useSROM = FALSE;
if (lp->bus == PCI) {
PCI_signature(name, lp);
} else {
- EISA_signature(name, EISA_ID0);
+ EISA_signature(name, gendev);
}
if (*name == '\0') { /* Not found a board signature */
@@ -1170,13 +1122,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
}
dev->base_addr = iobase;
- if (lp->bus == EISA) {
- printk("%s: %s at 0x%04lx (EISA slot %ld)",
- dev->name, name, iobase, ((iobase>>12)&0x0f));
- } else { /* PCI port address */
- printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name,
- iobase, lp->bus_num, lp->device);
- }
+ printk ("%s: %s at 0x%04lx", gendev->bus_id, name, iobase);
printk(", h/w address ");
status = get_hw_addr(dev);
@@ -1189,38 +1135,12 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
printk(" which has an Ethernet PROM CRC error.\n");
return -ENXIO;
} else {
- struct de4x5_private *lp;
-
- /*
- ** Reserve a section of kernel memory for the adapter
- ** private area and the TX/RX descriptor rings.
- */
- dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + DE4X5_ALIGN,
- GFP_KERNEL);
- if (dev->priv == NULL) {
- return -ENOMEM;
- }
-
- /*
- ** Align to a longword boundary
- */
- tmp = dev->priv;
- dev->priv = (void *)(((u_long)dev->priv + DE4X5_ALIGN) & ~DE4X5_ALIGN);
- lp = (struct de4x5_private *)dev->priv;
- memset(dev->priv, 0, sizeof(struct de4x5_private));
- lp->bus = bus.bus;
- lp->bus_num = bus.bus_num;
- lp->device = bus.device;
- lp->chipset = bus.chipset;
- lp->cache.priv = tmp;
lp->cache.gepc = GEP_INIT;
lp->asBit = GEP_SLNK;
lp->asPolarity = GEP_SLNK;
lp->asBitValid = TRUE;
lp->timeout = -1;
- lp->useSROM = useSROM;
- lp->pdev = pdev;
- memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom));
+ lp->gendev = gendev;
lp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
init_timer(&lp->timer);
de4x5_parse_params(dev);
@@ -1238,16 +1158,15 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
}
}
lp->fdx = lp->params.fdx;
- sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
+ sprintf(lp->adapter_name,"%s (%s)", name, gendev->bus_id);
lp->dma_size = (NUM_RX_DESC + NUM_TX_DESC) * sizeof(struct de4x5_desc);
#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc_v9__) || defined(DE4X5_DO_MEMCPY)
lp->dma_size += RX_BUFF_SZ * NUM_RX_DESC + DE4X5_ALIGN;
#endif
- lp->rx_ring = pci_alloc_consistent(pdev, lp->dma_size, &lp->dma_rings);
+ lp->rx_ring = dma_alloc_coherent(gendev, lp->dma_size,
+ &lp->dma_rings, GFP_ATOMIC);
if (lp->rx_ring == NULL) {
- kfree(lp->cache.priv);
- lp->cache.priv = NULL;
return -ENOMEM;
}
@@ -1288,11 +1207,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
#endif
barrier();
-
- request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE),
- lp->adapter_name);
-
+
lp->rxRingSize = NUM_RX_DESC;
lp->txRingSize = NUM_TX_DESC;
@@ -1313,7 +1228,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
create_packet(dev, lp->frame, sizeof(lp->frame));
/* Check if the RX overflow bug needs testing for */
- i = cfrv & 0x000000fe;
+ i = lp->cfrv & 0x000000fe;
if ((lp->chipset == DC21140) && (i == 0x20)) {
lp->rx_ovf = 1;
}
@@ -1350,7 +1265,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
/* The DE4X5-specific entries in the device structure. */
SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_NETDEV_DEV(dev, gendev);
dev->open = &de4x5_open;
dev->hard_start_xmit = &de4x5_queue_pkt;
dev->stop = &de4x5_close;
@@ -1361,7 +1276,11 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
dev->mem_start = 0;
/* Fill in the generic fields of the device structure. */
- ether_setup(dev);
+ if ((status = register_netdev (dev))) {
+ dma_free_coherent (gendev, lp->dma_size,
+ lp->rx_ring, lp->dma_rings);
+ return status;
+ }
/* Let the adapter sleep to save power */
yawn(dev, SLEEP);
@@ -1766,9 +1685,9 @@ de4x5_rx(struct net_device *dev)
static inline void
de4x5_free_tx_buff(struct de4x5_private *lp, int entry)
{
- pci_unmap_single(lp->pdev, le32_to_cpu(lp->tx_ring[entry].buf),
+ dma_unmap_single(lp->gendev, le32_to_cpu(lp->tx_ring[entry].buf),
le32_to_cpu(lp->tx_ring[entry].des1) & TD_TBS1,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
if ((u_long) lp->tx_skb[entry] > 1)
dev_kfree_skb_irq(lp->tx_skb[entry]);
lp->tx_skb[entry] = NULL;
@@ -1987,7 +1906,7 @@ load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb)
{
struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
int entry = (lp->tx_new ? lp->tx_new-1 : lp->txRingSize-1);
- dma_addr_t buf_dma = pci_map_single(lp->pdev, buf, flags & TD_TBS1, PCI_DMA_TODEVICE);
+ dma_addr_t buf_dma = dma_map_single(lp->gendev, buf, flags & TD_TBS1, DMA_TO_DEVICE);
lp->tx_ring[lp->tx_new].buf = cpu_to_le32(buf_dma);
lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER);
@@ -2084,75 +2003,199 @@ SetMulticastFilter(struct net_device *dev)
return;
}
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
-/*
-** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
-** the motherboard. Upto 15 EISA devices are supported.
-*/
-static void __init
-eisa_probe(struct net_device *dev, u_long ioaddr)
+#ifdef CONFIG_EISA
+
+static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
+
+static int __init de4x5_eisa_probe (struct device *gendev)
{
- int i, maxSlots, status, device;
- u_char irq;
- u_short vendor;
- u32 cfid;
- u_long iobase;
- struct de4x5_bus_type *lp = &bus;
- char name[DE4X5_STRLEN];
+ struct eisa_device *edev;
+ u_long iobase;
+ u_char irq, regval;
+ u_short vendor;
+ u32 cfid;
+ int status, device;
+ struct net_device *dev;
+ struct de4x5_private *lp;
- if (lastEISA == MAX_EISA_SLOTS) return;/* No more EISA devices to search */
+ edev = to_eisa_device (gendev);
+ iobase = edev->base_addr;
- lp->bus = EISA;
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
-
- for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
- if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE)) continue;
- if (!EISA_signature(name, EISA_ID)) continue;
+ if (!request_region (iobase, DE4X5_EISA_TOTAL_SIZE, "de4x5"))
+ return -EBUSY;
+ if (!request_region (iobase + DE4X5_EISA_IO_PORTS,
+ DE4X5_EISA_TOTAL_SIZE, "de4x5")) {
+ status = -EBUSY;
+ goto release_reg_1;
+ }
+
+ if (!(dev = alloc_etherdev (sizeof (struct de4x5_private)))) {
+ status = -ENOMEM;
+ goto release_reg_2;
+ }
+ lp = dev->priv;
+
cfid = (u32) inl(PCI_CFID);
- cfrv = (u_short) inl(PCI_CFRV);
+ lp->cfrv = (u_short) inl(PCI_CFRV);
device = (cfid >> 8) & 0x00ffff00;
vendor = (u_short) cfid;
/* Read the EISA Configuration Registers */
- irq = inb(EISA_REG0);
- irq = de4x5_irq[(irq >> 1) & 0x03];
+ regval = inb(EISA_REG0) & (ER0_INTL | ER0_INTT);
+#ifdef CONFIG_ALPHA
+ /* Looks like the Jensen firmware (rev 2.2) doesn't really
+ * care about the EISA configuration, and thus doesn't
+ * configure the PLX bridge properly. Oh well... Simply mimic
+ * the EISA config file to sort it out. */
+
+ /* EISA REG1: Assert DecChip 21040 HW Reset */
+ outb (ER1_IAM | 1, EISA_REG1);
+ mdelay (1);
+ /* EISA REG1: Deassert DecChip 21040 HW Reset */
+ outb (ER1_IAM, EISA_REG1);
+ mdelay (1);
+
+ /* EISA REG3: R/W Burst Transfer Enable */
+ outb (ER3_BWE | ER3_BRE, EISA_REG3);
+
+ /* 32_bit slave/master, Preempt Time=23 bclks, Unlatched Interrupt */
+ outb (ER0_BSW | ER0_BMW | ER0_EPT | regval, EISA_REG0);
+#endif
+ irq = de4x5_irq[(regval >> 1) & 0x03];
+
if (is_DC2114x) {
- device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+ device = ((lp->cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
}
lp->chipset = device;
+ lp->bus = EISA;
/* Write the PCI Configuration Registers */
outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
outl(0x00006000, PCI_CFLT);
outl(iobase, PCI_CBIO);
- DevicePresent(EISA_APROM);
+ DevicePresent(dev, EISA_APROM);
dev->irq = irq;
- if ((status = de4x5_hw_init(dev, iobase, NULL)) == 0) {
- num_de4x5s++;
- if (loading_module) link_modules(lastModule, dev);
- lastEISA = i;
+
+ if (!(status = de4x5_hw_init (dev, iobase, gendev))) {
+ return 0;
+ }
+
+ free_netdev (dev);
+ release_reg_2:
+ release_region (iobase + DE4X5_EISA_IO_PORTS, DE4X5_EISA_TOTAL_SIZE);
+ release_reg_1:
+ release_region (iobase, DE4X5_EISA_TOTAL_SIZE);
+
+ return status;
+}
+
+static int __devexit de4x5_eisa_remove (struct device *device)
+{
+ struct net_device *dev;
+ u_long iobase;
+
+ dev = device->driver_data;
+ iobase = dev->base_addr;
+
+ unregister_netdev (dev);
+ free_netdev (dev);
+ release_region (iobase + DE4X5_EISA_IO_PORTS, DE4X5_EISA_TOTAL_SIZE);
+ release_region (iobase, DE4X5_EISA_TOTAL_SIZE);
+
+ return 0;
+}
+
+static struct eisa_device_id de4x5_eisa_ids[] = {
+ { "DEC4250", 0 }, /* 0 is the board name index... */
+ { "" }
+};
+
+static struct eisa_driver de4x5_eisa_driver = {
+ .id_table = de4x5_eisa_ids,
+ .driver = {
+ .name = "de4x5",
+ .probe = de4x5_eisa_probe,
+ .remove = __devexit_p (de4x5_eisa_remove),
+ }
+};
+#endif
+
+#ifdef CONFIG_PCI
+
+/*
+** This function searches the current bus (which is >0) for a DECchip with an
+** SROM, so that in multiport cards that have one SROM shared between multiple
+** DECchips, we can find the base SROM irrespective of the BIOS scan direction.
+** For single port cards this is a time waster...
+*/
+static void __init
+srom_search(struct net_device *dev, struct pci_dev *pdev)
+{
+ u_char pb;
+ u_short vendor, status;
+ u_int irq = 0, device;
+ u_long iobase = 0; /* Clear upper 32 bits in Alphas */
+ int i, j, cfrv;
+ struct de4x5_private *lp = dev->priv;
+ struct list_head *walk = &pdev->bus_list;
+
+ for (walk = walk->next; walk != &pdev->bus_list; walk = walk->next) {
+ struct pci_dev *this_dev = pci_dev_b(walk);
+
+ /* Skip the pci_bus list entry */
+ if (list_entry(walk, struct pci_bus, devices) == pdev->bus) continue;
+
+ vendor = this_dev->vendor;
+ device = this_dev->device << 8;
+ if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) continue;
+
+ /* Get the chip configuration revision register */
+ pb = this_dev->bus->number;
+ pci_read_config_dword(this_dev, PCI_REVISION_ID, &cfrv);
+
+ /* Set the device number information */
+ lp->device = PCI_SLOT(this_dev->devfn);
+ lp->bus_num = pb;
+
+ /* Set the chipset information */
+ if (is_DC2114x) {
+ device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+ }
+ lp->chipset = device;
+
+ /* Get the board I/O address (64 bits on sparc64) */
+ iobase = pci_resource_start(this_dev, 0);
+
+ /* Fetch the IRQ to be used */
+ irq = this_dev->irq;
+ if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
+
+ /* Check if I/O accesses are enabled */
+ pci_read_config_word(this_dev, PCI_COMMAND, &status);
+ if (!(status & PCI_COMMAND_IO)) continue;
+
+ /* Search for a valid SROM attached to this DECchip */
+ DevicePresent(dev, DE4X5_APROM);
+ for (j=0, i=0; i<ETH_ALEN; i++) {
+ j += (u_char) *((u_char *)&lp->srom + SROM_HWADD + i);
+ }
+ if ((j != 0) && (j != 0x5fa)) {
+ last.chipset = device;
+ last.bus = pb;
+ last.irq = irq;
+ for (i=0; i<ETH_ALEN; i++) {
+ last.addr[i] = (u_char)*((u_char *)&lp->srom + SROM_HWADD + i);
+ }
return;
}
}
- if (ioaddr == 0) lastEISA = i;
-
return;
}
-#endif /* !(__sparc_v9__) && !(__powerpc__) && !defined(__alpha__) */
/*
** PCI bus I/O device probe
@@ -2169,56 +2212,57 @@ eisa_probe(struct net_device *dev, u_long ioaddr)
** This function is only compatible with the *latest* 2.1.x kernels. For 2.0.x
** kernels use the V0.535[n] drivers.
*/
-#define PCI_LAST_DEV 32
-static void __init
-pci_probe(struct net_device *dev, u_long ioaddr)
+static int __init de4x5_pci_probe (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
- u_char pb, pbus, dev_num, dnum, timer;
- u_short vendor, index, status;
- u_int irq = 0, device, class = DE4X5_CLASS_CODE;
- u_long iobase = 0; /* Clear upper 32 bits in Alphas */
- struct de4x5_bus_type *lp = &bus;
-
- if (lastPCI == NO_MORE_PCI) return;
-
- lp->bus = PCI;
- lp->bus_num = 0;
-
- if ((ioaddr < 0x1000) && loading_module) {
- pbus = (u_short)(ioaddr >> 8);
- dnum = (u_short)(ioaddr & 0xff);
- } else {
- pbus = 0;
- dnum = 0;
- }
+ u_char pb, pbus = 0, dev_num, dnum = 0, timer;
+ u_short vendor, status;
+ u_int irq = 0, device;
+ u_long iobase = 0; /* Clear upper 32 bits in Alphas */
+ int error;
+ struct net_device *dev;
+ struct de4x5_private *lp;
- for (index=lastPCI+1;(pdev = pci_find_class(class, pdev))!=NULL;index++) {
dev_num = PCI_SLOT(pdev->devfn);
pb = pdev->bus->number;
- if ((pbus || dnum) && ((pbus != pb) || (dnum != dev_num))) continue;
+
+ if (io) { /* probe a single PCI device */
+ pbus = (u_short)(io >> 8);
+ dnum = (u_short)(io & 0xff);
+ if ((pbus != pb) || (dnum != dev_num))
+ return -ENODEV;
+ }
vendor = pdev->vendor;
device = pdev->device << 8;
- if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) continue;
+ if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x))
+ return -ENODEV;
+
+ /* Ok, the device seems to be for us. */
+ if (!(dev = alloc_etherdev (sizeof (struct de4x5_private))))
+ return -ENOMEM;
+ lp = dev->priv;
+ lp->bus = PCI;
+ lp->bus_num = 0;
+
/* Search for an SROM on this bus */
if (lp->bus_num != pb) {
lp->bus_num = pb;
- srom_search(pdev);
+ srom_search(dev, pdev);
}
/* Get the chip configuration revision register */
- pci_read_config_dword(pdev, PCI_REVISION_ID, &cfrv);
+ pci_read_config_dword(pdev, PCI_REVISION_ID, &lp->cfrv);
/* Set the device number information */
lp->device = dev_num;
lp->bus_num = pb;
- lp->pdev = pdev;
-
+
/* Set the chipset information */
if (is_DC2114x) {
- device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+ device = ((lp->cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
}
lp->chipset = device;
@@ -2227,7 +2271,10 @@ pci_probe(struct net_device *dev, u_long ioaddr)
/* Fetch the IRQ to be used */
irq = pdev->irq;
- if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
+ if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) {
+ error = -ENODEV;
+ goto free_dev;
+ }
/* Check if I/O accesses and Bus Mastering are enabled */
pci_read_config_word(pdev, PCI_COMMAND, &status);
@@ -2238,14 +2285,20 @@ pci_probe(struct net_device *dev, u_long ioaddr)
pci_read_config_word(pdev, PCI_COMMAND, &status);
}
#endif /* __powerpc__ */
- if (!(status & PCI_COMMAND_IO)) continue;
+ if (!(status & PCI_COMMAND_IO)) {
+ error = -ENODEV;
+ goto free_dev;
+ }
if (!(status & PCI_COMMAND_MASTER)) {
status |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, status);
pci_read_config_word(pdev, PCI_COMMAND, &status);
}
- if (!(status & PCI_COMMAND_MASTER)) continue;
+ if (!(status & PCI_COMMAND_MASTER)) {
+ error = -ENODEV;
+ goto free_dev;
+ }
/* Check the latency timer for values >= 0x60 */
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &timer);
@@ -2253,116 +2306,61 @@ pci_probe(struct net_device *dev, u_long ioaddr)
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x60);
}
- DevicePresent(DE4X5_APROM);
- if (check_region(iobase, DE4X5_PCI_TOTAL_SIZE) == 0) {
- dev->irq = irq;
- if ((status = de4x5_hw_init(dev, iobase, pdev)) == 0) {
- num_de4x5s++;
- lastPCI = index;
- if (loading_module) link_modules(lastModule, dev);
- return;
- }
- } else if (ioaddr != 0) {
- printk("%s: region already allocated at 0x%04lx.\n", dev->name,
- iobase);
- }
- }
-
- lastPCI = NO_MORE_PCI;
-
- return;
-}
+ DevicePresent(dev, DE4X5_APROM);
-/*
-** This function searches the current bus (which is >0) for a DECchip with an
-** SROM, so that in multiport cards that have one SROM shared between multiple
-** DECchips, we can find the base SROM irrespective of the BIOS scan direction.
-** For single port cards this is a time waster...
-*/
-static void __init
-srom_search(struct pci_dev *dev)
-{
- u_char pb;
- u_short vendor, status;
- u_int irq = 0, device;
- u_long iobase = 0; /* Clear upper 32 bits in Alphas */
- int i, j;
- struct de4x5_bus_type *lp = &bus;
- struct list_head *walk = &dev->bus_list;
-
- for (walk = walk->next; walk != &dev->bus_list; walk = walk->next) {
- struct pci_dev *this_dev = pci_dev_b(walk);
-
- /* Skip the pci_bus list entry */
- if (list_entry(walk, struct pci_bus, devices) == dev->bus) continue;
-
- vendor = this_dev->vendor;
- device = this_dev->device << 8;
- if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) continue;
-
- /* Get the chip configuration revision register */
- pb = this_dev->bus->number;
- pci_read_config_dword(this_dev, PCI_REVISION_ID, &cfrv);
-
- /* Set the device number information */
- lp->device = PCI_SLOT(this_dev->devfn);
- lp->bus_num = pb;
-
- /* Set the chipset information */
- if (is_DC2114x) {
- device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+ if (!request_region (iobase, DE4X5_PCI_TOTAL_SIZE, "de4x5")) {
+ error = -EBUSY;
+ goto free_dev;
}
- lp->chipset = device;
-
- /* Get the board I/O address (64 bits on sparc64) */
- iobase = pci_resource_start(this_dev, 0);
-
- /* Fetch the IRQ to be used */
- irq = this_dev->irq;
- if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
-
- /* Check if I/O accesses are enabled */
- pci_read_config_word(this_dev, PCI_COMMAND, &status);
- if (!(status & PCI_COMMAND_IO)) continue;
- /* Search for a valid SROM attached to this DECchip */
- DevicePresent(DE4X5_APROM);
- for (j=0, i=0; i<ETH_ALEN; i++) {
- j += (u_char) *((u_char *)&lp->srom + SROM_HWADD + i);
- }
- if ((j != 0) && (j != 0x5fa)) {
- last.chipset = device;
- last.bus = pb;
- last.irq = irq;
- for (i=0; i<ETH_ALEN; i++) {
- last.addr[i] = (u_char)*((u_char *)&lp->srom + SROM_HWADD + i);
- }
- return;
+ dev->irq = irq;
+
+ if ((error = de4x5_hw_init(dev, iobase, &pdev->dev))) {
+ goto release;
}
- }
- return;
+ return 0;
+
+ release:
+ release_region (iobase, DE4X5_PCI_TOTAL_SIZE);
+ free_dev:
+ free_netdev (dev);
+ return error;
}
-static void __init
-link_modules(struct net_device *dev, struct net_device *tmp)
+static void __devexit de4x5_pci_remove (struct pci_dev *pdev)
{
- struct net_device *p=dev;
-
- if (p) {
- while (((struct de4x5_private *)(p->priv))->next_module) {
- p = ((struct de4x5_private *)(p->priv))->next_module;
- }
+ struct net_device *dev;
+ u_long iobase;
+
+ dev = pdev->dev.driver_data;
+ iobase = dev->base_addr;
+
+ unregister_netdev (dev);
+ free_netdev (dev);
+ release_region (iobase, DE4X5_PCI_TOTAL_SIZE);
+}
+
+static struct pci_device_id de4x5_pci_tbl[] = {
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
+ { },
+};
- if (dev != tmp) {
- ((struct de4x5_private *)(p->priv))->next_module = tmp;
- } else {
- ((struct de4x5_private *)(p->priv))->next_module = NULL;
- }
- }
+static struct pci_driver de4x5_pci_driver = {
+ .name = "de4x5",
+ .id_table = de4x5_pci_tbl,
+ .probe = de4x5_pci_probe,
+ .remove = __devexit_p (de4x5_pci_remove),
+};
- return;
-}
+#endif
/*
** Auto configure the media here rather than setting the port at compile
@@ -3945,34 +3943,20 @@ create_packet(struct net_device *dev, char *frame, int len)
** Look for a particular board name in the EISA configuration space
*/
static int
-EISA_signature(char *name, s32 eisa_id)
+EISA_signature(char *name, struct device *device)
{
- static c_char *signatures[] = DE4X5_SIGNATURE;
- char ManCode[DE4X5_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *);
-
+ int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
+ struct eisa_device *edev;
+
*name = '\0';
- Eisa.ID = inl(eisa_id);
-
- ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
- ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
- ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
- ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);
- ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
- ManCode[5]='\0';
-
- for (i=0;i<siglen;i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name,ManCode);
+ edev = to_eisa_device (device);
+ i = edev->id.driver_data;
+
+ if (i >= 0 && i < siglen) {
+ strcpy (name, de4x5_signatures[i]);
status = 1;
- break;
- }
}
-
+
return status; /* return the device name string */
}
@@ -3980,9 +3964,8 @@ EISA_signature(char *name, s32 eisa_id)
** Look for a particular board name in the PCI configuration space
*/
static int
-PCI_signature(char *name, struct de4x5_bus_type *lp)
+PCI_signature(char *name, struct de4x5_private *lp)
{
- static c_char *de4x5_signatures[] = DE4X5_SIGNATURE;
int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
if (lp->chipset == DC21040) {
@@ -4008,10 +3991,10 @@ PCI_signature(char *name, struct de4x5_bus_type *lp)
)))))));
}
if (lp->chipset != DC21041) {
- useSROM = TRUE; /* card is not recognisably DEC */
+ lp->useSROM = TRUE; /* card is not recognisably DEC */
}
} else if ((lp->chipset & ~0x00ff) == DC2114x) {
- useSROM = TRUE;
+ lp->useSROM = TRUE;
}
return status;
@@ -4026,10 +4009,10 @@ PCI_signature(char *name, struct de4x5_bus_type *lp)
** be fixed up later).
*/
static void
-DevicePresent(u_long aprom_addr)
+DevicePresent(struct net_device *dev, u_long aprom_addr)
{
int i, j=0;
- struct de4x5_bus_type *lp = &bus;
+ struct de4x5_private *lp = (struct de4x5_private *) dev->priv;
if (lp->chipset == DC21040) {
if (lp->bus == EISA) {
@@ -4110,7 +4093,7 @@ get_hw_addr(struct net_device *dev)
u_long iobase = dev->base_addr;
int broken, i, k, tmp, status = 0;
u_short j,chksum;
- struct de4x5_bus_type *lp = &bus;
+ struct de4x5_private *lp = dev->priv;
broken = de4x5_bad_srom(lp);
@@ -4191,7 +4174,7 @@ get_hw_addr(struct net_device *dev)
** didn't seem to work here...?
*/
static int
-de4x5_bad_srom(struct de4x5_bus_type *lp)
+de4x5_bad_srom(struct de4x5_private *lp)
{
int i, status = 0;
@@ -4225,14 +4208,14 @@ de4x5_strncmp(char *a, char *b, int n)
static void
srom_repair(struct net_device *dev, int card)
{
- struct de4x5_bus_type *lp = &bus;
+ struct de4x5_private *lp = dev->priv;
switch(card) {
case SMC:
- memset((char *)&bus.srom, 0, sizeof(struct de4x5_srom));
+ memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom));
memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN);
memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100);
- useSROM = TRUE;
+ lp->useSROM = TRUE;
break;
}
@@ -4246,7 +4229,7 @@ srom_repair(struct net_device *dev, int card)
static int
test_bad_enet(struct net_device *dev, int status)
{
- struct de4x5_bus_type *lp = &bus;
+ struct de4x5_private *lp = dev->priv;
int i, tmp;
for (tmp=0,i=0; i<ETH_ALEN; i++) tmp += (u_char)dev->dev_addr[i];
@@ -4279,7 +4262,7 @@ test_bad_enet(struct net_device *dev, int status)
** List of board exceptions with correctly wired IRQs
*/
static int
-an_exception(struct de4x5_bus_type *lp)
+an_exception(struct de4x5_private *lp)
{
if ((*(u_short *)lp->srom.sub_vendor_id == 0x00c0) &&
(*(u_short *)lp->srom.sub_system_id == 0x95e0)) {
@@ -5312,19 +5295,20 @@ yawn(struct net_device *dev, int state)
break;
}
} else {
+ struct pci_dev *pdev = to_pci_dev (lp->gendev);
switch(state) {
case WAKEUP:
- pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP);
+ pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP);
mdelay(10);
break;
case SNOOZE:
- pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SNOOZE);
+ pci_write_config_byte(pdev, PCI_CFDA_PSM, SNOOZE);
break;
case SLEEP:
outl(0, DE4X5_SICR);
- pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SLEEP);
+ pci_write_config_byte(pdev, PCI_CFDA_PSM, SLEEP);
break;
}
}
@@ -5348,9 +5332,6 @@ de4x5_parse_params(struct net_device *dev)
t = *q;
*q = '\0';
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
- if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1;
-#endif
if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1;
if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) {
@@ -5758,146 +5739,29 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return status;
}
-#ifdef MODULE
-/*
-** Note now that module autoprobing is allowed under EISA and PCI. The
-** IRQ lines will not be auto-detected; instead I'll rely on the BIOSes
-** to "do the right thing".
-*/
-#define LP(a) ((struct de4x5_private *)(a))
-static struct net_device *mdev = NULL;
-static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "de4x5 I/O base address");
-
-int
-init_module(void)
-{
- int i, num, status = -EIO;
- struct net_device *p;
-
- num = count_adapters();
-
- for (i=0; i<num; i++) {
- if ((p = insert_device(NULL, io, de4x5_probe)) == NULL)
- return -ENOMEM;
-
- if (!mdev) mdev = p;
-
- if (register_netdev(p) != 0) {
- struct de4x5_private *lp = (struct de4x5_private *)p->priv;
- if (lp) {
- release_region(p->base_addr, (lp->bus == PCI ?
- DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE));
- if (lp->cache.priv) { /* Private area allocated? */
- kfree(lp->cache.priv); /* Free the private area */
- }
- if (lp->rx_ring) {
- pci_free_consistent(lp->pdev, lp->dma_size, lp->rx_ring,
- lp->dma_rings);
- }
- }
- kfree(p);
- } else {
- status = 0; /* At least one adapter will work */
- lastModule = p;
- }
- }
-
- return status;
-}
-
-void
-cleanup_module(void)
-{
- while (mdev != NULL) {
- mdev = unlink_modules(mdev);
- }
-
- return;
-}
-
-static struct net_device *
-unlink_modules(struct net_device *p)
-{
- struct net_device *next = NULL;
-
- if (p->priv) { /* Private areas allocated? */
- struct de4x5_private *lp = (struct de4x5_private *)p->priv;
-
- next = lp->next_module;
- if (lp->rx_ring) {
- pci_free_consistent(lp->pdev, lp->dma_size, lp->rx_ring,
- lp->dma_rings);
- }
- release_region(p->base_addr, (lp->bus == PCI ?
- DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE));
- kfree(lp->cache.priv); /* Free the private area */
- }
- unregister_netdev(p);
- free_netdev(p); /* Free the device structure */
-
- return next;
-}
-
-static int
-count_adapters(void)
+static int __init de4x5_module_init (void)
{
- int i, j=0;
- u_short vendor;
- u_int class = DE4X5_CLASS_CODE;
- u_int device;
-
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
- char name[DE4X5_STRLEN];
- u_long iobase = 0x1000;
+ int err = 0;
- for (i=1; i<MAX_EISA_SLOTS; i++, iobase+=EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID)) j++;
- }
+#if CONFIG_PCI
+ err = pci_module_init (&de4x5_pci_driver);
+#endif
+#ifdef CONFIG_EISA
+ err |= eisa_driver_register (&de4x5_eisa_driver);
#endif
- for (i=0; (pdev=pci_find_class(class, pdev))!= NULL; i++) {
- vendor = pdev->vendor;
- device = pdev->device << 8;
- if (is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x) j++;
- }
-
- return j;
+ return err;
}
-/*
-** If at end of eth device list and can't use current entry, malloc
-** one up. If memory could not be allocated, print an error message.
-*/
-static struct net_device * __init
-insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *))
+static void __exit de4x5_module_exit (void)
{
- struct net_device *new;
-
- new = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
- if (new == NULL) {
- printk("de4x5.c: Device not initialised, insufficient memory\n");
- return NULL;
- } else {
- memset((char *)new, 0, sizeof(struct net_device));
- new->base_addr = iobase; /* assign the io address */
- new->init = init; /* initialisation routine */
- }
-
- return new;
+#if CONFIG_PCI
+ pci_unregister_driver (&de4x5_pci_driver);
+#endif
+#ifdef CONFIG_EISA
+ eisa_driver_unregister (&de4x5_eisa_driver);
+#endif
}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- *
- * Delete -DMODVERSIONS below if you didn't define this in your kernel
- *
- * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -DMODVERSIONS -include /linux/include/linux/modversions.h -c de4x5.c"
- * End:
- */
+module_init (de4x5_module_init);
+module_exit (de4x5_module_exit);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 860e53b4d696..784a41d78ebf 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -640,3 +640,4 @@ void tun_cleanup(void)
module_init(tun_init);
module_exit(tun_cleanup);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(TUN_MINOR);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index e83372b7adbb..f30b72218b30 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -2455,7 +2455,7 @@ error_out_remap:
error_out_regions:
pci_release_regions(pdev);
error_out_dev:
- kfree(dev);
+ free_netdev(dev);
error_out:
return err;
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index c247af6bf6ad..3059d04aaf0d 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -868,7 +868,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree (dev);
+ free_netdev (dev);
err_out:
return -ENODEV;
}
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 97a08cf349f3..df80c5c25e37 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -35,7 +35,7 @@ config HOSTESS_SV11
# The COSA/SRP driver has not been tested as non-modular yet.
config COSA
tristate "COSA/SRP sync serial boards support"
- depends on WAN && ISA && m && BROKEN
+ depends on WAN && ISA && m
---help---
This is a driver for COSA and SRP synchronous serial boards. These
boards allow to connect synchronous serial devices (for example
@@ -465,7 +465,7 @@ config DLCI_MAX
config SDLA
tristate "SDLA (Sangoma S502/S508) support"
- depends on DLCI && ISA && BROKEN_ON_SMP
+ depends on DLCI && ISA
help
Say Y here if you need a driver for the Sangoma S502A, S502E, and
S508 Frame Relay Access Devices. These are multi-protocol cards, but
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index d445e916a18b..8a440eea9c60 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -357,11 +357,7 @@ static void debug_status_out(struct cosa_data *cosa, int status);
/* ---------- Initialization stuff ---------- */
-#ifdef MODULE
-int init_module(void)
-#else
static int __init cosa_init(void)
-#endif
{
int i;
@@ -398,9 +394,9 @@ static int __init cosa_init(void)
}
return 0;
}
+module_init(cosa_init);
-#ifdef MODULE
-void cleanup_module (void)
+static void __exit cosa_exit(void)
{
struct cosa_data *cosa;
int i;
@@ -424,7 +420,7 @@ void cleanup_module (void)
}
unregister_chrdev(cosa_major, "cosa");
}
-#endif
+module_exit(cosa_exit);
/*
* This function should register all the net devices needed for the
@@ -513,7 +509,6 @@ static int cosa_probe(int base, int irq, int dma)
if (irq < 0) {
unsigned long irqs;
/* printk(KERN_INFO "IRQ autoprobe\n"); */
- sti();
irqs = probe_irq_on();
/*
* Enable interrupt on tx buffer empty (it sure is)
@@ -624,6 +619,7 @@ static void sppp_channel_init(struct channel_data *chan)
if (register_netdev(d) == -1) {
printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
sppp_detach(chan->pppdev.dev);
+ free_netdev(chan->pppdev.dev);
return;
}
}
@@ -658,7 +654,6 @@ static int cosa_sppp_open(struct net_device *d)
chan->rx_done = sppp_rx_done;
chan->usage=-1;
chan->cosa->usage++;
- MOD_INC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
err = sppp_open(d);
@@ -666,7 +661,6 @@ static int cosa_sppp_open(struct net_device *d)
spin_lock_irqsave(&chan->cosa->lock, flags);
chan->usage=0;
chan->cosa->usage--;
- MOD_DEC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
return err;
@@ -726,7 +720,6 @@ static int cosa_sppp_close(struct net_device *d)
}
chan->usage=0;
chan->cosa->usage--;
- MOD_DEC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
return 0;
}
@@ -1187,21 +1180,6 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
return cosa_gettype(cosa, (char *)arg);
case COSAIORIDSTR:
return cosa_getidstr(cosa, (char *)arg);
-/*
- * These two are _very_ugly_hack_(tm). Don't even look at this.
- * Implementing this saved me few reboots after some process segfaulted
- * inside this module.
- */
-#ifdef MODULE
-#if 0
- case COSAIOMINC:
- MOD_INC_USE_COUNT;
- return 0;
- case COSAIOMDEC:
- MOD_DEC_USE_COUNT;
- return 0;
-#endif
-#endif
case COSAIONRCARDS:
return nr_cards;
case COSAIONRCHANS:
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 5aab67436cc7..380bb830d738 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -55,14 +55,13 @@
#include <asm/dma.h>
#include <asm/uaccess.h>
-static const char devname[] = "dlci";
static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";
-static struct net_device *open_dev[CONFIG_DLCI_COUNT];
-
+static LIST_HEAD(dlci_devs);
+static spinlock_t dlci_dev_lock = SPIN_LOCK_UNLOCKED;
static char *basename[16];
-int dlci_init(struct net_device *dev);
+static void dlci_setup(struct net_device *);
/* allow FRAD's to register their name as a valid FRAD */
int register_frad(const char *name)
@@ -115,6 +114,7 @@ int unregister_frad(const char *name)
return(0);
}
+EXPORT_SYMBOL(unregister_frad);
/*
* these encapsulate the RFC 1490 requirements as well as
@@ -168,6 +168,14 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
int process, header;
dlp = dev->priv;
+ if (!pskb_may_pull(skb, sizeof(*hdr))) {
+ printk(KERN_NOTICE "%s: invalid data no header\n",
+ dev->name);
+ dlp->stats.rx_errors++;
+ kfree_skb(skb);
+ return;
+ }
+
hdr = (struct frhdr *) skb->data;
process = 0;
header = 0;
@@ -277,7 +285,7 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
return(ret);
}
-int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
+static int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
{
struct dlci_conf config;
struct dlci_local *dlp;
@@ -311,7 +319,7 @@ int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
return(0);
}
-int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct dlci_local *dlp;
@@ -401,21 +409,23 @@ static struct net_device_stats *dlci_get_stats(struct net_device *dev)
return(&dlp->stats);
}
-int dlci_add(struct dlci_add *dlci)
+static int dlci_add(struct dlci_add *dlci)
{
- struct net_device *master, *slave;
+ struct net_device *master, *slave;
struct dlci_local *dlp;
struct frad_local *flp;
int err, i;
- char buf[10];
+
/* validate slave device */
- slave = __dev_get_by_name(dlci->devname);
+ slave = dev_get_by_name(dlci->devname);
if (!slave)
return(-ENODEV);
- if (slave->type != ARPHRD_FRAD)
+ if (slave->type != ARPHRD_FRAD) {
+ dev_put(slave);
return(-EINVAL);
+ }
/* check for registration */
for (i=0;i<sizeof(basename) / sizeof(char *); i++)
@@ -424,33 +434,22 @@ int dlci_add(struct dlci_add *dlci)
(strlen(dlci->devname) > strlen(basename[i])))
break;
- if (i == sizeof(basename) / sizeof(char *))
+ if (i == sizeof(basename) / sizeof(char *)) {
+ dev_put(slave);
return(-EINVAL);
-
- /* check for too many open devices : should this be dynamic ? */
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (!open_dev[i])
- break;
-
- if (i == CONFIG_DLCI_COUNT)
- return(-ENOSPC); /* #### Alan: Comments on this?? */
+ }
/* create device name */
- sprintf(buf, "%s%02i", devname, i);
-
- master = kmalloc(sizeof(*master), GFP_KERNEL);
- if (!master)
+ master = alloc_netdev( sizeof(struct dlci_local), "dlci%d",
+ dlci_setup);
+ if (!master) {
+ dev_put(slave);
return(-ENOMEM);
-
- memset(master, 0, sizeof(*master));
-
- strcpy(master->name, buf);
- master->init = dlci_init;
- master->flags = 0;
+ }
err = register_netdev(master);
- if (err < 0)
- {
+ if (err < 0) {
+ dev_put(slave);
kfree(master);
return(err);
}
@@ -459,64 +458,65 @@ int dlci_add(struct dlci_add *dlci)
dlp = (struct dlci_local *) master->priv;
dlp->slave = slave;
+ dlp->master = master;
flp = slave->priv;
err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
if (err < 0)
{
unregister_netdev(master);
- kfree(master->priv);
- kfree(master);
+ dev_put(slave);
+ free_netdev(master);
return(err);
}
- strcpy(dlci->devname, buf);
- open_dev[i] = master;
- MOD_INC_USE_COUNT;
+ strcpy(dlci->devname, master->name);
+
+ spin_lock_bh(&dlci_dev_lock);
+ list_add(&dlp->list, &dlci_devs);
+ spin_unlock_bh(&dlci_dev_lock);
+
return(0);
}
-int dlci_del(struct dlci_add *dlci)
+static int dlci_del(struct dlci_add *dlci)
{
struct dlci_local *dlp;
struct frad_local *flp;
- struct net_device *master, *slave;
- int i, err;
+ struct net_device *master, *slave;
+ int err;
/* validate slave device */
master = __dev_get_by_name(dlci->devname);
if (!master)
return(-ENODEV);
- if (netif_running(master))
+ if (netif_running(master)) {
return(-EBUSY);
+ }
dlp = master->priv;
slave = dlp->slave;
flp = slave->priv;
err = (*flp->deassoc)(slave, master);
- if (err)
+ if (err)
return(err);
- unregister_netdev(master);
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (master == open_dev[i])
- break;
+ spin_lock_bh(&dlci_dev_lock);
+ list_del(&dlp->list);
+ spin_unlock_bh(&dlci_dev_lock);
- if (i<CONFIG_DLCI_COUNT)
- open_dev[i] = NULL;
+ unregister_netdev(master);
- kfree(master->priv);
+ dev_put(slave);
free_netdev(master);
- MOD_DEC_USE_COUNT;
-
return(0);
}
-int dlci_ioctl(unsigned int cmd, void *arg)
+static int dlci_ioctl(unsigned int cmd, void *arg)
{
struct dlci_add add;
int err;
@@ -548,16 +548,9 @@ int dlci_ioctl(unsigned int cmd, void *arg)
return(err);
}
-int dlci_init(struct net_device *dev)
+static void dlci_setup(struct net_device *dev)
{
- struct dlci_local *dlp;
-
- dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL);
- if (!dev->priv)
- return(-ENOMEM);
-
- memset(dev->priv, 0, sizeof(struct dlci_local));
- dlp = dev->priv;
+ struct dlci_local *dlp = dev->priv;
dev->flags = 0;
dev->open = dlci_open;
@@ -573,9 +566,7 @@ int dlci_init(struct net_device *dev)
dev->type = ARPHRD_DLCI;
dev->hard_header_len = sizeof(struct frhdr);
dev->addr_len = sizeof(short);
- memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
- return(0);
}
int __init init_dlci(void)
@@ -584,9 +575,6 @@ int __init init_dlci(void)
dlci_ioctl_set(dlci_ioctl);
printk("%s.\n", version);
-
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- open_dev[i] = NULL;
for(i=0;i<sizeof(basename) / sizeof(char *);i++)
basename[i] = NULL;
@@ -596,7 +584,16 @@ int __init init_dlci(void)
void __exit dlci_exit(void)
{
+ struct dlci_local *dlp, *nxt;
+
dlci_ioctl_set(NULL);
+
+ list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) {
+ unregister_netdev(dlp->master);
+ dev_put(dlp->slave);
+ free_netdev(dlp->master);
+ }
+
}
module_init(init_dlci);
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 349400d4d95a..81b2f271036c 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -140,6 +140,7 @@ static void change_level( struct net_device * );
static void timeout_change_level( struct net_device * );
static u32 calc_crc32( u32, u8 *, u32 );
static struct sk_buff * get_rx_buf( struct net_device * );
+static int sbni_init( struct net_device * );
#ifdef CONFIG_SBNI_MULTILINE
static int enslave( struct net_device *, struct net_device * );
@@ -205,23 +206,44 @@ sbni_isa_probe( struct net_device *dev )
}
}
-
-int __init
-sbni_probe( struct net_device *dev )
+static void __init sbni_devsetup(struct net_device *dev)
{
- int i;
+ ether_setup( dev );
+ dev->init = &sbni_init;
+ dev->open = &sbni_open;
+ dev->stop = &sbni_close;
+ dev->hard_start_xmit = &sbni_start_xmit;
+ dev->get_stats = &sbni_get_stats;
+ dev->set_multicast_list = &set_multicast_list;
+ dev->do_ioctl = &sbni_ioctl;
+
+ SET_MODULE_OWNER( dev );
+}
+int __init sbni_probe(void)
+{
+ struct net_device *dev;
static unsigned version_printed __initdata = 0;
+
if( version_printed++ == 0 )
printk( KERN_INFO "%s", version );
- if( !dev ) { /* simple sanity check */
- printk( KERN_ERR "sbni: NULL device!\n" );
- return -ENODEV;
- }
+ dev = alloc_netdev(sizeof(struct net_local), "sbni%d", sbni_devsetup);
+ if (!dev)
+ return -ENOMEM;
- SET_MODULE_OWNER( dev );
+ netdev_boot_setup_check(dev);
+
+ if (register_netdev(dev)) {
+ kfree(dev);
+ return -ENODEV;
+ }
+ return 0;
+}
+static int __init sbni_init(struct net_device *dev)
+{
+ int i;
if( dev->base_addr )
return sbni_isa_probe( dev );
/* otherwise we have to perform search our adapter */
@@ -338,7 +360,7 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq )
dev->base_addr = ioaddr;
/* Allocate dev->priv and fill in sbni-specific dev fields. */
- nl = (struct net_local *) kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ nl = dev->priv;
if( !nl ) {
printk( KERN_ERR "%s: unable to get memory!\n", dev->name );
release_region( ioaddr, SBNI_IO_EXTENT );
@@ -389,14 +411,6 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq )
nl->link = NULL;
#endif
- dev->open = &sbni_open;
- dev->stop = &sbni_close;
- dev->hard_start_xmit = &sbni_start_xmit;
- dev->get_stats = &sbni_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &sbni_ioctl;
- ether_setup( dev );
-
sbni_cards[ num++ ] = dev;
return dev;
}
@@ -1478,15 +1492,15 @@ init_module( void )
struct net_device *dev;
while( num < SBNI_MAX_NUM_CARDS ) {
- if( !(dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) ){
+ dev = alloc_netdev(sizeof(struct net_local),
+ "sbni%d", sbni_devsetup);
+ if( !dev) {
printk( KERN_ERR "sbni: unable to allocate device!\n" );
return -ENOMEM;
}
- memset( dev, 0, sizeof(struct net_device) );
sprintf( dev->name, "sbni%d", num );
- dev->init = sbni_probe;
if( register_netdev( dev ) ) {
kfree( dev );
break;
@@ -1506,7 +1520,6 @@ cleanup_module( void )
if( (dev = sbni_cards[ num ]) != NULL ) {
unregister_netdev( dev );
release_region( dev->base_addr, SBNI_IO_EXTENT );
- kfree( dev->priv );
free_netdev( dev );
}
}
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 8079d8b5ddee..e11984b2bb03 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -71,6 +71,8 @@ static unsigned int valid_mem[] __initdata = {
0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
+static spinlock_t sdla_lock = SPIN_LOCK_UNLOCKED;
+
/*********************************************************
*
* these are the core routines that access the card itself
@@ -79,10 +81,10 @@ static unsigned int valid_mem[] __initdata = {
#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
-static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
+static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
- unsigned long flags;
- char *temp, *base;
+ char *temp;
+ const void *base;
int offset, bytes;
temp = buf;
@@ -90,13 +92,10 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
- base = (void *) (dev->mem_start + offset);
+ base = (const void *) (dev->mem_start + offset);
- save_flags(flags);
- cli();
SDLA_WINDOW(dev, addr);
memcpy(temp, base, bytes);
- restore_flags(flags);
addr += bytes;
temp += bytes;
@@ -104,10 +103,19 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
}
}
-static void sdla_write(struct net_device *dev, int addr, void *buf, short len)
+static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
unsigned long flags;
- char *temp, *base;
+ spin_lock_irqsave(&sdla_lock, flags);
+ __sdla_read(dev, addr, buf, len);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+}
+
+static void __sdla_write(struct net_device *dev, int addr,
+ const void *buf, short len)
+{
+ const char *temp;
+ void *base;
int offset, bytes;
temp = buf;
@@ -116,17 +124,27 @@ static void sdla_write(struct net_device *dev, int addr, void *buf, short len)
offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
base = (void *) (dev->mem_start + offset);
- save_flags(flags);
- cli();
+
SDLA_WINDOW(dev, addr);
memcpy(base, temp, bytes);
- restore_flags(flags);
+
addr += bytes;
temp += bytes;
len -= bytes;
}
}
+static void sdla_write(struct net_device *dev, int addr,
+ const void *buf, short len)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdla_lock, flags);
+ __sdla_write(dev, addr, buf, len);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+}
+
+
static void sdla_clear(struct net_device *dev)
{
unsigned long flags;
@@ -138,8 +156,7 @@ static void sdla_clear(struct net_device *dev)
bytes = SDLA_WINDOW_SIZE;
base = (void *) dev->mem_start;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
while(len)
{
SDLA_WINDOW(dev, addr);
@@ -148,7 +165,8 @@ static void sdla_clear(struct net_device *dev)
addr += bytes;
len -= bytes;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
+
}
static char sdla_byte(struct net_device *dev, int addr)
@@ -158,11 +176,10 @@ static char sdla_byte(struct net_device *dev, int addr)
temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
SDLA_WINDOW(dev, addr);
byte = *temp;
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
return(byte);
}
@@ -414,7 +431,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
struct frad_local *flp;
struct sdla_cmd *cmd_buf;
unsigned long pflags;
- int jiffs, ret, waiting, len;
+ unsigned long jiffs;
+ int ret, waiting, len;
long window;
flp = dev->priv;
@@ -423,8 +441,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
ret = 0;
len = 0;
jiffs = jiffies + HZ; /* 1 second is plenty */
- save_flags(pflags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
cmd_buf->cmd = cmd;
cmd_buf->dlci = dlci;
@@ -436,7 +454,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
cmd_buf->length = inlen;
cmd_buf->opp_flag = 1;
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
waiting = 1;
len = 0;
@@ -444,18 +462,17 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
{
if (waiting++ % 3)
{
- save_flags(pflags);
- cli();
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
waiting = ((volatile int)(cmd_buf->opp_flag));
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
}
}
if (!waiting)
{
- save_flags(pflags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window);
ret = cmd_buf->retval;
len = cmd_buf->length;
@@ -471,7 +488,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
if (ret)
memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);
- restore_flags(pflags);
+ spin_unlock_irqrestore(&sdla_lock, pflags);
}
else
ret = SDLA_RET_TIMEOUT;
@@ -555,7 +572,6 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
if (i == CONFIG_DLCI_MAX)
return(-EMLINK); /* #### Alan: Comments on this ?? */
- MOD_INC_USE_COUNT;
flp->master[i] = master;
flp->dlci[i] = -*(short *)(master->dev_addr);
@@ -588,7 +604,6 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
flp->master[i] = NULL;
flp->dlci[i] = 0;
- MOD_DEC_USE_COUNT;
if (netif_running(slave)) {
if (flp->config.station == FRAD_STATION_CPE)
@@ -688,14 +703,14 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
if (ret == SDLA_RET_OK)
{
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&sdla_lock, flags);
SDLA_WINDOW(dev, addr);
pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
- sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
- SDLA_WINDOW(dev, addr);
+ __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+ SDLA_WINDOW(dev, addr);
pbuf->opp_flag = 1;
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
}
break;
}
@@ -753,8 +768,7 @@ static void sdla_receive(struct net_device *dev)
pbufi = NULL;
pbuf = NULL;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sdla_lock, flags);
switch (flp->type)
{
@@ -821,7 +835,7 @@ static void sdla_receive(struct net_device *dev)
case SDLA_S502A:
case SDLA_S502E:
if (success)
- sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
+ __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
cmd->opp_flag = 0;
@@ -834,9 +848,9 @@ static void sdla_receive(struct net_device *dev)
split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
len2 = len - split;
- sdla_read(dev, addr, skb_put(skb, len2), len2);
+ __sdla_read(dev, addr, skb_put(skb, len2), len2);
if (split)
- sdla_read(dev, buf_base, skb_put(skb, split), split);
+ __sdla_read(dev, buf_base, skb_put(skb, split), split);
}
/* increment the buffer we're looking at */
@@ -853,7 +867,7 @@ static void sdla_receive(struct net_device *dev)
(*dlp->receive)(skb, master);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&sdla_lock, flags);
}
static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
@@ -979,8 +993,6 @@ static int sdla_close(struct net_device *dev)
netif_stop_queue(dev);
- MOD_DEC_USE_COUNT;
-
return(0);
}
@@ -1082,8 +1094,6 @@ static int sdla_open(struct net_device *dev)
netif_start_queue(dev);
- MOD_INC_USE_COUNT;
-
return(0);
}
@@ -1614,19 +1624,44 @@ static struct net_device_stats *sdla_stats(struct net_device *dev)
return(&flp->stats);
}
-int __init sdla_init(struct net_device *dev)
+static void setup_sdla(struct net_device *dev)
+{
+ dev->flags = 0;
+ dev->type = 0xFFFF;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->mtu = SDLA_MAX_MTU;
+}
+
+static int frad_registered;
+
+struct net_device * __init sdla_init(void)
{
+ struct net_device *dev;
struct frad_local *flp;
+ int err = -ENOMEM;
+
+ if (!frad_registered) {
+ err = register_frad(devname);
+ if (err) {
+ printk(KERN_ERR "%s: frad registration failed %d\n",
+ devname, err);
+ return ERR_PTR(err);
+ }
+ frad_registered = 1;
+ printk("%s.\n", version);
+ }
+
- /* allocate the private data structure */
- flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
- if (!flp)
- return(-ENOMEM);
+ dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
+ if (!dev)
+ goto out;
- memset(flp, 0, sizeof(struct frad_local));
- dev->priv = flp;
+ SET_MODULE_OWNER(dev);
+ netdev_boot_setup_check(dev);
+
+ flp = dev->priv;
- dev->flags = 0;
dev->open = sdla_open;
dev->stop = sdla_close;
dev->do_ioctl = sdla_ioctl;
@@ -1635,12 +1670,6 @@ int __init sdla_init(struct net_device *dev)
dev->hard_start_xmit = sdla_transmit;
dev->change_mtu = sdla_change_mtu;
- dev->type = 0xFFFF;
- dev->hard_header_len = 0;
- dev->addr_len = 0;
- dev->mtu = SDLA_MAX_MTU;
- SET_MODULE_OWNER(dev);
-
flp->activate = sdla_activate;
flp->deactivate = sdla_deactivate;
flp->assoc = sdla_assoc;
@@ -1652,44 +1681,45 @@ int __init sdla_init(struct net_device *dev)
flp->timer.data = (unsigned long) dev;
flp->timer.function = sdla_poll;
- return(0);
-}
-
-int __init sdla_c_setup(void)
-{
- printk("%s.\n", version);
- register_frad(devname);
- return 0;
+ err = register_netdev(dev);
+ if (err)
+ goto out1;
+ return dev;
+out1:
+ kfree(dev);
+out:
+ return ERR_PTR(err);
}
#ifdef MODULE
-static struct net_device sdla0 = {
- .name = "sdla0",
- .init = sdla_init
-};
-#endif /* MODULE */
+static struct net_device *sdla0;
static int __init init_sdla(void)
{
int result = 0;
- sdla_c_setup();
-#ifdef MODULE
- result = register_netdev(&sdla0);
-#endif
+ sdla0 = sdla_init();
+ if (IS_ERR(sdla0))
+ result = PTR_ERR(sdla0);
+
return result;
}
static void __exit exit_sdla(void)
{
-#ifdef MODULE
- unregister_netdev(&sdla0);
- if (sdla0.priv)
- kfree(sdla0.priv);
- if (sdla0.irq)
- free_irq(sdla0.irq, &sdla0);
-#endif
+ struct frad_local *flp;
+
+ unregister_netdev(sdla0);
+ if (sdla0->irq)
+ free_irq(sdla0->irq, sdla0);
+
+ flp = sdla0->priv;
+ del_timer_sync(&flp->timer);
+ free_netdev(sdla0);
+
+ unregister_frad(devname);
}
+#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 02362e27c7ae..4b78dce165f5 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2665,11 +2665,13 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
badmic:
dev_kfree_skb_irq (skb);
+#else
+ if (0) {
+#endif
badrx:
OUT4500( apriv, EVACK, EV_RX);
goto exitrx;
}
-#endif
}
#if WIRELESS_EXT > 15
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
@@ -5662,9 +5664,10 @@ static int airo_get_power(struct net_device *dev,
char *extra)
{
struct airo_info *local = dev->priv;
+ int mode;
readConfigRid(local, 1);
- int mode = local->config.powerSaveMode;
+ mode = local->config.powerSaveMode;
if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
return 0;
if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index b43fa0cf3940..b29e42a146f1 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -302,12 +302,14 @@ typedef struct hermes_response {
#define hermes_read_reg(hw, off) ((hw)->io_space ? \
inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
-#define hermes_write_reg(hw, off, val) ((hw)->io_space ? \
- outw_p((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
- writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )))
-
-#define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
-#define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
+#define hermes_write_reg(hw, off, val) do { \
+ if ((hw)->io_space) \
+ outw_p((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \
+ else \
+ writew((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \
+ } while (0)
+#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
+#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
/* Function prototypes */
void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing);
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 8a3328687d1f..c22ca46b0d81 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -577,7 +577,7 @@ err_out_free_res:
#endif
pci_release_regions(pdev);
err_out_free_netdev:
- kfree (dev);
+ free_netdev (dev);
return -ENODEV;
}
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 60bb81d4649b..4e384344042c 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -1758,7 +1758,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
printk("53c700: scsi%d, command ", SCp->device->host->host_no);
print_command(SCp->cmnd);
#endif
- if(SCp->device->tagged_supported && !SCp->device->tagged_queue
+ if(SCp->device->tagged_supported && !SCp->device->simple_tags
&& (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
&& NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
/* upper layer has indicated tags are supported. We don't
diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
index 85d4d0507546..904115d0eac3 100644
--- a/drivers/scsi/AM53C974.c
+++ b/drivers/scsi/AM53C974.c
@@ -1231,8 +1231,8 @@ static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs)
hostdata->sel_cmd = NULL;
hostdata->selecting = 0;
#ifdef SCSI2
- if (!hostdata->connected->device->tagged_queue)
-#endif
+ if (!hostdata->conneted->device->simple_tags)
+#else
hostdata->busy[hostdata->connected->device->id] |= (1 << hostdata->connected->device->lun);
/* very strange -- use_sg is sometimes nonzero for request sense commands !! */
if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) {
@@ -1811,7 +1811,7 @@ static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd * cmd,
case HEAD_OF_QUEUE_TAG:
case ORDERED_QUEUE_TAG:
case SIMPLE_QUEUE_TAG:
- cmd->device->tagged_queue = 0;
+ cmd->device->simple_tags = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
break;
default:
@@ -1958,7 +1958,7 @@ static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag
#endif
#ifdef SCSI2
- if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
+ if (cmd->device->simple_tags && (tag != TAG_NONE)) {
tmp[1] = SIMPLE_QUEUE_TAG;
if (tag == TAG_NEXT) {
/* 0 is TAG_NONE, used to imply no tag for this command */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 01218bd31486..b3c9048c3a17 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -22,6 +22,17 @@ config SCSI
module if your root file system (the one containing the directory /)
is located on a SCSI device.
+config SCSI_PROC_FS
+ bool "legacy /proc/scsi/ support"
+ depends on SCSI
+ default y
+ ---help---
+ This option enables support for the various files in
+ /proc/scsi. In Linux 2.6 this has been superceeded by
+ files in sysfs but many legacy applications rely on this.
+
+ If unusure say Y.
+
comment "SCSI support type (disk, tape, CD-ROM)"
depends on SCSI
@@ -726,13 +737,13 @@ config IBMMCA_SCSI_DEV_RESET
config SCSI_IPS
tristate "IBM ServeRAID support"
- depends on X86 && PCI && SCSI
+ depends on PCI && SCSI
---help---
This is support for the IBM ServeRAID hardware RAID controllers.
See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
for more information. If this driver does not work correctly
without modification please contact the author by email at
- ipslinux@us.ibm.com.
+ ipslinux@adaptec.com.
You can build this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
@@ -989,36 +1000,9 @@ config SCSI_NCR_Q720
Unless you have an NCR manufactured machine, the chances are that
you do not have this SCSI card, so say N.
-config SCSI_SYM53C8XX
- tristate "SYM53C8XX SCSI support"
- depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI
- ---help---
- This driver supports all the features of recent 53C8XX chips (used
- in PCI SCSI controllers), notably the hardware phase mismatch
- feature of the SYM53C896.
-
- Older versions of the 53C8XX chips are not supported by this
- driver. If your system uses either a 810 rev. < 16, a 815, or a 825
- rev. < 16 PCI SCSI processor, you must use the generic NCR53C8XX
- driver ("NCR53C8XX SCSI support" above) or configure both the
- NCR53C8XX and this SYM53C8XX drivers either as module or linked to
- the kernel image.
-
- When both drivers are linked into the kernel, the SYM53C8XX driver
- is called first at initialization and you can use the 'excl=ioaddr'
- driver boot option to exclude attachment of adapters by the
- SYM53C8XX driver. For example, entering
- 'sym53c8xx=excl:0xb400,excl=0xc000' at the lilo prompt prevents
- adapters at io address 0xb400 and 0xc000 from being attached by the
- SYM53C8XX driver, thus allowing the NCR53C8XX driver to attach them.
- The 'excl' option is also supported by the NCR53C8XX driver.
-
- Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
- information.
-
config SCSI_NCR53C8XX_DEFAULT_TAGS
int " default tagged command queue depth"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
+ depends on SCSI_ZALON || SCSI_NCR_Q720
default "8"
---help---
"Tagged command queuing" is a feature of SCSI-2 which improves
@@ -1044,7 +1028,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
config SCSI_NCR53C8XX_MAX_TAGS
int " maximum number of queued commands"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
+ depends on SCSI_ZALON || SCSI_NCR_Q720
default "32"
---help---
This option allows you to specify the maximum number of commands
@@ -1061,7 +1045,7 @@ config SCSI_NCR53C8XX_MAX_TAGS
config SCSI_NCR53C8XX_SYNC
int " synchronous transfers frequency in MHz"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
+ depends on SCSI_ZALON || SCSI_NCR_Q720
default "20"
---help---
The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
@@ -1095,7 +1079,7 @@ config SCSI_NCR53C8XX_SYNC
config SCSI_NCR53C8XX_PROFILE
bool " enable profiling"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720)
+ depends on SCSI_ZALON || SCSI_NCR_Q720
help
This option allows you to enable profiling information gathering.
These statistics are not very accurate due to the low frequency
@@ -1104,34 +1088,9 @@ config SCSI_NCR53C8XX_PROFILE
The normal answer therefore is N.
-config SCSI_NCR53C8XX_IOMAPPED
- bool " use normal IO"
- depends on SCSI_SYM53C8XX && !(SCSI_ZALON || SCSI_NCR_Q720)
- help
- If you say Y here, the driver will use normal IO, as opposed to
- memory mapped IO. Memory mapped IO has less latency than normal IO
- and works for most Intel-based hardware. Under Linux/Alpha only
- normal IO is currently supported by the driver and so, this option
- has no effect on those systems.
-
- The normal answer therefore is N; try Y only if you encounter SCSI
- related problems.
-
-config SCSI_NCR53C8XX_PQS_PDS
- bool " include support for the NCR PQS/PDS SCSI card"
- depends on SCSI_SYM53C8XX
- help
- Say Y here if you have a special SCSI adapter produced by NCR
- corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need
- this if you do not have one of these adapters. However, since this
- device is detected as a specific PCI device, this option is quite
- safe.
-
- The common answer here is N, but answering Y is safe.
-
config SCSI_NCR53C8XX_NO_DISCONNECT
bool " not allow targets to disconnect"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
+ depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
help
This option is only provided for safety if you suspect some SCSI
device of yours to not support properly the target-disconnect
@@ -1139,26 +1098,6 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
not allow targets to disconnect is not reasonable if there is more
than 1 device on a SCSI bus. The normal answer therefore is N.
-config SCSI_NCR53C8XX_SYMBIOS_COMPAT
- bool " assume boards are SYMBIOS compatible (EXPERIMENTAL)"
- depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720 ) && EXPERIMENTAL
- ---help---
- This option allows you to enable some features depending on GPIO
- wiring. These General Purpose Input/Output pins can be used for
- vendor specific features or implementation of the standard SYMBIOS
- features. Genuine SYMBIOS controllers use GPIO0 in output for
- controller LED and GPIO3 bit as a flag indicating
- singled-ended/differential interface. The Tekram DC-390U/F boards
- uses a different GPIO wiring.
-
- Your answer to this question is ignored if all your controllers have
- NVRAM, since the driver is able to detect the board type from the
- NVRAM format.
-
- If all the controllers in your system are genuine SYMBIOS boards or
- use BIOS and drivers from SYMBIOS, you would want to say Y here,
- otherwise N. N is the safe answer.
-
config SCSI_MCA_53C9X
tristate "NCR MCA 53C9x SCSI support"
depends on MCA && SCSI && BROKEN_ON_SMP
@@ -1298,6 +1237,16 @@ config SCSI_QLOGIC_1280
The module will be called qla1280. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
+config SCSI_QLOGIC_1280_PIO
+ bool "Use PIO instead of MMIO" if !X86_VISWS
+ depends on SCSI_QLOGIC_1280
+ default y if X86_VISWS
+ help
+ This instructs the driver to use programmed I/O ports (PIO) instead
+ of PCI shared memory (MMIO). This can possibly solve some problems
+ in case your mainboard has memory consistency issues. If unsure,
+ say N.
+
config SCSI_QLOGICPTI
tristate "PTI Qlogic, ISP Driver"
depends on SBUS && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b2ed067c7b98..fb2442aeb330 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -126,7 +126,8 @@ scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \
scsicam.o scsi_error.o scsi_lib.o \
scsi_scan.o scsi_syms.o scsi_sysfs.o \
scsi_devinfo.o
-scsi_mod-$(CONFIG_PROC_FS) += scsi_proc.o
+scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
+scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
scsi_mod-$(CONFIG_X86_PC9800) += scsi_pc98.o
sd_mod-objs := sd.o
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index dba125a0db5c..7262cca5529e 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2512,7 +2512,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
case HEAD_OF_QUEUE_TAG:
case ORDERED_QUEUE_TAG:
case SIMPLE_QUEUE_TAG:
- cmd->device->tagged_queue = 0;
+ cmd->device->simple_tags = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
break;
default:
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 1ec4a55cbd10..390f63b3a371 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -6362,8 +6362,8 @@ advansys_slave_configure(Scsi_Device *device)
} else {
scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
}
- ASC_DBG3(1, "advansys_slave_configure: shp 0x%lx, id %d, depth %d\n",
- (ulong) shp, device->id, device->queue_depth);
+ ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
+ (ulong) device, (ulong) boardp, device->id, device->queue_depth);
return 0;
}
@@ -9354,8 +9354,8 @@ asc_prt_scsi_host(struct Scsi_Host *s)
printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
printk(
-" next 0x%lx, host_busy %u, host_no %d, last_reset %d,\n",
- (ulong) s->next, s->host_busy, s->host_no,
+" host_busy %u, host_no %d, last_reset %d,\n",
+ s->host_busy, s->host_no,
(unsigned) s->last_reset);
#if ASC_LINUX_KERNEL24
@@ -9399,8 +9399,8 @@ asc_prt_scsi_cmnd(Scsi_Cmnd *s)
printk(
" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
- (ulong) s->host, (ulong) s->device, s->target, s->lun,
- s->channel);
+ (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
+ s->device->channel);
asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index a0452a6c6122..efc61b3f2502 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -768,7 +768,7 @@ intr_ret_t acornscsi_kick(AS_Host *host)
/*
* tagged queueing - allocate a new tag to this command
*/
- if (SCpnt->device->tagged_queue) {
+ if (SCpnt->device->simple_tags) {
SCpnt->device->current_tag += 1;
if (SCpnt->device->current_tag == 0)
SCpnt->device->current_tag = 1;
@@ -1590,7 +1590,7 @@ void acornscsi_message(AS_Host *host)
*/
printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
host->host->host_no, acornscsi_target(host));
- host->SCpnt->device->tagged_queue = 0;
+ host->SCpnt->device->simple_tags = 0;
set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns);
break;
#endif
@@ -2935,7 +2935,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
p += sprintf(p, " %d/%d ", scd->id, scd->lun);
if (scd->tagged_supported)
p += sprintf(p, "%3sabled(%3d) ",
- scd->tagged_queue ? "en" : "dis",
+ scd->simple_tags ? "en" : "dis",
scd->current_tag);
else
p += sprintf(p, "unsupported ");
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index fbda4d4f78a7..2c99ea7dae85 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -1819,7 +1819,7 @@ static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
/*
* tagged queuing - allocate a new tag to this command
*/
- if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
+ if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE &&
SCpnt->cmnd[0] != INQUIRY) {
SCpnt->device->current_tag += 1;
if (SCpnt->device->current_tag == 0)
@@ -3012,7 +3012,7 @@ int fas216_print_devices(FAS216_Info *info, char *buffer)
p += sprintf(p, " %d/%d ", scd->id, scd->lun);
if (scd->tagged_supported)
p += sprintf(p, "%3sabled(%3d) ",
- scd->tagged_queue ? "en" : "dis",
+ scd->simple_tags ? "en" : "dis",
scd->current_tag);
else
p += sprintf(p, "unsupported ");
diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
index 943778cca0eb..d165a3af3e14 100644
--- a/drivers/scsi/cpqfcTSinit.c
+++ b/drivers/scsi/cpqfcTSinit.c
@@ -603,7 +603,7 @@ int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg)
return -ENOMEM;
}
// Now build a Scsi_Request to pass down...
- ScsiPassThruReq = scsi_allocate_request(ScsiDev);
+ ScsiPassThruReq = scsi_allocate_request(ScsiDev, GFP_KERNEL);
if (ScsiPassThruReq == NULL) {
kfree(buf);
return -ENOMEM;
diff --git a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
index b41038baa394..2b5735863b65 100644
--- a/drivers/scsi/cpqfcTSworker.c
+++ b/drivers/scsi/cpqfcTSworker.c
@@ -2878,7 +2878,7 @@ static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd)
}
}
-Done:
+Done: ;
}
extern int is_private_data_of_cpqfc(CPQFCHBA *hba, void * pointer);
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index e0a1d2191eed..107c220ae086 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -224,14 +224,14 @@ static char traceoverflow[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
#define DC395x_SMP_IO_UNLOCK(dev,irq_flags) spin_unlock_irqrestore(((struct Scsi_Host*)dev)->host_lock,irq_flags)
-#define DC395x_read8(acb,address) (u8)(inb(acb->IOPortBase + (address)))
+#define DC395x_read8(acb,address) (u8)(inb(acb->io_port_base + (address)))
#define DC395x_read8_(address, base) (u8)(inb((USHORT)(base) + (address)))
-#define DC395x_read16(acb,address) (u16)(inw(acb->IOPortBase + (address)))
-#define DC395x_read32(acb,address) (u32)(inl(acb->IOPortBase + (address)))
-#define DC395x_write8(acb,address,value) outb((value), acb->IOPortBase + (address))
+#define DC395x_read16(acb,address) (u16)(inw(acb->io_port_base + (address)))
+#define DC395x_read32(acb,address) (u32)(inl(acb->io_port_base + (address)))
+#define DC395x_write8(acb,address,value) outb((value), acb->io_port_base + (address))
#define DC395x_write8_(address,value,base) outb((value), (USHORT)(base) + (address))
-#define DC395x_write16(acb,address,value) outw((value), acb->IOPortBase + (address))
-#define DC395x_write32(acb,address,value) outl((value), acb->IOPortBase + (address))
+#define DC395x_write16(acb,address,value) outw((value), acb->io_port_base + (address))
+#define DC395x_write32(acb,address,value) outl((value), acb->io_port_base + (address))
#define BUS_ADDR(sg) sg_dma_address(&(sg))
@@ -383,7 +383,8 @@ struct DeviceCtlBlk {
struct AdapterCtlBlk {
struct Scsi_Host *scsi_host;
- u16 IOPortBase;
+ u16 io_port_base;
+ u16 io_port_len;
struct list_head dcb_list; /* head of going dcb list */
struct DeviceCtlBlk *dcb_run_robin;
@@ -496,10 +497,6 @@ static void request_sense(struct AdapterCtlBlk *acb,
struct ScsiReqBlk *srb);
static inline void set_xfer_rate(struct AdapterCtlBlk *acb,
struct DeviceCtlBlk *dcb);
-static void init_dcb(struct AdapterCtlBlk *acb,
- struct DeviceCtlBlk **pdcb, u8 target, u8 lun);
-static void remove_dev(struct AdapterCtlBlk *acb,
- struct DeviceCtlBlk *dcb);
static void waiting_timeout(unsigned long ptr);
@@ -822,6 +819,7 @@ void __init eeprom_override(struct NvRamType *eeprom)
*
* @head: The pointer to the head of the list to count the items in.
**/
+static
unsigned int list_size(struct list_head *head)
{
unsigned int count = 0;
@@ -841,6 +839,7 @@ unsigned int list_size(struct list_head *head)
* @pos: The pointer the dcb for which we are searching for the
* following dcb.
**/
+static
struct DeviceCtlBlk *dcb_get_next(
struct list_head *head,
struct DeviceCtlBlk *pos)
@@ -1449,34 +1448,6 @@ complete:
}
-/***********************************************************************
- * Function static int dc395x_slave_alloc()
- *
- * Purpose: Allocate DCB
- ***********************************************************************/
-static int dc395x_slave_alloc(struct scsi_device *sdp)
-{
- struct AdapterCtlBlk *acb;
- struct DeviceCtlBlk *dummy;
-
- acb = (struct AdapterCtlBlk *) sdp->host->hostdata;
-
- init_dcb(acb, &dummy, sdp->id, sdp->lun);
-
- return dummy ? 0 : -ENOMEM;
-}
-
-
-static void dc395x_slave_destroy(struct scsi_device *sdp)
-{
- struct AdapterCtlBlk *acb;
- struct DeviceCtlBlk *dcb;
-
- acb = (struct AdapterCtlBlk *) sdp->host->hostdata;
- dcb = find_dcb(acb, sdp->id, sdp->lun);
-
- remove_dev(acb, dcb);
-}
/*
@@ -1635,7 +1606,6 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
dcb->sync_offset = 0;
dcb->dev_mode = eeprom->target[dcb->target_id].cfg0;
- /*dcb->AdpMode = eeprom->channel_cfg; */
period_index = eeprom->target[dcb->target_id].period & 0x07;
dcb->min_nego_period = clock_period[period_index];
if (!(dcb->dev_mode & NTC_DO_WIDE_NEGO)
@@ -1824,7 +1794,6 @@ static void selto_timer(struct AdapterCtlBlk *acb)
{
if (timer_pending(&acb->selto_timer))
return;
- init_timer(&acb->selto_timer);
acb->selto_timer.function = selection_timeout_missed;
acb->selto_timer.data = (unsigned long) acb;
if (time_before
@@ -4049,40 +4018,8 @@ static void reselect(struct AdapterCtlBlk *acb)
}
-/* Dynamic device handling */
-
-/* Remove dev (and DCB) */
-static
-void remove_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
-{
- struct DeviceCtlBlk *i;
- struct DeviceCtlBlk *tmp;
-
- dprintkdbg(DBG_0, "remove_dev\n");
- if (list_size(&dcb->srb_going_list) > 1) {
- dprintkdbg(DBG_DCB, "Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",
- dcb->target_id, dcb->target_lun, (int) dcb,
- list_size(&dcb->srb_going_list));
- return;
- }
- acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun);
- acb->children[dcb->target_id][dcb->target_lun] = NULL;
- list_for_each_entry_safe(i, tmp, &acb->dcb_list, list) {
- if (dcb == i) {
- list_del(&i->list);
- break;
- }
- }
- dprintkdbg(DBG_DCB, "Driver about to free DCB (ID %i, LUN %i): %p\n",
- dcb->target_id, dcb->target_lun, dcb);
- if (dcb == acb->active_dcb)
- acb->active_dcb = NULL;
- if (dcb == acb->dcb_run_robin)
- acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb);
- dc395x_kfree(dcb);
-}
static inline u8 tagq_blacklist(char *name)
@@ -4681,58 +4618,55 @@ void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
}
-/*
- *********************************************************************
- * dc395x_queue_command
+
+
+
+/**
+ * device_alloc - Allocate a new device instance. This create the
+ * devices instance and sets up all the data items. The adapter
+ * instance is required to obtain confiuration information for this
+ * device. This does *not* add this device to the adapters device
+ * list.
*
- * Function : void init_dcb
- * Purpose : initialize the internal structures for a given DCB
- * Inputs : cmd - pointer to this scsi cmd request block structure
- *********************************************************************
- */
+ * @acb: The adapter to obtain configuration information from.
+ * @target: The target for the new device.
+ * @lun: The lun for the new device.
+ *
+ * Return the new device if succesfull or NULL on failure.
+ **/
static
-void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
- u8 target, u8 lun)
+struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 target, u8 lun)
{
struct NvRamType *eeprom = &acb->eeprom;
- u8 period_index;
+ u8 period_index = eeprom->target[target].period & 0x07;
struct DeviceCtlBlk *dcb;
- struct DeviceCtlBlk *dcb2;
- dprintkdbg(DBG_0, "init_dcb..............\n");
dcb = dc395x_kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC);
- /*dcb = find_dcb (acb, target, lun); */
- *pdcb = dcb;
- dcb2 = NULL;
- if (!dcb)
- return;
-
- INIT_LIST_HEAD(&dcb->srb_waiting_list);
+ dprintkdbg(DBG_0, "device_alloc: device %p\n", dcb);
+ if (!dcb) {
+ return NULL;
+ }
+ dcb->acb = NULL;
INIT_LIST_HEAD(&dcb->srb_going_list);
- if (list_empty(&acb->dcb_list))
- acb->dcb_run_robin = dcb;
- list_add_tail(&dcb->list, &acb->dcb_list);
-
- /* $$$$$$$ */
- dcb->acb = acb;
- dcb->target_id = target;
- dcb->target_lun = lun;
- /* $$$$$$$ */
+ INIT_LIST_HEAD(&dcb->srb_waiting_list);
dcb->active_srb = NULL;
- /* $$$$$$$ */
dcb->tag_mask = 0;
- dcb->flag = 0;
dcb->max_command = 1;
- /* $$$$$$$ */
+ dcb->target_id = target;
+ dcb->target_lun = lun;
+#ifndef DC395x_NO_DISCONNECT
+ dcb->identify_msg =
+ IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
+#else
+ dcb->identify_msg = IDENTIFY(0, lun);
+#endif
dcb->dev_mode = eeprom->target[target].cfg0;
- /*dcb->AdpMode = eeprom->channel_cfg; */
dcb->inquiry7 = 0;
dcb->sync_mode = 0;
- /* $$$$$$$ */
+ dcb->min_nego_period = clock_period[period_index];
dcb->sync_period = 0;
dcb->sync_offset = 0;
- period_index = eeprom->target[target].period & 0x07;
- dcb->min_nego_period = clock_period[period_index];
+ dcb->flag = 0;
#ifndef DC395x_NO_WIDE
if ((dcb->dev_mode & NTC_DO_WIDE_NEGO)
@@ -4744,318 +4678,166 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
if (!(lun) || current_sync_offset)
dcb->sync_mode |= SYNC_NEGO_ENABLE;
#endif
- /* $$$$$$$ */
-#ifndef DC395x_NO_DISCONNECT
- dcb->identify_msg =
- IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
-#else
- dcb->identify_msg = IDENTIFY(0, lun);
-#endif
- /* $$$$$$$ */
if (dcb->target_lun != 0) {
/* Copy settings */
- struct DeviceCtlBlk *prevDCB;
- list_for_each_entry(prevDCB, &acb->dcb_list, list)
- if (prevDCB->target_id == dcb->target_id)
+ struct DeviceCtlBlk *p;
+ list_for_each_entry(p, &acb->dcb_list, list)
+ if (p->target_id == dcb->target_id)
break;
- dprintkdbg(DBG_KG,
+ dprintkdbg(DBG_KG,
"Copy settings from %02i-%02i to %02i-%02i\n",
- prevDCB->target_id, prevDCB->target_lun,
+ p->target_id, p->target_lun,
dcb->target_id, dcb->target_lun);
- dcb->sync_mode = prevDCB->sync_mode;
- dcb->sync_period = prevDCB->sync_period;
- dcb->min_nego_period = prevDCB->min_nego_period;
- dcb->sync_offset = prevDCB->sync_offset;
- dcb->inquiry7 = prevDCB->inquiry7;
- };
-
- acb->dcb_map[target] |= (1 << lun);
- acb->children[target][lun] = dcb;
+ dcb->sync_mode = p->sync_mode;
+ dcb->sync_period = p->sync_period;
+ dcb->min_nego_period = p->min_nego_period;
+ dcb->sync_offset = p->sync_offset;
+ dcb->inquiry7 = p->inquiry7;
+ }
+ return dcb;
}
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-/*
- * Memory for trace buffers
- */
+/**
+ * adapter_add_device - Adds the device instance to the adaptor instance.
+ *
+ * @acb: The adapter device to be updated
+ * @dcb: A newly created and intialised device instance to add.
+ **/
static
-void free_tracebufs(struct AdapterCtlBlk *acb, int srb_idx)
+void adapter_add_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{
- int i;
- const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
- for (i = 0; i < srb_idx; i += bufs_per_page) {
- /*dprintkl(KERN_DEBUG, "Free tracebuf %p (for %i)\n", */
- /* acb->srb_array[i].debugtrace, i); */
- dc395x_kfree(acb->srb_array[i].debugtrace);
- }
-}
+ /* backpointer to adapter */
+ dcb->acb = acb;
+
+ /* set run_robin to this device if it is currently empty */
+ if (list_empty(&acb->dcb_list))
+ acb->dcb_run_robin = dcb;
+ /* add device to list */
+ list_add_tail(&dcb->list, &acb->dcb_list);
-static
-int alloc_tracebufs(struct AdapterCtlBlk *acb)
-{
- const unsigned mem_needed =
- (DC395x_MAX_SRB_CNT + 1) * DEBUGTRACEBUFSZ;
- int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE;
- const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
- int srb_idx = 0;
- unsigned i = 0;
- unsigned char *ptr;
- /*dprintkl(KERN_DEBUG, "Alloc %i pages for tracebufs\n", pages); */
- while (pages--) {
- ptr = dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!ptr) {
- free_tracebufs(acb, srb_idx);
- return 1;
- }
- /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for tracebuf %i\n", */
- /* PAGE_SIZE, ptr, srb_idx); */
- i = 0;
- while (i < bufs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
- acb->srb_array[srb_idx++].debugtrace =
- ptr + (i++ * DEBUGTRACEBUFSZ);
- }
- if (i < bufs_per_page) {
- acb->srb.debugtrace = ptr + (i * DEBUGTRACEBUFSZ);
- acb->srb.debugtrace[0] = 0;
- } else
- dprintkl(KERN_DEBUG, "No space for tmsrb tracebuf reserved?!\n");
- return 0;
+ /* update device maps */
+ acb->dcb_map[dcb->target_id] |= (1 << dcb->target_lun);
+ acb->children[dcb->target_id][dcb->target_lun] = dcb;
}
-#endif
-/* Free SG tables */
-static void free_sg_tables(struct AdapterCtlBlk *acb, int srb_idx)
+/**
+ * adapter_remove_device - Removes the device instance from the adaptor
+ * instance. The device instance is not check in any way or freed by this.
+ * The caller is expected to take care of that. This will simply remove the
+ * device from the adapters data strcutures.
+ *
+ * @acb: The adapter device to be updated
+ * @dcb: A device that has previously been added to the adapter.
+ **/
+static
+void adapter_remove_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{
- int i;
- const unsigned srbs_per_page =
- PAGE_SIZE / (DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry));
- for (i = 0; i < srb_idx; i += srbs_per_page) {
- /*dprintkl(KERN_DEBUG, "Free SG segs %p (for %i)\n", */
- /* acb->srb_array[i].segment_x, i); */
- dc395x_kfree(acb->srb_array[i].segment_x);
- }
-}
+ struct DeviceCtlBlk *i;
+ struct DeviceCtlBlk *tmp;
+ dprintkdbg(DBG_0, "adapter_remove_device: Remove device (ID %i, LUN %i): %p\n",
+ dcb->target_id, dcb->target_lun, dcb);
+ /* fix up any pointers to this device that we have in the adapter */
+ if (acb->active_dcb == dcb)
+ acb->active_dcb = NULL;
+ if (acb->dcb_run_robin == dcb)
+ acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb);
-/*
- * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
- * should never cross a page boundary */
-static int alloc_sg_tables(struct AdapterCtlBlk *acb)
-{
- const unsigned mem_needed =
- (DC395x_MAX_SRB_CNT +
- 1) * DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry);
- int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE;
- const unsigned srbs_per_page =
- PAGE_SIZE / (DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry));
- int srb_idx = 0;
- unsigned i = 0;
- struct SGentry *ptr;
- /*dprintkl(KERN_DEBUG, "Alloc %i pages for SG tables\n", pages); */
- while (pages--) {
- ptr = (struct SGentry *) dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!ptr) {
- free_sg_tables(acb, srb_idx);
- return 1;
+ /* unlink from list */
+ list_for_each_entry_safe(i, tmp, &acb->dcb_list, list)
+ if (dcb == i) {
+ list_del(&i->list);
+ break;
}
- /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for SG segments %i\n", */
- /* PAGE_SIZE, ptr, srb_idx); */
- i = 0;
- while (i < srbs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
- acb->srb_array[srb_idx++].segment_x =
- ptr + (i++ * DC395x_MAX_SG_LISTENTRY);
- }
- if (i < srbs_per_page)
- acb->srb.segment_x =
- ptr + (i * DC395x_MAX_SG_LISTENTRY);
- else
- dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
- return 0;
+
+ /* clear map and children */
+ acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun);
+ acb->children[dcb->target_id][dcb->target_lun] = NULL;
+ dcb->acb = NULL;
}
-/*
- ********************************************************************
- * scsiio
- * init_acb
- ********************************************************************
+/**
+ * adapter_remove_and_free_device - Removes a single device from the adapter
+ * and then frees the device information.
+ *
+ * @acb: The adapter device to be updated
+ * @dcb: A device that has previously been added to the adapter.
*/
-static void __init link_srb(struct AdapterCtlBlk *acb)
+static
+void adapter_remove_and_free_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{
- int i;
-
- for (i = 0; i < acb->srb_count - 1; i++)
- srb_free_insert(acb, &acb->srb_array[i]);
+ if (list_size(&dcb->srb_going_list) > 1) {
+ dprintkdbg(DBG_DCB, "adapter_remove_and_free_device: "
+ "Won't remove because of %i active requests\n",
+ list_size(&dcb->srb_going_list));
+ return;
+ }
+ adapter_remove_device(acb, dcb);
+ dc395x_kfree(dcb);
}
-/*
- ***********************************************************************
- * host_init
+/**
+ * adapter_remove_and_free_all_devices - Removes and frees all of the
+ * devices associated with the specified adapter.
*
- * Function : static void init_acb
- * Purpose : initialize the internal structures for a given SCSI host
- * Inputs : host - pointer to this host adapter's structure
- ***********************************************************************
- */
+ * @acb: The adapter from which all devices should be removed.
+ **/
static
-int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
+void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb)
{
- struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
- struct NvRamType *eeprom = &acb->eeprom;
- u16 i;
+ struct DeviceCtlBlk *dcb;
+ struct DeviceCtlBlk *tmp;
+ dprintkdbg(DBG_DCB, "adapter_remove_and_free_all_devices: Free all devices (%i devices)\n",
+ list_size(&acb->dcb_list));
- host->max_cmd_len = 24;
- host->can_queue = DC395x_MAX_CMD_QUEUE;
- host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN;
- host->this_id = (int) eeprom->scsi_id;
- host->io_port = io_port;
- host->n_io_port = 0x80;
- host->dma_channel = -1;
- host->unique_id = io_port;
- host->irq = irq;
- host->last_reset = jiffies;
+ list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list)
+ adapter_remove_and_free_device(acb, dcb);
+}
- host->max_id = 16;
- if (host->max_id - 1 == eeprom->scsi_id)
- host->max_id--;
-#ifdef CONFIG_SCSI_MULTI_LUN
- if (eeprom->channel_cfg & NAC_SCANLUN)
- host->max_lun = 8;
- else
- host->max_lun = 1;
-#else
- host->max_lun = 1;
-#endif
- /*
- ********************************
- */
- acb->scsi_host = host;
- acb->IOPortBase = (u16) io_port;
- acb->dcb_run_robin = NULL;
- acb->active_dcb = NULL;
- acb->srb_count = DC395x_MAX_SRB_CNT;
- acb->scsi_host->this_id = eeprom->scsi_id;
- acb->hostid_bit = (1 << acb->scsi_host->this_id);
- /*acb->scsi_host->this_lun = 0; */
- acb->irq_level = irq;
- acb->tag_max_num = 1 << eeprom->max_tag;
- if (acb->tag_max_num > 30)
- acb->tag_max_num = 30;
- acb->acb_flag = 0; /* RESET_DETECT, RESET_DONE, RESET_DEV */
- acb->scan_devices = 1;
- acb->msg_len = 0;
- acb->gmode2 = eeprom->channel_cfg;
- if (eeprom->channel_cfg & NAC_SCANLUN)
- acb->lun_chk = 1;
- /*
- * link all device's SRB Q of this adapter
- */
- if (alloc_sg_tables(acb)) {
- dprintkl(KERN_DEBUG, "SG table allocation failed!\n");
- return 1;
- }
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
- if (alloc_tracebufs(acb)) {
- dprintkl(KERN_DEBUG, "SG trace buffer allocation failed!\n");
- free_sg_tables(acb, DC395x_MAX_SRB_CNT);
- return 1;
- }
-#endif
- INIT_LIST_HEAD(&acb->dcb_list);
- INIT_LIST_HEAD(&acb->srb_free_list);
- link_srb(acb);
+/**
+ * dc395x_slave_alloc - Called by the scsi mid layer to tell us about a new
+ * scsi device that we need to deal with. We allocate a new device and then
+ * insert that device into the adapters device list.
+ *
+ * @scsi_device: The new scsi device that we need to handle.
+ **/
+static
+int dc395x_slave_alloc(struct scsi_device *scsi_device)
+{
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata;
+ struct DeviceCtlBlk *dcb;
- /*
- * temp SRB for Q tag used or abort command used
- */
- acb->tmp_srb = &acb->srb;
- init_timer(&acb->waiting_timer);
+ dcb = device_alloc(acb, scsi_device->id, scsi_device->lun);
+ if (!dcb)
+ return -ENOMEM;
+ adapter_add_device(acb, dcb);
- for (i = 0; i < DC395x_MAX_SCSI_ID; i++)
- acb->dcb_map[i] = 0;
- dprintkdbg(DBG_0, "acb = %p, pdcb_map = %p, psrb_array = %p\n", acb,
- acb->dcb_map, acb->srb_array);
- dprintkdbg(DBG_0, "ACB size= %04x, DCB size= %04x, SRB size= %04x\n",
- sizeof(struct AdapterCtlBlk), sizeof(struct DeviceCtlBlk),
- sizeof(struct ScsiReqBlk));
return 0;
}
-/*===========================================================================
- Init
- ===========================================================================*/
/**
- * init_adapter - Initialize the SCSI chip control registers
- *
- * @host: This hosts adapter strcuture
- * @io_port: The base I/O port
- * @irq: IRQ
+ * dc395x_slave_destroy - Called by the scsi mid layer to tell us about a
+ * device that is going away.
*
- * Returns 0 if the initialization succeeds, any other value on failure.
+ * @scsi_device: The new scsi device that we need to handle.
**/
static
-int __init init_adapter(struct Scsi_Host *host, u32 io_port, u8 irq)
+void dc395x_slave_destroy(struct scsi_device *scsi_device)
{
- struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
- struct NvRamType *eeprom = &acb->eeprom;
-
- if (!request_region(io_port, host->n_io_port, DC395X_NAME)) {
- dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port);
- return -1;
- }
- if (request_irq(irq, dc395x_interrupt, SA_SHIRQ, DC395X_NAME, acb)) {
- /* release the region we just claimed */
- release_region(io_port, host->n_io_port);
- dprintkl(KERN_INFO, "Failed to register IRQ!\n");
- return -1;
- }
-
- acb->IOPortBase = io_port;
-
- /* selection timeout = 250 ms */
- acb->sel_timeout = DC395x_SEL_TIMEOUT;
-
- /* Mask all the interrupt */
- DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0x00);
- DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0x00);
-
- /* Reset SCSI module */
- DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE);
-
- /* Reset PCI/DMA module */
- DC395x_write8(acb, TRM_S1040_DMA_CONTROL, DMARESETMODULE);
- udelay(20);
-
- /* program configuration 0 */
- acb->config = HCC_AUTOTERM | HCC_PARITY;
- if (DC395x_read8(acb, TRM_S1040_GEN_STATUS) & WIDESCSI)
- acb->config |= HCC_WIDE_CARD;
-
- if (eeprom->channel_cfg & NAC_POWERON_SCSI_RESET)
- acb->config |= HCC_SCSI_RESET;
-
- if (acb->config & HCC_SCSI_RESET) {
- dprintkl(KERN_INFO, "Performing initial SCSI bus reset\n");
- DC395x_write8(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI);
-
- /*while (!( DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET )); */
- /*spin_unlock_irq (&io_request_lock); */
- udelay(500);
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata;
+ struct DeviceCtlBlk *dcb = find_dcb(acb, scsi_device->id, scsi_device->lun);
+ if (dcb)
+ adapter_remove_and_free_device(acb, dcb);
+}
- acb->scsi_host->last_reset =
- jiffies + HZ / 2 +
- HZ * acb->eeprom.delay_time;
- /*spin_lock_irq (&io_request_lock); */
- }
- set_basic_config(acb);
- return 0;
-}
/**
@@ -5363,20 +5145,161 @@ void __init check_eeprom(struct NvRamType *eeprom, u16 io_port)
}
+
+
/**
- * print_config - print adapter connection and termination
+ * print_eeprom_settings - output the eeprom settings
+ * to the kernel log so people can see what they were.
+ *
+ * @eeprom: The eeprom data strucutre to show details for.
+ **/
+static
+void __init print_eeprom_settings(struct NvRamType *eeprom)
+{
+ dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
+ eeprom->scsi_id,
+ eeprom->target[0].period,
+ clock_speed[eeprom->target[0].period] / 10,
+ clock_speed[eeprom->target[0].period] % 10,
+ eeprom->target[0].cfg0);
+ dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n",
+ eeprom->channel_cfg,
+ eeprom->max_tag,
+ 1 << eeprom->max_tag,
+ eeprom->delay_time);
+}
+
+
+
+#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
+/*
+ * Memory for trace buffers
+ */
+static
+void free_tracebufs(struct AdapterCtlBlk *acb)
+{
+ int i;
+ const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
+
+ for (i = 0; i < srb_idx; i += bufs_per_page)
+ if (acb->srb_array[i].debugtrace)
+ dc395x_kfree(acb->srb_array[i].debugtrace);
+}
+
+
+static
+int alloc_tracebufs(struct AdapterCtlBlk *acb)
+{
+ const unsigned mem_needed =
+ (DC395x_MAX_SRB_CNT + 1) * DEBUGTRACEBUFSZ;
+ int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE;
+ const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
+ int srb_idx = 0;
+ unsigned i = 0;
+ unsigned char *ptr;
+
+ for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
+ acb->srb_array[i].debugtrace = NULL;
+
+ while (pages--) {
+ ptr = dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!ptr) {
+ free_tracebufs(acb);
+ return 1;
+ }
+ /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for tracebuf %i\n", */
+ /* PAGE_SIZE, ptr, srb_idx); */
+ i = 0;
+ while (i < bufs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
+ acb->srb_array[srb_idx++].debugtrace =
+ ptr + (i++ * DEBUGTRACEBUFSZ);
+ }
+ if (i < bufs_per_page) {
+ acb->srb.debugtrace = ptr + (i * DEBUGTRACEBUFSZ);
+ acb->srb.debugtrace[0] = 0;
+ } else
+ dprintkl(KERN_DEBUG, "No space for tmsrb tracebuf reserved?!\n");
+ return 0;
+}
+#else
+static void free_tracebufs(struct AdapterCtlBlk *acb) {}
+static int alloc_tracebufs(struct AdapterCtlBlk *acb) { return 0; }
+#endif
+
+/* Free SG tables */
+static
+void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
+{
+ int i;
+ const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY
+ *sizeof(struct SGentry));
+
+ for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
+ if (acb->srb_array[i].segment_x)
+ dc395x_kfree(acb->srb_array[i].segment_x);
+}
+
+
+/*
+ * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
+ * should never cross a page boundary */
+static
+int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
+{
+ const unsigned mem_needed = (DC395x_MAX_SRB_CNT+1)
+ *DC395x_MAX_SG_LISTENTRY
+ *sizeof(struct SGentry);
+ int pages = (mem_needed+(PAGE_SIZE-1))/PAGE_SIZE;
+ const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY
+ *sizeof(struct SGentry));
+ int srb_idx = 0;
+ unsigned i = 0;
+ struct SGentry *ptr;
+
+ for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
+ acb->srb_array[i].segment_x = NULL;
+
+ dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
+ while (pages--) {
+ ptr = (struct SGentry *)dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!ptr) {
+ adapter_sg_tables_free(acb);
+ return 1;
+ }
+ dprintkdbg(DBG_1, "Allocate %li bytes at %p for SG segments %i\n",
+ PAGE_SIZE, ptr, srb_idx);
+ i = 0;
+ while (i < srbs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
+ acb->srb_array[srb_idx++].segment_x =
+ ptr + (i++ * DC395x_MAX_SG_LISTENTRY);
+ }
+ if (i < srbs_per_page)
+ acb->srb.segment_x =
+ ptr + (i * DC395x_MAX_SG_LISTENTRY);
+ else
+ dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
+ return 0;
+}
+
+
+
+/**
+ * adapter_print_config - print adapter connection and termination
* config
*
- * @acb: adapter control block
+ * The io port in the adapter needs to have been set before calling
+ * this function.
+ *
+ * @acb: The adapter to print the information for.
**/
static
-void __init print_config(struct AdapterCtlBlk *acb)
+void __init adapter_print_config(struct AdapterCtlBlk *acb)
{
u8 bval;
bval = DC395x_read8(acb, TRM_S1040_GEN_STATUS);
- dprintkl(KERN_INFO, "%c: Connectors: ",
- ((bval & WIDESCSI) ? 'W' : ' '));
+ dprintkl(KERN_INFO, "%s Connectors: ",
+ ((bval & WIDESCSI) ? "(Wide)" : ""));
if (!(bval & CON5068))
printk("ext%s ", !(bval & EXT68HIGH) ? "68" : "50");
if (!(bval & CON68))
@@ -5403,77 +5326,290 @@ void __init print_config(struct AdapterCtlBlk *acb)
/**
- * print_eeprom_settings - output the eeprom settings
- * to the kernel log so people can see what they were.
+ * adapter_init_params - Initialize the various parameters in the
+ * adapter structure. Note that the pointer to the scsi_host is set
+ * early (when this instance is created) and the io_port and irq
+ * values are set later after they have been reserved. This just gets
+ * everything set to a good starting position.
*
- * @eeprom: The eeprom data strucutre to show details for.
+ * The eeprom structure in the adapter needs to have been set before
+ * calling this function.
+ *
+ * @acb: The adapter to initialize.
**/
static
-void __init print_eeprom_settings(struct NvRamType *eeprom)
+void __init adapter_init_params(struct AdapterCtlBlk *acb)
{
- dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
- eeprom->scsi_id,
- eeprom->target[0].period,
- clock_speed[eeprom->target[0].period] / 10,
- clock_speed[eeprom->target[0].period] % 10,
- eeprom->target[0].cfg0);
- dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n",
- eeprom->channel_cfg,
- eeprom->max_tag,
- 1 << eeprom->max_tag,
- eeprom->delay_time);
+ struct NvRamType *eeprom = &acb->eeprom;
+ int i;
+
+ /* NOTE: acb->scsi_host is set at scsi_host/acb creation time */
+ /* NOTE: acb->io_port_base is set at port registration time */
+ /* NOTE: acb->io_port_len is set at port registration time */
+
+ INIT_LIST_HEAD(&acb->dcb_list);
+ acb->dcb_run_robin = NULL;
+ acb->active_dcb = NULL;
+
+ INIT_LIST_HEAD(&acb->srb_free_list);
+ /* temp SRB for Q tag used or abort command used */
+ acb->tmp_srb = &acb->srb;
+ init_timer(&acb->waiting_timer);
+ init_timer(&acb->selto_timer);
+
+ acb->srb_count = DC395x_MAX_SRB_CNT;
+
+ acb->sel_timeout = DC395x_SEL_TIMEOUT; /* timeout=250ms */
+ /* NOTE: acb->irq_level is set at IRQ registration time */
+
+ acb->tag_max_num = 1 << eeprom->max_tag;
+ if (acb->tag_max_num > 30)
+ acb->tag_max_num = 30;
+
+ acb->acb_flag = 0; /* RESET_DETECT, RESET_DONE, RESET_DEV */
+ acb->gmode2 = eeprom->channel_cfg;
+ acb->config = 0; /* NOTE: actually set in adapter_init_chip */
+
+ if (eeprom->channel_cfg & NAC_SCANLUN)
+ acb->lun_chk = 1;
+ acb->scan_devices = 1;
+
+ acb->scsi_host->this_id = eeprom->scsi_id;
+ acb->hostid_bit = (1 << acb->scsi_host->this_id);
+
+ for (i = 0; i < DC395x_MAX_SCSI_ID; i++)
+ acb->dcb_map[i] = 0;
+
+ acb->msg_len = 0;
+
+ /* link static array of srbs into the srb free list */
+ for (i = 0; i < acb->srb_count - 1; i++)
+ srb_free_insert(acb, &acb->srb_array[i]);
}
-/*
- *********************************************************************
- * DC395x_detect
+/**
+ * adapter_init_host - Initialize the scsi host instance based on
+ * values that we have already stored in the adapter instance. There's
+ * some mention that a lot of these are deprecated, so we won't use
+ * them (we'll use the ones in the adapter instance) but we'll fill
+ * them in in case something else needs them.
*
- * Function : static int host_init (struct Scsi_Host *host)
- * Purpose : initialize the internal structures for a given SCSI host
- * Inputs : host - pointer to this host adapter's structure/
- * Preconditions : when this function is called, the chip_type
- * field of the acb structure MUST have been set.
- *********************************************************************
- */
+ * The eeprom structure, irq and io ports in the adapter need to have
+ * been set before calling this function.
+ *
+ * @host: The scsi host instance to fill in the values for.
+ **/
static
-struct Scsi_Host *__init host_init(Scsi_Host_Template * host_template,
- u32 io_port, u8 irq)
+void __init adapter_init_scsi_host(struct Scsi_Host *host)
{
- struct Scsi_Host *host;
- struct AdapterCtlBlk *acb;
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
+ struct NvRamType *eeprom = &acb->eeprom;
+
+ host->max_cmd_len = 24;
+ host->can_queue = DC395x_MAX_CMD_QUEUE;
+ host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN;
+ host->this_id = (int)eeprom->scsi_id;
+ host->io_port = acb->io_port_base;
+ host->n_io_port = acb->io_port_len;
+ host->dma_channel = -1;
+ host->unique_id = acb->io_port_base;
+ host->irq = acb->irq_level;
+ host->last_reset = jiffies;
- host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk));
- if (!host) {
- dprintkl(KERN_INFO, "scsi_host_alloc failed\n");
+ host->max_id = 16;
+ if (host->max_id - 1 == eeprom->scsi_id)
+ host->max_id--;
+
+#ifdef CONFIG_SCSI_MULTI_LUN
+ if (eeprom->channel_cfg & NAC_SCANLUN)
+ host->max_lun = 8;
+ else
+ host->max_lun = 1;
+#else
+ host->max_lun = 1;
+#endif
+
+}
+
+
+/**
+ * adapter_init_chip - Get the chip into a know state and figure out
+ * some of the settings that apply to this adapter.
+ *
+ * The io port in the adapter needs to have been set before calling
+ * this function. The config will be configured correctly on return.
+ *
+ * @acb: The adapter which we are to init.
+ **/
+void __init adapter_init_chip(struct AdapterCtlBlk *acb)
+{
+ struct NvRamType *eeprom = &acb->eeprom;
+
+ /* Mask all the interrupt */
+ DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0x00);
+ DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0x00);
+
+ /* Reset SCSI module */
+ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE);
+
+ /* Reset PCI/DMA module */
+ DC395x_write8(acb, TRM_S1040_DMA_CONTROL, DMARESETMODULE);
+ udelay(20);
+
+ /* program configuration 0 */
+ acb->config = HCC_AUTOTERM | HCC_PARITY;
+ if (DC395x_read8(acb, TRM_S1040_GEN_STATUS) & WIDESCSI)
+ acb->config |= HCC_WIDE_CARD;
+
+ if (eeprom->channel_cfg & NAC_POWERON_SCSI_RESET)
+ acb->config |= HCC_SCSI_RESET;
+
+ if (acb->config & HCC_SCSI_RESET) {
+ dprintkl(KERN_INFO, "Performing initial SCSI bus reset\n");
+ DC395x_write8(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI);
+
+ /*while (!( DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET )); */
+ /*spin_unlock_irq (&io_request_lock); */
+ udelay(500);
+
+ acb->scsi_host->last_reset =
+ jiffies + HZ / 2 +
+ HZ * acb->eeprom.delay_time;
+
+ /*spin_lock_irq (&io_request_lock); */
+ }
+}
+
+
+/**
+ * init_adapter - Grab the resource for the card, setup the adapter
+ * information, set the card into a known state, create the various
+ * tables etc etc. This basically gets all adapter information all up
+ * to date, intialised and gets the chip in sync with it.
+ *
+ * @host: This hosts adapter structure
+ * @io_port: The base I/O port
+ * @irq: IRQ
+ *
+ * Returns 0 if the initialization succeeds, any other value on
+ * failure.
+ **/
+static
+int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port, u32 io_port_len, u8 irq)
+{
+ if (!request_region(io_port, io_port_len, DC395X_NAME)) {
+ dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port);
goto failed;
}
- acb = (struct AdapterCtlBlk *)host->hostdata;
+ /* store port base to indicate we have registered it */
+ acb->io_port_base = io_port;
+ acb->io_port_len = io_port_len;
+
+ if (request_irq(irq, dc395x_interrupt, SA_SHIRQ, DC395X_NAME, acb)) {
+ /* release the region we just claimed */
+ dprintkl(KERN_INFO, "Failed to register IRQ\n");
+ goto failed;
+ }
+ /* store irq to indicate we have registered it */
+ acb->irq_level = irq;
+ /* get eeprom configuration information and command line settings etc */
check_eeprom(&acb->eeprom, (u16)io_port);
print_eeprom_settings(&acb->eeprom);
- if (init_acb(host, io_port, irq)) {
+ /* setup adapter control block */
+ adapter_init_params(acb);
+
+ /* display card connectors/termination settings */
+ adapter_print_config(acb);
+
+ if (adapter_sg_tables_alloc(acb)) {
+ dprintkl(KERN_DEBUG, "Memory allocation for SG tables failed\n");
goto failed;
}
- print_config(acb);
-
- if (init_adapter(host, io_port, irq)) {
- dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
+ if (alloc_tracebufs(acb)) {
+ dprintkl(KERN_DEBUG, "Memory allocation for trace buffers failed\n");
goto failed;
}
+ adapter_init_scsi_host(acb->scsi_host);
+ adapter_init_chip(acb);
+ set_basic_config(acb);
- return host;
+ dprintkdbg(DBG_0, "adapter_init: acb=%p, pdcb_map=%p "
+ "psrb_array=%p ACB size=%04x, DCB size=%04x "
+ "SRB size=%04x\n",
+ acb, acb->dcb_map, acb->srb_array, sizeof(struct AdapterCtlBlk),
+ sizeof(struct DeviceCtlBlk), sizeof(struct ScsiReqBlk));
+ return 0;
failed:
- if (host)
- scsi_host_put(host);
- return NULL;
+ if (acb->irq_level)
+ free_irq(acb->irq_level, acb);
+ if (acb->io_port_base)
+ release_region(acb->io_port_base, acb->io_port_len);
+ adapter_sg_tables_free(acb);
+ free_tracebufs(acb);
+
+ return 1;
}
-#undef SEARCH
-#undef YESNO
-#undef SCANF
+
+/**
+ * adapter_uninit_chip - cleanly shut down the scsi controller chip,
+ * stopping all operations and disabling interrupt generation on the
+ * card.
+ *
+ * @acb: The adapter which we are to shutdown.
+ **/
+static
+void adapter_uninit_chip(struct AdapterCtlBlk *acb)
+{
+ /* disable interrupts */
+ DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0);
+ DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0);
+
+ /* reset the scsi bus */
+ if (acb->config & HCC_SCSI_RESET)
+ reset_scsi_bus(acb);
+
+ /* clear any pending interupt state */
+ DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
+}
+
+
+
+/**
+ * adapter_uninit - Shut down the chip and release any resources that
+ * we had allocated. Once this returns the adapter should not be used
+ * anymore.
+ *
+ * @acb: The adapter which we are to un-initialize.
+ **/
+static
+void adapter_uninit(struct AdapterCtlBlk *acb)
+{
+ unsigned long flags;
+ DC395x_LOCK_IO(acb->scsi_host, flags);
+
+ /* remove timers */
+ if (timer_pending(&acb->waiting_timer))
+ del_timer(&acb->waiting_timer);
+ if (timer_pending(&acb->selto_timer))
+ del_timer(&acb->selto_timer);
+
+ adapter_uninit_chip(acb);
+ adapter_remove_and_free_all_devices(acb);
+ DC395x_UNLOCK_IO(acb->scsi_host, flags);
+
+ if (acb->irq_level)
+ free_irq(acb->irq_level, acb);
+ if (acb->io_port_base)
+ release_region(acb->io_port_base, acb->io_port_len);
+
+ adapter_sg_tables_free(acb);
+ free_tracebufs(acb);
+}
/*
@@ -5500,6 +5636,7 @@ failed:
#undef SPRINTF
#define SPRINTF(args...) pos += sprintf(pos, args)
+#undef YESNO
#define YESNO(YN) \
if (YN) SPRINTF(" Yes ");\
else SPRINTF(" No ")
@@ -5526,7 +5663,7 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
SPRINTF("SCSI Host Nr %i, ", host->host_no);
SPRINTF("DC395U/UW/F DC315/U %s\n",
(acb->config & HCC_WIDE_CARD) ? "Wide" : "");
- SPRINTF("IOPortBase 0x%04x, ", acb->IOPortBase);
+ SPRINTF("io_port_base 0x%04x, ", acb->io_port_base);
SPRINTF("irq_level 0x%02x, ", acb->irq_level);
SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000);
@@ -5633,84 +5770,6 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
}
-/**
- * chip_shutdown - cleanly shut down the scsi controller chip,
- * stopping all operations and disablig interrupt generation on the
- * card.
- *
- * @acb: The scsi adapter control block of the adapter to shut down.
- **/
-static
-void chip_shutdown(struct AdapterCtlBlk *acb)
-{
- /* disable interrupt */
- DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0);
- DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0);
-
- /* remove timers */
- if (timer_pending(&acb->waiting_timer))
- del_timer(&acb->waiting_timer);
- if (timer_pending(&acb->selto_timer))
- del_timer(&acb->selto_timer);
-
- /* reset the scsi bus */
- if (acb->config & HCC_SCSI_RESET)
- reset_scsi_bus(acb);
-
- /* clear any pending interupt state */
- DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
-
- /* release chip resources */
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
- free_tracebufs(acb, DC395x_MAX_SRB_CNT);
-#endif
- free_sg_tables(acb, DC395x_MAX_SRB_CNT);
-}
-
-
-/**
- * free_dcbs - Free all of the DCBs.
- *
- * @acb: Adapter to remove the DCBs for.
- **/
-static
-void free_dcbs(struct AdapterCtlBlk* acb)
-{
- struct DeviceCtlBlk *dcb;
- struct DeviceCtlBlk *tmp;
-
- dprintkdbg(DBG_DCB, "Free %i DCBs\n", list_size(&acb->dcb_list));
-
- list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) {
- dprintkdbg(DBG_DCB, "Free DCB (ID %i, LUN %i): %p\n",
- dcb->target_id, dcb->target_lun, dcb);
- remove_dev(acb, dcb);
- }
-}
-
-/**
- * host_release - shutdown device and release resources that were
- * allocate for it. Called once for each card as it is shutdown.
- *
- * @host: The adapter instance to shutdown.
- **/
-static
-void host_release(struct Scsi_Host *host)
-{
- struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(host->hostdata);
- unsigned long flags;
-
- dprintkl(KERN_DEBUG, "DC395x release\n");
-
- DC395x_LOCK_IO(acb->scsi_host, flags);
- chip_shutdown(acb);
- free_dcbs(acb);
-
- free_irq(host->irq, acb);
- release_region(host->io_port, host->n_io_port);
-
- DC395x_UNLOCK_IO(acb->scsi_host, flags);
-}
/*
@@ -5737,6 +5796,22 @@ static Scsi_Host_Template dc395x_driver_template = {
/**
+ * banner_display - Display banner on first instance of driver
+ * initialized.
+ **/
+static
+void banner_display(void)
+{
+ static int banner_done = 0;
+ if (!banner_done)
+ {
+ dprintkl(KERN_INFO, "%s %s\n", DC395X_BANNER, DC395X_VERSION);
+ banner_done = 1;
+ }
+}
+
+
+/**
* dc395x_init_one - Initialise a single instance of the adapter.
*
* The PCI layer will call this once for each instance of the adapter
@@ -5753,51 +5828,55 @@ static
int __devinit dc395x_init_one(struct pci_dev *dev,
const struct pci_device_id *id)
{
- unsigned int io_port;
- u8 irq;
struct Scsi_Host *scsi_host;
- static int banner_done = 0;
- int error = 0;
-
- dprintkdbg(DBG_0, "Init one instance of the dc395x\n");
- if (!banner_done)
- {
- dprintkl(KERN_INFO, "%s %s\n", DC395X_BANNER, DC395X_VERSION);
- banner_done = 1;
- }
+ struct AdapterCtlBlk *acb;
+ unsigned int io_port_base;
+ unsigned int io_port_len;
+ u8 irq;
+
+ dprintkdbg(DBG_0, "Init one instance (%s)\n", pci_name(dev));
+ banner_display();
if (pci_enable_device(dev))
{
dprintkl(KERN_INFO, "PCI Enable device failed.\n");
return -ENODEV;
}
-
- dprintkdbg(DBG_0, "Get resources...\n");
- io_port = pci_resource_start(dev, 0) & PCI_BASE_ADDRESS_IO_MASK;
+ io_port_base = pci_resource_start(dev, 0) & PCI_BASE_ADDRESS_IO_MASK;
+ io_port_len = pci_resource_len(dev, 0);
irq = dev->irq;
- dprintkdbg(DBG_0, "IO_PORT=%04x,IRQ=%x\n", (unsigned int) io_port, irq);
+ dprintkdbg(DBG_0, "IO_PORT=%04x, IRQ=%x\n", io_port_base, dev->irq);
- scsi_host = host_init(&dc395x_driver_template, io_port, irq);
- if (!scsi_host)
- {
- dprintkdbg(DBG_0, "host_init failed\n");
+ /* allocate scsi host information (includes out adapter) */
+ scsi_host = scsi_host_alloc(&dc395x_driver_template,
+ sizeof(struct AdapterCtlBlk));
+ if (!scsi_host) {
+ dprintkl(KERN_INFO, "scsi_host_alloc failed\n");
return -ENOMEM;
}
- ((struct AdapterCtlBlk *)(scsi_host->hostdata))->dev = dev;
+ acb = (struct AdapterCtlBlk*)scsi_host->hostdata;
+ acb->scsi_host = scsi_host;
+
+ /* initialise the adapter and everything we need */
+ if (adapter_init(acb, io_port_base, io_port_len, irq)) {
+ dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
+ scsi_host_put(scsi_host);
+ return -ENODEV;
+ }
+
pci_set_master(dev);
- pci_set_drvdata(dev, scsi_host);
/* get the scsi mid level to scan for new devices on the bus */
- error = scsi_add_host(scsi_host, &dev->dev);
- if (error) {
+ if (scsi_add_host(scsi_host, &dev->dev)) {
dprintkl(KERN_ERR, "scsi_add_host failed\n");
- error = -ENODEV;
- host_release(scsi_host);
+ adapter_uninit(acb);
scsi_host_put(scsi_host);
- } else
- scsi_scan_host(scsi_host);
+ return -ENODEV;
+ }
+ pci_set_drvdata(dev, scsi_host);
+ scsi_scan_host(scsi_host);
- return error;
+ return 0;
}
@@ -5809,16 +5888,14 @@ int __devinit dc395x_init_one(struct pci_dev *dev,
**/
static void __devexit dc395x_remove_one(struct pci_dev *dev)
{
- struct Scsi_Host *host = pci_get_drvdata(dev);
+ struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(scsi_host->hostdata);
dprintkdbg(DBG_0, "Removing instance\n");
- if (!host) {
- dprintkl(KERN_ERR, "no host allocated\n");
- return;
- }
- scsi_remove_host(host);
- host_release(host);
- scsi_host_put(host);
+
+ scsi_remove_host(scsi_host);
+ adapter_uninit(acb);
+ scsi_host_put(scsi_host);
pci_set_drvdata(dev, NULL);
}
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 19b77daaf4ee..6ffd2df205b6 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -4990,7 +4990,7 @@ static int ioc_resetdrv(unsigned long arg, char *cmnd)
cmd.u.cache.DeviceNo = res.number;
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
@@ -5091,7 +5091,7 @@ static int ioc_general(unsigned long arg, char *cmnd)
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
@@ -5164,7 +5164,7 @@ static int ioc_hdrlist(unsigned long arg, char *cmnd)
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
@@ -5253,7 +5253,7 @@ static int ioc_rescan(unsigned long arg, char *cmnd)
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
@@ -5631,7 +5631,7 @@ static void gdth_flush(int hanum)
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp)
return;
srp->sr_cmd_len = 12;
@@ -5727,7 +5727,7 @@ void gdth_halt(void)
TRACE2(("gdth_halt(): reset controller %d\n", hanum));
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- srp = scsi_allocate_request(sdev);
+ srp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!srp) {
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier(&gdth_notifier);
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index 9c4485b2fd1c..ef67f26855fd 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -44,7 +44,7 @@ static int gdth_set_info(char *buffer,int length,int hanum,int busnum)
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- scp = scsi_allocate_request(sdev);
+ scp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!scp)
return -ENOMEM;
scp->sr_cmd_len = 12;
@@ -797,7 +797,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
- scp = scsi_allocate_request(sdev);
+ scp = scsi_allocate_request(sdev, GFP_KERNEL);
if (!scp)
return -ENOMEM;
scp->sr_cmd_len = 12;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index b270dac4e2d2..b631105fbdb2 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -627,7 +627,6 @@ static ide_driver_t idescsi_driver = {
.version = IDESCSI_VERSION,
.media = ide_scsi,
.busy = 0,
- .supports_dma = 1,
.supports_dsc_overlap = 0,
.attach = idescsi_attach,
.cleanup = idescsi_cleanup,
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 3c8377c3aa48..bcee9b28fbfe 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -86,6 +86,7 @@ int imm_release(struct Scsi_Host *host)
int host_no = host->unique_id;
printk("Releasing imm%i\n", host_no);
+ scsi_unregister(host);
parport_unregister_device(imm_hosts[host_no].dev);
return 0;
}
diff --git a/drivers/scsi/imm.h b/drivers/scsi/imm.h
index c00f1539a43f..4b5b28f965fd 100644
--- a/drivers/scsi/imm.h
+++ b/drivers/scsi/imm.h
@@ -100,7 +100,6 @@ static char *IMM_MODE_STRING[] =
[IMM_NIBBLE] = "SPP",
[IMM_PS2] = "PS/2",
[IMM_EPP_8] = "EPP 8 bit",
- [IMM_EPP_16] = "EPP 16 bit",
#ifdef CONFIG_SCSI_IZIP_EPP16
[IMM_EPP_16] = "EPP 16 bit",
#else
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 46b0069406e9..7213e6263642 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -199,7 +199,7 @@ MODULE_PARM(ips, "s");
#define IPS_VERSION_LOW ".90-BETA"
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
-#error "This driver has only been tested on the x86/ia64/x86_64 platforms"
+#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
@@ -284,9 +284,9 @@ IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
/* This table describes all ServeRAID Adapters */
static struct pci_device_id ips_pci_table[] = {
{ 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0, }
+ { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0, }
};
MODULE_DEVICE_TABLE( pci, ips_pci_table );
@@ -300,7 +300,7 @@ struct pci_driver ips_pci_driver = {
.name = ips_hot_plug_name,
.id_table = ips_pci_table,
.probe = ips_insert_device,
- .remove = __devexit_p(ips_remove_device),
+ .remove = __devexit_p(ips_remove_device),
};
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index f0e8d85e6500..4fa1a9955ddf 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -4357,19 +4357,6 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
}
cp->cmd = cmd;
- /*---------------------------------------------------
- **
- ** Enable tagged queue if asked by scsi ioctl
- **
- **----------------------------------------------------
- */
-#if 0 /* This stuff was only useful for linux-1.2.13 */
- if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) {
- lp->numtags = tp->usrtags;
- ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
- }
-#endif
-
/*----------------------------------------------------
**
** Build the identify / tag / sdtr message
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 48afbdd2faa8..c6bfb85db04b 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -316,7 +316,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
static int repeat = 0;
#endif
if (SRpnt == NULL) {
- if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
+ if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) {
printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
if (signal_pending(current))
(STp->buffer)->syscall_result = (-EINTR);
diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig
index 4cadd40bca98..4eda8c41cff5 100644
--- a/drivers/scsi/pcmcia/Kconfig
+++ b/drivers/scsi/pcmcia/Kconfig
@@ -3,7 +3,7 @@
#
menu "PCMCIA SCSI adapter support"
- depends on SCSI!=n && PCMCIA!=n
+ depends on SCSI!=n && PCMCIA!=n && MODULES
config PCMCIA_AHA152X
tristate "Adaptec AHA152X PCMCIA support"
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index bd05b2a7268f..5de0a6329d8a 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -331,11 +331,17 @@
*/
#define QL1280_LUN_SUPPORT 0
#define WATCHDOGTIMER 0
-#define MEMORY_MAPPED_IO 1
+
#define DEBUG_QLA1280_INTR 0
#define DEBUG_PRINT_NVRAM 0
#define DEBUG_QLA1280 0
+#ifdef CONFIG_SCSI_QLOGIC_1280_PIO
+#define MEMORY_MAPPED_IO 0
+#else
+#define MEMORY_MAPPED_IO 1
+#endif
+
#define UNIQUE_FW_NAME
#include "qla1280.h"
#include "ql12160_fw.h" /* ISP RISC codes */
@@ -3649,7 +3655,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
/* Enable simple tag queuing if device supports it. */
- if (cmd->device->tagged_queue)
+ if (cmd->device->simple_tags)
pkt->control_flags |= cpu_to_le16(BIT_3);
/* Load SCSI command packet. */
@@ -3949,7 +3955,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
/* Enable simple tag queuing if device supports it. */
- if (cmd->device->tagged_queue)
+ if (cmd->device->simple_tags)
pkt->control_flags |= cpu_to_le16(BIT_3);
/* Load SCSI command packet. */
@@ -4909,7 +4915,7 @@ qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
} else
printk(" Async");
- if (device->tagged_queue)
+ if (device->simple_tags)
printk(", Tagged queuing: depth %d", device->queue_depth);
printk("\n");
}
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index d5894886fcea..cda15b271b21 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -113,26 +113,21 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
*
* Purpose: Allocate a request descriptor.
*
- * Arguments: device - device for which we want a request
+ * Arguments: device - device for which we want a request
+ * gfp_mask - allocation flags passed to kmalloc
*
* Lock status: No locks assumed to be held. This function is SMP-safe.
*
* Returns: Pointer to request block.
- *
- * Notes: With the new queueing code, it becomes important
- * to track the difference between a command and a
- * request. A request is a pending item in the queue that
- * has not yet reached the top of the queue.
- *
- * XXX(hch): Need to add a gfp_mask argument.
*/
-struct scsi_request *scsi_allocate_request(struct scsi_device *sdev)
+struct scsi_request *scsi_allocate_request(struct scsi_device *sdev,
+ int gfp_mask)
{
const int offset = ALIGN(sizeof(struct scsi_request), 4);
const int size = offset + sizeof(struct request);
struct scsi_request *sreq;
- sreq = kmalloc(size, GFP_ATOMIC);
+ sreq = kmalloc(size, gfp_mask);
if (likely(sreq != NULL)) {
memset(sreq, 0, size);
sreq->sr_request = (struct request *)(((char *)sreq) + offset);
@@ -1006,9 +1001,12 @@ static int __init init_scsi(void)
error = scsi_init_hosts();
if (error)
goto cleanup_devlist;
- error = scsi_sysfs_register();
+ error = scsi_init_sysctl();
if (error)
goto cleanup_hosts;
+ error = scsi_sysfs_register();
+ if (error)
+ goto cleanup_sysctl;
for (i = 0; i < NR_CPUS; i++)
INIT_LIST_HEAD(&done_q[i]);
@@ -1018,6 +1016,8 @@ static int __init init_scsi(void)
printk(KERN_NOTICE "SCSI subsystem initialized\n");
return 0;
+cleanup_sysctl:
+ scsi_exit_sysctl();
cleanup_hosts:
scsi_exit_hosts();
cleanup_devlist:
@@ -1034,6 +1034,7 @@ cleanup_queue:
static void __exit exit_scsi(void)
{
scsi_sysfs_unregister();
+ scsi_exit_sysctl();
scsi_exit_hosts();
scsi_exit_devinfo();
devfs_remove("scsi");
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 8424c445c6b7..4b5a903704b4 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -381,6 +381,7 @@ int scsi_get_device_flags(unsigned char *vendor, unsigned char *model)
return scsi_default_dev_flags;
}
+#ifdef CONFIG_SCSI_PROC_FS
/*
* proc_scsi_dev_info_read: dump the scsi_dev_info_list via
* /proc/scsi/device_info
@@ -451,6 +452,7 @@ out:
free_page((unsigned long)buffer);
return err;
}
+#endif /* CONFIG_SCSI_PROC_FS */
module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0);
MODULE_PARM_DESC(dev_flags,
@@ -471,7 +473,9 @@ void scsi_exit_devinfo(void)
struct list_head *lh, *lh_next;
struct scsi_dev_info_list *devinfo;
+#ifdef CONFIG_SCSI_PROC_FS
remove_proc_entry("scsi/device_info", 0);
+#endif
list_for_each_safe(lh, lh_next, &scsi_dev_info_list) {
devinfo = list_entry(lh, struct scsi_dev_info_list,
@@ -490,7 +494,9 @@ void scsi_exit_devinfo(void)
**/
int scsi_init_devinfo(void)
{
+#ifdef CONFIG_SCSI_PROC_FS
struct proc_dir_entry *p;
+#endif
int error, i;
error = scsi_dev_info_list_add_str(scsi_dev_flags);
@@ -507,6 +513,7 @@ int scsi_init_devinfo(void)
goto out;
}
+#ifdef CONFIG_SCSI_PROC_FS
p = create_proc_entry("scsi/device_info", 0, NULL);
if (!p) {
error = -ENOMEM;
@@ -516,6 +523,7 @@ int scsi_init_devinfo(void)
p->owner = THIS_MODULE;
p->get_info = proc_scsi_devinfo_read;
p->write_proc = proc_scsi_devinfo_write;
+#endif /* CONFIG_SCSI_PROC_FS */
out:
if (error)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 6e4906ab2241..fce6a580363c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1339,7 +1339,7 @@ static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
**/
static void scsi_eh_lock_door(struct scsi_device *sdev)
{
- struct scsi_request *sreq = scsi_allocate_request(sdev);
+ struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
if (unlikely(!sreq)) {
printk(KERN_ERR "%s: request allocate failed,"
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 3dfdcf1f5bc8..53d4b5dd5344 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -98,7 +98,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
- sreq = scsi_allocate_request(sdev);
+ sreq = scsi_allocate_request(sdev, GFP_KERNEL);
if (!sreq) {
printk("SCSI internal ioctl failed, no memory\n");
return -ENOMEM;
@@ -321,7 +321,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
break;
}
- sreq = scsi_allocate_request(sdev);
+ sreq = scsi_allocate_request(sdev, GFP_KERNEL);
if (!sreq) {
result = -EINTR;
goto error;
@@ -408,30 +408,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
return 0;
case SCSI_IOCTL_GET_BUS_NUMBER:
return put_user(sdev->host->host_no, (int *)arg);
- /*
- * The next two ioctls either need to go or need to be changed to
- * pass tagged queueing changes through the low level drivers.
- * Simply enabling or disabling tagged queueing without the knowledge
- * of the low level driver is a *BAD* thing.
- *
- * Oct. 10, 2002 - Doug Ledford <dledford@redhat.com>
- */
- case SCSI_IOCTL_TAGGED_ENABLE:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if (!sdev->tagged_supported)
- return -EINVAL;
- sdev->tagged_queue = 1;
- sdev->current_tag = 1;
- return 0;
- case SCSI_IOCTL_TAGGED_DISABLE:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if (!sdev->tagged_supported)
- return -EINVAL;
- sdev->tagged_queue = 0;
- sdev->current_tag = 0;
- return 0;
case SCSI_IOCTL_PROBE_HOST:
return ioctl_probe(sdev->host, arg);
case SCSI_IOCTL_SEND_COMMAND:
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 415be0cf47b0..e9e374cbdb4f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1454,7 +1454,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout, int retries,
struct scsi_mode_data *data)
{
- struct scsi_request *sreq = scsi_allocate_request(sdev);
+ struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
int ret;
if (!sreq)
diff --git a/drivers/scsi/scsi_logging.h b/drivers/scsi/scsi_logging.h
index a282c84c8ef5..b0a31a11ffcf 100644
--- a/drivers/scsi/scsi_logging.h
+++ b/drivers/scsi/scsi_logging.h
@@ -37,39 +37,23 @@
#define SCSI_LOG_HLCOMPLETE_BITS 3
#define SCSI_LOG_IOCTL_BITS 3
+extern unsigned int scsi_logging_level;
#ifdef CONFIG_SCSI_LOGGING
-extern unsigned int scsi_logging_level;
#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) \
{ \
unsigned int mask = (1 << (BITS)) - 1; \
if (((scsi_logging_level >> (SHIFT)) & mask) > (LEVEL)) \
(CMD); \
}
-
-#define SCSI_SET_LOGGING(SHIFT, BITS, LEVEL) \
-{ \
- unsigned int mask = ((1 << (BITS)) - 1) << SHIFT; \
- scsi_logging_level = ((scsi_logging_level & ~mask) \
- | ((LEVEL << SHIFT) & mask)); \
-}
#else
-/*
- * With no logging enabled, stub these out so they don't do anything.
- */
#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
-#define SCSI_SET_LOGGING(SHIFT, BITS, LEVEL)
#endif /* CONFIG_SCSI_LOGGING */
/*
* These are the macros that are actually used throughout the code to
* log events. If logging isn't enabled, they are no-ops and will be
* completely absent from the user's code.
- *
- * The 'set' versions of the macros are really intended to only be called
- * from the /proc filesystem, and in production kernels this will be about
- * all that is ever used. It could be useful in a debugging environment to
- * bump the logging level when certain strange events are detected, however.
*/
#define SCSI_LOG_ERROR_RECOVERY(LEVEL,CMD) \
SCSI_CHECK_LOGGING(SCSI_LOG_ERROR_SHIFT, SCSI_LOG_ERROR_BITS, LEVEL,CMD);
@@ -92,26 +76,4 @@ extern unsigned int scsi_logging_level;
#define SCSI_LOG_IOCTL(LEVEL,CMD) \
SCSI_CHECK_LOGGING(SCSI_LOG_IOCTL_SHIFT, SCSI_LOG_IOCTL_BITS, LEVEL,CMD);
-
-#define SCSI_SET_ERROR_RECOVERY_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_ERROR_SHIFT, SCSI_LOG_ERROR_BITS, LEVEL);
-#define SCSI_SET_TIMEOUT_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_TIMEOUT_SHIFT, SCSI_LOG_TIMEOUT_BITS, LEVEL);
-#define SCSI_SET_SCAN_BUS_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_SCAN_SHIFT, SCSI_LOG_SCAN_BITS, LEVEL);
-#define SCSI_SET_MLQUEUE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_MLQUEUE_SHIFT, SCSI_LOG_MLQUEUE_BITS, LEVEL);
-#define SCSI_SET_MLCOMPLETE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_MLCOMPLETE_SHIFT, SCSI_LOG_MLCOMPLETE_BITS, LEVEL);
-#define SCSI_SET_LLQUEUE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_LLQUEUE_SHIFT, SCSI_LOG_LLQUEUE_BITS, LEVEL);
-#define SCSI_SET_LLCOMPLETE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_LLCOMPLETE_SHIFT, SCSI_LOG_LLCOMPLETE_BITS, LEVEL);
-#define SCSI_SET_HLQUEUE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_HLQUEUE_SHIFT, SCSI_LOG_HLQUEUE_BITS, LEVEL);
-#define SCSI_SET_HLCOMPLETE_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_HLCOMPLETE_SHIFT, SCSI_LOG_HLCOMPLETE_BITS, LEVEL);
-#define SCSI_SET_IOCTL_LOGGING(LEVEL) \
- SCSI_SET_LOGGING(SCSI_LOG_IOCTL_SHIFT, SCSI_LOG_IOCTL_BITS, LEVEL);
-
#endif /* _SCSI_LOGGING_H */
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 8608752c0fa4..62123cefb4c3 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -1,6 +1,17 @@
#ifndef _SCSI_PRIV_H
#define _SCSI_PRIV_H
+#include <linux/config.h>
+#include <linux/device.h>
+
+struct request_queue;
+struct scsi_cmnd;
+struct scsi_device;
+struct scsi_host_template;
+struct scsi_request;
+struct Scsi_Host;
+
+
/*
* These are the values that the owner field can take.
* They are used as an indication of who the command belongs to.
@@ -98,7 +109,7 @@ extern int scsi_init_queue(void);
extern void scsi_exit_queue(void);
/* scsi_proc.c */
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
extern void scsi_proc_hostdir_add(struct scsi_host_template *);
extern void scsi_proc_hostdir_rm(struct scsi_host_template *);
extern void scsi_proc_host_add(struct Scsi_Host *);
@@ -115,12 +126,21 @@ extern void scsi_exit_procfs(void);
#endif /* CONFIG_PROC_FS */
/* scsi_scan.c */
-int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int,
- unsigned int, int);
+extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
+ unsigned int, unsigned int, int);
extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_rescan_device(struct device *);
+/* scsi_sysctl.c */
+#ifdef CONFIG_SYSCTL
+extern int scsi_init_sysctl(void);
+extern void scsi_exit_sysctl(void);
+#else
+# define scsi_init_sysctl() (0)
+# define scsi_exit_sysctl() do { } while (0)
+#endif /* CONFIG_SYSCTL */
+
/* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *);
extern int scsi_sysfs_add_host(struct Scsi_Host *);
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index dd8bfd4b36c6..f72dd45bb651 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -37,9 +37,7 @@
/* 4K page size, but our output routines, use some slack for overruns */
#define PROC_BLOCK_SIZE (3*1024)
-/* XXX: this shouldn't really be exposed to drivers. */
-struct proc_dir_entry *proc_scsi;
-EXPORT_SYMBOL(proc_scsi);
+static struct proc_dir_entry *proc_scsi;
/* Protect sht->present and sht->proc_dir */
static DECLARE_MUTEX(global_host_template_sem);
@@ -235,106 +233,28 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
char *buffer, *p;
int err;
- if (!buf || length>PAGE_SIZE)
+ if (!buf || length > PAGE_SIZE)
return -EINVAL;
buffer = (char *)__get_free_page(GFP_KERNEL);
if (!buffer)
return -ENOMEM;
- if (copy_from_user(buffer, buf, length)) {
- err =-EFAULT;
+
+ err = -EFAULT;
+ if (copy_from_user(buffer, buf, length))
goto out;
- }
err = -EINVAL;
-
if (length < PAGE_SIZE)
buffer[length] = '\0';
else if (buffer[PAGE_SIZE-1])
goto out;
- if (length < 11 || strncmp("scsi", buffer, 4))
- goto out;
-
-#ifdef CONFIG_SCSI_LOGGING
- /*
- * Usage: echo "scsi log token #N" > /proc/scsi/scsi
- * where token is one of [error,scan,mlqueue,mlcomplete,llqueue,
- * llcomplete,hlqueue,hlcomplete]
- */
- if (!strncmp("log", buffer + 5, 3)) {
- char *token;
- unsigned int level;
-
- p = buffer + 9;
- token = p;
- while (*p != ' ' && *p != '\t' && *p != '\0') {
- p++;
- }
-
- if (*p == '\0') {
- if (strncmp(token, "all", 3) == 0) {
- /*
- * Turn on absolutely everything.
- */
- scsi_logging_level = ~0;
- } else if (strncmp(token, "none", 4) == 0) {
- /*
- * Turn off absolutely everything.
- */
- scsi_logging_level = 0;
- } else {
- goto out;
- }
- } else {
- *p++ = '\0';
-
- level = simple_strtoul(p, NULL, 0);
-
- /*
- * Now figure out what to do with it.
- */
- if (strcmp(token, "error") == 0) {
- SCSI_SET_ERROR_RECOVERY_LOGGING(level);
- } else if (strcmp(token, "timeout") == 0) {
- SCSI_SET_TIMEOUT_LOGGING(level);
- } else if (strcmp(token, "scan") == 0) {
- SCSI_SET_SCAN_BUS_LOGGING(level);
- } else if (strcmp(token, "mlqueue") == 0) {
- SCSI_SET_MLQUEUE_LOGGING(level);
- } else if (strcmp(token, "mlcomplete") == 0) {
- SCSI_SET_MLCOMPLETE_LOGGING(level);
- } else if (strcmp(token, "llqueue") == 0) {
- SCSI_SET_LLQUEUE_LOGGING(level);
- } else if (strcmp(token, "llcomplete") == 0) {
- SCSI_SET_LLCOMPLETE_LOGGING(level);
- } else if (strcmp(token, "hlqueue") == 0) {
- SCSI_SET_HLQUEUE_LOGGING(level);
- } else if (strcmp(token, "hlcomplete") == 0) {
- SCSI_SET_HLCOMPLETE_LOGGING(level);
- } else if (strcmp(token, "ioctl") == 0) {
- SCSI_SET_IOCTL_LOGGING(level);
- } else {
- goto out;
- }
- }
-
- printk(KERN_INFO "scsi logging level set to 0x%8.8x\n", scsi_logging_level);
- }
-#endif /* CONFIG_SCSI_LOGGING */
-
/*
* Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi
* with "0 1 2 3" replaced by your "Host Channel Id Lun".
- * Consider this feature BETA.
- * CAUTION: This is not for hotplugging your peripherals. As
- * SCSI was not designed for this you could damage your
- * hardware !
- * However perhaps it is legal to switch on an
- * already connected device. It is perhaps not
- * guaranteed this device doesn't corrupt an ongoing data transfer.
*/
- if (!strncmp("add-single-device", buffer + 5, 17)) {
+ if (!strncmp("scsi add-single-device", buffer, 22)) {
p = buffer + 23;
host = simple_strtoul(p, &p, 0);
@@ -345,18 +265,12 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
err = scsi_add_single_device(host, channel, id, lun);
if (err >= 0)
err = length;
+
/*
* Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi
* with "0 1 2 3" replaced by your "Host Channel Id Lun".
- *
- * Consider this feature pre-BETA.
- *
- * CAUTION: This is not for hotplugging your peripherals. As
- * SCSI was not designed for this you could damage your
- * hardware and thoroughly confuse the SCSI subsystem.
- *
*/
- } else if (!strncmp("remove-single-device", buffer + 5, 20)) {
+ } else if (!strncmp("scsi remove-single-device", buffer, 25)) {
p = buffer + 26;
host = simple_strtoul(p, &p, 0);
@@ -366,8 +280,8 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
err = scsi_remove_single_device(host, channel, id, lun);
}
-out:
-
+
+ out:
free_page((unsigned long)buffer);
return err;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index cef0c4467a92..65807367d046 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/blkdev.h>
+#include <asm/semaphore.h>
#include "scsi.h"
#include "hosts.h"
@@ -94,6 +95,13 @@ MODULE_PARM_DESC(max_report_luns,
" between 1 and 16384)");
#endif
+/*
+ * This mutex serializes all scsi scanning activity from kernel- and
+ * userspace. It could easily be made per-host but I'd like to avoid
+ * the overhead for now.
+ */
+static DECLARE_MUTEX(scsi_scan_mutex);
+
/**
* scsi_unlock_floptical - unlock device via a special MODE SENSE command
* @sreq: used to send the command
@@ -685,7 +693,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
sdev = scsi_alloc_sdev(host, channel, id, lun);
if (!sdev)
goto out;
- sreq = scsi_allocate_request(sdev);
+ sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
if (!sreq)
goto out_free_sdev;
result = kmalloc(256, GFP_ATOMIC |
@@ -898,7 +906,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
if (bflags & BLIST_NOLUN)
return 0;
- sreq = scsi_allocate_request(sdev);
+ sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
if (!sreq)
goto out;
@@ -1067,9 +1075,12 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
struct scsi_device *sdev;
int res;
+ down(&scsi_scan_mutex);
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1);
if (res != SCSI_SCAN_LUN_PRESENT)
sdev = ERR_PTR(-ENODEV);
+ up(&scsi_scan_mutex);
+
return sdev;
}
@@ -1191,11 +1202,14 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
return -EINVAL;
+ down(&scsi_scan_mutex);
if (channel == SCAN_WILD_CARD)
for (channel = 0; channel <= shost->max_channel; channel++)
scsi_scan_channel(shost, channel, id, lun, rescan);
else
scsi_scan_channel(shost, channel, id, lun, rescan);
+ up(&scsi_scan_mutex);
+
return 0;
}
diff --git a/drivers/scsi/scsi_sysctl.c b/drivers/scsi/scsi_sysctl.c
new file mode 100644
index 000000000000..04d06c25132b
--- /dev/null
+++ b/drivers/scsi/scsi_sysctl.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003 Christoph Hellwig.
+ * Released under GPL v2.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sysctl.h>
+
+#include "scsi_logging.h"
+
+
+static ctl_table scsi_table[] = {
+ { .ctl_name = DEV_SCSI_LOGGING_LEVEL,
+ .procname = "logging_level",
+ .data = &scsi_logging_level,
+ .maxlen = sizeof(scsi_logging_level),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec },
+ { }
+};
+
+static ctl_table scsi_dir_table[] = {
+ { .ctl_name = DEV_SCSI,
+ .procname = "scsi",
+ .mode = 0555,
+ .child = scsi_table },
+ { }
+};
+
+static ctl_table scsi_root_table[] = {
+ { .ctl_name = CTL_DEV,
+ .procname = "dev",
+ .mode = 0555,
+ .child = scsi_dir_table },
+ { }
+};
+
+static struct ctl_table_header *scsi_table_header;
+
+int __init scsi_init_sysctl(void)
+{
+ scsi_table_header = register_sysctl_table(scsi_root_table, 1);
+ if (!scsi_table_header)
+ return -ENOMEM;
+ return 0;
+}
+
+void scsi_exit_sysctl(void)
+{
+ unregister_sysctl_table(scsi_table_header);
+}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2d9c592537b7..2bd0ee80e138 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -370,25 +370,24 @@ static int sd_open(struct inode *inode, struct file *filp)
if (!scsi_block_when_processing_errors(sdev))
goto error_out;
- if (sdev->removable) {
+ if (sdev->removable || sdkp->write_prot)
check_disk_change(inode->i_bdev);
- /*
- * If the drive is empty, just let the open fail.
- */
- retval = -ENOMEDIUM;
- if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY))
- goto error_out;
+ /*
+ * If the drive is empty, just let the open fail.
+ */
+ retval = -ENOMEDIUM;
+ if (sdev->removable && !sdkp->media_present &&
+ !(filp->f_flags & O_NDELAY))
+ goto error_out;
- /*
- * Similarly, if the device has the write protect tab set,
- * have the open fail if the user expects to be able to write
- * to the thing.
- */
- retval = -EROFS;
- if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE))
- goto error_out;
- }
+ /*
+ * If the device has the write protect tab set, have the open fail
+ * if the user expects to be able to write to the thing.
+ */
+ retval = -EROFS;
+ if (sdkp->write_prot && (filp->f_mode & FMODE_WRITE))
+ goto error_out;
/*
* It is possible that the disk changing stuff resulted in
@@ -1174,7 +1173,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
if (!sdp->online)
goto out;
- sreq = scsi_allocate_request(sdp);
+ sreq = scsi_allocate_request(sdp, GFP_KERNEL);
if (!sreq) {
printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation "
"failure.\n");
@@ -1355,12 +1354,12 @@ static int sd_remove(struct device *dev)
static void sd_shutdown(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
- struct scsi_disk *sdkp;
+ struct scsi_disk *sdkp;
struct scsi_request *sreq;
int retries, res;
- sdkp = dev_get_drvdata(dev);
- if (!sdkp)
+ sdkp = dev_get_drvdata(dev);
+ if (!sdkp)
return; /* this can happen */
if (!sdp->online || !sdkp->WCE)
@@ -1369,7 +1368,7 @@ static void sd_shutdown(struct device *dev)
printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: ",
sdkp->disk->disk_name);
- sreq = scsi_allocate_request(sdp);
+ sreq = scsi_allocate_request(sdp, GFP_KERNEL);
if (!sreq) {
printk("FAILED\n No memory for request\n");
return;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 813364338aea..0a5497ea2389 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -70,7 +70,7 @@ static int sg_version_num = 30529; /* 2 digits for each component */
#include "scsi_logging.h"
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
@@ -222,7 +222,7 @@ static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
// static void sg_unmap_and(Sg_scatter_hold * schp, int free_also);
static Sg_device *sg_get_dev(int dev);
static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp);
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
static int sg_last_dev(void);
#endif
@@ -680,7 +680,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
sg_finish_rem_req(srp);
return -ENODEV;
}
- SRpnt = scsi_allocate_request(sdp->device);
+ SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC);
if (SRpnt == NULL) {
SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n"));
sg_finish_rem_req(srp);
@@ -1516,18 +1516,18 @@ init_sg(void)
rc = scsi_register_interface(&sg_interface);
if (rc)
return rc;
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
sg_proc_init();
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SCSI_PROC_FS */
return 0;
}
static void __exit
exit_sg(void)
{
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
sg_proc_cleanup();
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SCSI_PROC_FS */
scsi_unregister_interface(&sg_interface);
unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
if (sg_dev_arr != NULL) {
@@ -2225,7 +2225,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
return resp;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
static Sg_request *
sg_get_nth_request(Sg_fd * sfp, int nth)
{
@@ -2317,7 +2317,7 @@ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
return res;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
static Sg_fd *
sg_get_nth_sfp(Sg_device * sdp, int nth)
{
@@ -2548,7 +2548,7 @@ sg_allow_access(unsigned char opcode, char dev_type)
return 0;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
static int
sg_last_dev(void)
{
@@ -2579,11 +2579,11 @@ sg_get_dev(int dev)
return sdp;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SCSI_PROC_FS
static struct proc_dir_entry *sg_proc_sgp = NULL;
-static char sg_proc_sg_dirname[] = "sg";
+static char sg_proc_sg_dirname[] = "scsi/sg";
static int sg_proc_adio_read(char *buffer, char **start, off_t offset,
int size, int *eof, void *data);
@@ -2657,10 +2657,6 @@ static struct sg_proc_leaf sg_proc_leaf_arr[] = {
size : begin + len - offset; \
} while(0)
-/* this should _really_ be private to the scsi midlayer. But
- /proc/scsi/sg is an established name, so.. */
-extern struct proc_dir_entry *proc_scsi;
-
static int
sg_proc_init(void)
{
@@ -2670,10 +2666,8 @@ sg_proc_init(void)
struct proc_dir_entry *pdep;
struct sg_proc_leaf * leaf;
- if (!proc_scsi)
- return 1;
sg_proc_sgp = create_proc_entry(sg_proc_sg_dirname,
- S_IFDIR | S_IRUGO | S_IXUGO, proc_scsi);
+ S_IFDIR | S_IRUGO | S_IXUGO, NULL);
if (!sg_proc_sgp)
return 1;
for (k = 0; k < num_leaves; ++k) {
@@ -2696,11 +2690,11 @@ sg_proc_cleanup(void)
int num_leaves =
sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]);
- if ((!proc_scsi) || (!sg_proc_sgp))
+ if (!sg_proc_sgp)
return;
for (k = 0; k < num_leaves; ++k)
remove_proc_entry(sg_proc_leaf_arr[k].name, sg_proc_sgp);
- remove_proc_entry(sg_proc_sg_dirname, proc_scsi);
+ remove_proc_entry(sg_proc_sg_dirname, NULL);
}
static int
@@ -2971,7 +2965,7 @@ sg_proc_version_info(char *buffer, int *len, off_t * begin,
PRINT_PROC("%d\t%s\n", sg_version_num, sg_version_str);
return 1;
}
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SCSI_PROC_FS */
module_init(init_sg);
module_exit(exit_sg);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index bbef9a48030f..089510b7a819 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -599,7 +599,7 @@ static void get_sectorsize(struct scsi_cd *cd)
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
if (!buffer)
goto Enomem;
- SRpnt = scsi_allocate_request(cd->device);
+ SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL);
if (!SRpnt)
goto Enomem;
@@ -713,7 +713,7 @@ static void get_capabilities(struct scsi_cd *cd)
};
/* allocate a request for the TEST_UNIT_READY */
- SRpnt = scsi_allocate_request(cd->device);
+ SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL);
if (!SRpnt) {
printk(KERN_WARNING "(get_capabilities:) Request allocation "
"failure.\n");
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 7eb274c0a33d..0416030f717f 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -82,7 +82,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct cdrom_generic_command *cgc)
int result, err = 0, retries = 0;
SDev = cd->device;
- SRpnt = scsi_allocate_request(SDev);
+ SRpnt = scsi_allocate_request(SDev, GFP_KERNEL);
if (!SRpnt) {
printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl");
err = -ENOMEM;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 85969cd26c84..ed0a5ab2667b 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -374,7 +374,7 @@ static Scsi_Request *
unsigned char *bp;
if (SRpnt == NULL) {
- SRpnt = scsi_allocate_request(STp->device);
+ SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC);
if (SRpnt == NULL) {
DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
tape_name(STp)); );
diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
index c549d49e3c30..a31642785f19 100644
--- a/drivers/scsi/sym53c8xx.c
+++ b/drivers/scsi/sym53c8xx.c
@@ -6594,19 +6594,6 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
}
cp->cmd = cmd;
- /*---------------------------------------------------
- **
- ** Enable tagged queue if asked by scsi ioctl
- **
- **----------------------------------------------------
- */
-#if 0 /* This stuff was only useful for linux-1.2.13 */
- if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) {
- lp->numtags = tp->usrtags;
- ncr_setup_tags (np, cp->target, cp->lun);
- }
-#endif
-
/*----------------------------------------------------
**
** Build the identify / tag / sdtr message
diff --git a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h
index 8bc52f731a5a..705ffaadb31f 100644
--- a/drivers/scsi/sym53c8xx_2/sym_conf.h
+++ b/drivers/scsi/sym53c8xx_2/sym_conf.h
@@ -131,11 +131,6 @@
/* #define SYM_CONF_IARB_SUPPORT */
/*
- * Support for some PCI fix-ups (or assumed so).
- */
-#define SYM_CONF_PCI_FIX_UP
-
-/*
* Number of lists for the optimization of the IO timeout handling.
* Not used under FreeBSD and Linux.
*/
diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
index 70649d107d6a..f8344b42dfd1 100644
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h
@@ -74,8 +74,8 @@
#define PCI_ID_SYM53C896 0xb
#define PCI_ID_SYM53C895A 0x12
#define PCI_ID_SYM53C875A 0x13
-#define PCI_ID_LSI53C1010 0x20
-#define PCI_ID_LSI53C1010_2 0x21
+#define PCI_ID_LSI53C1010_33 0x20
+#define PCI_ID_LSI53C1010_66 0x21
#define PCI_ID_LSI53C1510D 0xa
/*
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
index bcdd7c5297e0..5b24d1fe9652 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c
@@ -270,13 +270,13 @@ sym_fw2_patch(hcb_p np)
* Remove a couple of work-arounds specific to C1010 if
* they are not desirable. See `sym_fw2.h' for more details.
*/
- if (!(np->device_id == PCI_ID_LSI53C1010_2 &&
+ if (!(np->device_id == PCI_ID_LSI53C1010_66 &&
np->revision_id < 0x1 &&
np->pciclk_khz < 60000)) {
scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
scripta0->datao_phase[1] = cpu_to_scr(0);
}
- if (!(np->device_id == PCI_ID_LSI53C1010 &&
+ if (!(np->device_id == PCI_ID_LSI53C1010_33 &&
/* np->revision_id < 0xff */ 1)) {
scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
scripta0->sel_done[1] = cpu_to_scr(0);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index a8cb6c5ad4fe..26dcbea2b562 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -57,7 +57,7 @@
#define NAME53C "sym53c"
#define NAME53C8XX "sym53c8xx"
-static int __init
+static int __devinit
pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
{
u32 tmp;
@@ -77,30 +77,6 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
#undef PCI_BAR_OFFSET
}
-/*
- * Insert a delay in micro-seconds and milli-seconds.
- */
-void sym_udelay(int us) { udelay(us); }
-void sym_mdelay(int ms) { mdelay(ms); }
-
-/*
- * SMP threading.
- *
- * The whole SCSI sub-system under Linux is basically single-threaded.
- * Everything, including low-level driver interrupt routine, happens
- * with the `io_request_lock' held.
- * The sym53c8xx-1.x drivers series ran their interrupt code using a
- * spin mutex per controller. This added complexity without improving
- * scalability significantly. the sym-2 driver still use a spinlock
- * per controller for safety, but basically runs with the damned
- * io_request_lock held.
- */
-
-spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
-
-#define SYM_LOCK_DRIVER(flags) spin_lock_irqsave(&sym53c8xx_lock, flags)
-#define SYM_UNLOCK_DRIVER(flags) spin_unlock_irqrestore(&sym53c8xx_lock,flags)
-
#define SYM_INIT_LOCK_HCB(np) spin_lock_init((np)->s.host->host_lock);
#define SYM_LOCK_HCB(np, flags) \
spin_lock_irqsave((np)->s.host->host_lock, flags)
@@ -118,6 +94,9 @@ spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
#define ktime_add(a, o) ((a) + (u_long)(o))
#define ktime_sub(a, o) ((a) - (u_long)(o))
+/* This lock protects only the memory allocation/free. */
+spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
+
/*
* Wrappers to the generic memory allocator.
*/
@@ -125,58 +104,53 @@ void *sym_calloc(int size, char *name)
{
u_long flags;
void *m;
- SYM_LOCK_DRIVER(flags);
+ spin_lock_irqsave(&sym53c8xx_lock, flags);
m = sym_calloc_unlocked(size, name);
- SYM_UNLOCK_DRIVER(flags);
+ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
return m;
}
void sym_mfree(void *m, int size, char *name)
{
u_long flags;
- SYM_LOCK_DRIVER(flags);
+ spin_lock_irqsave(&sym53c8xx_lock, flags);
sym_mfree_unlocked(m, size, name);
- SYM_UNLOCK_DRIVER(flags);
+ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
}
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
-
void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name)
{
u_long flags;
void *m;
- SYM_LOCK_DRIVER(flags);
+ spin_lock_irqsave(&sym53c8xx_lock, flags);
m = __sym_calloc_dma_unlocked(dev_dmat, size, name);
- SYM_UNLOCK_DRIVER(flags);
+ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
return m;
}
void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name)
{
u_long flags;
- SYM_LOCK_DRIVER(flags);
+ spin_lock_irqsave(&sym53c8xx_lock, flags);
__sym_mfree_dma_unlocked(dev_dmat, m, size, name);
- SYM_UNLOCK_DRIVER(flags);
+ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
}
m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m)
{
u_long flags;
m_addr_t b;
- SYM_LOCK_DRIVER(flags);
+ spin_lock_irqsave(&sym53c8xx_lock, flags);
b = __vtobus_unlocked(dev_dmat, m);
- SYM_UNLOCK_DRIVER(flags);
+ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
return b;
}
-#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */
-
-
/*
* Map/unmap a PCI memory window.
*/
#ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING
-static u_long __init pci_map_mem(u_long base, u_long size)
+static u_long __devinit pci_map_mem(u_long base, u_long size)
{
u_long page_base = ((u_long) base) & PAGE_MASK;
u_long page_offs = ((u_long) base) - page_base;
@@ -185,19 +159,13 @@ static u_long __init pci_map_mem(u_long base, u_long size)
return page_remapped? (page_remapped + page_offs) : 0UL;
}
-static void __init pci_unmap_mem(u_long vaddr, u_long size)
+static void __devinit pci_unmap_mem(u_long vaddr, u_long size)
{
if (vaddr)
iounmap((void *) (vaddr & PAGE_MASK));
}
#endif
-/*
- * Used to retrieve the host structure when the
- * driver is called from the proc FS.
- */
-static struct Scsi_Host *first_host = NULL;
-
#define scsi_data_direction(cmd) (cmd->sc_data_direction)
/*
@@ -210,11 +178,7 @@ struct host_data {
/*
* Some type that fit DMA addresses as seen from BUS.
*/
-#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
-typedef u_long bus_addr_t;
-#else
typedef dma_addr_t bus_addr_t;
-#endif
/*
* Used by the eh thread to wait for command completion.
@@ -233,10 +197,8 @@ struct sym_eh_wait {
*/
struct sym_ucmd { /* Override the SCSI pointer structure */
SYM_QUEHEAD link_cmdq; /* Must stay at offset ZERO */
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
bus_addr_t data_mapping;
u_char data_mapped;
-#endif
struct sym_eh_wait *eh_wait;
};
@@ -249,39 +211,18 @@ typedef struct sym_ucmd *ucmd_p;
/*
* Deal with DMA mapping/unmapping.
*/
-
-#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
-
-/* Linux versions prior to pci bus iommu kernel interface */
-
-#define __unmap_scsi_data(pdev, cmd) do {; } while (0)
-#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer))
-#define __map_scsi_sg_data(pdev, cmd) ((cmd)->use_sg)
-#define __sync_scsi_data(pdev, cmd) do {; } while (0)
-
-#define bus_sg_dma_address(sc) vtobus((sc)->address)
-#define bus_sg_dma_len(sc) ((sc)->length)
-
-#else /* Linux version with pci bus iommu kernel interface */
-
#define bus_unmap_sg(pdev, sgptr, sgcnt, dir) \
pci_unmap_sg(pdev, sgptr, sgcnt, dir)
-
#define bus_unmap_single(pdev, mapping, bufptr, dir) \
pci_unmap_single(pdev, mapping, bufptr, dir)
-
#define bus_map_single(pdev, bufptr, bufsiz, dir) \
pci_map_single(pdev, bufptr, bufsiz, dir)
-
#define bus_map_sg(pdev, sgptr, sgcnt, dir) \
pci_map_sg(pdev, sgptr, sgcnt, dir)
-
#define bus_dma_sync_sg(pdev, sgptr, sgcnt, dir) \
pci_dma_sync_sg(pdev, sgptr, sgcnt, dir)
-
#define bus_dma_sync_single(pdev, mapping, bufsiz, dir) \
pci_dma_sync_single(pdev, mapping, bufsiz, dir)
-
#define bus_sg_dma_address(sc) sg_dma_address(sc)
#define bus_sg_dma_len(sc) sg_dma_len(sc)
@@ -345,8 +286,6 @@ static void __sync_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
}
}
-#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */
-
#define unmap_scsi_data(np, cmd) \
__unmap_scsi_data(np->s.device, cmd)
#define map_scsi_single_data(np, cmd) \
@@ -1656,13 +1595,13 @@ static int sym_host_info(hcb_p np, char *ptr, off_t offset, int len)
copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, "
"revision id 0x%x\n",
np->s.chip_name, np->device_id, np->revision_id);
- copy_info(&info, "On PCI bus %d, device %d, function %d, "
+ copy_info(&info, "At PCI address %s, "
#ifdef __sparc__
"IRQ %s\n",
#else
"IRQ %d\n",
#endif
- np->s.bus, (np->s.device_fn & 0xf8) >> 3, np->s.device_fn & 7,
+ pci_name(np->s.device),
#ifdef __sparc__
__irq_itoa(np->s.irq));
#else
@@ -1748,7 +1687,6 @@ static void sym_free_resources(hcb_p np)
/*
* Ask/tell the system about DMA addressing.
*/
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
static int sym_setup_bus_dma_mask(hcb_p np)
{
#if SYM_CONF_DMA_ADDRESSING_MODE == 0
@@ -1780,7 +1718,6 @@ out_err32:
sym_name(np));
return -1;
}
-#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */
/*
* Host attach and initialisations.
@@ -1791,7 +1728,7 @@ out_err32:
* If all is OK, install interrupt handling and
* start the timer daemon.
*/
-static int __init
+static int __devinit
sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
{
struct host_data *host_data;
@@ -1802,15 +1739,14 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
struct sym_fw *fw;
printk(KERN_INFO
- "sym%d: <%s> rev 0x%x on pci bus %d device %d function %d "
+ "sym%d: <%s> rev 0x%x at pci %s "
#ifdef __sparc__
"irq %s\n",
#else
"irq %d\n",
#endif
unit, dev->chip.name, dev->chip.revision_id,
- dev->s.bus, (dev->s.device_fn & 0xf8) >> 3,
- dev->s.device_fn & 7,
+ pci_name(dev->pdev),
#ifdef __sparc__
__irq_itoa(dev->s.irq));
#else
@@ -1837,7 +1773,6 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
* We keep track in the HCB of all the resources that
* are to be released on error.
*/
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
np = __sym_calloc_dma(dev->pdev, sizeof(*np), "HCB");
if (np) {
np->s.device = dev->pdev;
@@ -1845,11 +1780,7 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
}
else
goto attach_failed;
-#else
- np = sym_calloc_dma(sizeof(*np), "HCB");
- if (!np)
- goto attach_failed;
-#endif
+
host_data->ncb = np;
np->s.host = instance;
@@ -1866,8 +1797,6 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
np->s.unit = unit;
np->device_id = dev->chip.device_id;
np->revision_id = dev->chip.revision_id;
- np->s.bus = dev->s.bus;
- np->s.device_fn = dev->s.device_fn;
np->features = dev->chip.features;
np->clock_divn = dev->chip.nr_divisor;
np->maxoffs = dev->chip.offset_max;
@@ -1883,10 +1812,8 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
/*
* Ask/tell the system about DMA addressing.
*/
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
if (sym_setup_bus_dma_mask(np))
goto attach_failed;
-#endif
/*
* Try to map the controller chip to
@@ -1987,12 +1914,6 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
sym_timer (np);
/*
- * Done.
- */
- if (!first_host)
- first_host = instance;
-
- /*
* Fill Linux host instance structure
* and return success.
*/
@@ -2039,7 +1960,7 @@ attach_failed:
* Detect and try to read SYMBIOS and TEKRAM NVRAM.
*/
#if SYM_CONF_NVRAM_SUPPORT
-static void __init sym_get_nvram(sym_device *devp, sym_nvram *nvp)
+static void __devinit sym_get_nvram(sym_device *devp, sym_nvram *nvp)
{
if (!nvp)
return;
@@ -2087,37 +2008,6 @@ char *sym53c8xx = 0; /* command line passed by insmod */
MODULE_PARM(sym53c8xx, "s");
#endif
-static void __init sym53c8xx_print_driver_setup(void)
-{
- printf_info (NAME53C8XX ": setup="
- "mpar:%d,spar:%d,tags:%d,sync:%d,burst:%d,"
- "led:%d,wide:%d,diff:%d,irqm:%d, buschk:%d\n",
- sym_driver_setup.pci_parity,
- sym_driver_setup.scsi_parity,
- sym_driver_setup.max_tag,
- sym_driver_setup.min_sync,
- sym_driver_setup.burst_order,
- sym_driver_setup.scsi_led,
- sym_driver_setup.max_wide,
- sym_driver_setup.scsi_diff,
- sym_driver_setup.irq_mode,
- sym_driver_setup.scsi_bus_check);
- printf_info (NAME53C8XX ": setup="
- "hostid:%d,offs:%d,luns:%d,pcifix:%d,revprob:%d,"
- "verb:%d,debug:0x%x,setlle_delay:%d\n",
- sym_driver_setup.host_id,
- sym_driver_setup.max_offs,
- sym_driver_setup.max_lun,
- sym_driver_setup.pci_fix_up,
- sym_driver_setup.reverse_probe,
- sym_driver_setup.verbose,
- sym_driver_setup.debug,
- sym_driver_setup.settle_delay);
-#ifdef DEBUG_2_0_X
-MDELAY(5000);
-#endif
-};
-
#define OPT_PCI_PARITY 1
#define OPT_SCSI_PARITY 2
#define OPT_MAX_TAG 3
@@ -2131,15 +2021,13 @@ MDELAY(5000);
#define OPT_HOST_ID 11
#define OPT_MAX_OFFS 12
#define OPT_MAX_LUN 13
-#define OPT_PCI_FIX_UP 14
-
-#define OPT_REVERSE_PROBE 15
-#define OPT_VERBOSE 16
-#define OPT_DEBUG 17
-#define OPT_SETTLE_DELAY 18
-#define OPT_USE_NVRAM 19
-#define OPT_EXCLUDE 20
-#define OPT_SAFE_SETUP 21
+#define OPT_REVERSE_PROBE 14
+#define OPT_VERBOSE 15
+#define OPT_DEBUG 16
+#define OPT_SETTLE_DELAY 17
+#define OPT_USE_NVRAM 18
+#define OPT_EXCLUDE 19
+#define OPT_SAFE_SETUP 20
static char setup_token[] __initdata =
"mpar:" "spar:"
@@ -2148,11 +2036,10 @@ static char setup_token[] __initdata =
"wide:" "diff:"
"irqm:" "buschk:"
"hostid:" "offset:"
- "luns:" "pcifix:"
- "revprob:" "verb:"
- "debug:" "settle:"
- "nvram:" "excl:"
- "safe:"
+ "luns:" "revprob:"
+ "verb:" "debug:"
+ "settle:" "nvram:"
+ "excl:" "safe:"
;
#ifdef MODULE
@@ -2239,7 +2126,6 @@ int __init sym53c8xx_setup(char *str)
__SIMPLE_OPTION(HOST_ID, host_id)
__SIMPLE_OPTION(MAX_OFFS, max_offs)
__SIMPLE_OPTION(MAX_LUN, max_lun)
- __SIMPLE_OPTION(PCI_FIX_UP, pci_fix_up)
__SIMPLE_OPTION(REVERSE_PROBE, reverse_probe)
__SIMPLE_OPTION(VERBOSE, verbose)
__SIMPLE_OPTION(DEBUG, debug)
@@ -2269,19 +2155,16 @@ __setup("sym53c8xx=", sym53c8xx_setup);
* boards and save data for attaching after all boards have
* been detected.
*/
-static int __init
+static int __devinit
sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
{
- u_short vendor_id, device_id, command, status_reg;
- u_char cache_line_size;
- u_char suggested_cache_line_size = 0;
- u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP;
+ u_short vendor_id, device_id, status_reg;
u_char revision;
u_int irq;
u_long base, base_2;
u_long base_c, base_2_c, io_port;
int i;
- sym_chip *chip;
+ struct sym_pci_chip *chip;
/* Choose some short name for this device */
sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number,
@@ -2393,25 +2276,6 @@ sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
pci_set_master(pdev);
/*
- * Read additionnal info from the configuration space.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
-
- /*
- * If cache line size is not configured, suggest
- * a value for well known CPUs.
- */
-#if defined(__i386__) && !defined(MODULE)
- if (!cache_line_size && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
- switch(boot_cpu_data.x86) {
- case 4: suggested_cache_line_size = 4; break;
- case 6: if (boot_cpu_data.x86_model > 8) break;
- case 5: suggested_cache_line_size = 8; break;
- }
- }
-#endif /* __i386__ */
-
- /*
* Some features are required to be enabled in order to
* work around some chip problems. :) ;)
* (ITEM 12 of a DEL about the 896 I haven't yet).
@@ -2420,31 +2284,12 @@ sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
*/
if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision < 0x4) {
chip->features |= (FE_WRIE | FE_CLSE);
- pci_fix_up |= 3; /* Force appropriate PCI fix-up */
- }
-
-#ifdef SYM_CONF_PCI_FIX_UP
- /*
- * Try to fix up PCI config according to wished features.
- */
- if ((pci_fix_up & 1) && (chip->features & FE_CLSE) &&
- !cache_line_size && suggested_cache_line_size) {
- cache_line_size = suggested_cache_line_size;
- pci_write_config_byte(pdev,
- PCI_CACHE_LINE_SIZE, cache_line_size);
- printf_info("%s: PCI_CACHE_LINE_SIZE set to %d.\n",
- sym_name(device), cache_line_size);
}
- pci_read_config_word(pdev, PCI_COMMAND, &command);
- if ((pci_fix_up & 2) && cache_line_size &&
- (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {
- printf_info("%s: setting PCI_COMMAND_INVALIDATE.\n",
- sym_name(device));
- command |= PCI_COMMAND_INVALIDATE;
- pci_write_config_word(pdev, PCI_COMMAND, command);
+ if (chip->features & FE_WRIE) {
+ if (pci_set_mwi(pdev))
+ return -1;
}
-#endif /* SYM_CONF_PCI_FIX_UP */
/*
* Work around for errant bit in 895A. The 66Mhz
@@ -2461,8 +2306,7 @@ sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
if (chip->features & FE_66MHZ) {
if (!(status_reg & PCI_STATUS_66MHZ))
chip->features &= ~FE_66MHZ;
- }
- else {
+ } else {
if (status_reg & PCI_STATUS_66MHZ) {
status_reg = PCI_STATUS_66MHZ;
pci_write_config_word(pdev, PCI_STATUS, status_reg);
@@ -2474,8 +2318,6 @@ sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
* Initialise device structure with items required by sym_attach.
*/
device->pdev = pdev;
- device->s.bus = pdev->bus->number;
- device->s.device_fn = pdev->devfn;
device->s.base = base;
device->s.base_2 = base_2;
device->s.base_c = base_c;
@@ -2487,203 +2329,6 @@ sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
return 0;
}
-#if 0
-/*
- * Detect all 53c8xx hosts and then attach them.
- *
- * If we are using NVRAM, once all hosts are detected, we need to
- * check any NVRAM for boot order in case detect and boot order
- * differ and attach them using the order in the NVRAM.
- *
- * If no NVRAM is found or data appears invalid attach boards in
- * the order they are detected.
- */
-int __init sym53c8xx_detect(struct scsi_host_template *tpnt)
-{
- struct pci_dev *pcidev;
- int i, j, chips, hosts, count;
- int attach_count = 0;
- sym_device *devtbl, *devp;
- sym_nvram nvram;
-#if SYM_CONF_NVRAM_SUPPORT
- sym_nvram nvram0, *nvp;
-#endif
-
- /*
- * Initialize driver general stuff.
- */
-#ifdef SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT
-#ifdef MODULE
-if (sym53c8xx)
- sym53c8xx_setup(sym53c8xx);
-#endif
-#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT
- sym_debug_flags = sym_driver_setup.debug;
-#endif
- if (boot_verbose >= 2)
- sym53c8xx_print_driver_setup();
-#endif /* SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT */
-
- /*
- * Allocate the device table since we donnot want to
- * overflow the kernel stack.
- * 1 x 4K PAGE is enough for more than 40 devices for i386.
- */
- devtbl = sym_calloc(PAGE_SIZE, "DEVTBL");
- if (!devtbl)
- return 0;
-
- /*
- * Detect all NCR PQS/PDS memory controllers.
- */
-#ifdef SYM_CONF_PQS_PDS_SUPPORT
- sym_detect_pqs_pds();
-#endif
-
- /*
- * Detect all 53c8xx hosts.
- * Save the first Symbios NVRAM content if any
- * for the boot order.
- */
- chips = sizeof(sym_chip_ids) / sizeof(sym_chip_ids[0]);
- hosts = PAGE_SIZE / sizeof(*devtbl);
-#if SYM_CONF_NVRAM_SUPPORT
- nvp = (sym_driver_setup.use_nvram & 0x1) ? &nvram0 : 0;
-#endif
- j = 0;
- count = 0;
- pcidev = NULL;
- while (1) {
- char *msg = "";
- if (count >= hosts)
- break;
- if (j >= chips)
- break;
- i = sym_driver_setup.reverse_probe ? chips - 1 - j : j;
- pcidev = pci_find_device(PCI_VENDOR_ID_NCR, sym_chip_ids[i],
- pcidev);
- if (pcidev == NULL) {
- ++j;
- continue;
- }
- /* This one is guaranteed by AC to do nothing :-) */
- if (pci_enable_device(pcidev))
- continue;
- devp = &devtbl[count];
- devp->host_id = SYM_SETUP_HOST_ID;
- if (sym53c8xx_pci_init(pcidev, devp)) {
- continue;
- }
- ++count;
-#if SYM_CONF_NVRAM_SUPPORT
- if (nvp) {
- sym_get_nvram(devp, nvp);
- switch(nvp->type) {
- case SYM_SYMBIOS_NVRAM:
- /*
- * Switch to the other nvram buffer, so that
- * nvram0 will contain the first Symbios
- * format NVRAM content with boot order.
- */
- nvp = &nvram;
- msg = "with Symbios NVRAM";
- break;
- case SYM_TEKRAM_NVRAM:
- msg = "with Tekram NVRAM";
- break;
- }
- }
-#endif
-#ifdef SYM_CONF_PQS_PDS_SUPPORT
- /*
- * Match the BUS number for PQS/PDS devices.
- * Read the SCSI ID from a special register mapped
- * into the configuration space of the individual
- * 875s. This register is set up by the PQS bios
- */
- for(i = 0; i < SYM_CONF_MAX_PQS_BUS && pqs_bus[i] != -1; i++) {
- u_char tmp;
- if (pqs_bus[i] == pcidev->bus->number) {
- pci_read_config_byte(pcidev, 0x84, &tmp);
- devp->pqs_pds = 1;
- devp->host_id = tmp;
- break;
- }
- }
- if (devp->pqs_pds)
- msg = "(NCR PQS/PDS)";
-#endif
- if (boot_verbose)
- printf_info("%s: 53c%s detected %s\n",
- sym_name(devp), devp->chip.name, msg);
- }
-
- /*
- * If we have found a SYMBIOS NVRAM, use first the NVRAM boot
- * sequence as device boot order.
- * check devices in the boot record against devices detected.
- * attach devices if we find a match. boot table records that
- * do not match any detected devices will be ignored.
- * devices that do not match any boot table will not be attached
- * here but will attempt to be attached during the device table
- * rescan.
- */
-#if SYM_CONF_NVRAM_SUPPORT
- if (!nvp || nvram0.type != SYM_SYMBIOS_NVRAM)
- goto next;
- for (i = 0; i < 4; i++) {
- Symbios_host *h = &nvram0.data.Symbios.host[i];
- for (j = 0 ; j < count ; j++) {
- devp = &devtbl[j];
- if (h->device_fn != devp->s.device_fn ||
- h->bus_nr != devp->s.bus ||
- h->device_id != devp->chip.device_id)
- continue;
- if (devp->attach_done)
- continue;
- if (h->flags & SYMBIOS_INIT_SCAN_AT_BOOT) {
- sym_get_nvram(devp, nvp);
- if (!sym_attach (tpnt, attach_count, devp))
- attach_count++;
- }
- else if (!(sym_driver_setup.use_nvram & 0x80))
- printf_info(
- "%s: 53c%s state OFF thus not attached\n",
- sym_name(devp), devp->chip.name);
- else
- continue;
-
- devp->attach_done = 1;
- break;
- }
- }
-next:
-#endif
-
- /*
- * Rescan device list to make sure all boards attached.
- * Devices without boot records will not be attached yet
- * so try to attach them here.
- */
- for (i= 0; i < count; i++) {
- devp = &devtbl[i];
- if (!devp->attach_done) {
- devp->nvram = &nvram;
- nvram.type = 0;
-#if SYM_CONF_NVRAM_SUPPORT
- sym_get_nvram(devp, nvp);
-#endif
- if (!sym_attach (tpnt, attach_count, devp))
- attach_count++;
- }
- }
-
- sym_mfree(devtbl, PAGE_SIZE, "DEVTBL");
-
- return attach_count;
-}
-#endif
-
/*
* Linux release module stuff.
@@ -2717,15 +2362,6 @@ static int sym_detach(hcb_p np)
return 1;
}
-#if 0
-int sym53c8xx_release(struct Scsi_Host *host)
-{
- sym_detach(((struct host_data *) host->hostdata)->ncb);
-
- return 0;
-}
-#endif
-
MODULE_LICENSE("Dual BSD/GPL");
/*
@@ -2734,10 +2370,6 @@ MODULE_LICENSE("Dual BSD/GPL");
static struct scsi_host_template sym2_template = {
.module = THIS_MODULE,
.name = "sym53c8xx",
-#if 0
- .detect = sym53c8xx_detect,
- .release = sym53c8xx_release,
-#endif
.info = sym53c8xx_info,
.queuecommand = sym53c8xx_queue_command,
.slave_configure = sym53c8xx_slave_configure,
@@ -2839,7 +2471,6 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
sym_dev.host_id = SYM_SETUP_HOST_ID;
if (sym53c8xx_pci_init(pdev, &sym_dev))
return -ENODEV;
- printk(KERN_INFO "%s: 53c%s detected\n", sym_name(&sym_dev), sym_dev.chip.name);
sym_dev.nvram = &nvram;
nvram.type = 0;
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index 5ee8c1b63f0f..a8f5a81cad40 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -111,8 +111,6 @@ typedef u_long vm_offset_t;
/*
* Configuration addendum for Linux.
*/
-#define SYM_LINUX_DYNAMIC_DMA_MAPPING
-
#define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2)
#define SYM_OPT_HANDLE_DIR_UNKNOWN
@@ -121,10 +119,7 @@ typedef u_long vm_offset_t;
#define SYM_OPT_SNIFF_INQUIRY
#define SYM_OPT_LIMIT_COMMAND_REORDERING
#define SYM_OPT_ANNOUNCE_TRANSFER_RATE
-
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
#define SYM_OPT_BUS_DMA_ABSTRACTION
-#endif
/*
* Print a message with severity.
@@ -142,8 +137,8 @@ typedef u_long vm_offset_t;
/*
* Insert a delay in micro-seconds and milli-seconds.
*/
-void sym_udelay(int us);
-void sym_mdelay(int ms);
+#define sym_udelay(us) udelay(us)
+#define sym_mdelay(ms) mdelay(ms)
/*
* Let the compiler know about driver data structure names.
@@ -426,9 +421,6 @@ struct sym_shcb {
struct Scsi_Host *host;
- u_char bus; /* PCI BUS number */
- u_char device_fn; /* PCI BUS device and function */
-
vm_offset_t mmio_va; /* MMIO kernel virtual address */
vm_offset_t ram_va; /* RAM kernel virtual address */
u_long io_port; /* IO port address cookie */
@@ -455,8 +447,6 @@ struct sym_shcb {
* used as sub-field 's' of another structure.
*/
typedef struct {
- int bus;
- u_char device_fn;
u_long base;
u_long base_2;
u_long base_c;
@@ -469,12 +459,11 @@ typedef struct {
} sym_slot;
typedef struct sym_nvram sym_nvram;
-typedef struct sym_pci_chip sym_chip;
typedef struct {
struct pci_dev *pdev;
sym_slot s;
- sym_chip chip;
+ struct sym_pci_chip chip;
sym_nvram *nvram;
u_short device_id;
u_char host_id;
@@ -496,9 +485,7 @@ typedef u_long m_addr_t; /* Enough bits to represent any address */
#ifdef MODULE
#define SYM_MEM_FREE_UNUSED /* Free unused pages immediately */
#endif
-#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
typedef struct pci_dev *m_pool_ident_t;
-#endif
/*
* Include driver soft definitions.
@@ -521,19 +508,7 @@ typedef struct pci_dev *m_pool_ident_t;
void *sym_calloc(int size, char *name);
void sym_mfree(void *m, int size, char *name);
-#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
/*
- * Simple case.
- * All the memory assummed DMAable and O/S providing virtual
- * to bus physical address translation.
- */
-#define __sym_calloc_dma(pool_id, size, name) sym_calloc(size, name)
-#define __sym_mfree_dma(pool_id, m, size, name) sym_mfree(m, size, name)
-#define __vtobus(b, p) virt_to_bus(p)
-
-#else /* SYM_LINUX_DYNAMIC_DMA_MAPPING */
-/*
- * Complex case.
* We have to provide the driver memory allocator with methods for
* it to maintain virtual to bus physical address translations.
*/
@@ -560,15 +535,12 @@ static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
}
#define sym_m_create_dma_mem_tag(mp) (0)
-
#define sym_m_delete_dma_mem_tag(mp) do { ; } while (0)
void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name);
void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name);
m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
-#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */
-
/*
* Set the status field of a CAM CCB.
*/
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 7d83f2c28869..a8984f6ee40e 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -50,7 +50,7 @@
* SUCH DAMAGE.
*/
-#define SYM_DRIVER_NAME "sym-2.1.16a"
+#define SYM_DRIVER_NAME "sym-2.1.17a"
#ifdef __FreeBSD__
#include <dev/sym/sym_glue.h>
@@ -289,7 +289,7 @@ int sym_reset_scsi_bus(hcb_p np, int enab_int)
((INW(nc_sbdl) & 0xff00) << 10) | /* d15-8 */
INB(nc_sbcl); /* req ack bsy sel atn msg cd io */
- if (!(np->features & FE_WIDE))
+ if (!np->maxwide)
term &= 0x3ffff;
if (term != (2<<7)) {
@@ -744,6 +744,12 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
u32 period;
int i;
+#ifdef CONFIG_PARISC
+ unsigned long pdc_period;
+ char scsi_mode = -1;
+ struct hardware_path hwpath;
+#endif
+
/*
* Wide ?
*/
@@ -800,6 +806,31 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
* Btw, 'period' is in tenths of nanoseconds.
*/
period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
+
+#if defined(CONFIG_PARISC)
+ /* Host firmware (PDC) keeps a table for crippling SCSI capabilities.
+ * Many newer machines export one channel of 53c896 chip
+ * as SE, 50-pin HD. Also used for Multi-initiator SCSI clusters
+ * to set the SCSI Initiator ID.
+ */
+ get_pci_node_path(np->s.device, &hwpath);
+ if (pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period, &np->maxwide, &scsi_mode))
+ {
+ if (scsi_mode >= 0) {
+ /* C3000 PDC reports period/mode */
+ SYM_SETUP_SCSI_DIFF = 0;
+ switch(scsi_mode) {
+ case 0: np->scsi_mode = SMODE_SE; break;
+ case 1: np->scsi_mode = SMODE_HVD; break;
+ case 2: np->scsi_mode = SMODE_LVD; break;
+ default: break;
+ }
+ }
+
+ period = (u32) pdc_period;
+ }
+#endif
+
if (period <= 250) np->minsync = 10;
else if (period <= 303) np->minsync = 11;
else if (period <= 500) np->minsync = 12;
@@ -862,7 +893,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
* In dual channel mode, contention occurs if internal cycles
* are used. Disable internal cycles.
*/
- if (np->device_id == PCI_ID_LSI53C1010 &&
+ if (np->device_id == PCI_ID_LSI53C1010_33 &&
np->revision_id < 0x1)
np->rv_ccntl0 |= DILS;
@@ -1362,17 +1393,17 @@ static struct sym_pci_chip sym_pci_dev_table[] = {
FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
,
- {PCI_ID_LSI53C1010, 0x00, "1010-33", 6, 31, 7, 8,
+ {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
FE_C10}
,
- {PCI_ID_LSI53C1010, 0xff, "1010-33", 6, 31, 7, 8,
+ {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
FE_C10|FE_U3EN}
,
- {PCI_ID_LSI53C1010_2, 0xff, "1010-66", 6, 31, 7, 8,
+ {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC|
FE_C10|FE_U3EN}
@@ -1809,7 +1840,7 @@ void sym_start_up (hcb_p np, int reason)
/*
* For now, disable AIP generation on C1010-66.
*/
- if (np->device_id == PCI_ID_LSI53C1010_2)
+ if (np->device_id == PCI_ID_LSI53C1010_66)
OUTB (nc_aipcntl1, DISAIP);
/*
@@ -1819,7 +1850,7 @@ void sym_start_up (hcb_p np, int reason)
* that from SCRIPTS for each selection/reselection, but
* I just don't want. :)
*/
- if (np->device_id == PCI_ID_LSI53C1010 &&
+ if (np->device_id == PCI_ID_LSI53C1010_33 &&
np->revision_id < 1)
OUTB (nc_stest1, INB(nc_stest1) | 0x30);
diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h
index 3a4b41f13907..2b01031c5283 100644
--- a/drivers/scsi/sym53c8xx_2/sym_misc.h
+++ b/drivers/scsi/sym53c8xx_2/sym_misc.h
@@ -77,23 +77,8 @@
* should be enough).
*/
-#if defined __i386__
-#define __READ_BARRIER() \
- __asm__ volatile("lock; addl $0,0(%%esp)": : :"memory")
-#define __WRITE_BARRIER() __asm__ volatile ("": : :"memory")
-#elif defined __powerpc__
-#define __READ_BARRIER() __asm__ volatile("eieio; sync" : : : "memory")
-#define __WRITE_BARRIER() __asm__ volatile("eieio; sync" : : : "memory")
-#elif defined __ia64__
-#define __READ_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory")
-#define __WRITE_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory")
-#elif defined __alpha__
-#define __READ_BARRIER() __asm__ volatile("mb": : :"memory")
-#define __WRITE_BARRIER() __asm__ volatile("mb": : :"memory")
-#else
-#define __READ_BARRIER() mb()
-#define __WRITE_BARRIER() mb()
-#endif
+#define __READ_BARRIER() rmb()
+#define __WRITE_BARRIER() wmb()
#ifndef MEMORY_READ_BARRIER
#define MEMORY_READ_BARRIER() __READ_BARRIER()
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
index 289e3f06bca9..13a68b562dda 100644
--- a/drivers/scsi/sym53c8xx_defs.h
+++ b/drivers/scsi/sym53c8xx_defs.h
@@ -259,17 +259,6 @@
#endif
/*
- * Vendor specific stuff
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
-#define SCSI_NCR_SETUP_LED_PIN (1)
-#define SCSI_NCR_SETUP_DIFF_SUPPORT (4)
-#else
-#define SCSI_NCR_SETUP_LED_PIN (0)
-#define SCSI_NCR_SETUP_DIFF_SUPPORT (0)
-#endif
-
-/*
* Settle time after reset at boot-up
*/
#define SCSI_NCR_SETUP_SETTLE_TIME (2)
@@ -926,10 +915,10 @@ struct ncr_driver_setup {
SCSI_NCR_SETUP_DEFAULT_SYNC, \
0x00, \
7, \
- SCSI_NCR_SETUP_LED_PIN, \
+ 0, \
1, \
SCSI_NCR_SETUP_SETTLE_TIME, \
- SCSI_NCR_SETUP_DIFF_SUPPORT, \
+ 0, \
0, \
1, \
0, \
diff --git a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c
index 7692b54a9ad6..d104be2f167a 100644
--- a/drivers/serial/8250_acpi.c
+++ b/drivers/serial/8250_acpi.c
@@ -108,3 +108,6 @@ static void __exit acpi_serial_exit(void)
module_init(acpi_serial_init);
module_exit(acpi_serial_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 ACPI serial driver");
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index c85528623cfa..4205682ea286 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -798,7 +798,7 @@ int __init hiddev_init(void)
return usb_register(&hiddev_driver);
}
-void __exit hiddev_exit(void)
+void hiddev_exit(void)
{
usb_deregister(&hiddev_driver);
devfs_remove("usb/hid");
diff --git a/fs/bio.c b/fs/bio.c
index d80b7d19dc08..b02019be4668 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -296,7 +296,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
unsigned int offset)
{
request_queue_t *q = bdev_get_queue(bio->bi_bdev);
- int fail_segments = 0, retried_segments = 0;
+ int retried_segments = 0;
struct bio_vec *bvec;
/*
@@ -315,18 +315,15 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
* we might lose a segment or two here, but rather that than
* make this too complex.
*/
-retry_segments:
- if (bio_phys_segments(q, bio) >= q->max_phys_segments
- || bio_hw_segments(q, bio) >= q->max_hw_segments)
- fail_segments = 1;
- if (fail_segments) {
+ while (bio_phys_segments(q, bio) >= q->max_phys_segments
+ || bio_hw_segments(q, bio) >= q->max_hw_segments) {
+
if (retried_segments)
return 0;
bio->bi_flags &= ~(1 << BIO_SEG_VALID);
retried_segments = 1;
- goto retry_segments;
}
/*
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 153a4b0ff288..10114ce265da 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,14 @@
+Version 0.91
+------------
+Fix oops in reopen_files when invalid dentry. drop dentry on server rename
+and on revalidate errors. Fix cases where pid is now tgid. Fix return code
+on create hard link when server does not support them.
+
+Version 0.90
+------------
+Fix scheduling while atomic error in getting inode info on newly created file.
+Fix truncate of existing files opened with O_CREAT but not O_TRUNC set.
+
Version 0.89
------------
Fix oops on write to dead tcp session. Remove error log write for case when file open
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 9643932c9df2..ef523c53f680 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifssmb.c
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* Contains the routines for constructing the SMB PDUs themselves
@@ -656,7 +656,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = smb_file_id; /* netfid stays le */
- pSMB->Locks[0].Pid = cpu_to_le16(current->pid);
+ pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
pSMB->Locks[0].Length = cpu_to_le64(len);
pSMB->Locks[0].Offset = cpu_to_le64(offset);
pSMB->ByteCount = sizeof (LOCKING_ANDX_RANGE);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 7795f24d90b4..8873ca0447c9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
*
* vfs operations that deal with dentries
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -134,6 +134,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
struct inode *newinode = NULL;
struct cifsFileInfo * pCifsFile = NULL;
struct cifsInodeInfo * pCifsInode;
+ int disposition = FILE_OVERWRITE_IF;
xid = GetXid();
@@ -151,6 +152,16 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
desiredAccess = GENERIC_WRITE;
else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR)
desiredAccess = GENERIC_ALL;
+
+ if((nd->intent.open.flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ disposition = FILE_CREATE;
+ else if((nd->intent.open.flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
+ disposition = FILE_OVERWRITE_IF;
+ else if((nd->intent.open.flags & O_CREAT) == O_CREAT)
+ disposition = FILE_OPEN_IF;
+ else {
+ cFYI(1,("Create flag not set in create function"));
+ }
}
/* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
@@ -158,7 +169,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
oplock = REQ_OPLOCK;
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
- rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF,
+ rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
desiredAccess, CREATE_NOT_DIR,
&fileHandle, &oplock, buf, cifs_sb->local_nls);
if (rc) {
@@ -205,7 +216,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
memset((char *)pCifsFile, 0,
sizeof (struct cifsFileInfo));
pCifsFile->netfid = fileHandle;
- pCifsFile->pid = current->pid;
+ pCifsFile->pid = current->tgid;
pCifsFile->pInode = newinode;
/* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock);
@@ -297,6 +308,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
(" parent inode = 0x%p name is: %s and dentry = 0x%p",
parent_dir_inode, direntry->d_name.name, direntry));
+ if(nd) { /* BB removeme */
+ cFYI(1,("In lookup nd flags 0x%x open intent flags 0x%x",nd->flags,nd->intent.open.flags));
+ } /* BB removeme BB */
/* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */
/* check whether path exists */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 49f9c88c65cc..247a39b899b3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3,7 +3,7 @@
*
* vfs operations that deal with files
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -144,6 +144,10 @@ cifs_open(struct inode *inode, struct file *file)
list_add(&pCifsFile->tlist,&pTcon->openFileList);
pCifsInode = CIFS_I(file->f_dentry->d_inode);
if(pCifsInode) {
+ list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+ write_unlock(&GlobalSMBSeslock);
+ write_unlock(&file->f_owner.lock);
+
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
full_path, inode->i_sb);
@@ -151,16 +155,16 @@ cifs_open(struct inode *inode, struct file *file)
rc = cifs_get_inode_info(&file->f_dentry->d_inode,
full_path, buf, inode->i_sb);
- list_add(&pCifsFile->flist,&pCifsInode->openFileList);
if(oplock == OPLOCK_EXCLUSIVE) {
pCifsInode->clientCanCacheAll = TRUE;
pCifsInode->clientCanCacheRead = TRUE;
cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
} else if(oplock == OPLOCK_READ)
pCifsInode->clientCanCacheRead = TRUE;
+ } else {
+ write_unlock(&GlobalSMBSeslock);
+ write_unlock(&file->f_owner.lock);
}
- write_unlock(&GlobalSMBSeslock);
- write_unlock(&file->f_owner.lock);
if(file->f_flags & O_CREAT) {
/* time to set mode which we can not set earlier due
to problems creating new read-only files */
@@ -221,16 +225,21 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
if(file) {
file->private_data = NULL;
read_unlock(&GlobalSMBSeslock);
- rc = cifs_open(file->f_dentry->d_inode,file);
- read_lock(&GlobalSMBSeslock);
- if(rc) {
- cFYI(1,("reconnecting file %s failed with %d",
- file->f_dentry->d_name.name,rc));
+ if(file->f_dentry == 0) {
+ cFYI(1,("Null dentry for file %p",file));
+ read_lock(&GlobalSMBSeslock);
} else {
- cFYI(1,("reconnection of %s succeeded",
- file->f_dentry->d_name.name));
- }
- }
+ rc = cifs_open(file->f_dentry->d_inode,file);
+ read_lock(&GlobalSMBSeslock);
+ if(rc) {
+ cFYI(1,("reconnecting file %s failed with %d",
+ file->f_dentry->d_name.name,rc));
+ } else {
+ cFYI(1,("reconnection of %s succeeded",
+ file->f_dentry->d_name.name));
+ }
+ }
+ }
}
}
read_unlock(&GlobalSMBSeslock);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 62625e532132..3625916ca351 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/inode.c
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -345,6 +345,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
if (!rc) {
direntry->d_inode->i_nlink--;
+ } else if (rc == -ENOENT) {
+ d_drop(direntry);
} else if (rc == -ETXTBSY) {
int oplock = FALSE;
__u16 netfid;
@@ -585,12 +587,24 @@ cifs_revalidate(struct dentry *direntry)
}
}
- if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
- cifs_get_inode_info_unix(&direntry->d_inode, full_path,
+ if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
+ rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
direntry->d_sb);
- else
- cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
+ if(rc) {
+ cFYI(1,("error on getting revalidate info %d",rc));
+/* if(rc != -ENOENT)
+ rc = 0; */ /* BB should we cache info on certain errors? */
+ }
+ } else {
+ rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
direntry->d_sb);
+ if(rc) {
+ cFYI(1,("error on getting revalidate info %d",rc));
+/* if(rc != -ENOENT)
+ rc = 0; */ /* BB should we cache info on certain errors? */
+ }
+ }
+ /* should we remap certain errors, access denied?, to zero */
/* BB if not oplocked, invalidate inode pages if mtime has changed */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 9717910ee514..93c200f49f51 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/link.c
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (C) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -51,9 +51,12 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)
rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
cifs_sb_target->local_nls);
- else
+ else {
rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
cifs_sb_target->local_nls);
+ if(rc == -EIO)
+ rc = -EOPNOTSUPP;
+ }
/* if (!rc) */
{
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index b9a5137df6d7..65d84985a3ce 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/misc.c
*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (c) International Business Machines Corp., 2002,2003
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -213,7 +213,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
buffer->Command = smb_command;
buffer->Flags = 0x00; /* case sensitive */
buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES;
- tmp = cpu_to_le32(current->pid);
+ tmp = cpu_to_le32(current->tgid);
buffer->Pid = tmp & 0xFFFF;
tmp >>= 16;
buffer->PidHigh = tmp & 0xFFFF;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 23a295cf2269..e042f16e8764 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -356,10 +356,9 @@ static struct file_operations proc_slabinfo_operations = {
.release = seq_release,
};
-static int kstat_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+int show_stat(struct seq_file *p, void *v)
{
- int i, len;
+ int i;
extern unsigned long total_forks;
u64 jif;
unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
@@ -379,10 +378,10 @@ static int kstat_read_proc(char *page, char **start, off_t off,
jif = ((u64)now.tv_sec * HZ) + (now.tv_usec/(1000000/HZ)) - jif;
do_div(jif, HZ);
- for (i = 0 ; i < NR_CPUS; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
int j;
- if(!cpu_online(i)) continue;
+ if (!cpu_online(i)) continue;
user += kstat_cpu(i).cpustat.user;
nice += kstat_cpu(i).cpustat.nice;
system += kstat_cpu(i).cpustat.system;
@@ -394,7 +393,7 @@ static int kstat_read_proc(char *page, char **start, off_t off,
sum += kstat_cpu(i).irqs[j];
}
- len = sprintf(page, "cpu %u %u %u %u %u %u %u\n",
+ seq_printf(p, "cpu %u %u %u %u %u %u %u\n",
jiffies_to_clock_t(user),
jiffies_to_clock_t(nice),
jiffies_to_clock_t(system),
@@ -402,9 +401,9 @@ static int kstat_read_proc(char *page, char **start, off_t off,
jiffies_to_clock_t(iowait),
jiffies_to_clock_t(irq),
jiffies_to_clock_t(softirq));
- for (i = 0 ; i < NR_CPUS; i++){
+ for (i = 0; i < NR_CPUS; i++){
if (!cpu_online(i)) continue;
- len += sprintf(page + len, "cpu%d %u %u %u %u %u %u %u\n",
+ seq_printf(p, "cpu%d %u %u %u %u %u %u %u\n",
i,
jiffies_to_clock_t(kstat_cpu(i).cpustat.user),
jiffies_to_clock_t(kstat_cpu(i).cpustat.nice),
@@ -414,14 +413,14 @@ static int kstat_read_proc(char *page, char **start, off_t off,
jiffies_to_clock_t(kstat_cpu(i).cpustat.irq),
jiffies_to_clock_t(kstat_cpu(i).cpustat.softirq));
}
- len += sprintf(page + len, "intr %u", sum);
+ seq_printf(p, "intr %u", sum);
#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA)
- for (i = 0 ; i < NR_IRQS ; i++)
- len += sprintf(page + len, " %u", kstat_irqs(i));
+ for (i = 0; i < NR_IRQS; i++)
+ seq_printf(p, " %u", kstat_irqs(i));
#endif
- len += sprintf(page + len,
+ seq_printf(p,
"\nctxt %lu\n"
"btime %lu\n"
"processes %lu\n"
@@ -433,9 +432,39 @@ static int kstat_read_proc(char *page, char **start, off_t off,
nr_running(),
nr_iowait());
- return proc_calc_metrics(page, start, off, count, eof, len);
+ return 0;
}
+static int stat_open(struct inode *inode, struct file *file)
+{
+ unsigned size = 4096 * (1 + num_online_cpus() / 32);
+ char *buf;
+ struct seq_file *m;
+ int res;
+
+ /* don't ask for more than the kmalloc() max size, currently 128 KB */
+ if (size > 128 * 1024)
+ size = 128 * 1024;
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ res = single_open(file, show_stat, NULL);
+ if (!res) {
+ m = file->private_data;
+ m->buf = buf;
+ m->size = size;
+ } else
+ kfree(buf);
+ return res;
+}
+static struct file_operations proc_stat_operations = {
+ .open = stat_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int devices_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -626,7 +655,6 @@ void __init proc_misc_init(void)
#ifdef CONFIG_STRAM_PROC
{"stram", stram_read_proc},
#endif
- {"stat", kstat_read_proc},
{"devices", devices_read_proc},
{"filesystems", filesystems_read_proc},
{"cmdline", cmdline_read_proc},
@@ -648,6 +676,7 @@ void __init proc_misc_init(void)
entry->proc_fops = &proc_kmsg_operations;
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
create_seq_entry("partitions", 0, &proc_partitions_operations);
+ create_seq_entry("stat", 0, &proc_stat_operations);
create_seq_entry("interrupts", 0, &proc_interrupts_operations);
create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h
index ab26cfbaddbf..a363f018a35f 100644
--- a/include/asm-alpha/semaphore.h
+++ b/include/asm-alpha/semaphore.h
@@ -88,14 +88,18 @@ extern void __up_wakeup(struct semaphore *);
static inline void __down(struct semaphore *sem)
{
- long count = atomic_dec_return(&sem->count);
+ long count;
+ might_sleep();
+ count = atomic_dec_return(&sem->count);
if (unlikely(count < 0))
__down_failed(sem);
}
static inline int __down_interruptible(struct semaphore *sem)
{
- long count = atomic_dec_return(&sem->count);
+ long count;
+ might_sleep();
+ count = atomic_dec_return(&sem->count);
if (unlikely(count < 0))
return __down_failed_interruptible(sem);
return 0;
diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h
index 677eedee6694..84ab93eb4643 100644
--- a/include/asm-arm/assembler.h
+++ b/include/asm-arm/assembler.h
@@ -1,18 +1,23 @@
/*
- * linux/asm/assembler.h
+ * linux/include/asm-arm/assembler.h
*
- * This file contains arm architecture specific defines
- * for the different processors.
+ * Copyright (C) 1996-2000 Russell King
*
- * Do not include any C declarations in this file - it is included by
- * assembler source.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
*/
#ifndef __ASSEMBLY__
#error "Only include this from assembly code"
#endif
-#include <asm/proc/ptrace.h>
-#include <asm/proc/assembler.h>
+#include <asm/ptrace.h>
/*
* Endian independent macros for shifting bytes within registers.
@@ -36,3 +41,63 @@
#define PLD(code...)
#endif
+#define MODE_USR USR_MODE
+#define MODE_FIQ FIQ_MODE
+#define MODE_IRQ IRQ_MODE
+#define MODE_SVC SVC_MODE
+
+#define DEFAULT_FIQ MODE_FIQ
+
+/*
+ * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
+ */
+#ifdef __STDC__
+#define LOADREGS(cond, base, reglist...)\
+ ldm##cond base,reglist
+#else
+#define LOADREGS(cond, base, reglist...)\
+ ldm/**/cond base,reglist
+#endif
+
+/*
+ * Build a return instruction for this processor type.
+ */
+#define RETINSTR(instr, regs...)\
+ instr regs
+
+/*
+ * Save the current IRQ state and disable IRQs. Note that this macro
+ * assumes FIQs are enabled, and that the processor is in SVC mode.
+ */
+ .macro save_and_disable_irqs, oldcpsr, temp
+ mrs \oldcpsr, cpsr
+ mov \temp, #PSR_I_BIT | MODE_SVC
+ msr cpsr_c, \temp
+ .endm
+
+/*
+ * Restore interrupt state previously stored in a register. We don't
+ * guarantee that this will preserve the flags.
+ */
+ .macro restore_irqs, oldcpsr
+ msr cpsr_c, \oldcpsr
+ .endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do. On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+ .macro save_lr
+ .endm
+
+ .macro restore_pc
+ mov pc, lr
+ .endm
+
+#define USER(x...) \
+9999: x; \
+ .section __ex_table,"a"; \
+ .align 3; \
+ .long 9999b,9001f; \
+ .previous
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index ba9e4b72d821..e8e2cd1d69f1 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -27,7 +27,7 @@ typedef struct { volatile int counter; } atomic_t;
#define ATOMIC_INIT(i) { (i) }
#ifdef __KERNEL__
-#include <asm/proc/system.h>
+#include <asm/system.h>
#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index f5f2b2a3e199..30a47cba4d4b 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -1,7 +1,7 @@
/*
* linux/include/asm-arm/cacheflush.h
*
- * Copyright (C) 2000-2002 Russell King
+ * Copyright (C) 1999-2002 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
@@ -12,6 +12,275 @@
#include <linux/sched.h>
#include <linux/mm.h>
-#include <asm/proc/cache.h>
+
+#include <asm/mman.h>
+#include <asm/glue.h>
+
+/*
+ * Cache Model
+ * ===========
+ */
+#undef _CACHE
+#undef MULTI_CACHE
+
+#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM720T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM1020)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_ARM926T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm926
+# endif
+#endif
+
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4wb
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSCALE)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE xscale
+# endif
+#endif
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintainence model
+#endif
+
+/*
+ * This flag is used to indicate that the page pointed to by a pte
+ * is dirty and requires cleaning before returning it to the user.
+ */
+#define PG_dcache_dirty PG_arch_1
+
+/*
+ * MM Cache Management
+ * ===================
+ *
+ * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
+ * implement these methods.
+ *
+ * Start addresses are inclusive and end addresses are exclusive;
+ * start addresses should be rounded down, end addresses up.
+ *
+ * See linux/Documentation/cachetlb.txt for more information.
+ * Please note that the implementation of these, and the required
+ * effects are cache-type (VIVT/VIPT/PIPT) specific.
+ *
+ * flush_cache_kern_all()
+ *
+ * Unconditionally clean and invalidate the entire cache.
+ *
+ * flush_cache_user_mm(mm)
+ *
+ * Clean and invalidate all user space cache entries
+ * before a change of page tables.
+ *
+ * flush_cache_user_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address space before a change of page tables.
+ * - start - user start address (inclusive, page aligned)
+ * - end - user end address (exclusive, page aligned)
+ * - flags - vma->vm_flags field
+ *
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * DMA Cache Coherency
+ * ===================
+ *
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * dma_clean_range(start, end)
+ *
+ * Clean (write back) the specified virtual address range.
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+
+struct cpu_cache_fns {
+ void (*flush_kern_all)(void);
+ void (*flush_user_all)(void);
+ void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
+
+ void (*coherent_kern_range)(unsigned long, unsigned long);
+ void (*flush_kern_dcache_page)(void *);
+
+ void (*dma_inv_range)(unsigned long, unsigned long);
+ void (*dma_clean_range)(unsigned long, unsigned long);
+ void (*dma_flush_range)(unsigned long, unsigned long);
+};
+
+/*
+ * Select the calling method
+ */
+#ifdef MULTI_CACHE
+
+extern struct cpu_cache_fns cpu_cache;
+
+#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
+#define __cpuc_flush_user_all cpu_cache.flush_user_all
+#define __cpuc_flush_user_range cpu_cache.flush_user_range
+#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
+#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page
+
+/*
+ * These are private to the dma-mapping API. Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+#define dmac_inv_range cpu_cache.dma_inv_range
+#define dmac_clean_range cpu_cache.dma_clean_range
+#define dmac_flush_range cpu_cache.dma_flush_range
+
+#else
+
+#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
+#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
+#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
+#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page)
+
+extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_user_all(void);
+extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
+extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
+extern void __cpuc_flush_dcache_page(void *);
+
+/*
+ * These are private to the dma-mapping API. Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
+#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
+#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
+
+extern void dmac_inv_range(unsigned long, unsigned long);
+extern void dmac_clean_range(unsigned long, unsigned long);
+extern void dmac_flush_range(unsigned long, unsigned long);
+
+#endif
+
+/*
+ * Convert calls to our calling convention.
+ */
+#define flush_cache_all() __cpuc_flush_kern_all()
+
+static inline void flush_cache_mm(struct mm_struct *mm)
+{
+ if (current->active_mm == mm)
+ __cpuc_flush_user_all();
+}
+
+static inline void
+flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ if (current->active_mm == vma->vm_mm)
+ __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
+ vma->vm_flags);
+}
+
+static inline void
+flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr)
+{
+ if (current->active_mm == vma->vm_mm) {
+ unsigned long addr = user_addr & PAGE_MASK;
+ __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
+ }
+}
+
+/*
+ * Perform necessary cache operations to ensure that data previously
+ * stored within this range of addresses can be executed by the CPU.
+ */
+#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
+
+/*
+ * Perform necessary cache operations to ensure that the TLB will
+ * see data written in the specified area.
+ */
+#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
+
+/*
+ * flush_dcache_page is used when the kernel has written to the page
+ * cache page at virtual address page->virtual.
+ *
+ * If this page isn't mapped (ie, page->mapping = NULL), or it has
+ * userspace mappings (page->mapping->i_mmap or page->mapping->i_mmap_shared)
+ * then we _must_ always clean + invalidate the dcache entries associated
+ * with the kernel mapping.
+ *
+ * Otherwise we can defer the operation, and clean the cache when we are
+ * about to change to user space. This is the same method as used on SPARC64.
+ * See update_mmu_cache for the user space part.
+ */
+#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \
+ !list_empty(&(map)->i_mmap_shared))
+
+extern void __flush_dcache_page(struct page *);
+
+static inline void flush_dcache_page(struct page *page)
+{
+ if (page->mapping && !mapping_mapped(page->mapping))
+ set_bit(PG_dcache_dirty, &page->flags);
+ else
+ __flush_dcache_page(page);
+}
+
+#define flush_icache_user_range(vma,page,addr,len) \
+ flush_dcache_page(page)
+
+/*
+ * We don't appear to need to do anything here. In fact, if we did, we'd
+ * duplicate cache flushing elsewhere performed by flush_dcache_page().
+ */
+#define flush_icache_page(vma,page) do { } while (0)
#endif
diff --git a/include/asm-arm/cpu-multi26.h b/include/asm-arm/cpu-multi26.h
deleted file mode 100644
index 415ce60471dd..000000000000
--- a/include/asm-arm/cpu-multi26.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * linux/include/asm-arm/cpu-multi26.h
- *
- * Copyright (C) 2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASSEMBLY__
-
-#include <asm/page.h>
-
-/* forward-declare task_struct */
-struct task_struct;
-
-/*
- * Don't change this structure - ASM code
- * relies on it.
- */
-extern struct processor {
- /* Set up any processor specifics */
- void (*_proc_init)(void);
- /* Disable any processor specifics */
- void (*_proc_fin)(void);
- /* set the MEMC hardware mappings */
- void (*_switch_mm)(pgd_t *pgd);
- /* XCHG */
- unsigned long (*_xchg_1)(unsigned long x, volatile void *ptr);
- unsigned long (*_xchg_4)(unsigned long x, volatile void *ptr);
-} processor;
-
-extern const struct processor arm2_processor_functions;
-extern const struct processor arm250_processor_functions;
-extern const struct processor arm3_processor_functions;
-
-#define cpu_proc_init() processor._proc_init()
-#define cpu_proc_fin() processor._proc_fin()
-#define cpu_do_idle() do { } while (0)
-#define cpu_switch_mm(pgd,mm) processor._switch_mm(pgd)
-#define cpu_xchg_1(x,ptr) processor._xchg_1(x,ptr)
-#define cpu_xchg_4(x,ptr) processor._xchg_4(x,ptr)
-
-extern void cpu_memc_update_all(pgd_t *pgd);
-extern void cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long log_addr);
-
-#endif
diff --git a/include/asm-arm/proc-armv/domain.h b/include/asm-arm/domain.h
index 67f889162c31..87f9734a8a4a 100644
--- a/include/asm-arm/proc-armv/domain.h
+++ b/include/asm-arm/domain.h
@@ -1,5 +1,5 @@
/*
- * linux/include/asm-arm/proc-armv/domain.h
+ * linux/include/asm-arm/domain.h
*
* Copyright (C) 1999 Russell King.
*
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index 536b2d6f2854..b67e06c0f588 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -7,7 +7,6 @@
#include <asm/ptrace.h>
#include <asm/user.h>
-#include <asm/proc/elf.h>
#include <asm/procinfo.h>
typedef unsigned long elf_greg_t;
@@ -42,6 +41,7 @@ typedef struct user_fp elf_fpregset_t;
#define ELF_ARCH EM_ARM
#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
@@ -76,4 +76,29 @@ typedef struct user_fp elf_fpregset_t;
extern char elf_platform[];
#define ELF_PLATFORM (elf_platform)
+#ifdef __KERNEL__
+
+/*
+ * 32-bit code is always OK. Some cpus can do 26-bit, some can't.
+ */
+#define ELF_PROC_OK(x) (ELF_THUMB_OK(x) && ELF_26BIT_OK(x))
+
+#define ELF_THUMB_OK(x) \
+ (( (elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 1) == 1) || \
+ ((x)->e_entry & 3) == 0)
+
+#define ELF_26BIT_OK(x) \
+ (( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \
+ ((x)->e_flags & EF_ARM_APCS26) == 0)
+
+/* Old NetWinder binaries were compiled in such a way that the iBCS
+ heuristic always trips on them. Until these binaries become uncommon
+ enough not to care, don't trust the `ibcs' flag here. In any case
+ there is no other ELF system currently supported by iBCS.
+ @@ Could print a warning message to encourage users to upgrade. */
+#define SET_PERSONALITY(ex,ibcs2) \
+ set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT))
+
+#endif
+
#endif
diff --git a/include/asm-arm/proc-armv/locks.h b/include/asm-arm/locks.h
index 13248f903677..435ed505feda 100644
--- a/include/asm-arm/proc-armv/locks.h
+++ b/include/asm-arm/locks.h
@@ -1,5 +1,5 @@
/*
- * linux/include/asm-arm/proc-armv/locks.h
+ * linux/include/asm-arm/locks.h
*
* Copyright (C) 2000 Russell King
*
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index 1b61a0e02c20..588c47d26338 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -15,6 +15,8 @@
#include <linux/config.h>
#include <asm/arch/memory.h>
+#ifndef __ASSEMBLY__
+
/*
* PFNs are used to describe any physical page; this means
* PFN 0 == physical address 0.
@@ -120,3 +122,5 @@ static inline void *phys_to_virt(unsigned long x)
#define page_to_bus(page) (virt_to_bus(page_address(page)))
#endif
+
+#endif
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index ca379e1f9184..94aeae2a4fb1 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -1,9 +1,27 @@
+/*
+ * linux/include/asm-arm/page.h
+ *
+ * Copyright (C) 1995-2003 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.
+ */
#ifndef _ASMARM_PAGE_H
#define _ASMARM_PAGE_H
#include <linux/config.h>
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
#ifdef __KERNEL__
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
#ifndef __ASSEMBLY__
#include <asm/glue.h>
@@ -119,10 +137,12 @@ extern void copy_page(void *to, void *from);
*/
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd[2]; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte)
#define pmd_val(x) ((x).pmd)
+#define pgd_val(x) ((x).pgd[0])
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
@@ -135,10 +155,12 @@ typedef struct { unsigned long pgprot; } pgprot_t;
*/
typedef unsigned long pte_t;
typedef unsigned long pmd_t;
+typedef unsigned long pgd_t[2];
typedef unsigned long pgprot_t;
#define pte_val(x) (x)
#define pmd_val(x) (x)
+#define pgd_val(x) ((x)[0])
#define pgprot_val(x) (x)
#define __pte(x) (x)
@@ -146,19 +168,6 @@ typedef unsigned long pgprot_t;
#define __pgprot(x) (x)
#endif /* STRICT_MM_TYPECHECKS */
-#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
-#include <asm/proc/page.h>
-
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
/* Pure 2^n version of get_order */
static inline int get_order(unsigned long size)
diff --git a/include/asm-arm/param.h b/include/asm-arm/param.h
index 2bf8b1d793f6..c1ccdcbe2bd1 100644
--- a/include/asm-arm/param.h
+++ b/include/asm-arm/param.h
@@ -11,7 +11,6 @@
#define __ASM_PARAM_H
#include <asm/arch/param.h> /* for HZ */
-#include <asm/proc/page.h> /* for EXEC_PAGE_SIZE */
#ifndef __KERNEL_HZ
#define __KERNEL_HZ 100
@@ -25,6 +24,8 @@
# define HZ 100
#endif
+#define EXEC_PAGESIZE 4096
+
#ifndef NGROUPS
#define NGROUPS 32
#endif
diff --git a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h
index 81a7eccf2991..23eb321f4af2 100644
--- a/include/asm-arm/pgalloc.h
+++ b/include/asm-arm/pgalloc.h
@@ -11,7 +11,8 @@
#define _ASMARM_PGALLOC_H
#include <asm/processor.h>
-#include <asm/proc/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
/*
* Since we have only two-level page tables, these are trivial
@@ -28,4 +29,104 @@ extern void free_pgd_slow(pgd_t *pgd);
#define check_pgt_cache() do { } while (0)
+/*
+ * Allocate one PTE table.
+ *
+ * This actually allocates two hardware PTE tables, but we wrap this up
+ * into one table thus:
+ *
+ * +------------+
+ * | h/w pt 0 |
+ * +------------+
+ * | h/w pt 1 |
+ * +------------+
+ * | Linux pt 0 |
+ * +------------+
+ * | Linux pt 1 |
+ * +------------+
+ */
+static inline pte_t *
+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+{
+ pte_t *pte;
+
+ pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+ if (pte) {
+ clear_page(pte);
+ clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
+ pte += PTRS_PER_PTE;
+ }
+
+ return pte;
+}
+
+static inline struct page *
+pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ struct page *pte;
+
+ pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+ if (pte) {
+ void *page = page_address(pte);
+ clear_page(page);
+ clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
+ }
+
+ return pte;
+}
+
+/*
+ * Free one PTE table.
+ */
+static inline void pte_free_kernel(pte_t *pte)
+{
+ if (pte) {
+ pte -= PTRS_PER_PTE;
+ free_page((unsigned long)pte);
+ }
+}
+
+static inline void pte_free(struct page *pte)
+{
+ __free_page(pte);
+}
+
+/*
+ * Populate the pmdp entry with a pointer to the pte. This pmd is part
+ * of the mm address space.
+ *
+ * Ensure that we always set both PMD entries.
+ */
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
+{
+ unsigned long pte_ptr = (unsigned long)ptep;
+ unsigned long pmdval;
+
+ BUG_ON(mm != &init_mm);
+
+ /*
+ * The pmd must be loaded with the physical
+ * address of the PTE table
+ */
+ pte_ptr -= PTRS_PER_PTE * sizeof(void *);
+ pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ flush_pmd_entry(pmdp);
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
+{
+ unsigned long pmdval;
+
+ BUG_ON(mm == &init_mm);
+
+ pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ flush_pmd_entry(pmdp);
+}
+
#endif
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index e2ed74082ae1..473b238e6fbc 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -1,7 +1,7 @@
/*
* linux/include/asm-arm/pgtable.h
*
- * Copyright (C) 2000-2002 Russell King
+ * Copyright (C) 1995-2002 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
@@ -16,15 +16,24 @@
#include <asm/arch/vmalloc.h>
/*
+ * We pull a couple of tricks here:
+ * 1. We wrap the PMD into the PGD.
+ * 2. We lie about the size of the PTE and PGD.
+ * Even though we have 256 PTE entries and 4096 PGD entries, we tell
+ * Linux that we actually have 512 PTE entries and 2048 PGD entries.
+ * Each "Linux" PGD entry is made up of two hardware PGD entries, and
+ * each PTE table is actually two hardware PTE tables.
+ */
+#define PTRS_PER_PTE 512
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD 2048
+
+/*
* PMD_SHIFT determines the size of the area a second-level page table can map
* PGDIR_SHIFT determines what a third-level page table entry can map
*/
#define PMD_SHIFT 20
-#ifdef CONFIG_CPU_32
#define PGDIR_SHIFT 21
-#else
-#define PGDIR_SHIFT 20
-#endif
#define LIBRARY_TEXT_START 0x0c000000
@@ -47,6 +56,117 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ * - common
+ */
+#define PMD_TYPE_MASK (3 << 0)
+#define PMD_TYPE_FAULT (0 << 0)
+#define PMD_TYPE_TABLE (1 << 0)
+#define PMD_TYPE_SECT (2 << 0)
+#define PMD_BIT4 (1 << 4)
+#define PMD_DOMAIN(x) ((x) << 5)
+#define PMD_PROTECTION (1 << 9) /* v5 */
+/*
+ * - section
+ */
+#define PMD_SECT_BUFFERABLE (1 << 2)
+#define PMD_SECT_CACHEABLE (1 << 3)
+#define PMD_SECT_AP_WRITE (1 << 10)
+#define PMD_SECT_AP_READ (1 << 11)
+#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
+#define PMD_SECT_APX (1 << 15) /* v6 */
+#define PMD_SECT_S (1 << 16) /* v6 */
+#define PMD_SECT_nG (1 << 17) /* v6 */
+
+#define PMD_SECT_UNCACHED (0)
+#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
+#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+
+/*
+ * - coarse table (not used)
+ */
+
+/*
+ * + Level 2 descriptor (PTE)
+ * - common
+ */
+#define PTE_TYPE_MASK (3 << 0)
+#define PTE_TYPE_FAULT (0 << 0)
+#define PTE_TYPE_LARGE (1 << 0)
+#define PTE_TYPE_SMALL (2 << 0)
+#define PTE_TYPE_EXT (3 << 0) /* v5 */
+#define PTE_BUFFERABLE (1 << 2)
+#define PTE_CACHEABLE (1 << 3)
+
+/*
+ * - extended small page/tiny page
+ */
+#define PTE_EXT_AP_UNO_SRO (0 << 4)
+#define PTE_EXT_AP_UNO_SRW (1 << 4)
+#define PTE_EXT_AP_URO_SRW (2 << 4)
+#define PTE_EXT_AP_URW_SRW (3 << 4)
+#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
+
+/*
+ * - small page
+ */
+#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
+#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
+#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
+#define PTE_SMALL_AP_URW_SRW (0xff << 4)
+#define PTE_AP_READ PTE_SMALL_AP_URO_SRW
+#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW
+
+/*
+ * "Linux" PTE definitions.
+ *
+ * We keep two sets of PTEs - the hardware and the linux version.
+ * This allows greater flexibility in the way we map the Linux bits
+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
+ * bits.
+ *
+ * The PTE table pointer refers to the hardware entries; the "Linux"
+ * entries are stored 1024 bytes below.
+ */
+#define L_PTE_PRESENT (1 << 0)
+#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
+#define L_PTE_YOUNG (1 << 1)
+#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */
+#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */
+#define L_PTE_USER (1 << 4)
+#define L_PTE_WRITE (1 << 5)
+#define L_PTE_EXEC (1 << 6)
+#define L_PTE_DIRTY (1 << 7)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/domain.h>
+
+#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
+
+/*
+ * The following macros handle the cache and bufferable bits...
+ */
+#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
+#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
+
+#define PAGE_NONE __pgprot(_L_PTE_DEFAULT)
+#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
+#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_KERNEL __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE | L_PTE_EXEC)
+
+#define _PAGE_CHG_MASK (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)
+
+#endif /* __ASSEMBLY__ */
+
+/*
* The table below defines the page protection levels that we insert into our
* Linux page table version. These get translated into the best that the
* architecture can perform. Note that on most ARM hardware:
@@ -86,9 +206,82 @@ extern struct page *empty_zero_page;
#define pte_none(pte) (!pte_val(pte))
#define pte_clear(ptep) set_pte((ptep), __pte(0))
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
+#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
+#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
+#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+
+#define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
+#define pte_read(pte) (pte_val(pte) & L_PTE_USER)
+#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
+#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
+#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
+
+/*
+ * The following only works if pte_present() is not true.
+ */
+#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
+#define pte_to_pgoff(x) (pte_val(x) >> 2)
+#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
+
+#define PTE_FILE_MAX_BITS 30
+
+#define PTE_BIT_FUNC(fn,op) \
+static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+
+/*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/
+/*PTE_BIT_FUNC(mkread, |= L_PTE_USER);*/
+PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
+PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
+PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC);
+PTE_BIT_FUNC(mkexec, |= L_PTE_EXEC);
+PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
+PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
+PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
+PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
+
+/*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
+#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+
+#define set_pmd(pmdp,pmd) \
+ do { \
+ *pmdp = pmd; \
+ flush_pmd_entry(pmdp); \
+ } while (0)
+
+#define pmd_clear(pmdp) \
+ do { \
+ pmdp[0] = __pmd(0); \
+ pmdp[1] = __pmd(0); \
+ clean_pmd_entry(pmdp); \
+ } while (0)
+
+static inline pte_t *pmd_page_kernel(pmd_t pmd)
+{
+ unsigned long ptr;
+
+ ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
+ ptr += PTRS_PER_PTE * sizeof(void *);
+
+ return __va(ptr);
+}
+
+#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
/*
* Permanent address of a page. We never have highmem, so this is trivial.
@@ -129,8 +322,6 @@ extern struct page *empty_zero_page;
/* Find an entry in the third-level page table.. */
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-#include <asm/proc/pgtable.h>
-
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
@@ -164,6 +355,8 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
typedef pte_t *pte_addr_t;
+#define pgtable_cache_init() do { } while (0)
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM_PGTABLE_H */
diff --git a/include/asm-arm/proc-armo/assembler.h b/include/asm-arm/proc-armo/assembler.h
deleted file mode 100644
index 7f6bd57cba74..000000000000
--- a/include/asm-arm/proc-armo/assembler.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * linux/asm-arm/proc-armo/assembler.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file contains arm architecture specific defines
- * for the different processors
- */
-#define MODE_USR USR26_MODE
-#define MODE_FIQ FIQ26_MODE
-#define MODE_IRQ IRQ26_MODE
-#define MODE_SVC SVC26_MODE
-
-#define DEFAULT_FIQ MODE_FIQ
-
-#ifdef __STDC__
-#define LOADREGS(cond, base, reglist...)\
- ldm##cond base,reglist^
-
-#define RETINSTR(instr, regs...)\
- instr##s regs
-#else
-#define LOADREGS(cond, base, reglist...)\
- ldm/**/cond base,reglist^
-
-#define RETINSTR(instr, regs...)\
- instr/**/s regs
-#endif
-
-#define MODENOP\
- mov r0, r0
-
-#define MODE(savereg,tmpreg,mode) \
- mov savereg, pc; \
- bic tmpreg, savereg, $0x0c000003; \
- orr tmpreg, tmpreg, $mode; \
- teqp tmpreg, $0
-
-#define RESTOREMODE(savereg) \
- teqp savereg, $0
-
-#define SAVEIRQS(tmpreg)
-
-#define RESTOREIRQS(tmpreg)
-
-#define DISABLEIRQS(tmpreg)\
- teqp pc, $0x08000003
-
-#define ENABLEIRQS(tmpreg)\
- teqp pc, $0x00000003
-
-#define USERMODE(tmpreg)\
- teqp pc, $0x00000000;\
- mov r0, r0
-
-#define SVCMODE(tmpreg)\
- teqp pc, $0x00000003;\
- mov r0, r0
-
-
-/*
- * Save the current IRQ state and disable IRQs
- * Note that this macro assumes FIQs are enabled, and
- * that the processor is in SVC mode.
- */
- .macro save_and_disable_irqs, oldcpsr, temp
- mov \oldcpsr, pc
- orr \temp, \oldcpsr, #0x08000000
- teqp \temp, #0
- .endm
-
-/*
- * Restore interrupt state previously stored in
- * a register
- * ** Actually do nothing on Arc - hope that the caller uses a MOVS PC soon
- * after!
- */
- .macro restore_irqs, oldcpsr
- @ This be restore_irqs
- .endm
-
-/*
- * These two are used to save LR/restore PC over a user-based access.
- * The old 26-bit architecture requires that we do. On 32-bit
- * architecture, we can safely ignore this requirement.
- */
- .macro save_lr
- str lr, [sp, #-4]!
- .endm
-
- .macro restore_pc
- ldmfd sp!, {pc}^
- .endm
-
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
-
diff --git a/include/asm-arm/proc-armo/cache.h b/include/asm-arm/proc-armo/cache.h
deleted file mode 100644
index 47c8125fa719..000000000000
--- a/include/asm-arm/proc-armo/cache.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/cache.h
- *
- * Copyright (C) 1999-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.
- *
- * Cache handling for 26-bit ARM processors.
- */
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_range(vma,start,end) do { } while (0)
-#define flush_cache_page(vma,vmaddr) do { } while (0)
-
-#define invalidate_dcache_range(start,end) do { } while (0)
-#define clean_dcache_range(start,end) do { } while (0)
-#define flush_dcache_range(start,end) do { } while (0)
-#define flush_dcache_page(page) do { } while (0)
-#define clean_dcache_entry(_s) do { } while (0)
-#define clean_cache_entry(_start) do { } while (0)
-
-#define flush_icache_range(start,end) do { } while (0)
-#define flush_icache_page(vma,page) do { } while (0)
-
-/* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
-#define clean_cache_area(_start,_size) do { } while (0)
diff --git a/include/asm-arm/proc-armo/elf.h b/include/asm-arm/proc-armo/elf.h
deleted file mode 100644
index b5901f767c6d..000000000000
--- a/include/asm-arm/proc-armo/elf.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * ELF definitions for 26-bit CPUs
- */
-
-#define ELF_EXEC_PAGESIZE 32768
-
-#ifdef __KERNEL__
-
-/* We can only execute 26-bit code. */
-#define ELF_PROC_OK(x) \
- ((x)->e_flags & EF_ARM_APCS26)
-
-#define SET_PERSONALITY(ex,ibcs2) set_personality(PER_LINUX)
-
-#endif
diff --git a/include/asm-arm/proc-armo/locks.h b/include/asm-arm/proc-armo/locks.h
deleted file mode 100644
index 81b3bda2ed00..000000000000
--- a/include/asm-arm/proc-armo/locks.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/locks.h
- *
- * Copyright (C) 2000 Russell King
- * Fixes for 26 bit machines, (C) 2000 Dave Gilbert
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Interrupt safe locking assembler.
- */
-#ifndef __ASM_PROC_LOCKS_H
-#define __ASM_PROC_LOCKS_H
-
-/* Decrements by 1, fails if value < 0 */
-#define __down_op(ptr,fail) \
- ({ \
- __asm__ __volatile__ ( \
- "@ atomic down operation\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-" ldr lr, [%0]\n" \
-" and ip, ip, #0x0c000003\n" \
-" subs lr, lr, #1\n" \
-" str lr, [%0]\n" \
-" orrmi ip, ip, #0x80000000 @ set N\n" \
-" teqp ip, #0\n" \
-" movmi ip, %0\n" \
-" blmi " #fail \
- : \
- : "r" (ptr) \
- : "ip", "lr", "cc"); \
- })
-
-#define __down_op_ret(ptr,fail) \
- ({ \
- unsigned int result; \
- __asm__ __volatile__ ( \
-" @ down_op_ret\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-" ldr lr, [%1]\n" \
-" and ip, ip, #0x0c000003\n" \
-" subs lr, lr, #1\n" \
-" str lr, [%1]\n" \
-" orrmi ip, ip, #0x80000000 @ set N\n" \
-" teqp ip, #0\n" \
-" movmi ip, %1\n" \
-" movpl ip, #0\n" \
-" blmi " #fail "\n" \
-" mov %0, ip" \
- : "=&r" (result) \
- : "r" (ptr) \
- : "ip", "lr", "cc"); \
- result; \
- })
-
-#define __up_op(ptr,wake) \
- ({ \
- __asm__ __volatile__ ( \
- "@ up_op\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-" ldr lr, [%0]\n" \
-" and ip, ip, #0x0c000003\n" \
-" adds lr, lr, #1\n" \
-" str lr, [%0]\n" \
-" orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
-" teqp ip, #0\n" \
-" movmi ip, %0\n" \
-" blmi " #wake \
- : \
- : "r" (ptr) \
- : "ip", "lr", "cc"); \
- })
-
-/*
- * The value 0x01000000 supports up to 128 processors and
- * lots of processes. BIAS must be chosen such that sub'ing
- * BIAS once per CPU will result in the long remaining
- * negative.
- */
-#define RW_LOCK_BIAS 0x01000000
-#define RW_LOCK_BIAS_STR "0x01000000"
-
-/* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */
-#define __down_op_write(ptr,fail) \
- ({ \
- __asm__ __volatile__( \
- "@ down_op_write\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-" and ip, ip, #0x0c000003\n" \
-\
-" ldr lr, [%0]\n" \
-" subs lr, lr, %1\n" \
-" str lr, [%0]\n" \
-\
-" orreq ip, ip, #0x40000000 @ set Z \n"\
-" teqp ip, #0\n" \
-" movne ip, %0\n" \
-" blne " #fail \
- : \
- : "r" (ptr), "I" (RW_LOCK_BIAS) \
- : "ip", "lr", "cc"); \
- })
-
-/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
-#define __up_op_write(ptr,wake) \
- ({ \
- __asm__ __volatile__( \
- "@ up_op_read\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-\
-" ldr lr, [%0]\n" \
-" and ip, ip, #0x0c000003\n" \
-" adds lr, lr, %1\n" \
-" str lr, [%0]\n" \
-\
-" orrcs ip, ip, #0x20000000 @ set C\n" \
-" teqp ip, #0\n" \
-" movcs ip, %0\n" \
-" blcs " #wake \
- : \
- : "r" (ptr), "I" (RW_LOCK_BIAS) \
- : "ip", "lr", "cc"); \
- })
-
-#define __down_op_read(ptr,fail) \
- __down_op(ptr, fail)
-
-#define __up_op_read(ptr,wake) \
- ({ \
- __asm__ __volatile__( \
- "@ up_op_read\n" \
-" mov ip, pc\n" \
-" orr lr, ip, #0x08000000\n" \
-" teqp lr, #0\n" \
-\
-" ldr lr, [%0]\n" \
-" and ip, ip, #0x0c000003\n" \
-" adds lr, lr, %1\n" \
-" str lr, [%0]\n" \
-\
-" orreq ip, ip, #0x40000000 @ Set Z \n" \
-" teqp ip, #0\n" \
-" moveq ip, %0\n" \
-" bleq " #wake \
- : \
- : "r" (ptr), "I" (1) \
- : "ip", "lr", "cc"); \
- })
-
-#endif
diff --git a/include/asm-arm/proc-armo/page.h b/include/asm-arm/proc-armo/page.h
deleted file mode 100644
index d32a7af23b7a..000000000000
--- a/include/asm-arm/proc-armo/page.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/page.h
- *
- * Copyright (C) 1995-2002 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.
- */
-#ifndef __ASM_PROC_PAGE_H
-#define __ASM_PROC_PAGE_H
-
-#include <linux/config.h>
-
-/* PAGE_SHIFT determines the page size. This is configurable. */
-#if defined(CONFIG_PAGESIZE_16)
-#define PAGE_SHIFT 14 /* 16K */
-#else /* default */
-#define PAGE_SHIFT 15 /* 32K */
-#endif
-
-#define EXEC_PAGESIZE 32768
-
-#ifndef __ASSEMBLY__
-#ifdef STRICT_MM_TYPECHECKS
-
-typedef struct { unsigned long pgd; } pgd_t;
-
-#define pgd_val(x) ((x).pgd)
-
-#else
-
-typedef unsigned long pgd_t;
-
-#define pgd_val(x) (x)
-
-#endif
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_PROC_PAGE_H */
diff --git a/include/asm-arm/proc-armo/pgalloc.h b/include/asm-arm/proc-armo/pgalloc.h
deleted file mode 100644
index 7b9bf375abc7..000000000000
--- a/include/asm-arm/proc-armo/pgalloc.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/pgalloc.h
- *
- * Copyright (C) 2001-2002 Russell King
- *
- * Page table allocation/freeing primitives for 26-bit ARM processors.
- */
-
-#include <linux/slab.h>
-
-extern kmem_cache_t *pte_cache;
-
-static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
-{
- return kmem_cache_alloc(pte_cache, GFP_KERNEL);
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
- if (pte)
- kmem_cache_free(pte_cache, pte);
-}
-
-/*
- * Populate the pmdp entry with a pointer to the pte. This pmd is part
- * of the mm address space.
- *
- * If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
- * need to set stuff up correctly for it.
- */
-static inline void
-pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
-{
- set_pmd(pmdp, __mk_pmd(ptep, _PAGE_TABLE));
-}
-
-/*
- * We use the old 2.5.5-rmk1 hack for this.
- * This is not truly correct, but should be functional.
- */
-#define pte_alloc_one(mm,addr) ((struct page *)pte_alloc_one_kernel(mm,addr))
-#define pte_free(pte) pte_free_kernel((pte_t *)pte)
-#define pmd_populate(mm,pmdp,ptep) pmd_populate_kernel(mm,pmdp,(pte_t *)ptep)
diff --git a/include/asm-arm/proc-armo/pgtable.h b/include/asm-arm/proc-armo/pgtable.h
deleted file mode 100644
index 152504bc9888..000000000000
--- a/include/asm-arm/proc-armo/pgtable.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/pgtable.h
- *
- * Copyright (C) 1995-2002 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.
- *
- * 18-Oct-1997 RMK Now two-level (32x32)
- */
-#ifndef __ASM_PROC_PGTABLE_H
-#define __ASM_PROC_PGTABLE_H
-
-/*
- * entries per page directory level: they are two-level, so
- * we don't really have any PMD directory.
- */
-#define PTRS_PER_PTE 32
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 32
-
-/*
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_START 0x01a00000
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END 0x01c00000
-
-#define _PAGE_TABLE (0x01)
-
-#define pmd_bad(pmd) ((pmd_val(pmd) & 0xfc000002))
-#define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd))
-#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
-
-static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
-{
- unsigned long pte_ptr = (unsigned long)ptep;
- pmd_t pmd;
-
- pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
-
- return pmd;
-}
-
-static inline unsigned long pmd_page(pmd_t pmd)
-{
- return __phys_to_virt(pmd_val(pmd) & ~_PAGE_TABLE);
-}
-
-#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
-
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-#define _PAGE_PRESENT 0x01
-#define _PAGE_READONLY 0x02
-#define _PAGE_NOT_USER 0x04
-#define _PAGE_OLD 0x08
-#define _PAGE_CLEAN 0x10
-
-/* -- present -- -- !dirty -- --- !write --- ---- !user --- */
-#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY | _PAGE_NOT_USER)
-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_CLEAN )
-#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY )
-#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY )
-#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_NOT_USER)
-
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_OLD | _PAGE_CLEAN)
-
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-#define pte_read(pte) (!(pte_val(pte) & _PAGE_NOT_USER))
-#define pte_write(pte) (!(pte_val(pte) & _PAGE_READONLY))
-#define pte_exec(pte) (!(pte_val(pte) & _PAGE_NOT_USER))
-#define pte_dirty(pte) (!(pte_val(pte) & _PAGE_CLEAN))
-#define pte_young(pte) (!(pte_val(pte) & _PAGE_OLD))
-
-static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_READONLY; return pte; }
-static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; }
-static inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; }
-static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) |= _PAGE_CLEAN; return pte; }
-static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) |= _PAGE_OLD; return pte; }
-
-static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_READONLY; return pte; }
-static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; }
-static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) &= ~_PAGE_CLEAN; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) &= ~_PAGE_OLD; return pte; }
-
-/*
- * We don't store cache state bits in the page table here.
- */
-#define pgprot_noncached(prot) (prot)
-
-extern void pgtable_cache_init(void);
-
-#endif /* __ASM_PROC_PGTABLE_H */
diff --git a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h
deleted file mode 100644
index aba9dbaa61b7..000000000000
--- a/include/asm-arm/proc-armo/processor.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/processor.h
- *
- * Copyright (C) 1996 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Changelog:
- * 27-06-1996 RMK Created
- * 10-10-1996 RMK Brought up to date with SA110
- * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
- * 28-09-1996 RMK Moved start_thread into the processor dependencies
- * 11-01-1998 RMK Added new uaccess_t
- * 09-09-1998 PJB Delete redundant `wp_works_ok'
- * 30-05-1999 PJB Save sl across context switches
- */
-#ifndef __ASM_PROC_PROCESSOR_H
-#define __ASM_PROC_PROCESSOR_H
-
-#include <linux/string.h>
-
-#define KERNEL_STACK_SIZE 4096
-
-typedef struct {
- void (*put_byte)(void); /* Special calling convention */
- void (*get_byte)(void); /* Special calling convention */
- void (*put_half)(void); /* Special calling convention */
- void (*get_half)(void); /* Special calling convention */
- void (*put_word)(void); /* Special calling convention */
- void (*get_word)(void); /* Special calling convention */
- unsigned long (*copy_from_user)(void *to, const void *from, unsigned long sz);
- unsigned long (*copy_to_user)(void *to, const void *from, unsigned long sz);
- unsigned long (*clear_user)(void *addr, unsigned long sz);
- unsigned long (*strncpy_from_user)(char *to, const char *from, unsigned long sz);
- unsigned long (*strnlen_user)(const char *s, long n);
-} uaccess_t;
-
-extern uaccess_t uaccess_user, uaccess_kernel;
-
-#define EXTRA_THREAD_STRUCT \
- uaccess_t *uaccess; /* User access functions*/
-
-#define EXTRA_THREAD_STRUCT_INIT \
- .uaccess = &uaccess_kernel,
-
-#define start_thread(regs,pc,sp) \
-({ \
- unsigned long *stack = (unsigned long *)sp; \
- set_fs(USER_DS); \
- memzero(regs->uregs, sizeof (regs->uregs)); \
- regs->ARM_pc = pc; /* pc */ \
- regs->ARM_sp = sp; /* sp */ \
- regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
- regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
- regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
-})
-
-#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
-#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1018])
-
-#endif
diff --git a/include/asm-arm/proc-armo/ptrace.h b/include/asm-arm/proc-armo/ptrace.h
deleted file mode 100644
index 79d44f4f71d8..000000000000
--- a/include/asm-arm/proc-armo/ptrace.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/ptrace.h
- *
- * Copyright (C) 1996-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.
- */
-#ifndef __ASM_PROC_PTRACE_H
-#define __ASM_PROC_PTRACE_H
-
-#define USR26_MODE 0x00000000
-#define FIQ26_MODE 0x00000001
-#define IRQ26_MODE 0x00000002
-#define SVC26_MODE 0x00000003
-#define USR_MODE USR26_MODE
-#define FIQ_MODE FIQ26_MODE
-#define IRQ_MODE IRQ26_MODE
-#define SVC_MODE SVC26_MODE
-#define MODE_MASK 0x00000003
-#define PSR_F_BIT 0x04000000
-#define PSR_I_BIT 0x08000000
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_N_BIT 0x80000000
-#define PCMASK 0xfc000003
-
-#ifndef __ASSEMBLY__
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct pt_regs {
- long uregs[17];
-};
-
-#define ARM_pc uregs[15]
-#define ARM_lr uregs[14]
-#define ARM_sp uregs[13]
-#define ARM_ip uregs[12]
-#define ARM_fp uregs[11]
-#define ARM_r10 uregs[10]
-#define ARM_r9 uregs[9]
-#define ARM_r8 uregs[8]
-#define ARM_r7 uregs[7]
-#define ARM_r6 uregs[6]
-#define ARM_r5 uregs[5]
-#define ARM_r4 uregs[4]
-#define ARM_r3 uregs[3]
-#define ARM_r2 uregs[2]
-#define ARM_r1 uregs[1]
-#define ARM_r0 uregs[0]
-#define ARM_ORIG_r0 uregs[16]
-
-#ifdef __KERNEL__
-
-#define processor_mode(regs) \
- ((regs)->ARM_pc & MODE_MASK)
-
-#define user_mode(regs) \
- (processor_mode(regs) == USR26_MODE)
-
-#define thumb_mode(regs) (0)
-
-#define interrupts_enabled(regs) \
- (!((regs)->ARM_pc & PSR_I_BIT))
-
-#define fast_interrupts_enabled(regs) \
- (!((regs)->ARM_pc & PSR_F_BIT))
-
-#define condition_codes(regs) \
- ((regs)->ARM_pc & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT))
-
-/* Are the current registers suitable for user mode?
- * (used to maintain security in signal handlers)
- */
-static inline int valid_user_regs(struct pt_regs *regs)
-{
- if (user_mode(regs) &&
- (regs->ARM_pc & (PSR_F_BIT | PSR_I_BIT)) == 0)
- return 1;
-
- /*
- * force it to be something sensible
- */
- regs->ARM_pc &= ~(MODE_MASK | PSR_F_BIT | PSR_I_BIT);
-
- return 0;
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#endif
-
diff --git a/include/asm-arm/proc-armo/shmparam.h b/include/asm-arm/proc-armo/shmparam.h
deleted file mode 100644
index 6b106f1419e8..000000000000
--- a/include/asm-arm/proc-armo/shmparam.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/shmparam.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * definitions for the shared process memory on the ARM3
- */
-#ifndef __ASM_PROC_SHMPARAM_H
-#define __ASM_PROC_SHMPARAM_H
-
-#ifndef SHMMAX
-#define SHMMAX 0x003fa000
-#endif
-
-#endif
diff --git a/include/asm-arm/proc-armo/system.h b/include/asm-arm/proc-armo/system.h
deleted file mode 100644
index 9e46e58f56e4..000000000000
--- a/include/asm-arm/proc-armo/system.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/system.h
- *
- * Copyright (C) 1995, 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_PROC_SYSTEM_H
-#define __ASM_PROC_SYSTEM_H
-
-#define vectors_base() (0)
-
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
-{
- extern void __bad_xchg(volatile void *, int);
-
- switch (size) {
- case 1: return cpu_xchg_1(x, ptr);
- case 4: return cpu_xchg_4(x, ptr);
- default: __bad_xchg(ptr, size);
- }
- return 0;
-}
-
-/*
- * We need to turn the caches off before calling the reset vector - RiscOS
- * messes up if we don't
- */
-#define proc_hard_reset() cpu_proc_fin()
-
-/*
- * A couple of speedups for the ARM
- */
-
-/*
- * Save the current interrupt enable state & disable IRQs
- */
-#define local_save_flags_cli(x) \
- do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ save_flags_cli\n" \
-" orr %1, %0, #0x08000000\n" \
-" and %0, %0, #0x0c000000\n" \
-" teqp %1, #0\n" \
- : "=r" (x), "=r" (temp) \
- : \
- : "memory"); \
- } while (0)
-
-/*
- * Enable IRQs
- */
-#define local_irq_enable() \
- do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ sti\n" \
-" bic %0, %0, #0x08000000\n" \
-" teqp %0, #0\n" \
- : "=r" (temp) \
- : \
- : "memory"); \
- } while(0)
-
-/*
- * Disable IRQs
- */
-#define local_irq_disable() \
- do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ cli\n" \
-" orr %0, %0, #0x08000000\n" \
-" teqp %0, #0\n" \
- : "=r" (temp) \
- : \
- : "memory"); \
- } while(0)
-
-#define __clf() do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ clf\n" \
-" orr %0, %0, #0x04000000\n" \
-" teqp %0, #0\n" \
- : "=r" (temp)); \
- } while(0)
-
-#define __stf() do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ stf\n" \
-" bic %0, %0, #0x04000000\n" \
-" teqp %0, #0\n" \
- : "=r" (temp)); \
- } while(0)
-
-/*
- * save current IRQ & FIQ state
- */
-#define local_save_flags(x) \
- do { \
- __asm__ __volatile__( \
-" mov %0, pc @ save_flags\n" \
-" and %0, %0, #0x0c000000\n" \
- : "=r" (x)); \
- } while (0)
-
-/*
- * restore saved IRQ & FIQ state
- */
-#define local_irq_restore(x) \
- do { \
- unsigned long temp; \
- __asm__ __volatile__( \
-" mov %0, pc @ restore_flags\n" \
-" bic %0, %0, #0x0c000000\n" \
-" orr %0, %0, %1\n" \
-" teqp %0, #0\n" \
- : "=&r" (temp) \
- : "r" (x) \
- : "memory"); \
- } while (0)
-
-#endif
diff --git a/include/asm-arm/proc-armo/tlbflush.h b/include/asm-arm/proc-armo/tlbflush.h
deleted file mode 100644
index f10e5b66b596..000000000000
--- a/include/asm-arm/proc-armo/tlbflush.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * TLB flushing:
- *
- * - flush_tlb_all() flushes all processes TLBs
- * - flush_tlb_mm(mm) flushes the specified mm context TLB's
- * - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_range(vma, start, end) flushes a range of pages
- */
-#define flush_tlb_all() memc_update_all()
-#define flush_tlb_mm(mm) memc_update_mm(mm)
-#define flush_tlb_range(vma,start,end) \
- do { memc_update_mm(vma->vm_mm); (void)(start); (void)(end); } while (0)
-#define flush_tlb_page(vma, vmaddr) do { } while (0)
-
-/*
- * The following handle the weird MEMC chip
- */
-static inline void memc_update_all(void)
-{
- struct task_struct *p;
-
- cpu_memc_update_all(init_mm.pgd);
- for_each_task(p) {
- if (!p->mm)
- continue;
- cpu_memc_update_all(p->mm->pgd);
- }
- processor._set_pgd(current->active_mm->pgd);
-}
-
-static inline void memc_update_mm(struct mm_struct *mm)
-{
- cpu_memc_update_all(mm->pgd);
-
- if (mm == current->active_mm)
- processor._set_pgd(mm->pgd);
-}
-
-static inline void
-memc_clear(struct mm_struct *mm, struct page *page)
-{
- cpu_memc_update_entry(mm->pgd, (unsigned long) page_address(page), 0);
-
- if (mm == current->active_mm)
- processor._set_pgd(mm->pgd);
-}
-
-static inline void
-memc_update_addr(struct mm_struct *mm, pte_t pte, unsigned long vaddr)
-{
- cpu_memc_update_entry(mm->pgd, pte_val(pte), vaddr);
-
- if (mm == current->active_mm)
- processor._set_pgd(mm->pgd);
-}
-
-static inline void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
-{
- struct mm_struct *mm = vma->vm_mm;
- memc_update_addr(mm, pte, addr);
-}
-
diff --git a/include/asm-arm/proc-armo/uaccess.h b/include/asm-arm/proc-armo/uaccess.h
deleted file mode 100644
index 77fcf9e482a5..000000000000
--- a/include/asm-arm/proc-armo/uaccess.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/segment.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*
- * The fs functions are implemented on the ARM2 and ARM3 architectures
- * manually.
- * Use *_user functions to access user memory with faulting behaving
- * as though the user is accessing the memory.
- * Use set_fs(get_ds()) and then the *_user functions to allow them to
- * access kernel memory.
- */
-
-/*
- * These are the values used to represent the user `fs' and the kernel `ds'
- */
-#define KERNEL_DS 0x03000000
-#define USER_DS 0x02000000
-
-extern uaccess_t uaccess_user, uaccess_kernel;
-
-static inline void set_fs (mm_segment_t fs)
-{
- current->addr_limit = fs;
- current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel;
-}
-
-#define __range_ok(addr,size) ({ \
- unsigned long flag, sum; \
- __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
- : "=&r" (flag), "=&r" (sum) \
- : "r" (addr), "Ir" (size), "0" (current->addr_limit) \
- : "cc"); \
- flag; })
-
-#define __addr_ok(addr) ({ \
- unsigned long flag; \
- __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \
- : "=&r" (flag) \
- : "0" (current->addr_limit), "r" (addr) \
- : "cc"); \
- (flag == 0); })
-
-#define __put_user_asm_byte(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %1\n" \
- " mov r1, %2\n" \
- " mov r2, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r2\n" \
- : "=r" (err) \
- : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \
- "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __put_user_asm_half(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %1\n" \
- " mov r1, %2\n" \
- " mov r2, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r2\n" \
- : "=r" (err) \
- : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \
- "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __put_user_asm_word(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %1\n" \
- " mov r1, %2\n" \
- " mov r2, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r2\n" \
- : "=r" (err) \
- : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \
- "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __get_user_asm_byte(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %2\n" \
- " mov r1, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r1\n" \
- " mov %1, r0\n" \
- : "=r" (err), "=r" (x) \
- : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __get_user_asm_half(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %2\n" \
- " mov r1, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r1\n" \
- " mov %1, r0\n" \
- : "=r" (err), "=r" (x) \
- : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __get_user_asm_word(x,addr,err) \
- __asm__ __volatile__( \
- " mov r0, %2\n" \
- " mov r1, %0\n" \
- " mov lr, pc\n" \
- " mov pc, %3\n" \
- " mov %0, r1\n" \
- " mov %1, r0\n" \
- : "=r" (err), "=r" (x) \
- : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \
- : "r0", "r1", "r2", "lr")
-
-#define __do_copy_from_user(to,from,n) \
- (n) = current->thread.uaccess->copy_from_user((to),(from),(n))
-
-#define __do_copy_to_user(to,from,n) \
- (n) = current->thread.uaccess->copy_to_user((to),(from),(n))
-
-#define __do_clear_user(addr,sz) \
- (sz) = current->thread.uaccess->clear_user((addr),(sz))
-
-#define __do_strncpy_from_user(dst,src,count,res) \
- (res) = current->thread.uaccess->strncpy_from_user(dst,src,count)
-
-#define __do_strnlen_user(s,n,res) \
- (res) = current->thread.uaccess->strnlen_user(s,n)
diff --git a/include/asm-arm/proc-armv/assembler.h b/include/asm-arm/proc-armv/assembler.h
deleted file mode 100644
index 64916c820b33..000000000000
--- a/include/asm-arm/proc-armv/assembler.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * linux/asm-arm/proc-armv/assembler.h
- *
- * Copyright (C) 1996-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file contains ARM processor specifics for
- * the ARM6 and better processors.
- */
-#define MODE_USR USR_MODE
-#define MODE_FIQ FIQ_MODE
-#define MODE_IRQ IRQ_MODE
-#define MODE_SVC SVC_MODE
-
-#define DEFAULT_FIQ MODE_FIQ
-
-/*
- * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
- */
-#ifdef __STDC__
-#define LOADREGS(cond, base, reglist...)\
- ldm##cond base,reglist
-#else
-#define LOADREGS(cond, base, reglist...)\
- ldm/**/cond base,reglist
-#endif
-
-/*
- * Build a return instruction for this processor type.
- */
-#define RETINSTR(instr, regs...)\
- instr regs
-
-/*
- * Save the current IRQ state and disable IRQs. Note that this macro
- * assumes FIQs are enabled, and that the processor is in SVC mode.
- */
- .macro save_and_disable_irqs, oldcpsr, temp
- mrs \oldcpsr, cpsr
- mov \temp, #PSR_I_BIT | MODE_SVC
- msr cpsr_c, \temp
- .endm
-
-/*
- * Restore interrupt state previously stored in a register. We don't
- * guarantee that this will preserve the flags.
- */
- .macro restore_irqs, oldcpsr
- msr cpsr_c, \oldcpsr
- .endm
-
-/*
- * These two are used to save LR/restore PC over a user-based access.
- * The old 26-bit architecture requires that we do. On 32-bit
- * architecture, we can safely ignore this requirement.
- */
- .macro save_lr
- .endm
-
- .macro restore_pc
- mov pc, lr
- .endm
-
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
-
diff --git a/include/asm-arm/proc-armv/cache.h b/include/asm-arm/proc-armv/cache.h
deleted file mode 100644
index 250a69e335ff..000000000000
--- a/include/asm-arm/proc-armv/cache.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/cache.h
- *
- * Copyright (C) 1999-2002 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.
- */
-#include <asm/mman.h>
-#include <asm/glue.h>
-
-/*
- * Cache Model
- * ===========
- */
-#undef _CACHE
-#undef MULTI_CACHE
-
-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM720T)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v4
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
- defined(CONFIG_CPU_ARM1020)
-# define MULTI_CACHE 1
-#endif
-
-#if defined(CONFIG_CPU_ARM926T)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE arm926
-# endif
-#endif
-
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v4wb
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSCALE)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE xscale
-# endif
-#endif
-
-#if !defined(_CACHE) && !defined(MULTI_CACHE)
-#error Unknown cache maintainence model
-#endif
-
-/*
- * This flag is used to indicate that the page pointed to by a pte
- * is dirty and requires cleaning before returning it to the user.
- */
-#define PG_dcache_dirty PG_arch_1
-
-/*
- * MM Cache Management
- * ===================
- *
- * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
- * implement these methods.
- *
- * Start addresses are inclusive and end addresses are exclusive;
- * start addresses should be rounded down, end addresses up.
- *
- * See linux/Documentation/cachetlb.txt for more information.
- * Please note that the implementation of these, and the required
- * effects are cache-type (VIVT/VIPT/PIPT) specific.
- *
- * flush_cache_kern_all()
- *
- * Unconditionally clean and invalidate the entire cache.
- *
- * flush_cache_user_mm(mm)
- *
- * Clean and invalidate all user space cache entries
- * before a change of page tables.
- *
- * flush_cache_user_range(start, end, flags)
- *
- * Clean and invalidate a range of cache entries in the
- * specified address space before a change of page tables.
- * - start - user start address (inclusive, page aligned)
- * - end - user end address (exclusive, page aligned)
- * - flags - vma->vm_flags field
- *
- * coherent_kern_range(start, end)
- *
- * Ensure coherency between the Icache and the Dcache in the
- * region described by start, end. If you have non-snooping
- * Harvard caches, you need to implement this function.
- * - start - virtual start address
- * - end - virtual end address
- *
- * DMA Cache Coherency
- * ===================
- *
- * dma_inv_range(start, end)
- *
- * Invalidate (discard) the specified virtual address range.
- * May not write back any entries. If 'start' or 'end'
- * are not cache line aligned, those lines must be written
- * back.
- * - start - virtual start address
- * - end - virtual end address
- *
- * dma_clean_range(start, end)
- *
- * Clean (write back) the specified virtual address range.
- * - start - virtual start address
- * - end - virtual end address
- *
- * dma_flush_range(start, end)
- *
- * Clean and invalidate the specified virtual address range.
- * - start - virtual start address
- * - end - virtual end address
- */
-
-struct cpu_cache_fns {
- void (*flush_kern_all)(void);
- void (*flush_user_all)(void);
- void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
-
- void (*coherent_kern_range)(unsigned long, unsigned long);
- void (*flush_kern_dcache_page)(void *);
-
- void (*dma_inv_range)(unsigned long, unsigned long);
- void (*dma_clean_range)(unsigned long, unsigned long);
- void (*dma_flush_range)(unsigned long, unsigned long);
-};
-
-/*
- * Select the calling method
- */
-#ifdef MULTI_CACHE
-
-extern struct cpu_cache_fns cpu_cache;
-
-#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
-#define __cpuc_flush_user_all cpu_cache.flush_user_all
-#define __cpuc_flush_user_range cpu_cache.flush_user_range
-#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
-#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page
-
-/*
- * These are private to the dma-mapping API. Do not use directly.
- * Their sole purpose is to ensure that data held in the cache
- * is visible to DMA, or data written by DMA to system memory is
- * visible to the CPU.
- */
-#define dmac_inv_range cpu_cache.dma_inv_range
-#define dmac_clean_range cpu_cache.dma_clean_range
-#define dmac_flush_range cpu_cache.dma_flush_range
-
-#else
-
-#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
-#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
-#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
-#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
-#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page)
-
-extern void __cpuc_flush_kern_all(void);
-extern void __cpuc_flush_user_all(void);
-extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
-extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
-extern void __cpuc_flush_dcache_page(void *);
-
-/*
- * These are private to the dma-mapping API. Do not use directly.
- * Their sole purpose is to ensure that data held in the cache
- * is visible to DMA, or data written by DMA to system memory is
- * visible to the CPU.
- */
-#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
-#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
-#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
-
-extern void dmac_inv_range(unsigned long, unsigned long);
-extern void dmac_clean_range(unsigned long, unsigned long);
-extern void dmac_flush_range(unsigned long, unsigned long);
-
-#endif
-
-/*
- * Convert calls to our calling convention.
- */
-#define flush_cache_all() __cpuc_flush_kern_all()
-
-static inline void flush_cache_mm(struct mm_struct *mm)
-{
- if (current->active_mm == mm)
- __cpuc_flush_user_all();
-}
-
-static inline void
-flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- if (current->active_mm == vma->vm_mm)
- __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
- vma->vm_flags);
-}
-
-static inline void
-flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr)
-{
- if (current->active_mm == vma->vm_mm) {
- unsigned long addr = user_addr & PAGE_MASK;
- __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
- }
-}
-
-/*
- * Perform necessary cache operations to ensure that data previously
- * stored within this range of addresses can be executed by the CPU.
- */
-#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
-
-/*
- * Perform necessary cache operations to ensure that the TLB will
- * see data written in the specified area.
- */
-#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
-
-/*
- * flush_dcache_page is used when the kernel has written to the page
- * cache page at virtual address page->virtual.
- *
- * If this page isn't mapped (ie, page->mapping = NULL), or it has
- * userspace mappings (page->mapping->i_mmap or page->mapping->i_mmap_shared)
- * then we _must_ always clean + invalidate the dcache entries associated
- * with the kernel mapping.
- *
- * Otherwise we can defer the operation, and clean the cache when we are
- * about to change to user space. This is the same method as used on SPARC64.
- * See update_mmu_cache for the user space part.
- */
-#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \
- !list_empty(&(map)->i_mmap_shared))
-
-extern void __flush_dcache_page(struct page *);
-
-static inline void flush_dcache_page(struct page *page)
-{
- if (page->mapping && !mapping_mapped(page->mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else
- __flush_dcache_page(page);
-}
-
-#define flush_icache_user_range(vma,page,addr,len) \
- flush_dcache_page(page)
-
-/*
- * We don't appear to need to do anything here. In fact, if we did, we'd
- * duplicate cache flushing elsewhere performed by flush_dcache_page().
- */
-#define flush_icache_page(vma,page) do { } while (0)
diff --git a/include/asm-arm/proc-armv/elf.h b/include/asm-arm/proc-armv/elf.h
deleted file mode 100644
index 1b8a0ac3b2b5..000000000000
--- a/include/asm-arm/proc-armv/elf.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * ELF definitions for 32-bit CPUs
- */
-
-#define ELF_EXEC_PAGESIZE 4096
-
-#ifdef __KERNEL__
-
-/*
- * 32-bit code is always OK. Some cpus can do 26-bit, some can't.
- */
-#define ELF_PROC_OK(x) (ELF_THUMB_OK(x) && ELF_26BIT_OK(x))
-
-#define ELF_THUMB_OK(x) \
- (( (elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 1) == 1) || \
- ((x)->e_entry & 3) == 0)
-
-#define ELF_26BIT_OK(x) \
- (( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \
- ((x)->e_flags & EF_ARM_APCS26) == 0)
-
-/* Old NetWinder binaries were compiled in such a way that the iBCS
- heuristic always trips on them. Until these binaries become uncommon
- enough not to care, don't trust the `ibcs' flag here. In any case
- there is no other ELF system currently supported by iBCS.
- @@ Could print a warning message to encourage users to upgrade. */
-#define SET_PERSONALITY(ex,ibcs2) \
- set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT))
-
-#endif
diff --git a/include/asm-arm/proc-armv/page.h b/include/asm-arm/proc-armv/page.h
deleted file mode 100644
index 726b16df7195..000000000000
--- a/include/asm-arm/proc-armv/page.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/page.h
- *
- * Copyright (C) 1995-2002 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.
- */
-#ifndef __ASM_PROC_PAGE_H
-#define __ASM_PROC_PAGE_H
-
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef __ASSEMBLY__
-#ifdef STRICT_MM_TYPECHECKS
-
-typedef struct {
- unsigned long pgd0;
- unsigned long pgd1;
-} pgd_t;
-
-#define pgd_val(x) ((x).pgd0)
-
-#else
-
-typedef unsigned long pgd_t[2];
-
-#define pgd_val(x) ((x)[0])
-
-#endif
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_PROC_PAGE_H */
diff --git a/include/asm-arm/proc-armv/pgalloc.h b/include/asm-arm/proc-armv/pgalloc.h
deleted file mode 100644
index 0e65ab7362e4..000000000000
--- a/include/asm-arm/proc-armv/pgalloc.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/pgalloc.h
- *
- * Copyright (C) 2001-2002 Russell King
- *
- * Page table allocation/freeing primitives for 32-bit ARM processors.
- */
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include "pgtable.h"
-
-/*
- * Allocate one PTE table.
- *
- * This actually allocates two hardware PTE tables, but we wrap this up
- * into one table thus:
- *
- * +------------+
- * | h/w pt 0 |
- * +------------+
- * | h/w pt 1 |
- * +------------+
- * | Linux pt 0 |
- * +------------+
- * | Linux pt 1 |
- * +------------+
- */
-static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
-{
- pte_t *pte;
-
- pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
- if (pte) {
- clear_page(pte);
- clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
- pte += PTRS_PER_PTE;
- }
-
- return pte;
-}
-
-static inline struct page *
-pte_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
- struct page *pte;
-
- pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
- if (pte) {
- void *page = page_address(pte);
- clear_page(page);
- clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
- }
-
- return pte;
-}
-
-/*
- * Free one PTE table.
- */
-static inline void pte_free_kernel(pte_t *pte)
-{
- if (pte) {
- pte -= PTRS_PER_PTE;
- free_page((unsigned long)pte);
- }
-}
-
-static inline void pte_free(struct page *pte)
-{
- __free_page(pte);
-}
-
-/*
- * Populate the pmdp entry with a pointer to the pte. This pmd is part
- * of the mm address space.
- *
- * Ensure that we always set both PMD entries.
- */
-static inline void
-pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
-{
- unsigned long pte_ptr = (unsigned long)ptep;
- unsigned long pmdval;
-
- BUG_ON(mm != &init_mm);
-
- /*
- * The pmd must be loaded with the physical
- * address of the PTE table
- */
- pte_ptr -= PTRS_PER_PTE * sizeof(void *);
- pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
- pmdp[0] = __pmd(pmdval);
- pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
- flush_pmd_entry(pmdp);
-}
-
-static inline void
-pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
-{
- unsigned long pmdval;
-
- BUG_ON(mm == &init_mm);
-
- pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
- pmdp[0] = __pmd(pmdval);
- pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
- flush_pmd_entry(pmdp);
-}
diff --git a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h
deleted file mode 100644
index 4b1cb65443ae..000000000000
--- a/include/asm-arm/proc-armv/pgtable.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/pgtable.h
- *
- * Copyright (C) 1995-2002 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.
- *
- * 12-Jan-1997 RMK Altered flushing routines to use function pointers
- * now possible to combine ARM6, ARM7 and StrongARM versions.
- * 17-Apr-1999 RMK Now pass an area size to clean_cache_area and
- * flush_icache_area.
- */
-#ifndef __ASM_PROC_PGTABLE_H
-#define __ASM_PROC_PGTABLE_H
-
-/*
- * We pull a couple of tricks here:
- * 1. We wrap the PMD into the PGD.
- * 2. We lie about the size of the PTE and PGD.
- * Even though we have 256 PTE entries and 4096 PGD entries, we tell
- * Linux that we actually have 512 PTE entries and 2048 PGD entries.
- * Each "Linux" PGD entry is made up of two hardware PGD entries, and
- * each PTE table is actually two hardware PTE tables.
- */
-#define PTRS_PER_PTE 512
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 2048
-
-/*
- * Hardware page table definitions.
- *
- * + Level 1 descriptor (PMD)
- * - common
- */
-#define PMD_TYPE_MASK (3 << 0)
-#define PMD_TYPE_FAULT (0 << 0)
-#define PMD_TYPE_TABLE (1 << 0)
-#define PMD_TYPE_SECT (2 << 0)
-#define PMD_BIT4 (1 << 4)
-#define PMD_DOMAIN(x) ((x) << 5)
-#define PMD_PROTECTION (1 << 9) /* v5 */
-/*
- * - section
- */
-#define PMD_SECT_BUFFERABLE (1 << 2)
-#define PMD_SECT_CACHEABLE (1 << 3)
-#define PMD_SECT_AP_WRITE (1 << 10)
-#define PMD_SECT_AP_READ (1 << 11)
-#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
-#define PMD_SECT_APX (1 << 15) /* v6 */
-#define PMD_SECT_S (1 << 16) /* v6 */
-#define PMD_SECT_nG (1 << 17) /* v6 */
-
-#define PMD_SECT_UNCACHED (0)
-#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
-#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
-#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
-#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-
-/*
- * - coarse table (not used)
- */
-
-/*
- * + Level 2 descriptor (PTE)
- * - common
- */
-#define PTE_TYPE_MASK (3 << 0)
-#define PTE_TYPE_FAULT (0 << 0)
-#define PTE_TYPE_LARGE (1 << 0)
-#define PTE_TYPE_SMALL (2 << 0)
-#define PTE_TYPE_EXT (3 << 0) /* v5 */
-#define PTE_BUFFERABLE (1 << 2)
-#define PTE_CACHEABLE (1 << 3)
-
-/*
- * - extended small page/tiny page
- */
-#define PTE_EXT_AP_UNO_SRO (0 << 4)
-#define PTE_EXT_AP_UNO_SRW (1 << 4)
-#define PTE_EXT_AP_URO_SRW (2 << 4)
-#define PTE_EXT_AP_URW_SRW (3 << 4)
-#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
-
-/*
- * - small page
- */
-#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
-#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
-#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
-#define PTE_SMALL_AP_URW_SRW (0xff << 4)
-#define PTE_AP_READ PTE_SMALL_AP_URO_SRW
-#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW
-
-/*
- * "Linux" PTE definitions.
- *
- * We keep two sets of PTEs - the hardware and the linux version.
- * This allows greater flexibility in the way we map the Linux bits
- * onto the hardware tables, and allows us to have YOUNG and DIRTY
- * bits.
- *
- * The PTE table pointer refers to the hardware entries; the "Linux"
- * entries are stored 1024 bytes below.
- */
-#define L_PTE_PRESENT (1 << 0)
-#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
-#define L_PTE_YOUNG (1 << 1)
-#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */
-#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */
-#define L_PTE_USER (1 << 4)
-#define L_PTE_WRITE (1 << 5)
-#define L_PTE_EXEC (1 << 6)
-#define L_PTE_DIRTY (1 << 7)
-
-#ifndef __ASSEMBLY__
-
-#include <asm/proc/domain.h>
-
-#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
-#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
-
-#define pmd_bad(pmd) (pmd_val(pmd) & 2)
-
-#define set_pmd(pmdp,pmd) \
- do { \
- *pmdp = pmd; \
- flush_pmd_entry(pmdp); \
- } while (0)
-
-#define pmd_clear(pmdp) \
- do { \
- pmdp[0] = __pmd(0); \
- pmdp[1] = __pmd(0); \
- clean_pmd_entry(pmdp); \
- } while (0)
-
-static inline pte_t *pmd_page_kernel(pmd_t pmd)
-{
- unsigned long ptr;
-
- ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
- ptr += PTRS_PER_PTE * sizeof(void *);
-
- return __va(ptr);
-}
-
-#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
-
-#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
-#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
-
-#define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
-
-/*
- * The following macros handle the cache and bufferable bits...
- */
-#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
-#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
-
-#define PAGE_NONE __pgprot(_L_PTE_DEFAULT)
-#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
-#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define PAGE_KERNEL __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE | L_PTE_EXEC)
-
-#define _PAGE_CHG_MASK (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)
-
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
-#define pte_read(pte) (pte_val(pte) & L_PTE_USER)
-#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
-#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
-#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
-#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
-#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
-
-#define PTE_BIT_FUNC(fn,op) \
-static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
-
-/*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/
-/*PTE_BIT_FUNC(mkread, |= L_PTE_USER);*/
-PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
-PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
-PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC);
-PTE_BIT_FUNC(mkexec, |= L_PTE_EXEC);
-PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
-PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
-PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
-PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
-
-/*
- * Mark the prot value as uncacheable and unbufferable.
- */
-#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
-#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
-
-#define pgtable_cache_init() do { } while (0)
-
-#define pte_to_pgoff(x) (pte_val(x) >> 2)
-#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
-
-#define PTE_FILE_MAX_BITS 30
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_PROC_PGTABLE_H */
diff --git a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h
deleted file mode 100644
index 373ca267700c..000000000000
--- a/include/asm-arm/proc-armv/processor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/processor.h
- *
- * Copyright (C) 1996-1999 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Changelog:
- * 20-09-1996 RMK Created
- * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
- * 28-09-1996 RMK Moved start_thread into the processor dependencies
- * 09-09-1998 PJB Delete redundant `wp_works_ok'
- * 30-05-1999 PJB Save sl across context switches
- * 31-07-1999 RMK Added 'domain' stuff
- */
-#ifndef __ASM_PROC_PROCESSOR_H
-#define __ASM_PROC_PROCESSOR_H
-
-#include <asm/proc/domain.h>
-
-#define KERNEL_STACK_SIZE PAGE_SIZE
-
-#define INIT_EXTRA_THREAD_INFO \
- .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
- domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
- domain_val(DOMAIN_IO, DOMAIN_CLIENT)
-
-#define start_thread(regs,pc,sp) \
-({ \
- unsigned long *stack = (unsigned long *)sp; \
- set_fs(USER_DS); \
- memzero(regs->uregs, sizeof(regs->uregs)); \
- if (current->personality & ADDR_LIMIT_32BIT) \
- regs->ARM_cpsr = USR_MODE; \
- else \
- regs->ARM_cpsr = USR26_MODE; \
- if (elf_hwcap & HWCAP_THUMB && pc & 1) \
- regs->ARM_cpsr |= PSR_T_BIT; \
- regs->ARM_pc = pc & ~1; /* pc */ \
- regs->ARM_sp = sp; /* sp */ \
- regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
- regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
- regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
-})
-
-#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
-#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017])
-
-#endif
diff --git a/include/asm-arm/proc-armv/ptrace.h b/include/asm-arm/proc-armv/ptrace.h
deleted file mode 100644
index d70d3724612a..000000000000
--- a/include/asm-arm/proc-armv/ptrace.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/ptrace.h
- *
- * Copyright (C) 1996-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_PROC_PTRACE_H
-#define __ASM_PROC_PTRACE_H
-
-#include <linux/config.h>
-
-/*
- * PSR bits
- */
-#define USR26_MODE 0x00000000
-#define FIQ26_MODE 0x00000001
-#define IRQ26_MODE 0x00000002
-#define SVC26_MODE 0x00000003
-#define USR_MODE 0x00000010
-#define FIQ_MODE 0x00000011
-#define IRQ_MODE 0x00000012
-#define SVC_MODE 0x00000013
-#define ABT_MODE 0x00000017
-#define UND_MODE 0x0000001b
-#define SYSTEM_MODE 0x0000001f
-#define MODE32_BIT 0x00000010
-#define MODE_MASK 0x0000001f
-#define PSR_T_BIT 0x00000020
-#define PSR_F_BIT 0x00000040
-#define PSR_I_BIT 0x00000080
-#define PSR_J_BIT 0x01000000
-#define PSR_Q_BIT 0x08000000
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_N_BIT 0x80000000
-#define PCMASK 0
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_s 0x00ff0000 /* Status */
-#define PSR_x 0x0000ff00 /* Extension */
-#define PSR_c 0x000000ff /* Control */
-
-/*
- * CR1 bits
- */
-#define CR1_M 0x00000001 /* MMU */
-#define CR1_A 0x00000002 /* Alignment fault */
-#define CR1_C 0x00000004 /* Dcache */
-#define CR1_W 0x00000008 /* Write buffer */
-#define CR1_P 0x00000010 /* Prog32 */
-#define CR1_D 0x00000020 /* Data32 */
-#define CR1_L 0x00000040 /* Late abort */
-#define CR1_B 0x00000080 /* Big endian */
-#define CR1_S 0x00000100 /* System protection */
-#define CR1_R 0x00000200 /* ROM protection */
-#define CR1_F 0x00000400
-#define CR1_Z 0x00000800 /* BTB enable */
-#define CR1_I 0x00001000 /* Icache */
-#define CR1_V 0x00002000 /* Vector relocation */
-#define CR1_RR 0x00004000 /* Round Robin */
-
-#ifndef __ASSEMBLY__
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct pt_regs {
- long uregs[18];
-};
-
-#define ARM_cpsr uregs[16]
-#define ARM_pc uregs[15]
-#define ARM_lr uregs[14]
-#define ARM_sp uregs[13]
-#define ARM_ip uregs[12]
-#define ARM_fp uregs[11]
-#define ARM_r10 uregs[10]
-#define ARM_r9 uregs[9]
-#define ARM_r8 uregs[8]
-#define ARM_r7 uregs[7]
-#define ARM_r6 uregs[6]
-#define ARM_r5 uregs[5]
-#define ARM_r4 uregs[4]
-#define ARM_r3 uregs[3]
-#define ARM_r2 uregs[2]
-#define ARM_r1 uregs[1]
-#define ARM_r0 uregs[0]
-#define ARM_ORIG_r0 uregs[17]
-
-#ifdef __KERNEL__
-
-#define user_mode(regs) \
- (((regs)->ARM_cpsr & 0xf) == 0)
-
-#ifdef CONFIG_ARM_THUMB
-#define thumb_mode(regs) \
- (((regs)->ARM_cpsr & PSR_T_BIT))
-#else
-#define thumb_mode(regs) (0)
-#endif
-
-#define processor_mode(regs) \
- ((regs)->ARM_cpsr & MODE_MASK)
-
-#define interrupts_enabled(regs) \
- (!((regs)->ARM_cpsr & PSR_I_BIT))
-
-#define fast_interrupts_enabled(regs) \
- (!((regs)->ARM_cpsr & PSR_F_BIT))
-
-#define condition_codes(regs) \
- ((regs)->ARM_cpsr & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT))
-
-/* Are the current registers suitable for user mode?
- * (used to maintain security in signal handlers)
- */
-static inline int valid_user_regs(struct pt_regs *regs)
-{
- if (user_mode(regs) &&
- (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0)
- return 1;
-
- /*
- * Force CPSR to something logical...
- */
- regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
-
- return 0;
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#endif
-
diff --git a/include/asm-arm/proc-armv/shmparam.h b/include/asm-arm/proc-armv/shmparam.h
deleted file mode 100644
index 5b692cc5b3e8..000000000000
--- a/include/asm-arm/proc-armv/shmparam.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/shmparam.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * definitions for the shared process memory on ARM v3 or v4
- * processors
- */
-#ifndef __ASM_PROC_SHMPARAM_H
-#define __ASM_PROC_SHMPARAM_H
-
-#ifndef SHMMAX
-#define SHMMAX 0x01000000
-#endif
-
-#endif
diff --git a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h
deleted file mode 100644
index 2179e2a175fe..000000000000
--- a/include/asm-arm/proc-armv/system.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/system.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_PROC_SYSTEM_H
-#define __ASM_PROC_SYSTEM_H
-
-#include <linux/config.h>
-
-#define set_cr(x) \
- __asm__ __volatile__( \
- "mcr p15, 0, %0, c1, c0, 0 @ set CR" \
- : : "r" (x) : "cc")
-
-#define get_cr() \
- ({ \
- unsigned int __val; \
- __asm__ __volatile__( \
- "mrc p15, 0, %0, c1, c0, 0 @ get CR" \
- : "=r" (__val) : : "cc"); \
- __val; \
- })
-
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_A (1 << 1) /* Alignment abort enable */
-#define CR_C (1 << 2) /* Dcache enable */
-#define CR_W (1 << 3) /* Write buffer enable */
-#define CR_P (1 << 4) /* 32-bit exception handler */
-#define CR_D (1 << 5) /* 32-bit data address range */
-#define CR_L (1 << 6) /* Implementation defined */
-#define CR_B (1 << 7) /* Big endian */
-#define CR_S (1 << 8) /* System MMU protection */
-#define CR_R (1 << 9) /* ROM MMU protection */
-#define CR_F (1 << 10) /* Implementation defined */
-#define CR_Z (1 << 11) /* Implementation defined */
-#define CR_I (1 << 12) /* Icache enable */
-#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
-#define CR_RR (1 << 14) /* Round Robin cache replacement */
-#define CR_L4 (1 << 15) /* LDR pc can set T bit */
-#define CR_DT (1 << 16)
-#define CR_IT (1 << 18)
-#define CR_ST (1 << 19)
-#define CR_FI (1 << 21)
-#define CR_U (1 << 22) /* Unaligned access operation */
-#define CR_XP (1 << 23) /* Extended page tables */
-#define CR_VE (1 << 24) /* Vectored interrupts */
-
-extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
-extern unsigned long cr_alignment; /* defined in entry-armv.S */
-
-#if __LINUX_ARM_ARCH__ >= 4
-#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0)
-#else
-#define vectors_base() (0)
-#endif
-
-/*
- * Save the current interrupt enable state & disable IRQs
- */
-#define local_irq_save(x) \
- ({ \
- unsigned long temp; \
- (void) (&temp == &x); \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_save\n" \
-" orr %1, %0, #128\n" \
-" msr cpsr_c, %1" \
- : "=r" (x), "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
-/*
- * Enable IRQs
- */
-#define local_irq_enable() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_enable\n" \
-" bic %0, %0, #128\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
-/*
- * Disable IRQs
- */
-#define local_irq_disable() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_irq_disable\n" \
-" orr %0, %0, #128\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
-/*
- * Enable FIQs
- */
-#define __stf() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ stf\n" \
-" bic %0, %0, #64\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
-/*
- * Disable FIQs
- */
-#define __clf() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ clf\n" \
-" orr %0, %0, #64\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory", "cc"); \
- })
-
-/*
- * Save the current interrupt enable state.
- */
-#define local_save_flags(x) \
- ({ \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ local_save_flags" \
- : "=r" (x) : : "memory", "cc"); \
- })
-
-/*
- * restore saved IRQ & FIQ state
- */
-#define local_irq_restore(x) \
- __asm__ __volatile__( \
- "msr cpsr_c, %0 @ local_irq_restore\n" \
- : \
- : "r" (x) \
- : "memory", "cc")
-
-#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
-/*
- * On the StrongARM, "swp" is terminally broken since it bypasses the
- * cache totally. This means that the cache becomes inconsistent, and,
- * since we use normal loads/stores as well, this is really bad.
- * Typically, this causes oopsen in filp_close, but could have other,
- * more disasterous effects. There are two work-arounds:
- * 1. Disable interrupts and emulate the atomic swap
- * 2. Clean the cache, perform atomic swap, flush the cache
- *
- * We choose (1) since its the "easiest" to achieve here and is not
- * dependent on the processor type.
- */
-#define swp_is_buggy
-#endif
-
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
-{
- extern void __bad_xchg(volatile void *, int);
- unsigned long ret;
-#ifdef swp_is_buggy
- unsigned long flags;
-#endif
-
- switch (size) {
-#ifdef swp_is_buggy
- case 1:
- local_irq_save(flags);
- ret = *(volatile unsigned char *)ptr;
- *(volatile unsigned char *)ptr = x;
- local_irq_restore(flags);
- break;
-
- case 4:
- local_irq_save(flags);
- ret = *(volatile unsigned long *)ptr;
- *(volatile unsigned long *)ptr = x;
- local_irq_restore(flags);
- break;
-#else
- case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]"
- : "=&r" (ret)
- : "r" (x), "r" (ptr)
- : "memory", "cc");
- break;
- case 4: __asm__ __volatile__ ("swp %0, %1, [%2]"
- : "=&r" (ret)
- : "r" (x), "r" (ptr)
- : "memory", "cc");
- break;
-#endif
- default: __bad_xchg(ptr, size), ret = 0;
- }
-
- return ret;
-}
-
-#endif
diff --git a/include/asm-arm/proc-armv/tlbflush.h b/include/asm-arm/proc-armv/tlbflush.h
deleted file mode 100644
index f51019309d59..000000000000
--- a/include/asm-arm/proc-armv/tlbflush.h
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/tlbflush.h
- *
- * Copyright (C) 1999-2003 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.
- */
-#include <linux/config.h>
-#include <asm/glue.h>
-
-#define TLB_V3_PAGE (1 << 0)
-#define TLB_V4_U_PAGE (1 << 1)
-#define TLB_V4_D_PAGE (1 << 2)
-#define TLB_V4_I_PAGE (1 << 3)
-#define TLB_V6_U_PAGE (1 << 4)
-#define TLB_V6_D_PAGE (1 << 5)
-#define TLB_V6_I_PAGE (1 << 6)
-
-#define TLB_V3_FULL (1 << 8)
-#define TLB_V4_U_FULL (1 << 9)
-#define TLB_V4_D_FULL (1 << 10)
-#define TLB_V4_I_FULL (1 << 11)
-#define TLB_V6_U_FULL (1 << 12)
-#define TLB_V6_D_FULL (1 << 13)
-#define TLB_V6_I_FULL (1 << 14)
-
-#define TLB_V6_U_ASID (1 << 16)
-#define TLB_V6_D_ASID (1 << 17)
-#define TLB_V6_I_ASID (1 << 18)
-
-#define TLB_DCLEAN (1 << 30)
-#define TLB_WB (1 << 31)
-
-/*
- * MMU TLB Model
- * =============
- *
- * We have the following to choose from:
- * v3 - ARMv3
- * v4 - ARMv4 without write buffer
- * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
- * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
- * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
- */
-#undef _TLB
-#undef MULTI_TLB
-
-#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
-
-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
-# define v3_possible_flags v3_tlb_flags
-# define v3_always_flags v3_tlb_flags
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v3
-# endif
-#else
-# define v3_possible_flags 0
-# define v3_always_flags (-1UL)
-#endif
-
-#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE)
-
-#if defined(CONFIG_CPU_ARM720T)
-# define v4_possible_flags v4_tlb_flags
-# define v4_always_flags v4_tlb_flags
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4
-# endif
-#else
-# define v4_possible_flags 0
-# define v4_always_flags (-1UL)
-#endif
-
-#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
- TLB_V4_I_FULL | TLB_V4_D_FULL | \
- TLB_V4_I_PAGE | TLB_V4_D_PAGE)
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
- defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
- defined(CONFIG_CPU_XSCALE)
-# define v4wbi_possible_flags v4wbi_tlb_flags
-# define v4wbi_always_flags v4wbi_tlb_flags
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4wbi
-# endif
-#else
-# define v4wbi_possible_flags 0
-# define v4wbi_always_flags (-1UL)
-#endif
-
-#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \
- TLB_V4_I_FULL | TLB_V4_D_FULL | \
- TLB_V4_D_PAGE)
-
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
-# define v4wb_possible_flags v4wb_tlb_flags
-# define v4wb_always_flags v4wb_tlb_flags
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4wb
-# endif
-#else
-# define v4wb_possible_flags 0
-# define v4wb_always_flags (-1UL)
-#endif
-
-#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
- TLB_V6_I_FULL | TLB_V6_D_FULL | \
- TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
- TLB_V6_I_ASID | TLB_V6_D_ASID)
-
-#if defined(CONFIG_CPU_V6)
-# define v6wbi_possible_flags v6wbi_tlb_flags
-# define v6wbi_always_flags v6wbi_tlb_flags
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v6wbi
-# endif
-#else
-# define v6wbi_possible_flags 0
-# define v6wbi_always_flags (-1UL)
-#endif
-
-#ifndef _TLB
-#error Unknown TLB model
-#endif
-
-#ifndef __ASSEMBLY__
-
-struct cpu_tlb_fns {
- void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
- void (*flush_kern_range)(unsigned long, unsigned long);
- unsigned long tlb_flags;
-};
-
-/*
- * Select the calling method
- */
-#ifdef MULTI_TLB
-
-#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range
-#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range
-
-#else
-
-#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range)
-#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range)
-
-extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
-extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
-
-#endif
-
-extern struct cpu_tlb_fns cpu_tlb;
-
-#define __cpu_tlb_flags cpu_tlb.tlb_flags
-
-/*
- * TLB Management
- * ==============
- *
- * The arch/arm/mm/tlb-*.S files implement these methods.
- *
- * The TLB specific code is expected to perform whatever tests it
- * needs to determine if it should invalidate the TLB for each
- * call. Start addresses are inclusive and end addresses are
- * exclusive; it is safe to round these addresses down.
- *
- * flush_tlb_all()
- *
- * Invalidate the entire TLB.
- *
- * flush_tlb_mm(mm)
- *
- * Invalidate all TLB entries in a particular address
- * space.
- * - mm - mm_struct describing address space
- *
- * flush_tlb_range(mm,start,end)
- *
- * Invalidate a range of TLB entries in the specified
- * address space.
- * - mm - mm_struct describing address space
- * - start - start address (may not be aligned)
- * - end - end address (exclusive, may not be aligned)
- *
- * flush_tlb_page(vaddr,vma)
- *
- * Invalidate the specified page in the specified address range.
- * - vaddr - virtual address (may not be aligned)
- * - vma - vma_struct describing address range
- *
- * flush_kern_tlb_page(kaddr)
- *
- * Invalidate the TLB entry for the specified page. The address
- * will be in the kernels virtual memory space. Current uses
- * only require the D-TLB to be invalidated.
- * - kaddr - Kernel virtual memory address
- */
-
-/*
- * We optimise the code below by:
- * - building a set of TLB flags that might be set in __cpu_tlb_flags
- * - building a set of TLB flags that will always be set in __cpu_tlb_flags
- * - if we're going to need __cpu_tlb_flags, access it once and only once
- *
- * This allows us to build optimal assembly for the single-CPU type case,
- * and as close to optimal given the compiler constrants for multi-CPU
- * case. We could do better for the multi-CPU case if the compiler
- * implemented the "%?" method, but this has been discontinued due to too
- * many people getting it wrong.
- */
-#define possible_tlb_flags (v3_possible_flags | \
- v4_possible_flags | \
- v4wbi_possible_flags | \
- v4wb_possible_flags | \
- v6wbi_possible_flags)
-
-#define always_tlb_flags (v3_always_flags & \
- v4_always_flags & \
- v4wbi_always_flags & \
- v4wb_always_flags & \
- v6wbi_always_flags)
-
-#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
-
-static inline void flush_tlb_all(void)
-{
- const int zero = 0;
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- if (tlb_flag(TLB_WB))
- asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-
- if (tlb_flag(TLB_V3_FULL))
- asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
- asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
- asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
- asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- const int zero = 0;
- const int asid = ASID(mm);
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- if (tlb_flag(TLB_WB))
- asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-
- if (mm == current->active_mm) {
- if (tlb_flag(TLB_V3_FULL))
- asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_U_FULL))
- asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_D_FULL))
- asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
- if (tlb_flag(TLB_V4_I_FULL))
- asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
- }
-
- if (tlb_flag(TLB_V6_U_ASID))
- asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid));
- if (tlb_flag(TLB_V6_D_ASID))
- asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid));
- if (tlb_flag(TLB_V6_I_ASID))
- asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid));
-}
-
-static inline void
-flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
-{
- const int zero = 0;
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
-
- if (tlb_flag(TLB_WB))
- asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-
- if (vma->vm_mm == current->active_mm) {
- if (tlb_flag(TLB_V3_PAGE))
- asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr));
- if (tlb_flag(TLB_V4_U_PAGE))
- asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
- if (tlb_flag(TLB_V4_D_PAGE))
- asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
- if (tlb_flag(TLB_V4_I_PAGE))
- asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
- if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
- asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
- }
-
- if (tlb_flag(TLB_V6_U_PAGE))
- asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
- if (tlb_flag(TLB_V6_D_PAGE))
- asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
- if (tlb_flag(TLB_V6_I_PAGE))
- asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
-}
-
-static inline void flush_tlb_kernel_page(unsigned long kaddr)
-{
- const int zero = 0;
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- kaddr &= PAGE_MASK;
-
- if (tlb_flag(TLB_WB))
- asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-
- if (tlb_flag(TLB_V3_PAGE))
- asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr));
- if (tlb_flag(TLB_V4_U_PAGE))
- asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
- if (tlb_flag(TLB_V4_D_PAGE))
- asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
- if (tlb_flag(TLB_V4_I_PAGE))
- asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
- if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
- asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
-
- if (tlb_flag(TLB_V6_U_PAGE))
- asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
- if (tlb_flag(TLB_V6_D_PAGE))
- asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
- if (tlb_flag(TLB_V6_I_PAGE))
- asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
-}
-
-/*
- * flush_pmd_entry
- *
- * Flush a PMD entry (word aligned, or double-word aligned) to
- * RAM if the TLB for the CPU we are running on requires this.
- * This is typically used when we are creating PMD entries.
- *
- * clean_pmd_entry
- *
- * Clean (but don't drain the write buffer) if the CPU requires
- * these operations. This is typically used when we are removing
- * PMD entries.
- */
-static inline void flush_pmd_entry(pmd_t *pmd)
-{
- const unsigned int zero = 0;
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- if (tlb_flag(TLB_DCLEAN))
- asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd"
- : : "r" (pmd));
- if (tlb_flag(TLB_WB))
- asm("mcr%? p15, 0, %0, c7, c10, 4 @ flush_pmd"
- : : "r" (zero));
-}
-
-static inline void clean_pmd_entry(pmd_t *pmd)
-{
- const unsigned int __tlb_flag = __cpu_tlb_flags;
-
- if (tlb_flag(TLB_DCLEAN))
- asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd"
- : : "r" (pmd));
-}
-
-#undef tlb_flag
-#undef always_tlb_flags
-#undef possible_tlb_flags
-
-/*
- * Convert calls to our calling convention.
- */
-#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
-
-/*
- * if PG_dcache_dirty is set for the page, we need to ensure that any
- * cache entries for the kernels virtual memory range are written
- * back to the page.
- */
-extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
-
-/*
- * ARM processors do not cache TLB tables in RAM.
- */
-#define flush_tlb_pgtables(mm,start,end) do { } while (0)
-
-/*
- * Old ARM MEMC stuff. This supports the reversed mapping handling that
- * we have on the older 26-bit machines. We don't have a MEMC chip, so...
- */
-#define memc_update_all() do { } while (0)
-#define memc_update_mm(mm) do { } while (0)
-#define memc_update_addr(mm,pte,log) do { } while (0)
-#define memc_clear(mm,physaddr) do { } while (0)
-
-#endif
diff --git a/include/asm-arm/proc-armv/uaccess.h b/include/asm-arm/proc-armv/uaccess.h
deleted file mode 100644
index b871c78160b1..000000000000
--- a/include/asm-arm/proc-armv/uaccess.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/uaccess.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <asm/arch/memory.h>
-#include <asm/proc/domain.h>
-
-/*
- * Note that this is actually 0x1,0000,0000
- */
-#define KERNEL_DS 0x00000000
-#define USER_DS TASK_SIZE
-
-static inline void set_fs (mm_segment_t fs)
-{
- current_thread_info()->addr_limit = fs;
- modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
-}
-
-/* We use 33-bit arithmetic here... */
-#define __range_ok(addr,size) ({ \
- unsigned long flag, sum; \
- __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
- : "=&r" (flag), "=&r" (sum) \
- : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
- : "cc"); \
- flag; })
-
-#define __addr_ok(addr) ({ \
- unsigned long flag; \
- __asm__("cmp %2, %0; movlo %0, #0" \
- : "=&r" (flag) \
- : "0" (current_thread_info()->addr_limit), "r" (addr) \
- : "cc"); \
- (flag == 0); })
-
-#define __put_user_asm_byte(x,__pu_addr,err) \
- __asm__ __volatile__( \
- "1: strbt %1,[%2],#0\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: mov %0, %3\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err) \
- : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
- : "cc")
-
-#ifndef __ARMEB__
-#define __put_user_asm_half(x,__pu_addr,err) \
-({ \
- unsigned long __temp = (unsigned long)(x); \
- __put_user_asm_byte(__temp, __pu_addr, err); \
- __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
-})
-#else
-#define __put_user_asm_half(x,__pu_addr,err) \
-({ \
- unsigned long __temp = (unsigned long)(x); \
- __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
- __put_user_asm_byte(__temp, __pu_addr + 1, err); \
-})
-#endif
-
-#define __put_user_asm_word(x,__pu_addr,err) \
- __asm__ __volatile__( \
- "1: strt %1,[%2],#0\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: mov %0, %3\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err) \
- : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
- : "cc")
-
-#ifndef __ARMEB__
-#define __reg_oper0 "%R2"
-#define __reg_oper1 "%Q2"
-#else
-#define __reg_oper0 "%Q2"
-#define __reg_oper1 "%R2"
-#endif
-
-#define __put_user_asm_dword(x,__pu_addr,err) \
- __asm__ __volatile__( \
- "1: strt " __reg_oper1 ", [%1], #4\n" \
- "2: strt " __reg_oper0 ", [%1], #0\n" \
- "3:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "4: mov %0, %3\n" \
- " b 3b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 4b\n" \
- " .long 2b, 4b\n" \
- " .previous" \
- : "+r" (err), "+r" (__pu_addr) \
- : "r" (x), "i" (-EFAULT) \
- : "cc")
-
-#define __get_user_asm_byte(x,addr,err) \
- __asm__ __volatile__( \
- "1: ldrbt %1,[%2],#0\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: mov %0, %3\n" \
- " mov %1, #0\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err), "=&r" (x) \
- : "r" (addr), "i" (-EFAULT) \
- : "cc")
-
-#ifndef __ARMEB__
-#define __get_user_asm_half(x,__gu_addr,err) \
-({ \
- unsigned long __b1, __b2; \
- __get_user_asm_byte(__b1, __gu_addr, err); \
- __get_user_asm_byte(__b2, __gu_addr + 1, err); \
- (x) = __b1 | (__b2 << 8); \
-})
-#else
-#define __get_user_asm_half(x,__gu_addr,err) \
-({ \
- unsigned long __b1, __b2; \
- __get_user_asm_byte(__b1, __gu_addr, err); \
- __get_user_asm_byte(__b2, __gu_addr + 1, err); \
- (x) = (__b1 << 8) | __b2; \
-})
-#endif
-
-#define __get_user_asm_word(x,addr,err) \
- __asm__ __volatile__( \
- "1: ldrt %1,[%2],#0\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: mov %0, %3\n" \
- " mov %1, #0\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err), "=&r" (x) \
- : "r" (addr), "i" (-EFAULT) \
- : "cc")
-
-extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
-#define __do_copy_from_user(to,from,n) \
- (n) = __arch_copy_from_user(to,from,n)
-
-extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n);
-#define __do_copy_to_user(to,from,n) \
- (n) = __arch_copy_to_user(to,from,n)
-
-extern unsigned long __arch_clear_user(void *addr, unsigned long n);
-#define __do_clear_user(addr,sz) \
- (sz) = __arch_clear_user(addr,sz)
-
-extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count);
-#define __do_strncpy_from_user(dst,src,count,res) \
- (res) = __arch_strncpy_from_user(dst,src,count)
-
-extern unsigned long __arch_strnlen_user(const char *s, long n);
-#define __do_strnlen_user(s,n,res) \
- (res) = __arch_strnlen_user(s,n)
diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h
index 5b6040fc3f74..9fcc8a89080c 100644
--- a/include/asm-arm/proc-fns.h
+++ b/include/asm-arm/proc-fns.h
@@ -21,11 +21,6 @@
#undef MULTI_CPU
#undef CPU_NAME
-#ifdef CONFIG_CPU_26
-# define CPU_INCLUDE_NAME "asm/cpu-multi26.h"
-# define MULTI_CPU
-#endif
-
/*
* CPU_NAME - the prefix for CPU related functions
*/
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 181223a7329b..31c888ba601c 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -1,7 +1,7 @@
/*
* linux/include/asm-arm/processor.h
*
- * Copyright (C) 1995 Russell King
+ * Copyright (C) 1995-1999 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -27,9 +27,10 @@
#include <asm/ptrace.h>
#include <asm/procinfo.h>
#include <asm/arch/memory.h>
-#include <asm/proc/processor.h>
#include <asm/types.h>
+#define KERNEL_STACK_SIZE PAGE_SIZE
+
union debug_insn {
u32 arm;
u16 thumb;
@@ -56,6 +57,24 @@ struct thread_struct {
#define INIT_THREAD { }
+#define start_thread(regs,pc,sp) \
+({ \
+ unsigned long *stack = (unsigned long *)sp; \
+ set_fs(USER_DS); \
+ memzero(regs->uregs, sizeof(regs->uregs)); \
+ if (current->personality & ADDR_LIMIT_32BIT) \
+ regs->ARM_cpsr = USR_MODE; \
+ else \
+ regs->ARM_cpsr = USR26_MODE; \
+ if (elf_hwcap & HWCAP_THUMB && pc & 1) \
+ regs->ARM_cpsr |= PSR_T_BIT; \
+ regs->ARM_pc = pc & ~1; /* pc */ \
+ regs->ARM_sp = sp; /* sp */ \
+ regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
+ regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
+ regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
+})
+
/* Forward declaration, a strange C thing */
struct task_struct;
@@ -74,6 +93,9 @@ unsigned long get_wchan(struct task_struct *p);
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
+#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017])
+
/*
* Prefetching support - only ARMv5.
*/
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
index eaf50e3bd63e..162c456638db 100644
--- a/include/asm-arm/ptrace.h
+++ b/include/asm-arm/ptrace.h
@@ -1,6 +1,17 @@
+/*
+ * linux/include/asm-arm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 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.
+ */
#ifndef __ASM_ARM_PTRACE_H
#define __ASM_ARM_PTRACE_H
+#include <linux/config.h>
+
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#define PTRACE_GETFPREGS 14
@@ -8,9 +19,112 @@
#define PTRACE_OLDSETOPTIONS 21
-#include <asm/proc/ptrace.h>
+/*
+ * PSR bits
+ */
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define ABT_MODE 0x00000017
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+#define PSR_T_BIT 0x00000020
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_J_BIT 0x01000000
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+#define PCMASK 0
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_s 0x00ff0000 /* Status */
+#define PSR_x 0x0000ff00 /* Extension */
+#define PSR_c 0x000000ff /* Control */
#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+ stack during a system call. */
+
+struct pt_regs {
+ long uregs[18];
+};
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+#ifdef __KERNEL__
+
+#define user_mode(regs) \
+ (((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+ (((regs)->ARM_cpsr & PSR_T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define processor_mode(regs) \
+ ((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_F_BIT))
+
+#define condition_codes(regs) \
+ ((regs)->ARM_cpsr & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+ if (user_mode(regs) &&
+ (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0)
+ return 1;
+
+ /*
+ * Force CPSR to something logical...
+ */
+ regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
+
+ return 0;
+}
+
+#endif /* __KERNEL__ */
+
#define pc_pointer(v) \
((v) & ~PCMASK)
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
index 34412c203747..76284ff21f49 100644
--- a/include/asm-arm/semaphore.h
+++ b/include/asm-arm/semaphore.h
@@ -10,7 +10,7 @@
#include <linux/rwsem.h>
#include <asm/atomic.h>
-#include <asm/proc/locks.h>
+#include <asm/locks.h>
struct semaphore {
atomic_t count;
@@ -88,7 +88,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__down_op(sem, __down_failed);
}
@@ -101,7 +101,7 @@ static inline int down_interruptible (struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
return __down_op_ret(sem, __down_interruptible_failed);
}
diff --git a/include/asm-arm/shmparam.h b/include/asm-arm/shmparam.h
index 4359852cc1ac..46d9944a7a14 100644
--- a/include/asm-arm/shmparam.h
+++ b/include/asm-arm/shmparam.h
@@ -1,8 +1,6 @@
#ifndef _ASMARM_SHMPARAM_H
#define _ASMARM_SHMPARAM_H
-#include <asm/proc/shmparam.h>
-
/*
* This should be the size of the virtually indexed cache/ways,
* or page size, whichever is greater since the cache aliases
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index d000f45ed4e7..bb533f25fc7d 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -4,6 +4,45 @@
#ifdef __KERNEL__
#include <linux/config.h>
+
+#define CPU_ARCH_UNKNOWN 0
+#define CPU_ARCH_ARMv3 1
+#define CPU_ARCH_ARMv4 2
+#define CPU_ARCH_ARMv4T 3
+#define CPU_ARCH_ARMv5 4
+#define CPU_ARCH_ARMv5T 5
+#define CPU_ARCH_ARMv5TE 6
+#define CPU_ARCH_ARMv6 7
+
+/*
+ * CR1 bits (CP#15 CR1)
+ */
+#define CR_M (1 << 0) /* MMU enable */
+#define CR_A (1 << 1) /* Alignment abort enable */
+#define CR_C (1 << 2) /* Dcache enable */
+#define CR_W (1 << 3) /* Write buffer enable */
+#define CR_P (1 << 4) /* 32-bit exception handler */
+#define CR_D (1 << 5) /* 32-bit data address range */
+#define CR_L (1 << 6) /* Implementation defined */
+#define CR_B (1 << 7) /* Big endian */
+#define CR_S (1 << 8) /* System MMU protection */
+#define CR_R (1 << 9) /* ROM MMU protection */
+#define CR_F (1 << 10) /* Implementation defined */
+#define CR_Z (1 << 11) /* Implementation defined */
+#define CR_I (1 << 12) /* Icache enable */
+#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
+#define CR_RR (1 << 14) /* Round Robin cache replacement */
+#define CR_L4 (1 << 15) /* LDR pc can set T bit */
+#define CR_DT (1 << 16)
+#define CR_IT (1 << 18)
+#define CR_ST (1 << 19)
+#define CR_FI (1 << 21)
+#define CR_U (1 << 22) /* Unaligned access operation */
+#define CR_XP (1 << 23) /* Extended page tables */
+#define CR_VE (1 << 24) /* Vectored interrupts */
+
+#ifndef __ASSEMBLY__
+
#include <linux/kernel.h>
struct thread_info;
@@ -34,21 +73,30 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
extern asmlinkage void __backtrace(void);
-#define CPU_ARCH_UNKNOWN 0
-#define CPU_ARCH_ARMv3 1
-#define CPU_ARCH_ARMv4 2
-#define CPU_ARCH_ARMv4T 3
-#define CPU_ARCH_ARMv5 4
-#define CPU_ARCH_ARMv5T 5
-#define CPU_ARCH_ARMv5TE 6
-#define CPU_ARCH_ARMv6 7
-
extern int cpu_architecture(void);
-/*
- * Include processor dependent parts
- */
-#include <asm/proc/system.h>
+#define set_cr(x) \
+ __asm__ __volatile__( \
+ "mcr p15, 0, %0, c1, c0, 0 @ set CR" \
+ : : "r" (x) : "cc")
+
+#define get_cr() \
+ ({ \
+ unsigned int __val; \
+ __asm__ __volatile__( \
+ "mrc p15, 0, %0, c1, c0, 0 @ get CR" \
+ : "=r" (__val) : : "cc"); \
+ __val; \
+ })
+
+extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
+extern unsigned long cr_alignment; /* defined in entry-armv.S */
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0)
+#else
+#define vectors_base() (0)
+#endif
#define mb() __asm__ __volatile__ ("" : : : "memory")
#define rmb() mb()
@@ -75,6 +123,102 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info
mb(); \
} while (0)
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define local_irq_save(x) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &x); \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_save\n" \
+" orr %1, %0, #128\n" \
+" msr cpsr_c, %1" \
+ : "=r" (x), "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Enable IRQs
+ */
+#define local_irq_enable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_enable\n" \
+" bic %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Disable IRQs
+ */
+#define local_irq_disable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_disable\n" \
+" orr %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Enable FIQs
+ */
+#define __stf() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ stf\n" \
+" bic %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Disable FIQs
+ */
+#define __clf() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ clf\n" \
+" orr %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Save the current interrupt enable state.
+ */
+#define local_save_flags(x) \
+ ({ \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_save_flags" \
+ : "=r" (x) : : "memory", "cc"); \
+ })
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define local_irq_restore(x) \
+ __asm__ __volatile__( \
+ "msr cpsr_c, %0 @ local_irq_restore\n" \
+ : \
+ : "r" (x) \
+ : "memory", "cc")
+
#ifdef CONFIG_SMP
#error SMP not supported
@@ -100,8 +244,67 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info
flags & PSR_I_BIT; \
})
+#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
+/*
+ * On the StrongARM, "swp" is terminally broken since it bypasses the
+ * cache totally. This means that the cache becomes inconsistent, and,
+ * since we use normal loads/stores as well, this is really bad.
+ * Typically, this causes oopsen in filp_close, but could have other,
+ * more disasterous effects. There are two work-arounds:
+ * 1. Disable interrupts and emulate the atomic swap
+ * 2. Clean the cache, perform atomic swap, flush the cache
+ *
+ * We choose (1) since its the "easiest" to achieve here and is not
+ * dependent on the processor type.
+ */
+#define swp_is_buggy
+#endif
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
+{
+ extern void __bad_xchg(volatile void *, int);
+ unsigned long ret;
+#ifdef swp_is_buggy
+ unsigned long flags;
+#endif
+
+ switch (size) {
+#ifdef swp_is_buggy
+ case 1:
+ local_irq_save(flags);
+ ret = *(volatile unsigned char *)ptr;
+ *(volatile unsigned char *)ptr = x;
+ local_irq_restore(flags);
+ break;
+
+ case 4:
+ local_irq_save(flags);
+ ret = *(volatile unsigned long *)ptr;
+ *(volatile unsigned long *)ptr = x;
+ local_irq_restore(flags);
+ break;
+#else
+ case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]"
+ : "=&r" (ret)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+ case 4: __asm__ __volatile__ ("swp %0, %1, [%2]"
+ : "=&r" (ret)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+#endif
+ default: __bad_xchg(ptr, size), ret = 0;
+ }
+
+ return ret;
+}
+
#endif /* CONFIG_SMP */
+#endif /* __ASSEMBLY__ */
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 60bec9ec8c79..642810a9ed84 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -18,9 +18,9 @@ struct task_struct;
struct exec_domain;
#include <asm/fpstate.h>
-#include <asm/proc/processor.h>
#include <asm/ptrace.h>
#include <asm/types.h>
+#include <asm/domain.h>
typedef unsigned long mm_segment_t;
@@ -55,17 +55,19 @@ struct thread_info {
union fp_state fpstate;
};
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .exec_domain = &default_exec_domain, \
- .flags = 0, \
- .preempt_count = 1, \
- .addr_limit = KERNEL_DS, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
- INIT_EXTRA_THREAD_INFO, \
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .preempt_count = 1, \
+ .addr_limit = KERNEL_DS, \
+ .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_IO, DOMAIN_CLIENT), \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
}
#define init_thread_info (init_thread_union.thread_info)
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 9011f00fca32..6fdcc6ffeb0c 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -1,7 +1,7 @@
/*
* linux/include/asm-arm/tlbflush.h
*
- * Copyright (C) 2000-2002 Russell King
+ * Copyright (C) 1999-2003 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
@@ -10,6 +10,397 @@
#ifndef _ASMARM_TLBFLUSH_H
#define _ASMARM_TLBFLUSH_H
-#include <asm-arm/proc/tlbflush.h>
+#include <linux/config.h>
+#include <asm/glue.h>
+
+#define TLB_V3_PAGE (1 << 0)
+#define TLB_V4_U_PAGE (1 << 1)
+#define TLB_V4_D_PAGE (1 << 2)
+#define TLB_V4_I_PAGE (1 << 3)
+#define TLB_V6_U_PAGE (1 << 4)
+#define TLB_V6_D_PAGE (1 << 5)
+#define TLB_V6_I_PAGE (1 << 6)
+
+#define TLB_V3_FULL (1 << 8)
+#define TLB_V4_U_FULL (1 << 9)
+#define TLB_V4_D_FULL (1 << 10)
+#define TLB_V4_I_FULL (1 << 11)
+#define TLB_V6_U_FULL (1 << 12)
+#define TLB_V6_D_FULL (1 << 13)
+#define TLB_V6_I_FULL (1 << 14)
+
+#define TLB_V6_U_ASID (1 << 16)
+#define TLB_V6_D_ASID (1 << 17)
+#define TLB_V6_I_ASID (1 << 18)
+
+#define TLB_DCLEAN (1 << 30)
+#define TLB_WB (1 << 31)
+
+/*
+ * MMU TLB Model
+ * =============
+ *
+ * We have the following to choose from:
+ * v3 - ARMv3
+ * v4 - ARMv4 without write buffer
+ * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
+ * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
+ * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
+ */
+#undef _TLB
+#undef MULTI_TLB
+
+#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
+
+#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+# define v3_possible_flags v3_tlb_flags
+# define v3_always_flags v3_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v3
+# endif
+#else
+# define v3_possible_flags 0
+# define v3_always_flags (-1UL)
+#endif
+
+#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#if defined(CONFIG_CPU_ARM720T)
+# define v4_possible_flags v4_tlb_flags
+# define v4_always_flags v4_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4
+# endif
+#else
+# define v4_possible_flags 0
+# define v4_always_flags (-1UL)
+#endif
+
+#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
+ defined(CONFIG_CPU_XSCALE)
+# define v4wbi_possible_flags v4wbi_tlb_flags
+# define v4wbi_always_flags v4wbi_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wbi
+# endif
+#else
+# define v4wbi_possible_flags 0
+# define v4wbi_always_flags (-1UL)
+#endif
+
+#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_D_PAGE)
+
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+# define v4wb_possible_flags v4wb_tlb_flags
+# define v4wb_always_flags v4wb_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wb
+# endif
+#else
+# define v4wb_possible_flags 0
+# define v4wb_always_flags (-1UL)
+#endif
+
+#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
+ TLB_V6_I_FULL | TLB_V6_D_FULL | \
+ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
+ TLB_V6_I_ASID | TLB_V6_D_ASID)
+
+#if defined(CONFIG_CPU_V6)
+# define v6wbi_possible_flags v6wbi_tlb_flags
+# define v6wbi_always_flags v6wbi_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v6wbi
+# endif
+#else
+# define v6wbi_possible_flags 0
+# define v6wbi_always_flags (-1UL)
+#endif
+
+#ifndef _TLB
+#error Unknown TLB model
+#endif
+
+#ifndef __ASSEMBLY__
+
+struct cpu_tlb_fns {
+ void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
+ void (*flush_kern_range)(unsigned long, unsigned long);
+ unsigned long tlb_flags;
+};
+
+/*
+ * Select the calling method
+ */
+#ifdef MULTI_TLB
+
+#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range
+#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range
+
+#else
+
+#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range)
+#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range)
+
+extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
+
+#endif
+
+extern struct cpu_tlb_fns cpu_tlb;
+
+#define __cpu_tlb_flags cpu_tlb.tlb_flags
+
+/*
+ * TLB Management
+ * ==============
+ *
+ * The arch/arm/mm/tlb-*.S files implement these methods.
+ *
+ * The TLB specific code is expected to perform whatever tests it
+ * needs to determine if it should invalidate the TLB for each
+ * call. Start addresses are inclusive and end addresses are
+ * exclusive; it is safe to round these addresses down.
+ *
+ * flush_tlb_all()
+ *
+ * Invalidate the entire TLB.
+ *
+ * flush_tlb_mm(mm)
+ *
+ * Invalidate all TLB entries in a particular address
+ * space.
+ * - mm - mm_struct describing address space
+ *
+ * flush_tlb_range(mm,start,end)
+ *
+ * Invalidate a range of TLB entries in the specified
+ * address space.
+ * - mm - mm_struct describing address space
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ *
+ * flush_tlb_page(vaddr,vma)
+ *
+ * Invalidate the specified page in the specified address range.
+ * - vaddr - virtual address (may not be aligned)
+ * - vma - vma_struct describing address range
+ *
+ * flush_kern_tlb_page(kaddr)
+ *
+ * Invalidate the TLB entry for the specified page. The address
+ * will be in the kernels virtual memory space. Current uses
+ * only require the D-TLB to be invalidated.
+ * - kaddr - Kernel virtual memory address
+ */
+
+/*
+ * We optimise the code below by:
+ * - building a set of TLB flags that might be set in __cpu_tlb_flags
+ * - building a set of TLB flags that will always be set in __cpu_tlb_flags
+ * - if we're going to need __cpu_tlb_flags, access it once and only once
+ *
+ * This allows us to build optimal assembly for the single-CPU type case,
+ * and as close to optimal given the compiler constrants for multi-CPU
+ * case. We could do better for the multi-CPU case if the compiler
+ * implemented the "%?" method, but this has been discontinued due to too
+ * many people getting it wrong.
+ */
+#define possible_tlb_flags (v3_possible_flags | \
+ v4_possible_flags | \
+ v4wbi_possible_flags | \
+ v4wb_possible_flags | \
+ v6wbi_possible_flags)
+
+#define always_tlb_flags (v3_always_flags & \
+ v4_always_flags & \
+ v4wbi_always_flags & \
+ v4wb_always_flags & \
+ v6wbi_always_flags)
+
+#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
+
+static inline void flush_tlb_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
+ asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
+ asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ const int zero = 0;
+ const int asid = ASID(mm);
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (mm == current->active_mm) {
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_U_FULL))
+ asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_D_FULL))
+ asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+ }
+
+ if (tlb_flag(TLB_V6_U_ASID))
+ asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid));
+ if (tlb_flag(TLB_V6_D_ASID))
+ asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid));
+ if (tlb_flag(TLB_V6_I_ASID))
+ asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid));
+}
+
+static inline void
+flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (vma->vm_mm == current->active_mm) {
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+ }
+
+ if (tlb_flag(TLB_V6_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V6_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V6_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+}
+
+static inline void flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ kaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+
+ if (tlb_flag(TLB_V6_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V6_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V6_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+}
+
+/*
+ * flush_pmd_entry
+ *
+ * Flush a PMD entry (word aligned, or double-word aligned) to
+ * RAM if the TLB for the CPU we are running on requires this.
+ * This is typically used when we are creating PMD entries.
+ *
+ * clean_pmd_entry
+ *
+ * Clean (but don't drain the write buffer) if the CPU requires
+ * these operations. This is typically used when we are removing
+ * PMD entries.
+ */
+static inline void flush_pmd_entry(pmd_t *pmd)
+{
+ const unsigned int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_DCLEAN))
+ asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd"
+ : : "r" (pmd));
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4 @ flush_pmd"
+ : : "r" (zero));
+}
+
+static inline void clean_pmd_entry(pmd_t *pmd)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_DCLEAN))
+ asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd"
+ : : "r" (pmd));
+}
+
+#undef tlb_flag
+#undef always_tlb_flags
+#undef possible_tlb_flags
+
+/*
+ * Convert calls to our calling convention.
+ */
+#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
+#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
+
+/*
+ * if PG_dcache_dirty is set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page.
+ */
+extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
+
+/*
+ * ARM processors do not cache TLB tables in RAM.
+ */
+#define flush_tlb_pgtables(mm,start,end) do { } while (0)
+
+#endif
#endif
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index 23bf0cbc1c76..634980801347 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -1,3 +1,10 @@
+/*
+ * linux/include/asm-arm/uaccess.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
#ifndef _ASMARM_UACCESS_H
#define _ASMARM_UACCESS_H
@@ -6,6 +13,8 @@
*/
#include <linux/sched.h>
#include <asm/errno.h>
+#include <asm/arch/memory.h>
+#include <asm/domain.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
@@ -30,11 +39,39 @@ struct exception_table_entry
extern int fixup_exception(struct pt_regs *regs);
+/*
+ * Note that this is actually 0x1,0000,0000
+ */
+#define KERNEL_DS 0x00000000
+#define USER_DS TASK_SIZE
+
#define get_ds() (KERNEL_DS)
#define get_fs() (current_thread_info()->addr_limit)
+
+static inline void set_fs (mm_segment_t fs)
+{
+ current_thread_info()->addr_limit = fs;
+ modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
+}
+
#define segment_eq(a,b) ((a) == (b))
-#include <asm/proc/uaccess.h>
+#define __addr_ok(addr) ({ \
+ unsigned long flag; \
+ __asm__("cmp %2, %0; movlo %0, #0" \
+ : "=&r" (flag) \
+ : "0" (current_thread_info()->addr_limit), "r" (addr) \
+ : "cc"); \
+ (flag == 0); })
+
+/* We use 33-bit arithmetic here... */
+#define __range_ok(addr,size) ({ \
+ unsigned long flag, sum; \
+ __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
+ : "=&r" (flag), "=&r" (sum) \
+ : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
+ : "cc"); \
+ flag; })
#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
@@ -125,17 +162,71 @@ do { \
(x) = (__typeof__(*(ptr)))__gu_val; \
} while (0)
+#define __get_user_asm_byte(x,addr,err) \
+ __asm__ __volatile__( \
+ "1: ldrbt %1,[%2],#0\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " mov %1, #0\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "+r" (err), "=&r" (x) \
+ : "r" (addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __get_user_asm_half(x,__gu_addr,err) \
+({ \
+ unsigned long __b1, __b2; \
+ __get_user_asm_byte(__b1, __gu_addr, err); \
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
+ (x) = __b1 | (__b2 << 8); \
+})
+#else
+#define __get_user_asm_half(x,__gu_addr,err) \
+({ \
+ unsigned long __b1, __b2; \
+ __get_user_asm_byte(__b1, __gu_addr, err); \
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
+ (x) = (__b1 << 8) | __b2; \
+})
+#endif
+
+#define __get_user_asm_word(x,addr,err) \
+ __asm__ __volatile__( \
+ "1: ldrt %1,[%2],#0\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " mov %1, #0\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "+r" (err), "=&r" (x) \
+ : "r" (addr), "i" (-EFAULT) \
+ : "cc")
+
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...) \
+#define __put_user_x(__r1,__p,__e,__s) \
__asm__ __volatile__ ("bl __put_user_" #__s \
: "=&r" (__e) \
: "0" (__p), "r" (__r1) \
- : __i, "cc")
+ : "ip", "lr", "cc")
#define put_user(x,p) \
({ \
@@ -144,16 +235,16 @@ extern int __put_user_bad(void);
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \
case 1: \
- __put_user_x(__r1, __p, __e, 1, "ip", "lr"); \
+ __put_user_x(__r1, __p, __e, 1); \
break; \
case 2: \
- __put_user_x(__r1, __p, __e, 2, "ip", "lr"); \
+ __put_user_x(__r1, __p, __e, 2); \
break; \
case 4: \
- __put_user_x(__r1, __p, __e, 4, "ip", "lr"); \
+ __put_user_x(__r1, __p, __e, 4); \
break; \
case 8: \
- __put_user_x(__r1, __p, __e, 8, "ip", "lr"); \
+ __put_user_x(__r1, __p, __e, 8); \
break; \
default: __e = __put_user_bad(); break; \
} \
@@ -186,10 +277,93 @@ do { \
} \
} while (0)
+#define __put_user_asm_byte(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ "1: strbt %1,[%2],#0\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "+r" (err) \
+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __put_user_asm_half(x,__pu_addr,err) \
+({ \
+ unsigned long __temp = (unsigned long)(x); \
+ __put_user_asm_byte(__temp, __pu_addr, err); \
+ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
+})
+#else
+#define __put_user_asm_half(x,__pu_addr,err) \
+({ \
+ unsigned long __temp = (unsigned long)(x); \
+ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
+ __put_user_asm_byte(__temp, __pu_addr + 1, err); \
+})
+#endif
+
+#define __put_user_asm_word(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ "1: strt %1,[%2],#0\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "+r" (err) \
+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __reg_oper0 "%R2"
+#define __reg_oper1 "%Q2"
+#else
+#define __reg_oper0 "%Q2"
+#define __reg_oper1 "%R2"
+#endif
+
+#define __put_user_asm_dword(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ "1: strt " __reg_oper1 ", [%1], #4\n" \
+ "2: strt " __reg_oper0 ", [%1], #0\n" \
+ "3:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "4: mov %0, %3\n" \
+ " b 3b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 4b\n" \
+ " .long 2b, 4b\n" \
+ " .previous" \
+ : "+r" (err), "+r" (__pu_addr) \
+ : "r" (x), "i" (-EFAULT) \
+ : "cc")
+
+extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
+extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n);
+extern unsigned long __arch_clear_user(void *addr, unsigned long n);
+extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count);
+extern unsigned long __arch_strnlen_user(const char *s, long n);
+
static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
- __do_copy_from_user(to, from, n);
+ n = __arch_copy_from_user(to, from, n);
else /* security hole - plug it */
memzero(to, n);
return n;
@@ -197,49 +371,44 @@ static __inline__ unsigned long copy_from_user(void *to, const void *from, unsig
static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
{
- __do_copy_from_user(to, from, n);
- return n;
+ return __arch_copy_from_user(to, from, n);
}
static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
- __do_copy_to_user(to, from, n);
+ n = __arch_copy_to_user(to, from, n);
return n;
}
static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
{
- __do_copy_to_user(to, from, n);
- return n;
+ return __arch_copy_to_user(to, from, n);
}
static __inline__ unsigned long clear_user (void *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
- __do_clear_user(to, n);
+ n = __arch_clear_user(to, n);
return n;
}
static __inline__ unsigned long __clear_user (void *to, unsigned long n)
{
- __do_clear_user(to, n);
- return n;
+ return __arch_clear_user(to, n);
}
static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
- __do_strncpy_from_user(dst, src, count, res);
+ res = __arch_strncpy_from_user(dst, src, count);
return res;
}
static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
{
- long res;
- __do_strncpy_from_user(dst, src, count, res);
- return res;
+ return __arch_strncpy_from_user(dst, src, count);
}
#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
@@ -249,7 +418,7 @@ static inline long strnlen_user(const char *s, long n)
unsigned long res = 0;
if (__addr_ok(s))
- __do_strnlen_user(s, n, res);
+ res = __arch_strnlen_user(s, n);
return res;
}
diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
index a7d94526309d..49946274a67b 100644
--- a/include/asm-arm26/semaphore.h
+++ b/include/asm-arm26/semaphore.h
@@ -84,7 +84,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__down_op(sem, __down_failed);
}
@@ -97,7 +97,7 @@ static inline int down_interruptible (struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
return __down_op_ret(sem, __down_interruptible_failed);
}
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
index 011a3bdc9ca7..d0821f6cef7f 100644
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -79,6 +79,7 @@ extern inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
/* atomically decrement the semaphores count, and if its negative, we wait */
local_save_flags(flags);
@@ -104,6 +105,7 @@ extern inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
/* atomically decrement the semaphores count, and if its negative, we wait */
local_save_flags(flags);
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h
index 962f5eb32d16..62e6e9ce669e 100644
--- a/include/asm-h8300/semaphore.h
+++ b/include/asm-h8300/semaphore.h
@@ -90,6 +90,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
count = &(sem->count);
__asm__ __volatile__(
@@ -117,6 +118,7 @@ static inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
count = &(sem->count);
__asm__ __volatile__(
diff --git a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h
index 8890ea1fdb4e..ffc472ff5418 100644
--- a/include/asm-i386/hpet.h
+++ b/include/asm-i386/hpet.h
@@ -102,8 +102,7 @@ extern int is_hpet_capable(void);
extern int hpet_readl(unsigned long a);
extern void hpet_writel(unsigned long d, unsigned long a);
-#ifdef CONFIG_RTC
-#define CONFIG_HPET_EMULATE_RTC 1
+#ifdef CONFIG_HPET_EMULATE_RTC
extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec);
@@ -111,6 +110,6 @@ extern int hpet_set_periodic_freq(unsigned long freq);
extern int hpet_rtc_dropped_irq(void);
extern int hpet_rtc_timer_init(void);
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#endif /* CONFIG_RTC */
+#endif /* CONFIG_HPET_EMULATE_RTC */
#endif /* CONFIG_HPET_TIMER */
#endif /* _I386_HPET_H */
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index c4cc5c8168aa..03f548536d6b 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -58,6 +58,7 @@ struct termio {
#define N_HCI 15 /* Bluetooth HCI UART */
#ifdef __KERNEL__
+#include <linux/module.h>
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
index dd0eade35495..44165a637add 100644
--- a/include/asm-ia64/semaphore.h
+++ b/include/asm-ia64/semaphore.h
@@ -73,6 +73,7 @@ down (struct semaphore *sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
__down(sem);
}
@@ -89,6 +90,7 @@ down_interruptible (struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
ret = __down_interruptible(sem);
return ret;
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index 8581f361c52d..cc844ef36a83 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -89,7 +89,7 @@ extern inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__asm__ __volatile__(
"| atomic down operation\n\t"
"subql #1,%0@\n\t"
@@ -112,7 +112,7 @@ extern inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__asm__ __volatile__(
"| atomic interruptible down operation\n\t"
"subql #1,%1@\n\t"
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
index 4720a09e6191..f85d311bc2d8 100644
--- a/include/asm-m68knommu/semaphore.h
+++ b/include/asm-m68knommu/semaphore.h
@@ -88,7 +88,7 @@ extern inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__asm__ __volatile__(
"| atomic down operation\n\t"
"movel %0, %%a1\n\t"
@@ -108,7 +108,7 @@ extern inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
__asm__ __volatile__(
"| atomic down operation\n\t"
"movel %1, %%a1\n\t"
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
index 34fc00d60460..a867bb1014be 100644
--- a/include/asm-mips/semaphore.h
+++ b/include/asm-mips/semaphore.h
@@ -88,6 +88,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
__down(sem);
}
@@ -103,6 +104,7 @@ static inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
ret = __down_interruptible(sem);
return ret;
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index 80686a7ab250..f01554398f1a 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -84,7 +84,7 @@ extern __inline__ void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
spin_lock_irq(&sem->sentry);
if (sem->count > 0) {
sem->count--;
@@ -100,7 +100,7 @@ extern __inline__ int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
-
+ might_sleep();
spin_lock_irq(&sem->sentry);
if (sem->count > 0) {
sem->count--;
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
new file mode 100644
index 000000000000..ff6b72df2c10
--- /dev/null
+++ b/include/asm-ppc/ibm44x.h
@@ -0,0 +1,435 @@
+/*
+ * include/asm-ppc/ibm44x.h
+ *
+ * PPC44x definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_IBM44x_H__
+#define __ASM_IBM44x_H__
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Data structure defining board information maintained by the boot
+ * ROM on IBM's "Ebony" evaluation board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ *
+ * Ebony firmware stores MAC addresses in the F/W VPD area. The
+ * firmware must store the other dynamic values in NVRAM like on
+ * the previous 40x systems so they should be accessible if we
+ * really want them.
+ */
+typedef struct board_info {
+ unsigned char bi_enetaddr[2][6]; /* EMAC addresses */
+ unsigned int bi_opb_busfreq; /* OPB clock in Hz */
+ int bi_iic_fast[2]; /* Use fast i2c mode */
+} bd_t;
+#endif /* __ASSEMBLY__ */
+
+#ifndef NR_BOARD_IRQS
+#define NR_BOARD_IRQS 0
+#endif
+
+#define _IO_BASE isa_io_base
+#define _ISA_MEM_BASE isa_mem_base
+#define PCI_DRAM_OFFSET pci_dram_offset
+
+/* TLB entry offset/size used for pinning kernel lowmem */
+#define PPC44x_PIN_SHIFT 28
+#define PPC44x_PIN_SIZE (1 << PPC44x_PIN_SHIFT)
+
+/* Lowest TLB slot consumed by the default pinned TLBs */
+#define PPC44x_LOW_SLOT 62
+
+/*
+ * Standard 4GB "page" definitions
+ */
+#define PPC44x_IO_PAGE 0x0000000100000000ULL
+#define PPC44x_PCICFG_PAGE 0x0000000200000000ULL
+#define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE
+#define PPC44x_PCIMEM_PAGE 0x0000000300000000ULL
+
+/*
+ * 36-bit trap ranges
+ */
+#define PPC44x_IO_LO 0x40000000
+#define PPC44x_IO_HI 0x40001000
+#define PPC44x_PCICFG_LO 0x0ec00000
+#define PPC44x_PCICFG_HI 0x0ec7ffff
+#define PPC44x_PCIMEM_LO 0x80002000
+#define PPC44x_PCIMEM_HI 0xffffffff
+
+/*
+ * The "residual" board information structure the boot loader passes
+ * into the kernel.
+ */
+#ifndef __ASSEMBLY__
+
+/*
+ * SPRN definitions
+ */
+#define SPRN_CPC0_GPIO 0xe5/BEARLRL
+
+/*
+ * DCRN definitions
+ */
+
+#ifdef CONFIG_440GX
+/* SDRs */
+#define DCRN_SDR_CONFIG_ADDR 0xe
+#define DCRN_SDR_CONFIG_DATA 0xf
+#define DCRN_SDR_PFC0 0x4100
+#define DCRN_SDR_PFC1 0x4101
+#define DCRN_SDR_MFR 0x4300
+#define DCRN_SDR_MFR_TAH0 0x80000000 /* TAHOE0 Enable */
+#define DCRN_SDR_MFR_TAH1 0x40000000 /* TAHOE1 Enable */
+#define DCRN_SDR_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */
+#define DCRN_SDR_MFR_ECS 0x08000000 /* EMAC int clk */
+#define DCRN_SDR_MFR_T0TXFL 0x00080000
+#define DCRN_SDR_MFR_T0TXFH 0x00040000
+#define DCRN_SDR_MFR_T1TXFL 0x00020000
+#define DCRN_SDR_MFR_T1TXFH 0x00010000
+#define DCRN_SDR_MFR_E0TXFL 0x00008000
+#define DCRN_SDR_MFR_E0TXFH 0x00004000
+#define DCRN_SDR_MFR_E0RXFL 0x00002000
+#define DCRN_SDR_MFR_E0RXFH 0x00001000
+#define DCRN_SDR_MFR_E1TXFL 0x00000800
+#define DCRN_SDR_MFR_E1TXFH 0x00000400
+#define DCRN_SDR_MFR_E1RXFL 0x00000200
+#define DCRN_SDR_MFR_E1RXFH 0x00000100
+#define DCRN_SDR_MFR_E2TXFL 0x00000080
+#define DCRN_SDR_MFR_E2TXFH 0x00000040
+#define DCRN_SDR_MFR_E2RXFL 0x00000020
+#define DCRN_SDR_MFR_E2RXFH 0x00000010
+#define DCRN_SDR_MFR_E3TXFL 0x00000008
+#define DCRN_SDR_MFR_E3TXFH 0x00000004
+#define DCRN_SDR_MFR_E3RXFL 0x00000002
+#define DCRN_SDR_MFR_E3RXFH 0x00000001
+
+/* SDR read/write helper macros */
+#define SDR_READ(offset) ({\
+ mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
+ mfdcr(DCRN_SDR_CONFIG_DATA);})
+#define SDR_WRITE(offset, data) ({\
+ mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
+ mtdcr(DCRN_SDR_CONFIG_DATA,data);})
+#endif /* CONFIG_440GX */
+
+/* Base DCRNs */
+#define DCRN_DMA0_BASE 0x100
+#define DCRN_DMA1_BASE 0x108
+#define DCRN_DMA2_BASE 0x110
+#define DCRN_DMA3_BASE 0x118
+#define DCRN_DMASR_BASE 0x120
+#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */
+#define DCRN_MAL_BASE 0x180
+
+/* UIC */
+#define DCRN_UIC0_BASE 0xc0
+#define DCRN_UIC1_BASE 0xd0
+#define UIC0 DCRN_UIC0_BASE
+#define UIC1 DCRN_UIC1_BASE
+
+#define DCRN_UIC_SR(base) (base + 0x0)
+#define DCRN_UIC_ER(base) (base + 0x2)
+#define DCRN_UIC_CR(base) (base + 0x3)
+#define DCRN_UIC_PR(base) (base + 0x4)
+#define DCRN_UIC_TR(base) (base + 0x5)
+#define DCRN_UIC_MSR(base) (base + 0x6)
+#define DCRN_UIC_VR(base) (base + 0x7)
+#define DCRN_UIC_VCR(base) (base + 0x8)
+
+#define UIC0_UIC1NC 30 /* UIC1 non-critical interrupt */
+#define UIC0_UIC1CR 31 /* UIC1 critical interrupt */
+
+/* 440GP MAL DCRs */
+#define DCRN_MALCR(base) (base + 0x0) /* Configuration */
+#define DCRN_MALESR(base) (base + 0x1) /* Error Status */
+#define DCRN_MALIER(base) (base + 0x2) /* Interrupt Enable */
+#define DCRN_MALTXCASR(base) (base + 0x4) /* Tx Channel Active Set */
+#define DCRN_MALTXCARR(base) (base + 0x5) /* Tx Channel Active Reset */
+#define DCRN_MALTXEOBISR(base) (base + 0x6) /* Tx End of Buffer Interrupt Status */
+#define DCRN_MALTXDEIR(base) (base + 0x7) /* Tx Descriptor Error Interrupt */
+#define DCRN_MALRXCASR(base) (base + 0x10) /* Rx Channel Active Set */
+#define DCRN_MALRXCARR(base) (base + 0x11) /* Rx Channel Active Reset */
+#define DCRN_MALRXEOBISR(base) (base + 0x12) /* Rx End of Buffer Interrupt Status */
+#define DCRN_MALRXDEIR(base) (base + 0x13) /* Rx Descriptor Error Interrupt */
+#define DCRN_MALTXCTP0R(base) (base + 0x20) /* Channel Tx 0 Channel Table Pointer */
+#define DCRN_MALTXCTP1R(base) (base + 0x21) /* Channel Tx 1 Channel Table Pointer */
+#define DCRN_MALTXCTP2R(base) (base + 0x22) /* Channel Tx 2 Channel Table Pointer */
+#define DCRN_MALTXCTP3R(base) (base + 0x23) /* Channel Tx 3 Channel Table Pointer */
+#define DCRN_MALRXCTP0R(base) (base + 0x40) /* Channel Rx 0 Channel Table Pointer */
+#define DCRN_MALRXCTP1R(base) (base + 0x41) /* Channel Rx 1 Channel Table Pointer */
+#define DCRN_MALRCBS0(base) (base + 0x60) /* Channel Rx 0 Channel Buffer Size */
+#define DCRN_MALRCBS1(base) (base + 0x61) /* Channel Rx 1 Channel Buffer Size */
+
+/* Compatibility DCRN's */
+#define DCRN_MALRXCTP2R(base) ((base) + 0x42) /* Channel Rx 2 Channel Table Pointer */
+#define DCRN_MALRXCTP3R(base) ((base) + 0x43) /* Channel Rx 3 Channel Table Pointer */
+#define DCRN_MALTXCTP4R(base) ((base) + 0x24) /* Channel Tx 4 Channel Table Pointer */
+#define DCRN_MALTXCTP5R(base) ((base) + 0x25) /* Channel Tx 5 Channel Table Pointer */
+#define DCRN_MALTXCTP6R(base) ((base) + 0x26) /* Channel Tx 6 Channel Table Pointer */
+#define DCRN_MALTXCTP7R(base) ((base) + 0x27) /* Channel Tx 7 Channel Table Pointer */
+#define DCRN_MALRCBS2(base) ((base) + 0x62) /* Channel Rx 2 Channel Buffer Size */
+#define DCRN_MALRCBS3(base) ((base) + 0x63) /* Channel Rx 3 Channel Buffer Size */
+
+
+#define MALCR_MMSR 0x80000000 /* MAL Software reset */
+#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */
+#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */
+#define MALCR_PLBP_3 0x00C00000 /* highest */
+#define MALCR_GA 0x00200000 /* Guarded Active Bit */
+#define MALCR_OA 0x00100000 /* Ordered Active Bit */
+#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */
+#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */
+#define MALCR_PLBLT_2 0x00020000
+#define MALCR_PLBLT_3 0x00010000
+#define MALCR_PLBLT_4 0x00008000
+#ifdef CONFIG_440GP
+#define MALCR_PLBLT_DEFAULT 0x00330000 /* PLB Latency Timer default */
+#else
+#define MALCR_PLBLT_DEFAULT 0x00ff0000 /* PLB Latency Timer default */
+#endif
+#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */
+#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */
+#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */
+#define MALCR_LEA 0x00000002 /* Locked Error Active */
+#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */
+/* DCRN_MALESR */
+#define MALESR_EVB 0x80000000 /* Error Valid Bit */
+#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */
+#define MALESR_DE 0x00100000 /* Descriptor Error */
+#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */
+#define MALESR_OTE 0x00040000 /* OPB Timeout Error */
+#define MALESR_OSE 0x00020000 /* OPB Slave Error */
+#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */
+#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */
+#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */
+#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */
+#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */
+#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */
+/* DCRN_MALIER */
+#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */
+#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */
+#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */
+#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */
+#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */
+/* DCRN_MALTXEOBISR */
+#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */
+#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */
+
+/* 440GP PLB Arbiter DCRs */
+#define DCRN_PLB0_REVID 0x082 /* PLB Arbiter Revision ID */
+#define DCRN_PLB0_ACR 0x083 /* PLB Arbiter Control */
+#define DCRN_PLB0_BESR 0x084 /* PLB Error Status */
+#define DCRN_PLB0_BEARL 0x086 /* PLB Error Address Low */
+#define DCRN_PLB0_BEAR DCRN_PLB0_BEARL /* 40x compatibility */
+#define DCRN_PLB0_BEARH 0x087 /* PLB Error Address High */
+
+/* 440GP Clock, PM, chip control */
+#define DCRN_CPC0_SR 0x0b0
+#define DCRN_CPC0_ER 0x0b1
+#define DCRN_CPC0_FR 0x0b2
+#define DCRN_CPC0_SYS0 0x0e0
+#define DCRN_CPC0_SYS1 0x0e1
+#define DCRN_CPC0_CUST0 0x0e2
+#define DCRN_CPC0_CUST1 0x0e3
+#define DCRN_CPC0_STRP0 0x0e4
+#define DCRN_CPC0_STRP1 0x0e5
+#define DCRN_CPC0_STRP2 0x0e6
+#define DCRN_CPC0_STRP3 0x0e7
+#define DCRN_CPC0_GPIO 0x0e8
+#define DCRN_CPC0_PLB 0x0e9
+#define DCRN_CPC0_CR1 0x0ea
+#define DCRN_CPC0_CR0 0x0eb
+#define DCRN_CPC0_MIRQ0 0x0ec
+#define DCRN_CPC0_MIRQ1 0x0ed
+#define DCRN_CPC0_JTAGID 0x0ef
+
+/* 440GP DMA controller DCRs */
+#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) /* DMA Channel Control 0 */
+#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count 0 */
+#define DCRN_DMASAH0 (DCRN_DMA0_BASE + 0x2) /* DMA Src Addr High 0 */
+#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) /* DMA Src Addr Low 0 */
+#define DCRN_DMADAH0 (DCRN_DMA0_BASE + 0x4) /* DMA Dest Addr High 0 */
+#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x5) /* DMA Dest Addr Low 0 */
+#define DCRN_ASGH0 (DCRN_DMA0_BASE + 0x6) /* DMA SG Desc Addr High 0 */
+#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x7) /* DMA SG Desc Addr Low 0 */
+
+#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) /* DMA Channel Control 1 */
+#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count 1 */
+#define DCRN_DMASAH1 (DCRN_DMA1_BASE + 0x2) /* DMA Src Addr High 1 */
+#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Src Addr Low 1 */
+#define DCRN_DMADAH1 (DCRN_DMA1_BASE + 0x4) /* DMA Dest Addr High 1 */
+#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x5) /* DMA Dest Addr Low 1 */
+#define DCRN_ASGH1 (DCRN_DMA1_BASE + 0x6) /* DMA SG Desc Addr High 1 */
+#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x7) /* DMA SG Desc Addr Low 1 */
+
+#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control 2 */
+#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count 2 */
+#define DCRN_DMASAH2 (DCRN_DMA2_BASE + 0x2) /* DMA Src Addr High 2 */
+#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Src Addr Low 2 */
+#define DCRN_DMADAH2 (DCRN_DMA2_BASE + 0x4) /* DMA Dest Addr High 2 */
+#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x5) /* DMA Dest Addr Low 2 */
+#define DCRN_ASGH2 (DCRN_DMA2_BASE + 0x6) /* DMA SG Desc Addr High 2 */
+#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x7) /* DMA SG Desc Addr Low 2 */
+
+#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control 3 */
+#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count 3 */
+#define DCRN_DMASAH3 (DCRN_DMA3_BASE + 0x2) /* DMA Src Addr High 3 */
+#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Src Addr Low 3 */
+#define DCRN_DMADAH3 (DCRN_DMA3_BASE + 0x4) /* DMA Dest Addr High 3 */
+#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x5) /* DMA Dest Addr Low 3 */
+#define DCRN_ASGH3 (DCRN_DMA3_BASE + 0x6) /* DMA SG Desc Addr High 3 */
+#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x7) /* DMA SG Desc Addr Low 3 */
+
+#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */
+#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */
+#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */
+#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */
+
+/* 440GP DRAM controller DCRs */
+#define DCRN_SDRAM0_CFGADDR 0x010
+#define DCRN_SDRAM0_CFGDATA 0x011
+
+#define SDRAM0_B0CR 0x40
+#define SDRAM0_B1CR 0x44
+#define SDRAM0_B2CR 0x48
+#define SDRAM0_B3CR 0x4c
+
+#define SDRAM_CONFIG_BANK_ENABLE 0x00000001
+#define SDRAM_CONFIG_SIZE_MASK 0x000e0000
+#define SDRAM_CONFIG_BANK_SIZE(reg) ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17)
+#define SDRAM_CONFIG_SIZE_8M 0x00000001
+#define SDRAM_CONFIG_SIZE_16M 0x00000002
+#define SDRAM_CONFIG_SIZE_32M 0x00000003
+#define SDRAM_CONFIG_SIZE_64M 0x00000004
+#define SDRAM_CONFIG_SIZE_128M 0x00000005
+#define SDRAM_CONFIG_SIZE_256M 0x00000006
+#define SDRAM_CONFIG_SIZE_512M 0x00000007
+#define PPC44x_MEM_SIZE_8M 0x00800000
+#define PPC44x_MEM_SIZE_16M 0x01000000
+#define PPC44x_MEM_SIZE_32M 0x02000000
+#define PPC44x_MEM_SIZE_64M 0x04000000
+#define PPC44x_MEM_SIZE_128M 0x08000000
+#define PPC44x_MEM_SIZE_256M 0x10000000
+#define PPC44x_MEM_SIZE_512M 0x20000000
+
+/*
+ * PCI-X definitions
+ */
+#define PCIX0_REG_BASE 0x20ec80000ULL
+#define PCIX0_REG_SIZE 0x200
+
+#define PCIX0_VENDID 0x000
+#define PCIX0_DEVID 0x002
+#define PCIX0_COMMAND 0x004
+#define PCIX0_STATUS 0x006
+#define PCIX0_REVID 0x008
+#define PCIX0_CLS 0x009
+#define PCIX0_CACHELS 0x00c
+#define PCIX0_LATTIM 0x00d
+#define PCIX0_HDTYPE 0x00e
+#define PCIX0_BIST 0x00f
+#define PCIX0_BAR0L 0x010
+#define PCIX0_BAR0H 0x014
+#define PCIX0_BAR1 0x018
+#define PCIX0_BAR2L 0x01c
+#define PCIX0_BAR2H 0x020
+#define PCIX0_BAR3 0x024
+#define PCIX0_CISPTR 0x028
+#define PCIX0_SBSYSVID 0x02c
+#define PCIX0_SBSYSID 0x02e
+#define PCIX0_EROMBA 0x030
+#define PCIX0_CAP 0x034
+#define PCIX0_RES0 0x035
+#define PCIX0_RES1 0x036
+#define PCIX0_RES2 0x038
+#define PCIX0_INTLN 0x03c
+#define PCIX0_INTPN 0x03d
+#define PCIX0_MINGNT 0x03e
+#define PCIX0_MAXLTNCY 0x03f
+#define PCIX0_BRDGOPT1 0x040
+#define PCIX0_BRDGOPT2 0x044
+#define PCIX0_ERREN 0x050
+#define PCIX0_ERRSTS 0x054
+#define PCIX0_PLBBESR 0x058
+#define PCIX0_PLBBEARL 0x05c
+#define PCIX0_PLBBEARH 0x060
+#define PCIX0_POM0LAL 0x068
+#define PCIX0_POM0LAH 0x06c
+#define PCIX0_POM0SA 0x070
+#define PCIX0_POM0PCIAL 0x074
+#define PCIX0_POM0PCIAH 0x078
+#define PCIX0_POM1LAL 0x07c
+#define PCIX0_POM1LAH 0x080
+#define PCIX0_POM1SA 0x084
+#define PCIX0_POM1PCIAL 0x088
+#define PCIX0_POM1PCIAH 0x08c
+#define PCIX0_POM2SA 0x090
+#define PCIX0_PIM0SAL 0x098
+#define PCIX0_PIM0SA PCIX0_PIM0SAL
+#define PCIX0_PIM0LAL 0x09c
+#define PCIX0_PIM0LAH 0x0a0
+#define PCIX0_PIM1SA 0x0a4
+#define PCIX0_PIM1LAL 0x0a8
+#define PCIX0_PIM1LAH 0x0ac
+#define PCIX0_PIM2SAL 0x0b0
+#define PCIX0_PIM2SA PCIX0_PIM2SAL
+#define PCIX0_PIM2LAL 0x0b4
+#define PCIX0_PIM2LAH 0x0b8
+#define PCIX0_OMCAPID 0x0c0
+#define PCIX0_OMNIPTR 0x0c1
+#define PCIX0_OMMC 0x0c2
+#define PCIX0_OMMA 0x0c4
+#define PCIX0_OMMUA 0x0c8
+#define PCIX0_OMMDATA 0x0cc
+#define PCIX0_OMMEOI 0x0ce
+#define PCIX0_PMCAPID 0x0d0
+#define PCIX0_PMNIPTR 0x0d1
+#define PCIX0_PMC 0x0d2
+#define PCIX0_PMCSR 0x0d4
+#define PCIX0_PMCSRBSE 0x0d6
+#define PCIX0_PMDATA 0x0d7
+#define PCIX0_PMSCRR 0x0d8
+#define PCIX0_CAPID 0x0dc
+#define PCIX0_NIPTR 0x0dd
+#define PCIX0_CMD 0x0de
+#define PCIX0_STS 0x0e0
+#define PCIX0_IDR 0x0e4
+#define PCIX0_CID 0x0e8
+#define PCIX0_RID 0x0ec
+#define PCIX0_PIM0SAH 0x0f8
+#define PCIX0_PIM2SAH 0x0fc
+#define PCIX0_MSGIL 0x100
+#define PCIX0_MSGIH 0x104
+#define PCIX0_MSGOL 0x108
+#define PCIX0_MSGOH 0x10c
+#define PCIX0_IM 0x1f8
+
+#define IIC_OWN 0x55
+#define IIC_CLOCK 50
+
+#undef NR_UICS
+#define NR_UICS 2
+#define UIC_CASCADE_MASK 0x0003 /* bits 30 & 31 */
+
+#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i]
+
+#include <asm/ibm4xx.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_IBM44x_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
index 4884067dbcd9..c8da43c8512f 100644
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -122,7 +122,25 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
#define PCI_DRAM_OFFSET 0
#endif
+#elif CONFIG_44x
+
+#if defined(CONFIG_EBONY)
+#include <platforms/4xx/ebony.h>
+#endif
+
+#if defined(CONFIG_OCOTEA)
+#include <platforms/4xx/ocotea.h>
+#endif
#endif /* CONFIG_40x */
+
+#ifndef __ASSEMBLY__
+/*
+ * The "residual" board information structure the boot loader passes
+ * into the kernel.
+ */
+extern bd_t __res;
+#endif
+
#endif /* __ASM_IBM4XX_H__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index b67f27323f46..55e67291c3d2 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -4,9 +4,11 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/mm.h>
#include <asm/page.h>
#include <asm/byteorder.h>
+#include <asm/mmu.h>
#define SIO_CONFIG_RA 0x398
#define SIO_CONFIG_RD 0x399
@@ -22,7 +24,7 @@
#define PREP_ISA_MEM_BASE 0xc0000000
#define PREP_PCI_DRAM_OFFSET 0x80000000
-#if defined(CONFIG_40x)
+#if defined(CONFIG_4xx)
#include <asm/ibm4xx.h>
#elif defined(CONFIG_8xx)
#include <asm/mpc8xx.h>
@@ -197,14 +199,17 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
* Map in an area of physical address space, for accessing
* I/O devices etc.
*/
-extern void *__ioremap(unsigned long address, unsigned long size,
+extern void *__ioremap(phys_addr_t address, unsigned long size,
unsigned long flags);
-extern void *ioremap(unsigned long address, unsigned long size);
+extern void *ioremap(phys_addr_t address, unsigned long size);
+#ifdef CONFIG_44x
+extern void *ioremap64(unsigned long long address, unsigned long size);
+#endif
#define ioremap_nocache(addr, size) ioremap((addr), (size))
extern void iounmap(void *addr);
extern unsigned long iopa(unsigned long addr);
extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
-extern void io_block_mapping(unsigned long virt, unsigned long phys,
+extern void io_block_mapping(unsigned long virt, phys_addr_t phys,
unsigned int size, int flags);
/*
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index 6ca586ab8f4e..02b993f6c3c7 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -71,11 +71,11 @@ irq_canonicalize(int irq)
return (irq);
}
-#elif defined(CONFIG_440)
-#include <asm/ibm440.h>
+#elif defined(CONFIG_44x)
+#include <asm/ibm44x.h>
-#define NR_UIC_IRQS 64
-#define NR_IRQS (NR_UIC_IRQS + NR_BOARD_IRQS)
+#define NR_UIC_IRQS 32
+#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
static __inline__ int
irq_canonicalize(int irq)
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
index 7b729cdf52f4..b75b24e4c056 100644
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -10,6 +10,18 @@
#ifndef __ASSEMBLY__
+/*
+ * Define physical address type. Machines using split size
+ * virtual/physical addressing like 32-bit virtual / 36-bit
+ * physical need a larger than native word size type. -Matt
+ */
+#ifndef CONFIG_PTE_64BIT
+typedef unsigned long phys_addr_t;
+#else
+typedef unsigned long long phys_addr_t;
+extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t);
+#endif
+
/* Default "unsigned long" context */
typedef unsigned long mm_context_t;
@@ -320,5 +332,55 @@ typedef struct _P601_BAT {
#define TLB_M 0x00000002 /* Memory is coherent */
#define TLB_G 0x00000001 /* Memory is guarded from prefetch */
+/*
+ * PPC440 support
+ */
+#define PPC44x_MMUCR_TID 0x000000ff
+#define PPC44x_MMUCR_STS 0x00010000
+
+#define PPC44x_TLB_PAGEID 0
+#define PPC44x_TLB_XLAT 1
+#define PPC44x_TLB_ATTRIB 2
+
+/* Page identification fields */
+#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */
+#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */
+#define PPC44x_TLB_TS 0x00000100 /* Translation address space */
+#define PPC44x_TLB_PAGESZ_MASK 0x000000f0
+#define PPC44x_TLB_PAGESZ(x) (x << 4)
+#define PPC44x_PAGESZ_1K 0
+#define PPC44x_PAGESZ_4K 1
+#define PPC44x_PAGESZ_16K 2
+#define PPC44x_PAGESZ_64K 3
+#define PPC44x_PAGESZ_256K 4
+#define PPC44x_PAGESZ_1M 5
+#define PPC44x_PAGESZ_16M 7
+#define PPC44x_PAGESZ_256M 9
+
+/* Translation fields */
+#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */
+#define PPC44x_TLB_ERPN_MASK 0x0000000f
+
+/* Storage attribute and access control fields */
+#define PPC44x_TLB_ATTR_MASK 0x0000ff80
+#define PPC44x_TLB_U0 0x00008000 /* User 0 */
+#define PPC44x_TLB_U1 0x00004000 /* User 1 */
+#define PPC44x_TLB_U2 0x00002000 /* User 2 */
+#define PPC44x_TLB_U3 0x00001000 /* User 3 */
+#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */
+#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */
+#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */
+#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */
+#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */
+
+#define PPC44x_TLB_PERM_MASK 0x0000003f
+#define PPC44x_TLB_UX 0x00000020 /* User execution */
+#define PPC44x_TLB_UW 0x00000010 /* User write */
+#define PPC44x_TLB_UR 0x00000008 /* User read */
+#define PPC44x_TLB_SX 0x00000004 /* Super execution */
+#define PPC44x_TLB_SW 0x00000002 /* Super write */
+#define PPC44x_TLB_SR 0x00000001 /* Super read */
+
+
#endif /* _PPC_MMU_H_ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index b8f25854778d..6d2a8a40368f 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -4,7 +4,12 @@
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
+
+/*
+ * Subtle: this is an int (not an unsigned long) and so it
+ * gets extended to 64 bits the way want (i.e. with 1s). -- paulus
+ */
+#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
#ifdef __KERNEL__
#include <linux/config.h>
@@ -15,13 +20,27 @@
#ifndef __ASSEMBLY__
-#define STRICT_MM_TYPECHECKS
+/*
+ * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
+ * physical addressing. For now this just the IBM PPC440.
+ */
+#ifdef CONFIG_PTE_64BIT
+typedef unsigned long long pte_basic_t;
+#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
+#define PTE_FMT "%16Lx"
+#else
+typedef unsigned long pte_basic_t;
+#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
+#define PTE_FMT "%.8lx"
+#endif
+
+#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
-typedef struct { unsigned long pte; } pte_t;
+typedef struct { pte_basic_t pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
@@ -40,7 +59,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
/*
* .. while these make it easier on the compiler
*/
-typedef unsigned long pte_t;
+typedef pte_basic_t pte_t;
typedef unsigned long pmd_t;
typedef unsigned long pgd_t;
typedef unsigned long pgprot_t;
@@ -123,6 +142,7 @@ static inline void* ___va(unsigned long p)
#define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PPC_PGSTART)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
#define pfn_valid(pfn) (((pfn) - PPC_PGSTART) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/include/asm-ppc/pgalloc.h b/include/asm-ppc/pgalloc.h
index 7d5d0455cc00..faf91bc03022 100644
--- a/include/asm-ppc/pgalloc.h
+++ b/include/asm-ppc/pgalloc.h
@@ -20,10 +20,17 @@ extern void pgd_free(pgd_t *pgd);
#define __pmd_free_tlb(tlb,x) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG()
+#ifndef CONFIG_BOOKE
#define pmd_populate_kernel(mm, pmd, pte) \
(pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
#define pmd_populate(mm, pmd, pte) \
(pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
+#else
+#define pmd_populate_kernel(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)page_to_virt(pte) | _PMD_PRESENT)
+#endif
extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 73a8f18d22cf..0399c8cfbcab 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -65,13 +65,23 @@ extern unsigned long ioremap_bot, ioremap_base;
* and ITLB, respectively (see "mmu.h" for definitions).
*/
-/* PMD_SHIFT determines the size of the area mapped by the second-level page tables */
-#define PMD_SHIFT 22
+/*
+ * The normal case is that PTEs are 32-bits and we have a 1-page
+ * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
+ *
+ * For any >32-bit physical address platform, we can use the following
+ * two level page table layout where the pgdir is 8KB and the MS 13 bits
+ * are an index to the second level table. The combined pgdir/pmd first
+ * level has 2048 entries and the second level has 512 64-bit PTE entries.
+ * -Matt
+ */
+/* PMD_SHIFT determines the size of the area mapped by the PTE pages */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_SHIFT)
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT 22
+/* PGDIR_SHIFT determines what a top-level page table entry can map */
+#define PGDIR_SHIFT PMD_SHIFT
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
@@ -79,9 +89,10 @@ extern unsigned long ioremap_bot, ioremap_base;
* entries per page directory level: our page-table tree is two-level, so
* we don't really have any PMD directory.
*/
-#define PTRS_PER_PTE 1024
+#define PTRS_PER_PTE (1 << PTE_SHIFT)
#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD 1024
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
#define FIRST_USER_PGD_NR 0
@@ -89,7 +100,7 @@ extern unsigned long ioremap_bot, ioremap_base;
#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
#define pte_ERROR(e) \
- printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+ printk("%s:%d: bad pte "PTE_FMT".\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \
@@ -113,7 +124,11 @@ extern unsigned long ioremap_bot, ioremap_base;
* of RAM. -- Cort
*/
#define VMALLOC_OFFSET (0x1000000) /* 16M */
+#ifdef CONFIG_44x
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#else
#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#define VMALLOC_END ioremap_bot
@@ -170,6 +185,44 @@ extern unsigned long ioremap_bot, ioremap_base;
#define _PMD_SIZE_16M 0x0e0
#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+#elif defined(CONFIG_44x)
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing. I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN. This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ */
+#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
+#define _PAGE_RW 0x00000002 /* S: Write permission */
+#define _PAGE_DIRTY 0x00000004 /* S: Page dirty */
+#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */
+#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */
+#define _PAGE_USER 0x00000040 /* S: User page */
+#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
+#define _PAGE_GUARDED 0x00000100 /* H: G bit */
+#define _PAGE_COHERENT 0x00000200 /* H: M bit */
+#define _PAGE_FILE 0x00000400 /* S: nonlinear file mapping */
+#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+
#elif defined(CONFIG_8xx)
/* Definitions for 8xx embedded chips. */
#define _PAGE_PRESENT 0x0001 /* Page is valid */
@@ -270,7 +323,11 @@ extern unsigned long ioremap_bot, ioremap_base;
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
+#ifndef CONFIG_44x
#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
+#else
+#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE | _PAGE_GUARDED)
+#endif
#ifdef CONFIG_PPC_STD_MMU
/* On standard PPC MMU, no user access implies kernel read/write access,
@@ -283,7 +340,7 @@ extern unsigned long ioremap_bot, ioremap_base;
#define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED)
#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC)
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH)
/* We want the debuggers to be able to set breakpoints anywhere, so
* don't write protect the kernel text */
#define _PAGE_RAM_TEXT _PAGE_RAM
@@ -420,6 +477,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*
* pte_update clears and sets bit atomically, and returns
* the old pte value.
+ * The ((unsigned long)(p+1) - 4) hack is to get to the least-significant
+ * 32 bits of the PTE regardless of whether PTEs are 32 or 64 bits.
*/
static inline unsigned long pte_update(pte_t *p, unsigned long clr,
unsigned long set)
@@ -434,7 +493,7 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
" stwcx. %1,0,%3\n\
bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*p)
- : "r" (p), "r" (clr), "r" (set), "m" (*p)
+ : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
: "cc" );
return old;
}
@@ -485,11 +544,25 @@ static inline void ptep_mkdirty(pte_t *ptep)
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+/*
+ * Note that on Book E processors, the pmd contains the kernel virtual
+ * (lowmem) address of the pte page. The physical address is less useful
+ * because everything runs with translation enabled (even the TLB miss
+ * handler). On everything else the pmd contains the physical address
+ * of the pte page. -- paulus
+ */
+#ifndef CONFIG_BOOKE
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
#define pmd_page(pmd) \
(mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
-
+#else
+#define pmd_page_kernel(pmd) \
+ ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#endif
+
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
@@ -516,7 +589,8 @@ static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
-extern pgd_t swapper_pg_dir[1024];
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
extern void paging_init(void);
/*
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h
index 39049bcac7fc..afd99032491c 100644
--- a/include/asm-ppc/ppc_asm.h
+++ b/include/asm-ppc/ppc_asm.h
@@ -107,7 +107,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
bdnz 0b
#endif
-#if !defined(CONFIG_440)
+#if !defined(CONFIG_44x)
/*
* On APUS (Amiga PowerPC cpu upgrade board), we don't know the
* physical base address of RAM at compile time.
@@ -125,7 +125,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
.align 1; \
.long 0b; \
.previous
-#else /* CONFIG_440 */
+#else /* CONFIG_44x */
#define tophys(rd,rs) \
mr rd,rs
@@ -133,7 +133,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define tovirt(rd,rs) \
mr rd,rs
-#endif /* CONFIG_440 */
+#endif /* CONFIG_44x */
/*
* On 64-bit cpus, we use the rfid instruction instead of rfi, but
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index 21c2c819b98f..e13d0a0b1f45 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -3,6 +3,12 @@
#define __ASM_PPC_PROCESSOR_H
/*
+ * The Book E definitions are hacked into here for 440 right
+ * now. This whole thing needs regorganized (maybe two files)
+ * so that it becomes readable. -Matt
+ */
+
+/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
@@ -45,6 +51,11 @@
#define MSR_RI (1<<1) /* Recoverable Exception */
#define MSR_LE (1<<0) /* Little Endian */
+#ifdef CONFIG_BOOKE
+#define MSR_IS MSR_IR /* Instruction Space */
+#define MSR_DS MSR_DR /* Data Space */
+#endif
+
#ifdef CONFIG_APUS_FAST_EXCEPT
#define MSR_ (MSR_ME|MSR_IP|MSR_RI)
#else
@@ -93,8 +104,13 @@
#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */
#define SPRN_CTR 0x009 /* Count Register */
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
+#ifndef CONFIG_BOOKE
#define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */
#define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */
+#else
+#define SPRN_DAC1 0x13C /* Book E Data Address Compare 1 */
+#define SPRN_DAC2 0x13D /* Book E Data Address Compare 2 */
+#endif /* CONFIG_BOOKE */
#define SPRN_DAR 0x013 /* Data Address Register */
#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */
#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */
@@ -146,7 +162,11 @@
#define DBCR_SDA 0x00000004 /* Second DAC Enable */
#define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */
#define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */
+#ifndef CONFIG_BOOKE
#define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */
+#else
+#define SPRN_DBCR0 0x134 /* Book E Debug Control Register 0 */
+#endif /* CONFIG_BOOKE */
#define DBCR0_EDM 0x80000000 /* External Debug Mode */
#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */
#define DBCR0_RST 0x30000000 /* all the bits in the RST field */
@@ -169,11 +189,18 @@
#define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */
#define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */
#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */
+#ifndef CONFIG_BOOKE
#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */
#define SPRN_DBSR 0x3F0 /* Debug Status Register */
#define DBSR_IC 0x80000000 /* Instruction Completion */
#define DBSR_BT 0x40000000 /* Branch taken */
#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */
+#else
+#define SPRN_DBCR1 0x135 /* Book E Debug Control Register 1 */
+#define SPRN_DBSR 0x130 /* Book E Debug Status Register */
+#define DBSR_IC 0x08000000 /* Book E Instruction Completion */
+#define DBSR_TIE 0x01000000 /* Book E Trap Instruction Event */
+#endif /* CONFIG_BOOKE */
#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */
#define DCCR_NOCACHE 0 /* Noncacheable */
#define DCCR_CACHE 1 /* Cacheable */
@@ -181,7 +208,11 @@
#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */
#define DCWR_COPY 0 /* Copy-back */
#define DCWR_WRITE 1 /* Write-through */
+#ifndef CONFIG_BOOKE
#define SPRN_DEAR 0x3D5 /* Data Error Address Register */
+#else
+#define SPRN_DEAR 0x03D /* Book E Data Error Address Register */
+#endif /* CONFIG_BOOKE */
#define SPRN_DEC 0x016 /* Decrement Register */
#define SPRN_DER 0x095 /* Debug Enable Regsiter */
#define DER_RSTE 0x40000000 /* Reset Interrupt */
@@ -206,12 +237,16 @@
#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define SPRN_EAR 0x11A /* External Address Register */
+#ifndef CONFIG_BOOKE
#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */
+#else
+#define SPRN_ESR 0x03E /* Book E Exception Syndrome Register */
+#endif /* CONFIG_BOOKE */
#define ESR_MCI 0x80000000 /* 405 Machine Check - Instruction */
-#define ESR_IMCP 0x80000000 /* 403 Inst. Mach. Check - Protection */
-#define ESR_IMCN 0x40000000 /* 403 Inst. Mach. Check - Non-config */
-#define ESR_IMCB 0x20000000 /* 403 Inst. Mach. Check - Bus error */
-#define ESR_IMCT 0x10000000 /* 403 Inst. Mach. Check - Timeout */
+#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */
+#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */
+#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */
+#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */
#define ESR_PIL 0x08000000 /* Program Exception - Illegal */
#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */
#define ESR_PTR 0x02000000 /* Program Exception - Trap */
@@ -266,8 +301,13 @@
#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */
#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
+#ifndef CONFIG_BOOKE
#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */
#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */
+#else
+#define SPRN_IAC1 0x138 /* Book E Instruction Address Compare 1 */
+#define SPRN_IAC2 0x139 /* Book E Instruction Address Compare 2 */
+#endif /* CONFIG_BOOKE */
#define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */
#define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */
#define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */
@@ -358,8 +398,13 @@
#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */
#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */
#define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */
+#ifndef CONFIG_BOOKE
#define SPRN_PID 0x3B1 /* Process ID */
#define SPRN_PIR 0x3FF /* Processor Identification Register */
+#else
+#define SPRN_PID 0x030 /* Book E Process ID */
+#define SPRN_PIR 0x11E /* Book E Processor Identification Register */
+#endif /* CONFIG_BOOKE */
#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
@@ -375,6 +420,7 @@
#define SGR_NORMAL 0
#define SGR_GUARDED 1
#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
+#define SPRN_SLER 0x3BB /* Little-endian real mode */
#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
@@ -387,6 +433,7 @@
#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
#define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */
#define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */
+#define SPRN_SU0R 0x3BC /* "User 0" real mode */
#define SPRN_TBHI 0x3DC /* Time Base High (4xx) */
#define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */
#define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */
@@ -395,7 +442,11 @@
#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */
#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */
+#ifndef CONFIG_BOOKE
#define SPRN_TCR 0x3DA /* Timer Control Register */
+#else
+#define SPRN_TCR 0x154 /* Book E Timer Control Register */
+#endif
#define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */
#define TCR_WP_MASK TCR_WP(3)
#define WP_2_17 0 /* 2^17 clocks */
@@ -410,6 +461,7 @@
#define WRC_SYSTEM 3 /* System reset will occur */
#define TCR_WIE 0x08000000 /* WDT Interrupt Enable */
#define TCR_PIE 0x04000000 /* PIT Interrupt Enable */
+#define TCR_DIE TCR_PIE /* DEC Interrupt Enable */
#define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */
#define TCR_FP_MASK TCR_FP(3)
#define FP_2_9 0 /* 2^9 clocks */
@@ -431,7 +483,11 @@
#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */
#define THRM3_E (1<<0)
#define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */
+#ifndef CONFIG_BOOKE
#define SPRN_TSR 0x3D8 /* Timer Status Register */
+#else
+#define SPRN_TSR 0x150 /* Book E Timer Status Register */
+#endif /* CONFIG_BOOKE */
#define TSR_ENW 0x80000000 /* Enable Next Watchdog */
#define TSR_WIS 0x40000000 /* WDT Interrupt Status */
#define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */
@@ -440,6 +496,7 @@
#define WRS_CHIP 2 /* WDT forced chip reset */
#define WRS_SYSTEM 3 /* WDT forced system reset */
#define TSR_PIS 0x08000000 /* PIT Interrupt Status */
+#define TSR_DIS TSR_PIS /* DEC Interrupt Status */
#define TSR_FIS 0x04000000 /* FIT Interrupt Status */
#define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */
#define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */
@@ -452,6 +509,45 @@
#define SPRN_XER 0x001 /* Fixed Point Exception Register */
#define SPRN_ZPR 0x3B0 /* Zone Protection Register */
+/* Book E definitions */
+#define SPRN_DECAR 0x036 /* Decrementer Auto Reload Register */
+#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */
+#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */
+#define SPRN_IVPR 0x03F /* Interrupt Vector Prefix Register */
+#define SPRN_USPRG0 0x100 /* User Special Purpose Register General 0 */
+#define SPRN_SPRG4R 0x104 /* Special Purpose Register General 4 Read */
+#define SPRN_SPRG5R 0x105 /* Special Purpose Register General 5 Read */
+#define SPRN_SPRG6R 0x106 /* Special Purpose Register General 6 Read */
+#define SPRN_SPRG7R 0x107 /* Special Purpose Register General 7 Read */
+#define SPRN_SPRG4W 0x114 /* Special Purpose Register General 4 Write */
+#define SPRN_SPRG5W 0x115 /* Special Purpose Register General 5 Write */
+#define SPRN_SPRG6W 0x116 /* Special Purpose Register General 6 Write */
+#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */
+#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */
+#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */
+#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */
+#define SPRN_DVC1 0x13E /* */
+#define SPRN_DVC2 0x13F /* */
+#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */
+#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */
+#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */
+#define SPRN_IVOR3 0x193 /* Interrupt Vector Offset Register 3 */
+#define SPRN_IVOR4 0x194 /* Interrupt Vector Offset Register 4 */
+#define SPRN_IVOR5 0x195 /* Interrupt Vector Offset Register 5 */
+#define SPRN_IVOR6 0x196 /* Interrupt Vector Offset Register 6 */
+#define SPRN_IVOR7 0x197 /* Interrupt Vector Offset Register 7 */
+#define SPRN_IVOR8 0x198 /* Interrupt Vector Offset Register 8 */
+#define SPRN_IVOR9 0x199 /* Interrupt Vector Offset Register 9 */
+#define SPRN_IVOR10 0x19a /* Interrupt Vector Offset Register 10 */
+#define SPRN_IVOR11 0x19b /* Interrupt Vector Offset Register 11 */
+#define SPRN_IVOR12 0x19c /* Interrupt Vector Offset Register 12 */
+#define SPRN_IVOR13 0x19d /* Interrupt Vector Offset Register 13 */
+#define SPRN_IVOR14 0x19e /* Interrupt Vector Offset Register 14 */
+#define SPRN_IVOR15 0x19f /* Interrupt Vector Offset Register 15 */
+#define SPRN_MMUCR 0x3b2 /* MMU Control Register */
+
+#define ESR_ST 0x00800000 /* Store Operation */
+
/* Short-hand versions for a number of the above SPRNs */
#define CTR SPRN_CTR /* Counter Register */
@@ -524,6 +620,16 @@
#define SPRG5 SPRN_SPRG5
#define SPRG6 SPRN_SPRG6
#define SPRG7 SPRN_SPRG7
+#define SPRG4R SPRN_SPRG4R /* Book E Supervisor Private Registers */
+#define SPRG5R SPRN_SPRG5R
+#define SPRG6R SPRN_SPRG6R
+#define SPRG7R SPRN_SPRG7R
+#define SPRG4W SPRN_SPRG4W
+#define SPRG5W SPRN_SPRG5W
+#define SPRG6W SPRN_SPRG6W
+#define SPRG7W SPRN_SPRG7W
+#define CSRR0 SPRN_CSRR0 /* Critical Save and Restore Register 0 */
+#define CSRR1 SPRN_CSRR1 /* Critical Save and Restore Register 1 */
#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */
#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
#define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */
@@ -557,6 +663,51 @@
#define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */
#define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */
+/* Processor Version Numbers */
+
+#define PVR_403GA 0x00200000
+#define PVR_403GB 0x00200100
+#define PVR_403GC 0x00200200
+#define PVR_403GCX 0x00201400
+#define PVR_405GP 0x40110000
+#define PVR_STB03XXX 0x40310000
+#define PVR_NP405H 0x41410000
+#define PVR_NP405L 0x41610000
+#define PVR_440GP_RB 0x40120440
+#define PVR_440GP_RC1 0x40120481
+#define PVR_440GP_RC2 0x40200481
+#define PVR_440GX_RC1 0x51b21850
+#define PVR_601 0x00010000
+#define PVR_602 0x00050000
+#define PVR_603 0x00030000
+#define PVR_603e 0x00060000
+#define PVR_603ev 0x00070000
+#define PVR_603r 0x00071000
+#define PVR_604 0x00040000
+#define PVR_604e 0x00090000
+#define PVR_604r 0x000A0000
+#define PVR_620 0x00140000
+#define PVR_740 0x00080000
+#define PVR_750 PVR_740
+#define PVR_740P 0x10080000
+#define PVR_750P PVR_740P
+#define PVR_7400 0x000C0000
+#define PVR_7410 0x800C0000
+#define PVR_7450 0x80000000
+/*
+ * For the 8xx processors, all of them report the same PVR family for
+ * the PowerPC core. The various versions of these processors must be
+ * differentiated by the version number in the Communication Processor
+ * Module (CPM).
+ */
+#define PVR_821 0x00500000
+#define PVR_823 PVR_821
+#define PVR_850 PVR_821
+#define PVR_860 PVR_821
+#define PVR_8240 0x00810100
+#define PVR_8245 0x80811014
+#define PVR_8260 PVR_8240
+
/* We only need to define a new _MACH_xxx for machines which are part of
* a configuration which supports more than one type of different machine.
* This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. -- Tom
diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h
index 5d121448d3c1..2d9e8642cc87 100644
--- a/include/asm-ppc/serial.h
+++ b/include/asm-ppc/serial.h
@@ -28,7 +28,7 @@
#include <platforms/sandpoint.h>
#elif defined(CONFIG_SPRUCE)
#include <platforms/spruce_serial.h>
-#elif defined(CONFIG_40x)
+#elif defined(CONFIG_4xx)
#include <asm/ibm4xx.h>
#else
diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h
index 2ccb0b20d2af..a441eb07e0e5 100644
--- a/include/asm-ppc/tlbflush.h
+++ b/include/asm-ppc/tlbflush.h
@@ -19,17 +19,23 @@ extern void _tlbia(void);
#if defined(CONFIG_4xx)
+#ifndef CONFIG_44x
+#define __tlbia() asm volatile ("sync; tlbia; isync" : : : "memory")
+#else
+#define __tlbia _tlbia
+#endif
+
static inline void flush_tlb_mm(struct mm_struct *mm)
- { _tlbia(); }
+ { __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
- { _tlbia(); }
+ { __tlbia(); }
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
- { _tlbia(); }
+ { __tlbia(); }
#elif defined(CONFIG_8xx)
#define __tlbia() asm volatile ("tlbia; sync" : : : "memory")
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h
index 474abcd85b34..5720dea2459f 100644
--- a/include/asm-s390/semaphore.h
+++ b/include/asm-s390/semaphore.h
@@ -60,6 +60,7 @@ asmlinkage void __up(struct semaphore * sem);
static inline void down(struct semaphore * sem)
{
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
__down(sem);
}
@@ -68,6 +69,7 @@ static inline int down_interruptible(struct semaphore * sem)
{
int ret = 0;
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
ret = __down_interruptible(sem);
return ret;
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
index 2ba0930035f6..dc8955e3448c 100644
--- a/include/asm-sh/semaphore.h
+++ b/include/asm-sh/semaphore.h
@@ -107,6 +107,7 @@ static inline int down_interruptible(struct semaphore * sem)
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
if (atomic_dec_return(&sem->count) < 0)
ret = __down_interruptible(sem);
return ret;
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
index cf3135b928a0..0e6122ae3058 100644
--- a/include/asm-sparc/semaphore.h
+++ b/include/asm-sparc/semaphore.h
@@ -71,6 +71,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
ptr = &(sem->count.counter);
increment = 1;
@@ -107,6 +108,7 @@ static inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
ptr = &(sem->count.counter);
increment = 1;
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index 11f174e6b3c3..0a8ad4cac125 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -73,6 +73,7 @@ struct winsize {
#define N_HCI 15 /* Bluetooth HCI UART */
#ifdef __KERNEL__
+#include <linux/module.h>
/*
* c_cc characters in the termio structure. Oh, how I love being
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index d29aa87ad90b..8effce0da087 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -73,6 +73,7 @@ struct winsize {
#define N_HCI 15 /* Bluetooth HCI UART */
#ifdef __KERNEL__
+#include <linux/module.h>
/*
* c_cc characters in the termio structure. Oh, how I love being
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
index 0d6560f3ba98..c514062bb69e 100644
--- a/include/asm-v850/semaphore.h
+++ b/include/asm-v850/semaphore.h
@@ -57,6 +57,7 @@ extern void __up (struct semaphore * sem);
extern inline void down (struct semaphore * sem)
{
+ might_sleep();
if (atomic_dec_return (&sem->count) < 0)
__down (sem);
}
@@ -64,6 +65,7 @@ extern inline void down (struct semaphore * sem)
extern inline int down_interruptible (struct semaphore * sem)
{
int ret = 0;
+ might_sleep();
if (atomic_dec_return (&sem->count) < 0)
ret = __down_interruptible (sem);
return ret;
diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
index 6f42c7af790b..5fe25482facc 100644
--- a/include/asm-x86_64/semaphore.h
+++ b/include/asm-x86_64/semaphore.h
@@ -118,6 +118,7 @@ static inline void down(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
__asm__ __volatile__(
"# atomic down operation\n\t"
@@ -144,6 +145,7 @@ static inline int down_interruptible(struct semaphore * sem)
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
+ might_sleep();
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 99dbf0d24eaf..285fd86e2b48 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -12,6 +12,8 @@
#include <linux/wait.h>
#include <linux/mempool.h>
#include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
#include <asm/scatterlist.h>
@@ -268,7 +270,7 @@ struct request_queue
* Together with queue_head for cacheline sharing
*/
struct list_head queue_head;
- struct list_head *last_merge;
+ struct request *last_merge;
elevator_t elevator;
/*
@@ -671,6 +673,11 @@ void kblockd_flush(void);
} \
)
#endif
-
+
+#define MODULE_ALIAS_BLOCKDEV(major,minor) \
+ MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
+#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \
+ MODULE_ALIAS("block-major-" __stringify(major) "-*")
+
#endif
diff --git a/include/linux/device.h b/include/linux/device.h
index 8d6266f2e3c3..96043c0f46c5 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -398,4 +398,9 @@ extern void firmware_unregister(struct subsystem *);
#define dev_warn(dev, format, arg...) \
dev_printk(KERN_WARNING , dev , format , ## arg)
+/* Create alias, so I can be autoloaded. */
+#define MODULE_ALIAS_CHARDEV(major,minor) \
+ MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
+#define MODULE_ALIAS_CHARDEV_MAJOR(major) \
+ MODULE_ALIAS("char-major-" __stringify(major) "-*")
#endif /* _DEVICE_H_ */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index ac30ae089069..e43d670c1371 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -1,7 +1,7 @@
#ifndef _LINUX_ELEVATOR_H
#define _LINUX_ELEVATOR_H
-typedef int (elevator_merge_fn) (request_queue_t *, struct list_head **,
+typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
struct bio *);
typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
@@ -10,7 +10,7 @@ typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
typedef struct request *(elevator_next_req_fn) (request_queue_t *);
-typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
+typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
@@ -62,7 +62,7 @@ struct elevator_s
*/
extern void elv_add_request(request_queue_t *, struct request *, int, int);
extern void __elv_add_request(request_queue_t *, struct request *, int, int);
-extern int elv_merge(request_queue_t *, struct list_head **, struct bio *);
+extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
@@ -79,9 +79,6 @@ extern void elv_completed_request(request_queue_t *, struct request *);
extern int elv_set_request(request_queue_t *, struct request *, int);
extern void elv_put_request(request_queue_t *, struct request *);
-#define __elv_add_request_pos(q, rq, pos) \
- (q)->elevator.elevator_add_req_fn((q), (rq), (pos))
-
/*
* noop I/O scheduler. always merges, always inserts new request at tail
*/
@@ -111,4 +108,11 @@ extern inline int elv_try_last_merge(request_queue_t *, struct bio *);
#define ELEVATOR_FRONT_MERGE 1
#define ELEVATOR_BACK_MERGE 2
+/*
+ * Insertion selection
+ */
+#define ELEVATOR_INSERT_FRONT 1
+#define ELEVATOR_INSERT_BACK 2
+#define ELEVATOR_INSERT_SORT 3
+
#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 936f34c469dd..87ae270bf96c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1391,10 +1391,6 @@ extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count);
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned int real_root_dev;
-#endif
-
extern int inode_change_ok(struct inode *, struct iattr *);
extern int inode_setattr(struct inode *, struct iattr *);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 460ef0362ab5..13e0933ccbc7 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -75,7 +75,6 @@ struct disk_stats {
unsigned read_merges, write_merges;
unsigned read_ticks, write_ticks;
unsigned io_ticks;
- int in_flight;
unsigned time_in_queue;
};
@@ -101,6 +100,7 @@ struct gendisk {
unsigned sync_io; /* RAID */
unsigned long stamp, stamp_idle;
+ int in_flight;
#ifdef CONFIG_SMP
struct disk_stats *dkstats;
#else
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index dc6d8dd843b5..9e6d27476a74 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -207,7 +207,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value, struct pt_regs *regs);
void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
int __init hiddev_init(void);
-void __exit hiddev_exit(void);
+void hiddev_exit(void);
#else
static inline int hiddev_connect(struct hid_device *hid) { return -1; }
static inline void hiddev_disconnect(struct hid_device *hid) { }
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 4664fd44a986..e7c50528e10e 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1218,7 +1218,6 @@ typedef struct ide_driver_s {
const char *version;
u8 media;
unsigned busy : 1;
- unsigned supports_dma : 1;
unsigned supports_dsc_overlap : 1;
int (*cleanup)(ide_drive_t *);
int (*shutdown)(ide_drive_t *);
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 975aad03d762..3d9fc5d43803 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -155,9 +155,11 @@ struct frhdr
struct dlci_local
{
struct net_device_stats stats;
- struct net_device *slave;
+ struct net_device *master;
+ struct net_device *slave;
struct dlci_conf config;
int configured;
+ struct list_head list;
/* callback function */
void (*receive)(struct sk_buff *skb, struct net_device *);
diff --git a/include/linux/initrd.h b/include/linux/initrd.h
index 32452d53dac3..55289d261b4f 100644
--- a/include/linux/initrd.h
+++ b/include/linux/initrd.h
@@ -16,3 +16,5 @@ extern int initrd_below_start_ok;
/* free_initrd_mem always gets called with the next two as arguments.. */
extern unsigned long initrd_start, initrd_end;
extern void free_initrd_mem(unsigned long, unsigned long);
+
+extern unsigned int real_root_dev;
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index ecd0f5394e9e..35a2ef6e2452 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -258,13 +258,13 @@ typedef struct {
* variables. Of course, we need to check skb_headroom prior to
* any access.
*/
-typedef struct isdn_audio_skb {
+typedef struct _isdnaudio_header {
unsigned short dle_count;
unsigned char lock;
-} isdn_audio_skb;
+} isdnaudio_header;
-#define ISDN_AUDIO_SKB_DLECOUNT(skb) (((isdn_audio_skb*)skb->head)->dle_count)
-#define ISDN_AUDIO_SKB_LOCK(skb) (((isdn_audio_skb*)skb->head)->lock)
+#define ISDN_AUDIO_SKB_DLECOUNT(skb) (((isdnaudio_header*)skb->head)->dle_count)
+#define ISDN_AUDIO_SKB_LOCK(skb) (((isdnaudio_header*)skb->head)->lock)
#endif
/* Private data of AT-command-interpreter */
@@ -291,6 +291,7 @@ typedef struct atemu {
/* Private data (similar to async_struct in <linux/serial.h>) */
typedef struct modem_info {
int magic;
+ struct module *owner;
int flags; /* defined in tty.h */
int x_char; /* xon/xoff character */
int mcr; /* Modem control register */
diff --git a/include/linux/isdn/capilli.h b/include/linux/isdn/capilli.h
index cf501356aba4..d4747a9cee9c 100644
--- a/include/linux/isdn/capilli.h
+++ b/include/linux/isdn/capilli.h
@@ -54,7 +54,7 @@ struct capi_ctr {
int count, int *eof, struct capi_ctr *card);
/* filled in before calling ready callback */
- u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */
+ u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */
capi_version version; /* CAPI_GET_VERSION */
capi_profile profile; /* CAPI_GET_PROFILE */
u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b0aebfeda888..b2d17ea0dac0 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -52,8 +52,10 @@ struct completion;
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
void __might_sleep(char *file, int line);
#define might_sleep() __might_sleep(__FILE__, __LINE__)
+#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
#else
#define might_sleep() do {} while(0)
+#define might_sleep_if(cond) do {} while (0)
#endif
extern struct notifier_block *panic_notifier_list;
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 7fa02a737518..8412faeea0f7 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -29,7 +29,7 @@ extern int request_module(const char * name, ...) __attribute__ ((format (printf
static inline int request_module(const char * name, ...) { return -ENOSYS; }
#endif
-#define try_then_request_module(x, mod...) ((x) ?: request_module(mod), (x))
+#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
#ifdef CONFIG_HOTPLUG
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 159f8ab3df80..23b095889111 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -1,5 +1,7 @@
#ifndef _LINUX_MISCDEVICE_H
#define _LINUX_MISCDEVICE_H
+#include <linux/module.h>
+#include <linux/major.h>
#define BUSMOUSE_MINOR 0
#define PSMOUSE_MINOR 1
@@ -48,4 +50,7 @@ struct miscdevice
extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice * misc);
+#define MODULE_ALIAS_MISCDEV(minor) \
+ MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR) \
+ "-" __stringify(minor))
#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 445fc58751c7..9f9743146b54 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -110,6 +110,7 @@ struct vm_area_struct {
#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
+#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index dfc1aa47f35c..c99e53fed30e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -37,9 +37,6 @@
#ifdef __KERNEL__
#include <linux/config.h>
-#ifdef CONFIG_NET_PROFILE
-#include <net/profile.h>
-#endif
struct divert_blk;
struct vlan_group;
@@ -498,6 +495,7 @@ extern struct net_device loopback_dev; /* The loopback */
extern struct net_device *dev_base; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */
+extern void probe_old_netdevs(void);
extern int netdev_boot_setup_add(char *name, struct ifmap *map);
extern int netdev_boot_setup_check(struct net_device *dev);
extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr);
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index d4fd6bb3ca43..006fde0295d5 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -191,6 +191,8 @@ extern void get_full_page_state(struct page_state *ret);
#define PageSlab(page) test_bit(PG_slab, &(page)->flags)
#define SetPageSlab(page) set_bit(PG_slab, &(page)->flags)
#define ClearPageSlab(page) clear_bit(PG_slab, &(page)->flags)
+#define TestClearPageSlab(page) test_and_clear_bit(PG_slab, &(page)->flags)
+#define TestSetPageSlab(page) test_and_set_bit(PG_slab, &(page)->flags)
#ifdef CONFIG_HIGHMEM
#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags)
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 27c38b240736..e1aaf1fac8e0 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -101,6 +101,7 @@ typedef struct rtc_task {
int rtc_register(rtc_task_t *task);
int rtc_unregister(rtc_task_t *task);
int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
+void rtc_get_rtc_time(struct rtc_time *rtc_tm);
#endif /* __KERNEL__ */
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 3e3a26916a12..fd8b35209ccc 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -3,9 +3,6 @@
#include <linux/netlink.h>
-#define RTNL_DEBUG 1
-
-
/****
* Routing/neighbour discovery messages.
****/
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 6ebaff34570c..6131e3c9aa45 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
@@ -42,6 +42,8 @@
* randall@sctp.chicago.il.us
* kmorneau@cisco.com
* qxie1@email.mot.com
+ * Sridhar Samudrala <sri@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -507,6 +509,11 @@ typedef struct sctp_cwr_chunk {
* The ASCONF Parameter Response is used in the ASCONF-ACK to
* report status of ASCONF processing.
*/
+typedef struct sctp_addip_param {
+ sctp_paramhdr_t param_hdr;
+ __u32 crr_id;
+}sctp_addip_param_t __attribute__((packed));
+
typedef struct sctp_addiphdr {
__u32 serial;
__u8 params[0];
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a372186cb6d6..4b5f057f8bfb 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -389,6 +389,7 @@ static inline int skb_shared(struct sk_buff *skb)
*/
static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri)
{
+ might_sleep_if(pri & __GFP_WAIT);
if (skb_shared(skb)) {
struct sk_buff *nskb = skb_clone(skb, pri);
kfree_skb(skb);
@@ -419,6 +420,7 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri)
*/
static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri)
{
+ might_sleep_if(pri & __GFP_WAIT);
if (skb_cloned(skb)) {
struct sk_buff *nskb = skb_copy(skb, pri);
kfree_skb(skb); /* Free our shared copy */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index c48edf4a551e..38c43d95a616 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -603,7 +603,8 @@ enum {
DEV_HWMON=2,
DEV_PARPORT=3,
DEV_RAID=4,
- DEV_MAC_HID=5
+ DEV_MAC_HID=5,
+ DEV_SCSI=6,
};
/* /proc/sys/dev/cdrom */
@@ -664,6 +665,11 @@ enum {
DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
};
+/* /proc/sys/dev/scsi */
+enum {
+ DEV_SCSI_LOGGING_LEVEL=1,
+};
+
/* /proc/sys/abi */
enum
{
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index ac8ac46845ba..c851b7dc997e 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -138,4 +138,7 @@ struct tty_ldisc {
#define LDISC_FLAG_DEFINED 0x00000001
+#define MODULE_ALIAS_LDISC(ldisc) \
+ MODULE_ALIAS("tty-ldisc-" __stringify(ldisc))
+
#endif /* _LINUX_TTY_LDISC_H */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 471c37f5188b..a20b33d953aa 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -329,7 +329,7 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
{
int actual;
actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
- return (actual >= size) ? -1 : actual;
+ return (actual >= (int)size) ? -1 : actual;
}
/*-------------------------------------------------------------------------*/
diff --git a/include/linux/vcache.h b/include/linux/vcache.h
deleted file mode 100644
index 5708fe6a908a..000000000000
--- a/include/linux/vcache.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * virtual => physical mapping cache support.
- */
-#ifndef _LINUX_VCACHE_H
-#define _LINUX_VCACHE_H
-
-typedef struct vcache_s {
- unsigned long address;
- struct mm_struct *mm;
- struct list_head hash_entry;
- void (*callback)(struct vcache_s *data, struct page *new_page);
-} vcache_t;
-
-extern spinlock_t vcache_lock;
-
-extern void __attach_vcache(vcache_t *vcache,
- unsigned long address,
- struct mm_struct *mm,
- void (*callback)(struct vcache_s *data, struct page *new_page));
-
-extern void __detach_vcache(vcache_t *vcache);
-
-extern void invalidate_vcache(unsigned long address, struct mm_struct *mm,
- struct page *new_page);
-
-#endif
diff --git a/include/net/profile.h b/include/net/profile.h
deleted file mode 100644
index fd6a3b346990..000000000000
--- a/include/net/profile.h
+++ /dev/null
@@ -1,312 +0,0 @@
-#include <linux/config.h> /* for CONFIG_NET_PROFILE */
-#ifndef _NET_PROFILE_H_
-#define _NET_PROFILE_H_ 1
-
-#ifdef CONFIG_NET_PROFILE
-
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_X86_TSC
-#include <asm/msr.h>
-#endif
-
-struct net_profile_slot
-{
- char id[16];
- struct net_profile_slot *next;
- struct timeval entered;
- struct timeval accumulator;
- struct timeval irq;
- int hits;
- int active;
- int underflow;
-};
-
-extern atomic_t net_profile_active;
-extern struct timeval net_profile_adjust;
-extern void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved);
-
-#ifdef CONFIG_X86_TSC
-
-static inline void net_profile_stamp(struct timeval *pstamp)
-{
- rdtsc(pstamp->tv_usec, pstamp->tv_sec);
-}
-
-static inline void net_profile_accumulate(struct timeval *entered,
- struct timeval *leaved,
- struct timeval *acc)
-{
- __asm__ __volatile__ ("subl %2,%0\n\t"
- "sbbl %3,%1\n\t"
- "addl %4,%0\n\t"
- "adcl %5,%1\n\t"
- "subl net_profile_adjust+4,%0\n\t"
- "sbbl $0,%1\n\t"
- : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
- : "g" (entered->tv_usec), "g" (entered->tv_sec),
- "g" (leaved->tv_usec), "g" (leaved->tv_sec),
- "0" (acc->tv_usec), "1" (acc->tv_sec));
-}
-
-static inline void net_profile_sub(struct timeval *sub,
- struct timeval *acc)
-{
- __asm__ __volatile__ ("subl %2,%0\n\t"
- "sbbl %3,%1\n\t"
- : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
- : "g" (sub->tv_usec), "g" (sub->tv_sec),
- "0" (acc->tv_usec), "1" (acc->tv_sec));
-}
-
-static inline void net_profile_add(struct timeval *add,
- struct timeval *acc)
-{
- __asm__ __volatile__ ("addl %2,%0\n\t"
- "adcl %3,%1\n\t"
- : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
- : "g" (add->tv_usec), "g" (add->tv_sec),
- "0" (acc->tv_usec), "1" (acc->tv_sec));
-}
-
-
-#elif defined (__alpha__)
-
-extern __u32 alpha_lo;
-extern long alpha_hi;
-
-/* On alpha cycle counter has only 32 bits :-( :-( */
-
-static inline void net_profile_stamp(struct timeval *pstamp)
-{
- __u32 result;
- __asm__ __volatile__ ("rpcc %0" : "r="(result));
- if (result <= alpha_lo)
- alpha_hi++;
- alpha_lo = result;
- pstamp->tv_sec = alpha_hi;
- pstamp->tv_usec = alpha_lo;
-}
-
-static inline void net_profile_accumulate(struct timeval *entered,
- struct timeval *leaved,
- struct timeval *acc)
-{
- time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
- - net_profile_adjust.tv_usec;
- time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
-
- if (usecs >= 0x100000000L) {
- usecs -= 0x100000000L;
- secs++;
- } else if (usecs < -0x100000000L) {
- usecs += 0x200000000L;
- secs -= 2;
- } else if (usecs < 0) {
- usecs += 0x100000000L;
- secs--;
- }
- acc->tv_sec = secs;
- acc->tv_usec = usecs;
-}
-
-static inline void net_profile_sub(struct timeval *entered,
- struct timeval *leaved)
-{
- time_t usecs = leaved->tv_usec - entered->tv_usec;
- time_t secs = leaved->tv_sec - entered->tv_sec;
-
- if (usecs < 0) {
- usecs += 0x100000000L;
- secs--;
- }
- leaved->tv_sec = secs;
- leaved->tv_usec = usecs;
-}
-
-static inline void net_profile_add(struct timeval *entered, struct timeval *leaved)
-{
- time_t usecs = leaved->tv_usec + entered->tv_usec;
- time_t secs = leaved->tv_sec + entered->tv_sec;
-
- if (usecs >= 0x100000000L) {
- usecs -= 0x100000000L;
- secs++;
- }
- leaved->tv_sec = secs;
- leaved->tv_usec = usecs;
-}
-
-
-#else
-
-static inline void net_profile_stamp(struct timeval *pstamp)
-{
- /* Not "fast" counterpart! On architectures without
- cpu clock "fast" routine is absolutely useless in this
- situation. do_gettimeofday still says something on slow-slow-slow
- boxes, though it eats more cpu time than the subject of
- investigation :-) :-)
- */
- do_gettimeofday(pstamp);
-}
-
-static inline void net_profile_accumulate(struct timeval *entered,
- struct timeval *leaved,
- struct timeval *acc)
-{
- time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
- - net_profile_adjust.tv_usec;
- time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
-
- if (usecs >= 1000000) {
- usecs -= 1000000;
- secs++;
- } else if (usecs < -1000000) {
- usecs += 2000000;
- secs -= 2;
- } else if (usecs < 0) {
- usecs += 1000000;
- secs--;
- }
- acc->tv_sec = secs;
- acc->tv_usec = usecs;
-}
-
-static inline void net_profile_sub(struct timeval *entered,
- struct timeval *leaved)
-{
- time_t usecs = leaved->tv_usec - entered->tv_usec;
- time_t secs = leaved->tv_sec - entered->tv_sec;
-
- if (usecs < 0) {
- usecs += 1000000;
- secs--;
- }
- leaved->tv_sec = secs;
- leaved->tv_usec = usecs;
-}
-
-static inline void net_profile_add(struct timeval *entered, struct timeval *leaved)
-{
- time_t usecs = leaved->tv_usec + entered->tv_usec;
- time_t secs = leaved->tv_sec + entered->tv_sec;
-
- if (usecs >= 1000000) {
- usecs -= 1000000;
- secs++;
- }
- leaved->tv_sec = secs;
- leaved->tv_usec = usecs;
-}
-
-
-
-#endif
-
-static inline void net_profile_enter(struct net_profile_slot *s)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if (s->active++ == 0) {
- net_profile_stamp(&s->entered);
- atomic_inc(&net_profile_active);
- }
- restore_flags(flags);
-}
-
-static inline void net_profile_leave_irq(struct net_profile_slot *s)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if (--s->active <= 0) {
- if (s->active == 0) {
- struct timeval curr_pstamp;
- net_profile_stamp(&curr_pstamp);
- net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
- if (!atomic_dec_and_test(&net_profile_active))
- net_profile_irq_adjust(&s->entered, &curr_pstamp);
- } else {
- s->underflow++;
- }
- }
- s->hits++;
- restore_flags(flags);
-}
-
-static inline void net_profile_leave(struct net_profile_slot *s)
-{
- unsigned long flags;
- save_flags(flags);
- cli();
- if (--s->active <= 0) {
- if (s->active == 0) {
- struct timeval curr_pstamp;
- net_profile_stamp(&curr_pstamp);
- net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
- atomic_dec(&net_profile_active);
- } else {
- s->underflow++;
- }
- }
- s->hits++;
- restore_flags(flags);
-}
-
-
-#define NET_PROFILE_ENTER(slot) net_profile_enter(&net_prof_##slot)
-#define NET_PROFILE_LEAVE(slot) net_profile_leave(&net_prof_##slot)
-#define NET_PROFILE_LEAVE_IRQ(slot) net_profile_leave_irq(&net_prof_##slot)
-
-#define NET_PROFILE_SKB_CLEAR(skb) ({ \
- skb->pstamp.tv_usec = 0; \
-})
-
-#define NET_PROFILE_SKB_INIT(skb) ({ \
- net_profile_stamp(&skb->pstamp); \
-})
-
-#define NET_PROFILE_SKB_PASSED(skb, slot) ({ \
- if (skb->pstamp.tv_usec) { \
- struct timeval cur_pstamp = skb->pstamp; \
- net_profile_stamp(&skb->pstamp); \
- net_profile_accumulate(&cur_pstamp, &skb->pstamp, &net_prof_##slot.accumulator); \
- net_prof_##slot.hits++; \
- }})
-
-#define NET_PROFILE_DECL(slot) \
- extern struct net_profile_slot net_prof_##slot;
-
-#define NET_PROFILE_DEFINE(slot) \
- struct net_profile_slot net_prof_##slot = { #slot, };
-
-#define NET_PROFILE_REGISTER(slot) net_profile_register(&net_prof_##slot)
-#define NET_PROFILE_UNREGISTER(slot) net_profile_unregister(&net_prof_##slot)
-
-extern int net_profile_init(void);
-extern int net_profile_register(struct net_profile_slot *);
-extern int net_profile_unregister(struct net_profile_slot *);
-
-#else
-
-#define NET_PROFILE_ENTER(slot) do { /* nothing */ } while(0)
-#define NET_PROFILE_LEAVE(slot) do { /* nothing */ } while(0)
-#define NET_PROFILE_LEAVE_IRQ(slot) do { /* nothing */ } while(0)
-#define NET_PROFILE_SKB_CLEAR(skb) do { /* nothing */ } while(0)
-#define NET_PROFILE_SKB_INIT(skb) do { /* nothing */ } while(0)
-#define NET_PROFILE_SKB_PASSED(skb, slot) do { /* nothing */ } while(0)
-#define NET_PROFILE_DECL(slot)
-#define NET_PROFILE_DEFINE(slot)
-#define NET_PROFILE_REGISTER(slot) do { /* nothing */ } while(0)
-#define NET_PROFILE_UNREGISTER(slot) do { /* nothing */ } while(0)
-
-#endif
-
-#endif
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 506fd2cb1305..3f21f1985699 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001-2003 Intel Corp.
*
* This file is part of the SCTP kernel reference Implementation
@@ -40,6 +40,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -145,6 +146,7 @@ int sctp_primitive_SHUTDOWN(struct sctp_association *, void *arg);
int sctp_primitive_ABORT(struct sctp_association *, void *arg);
int sctp_primitive_SEND(struct sctp_association *, void *arg);
int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
+int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
/*
* sctp/crc32c.c
@@ -404,6 +406,12 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
return result;
}
+/* Tests if the list has one and only one entry. */
+static inline int sctp_list_single_entry(struct list_head *head)
+{
+ return ((head->next != head) && (head->next == head->prev));
+}
+
/* Calculate the size (in bytes) occupied by the data of an iovec. */
static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
{
@@ -525,6 +533,19 @@ static inline int ipver2af(__u8 ipver)
};
}
+/* Convert from an address parameter type to an address family. */
+static inline int param_type2af(__u16 type)
+{
+ switch (type) {
+ case SCTP_PARAM_IPV4_ADDRESS:
+ return AF_INET;
+ case SCTP_PARAM_IPV6_ADDRESS:
+ return AF_INET6;
+ default:
+ return 0;
+ };
+}
+
/* Perform some sanity checks. */
static inline int sctp_sanity_check(void)
{
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 28d4c6409247..3eb9c18df0c5 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -41,6 +41,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -268,6 +269,9 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
struct sctp_chunk *asconf,
int vparam_len);
+struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+ union sctp_addr *addr);
+
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
@@ -330,12 +334,6 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
__u32 sctp_generate_tag(const struct sctp_endpoint *);
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
-/* 4th level prototypes */
-void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *,
- __u16 port, int iif);
-int sctp_addr2sockaddr(const union sctp_params, union sctp_addr *);
-int sockaddr2sctp_addr(const union sctp_addr *, union sctp_addr_param *);
-
/* Extern declarations for major data structures. */
const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
extern const sctp_sm_table_entry_t
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f77373f18e7e..7ba32701be00 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2003 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -45,6 +45,7 @@
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Anup Pemmaiah <pemmaiah@cc.usu.edu>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -217,86 +218,6 @@ extern struct sctp_globals {
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
-/*
- * Pointers to address related SCTP functions.
- * (i.e. things that depend on the address family.)
- */
-struct sctp_af {
- int (*sctp_xmit) (struct sk_buff *skb,
- struct sctp_transport *,
- int ipfragok);
- int (*setsockopt) (struct sock *sk,
- int level,
- int optname,
- char *optval,
- int optlen);
- int (*getsockopt) (struct sock *sk,
- int level,
- int optname,
- char *optval,
- int *optlen);
- struct dst_entry *(*get_dst) (struct sctp_association *asoc,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
- void (*get_saddr) (struct sctp_association *asoc,
- struct dst_entry *dst,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
- void (*copy_addrlist) (struct list_head *,
- struct net_device *);
- void (*dst_saddr) (union sctp_addr *saddr,
- struct dst_entry *dst,
- unsigned short port);
- int (*cmp_addr) (const union sctp_addr *addr1,
- const union sctp_addr *addr2);
- void (*addr_copy) (union sctp_addr *dst,
- union sctp_addr *src);
- void (*from_skb) (union sctp_addr *,
- struct sk_buff *skb,
- int saddr);
- void (*from_sk) (union sctp_addr *,
- struct sock *sk);
- void (*to_sk_saddr) (union sctp_addr *,
- struct sock *sk);
- void (*to_sk_daddr) (union sctp_addr *,
- struct sock *sk);
- int (*addr_valid) (union sctp_addr *,
- struct sctp_opt *);
- sctp_scope_t (*scope) (union sctp_addr *);
- void (*inaddr_any) (union sctp_addr *, unsigned short);
- int (*is_any) (const union sctp_addr *);
- int (*available) (union sctp_addr *,
- struct sctp_opt *);
- int (*skb_iif) (const struct sk_buff *sk);
- int (*is_ce) (const struct sk_buff *sk);
- void (*seq_dump_addr)(struct seq_file *seq,
- union sctp_addr *addr);
- __u16 net_header_len;
- int sockaddr_len;
- sa_family_t sa_family;
- struct list_head list;
-};
-
-struct sctp_af *sctp_get_af_specific(sa_family_t);
-int sctp_register_af(struct sctp_af *);
-
-/* Protocol family functions. */
-struct sctp_pf {
- void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
- void (*skb_msgname) (struct sk_buff *, char *, int *);
- int (*af_supported) (sa_family_t, struct sctp_opt *);
- int (*cmp_addr) (const union sctp_addr *,
- const union sctp_addr *,
- struct sctp_opt *);
- int (*bind_verify) (struct sctp_opt *, union sctp_addr *);
- int (*send_verify) (struct sctp_opt *, union sctp_addr *);
- int (*supported_addrs)(const struct sctp_opt *, __u16 *);
- struct sock *(*create_accept_sk) (struct sock *sk,
- struct sctp_association *asoc);
- void (*addr_v4map) (struct sctp_opt *, union sctp_addr *);
- struct sctp_af *af;
-};
-
/* SCTP Socket type: UDP or TCP style. */
typedef enum {
SCTP_SOCKET_UDP = 0,
@@ -488,6 +409,92 @@ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
return stream->ssn[id]++;
}
+/*
+ * Pointers to address related SCTP functions.
+ * (i.e. things that depend on the address family.)
+ */
+struct sctp_af {
+ int (*sctp_xmit) (struct sk_buff *skb,
+ struct sctp_transport *,
+ int ipfragok);
+ int (*setsockopt) (struct sock *sk,
+ int level,
+ int optname,
+ char *optval,
+ int optlen);
+ int (*getsockopt) (struct sock *sk,
+ int level,
+ int optname,
+ char *optval,
+ int *optlen);
+ struct dst_entry *(*get_dst) (struct sctp_association *asoc,
+ union sctp_addr *daddr,
+ union sctp_addr *saddr);
+ void (*get_saddr) (struct sctp_association *asoc,
+ struct dst_entry *dst,
+ union sctp_addr *daddr,
+ union sctp_addr *saddr);
+ void (*copy_addrlist) (struct list_head *,
+ struct net_device *);
+ void (*dst_saddr) (union sctp_addr *saddr,
+ struct dst_entry *dst,
+ unsigned short port);
+ int (*cmp_addr) (const union sctp_addr *addr1,
+ const union sctp_addr *addr2);
+ void (*addr_copy) (union sctp_addr *dst,
+ union sctp_addr *src);
+ void (*from_skb) (union sctp_addr *,
+ struct sk_buff *skb,
+ int saddr);
+ void (*from_sk) (union sctp_addr *,
+ struct sock *sk);
+ void (*to_sk_saddr) (union sctp_addr *,
+ struct sock *sk);
+ void (*to_sk_daddr) (union sctp_addr *,
+ struct sock *sk);
+ void (*from_addr_param) (union sctp_addr *,
+ union sctp_addr_param *,
+ __u16 port, int iif);
+ int (*to_addr_param) (const union sctp_addr *,
+ union sctp_addr_param *);
+ int (*addr_valid) (union sctp_addr *,
+ struct sctp_opt *);
+ sctp_scope_t (*scope) (union sctp_addr *);
+ void (*inaddr_any) (union sctp_addr *, unsigned short);
+ int (*is_any) (const union sctp_addr *);
+ int (*available) (union sctp_addr *,
+ struct sctp_opt *);
+ int (*skb_iif) (const struct sk_buff *sk);
+ int (*is_ce) (const struct sk_buff *sk);
+ void (*seq_dump_addr)(struct seq_file *seq,
+ union sctp_addr *addr);
+ __u16 net_header_len;
+ int sockaddr_len;
+ sa_family_t sa_family;
+ struct list_head list;
+};
+
+struct sctp_af *sctp_get_af_specific(sa_family_t);
+int sctp_register_af(struct sctp_af *);
+
+/* Protocol family functions. */
+struct sctp_pf {
+ void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
+ void (*skb_msgname) (struct sk_buff *, char *, int *);
+ int (*af_supported) (sa_family_t, struct sctp_opt *);
+ int (*cmp_addr) (const union sctp_addr *,
+ const union sctp_addr *,
+ struct sctp_opt *);
+ int (*bind_verify) (struct sctp_opt *, union sctp_addr *);
+ int (*send_verify) (struct sctp_opt *, union sctp_addr *);
+ int (*supported_addrs)(const struct sctp_opt *, __u16 *);
+ struct sock *(*create_accept_sk) (struct sock *sk,
+ struct sctp_association *asoc);
+ void (*addr_v4map) (struct sctp_opt *, union sctp_addr *);
+ struct sctp_af *af;
+};
+
+
/* Structure to track chunk fragments that have been acked, but peer
* fragments of the same message have not.
*/
@@ -1688,6 +1695,8 @@ struct sctp_transport *sctp_assoc_choose_shutdown_transport(
void sctp_assoc_update_retran_path(struct sctp_association *);
struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *,
const union sctp_addr *);
+int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
+ const union sctp_addr *laddr);
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
const union sctp_addr *address,
const int gfp);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index da96859dba92..45f96479510f 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -551,13 +551,15 @@ struct sctp_status {
};
/*
- * 8.3, 8.5 get all peer/local addresses on a socket
- * This parameter struct is for getsockopt
+ * 8.3, 8.5 get all peer/local addresses in an association.
+ * This parameter struct is used by SCTP_GET_PEER_ADDRS and
+ * SCTP_GET_LOCAL_ADDRS socket options used internally to implement
+ * sctp_getpaddrs() and sctp_getladdrs() API.
*/
struct sctp_getaddrs {
sctp_assoc_t assoc_id;
int addr_num;
- struct sockaddr_storage *addrs;
+ struct sockaddr *addrs;
};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 04b8f47837a9..17cac6fdaa34 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -74,8 +74,6 @@ struct scsi_device {
unsigned wdtr:1; /* Device supports WDTR messages */
unsigned ppr:1; /* Device supports PPR messages */
unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
- unsigned tagged_queue:1;/* This is going away!!!! Look at simple_tags
- instead!!! Please fix your driver now!! */
unsigned simple_tags:1; /* simple queue tag messages are enabled */
unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
unsigned single_lun:1; /* Indicates we should only allow I/O to
diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
index d591d365c983..98719407d554 100644
--- a/include/scsi/scsi_request.h
+++ b/include/scsi/scsi_request.h
@@ -45,7 +45,7 @@ struct scsi_request {
level driver) of this request */
};
-extern struct scsi_request *scsi_allocate_request(struct scsi_device *);
+extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int);
extern void scsi_release_request(struct scsi_request *);
extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
void *buffer, unsigned bufflen,
diff --git a/init/Kconfig b/init/Kconfig
index c296f6bee03c..31871d1982f2 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -33,7 +33,7 @@ config EXPERIMENTAL
drivers that are currently considered to be in the alpha-test phase.
config CLEAN_COMPILE
- bool "Don't select drivers known to be broken" if EXPERIMENTAL
+ bool "Select only drivers expected to compile cleanly" if EXPERIMENTAL
default y
help
Select this option if you don't even want to see the option
diff --git a/kernel/configs.c b/kernel/configs.c
index dd7acd64b214..7faf6837bfb2 100644
--- a/kernel/configs.c
+++ b/kernel/configs.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/compile.h>
#include <linux/version.h>
@@ -41,75 +42,59 @@
/**************************************************/
/* globals and useful constants */
-static char *IKCONFIG_NAME = "ikconfig";
-static char *IKCONFIG_VERSION = "0.5";
+static const char IKCONFIG_NAME[] = "ikconfig";
+static const char IKCONFIG_VERSION[] = "0.6";
-static int ikconfig_current_size = 0;
-static struct proc_dir_entry *ikconfig_dir, *current_config, *built_with;
-
-static int
-ikconfig_permission_current(struct inode *inode, int op, struct nameidata *nd)
-{
- /* anyone can read the device, no one can write to it */
- return (op == MAY_READ) ? 0 : -EACCES;
-}
+static int ikconfig_size;
+static struct proc_dir_entry *ikconfig_dir;
static ssize_t
-ikconfig_output_current(struct file *file, char *buf,
- size_t len, loff_t * offset)
-{
- int i, limit;
- int cnt;
-
- limit = (ikconfig_current_size > len) ? len : ikconfig_current_size;
- for (i = file->f_pos, cnt = 0;
- i < ikconfig_current_size && cnt < limit; i++, cnt++) {
- if (put_user(ikconfig_config[i], buf + cnt))
- return -EFAULT;
- }
- file->f_pos = i;
- return cnt;
-}
-
-static int
-ikconfig_open_current(struct inode *inode, struct file *file)
-{
- if (file->f_mode & FMODE_READ) {
- inode->i_size = ikconfig_current_size;
- file->f_pos = 0;
- }
- return 0;
-}
-
-static int
-ikconfig_close_current(struct inode *inode, struct file *file)
+ikconfig_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
{
- return 0;
+ loff_t pos = *offset;
+ ssize_t count;
+
+ if (pos >= ikconfig_size)
+ return 0;
+
+ count = min(len, (size_t)(ikconfig_size - pos));
+ if(copy_to_user(buf, ikconfig_config + pos, count))
+ return -EFAULT;
+
+ *offset += count;
+ return count;
}
-static struct file_operations ikconfig_file_ops = {
- .read = ikconfig_output_current,
- .open = ikconfig_open_current,
- .release = ikconfig_close_current,
-};
-
-static struct inode_operations ikconfig_inode_ops = {
- .permission = ikconfig_permission_current,
+static struct file_operations config_fops = {
+ .owner = THIS_MODULE,
+ .read = ikconfig_read,
};
/***************************************************/
-/* proc_read_built_with: let people read the info */
+/* built_with_show: let people read the info */
/* we have on the tools used to build this kernel */
-static int
-proc_read_built_with(char *page, char **start,
- off_t off, int count, int *eof, void *data)
+static int builtwith_show(struct seq_file *seq, void *v)
+{
+ seq_printf(seq,
+ "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n",
+ ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+ return 0;
+}
+
+static int built_with_open(struct inode *inode, struct file *file)
{
- *eof = 1;
- return sprintf(page,
- "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n",
- ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+ return single_open(file, builtwith_show, PDE(inode)->data);
}
+
+static struct file_operations builtwith_fops = {
+ .owner = THIS_MODULE,
+ .open = built_with_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/***************************************************/
/* ikconfig_init: start up everything we need to */
@@ -117,41 +102,33 @@ proc_read_built_with(char *page, char **start,
int __init
ikconfig_init(void)
{
- int result = 0;
+ struct proc_dir_entry *entry;
printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n",
IKCONFIG_VERSION);
/* create the ikconfig directory */
ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL);
- if (ikconfig_dir == NULL) {
- result = -ENOMEM;
+ if (ikconfig_dir == NULL)
goto leave;
- }
ikconfig_dir->owner = THIS_MODULE;
/* create the current config file */
- current_config = create_proc_entry("config", S_IFREG | S_IRUGO,
- ikconfig_dir);
- if (current_config == NULL) {
- result = -ENOMEM;
+ entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir);
+ if (!entry)
goto leave2;
- }
- current_config->proc_iops = &ikconfig_inode_ops;
- current_config->proc_fops = &ikconfig_file_ops;
- current_config->owner = THIS_MODULE;
- ikconfig_current_size = strlen(ikconfig_config);
- current_config->size = ikconfig_current_size;
+
+ entry->proc_fops = &config_fops;
+ entry->size = ikconfig_size = strlen(ikconfig_config);
/* create the "built with" file */
- built_with = create_proc_read_entry("built_with", 0444, ikconfig_dir,
- proc_read_built_with, NULL);
- if (built_with == NULL) {
- result = -ENOMEM;
+ entry = create_proc_entry("built_with", S_IFREG | S_IRUGO,
+ ikconfig_dir);
+ if (!entry)
goto leave3;
- }
- built_with->owner = THIS_MODULE;
- goto leave;
+ entry->proc_fops = &builtwith_fops;
+
+ return 0;
leave3:
/* remove the file from proc */
@@ -162,7 +139,7 @@ leave2:
remove_proc_entry(IKCONFIG_NAME, NULL);
leave:
- return result;
+ return -ENOMEM;
}
/***************************************************/
diff --git a/kernel/futex.c b/kernel/futex.c
index 4557addfc6d6..a4feceee661a 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -5,6 +5,9 @@
* Generalized futexes, futex requeueing, misc fixes by Ingo Molnar
* (C) Copyright 2003 Red Hat Inc, All Rights Reserved
*
+ * Removed page pinning, fix privately mapped COW pages and other cleanups
+ * (C) Copyright 2003 Jamie Lokier
+ *
* Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
* enough at me, Linus for the original (flawed) idea, Matthew
* Kirkwood for proof-of-concept implementation.
@@ -33,12 +36,32 @@
#include <linux/hash.h>
#include <linux/init.h>
#include <linux/futex.h>
-#include <linux/vcache.h>
#include <linux/mount.h>
+#include <linux/pagemap.h>
#define FUTEX_HASHBITS 8
/*
+ * Futexes are matched on equal values of this key.
+ * The key type depends on whether it's a shared or private mapping.
+ */
+union futex_key {
+ struct {
+ unsigned long pgoff;
+ struct inode *inode;
+ } shared;
+ struct {
+ unsigned long uaddr;
+ struct mm_struct *mm;
+ } private;
+ struct {
+ unsigned long word;
+ void *ptr;
+ } both;
+ int offset;
+};
+
+/*
* We use this hashed waitqueue instead of a normal wait_queue_t, so
* we can wake only the relevant ones (hashed queues may be shared):
*/
@@ -46,12 +69,8 @@ struct futex_q {
struct list_head list;
wait_queue_head_t waiters;
- /* Page struct and offset within it. */
- struct page *page;
- int offset;
-
- /* the virtual => physical COW-safe cache */
- vcache_t vcache;
+ /* Key which the futex is hashed on. */
+ union futex_key key;
/* For fd, sigio sent using these. */
int fd;
@@ -66,111 +85,149 @@ static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
static struct vfsmount *futex_mnt;
/*
- * These are all locks that are necessery to look up a physical
- * mapping safely, and modify/search the futex hash, atomically:
+ * We hash on the keys returned from get_futex_key (see below).
*/
-static inline void lock_futex_mm(void)
+static inline struct list_head *hash_futex(union futex_key *key)
{
- spin_lock(&current->mm->page_table_lock);
- spin_lock(&vcache_lock);
- spin_lock(&futex_lock);
-}
-
-static inline void unlock_futex_mm(void)
-{
- spin_unlock(&futex_lock);
- spin_unlock(&vcache_lock);
- spin_unlock(&current->mm->page_table_lock);
+ return &futex_queues[hash_long(key->both.word
+ + (unsigned long) key->both.ptr
+ + key->offset, FUTEX_HASHBITS)];
}
/*
- * The physical page is shared, so we can hash on its address:
+ * Return 1 if two futex_keys are equal, 0 otherwise.
*/
-static inline struct list_head *hash_futex(struct page *page, int offset)
+static inline int match_futex(union futex_key *key1, union futex_key *key2)
{
- return &futex_queues[hash_long((unsigned long)page + offset,
- FUTEX_HASHBITS)];
+ return (key1->both.word == key2->both.word
+ && key1->both.ptr == key2->both.ptr
+ && key1->offset == key2->offset);
}
/*
- * Get kernel address of the user page and pin it.
+ * Get parameters which are the keys for a futex.
+ *
+ * For shared mappings, it's (page->index, vma->vm_file->f_dentry->d_inode,
+ * offset_within_page). For private mappings, it's (uaddr, current->mm).
+ * We can usually work out the index without swapping in the page.
*
- * Must be called with (and returns with) all futex-MM locks held.
+ * Returns: 0, or negative error code.
+ * The key words are stored in *key on success.
+ *
+ * Should be called with &current->mm->mmap_sem,
+ * but NOT &futex_lock or &current->mm->page_table_lock.
*/
-static inline struct page *__pin_page_atomic (struct page *page)
-{
- if (!PageReserved(page))
- get_page(page);
- return page;
-}
-
-static struct page *__pin_page(unsigned long addr)
+static int get_futex_key(unsigned long uaddr, union futex_key *key)
{
struct mm_struct *mm = current->mm;
- struct page *page, *tmp;
+ struct vm_area_struct *vma;
+ struct page *page;
int err;
/*
- * Do a quick atomic lookup first - this is the fastpath.
+ * The futex address must be "naturally" aligned.
+ */
+ key->offset = uaddr % PAGE_SIZE;
+ if (unlikely((key->offset % sizeof(u32)) != 0))
+ return -EINVAL;
+ uaddr -= key->offset;
+
+ /*
+ * The futex is hashed differently depending on whether
+ * it's in a shared or private mapping. So check vma first.
+ */
+ vma = find_extend_vma(mm, uaddr);
+ if (unlikely(!vma))
+ return -EFAULT;
+
+ /*
+ * Permissions.
*/
- page = follow_page(mm, addr, 0);
- if (likely(page != NULL))
- return __pin_page_atomic(page);
+ if (unlikely((vma->vm_flags & (VM_IO|VM_READ)) != VM_READ))
+ return (vma->vm_flags & VM_IO) ? -EPERM : -EACCES;
/*
- * No luck - need to fault in the page:
+ * Private mappings are handled in a simple way.
+ *
+ * NOTE: When userspace waits on a MAP_SHARED mapping, even if
+ * it's a read-only handle, it's expected that futexes attach to
+ * the object not the particular process. Therefore we use
+ * VM_MAYSHARE here, not VM_SHARED which is restricted to shared
+ * mappings of _writable_ handles.
*/
-repeat_lookup:
+ if (likely(!(vma->vm_flags & VM_MAYSHARE))) {
+ key->private.mm = mm;
+ key->private.uaddr = uaddr;
+ return 0;
+ }
- unlock_futex_mm();
+ /*
+ * Linear mappings are also simple.
+ */
+ key->shared.inode = vma->vm_file->f_dentry->d_inode;
+ if (likely(!(vma->vm_flags & VM_NONLINEAR))) {
+ key->shared.pgoff = (((uaddr - vma->vm_start) >> PAGE_SHIFT)
+ + vma->vm_pgoff);
+ return 0;
+ }
- down_read(&mm->mmap_sem);
- err = get_user_pages(current, mm, addr, 1, 0, 0, &page, NULL);
- up_read(&mm->mmap_sem);
+ /*
+ * We could walk the page table to read the non-linear
+ * pte, and get the page index without fetching the page
+ * from swap. But that's a lot of code to duplicate here
+ * for a rare case, so we simply fetch the page.
+ */
- lock_futex_mm();
+ /*
+ * Do a quick atomic lookup first - this is the fastpath.
+ */
+ spin_lock(&current->mm->page_table_lock);
+ page = follow_page(mm, uaddr, 0);
+ if (likely(page != NULL)) {
+ key->shared.pgoff =
+ page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ spin_unlock(&current->mm->page_table_lock);
+ return 0;
+ }
+ spin_unlock(&current->mm->page_table_lock);
- if (err < 0)
- return NULL;
/*
- * Since the faulting happened with locks released, we have to
- * check for races:
+ * Do it the general way.
*/
- tmp = follow_page(mm, addr, 0);
- if (tmp != page) {
+ err = get_user_pages(current, mm, uaddr, 1, 0, 0, &page, NULL);
+ if (err >= 0) {
+ key->shared.pgoff =
+ page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
put_page(page);
- goto repeat_lookup;
}
-
- return page;
+ return err;
}
+
/*
* Wake up all waiters hashed on the physical page that is mapped
* to this virtual address:
*/
-static inline int futex_wake(unsigned long uaddr, int offset, int num)
+static inline int futex_wake(unsigned long uaddr, int num)
{
struct list_head *i, *next, *head;
- struct page *page;
- int ret = 0;
+ union futex_key key;
+ int ret;
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
- return -EFAULT;
- }
+ ret = get_futex_key(uaddr, &key);
+ if (unlikely(ret != 0))
+ goto out;
- head = hash_futex(page, offset);
+ head = hash_futex(&key);
+ spin_lock(&futex_lock);
list_for_each_safe(i, next, head) {
struct futex_q *this = list_entry(i, struct futex_q, list);
- if (this->page == page && this->offset == offset) {
+ if (match_futex (&this->key, &key)) {
list_del_init(i);
- __detach_vcache(&this->vcache);
wake_up_all(&this->waiters);
if (this->filp)
send_sigio(&this->filp->f_owner, this->fd, POLL_IN);
@@ -179,113 +236,74 @@ static inline int futex_wake(unsigned long uaddr, int offset, int num)
break;
}
}
+ spin_unlock(&futex_lock);
- unlock_futex_mm();
- put_page(page);
-
+out:
+ up_read(&current->mm->mmap_sem);
return ret;
}
/*
- * This gets called by the COW code, we have to rehash any
- * futexes that were pending on the old physical page, and
- * rehash it to the new physical page. The pagetable_lock
- * and vcache_lock is already held:
- */
-static void futex_vcache_callback(vcache_t *vcache, struct page *new_page)
-{
- struct futex_q *q = container_of(vcache, struct futex_q, vcache);
- struct list_head *head = hash_futex(new_page, q->offset);
-
- spin_lock(&futex_lock);
-
- if (!list_empty(&q->list)) {
- put_page(q->page);
- q->page = new_page;
- __pin_page_atomic(new_page);
- list_del(&q->list);
- list_add_tail(&q->list, head);
- }
-
- spin_unlock(&futex_lock);
-}
-
-/*
* Requeue all waiters hashed on one physical page to another
* physical page.
*/
-static inline int futex_requeue(unsigned long uaddr1, int offset1,
- unsigned long uaddr2, int offset2, int nr_wake, int nr_requeue)
+static inline int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
+ int nr_wake, int nr_requeue)
{
struct list_head *i, *next, *head1, *head2;
- struct page *page1 = NULL, *page2 = NULL;
- int ret = 0;
+ union futex_key key1, key2;
+ int ret;
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page1 = __pin_page(uaddr1 - offset1);
- if (!page1)
+ ret = get_futex_key(uaddr1, &key1);
+ if (unlikely(ret != 0))
goto out;
- page2 = __pin_page(uaddr2 - offset2);
- if (!page2)
+ ret = get_futex_key(uaddr2, &key2);
+ if (unlikely(ret != 0))
goto out;
- head1 = hash_futex(page1, offset1);
- head2 = hash_futex(page2, offset2);
+ head1 = hash_futex(&key1);
+ head2 = hash_futex(&key2);
+ spin_lock(&futex_lock);
list_for_each_safe(i, next, head1) {
struct futex_q *this = list_entry(i, struct futex_q, list);
- if (this->page == page1 && this->offset == offset1) {
+ if (match_futex (&this->key, &key1)) {
list_del_init(i);
- __detach_vcache(&this->vcache);
if (++ret <= nr_wake) {
wake_up_all(&this->waiters);
if (this->filp)
send_sigio(&this->filp->f_owner,
this->fd, POLL_IN);
} else {
- put_page(this->page);
- __pin_page_atomic (page2);
list_add_tail(i, head2);
- __attach_vcache(&this->vcache, uaddr2,
- current->mm, futex_vcache_callback);
- this->offset = offset2;
- this->page = page2;
+ this->key = key2;
if (ret - nr_wake >= nr_requeue)
break;
}
}
}
+ spin_unlock(&futex_lock);
out:
- unlock_futex_mm();
-
- if (page1)
- put_page(page1);
- if (page2)
- put_page(page2);
-
+ up_read(&current->mm->mmap_sem);
return ret;
}
-static inline void __queue_me(struct futex_q *q, struct page *page,
- unsigned long uaddr, int offset,
- int fd, struct file *filp)
+static inline void queue_me(struct futex_q *q, union futex_key *key,
+ int fd, struct file *filp)
{
- struct list_head *head = hash_futex(page, offset);
+ struct list_head *head = hash_futex(key);
- q->offset = offset;
+ q->key = *key;
q->fd = fd;
q->filp = filp;
- q->page = page;
+ spin_lock(&futex_lock);
list_add_tail(&q->list, head);
- /*
- * We register a futex callback to this virtual address,
- * to make sure a COW properly rehashes the futex-queue.
- */
- __attach_vcache(&q->vcache, uaddr, current->mm, futex_vcache_callback);
+ spin_unlock(&futex_lock);
}
/* Return 1 if we were still queued (ie. 0 means we were woken) */
@@ -293,83 +311,107 @@ static inline int unqueue_me(struct futex_q *q)
{
int ret = 0;
- spin_lock(&vcache_lock);
spin_lock(&futex_lock);
if (!list_empty(&q->list)) {
list_del(&q->list);
- __detach_vcache(&q->vcache);
ret = 1;
}
spin_unlock(&futex_lock);
- spin_unlock(&vcache_lock);
return ret;
}
-static inline int futex_wait(unsigned long uaddr,
- int offset,
- int val,
- unsigned long time)
+static inline int futex_wait(unsigned long uaddr, int val, unsigned long time)
{
DECLARE_WAITQUEUE(wait, current);
- int ret = 0, curval;
- struct page *page;
+ int ret, curval;
+ union futex_key key;
struct futex_q q;
+ try_again:
init_waitqueue_head(&q.waiters);
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
- return -EFAULT;
- }
- __queue_me(&q, page, uaddr, offset, -1, NULL);
+ ret = get_futex_key(uaddr, &key);
+ if (unlikely(ret != 0))
+ goto out_release_sem;
+
+ queue_me(&q, &key, -1, NULL);
/*
- * Page is pinned, but may no longer be in this address space.
- * It cannot schedule, so we access it with the spinlock held.
+ * Access the page after the futex is queued.
+ * We hold the mmap semaphore, so the mapping cannot have changed
+ * since we looked it up.
*/
if (get_user(curval, (int *)uaddr) != 0) {
- unlock_futex_mm();
ret = -EFAULT;
- goto out;
+ goto out_unqueue;
}
if (curval != val) {
- unlock_futex_mm();
ret = -EWOULDBLOCK;
- goto out;
+ goto out_unqueue;
}
+
+ /*
+ * Now the futex is queued and we have checked the data, we
+ * don't want to hold mmap_sem while we sleep.
+ */
+ up_read(&current->mm->mmap_sem);
+
/*
- * The get_user() above might fault and schedule so we
- * cannot just set TASK_INTERRUPTIBLE state when queueing
- * ourselves into the futex hash. This code thus has to
+ * There might have been scheduling since the queue_me(), as we
+ * cannot hold a spinlock across the get_user() in case it
+ * faults. So we cannot just set TASK_INTERRUPTIBLE state when
+ * queueing ourselves into the futex hash. This code thus has to
* rely on the futex_wake() code doing a wakeup after removing
* the waiter from the list.
*/
add_wait_queue(&q.waiters, &wait);
+ spin_lock(&futex_lock);
set_current_state(TASK_INTERRUPTIBLE);
- if (!list_empty(&q.list)) {
- unlock_futex_mm();
- time = schedule_timeout(time);
+
+ if (unlikely(list_empty(&q.list))) {
+ /*
+ * We were woken already.
+ */
+ spin_unlock(&futex_lock);
+ set_current_state(TASK_RUNNING);
+ return 0;
}
+
+ spin_unlock(&futex_lock);
+ time = schedule_timeout(time);
set_current_state(TASK_RUNNING);
+
/*
* NOTE: we don't remove ourselves from the waitqueue because
* we are the only user of it.
*/
- if (time == 0) {
- ret = -ETIMEDOUT;
- goto out;
- }
+
+ /*
+ * Were we woken or interrupted for a valid reason?
+ */
+ ret = unqueue_me(&q);
+ if (ret == 0)
+ return 0;
+ if (time == 0)
+ return -ETIMEDOUT;
if (signal_pending(current))
- ret = -EINTR;
-out:
- /* Were we woken up anyway? */
+ return -EINTR;
+
+ /*
+ * No, it was a spurious wakeup. Try again. Should never happen. :)
+ */
+ goto try_again;
+
+ out_unqueue:
+ /*
+ * Were we unqueued anyway?
+ */
if (!unqueue_me(&q))
ret = 0;
- put_page(q.page);
-
+ out_release_sem:
+ up_read(&current->mm->mmap_sem);
return ret;
}
@@ -378,7 +420,6 @@ static int futex_close(struct inode *inode, struct file *filp)
struct futex_q *q = filp->private_data;
unqueue_me(q);
- put_page(q->page);
kfree(filp->private_data);
return 0;
}
@@ -406,12 +447,12 @@ static struct file_operations futex_fops = {
/* Signal allows caller to avoid the race which would occur if they
set the sigio stuff up afterwards. */
-static int futex_fd(unsigned long uaddr, int offset, int signal)
+static int futex_fd(unsigned long uaddr, int signal)
{
- struct page *page = NULL;
struct futex_q *q;
+ union futex_key key;
struct file *filp;
- int ret;
+ int ret, err;
ret = -EINVAL;
if (signal < 0 || signal > _NSIG)
@@ -450,69 +491,47 @@ static int futex_fd(unsigned long uaddr, int offset, int signal)
goto out;
}
- lock_futex_mm();
-
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
+ down_read(&current->mm->mmap_sem);
+ err = get_futex_key(uaddr, &key);
+ up_read(&current->mm->mmap_sem);
+ if (unlikely(err != 0)) {
put_unused_fd(ret);
put_filp(filp);
kfree(q);
- return -EFAULT;
+ return err;
}
init_waitqueue_head(&q->waiters);
filp->private_data = q;
- __queue_me(q, page, uaddr, offset, ret, filp);
-
- unlock_futex_mm();
+ queue_me(q, &key, ret, filp);
/* Now we map fd to filp, so userspace can access it */
fd_install(ret, filp);
- page = NULL;
out:
- if (page)
- put_page(page);
return ret;
}
long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout,
unsigned long uaddr2, int val2)
{
- unsigned long pos_in_page;
int ret;
- pos_in_page = uaddr % PAGE_SIZE;
-
- /* Must be "naturally" aligned */
- if (pos_in_page % sizeof(u32))
- return -EINVAL;
-
switch (op) {
case FUTEX_WAIT:
- ret = futex_wait(uaddr, pos_in_page, val, timeout);
+ ret = futex_wait(uaddr, val, timeout);
break;
case FUTEX_WAKE:
- ret = futex_wake(uaddr, pos_in_page, val);
+ ret = futex_wake(uaddr, val);
break;
case FUTEX_FD:
/* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
- ret = futex_fd(uaddr, pos_in_page, val);
+ ret = futex_fd(uaddr, val);
break;
case FUTEX_REQUEUE:
- {
- unsigned long pos_in_page2 = uaddr2 % PAGE_SIZE;
-
- /* Must be "naturally" aligned */
- if (pos_in_page2 % sizeof(u32))
- return -EINVAL;
-
- ret = futex_requeue(uaddr, pos_in_page, uaddr2, pos_in_page2,
- val, val2);
+ ret = futex_requeue(uaddr, uaddr2, val, val2);
break;
- }
default:
ret = -ENOSYS;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 142ccfcf835b..3180fa00d248 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -35,6 +35,7 @@
#include <linux/writeback.h>
#include <linux/hugetlb.h>
#include <linux/security.h>
+#include <linux/initrd.h>
#include <asm/uaccess.h>
#ifdef CONFIG_ROOT_NFS
diff --git a/mm/Makefile b/mm/Makefile
index a8de64ff3525..c66aba5886f8 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -9,6 +9,6 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \
obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
page_alloc.o page-writeback.o pdflush.o readahead.o \
- slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y)
+ slab.o swap.o truncate.o vmscan.o $(mmu-y)
obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
diff --git a/mm/fremap.c b/mm/fremap.c
index 8f96af82b4e8..b19bdde07bb6 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -144,9 +144,10 @@ long sys_remap_file_pages(unsigned long start, unsigned long size,
return err;
#endif
- down_read(&mm->mmap_sem);
-
+ /* We need down_write() to change vma->vm_flags. */
+ down_write(&mm->mmap_sem);
vma = find_vma(mm, start);
+
/*
* Make sure the vma is shared, that it supports prefaulting,
* and that the remapped range is valid and fully within
@@ -155,11 +156,27 @@ long sys_remap_file_pages(unsigned long start, unsigned long size,
if (vma && (vma->vm_flags & VM_SHARED) &&
vma->vm_ops && vma->vm_ops->populate &&
end > start && start >= vma->vm_start &&
- end <= vma->vm_end)
- err = vma->vm_ops->populate(vma, start, size, vma->vm_page_prot,
- pgoff, flags & MAP_NONBLOCK);
-
- up_read(&mm->mmap_sem);
+ end <= vma->vm_end) {
+
+ /* Must set VM_NONLINEAR before any pages are populated. */
+ if (pgoff != ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff)
+ vma->vm_flags |= VM_NONLINEAR;
+
+ /* ->populate can take a long time, so downgrade the lock. */
+ downgrade_write(&mm->mmap_sem);
+ err = vma->vm_ops->populate(vma, start, size,
+ vma->vm_page_prot,
+ pgoff, flags & MAP_NONBLOCK);
+
+ /*
+ * We can't clear VM_NONLINEAR because we'd have to do
+ * it after ->populate completes, and that would prevent
+ * downgrading the lock. (Locks can't be upgraded).
+ */
+ up_read(&mm->mmap_sem);
+ } else {
+ up_write(&mm->mmap_sem);
+ }
return err;
}
diff --git a/mm/memory.c b/mm/memory.c
index 61b782f40df9..980953dbbfb4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -43,7 +43,6 @@
#include <linux/swap.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-#include <linux/vcache.h>
#include <linux/rmap-locking.h>
#include <linux/module.h>
@@ -962,7 +961,6 @@ static inline void establish_pte(struct vm_area_struct * vma, unsigned long addr
static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address,
pte_t *page_table)
{
- invalidate_vcache(address, vma->vm_mm, new_page);
flush_cache_page(vma, address);
establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
}
diff --git a/mm/mremap.c b/mm/mremap.c
index d9180f18ad6c..0412a204cb69 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -420,7 +420,7 @@ unsigned long do_mremap(unsigned long addr,
if (flags & MREMAP_MAYMOVE) {
if (!(flags & MREMAP_FIXED)) {
unsigned long map_flags = 0;
- if (vma->vm_flags & VM_SHARED)
+ if (vma->vm_flags & VM_MAYSHARE)
map_flags |= MAP_SHARED;
new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 453f291437ab..4051a19b0ab5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -220,6 +220,7 @@ static inline void free_pages_check(const char *function, struct page *page)
1 << PG_locked |
1 << PG_active |
1 << PG_reclaim |
+ 1 << PG_slab |
1 << PG_writeback )))
bad_page(function, page);
if (PageDirty(page))
@@ -542,8 +543,7 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order,
int do_retry;
struct reclaim_state reclaim_state;
- if (wait)
- might_sleep();
+ might_sleep_if(wait);
cold = 0;
if (gfp_mask & __GFP_COLD)
diff --git a/mm/rmap.c b/mm/rmap.c
index 06377cb9c907..c4434f218e4d 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -503,8 +503,7 @@ struct pte_chain *pte_chain_alloc(int gfp_flags)
struct pte_chain *ret;
struct pte_chain **pte_chainp;
- if (gfp_flags & __GFP_WAIT)
- might_sleep();
+ might_sleep_if(gfp_flags & __GFP_WAIT);
pte_chainp = &get_cpu_var(local_pte_chain);
if (*pte_chainp) {
diff --git a/mm/slab.c b/mm/slab.c
index 6093193d0456..34b62ca48429 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -787,7 +787,8 @@ static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
* vm_scan(). Shouldn't be a worry.
*/
while (i--) {
- ClearPageSlab(page);
+ if (!TestClearPageSlab(page))
+ BUG();
page++;
}
sub_page_state(nr_slab, nr_freed);
@@ -1813,8 +1814,7 @@ alloc_done:
static inline void
cache_alloc_debugcheck_before(kmem_cache_t *cachep, int flags)
{
- if (flags & __GFP_WAIT)
- might_sleep();
+ might_sleep_if(flags & __GFP_WAIT);
#if DEBUG
kmem_flagcheck(cachep, flags);
#endif
diff --git a/mm/vcache.c b/mm/vcache.c
deleted file mode 100644
index 599e0f25490d..000000000000
--- a/mm/vcache.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * linux/mm/vcache.c
- *
- * virtual => physical page mapping cache. Users of this mechanism
- * register callbacks for a given (virt,mm,phys) page mapping, and
- * the kernel guarantees to call back when this mapping is invalidated.
- * (ie. upon COW or unmap.)
- *
- * Started by Ingo Molnar, Copyright (C) 2002
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/hash.h>
-#include <linux/vcache.h>
-
-#define VCACHE_HASHBITS 8
-#define VCACHE_HASHSIZE (1 << VCACHE_HASHBITS)
-
-spinlock_t vcache_lock = SPIN_LOCK_UNLOCKED;
-
-static struct list_head hash[VCACHE_HASHSIZE];
-
-static struct list_head *hash_vcache(unsigned long address,
- struct mm_struct *mm)
-{
- return &hash[hash_long(address + (unsigned long)mm, VCACHE_HASHBITS)];
-}
-
-void __attach_vcache(vcache_t *vcache,
- unsigned long address,
- struct mm_struct *mm,
- void (*callback)(struct vcache_s *data, struct page *new))
-{
- struct list_head *hash_head;
-
- address &= PAGE_MASK;
- vcache->address = address;
- vcache->mm = mm;
- vcache->callback = callback;
-
- hash_head = hash_vcache(address, mm);
-
- list_add_tail(&vcache->hash_entry, hash_head);
-}
-
-void __detach_vcache(vcache_t *vcache)
-{
- list_del_init(&vcache->hash_entry);
-}
-
-void invalidate_vcache(unsigned long address, struct mm_struct *mm,
- struct page *new_page)
-{
- struct list_head *l, *hash_head;
- vcache_t *vcache;
-
- address &= PAGE_MASK;
-
- hash_head = hash_vcache(address, mm);
- /*
- * This is safe, because this path is called with the pagetable
- * lock held. So while other mm's might add new entries in
- * parallel, *this* mm is locked out, so if the list is empty
- * now then we do not have to take the vcache lock to see it's
- * really empty.
- */
- if (likely(list_empty(hash_head)))
- return;
-
- spin_lock(&vcache_lock);
- list_for_each(l, hash_head) {
- vcache = list_entry(l, vcache_t, hash_entry);
- if (vcache->address != address || vcache->mm != mm)
- continue;
- vcache->callback(vcache, new_page);
- }
- spin_unlock(&vcache_lock);
-}
-
-static int __init vcache_init(void)
-{
- unsigned int i;
-
- for (i = 0; i < VCACHE_HASHSIZE; i++)
- INIT_LIST_HEAD(hash + i);
- return 0;
-}
-__initcall(vcache_init);
-
diff --git a/net/Kconfig b/net/Kconfig
index 4c3474604a0c..7d76574a9cc3 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -676,7 +676,6 @@ config NET_SCHED
source "net/sched/Kconfig"
-#bool 'Network code profiler' CONFIG_NET_PROFILE
endmenu
menu "Network testing"
diff --git a/net/README b/net/README
deleted file mode 100644
index e509ec526c25..000000000000
--- a/net/README
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Maintainers and developers for networking code sections
-
-Code Section Bug Report Contact
--------------------+-------------------------------------------
-802 [other ] alan@lxorguk.ukuu.org.uk
- [token ring ] p.norton@computer.org
-appletalk jschlst@samba.org
-ax25 g4klx@g4klx.demon.co.uk
-bridge buytenh@gnu.org
-core alan@lxorguk.ukuu.org.uk
-decnet SteveW@ACM.org
-ethernet alan@lxorguk.ukuu.org.uk
-ipv4 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipv6 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipx acme@conectiva.com.br
-spx jschlst@samba.org
-irda dagb@cs.uit.no
-lapb g4klx@g4klx.demon.co.uk
-netrom g4klx@g4klx.demon.co.uk
-rose g4klx@g4klx.demon.co.uk
-wanrouter gene@compuserve.com, jaspreet@sangoma and dm@sangoma.com
-unix alan@lxorguk.ukuu.org.uk
-x25 g4klx@g4klx.demon.co.uk
-bluetooth maxk@qualcomm.com
-8021q greearb@candelatech.com, vlan@scry.wanfear.com
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 4d5469bd8140..217244bd611d 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1888,8 +1888,6 @@ EXPORT_SYMBOL(aarp_send_ddp);
EXPORT_SYMBOL(atrtr_get_dev);
EXPORT_SYMBOL(atalk_find_dev_addr);
-static char atalk_banner[] __initdata =
- KERN_INFO "NET4: AppleTalk 0.20 for Linux NET4.0\n";
static char atalk_err_snap[] __initdata =
KERN_CRIT "Unable to register DDP with SNAP.\n";
@@ -1908,7 +1906,6 @@ static int __init atalk_init(void)
aarp_proto_init();
atalk_proc_init();
atalk_register_sysctl();
- printk(atalk_banner);
return 0;
}
module_init(atalk_init);
@@ -1939,5 +1936,5 @@ module_exit(atalk_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alan Cox <Alan.Cox@linux.org>");
-MODULE_DESCRIPTION("AppleTalk 0.20 for Linux NET4.0\n");
+MODULE_DESCRIPTION("AppleTalk 0.20\n");
MODULE_ALIAS_NETPROTO(PF_APPLETALK);
diff --git a/net/atm/addr.c b/net/atm/addr.c
index 5974a1876116..459bdeed05f9 100644
--- a/net/atm/addr.c
+++ b/net/atm/addr.c
@@ -118,23 +118,24 @@ int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
{
unsigned long flags;
struct atm_dev_addr *walk;
- int total;
+ int total = 0, error;
+ struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
+
spin_lock_irqsave(&dev->lock, flags);
- total = 0;
- for (walk = dev->local; walk; walk = walk->next) {
+ for (walk = dev->local; walk; walk = walk->next)
total += sizeof(struct sockaddr_atmsvc);
- if (total > size) {
- spin_unlock_irqrestore(&dev->lock, flags);
- return -E2BIG;
- }
- if (copy_to_user(u_buf,&walk->addr,
- sizeof(struct sockaddr_atmsvc))) {
- spin_unlock_irqrestore(&dev->lock, flags);
- return -EFAULT;
- }
- u_buf++;
+ tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
+ if (!tmp_buf) {
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return -ENOMEM;
}
+ for (walk = dev->local; walk; walk = walk->next)
+ memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
spin_unlock_irqrestore(&dev->lock, flags);
- return total;
+ error = total > size ? -E2BIG : total;
+ if (copy_to_user(u_buf, tmp_buf, total < size ? total : size))
+ error = -EFAULT;
+ kfree(tmp_buf);
+ return error;
}
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index fa25cbdd9a80..0f9d98463a69 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -18,6 +18,7 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
#include <net/arp.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
+#include <linux/seq_file.h>
#include <linux/atmbr2684.h>
@@ -666,31 +667,57 @@ static int br2684_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
return -ENOIOCTLCMD;
}
-/* Never put more than 256 bytes in at once */
-static int br2684_proc_engine(loff_t pos, char *buf)
+#ifdef CONFIG_PROC_FS
+static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct list_head *lhd, *lhc;
- struct net_device *net_dev;
- struct br2684_dev *brdev;
- struct br2684_vcc *brvcc;
- list_for_each(lhd, &br2684_devs) {
- net_dev = list_entry_brdev(lhd);
- brdev = BRPRIV(net_dev);
- if (pos-- == 0)
- return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:"
- "%02X:%02X:%02X:%02X (%s)\n", net_dev->name,
- brdev->number,
- net_dev->dev_addr[0],
- net_dev->dev_addr[1],
- net_dev->dev_addr[2],
- net_dev->dev_addr[3],
- net_dev->dev_addr[4],
- net_dev->dev_addr[5],
- brdev->mac_was_set ? "set" : "auto");
- list_for_each(lhc, &brdev->brvccs) {
- brvcc = list_entry_brvcc(lhc);
- if (pos-- == 0)
- return sprintf(buf, " vcc %d.%d.%d: encaps=%s"
+ loff_t offs = 0;
+ struct br2684_dev *brd;
+
+ read_lock(&devs_lock);
+
+ list_for_each_entry(brd, &br2684_devs, br2684_devs) {
+ if (offs == *pos)
+ return brd;
+ ++offs;
+ }
+ return NULL;
+}
+
+static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct br2684_dev *brd = v;
+
+ ++*pos;
+
+ brd = list_entry(brd->br2684_devs.next,
+ struct br2684_dev, br2684_devs);
+ return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
+}
+
+static void br2684_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&devs_lock);
+}
+
+static int br2684_seq_show(struct seq_file *seq, void *v)
+{
+ const struct br2684_dev *brdev = v;
+ const struct net_device *net_dev = brdev->net_dev;
+ const struct br2684_vcc *brvcc;
+
+ seq_printf(seq, "dev %.16s: num=%d, mac=%02X:%02X:"
+ "%02X:%02X:%02X:%02X (%s)\n", net_dev->name,
+ brdev->number,
+ net_dev->dev_addr[0],
+ net_dev->dev_addr[1],
+ net_dev->dev_addr[2],
+ net_dev->dev_addr[3],
+ net_dev->dev_addr[4],
+ net_dev->dev_addr[5],
+ brdev->mac_was_set ? "set" : "auto");
+
+ list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
+ seq_printf(seq, " vcc %d.%d.%d: encaps=%s"
#ifndef FASTER_VERSION
", failed copies %u/%u"
#endif /* FASTER_VERSION */
@@ -711,63 +738,41 @@ static int br2684_proc_engine(loff_t pos, char *buf)
#undef bs
#undef b1
#endif /* CONFIG_ATM_BR2684_IPFILTER */
- }
}
return 0;
}
-static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count,
- loff_t *pos)
+static struct seq_operations br2684_seq_ops = {
+ .start = br2684_seq_start,
+ .next = br2684_seq_next,
+ .stop = br2684_seq_stop,
+ .show = br2684_seq_show,
+};
+
+static int br2684_proc_open(struct inode *inode, struct file *file)
{
- unsigned long page;
- int len = 0, x, left;
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
- left = PAGE_SIZE - 256;
- if (count < left)
- left = count;
- read_lock(&devs_lock);
- for (;;) {
- x = br2684_proc_engine(*pos, &((char *) page)[len]);
- if (x == 0)
- break;
- if (x > left)
- /*
- * This should only happen if the user passed in
- * a "count" too small for even one line
- */
- x = -EINVAL;
- if (x < 0) {
- len = x;
- break;
- }
- len += x;
- left -= x;
- (*pos)++;
- if (left < 256)
- break;
- }
- read_unlock(&devs_lock);
- if (len > 0 && copy_to_user(buf, (char *) page, len))
- len = -EFAULT;
- free_page(page);
- return len;
+ return seq_open(file, &br2684_seq_ops);
}
-static struct file_operations br2684_proc_operations = {
- .owner = THIS_MODULE,
- .read = br2684_proc_read,
+static struct file_operations br2684_proc_ops = {
+ .owner = THIS_MODULE,
+ .open = br2684_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
};
extern struct proc_dir_entry *atm_proc_root; /* from proc.c */
+#endif
static int __init br2684_init(void)
{
+#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p;
if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
return -ENOMEM;
- p->proc_fops = &br2684_proc_operations;
+ p->proc_fops = &br2684_proc_ops;
+#endif
br2684_ioctl_set(br2684_ioctl);
return 0;
}
@@ -779,7 +784,9 @@ static void __exit br2684_exit(void)
struct br2684_vcc *brvcc;
br2684_ioctl_set(NULL);
+#ifdef CONFIG_PROC_FS
remove_proc_entry("br2684", atm_proc_root);
+#endif
while (!list_empty(&br2684_devs)) {
net_dev = list_entry_brdev(br2684_devs.next);
diff --git a/net/atm/common.c b/net/atm/common.c
index 6fde6b018418..62c8f0a72179 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -422,26 +422,31 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
}
if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
- if (error) {
- vcc_remove_socket(vcc->sk);
- return error;
- }
+ if (error)
+ goto fail;
DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal);
DPRINTK(" TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class,
vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
DPRINTK(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
- if (!try_module_get(dev->ops->owner))
- return -ENODEV;
+ if (!try_module_get(dev->ops->owner)) {
+ error = -ENODEV;
+ goto fail;
+ }
+
if (dev->ops->open) {
- error = dev->ops->open(vcc,vpi,vci);
- if (error) {
- module_put(dev->ops->owner);
- vcc_remove_socket(vcc->sk);
- return error;
- }
+ if ((error = dev->ops->open(vcc,vpi,vci)))
+ goto put_module_fail;
}
return 0;
+
+put_module_fail:
+ module_put(dev->ops->owner);
+fail:
+ vcc_remove_socket(vcc->sk);
+ /* ensure we get dev module ref count correct */
+ vcc->dev = NULL;
+ return error;
}
@@ -1109,12 +1114,10 @@ static int __init atm_init(void)
printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
goto failure;
}
-#ifdef CONFIG_PROC_FS
if ((error = atm_proc_init()) < 0) {
printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
goto failure;
}
-#endif
return 0;
failure:
@@ -1125,9 +1128,7 @@ failure:
static void __exit atm_exit(void)
{
-#ifdef CONFIG_PROC_FS
atm_proc_exit();
-#endif
atmsvc_exit();
atmpvc_exit();
}
diff --git a/net/atm/common.h b/net/atm/common.h
index eb98c9357431..426f1fa8bbb1 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -33,8 +33,21 @@ int atmpvc_init(void);
void atmpvc_exit(void);
int atmsvc_init(void);
void atmsvc_exit(void);
+
+#ifdef CONFIG_PROC_FS
int atm_proc_init(void);
void atm_proc_exit(void);
+#else
+static inline int atm_proc_init(void)
+{
+ return 0;
+}
+
+static inline void atm_proc_exit(void)
+{
+ /* nothing */
+}
+#endif /* CONFIG_PROC_FS */
/* SVC */
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index cca22da87ae6..4a8f73b41edf 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -341,16 +341,13 @@ static int pppoatm_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
return -ENOIOCTLCMD;
}
-/* the following avoids some spurious warnings from the compiler */
-#define UNUSED __attribute__((unused))
-
-static int __init UNUSED pppoatm_init(void)
+static int __init pppoatm_init(void)
{
pppoatm_ioctl_set(pppoatm_ioctl);
return 0;
}
-static void __exit UNUSED pppoatm_exit(void)
+static void __exit pppoatm_exit(void)
{
pppoatm_ioctl_set(NULL);
}
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 05c41491b431..d493ab2cd420 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -593,6 +593,10 @@ int atm_proc_dev_register(struct atm_dev *dev)
int digits,num;
int error;
+ /* No proc info */
+ if (!dev->ops->proc_read)
+ return 0;
+
error = -ENOMEM;
digits = 0;
for (num = dev->number; num; num /= 10) digits++;
@@ -619,6 +623,9 @@ fail1:
void atm_proc_dev_deregister(struct atm_dev *dev)
{
+ if (!dev->ops->proc_read)
+ return;
+
remove_proc_entry(dev->proc_name, atm_proc_root);
kfree(dev->proc_name);
}
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 9dee7f22c801..c0ce4d4d20b6 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -104,6 +104,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
static struct proto_ops pvc_proto_ops = {
.family = PF_ATMPVC,
+ .owner = THIS_MODULE,
.release = vcc_release,
.bind = pvc_bind,
@@ -134,6 +135,7 @@ static int pvc_create(struct socket *sock,int protocol)
static struct net_proto_family pvc_family_ops = {
.family = PF_ATMPVC,
.create = pvc_create,
+ .owner = THIS_MODULE,
};
diff --git a/net/atm/resources.c b/net/atm/resources.c
index ae3009c6eb4f..bd32c0caabe4 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -110,20 +110,16 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
list_add_tail(&dev->dev_list, &atm_devs);
spin_unlock(&atm_dev_lock);
-#ifdef CONFIG_PROC_FS
- if (ops->proc_read) {
- if (atm_proc_dev_register(dev) < 0) {
- printk(KERN_ERR "atm_dev_register: "
- "atm_proc_dev_register failed for dev %s\n",
- type);
- spin_lock(&atm_dev_lock);
- list_del(&dev->dev_list);
- spin_unlock(&atm_dev_lock);
- __free_atm_dev(dev);
- return NULL;
- }
+ if (atm_proc_dev_register(dev) < 0) {
+ printk(KERN_ERR "atm_dev_register: "
+ "atm_proc_dev_register failed for dev %s\n",
+ type);
+ spin_lock(&atm_dev_lock);
+ list_del(&dev->dev_list);
+ spin_unlock(&atm_dev_lock);
+ __free_atm_dev(dev);
+ return NULL;
}
-#endif
return dev;
}
@@ -133,10 +129,8 @@ void atm_dev_deregister(struct atm_dev *dev)
{
unsigned long warning_time;
-#ifdef CONFIG_PROC_FS
- if (dev->ops->proc_read)
- atm_proc_dev_deregister(dev);
-#endif
+ atm_proc_dev_deregister(dev);
+
spin_lock(&atm_dev_lock);
list_del(&dev->dev_list);
spin_unlock(&atm_dev_lock);
diff --git a/net/atm/resources.h b/net/atm/resources.h
index c4ecc1be6a26..1b6bad8db9cc 100644
--- a/net/atm/resources.h
+++ b/net/atm/resources.h
@@ -24,6 +24,18 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
int atm_proc_dev_register(struct atm_dev *dev);
void atm_proc_dev_deregister(struct atm_dev *dev);
-#endif
+#else
+
+static inline int atm_proc_dev_register(struct atm_dev *dev)
+{
+ return 0;
+}
+
+static inline void atm_proc_dev_deregister(struct atm_dev *dev)
+{
+ /* nothing */
+}
+
+#endif /* CONFIG_PROC_FS */
#endif
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 07c0849b37c7..aa46d6ae96d5 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -513,6 +513,7 @@ out:
static struct proto_ops svc_proto_ops = {
.family = PF_ATMSVC,
+ .owner = THIS_MODULE,
.release = svc_release,
.bind = svc_bind,
@@ -549,6 +550,7 @@ static int svc_create(struct socket *sock,int protocol)
static struct net_proto_family svc_family_ops = {
.family = PF_ATMSVC,
.create = svc_create,
+ .owner = THIS_MODULE,
};
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 4bb3798a2638..43662ed9a619 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -2003,8 +2003,6 @@ EXPORT_SYMBOL(asc2ax);
EXPORT_SYMBOL(null_ax25_address);
EXPORT_SYMBOL(ax25_display_timer);
-static char banner[] __initdata = KERN_INFO "NET4: G4KLX/GW4PTS AX.25 for Linux. Version 0.37 for Linux NET4.0\n";
-
static int __init ax25_init(void)
{
sock_register(&ax25_family_ops);
@@ -2016,7 +2014,6 @@ static int __init ax25_init(void)
proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
- printk(banner);
return 0;
}
module_init(ax25_init);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b1d5fff0d872..1292e56f3ce6 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -41,7 +41,6 @@
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
-#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 4b7c3315ff89..f62df6a7d153 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1794,7 +1794,7 @@ static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
if (p->next != &s->dlcs)
return p->next;
- for (p = s->list.next; p != &session_list; p = p->next) {
+ list_for_each(p, &session_list) {
s = list_entry(p, struct rfcomm_session, list);
__list_for_each(pp, &s->dlcs) {
seq->private = s;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 04dc0898ad1c..99aa7e32a695 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -39,7 +39,6 @@
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
-#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index b1ef7c76663d..f277bd75de7a 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -41,7 +41,6 @@
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
-#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
diff --git a/net/bridge/br.c b/net/bridge/br.c
index bf41aa2c61dd..3d90a9017bfc 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -32,8 +32,6 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
static int __init br_init(void)
{
- printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
-
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
if (br_netfilter_init())
return 1;
diff --git a/net/core/Makefile b/net/core/Makefile
index 28ec942019e8..22e715cbdeb2 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -11,6 +11,5 @@ obj-y += flow.o dev.o ethtool.o net-sysfs.o dev_mcast.o dst.o \
obj-$(CONFIG_NETFILTER) += netfilter.o
obj-$(CONFIG_NET_DIVERT) += dv.o
-obj-$(CONFIG_NET_PROFILE) += profile.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_NET_RADIO) += wireless.o
diff --git a/net/core/dev.c b/net/core/dev.c
index fe8976f4e757..2cf887cee6d7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -99,7 +99,6 @@
#include <linux/divert.h>
#include <net/dst.h>
#include <net/pkt_sched.h>
-#include <net/profile.h>
#include <net/checksum.h>
#include <linux/highmem.h>
#include <linux/init.h>
@@ -128,9 +127,6 @@ extern int plip_init(void);
*/
#undef OFFLINE_SAMPLE
-NET_PROFILE_DEFINE(dev_queue_xmit)
-NET_PROFILE_DEFINE(softnet_process)
-
/*
* The list of packet types we will receive (as opposed to discard)
* and the routines to invoke.
@@ -2981,7 +2977,6 @@ int unregister_netdevice(struct net_device *dev)
*/
static int __init net_dev_init(void)
{
- struct net_device *dev, **dp;
int i, rc = -ENOMEM;
BUG_ON(!dev_boot_phase);
@@ -3016,88 +3011,15 @@ static int __init net_dev_init(void)
atomic_set(&queue->backlog_dev.refcnt, 1);
}
-#ifdef CONFIG_NET_PROFILE
- net_profile_init();
- NET_PROFILE_REGISTER(dev_queue_xmit);
- NET_PROFILE_REGISTER(softnet_process);
-#endif
-
#ifdef OFFLINE_SAMPLE
samp_timer.expires = jiffies + (10 * HZ);
add_timer(&samp_timer);
#endif
- /*
- * Add the devices.
- * If the call to dev->init fails, the dev is removed
- * from the chain disconnecting the device until the
- * next reboot.
- *
- * NB At boot phase networking is dead. No locking is required.
- * But we still preserve dev_base_lock for sanity.
- */
-
- dp = &dev_base;
- while ((dev = *dp) != NULL) {
- spin_lock_init(&dev->queue_lock);
- spin_lock_init(&dev->xmit_lock);
-#ifdef CONFIG_NET_FASTROUTE
- dev->fastpath_lock = RW_LOCK_UNLOCKED;
-#endif
- dev->xmit_lock_owner = -1;
- dev->iflink = -1;
- dev_hold(dev);
-
- /*
- * Allocate name. If the init() fails
- * the name will be reissued correctly.
- */
- if (strchr(dev->name, '%'))
- dev_alloc_name(dev, dev->name);
-
- /*
- * Check boot time settings for the device.
- */
- netdev_boot_setup_check(dev);
-
- if ( (dev->init && dev->init(dev)) ||
- netdev_register_sysfs(dev) ) {
- /*
- * It failed to come up. It will be unhooked later.
- * dev_alloc_name can now advance to next suitable
- * name that is checked next.
- */
- dp = &dev->next;
- } else {
- dp = &dev->next;
- dev->ifindex = dev_new_index();
- dev->reg_state = NETREG_REGISTERED;
- if (dev->iflink == -1)
- dev->iflink = dev->ifindex;
- if (!dev->rebuild_header)
- dev->rebuild_header = default_rebuild_header;
- dev_init_scheduler(dev);
- set_bit(__LINK_STATE_PRESENT, &dev->state);
- }
- }
-
- /*
- * Unhook devices that failed to come up
- */
- dp = &dev_base;
- while ((dev = *dp) != NULL) {
- if (dev->reg_state != NETREG_REGISTERED) {
- write_lock_bh(&dev_base_lock);
- *dp = dev->next;
- write_unlock_bh(&dev_base_lock);
- dev_put(dev);
- } else {
- dp = &dev->next;
- }
- }
-
dev_boot_phase = 0;
+ probe_old_netdevs();
+
open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
diff --git a/net/core/dv.c b/net/core/dv.c
index 62352d7c9bcc..e7de41f94f9c 100644
--- a/net/core/dv.c
+++ b/net/core/dv.c
@@ -40,7 +40,6 @@ const char sysctl_divert_version[32]="0.46"; /* Current version */
static int __init dv_init(void)
{
- printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version);
return 0;
}
module_init(dv_init);
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 958385890b79..ae21f8932e45 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -11,7 +11,6 @@
*
*/
-#include <linux/workqueue.h>
#include <linux/config.h>
#include <linux/netdevice.h>
#include <linux/if.h>
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index ffb6a4471e85..07cbaf6b3c1e 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -101,7 +101,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg)
if (down_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
- for (i = nf_sockopts.next; i != &nf_sockopts; i = i->next) {
+ list_for_each(i, &nf_sockopts) {
struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i;
if (ops->pf == reg->pf
&& (overlap(ops->set_optmin, ops->set_optmax,
@@ -296,7 +296,7 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
if (down_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
- for (i = nf_sockopts.next; i != &nf_sockopts; i = i->next) {
+ list_for_each(i, &nf_sockopts) {
ops = (struct nf_sockopt_ops *)i;
if (ops->pf == pf) {
if (get) {
diff --git a/net/core/profile.c b/net/core/profile.c
deleted file mode 100644
index 0caedda13842..000000000000
--- a/net/core/profile.c
+++ /dev/null
@@ -1,294 +0,0 @@
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/ip.h>
-#include <linux/inet.h>
-#include <net/checksum.h>
-
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <net/profile.h>
-
-#ifdef CONFIG_NET_PROFILE
-
-atomic_t net_profile_active;
-struct timeval net_profile_adjust;
-
-NET_PROFILE_DEFINE(total);
-
-struct net_profile_slot *net_profile_chain = &net_prof_total;
-
-#ifdef __alpha__
-__u32 alpha_lo;
-long alpha_hi;
-
-static void alpha_tick(unsigned long);
-
-static struct timer_list alpha_timer = TIMER_INITIALIZER(alpha_tick, 0, 0);
-
-void alpha_tick(unsigned long dummy)
-{
- struct timeval dummy_stamp;
- net_profile_stamp(&dummy_stamp);
- alpha_timer.expires = jiffies + 4*HZ;
- add_timer(&alpha_timer);
-}
-
-#endif
-
-void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved)
-{
- struct net_profile_slot *s;
-
- net_profile_sub(entered, leaved);
- for (s = net_profile_chain; s; s = s->next) {
- if (s->active)
- net_profile_add(leaved, &s->irq);
- }
-}
-
-
-#ifdef CONFIG_PROC_FS
-static int profile_read_proc(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
-{
- off_t pos=0;
- off_t begin=0;
- int len=0;
- struct net_profile_slot *s;
-
- len+= sprintf(buffer, "Slot Hits Hi Lo OnIrqHi OnIrqLo Ufl\n");
-
- if (offset == 0) {
- cli();
- net_prof_total.active = 1;
- atomic_inc(&net_profile_active);
- NET_PROFILE_LEAVE(total);
- sti();
- }
- for (s = net_profile_chain; s; s = s->next) {
- struct net_profile_slot tmp;
-
- cli();
- tmp = *s;
-
- /* Wrong, but pretty close to truth */
-
- s->accumulator.tv_sec = 0;
- s->accumulator.tv_usec = 0;
- s->irq.tv_sec = 0;
- s->irq.tv_usec = 0;
- s->hits = 0;
- s->underflow = 0;
- /* Repair active count, it is possible, only if code has a bug */
- if (s->active) {
- s->active = 0;
- atomic_dec(&net_profile_active);
- }
- sti();
-
- net_profile_sub(&tmp.irq, &tmp.accumulator);
-
- len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d",
- tmp.id,
- tmp.hits,
- tmp.accumulator.tv_sec,
- tmp.accumulator.tv_usec,
- tmp.irq.tv_sec,
- tmp.irq.tv_usec,
- tmp.underflow, tmp.active);
-
- buffer[len++]='\n';
-
- pos=begin+len;
- if(pos<offset) {
- len=0;
- begin=pos;
- }
- if(pos>offset+length)
- goto done;
- }
- *eof = 1;
-
-done:
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- if (len < 0)
- len = 0;
- if (offset == 0) {
- cli();
- net_prof_total.active = 0;
- net_prof_total.hits = 0;
- net_profile_stamp(&net_prof_total.entered);
- sti();
- }
- return len;
-}
-#endif
-
-struct iphdr whitehole_iph;
-int whitehole_count;
-
-static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_device_stats *stats;
-
- stats = (struct net_device_stats *)dev->priv;
- stats->tx_packets++;
- stats->tx_bytes+=skb->len;
-
- dev_kfree_skb(skb);
- return 0;
-}
-
-static void whitehole_inject(unsigned long);
-int whitehole_init(struct net_device *dev);
-
-static struct timer_list whitehole_timer =
- TIMER_INITIALIZER(whitehole_inject, 0, 0);
-
-static struct net_device whitehole_dev = {
- .name = "whitehole",
- .init = whitehole_init,
-};
-
-static int whitehole_open(struct net_device *dev)
-{
- whitehole_count = 100000;
- whitehole_timer.expires = jiffies + 5*HZ;
- add_timer(&whitehole_timer);
- return 0;
-}
-
-static int whitehole_close(struct net_device *dev)
-{
- del_timer(&whitehole_timer);
- return 0;
-}
-
-static void whitehole_inject(unsigned long dummy)
-{
- struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv;
- extern int netdev_dropping;
-
- do {
- struct iphdr *iph;
- struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
- if (!skb)
- break;
- skb_reserve(skb, 32);
- iph = (struct iphdr*)skb_put(skb, sizeof(*iph));
- skb->mac.raw = ((u8*)iph) - 14;
- memcpy(iph, &whitehole_iph, sizeof(*iph));
- skb->protocol = __constant_htons(ETH_P_IP);
- skb->dev = &whitehole_dev;
- skb->pkt_type = PACKET_HOST;
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- netif_rx(skb);
- whitehole_count--;
- } while (netdev_dropping == 0 && whitehole_count>0);
- if (whitehole_count > 0) {
- whitehole_timer.expires = jiffies + 1;
- add_timer(&whitehole_timer);
- }
-}
-
-static struct net_device_stats *whitehole_get_stats(struct net_device *dev)
-{
- struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
- return stats;
-}
-
-int __init whitehole_init(struct net_device *dev)
-{
- dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOBUFS;
- memset(dev->priv, 0, sizeof(struct net_device_stats));
- dev->get_stats = whitehole_get_stats;
- dev->hard_start_xmit = whitehole_xmit;
- dev->open = whitehole_open;
- dev->stop = whitehole_close;
- ether_setup(dev);
- dev->tx_queue_len = 0;
- dev->flags |= IFF_NOARP;
- dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
- dev->iflink = 0;
- whitehole_iph.ihl = 5;
- whitehole_iph.version = 4;
- whitehole_iph.ttl = 2;
- whitehole_iph.saddr = in_aton("193.233.7.21");
- whitehole_iph.daddr = in_aton("193.233.7.10");
- whitehole_iph.tot_len = htons(20);
- whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20);
- return 0;
-}
-
-int net_profile_register(struct net_profile_slot *slot)
-{
- cli();
- slot->next = net_profile_chain;
- net_profile_chain = slot;
- sti();
- return 0;
-}
-
-int net_profile_unregister(struct net_profile_slot *slot)
-{
- struct net_profile_slot **sp, *s;
-
- for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) {
- if (s == slot) {
- cli();
- *sp = s->next;
- sti();
- return 0;
- }
- }
- return -ESRCH;
-}
-
-
-int __init net_profile_init(void)
-{
- int i;
-
-#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL);
-#endif
-
- register_netdevice(&whitehole_dev);
-
- printk("Evaluating net profiler cost ...");
-#ifdef __alpha__
- alpha_tick(0);
-#endif
- for (i=0; i<1024; i++) {
- NET_PROFILE_ENTER(total);
- NET_PROFILE_LEAVE(total);
- }
- if (net_prof_total.accumulator.tv_sec) {
- printk(" too high!\n");
- } else {
- net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10;
- printk("%ld units\n", net_profile_adjust.tv_usec);
- }
- net_prof_total.hits = 0;
- net_profile_stamp(&net_prof_total.entered);
- return 0;
-}
-
-#endif
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4215e4a7dcd0..444f07e51e27 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -559,9 +559,6 @@ struct notifier_block rtnetlink_dev_notifier = {
void __init rtnetlink_init(void)
{
-#ifdef RTNL_DEBUG
- printk("Initializing RT netlink socket\n");
-#endif
rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv);
if (rtnl == NULL)
panic("rtnetlink_init: cannot initialize rtnetlink\n");
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 52a0c5f688ff..918505be8ea7 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -35,7 +35,6 @@
#include <linux/string.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
-#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/sysctl.h>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8a5dbadd51f3..3879dca72b92 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1097,8 +1097,6 @@ static int __init inet_init(void)
struct inet_protosw *q;
struct list_head *r;
- printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n");
-
if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
return -EINVAL;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index c9f456eaa745..715919c77234 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -230,12 +230,18 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
#define icmp_socket __get_cpu_var(__icmp_socket)
-static __inline__ void icmp_xmit_lock(void)
+static __inline__ int icmp_xmit_lock(void)
{
local_bh_disable();
- if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock)))
- BUG();
+ if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) {
+ /* This can happen if the output path signals a
+ * dst_link_failure() for an outgoing ICMP packet.
+ */
+ local_bh_enable();
+ return 1;
+ }
+ return 0;
}
static void icmp_xmit_unlock(void)
@@ -376,7 +382,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
if (ip_options_echo(&icmp_param->replyopts, skb))
goto out;
- icmp_xmit_lock();
+ if (icmp_xmit_lock())
+ return;
icmp_param->data.icmph.checksum = 0;
icmp_out_count(icmp_param->data.icmph.type);
@@ -488,7 +495,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
}
}
- icmp_xmit_lock();
+ if (icmp_xmit_lock())
+ return;
/*
* Construct source address and options.
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 3f671efed9e6..9f5a0485e0a7 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1744,7 +1744,6 @@ static struct inet_protocol pim_protocol = {
void __init ip_mr_init(void)
{
- printk(KERN_INFO "Linux IP multicast router 0.06 plus PIM-SM\n");
mrt_cachep = kmem_cache_create("ip_mrt_cache",
sizeof(struct mfc_cache),
0, SLAB_HWCACHE_ALIGN,
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index ac3aafd9aa82..166e3be72987 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -31,7 +31,6 @@
#include <linux/proc_fs.h>
#include <linux/timer.h>
#include <linux/swap.h>
-#include <linux/proc_fs.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index d6e5f3bcb7f4..6dc8fd2a065b 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -150,8 +150,7 @@ list_conntracks(char *buffer, char **start, off_t offset, int length)
}
/* Now iterate through expecteds. */
- for (e = ip_conntrack_expect_list.next;
- e != &ip_conntrack_expect_list; e = e->next) {
+ list_for_each(e, &ip_conntrack_expect_list) {
unsigned int last_len;
struct ip_conntrack_expect *expect
= (struct ip_conntrack_expect *)e;
@@ -319,7 +318,7 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
struct list_head *i;
WRITE_LOCK(&ip_conntrack_lock);
- for (i = protocol_list.next; i != &protocol_list; i = i->next) {
+ list_for_each(i, &protocol_list) {
if (((struct ip_conntrack_protocol *)i)->proto
== proto->proto) {
ret = -EBUSY;
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index a9f726b10a46..249c8e66f5aa 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -157,8 +157,8 @@ in_range(const struct ip_conntrack_tuple *tuple,
continue;
}
- if ((mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED)
- && proto->in_range(&newtuple, IP_NAT_MANIP_SRC,
+ if (!(mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED)
+ || proto->in_range(&newtuple, IP_NAT_MANIP_SRC,
&mr->range[i].min, &mr->range[i].max))
return 1;
}
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 75df6c8222bb..0e3028dcb176 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -50,7 +50,6 @@
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h>
-#include <linux/types.h>
#include <linux/ip.h>
#include <net/udp.h>
#include <asm/uaccess.h>
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 825ae9ffef36..bd014b74571f 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -271,7 +271,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
struct list_head *i;
WRITE_LOCK(&ip_nat_lock);
- for (i = protos.next; i != &protos; i = i->next) {
+ list_for_each(i, &protos) {
if (((struct ip_nat_protocol *)i)->protonum
== proto->protonum) {
ret = -EBUSY;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index b5bfc900281b..272dab8ded25 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -141,7 +141,7 @@ static void send_reset(struct sk_buff *oldskb, int local)
nskb->nf_debug = 0;
#endif
nskb->nfmark = 0;
-#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(nskb->nf_bridge);
nskb->nf_bridge = NULL;
#endif
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 6374bdd52780..1398b8590dba 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -45,7 +45,6 @@
#include <linux/netlink.h>
#include <linux/netdevice.h>
#include <linux/mm.h>
-#include <linux/socket.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ULOG.h>
#include <linux/netfilter_ipv4/lockhelp.h>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 08c3a40a4bd2..1746eae040b3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1349,64 +1349,65 @@ struct proto udp_prot = {
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
-static __inline__ struct sock *udp_get_bucket(struct seq_file *seq, loff_t *pos)
+static struct sock *udp_get_first(struct seq_file *seq)
{
- int i;
struct sock *sk;
- struct hlist_node *node;
- loff_t l = *pos;
struct udp_iter_state *state = seq->private;
- for (; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
- i = 0;
+ for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
+ struct hlist_node *node;
sk_for_each(sk, node, &udp_hash[state->bucket]) {
- if (sk->sk_family != state->family) {
- ++i;
- continue;
- }
- if (l--) {
- ++i;
- continue;
- }
- *pos = i;
- goto out;
+ if (sk->sk_family == state->family)
+ goto found;
}
}
sk = NULL;
-out:
+found:
return sk;
}
+static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
+{
+ struct udp_iter_state *state = seq->private;
+
+ do {
+ sk = sk_next(sk);
+try_again:
+ ;
+ } while (sk && sk->sk_family != state->family);
+
+ if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
+ sk = sk_head(&udp_hash[state->bucket]);
+ goto try_again;
+ }
+ return sk;
+}
+
+static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct sock *sk = udp_get_first(seq);
+
+ if (sk)
+ while(pos && (sk = udp_get_next(seq, sk)) != NULL)
+ --pos;
+ return pos ? NULL : sk;
+}
+
static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
{
read_lock(&udp_hash_lock);
- return *pos ? udp_get_bucket(seq, pos) : (void *)1;
+ return *pos ? udp_get_idx(seq, *pos-1) : (void *)1;
}
static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *sk;
- struct hlist_node *node;
- struct udp_iter_state *state;
-
- if (v == (void *)1) {
- sk = udp_get_bucket(seq, pos);
- goto out;
- }
-
- state = seq->private;
-
- sk = v;
- sk_for_each_continue(sk, node)
- if (sk->sk_family == state->family)
- goto out;
- if (++state->bucket >= UDP_HTABLE_SIZE)
- goto out;
+ if (v == (void *)1)
+ sk = udp_get_idx(seq, 0);
+ else
+ sk = udp_get_next(seq, v);
- *pos = 0;
- sk = udp_get_bucket(seq, pos);
-out:
++*pos;
return sk;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c6246d0fc1d6..150089e25d2c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -57,7 +57,6 @@
#include <linux/delay.h>
#include <linux/notifier.h>
-#include <linux/proc_fs.h>
#include <net/sock.h>
#include <net/snmp.h>
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6289170cb341..df60b4030a44 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -40,7 +40,6 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
@@ -724,8 +723,6 @@ static int __init inet6_init(void)
#endif
#endif
- printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
-
if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "inet6_proto_init: size fault\n");
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 358b3f3f3d18..a97c931c5549 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
-#include <net/xfrm.h>
#include <net/ah.h>
#include <linux/crypto.h>
#include <linux/pfkeyv2.h>
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 083155a233a6..8c9091ede27d 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1940,10 +1940,6 @@ extern void destroy_8023_client(struct datalink_proto *);
static unsigned char ipx_8022_type = 0xE0;
static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
-static char ipx_banner[] __initdata =
- KERN_INFO "NET4: Linux IPX 0.51 for NET4.0\n"
- KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \
- KERN_INFO "IPX Portions Copyright (c) 2000-2003 Conectiva, Inc.\n";
static char ipx_EII_err_msg[] __initdata =
KERN_CRIT "IPX: Unable to register with Ethernet II\n";
static char ipx_8023_err_msg[] __initdata =
@@ -1980,7 +1976,6 @@ static int __init ipx_init(void)
register_netdevice_notifier(&ipx_dev_notifier);
ipx_register_sysctl();
ipx_proc_init();
- printk(ipx_banner);
return 0;
}
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index fbb552adc243..fc71309e7e9b 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -435,11 +435,8 @@ EXPORT_SYMBOL(lapb_disconnect_request);
EXPORT_SYMBOL(lapb_data_request);
EXPORT_SYMBOL(lapb_data_received);
-static char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
-
static int __init lapb_init(void)
{
- printk(banner);
return 0;
}
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5b011b872d94..ff2710542e4b 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -1042,15 +1042,10 @@ static struct proto_ops llc_ui_ops = {
.sendpage = sock_no_sendpage,
};
-static char llc_ui_banner[] __initdata =
- KERN_INFO "NET4.0 IEEE 802.2 BSD sockets, Jay Schulist, 2001, "
- "Arnaldo C. Melo, 2002-2003\n";
-
int __init llc_ui_init(void)
{
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
sock_register(&llc_ui_family_ops);
- printk(llc_ui_banner);
return 0;
}
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index 3ee7b0aa16ae..8f2fc4d7ec71 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -603,5 +603,5 @@ module_exit(llc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001-2003");
-MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support");
+MODULE_DESCRIPTION("LLC 2.0, IEEE 802.2 extended support");
MODULE_ALIAS_NETPROTO(PF_LLC);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e23847781517..3347859a1665 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -40,6 +40,7 @@
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/security.h>
@@ -964,62 +965,108 @@ int netlink_post(int unit, struct sk_buff *skb)
#endif
-
#ifdef CONFIG_PROC_FS
-static int netlink_read_proc(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
+static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
{
- off_t pos=0;
- off_t begin=0;
- int len=0;
- int i;
+ long i;
struct sock *s;
struct hlist_node *node;
-
- len+= sprintf(buffer,"sk Eth Pid Groups "
- "Rmem Wmem Dump Locks\n");
-
+ loff_t off = 0;
+
for (i=0; i<MAX_LINKS; i++) {
- read_lock(&nl_table_lock);
sk_for_each(s, node, &nl_table[i]) {
- struct netlink_opt *nlk = nlk_sk(s);
-
- len+=sprintf(buffer+len,"%p %-3d %-6d %08x %-8d %-8d %p %d",
- s,
- s->sk_protocol,
- nlk->pid,
- nlk->groups,
- atomic_read(&s->sk_rmem_alloc),
- atomic_read(&s->sk_wmem_alloc),
- nlk->cb,
- atomic_read(&s->sk_refcnt)
- );
-
- buffer[len++]='\n';
-
- pos=begin+len;
- if(pos<offset) {
- len=0;
- begin=pos;
+ if (off == pos) {
+ seq->private = (void *) i;
+ return s;
}
- if(pos>offset+length) {
- read_unlock(&nl_table_lock);
- goto done;
+ ++off;
+ }
+ }
+ return NULL;
+}
+
+static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ read_lock(&nl_table_lock);
+ return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : (void *) 1;
+}
+
+static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock *s;
+
+ ++*pos;
+
+ if (v == (void *) 1)
+ return netlink_seq_socket_idx(seq, 0);
+
+ s = sk_next(v);
+ if (!s) {
+ long i = (long)seq->private;
+
+ while (++i < MAX_LINKS) {
+ s = sk_head(&nl_table[i]);
+ if (s) {
+ seq->private = (void *) i;
+ break;
}
}
- read_unlock(&nl_table_lock);
}
- *eof = 1;
-
-done:
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- if(len<0)
- len=0;
- return len;
+ return s;
}
+
+static void netlink_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&nl_table_lock);
+}
+
+
+static int netlink_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == (void *)1)
+ seq_puts(seq,
+ "sk Eth Pid Groups "
+ "Rmem Wmem Dump Locks\n");
+ else {
+ struct sock *s = v;
+ struct netlink_opt *nlk = nlk_sk(s);
+
+ seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %d\n",
+ s,
+ s->sk_protocol,
+ nlk->pid,
+ nlk->groups,
+ atomic_read(&s->sk_rmem_alloc),
+ atomic_read(&s->sk_wmem_alloc),
+ nlk->cb,
+ atomic_read(&s->sk_refcnt)
+ );
+
+ }
+ return 0;
+}
+
+struct seq_operations netlink_seq_ops = {
+ .start = netlink_seq_start,
+ .next = netlink_seq_next,
+ .stop = netlink_seq_stop,
+ .show = netlink_seq_show,
+};
+
+
+static int netlink_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &netlink_seq_ops);
+}
+
+static struct file_operations netlink_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = netlink_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
#endif
int netlink_register_notifier(struct notifier_block *nb)
@@ -1069,7 +1116,7 @@ static int __init netlink_proto_init(void)
}
sock_register(&netlink_family_ops);
#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL);
+ proc_net_fops_create("netlink", 0, &netlink_seq_fops);
#endif
/* The netlink device handler may be needed early. */
rtnetlink_init();
@@ -1079,7 +1126,7 @@ static int __init netlink_proto_init(void)
static void __exit netlink_proto_exit(void)
{
sock_unregister(PF_NETLINK);
- remove_proc_entry("net/netlink", NULL);
+ proc_net_remove("netlink");
}
core_initcall(netlink_proto_init);
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c
index ada78e6532ba..08df88fcd643 100644
--- a/net/rxrpc/sysctl.c
+++ b/net/rxrpc/sysctl.c
@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/sysctl.h>
-#include <linux/config.h>
#include <rxrpc/types.h>
#include <rxrpc/rxrpc.h>
#include <asm/errno.h>
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 849b7a589ac0..c1323ddd5576 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
@@ -42,6 +42,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ryan Layer <rmlayer@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -1155,3 +1156,23 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3,
asoc->ep->base.bind_addr.port, gfp);
}
+
+/* Lookup laddr in the bind address list of an association. */
+int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
+ const union sctp_addr *laddr)
+{
+ int found;
+
+ sctp_read_lock(&asoc->base.addr_lock);
+ if ((asoc->base.bind_addr.port == ntohs(laddr->v4.sin_port)) &&
+ sctp_bind_addr_match(&asoc->base.bind_addr, laddr,
+ sctp_sk(asoc->base.sk))) {
+ found = 1;
+ goto out;
+ }
+
+ found = 0;
+out:
+ sctp_read_unlock(&asoc->base.addr_lock);
+ return found;
+}
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 58d6a3bb7c3e..c2a288bcca39 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001
- * Copyright (c) International Business Machines Corp., 2001,2002
* Copyright (c) La Monte H.P. Yarroll 2001
*
* This file is part of the SCTP kernel reference implementation.
@@ -223,6 +223,8 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
int len;
struct sctp_sockaddr_entry *addr;
struct list_head *pos;
+ struct sctp_af *af;
+
addrparms_len = 0;
len = 0;
@@ -247,7 +249,8 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
- len = sockaddr2sctp_addr(&addr->a, &rawaddr);
+ af = sctp_get_af_specific(addr->a.v4.sin_family);
+ len = af->to_addr_param(&addr->a, &rawaddr);
memcpy(addrparms.v, &rawaddr, len);
addrparms.v += len;
addrparms_len += len;
@@ -270,34 +273,31 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
union sctp_addr addr;
int retval = 0;
int len;
+ struct sctp_af *af;
/* Convert the raw address to standard address format */
while (addrs_len) {
param = (struct sctp_paramhdr *)raw_addr_list;
rawaddr = (union sctp_addr_param *)raw_addr_list;
- switch (param->type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- case SCTP_PARAM_IPV6_ADDRESS:
- sctp_param2sockaddr(&addr, rawaddr, port, 0);
- retval = sctp_add_bind_addr(bp, &addr, gfp);
- if (retval) {
- /* Can't finish building the list, clean up. */
- sctp_bind_addr_clean(bp);
- break;;
- }
- len = ntohs(param->length);
- addrs_len -= len;
- raw_addr_list += len;
- break;
- default:
- /* Corrupted raw addr list! */
+ af = sctp_get_af_specific(param_type2af(param->type));
+ if (unlikely(!af)) {
retval = -EINVAL;
sctp_bind_addr_clean(bp);
break;
}
- if (retval)
- break;
+
+ af->from_addr_param(&addr, rawaddr, port, 0);
+ retval = sctp_add_bind_addr(bp, &addr, gfp);
+ if (retval) {
+ /* Can't finish building the list, clean up. */
+ sctp_bind_addr_clean(bp);
+ break;;
+ }
+
+ len = ntohs(param->length);
+ addrs_len -= len;
+ raw_addr_list += len;
}
return retval;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 2c62c2171f6a..cc3e9314dd91 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -768,6 +768,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
union sctp_params params;
sctp_init_chunk_t *init;
struct sctp_transport *transport;
+ struct sctp_af *af;
ch = (sctp_chunkhdr_t *) skb->data;
@@ -802,11 +803,12 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
sctp_walk_params(params, init, init_hdr.params) {
/* Note: Ignoring hostname addresses. */
- if ((SCTP_PARAM_IPV4_ADDRESS != params.p->type) &&
- (SCTP_PARAM_IPV6_ADDRESS != params.p->type))
+ af = sctp_get_af_specific(param_type2af(params.p->type));
+ if (!af)
continue;
- sctp_param2sockaddr(paddr, params.addr, ntohs(sh->source), 0);
+ af->from_addr_param(paddr, params.addr, ntohs(sh->source), 0);
+
asoc = __sctp_lookup_association(laddr, paddr, &transport);
if (asoc)
return asoc;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 3bce456b895f..32ec1d5176ff 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -399,6 +399,33 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
}
}
+/* Initialize a sctp_addr from an address parameter. */
+static void sctp_v6_from_addr_param(union sctp_addr *addr,
+ union sctp_addr_param *param,
+ __u16 port, int iif)
+{
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = port;
+ addr->v6.sin6_flowinfo = 0; /* BUG */
+ ipv6_addr_copy(&addr->v6.sin6_addr, &param->v6.addr);
+ addr->v6.sin6_scope_id = iif;
+}
+
+/* Initialize an address parameter from a sctp_addr and return the length
+ * of the address parameter.
+ */
+static int sctp_v6_to_addr_param(const union sctp_addr *addr,
+ union sctp_addr_param *param)
+{
+ int length = sizeof(sctp_ipv6addr_param_t);
+
+ param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
+ param->v6.param_hdr.length = ntohs(length);
+ ipv6_addr_copy(&param->v6.addr, &addr->v6.sin6_addr);
+
+ return length;
+}
+
/* Initialize a sctp_addr from a dst_entry. */
static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
unsigned short port)
@@ -903,6 +930,8 @@ static struct sctp_af sctp_ipv6_specific = {
.from_sk = sctp_v6_from_sk,
.to_sk_saddr = sctp_v6_to_sk_saddr,
.to_sk_daddr = sctp_v6_to_sk_daddr,
+ .from_addr_param = sctp_v6_from_addr_param,
+ .to_addr_param = sctp_v6_to_addr_param,
.dst_saddr = sctp_v6_dst_saddr,
.cmp_addr = sctp_v6_cmp_addr,
.scope = sctp_v6_scope,
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index 243b1d5a8657..3a7ebfcc1fdb 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -39,6 +39,7 @@
* Narasimha Budihal <narasimha@refcode.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -203,3 +204,16 @@ DECLARE_PRIMITIVE(SEND);
*/
DECLARE_PRIMITIVE(REQUESTHEARTBEAT);
+
+/* ADDIP
+* 3.1.1 Address Configuration Change Chunk (ASCONF)
+*
+* This chunk is used to communicate to the remote endpoint one of the
+* configuration change requests that MUST be acknowledged. The
+* information carried in the ASCONF Chunk uses the form of a
+* Type-Length-Value (TLV), as described in "3.2.1 Optional/
+* Variable-length Parameter Format" in RFC2960 [5], forall variable
+* parameters.
+*/
+
+DECLARE_PRIMITIVE(ASCONF);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 727f237b1475..986460afaa6b 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -295,6 +295,31 @@ static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
inet_sk(sk)->daddr = addr->v4.sin_addr.s_addr;
}
+/* Initialize a sctp_addr from an address parameter. */
+static void sctp_v4_from_addr_param(union sctp_addr *addr,
+ union sctp_addr_param *param,
+ __u16 port, int iif)
+{
+ addr->v4.sin_family = AF_INET;
+ addr->v4.sin_port = port;
+ addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
+}
+
+/* Initialize an address parameter from a sctp_addr and return the length
+ * of the address parameter.
+ */
+static int sctp_v4_to_addr_param(const union sctp_addr *addr,
+ union sctp_addr_param *param)
+{
+ int length = sizeof(sctp_ipv4addr_param_t);
+
+ param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
+ param->v4.param_hdr.length = ntohs(length);
+ param->v4.addr.s_addr = addr->v4.sin_addr.s_addr;
+
+ return length;
+}
+
/* Initialize a sctp_addr from a dst_entry. */
static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst,
unsigned short port)
@@ -862,6 +887,8 @@ struct sctp_af sctp_ipv4_specific = {
.from_sk = sctp_v4_from_sk,
.to_sk_saddr = sctp_v4_to_sk_saddr,
.to_sk_daddr = sctp_v4_to_sk_daddr,
+ .from_addr_param= sctp_v4_from_addr_param,
+ .to_addr_param = sctp_v4_to_addr_param,
.dst_saddr = sctp_v4_dst_saddr,
.cmp_addr = sctp_v4_cmp_addr,
.addr_valid = sctp_v4_addr_valid,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index bf3f373d9feb..40a7a4f7116f 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * Copyright (C) IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -48,6 +48,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -1213,6 +1214,7 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
struct sctp_association *asoc;
struct sk_buff *skb;
sctp_scope_t scope;
+ struct sctp_af *af;
/* Create the bare association. */
scope = sctp_scope(sctp_source(chunk));
@@ -1222,29 +1224,10 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
asoc->temp = 1;
skb = chunk->skb;
/* Create an entry for the source address of the packet. */
- /* FIXME: Use the af specific helpers. */
- switch (skb->nh.iph->version) {
- case 4:
- asoc->c.peer_addr.v4.sin_family = AF_INET;
- asoc->c.peer_addr.v4.sin_port = ntohs(chunk->sctp_hdr->source);
- asoc->c.peer_addr.v4.sin_addr.s_addr = skb->nh.iph->saddr;
- break;
-
- case 6:
- asoc->c.peer_addr.v6.sin6_family = AF_INET6;
- asoc->c.peer_addr.v6.sin6_port
- = ntohs(chunk->sctp_hdr->source);
- asoc->c.peer_addr.v6.sin6_flowinfo = 0; /* BUG BUG BUG */
- asoc->c.peer_addr.v6.sin6_addr = skb->nh.ipv6h->saddr;
- asoc->c.peer_addr.v6.sin6_scope_id =
- ((struct inet6_skb_parm *)skb->cb)->iif;
- break;
-
- default:
- /* Yikes! I never heard of this kind of address. */
+ af = sctp_get_af_specific(ipver2af(skb->nh.iph->version));
+ if (unlikely(!af))
goto fail;
- };
-
+ af->from_skb(&asoc->c.peer_addr, skb, 1);
nodata:
return asoc;
@@ -1830,11 +1813,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* stream sequence number shall be set to 0.
*/
- /* Allocate storage for the negotiated streams. */
- asoc->ssnmap = sctp_ssnmap_new(asoc->peer.i.num_outbound_streams,
- asoc->c.sinit_num_ostreams, gfp);
- if (!asoc->ssnmap)
- goto nomem_ssnmap;
+ /* Allocate storage for the negotiated streams if it is not a temporary * association.
+ */
+ if (!asoc->temp) {
+ asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
+ asoc->c.sinit_num_ostreams, gfp);
+ if (!asoc->ssnmap)
+ goto nomem_ssnmap;
+ }
/* ADDIP Section 4.1 ASCONF Chunk Procedures
*
@@ -1882,6 +1868,7 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
int retval = 1;
sctp_scope_t scope;
time_t stale;
+ struct sctp_af *af;
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
@@ -1893,7 +1880,8 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
break;
/* Fall through. */
case SCTP_PARAM_IPV4_ADDRESS:
- sctp_param2sockaddr(&addr, param.addr, asoc->peer.port, 0);
+ af = sctp_get_af_specific(param_type2af(param.p->type));
+ af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
scope = sctp_scope(peer_addr);
if (sctp_in_scope(&addr, scope))
if (!sctp_assoc_add_peer(asoc, &addr, gfp))
@@ -2005,90 +1993,6 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
return retval;
}
-/********************************************************************
- * 4th Level Abstractions
- ********************************************************************/
-
-/* Convert from an SCTP IP parameter to a union sctp_addr. */
-void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *param,
- __u16 port, int iif)
-{
- switch(param->v4.param_hdr.type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- addr->v4.sin_family = AF_INET;
- addr->v4.sin_port = port;
- addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
- break;
-
- case SCTP_PARAM_IPV6_ADDRESS:
- addr->v6.sin6_family = AF_INET6;
- addr->v6.sin6_port = port;
- addr->v6.sin6_flowinfo = 0; /* BUG */
- addr->v6.sin6_addr = param->v6.addr;
- addr->v6.sin6_scope_id = iif;
- break;
-
- default:
- SCTP_DEBUG_PRINTK("Illegal address type %d\n",
- ntohs(param->v4.param_hdr.type));
- break;
- };
-}
-
-/* Convert an IP address in an SCTP param into a sockaddr_in. */
-/* Returns true if a valid conversion was possible. */
-int sctp_addr2sockaddr(union sctp_params p, union sctp_addr *sa)
-{
- switch (p.p->type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- sa->v4.sin_addr = *((struct in_addr *)&p.v4->addr);
- sa->v4.sin_family = AF_INET;
- break;
-
- case SCTP_PARAM_IPV6_ADDRESS:
- *((struct in6_addr *)&sa->v4.sin_addr)
- = p.v6->addr;
- sa->v4.sin_family = AF_INET6;
- break;
-
- default:
- return 0;
- };
-
- return 1;
-}
-
-/* Convert a sockaddr_in to an IP address in an SCTP param.
- * Returns len if a valid conversion was possible.
- */
-int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p)
-{
- int len = 0;
-
- switch (sa->v4.sin_family) {
- case AF_INET:
- p->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
- p->v4.param_hdr.length = ntohs(sizeof(sctp_ipv4addr_param_t));
- len = sizeof(sctp_ipv4addr_param_t);
- p->v4.addr.s_addr = sa->v4.sin_addr.s_addr;
- break;
-
- case AF_INET6:
- p->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
- p->v6.param_hdr.length = ntohs(sizeof(sctp_ipv6addr_param_t));
- len = sizeof(sctp_ipv6addr_param_t);
- p->v6.addr = *(&sa->v6.sin6_addr);
- break;
-
- default:
- printk(KERN_WARNING "sockaddr2sctp_addr: Illegal family %d.\n",
- sa->v4.sin_family);
- return 0;
- };
-
- return len;
-}
-
/*
* ADDIP 3.1.1 Address Configuration Change Chunk (ASCONF)
* 0 1 2 3
@@ -2119,8 +2023,9 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
int length = sizeof(asconf) + vparam_len;
union sctp_params addrparam;
int addrlen;
+ struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
- addrlen = sockaddr2sctp_addr(addr, (union sctp_addr_param *)&addrparam);
+ addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
if (!addrlen)
return NULL;
length += addrlen;
@@ -2135,7 +2040,51 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
retval->subh.addip_hdr =
sctp_addto_chunk(retval, sizeof(asconf), &asconf);
retval->param_hdr.v =
- sctp_addto_chunk(retval, addrlen, &addr);
+ sctp_addto_chunk(retval, addrlen, &addrparam);
+
+ return retval;
+}
+
+/* ADDIP
+ * 3.2.4 Set Primary IP Address
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type =0xC004 | Length = Variable |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ASCONF-Request Correlation ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Address Parameter |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Create an ASCONF chunk with Set Primary IP address parameter.
+ */
+struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+ union sctp_addr *addr)
+{
+ sctp_addip_param_t param;
+ struct sctp_chunk *retval;
+ int len = sizeof(param);
+ union sctp_params addrparam;
+ int addrlen;
+ struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
+
+ addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
+ if (!addrlen)
+ return NULL;
+ len += addrlen;
+
+ /* Create the chunk and make asconf header. */
+ retval = sctp_make_asconf(asoc, addr, len);
+ if (!retval)
+ return NULL;
+
+ param.param_hdr.type = SCTP_PARAM_SET_PRIMARY;
+ param.param_hdr.length = htons(len);
+ param.crr_id = 0;
+
+ sctp_addto_chunk(retval, sizeof(param), &param);
+ sctp_addto_chunk(retval, addrlen, &addrparam);
return retval;
}
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 531ff1606429..86208c51ba36 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -929,6 +929,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
struct sctp_errhdr *errhdr;
struct sctp_endpoint *ep;
char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
+ struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
/* Build the error on the stack. We are way to malloc crazy
* throughout the code today.
@@ -937,7 +938,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
addrparm = (union sctp_addr_param *)errhdr->variable;
/* Copy into a parm format. */
- len = sockaddr2sctp_addr(ssa, addrparm);
+ len = af->to_addr_param(ssa, addrparm);
len += sizeof(sctp_errhdr_t);
errhdr->cause = SCTP_ERROR_RESTART;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 722ddbc57c09..a7db6e38441a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1,6 +1,7 @@
-/* Copyright (c) 1999-2000 Cisco, Inc.
+/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001-2003 Intel Corp.
* Copyright (c) 2001-2002 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
@@ -50,6 +51,7 @@
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Anup Pemmaiah <pemmaiah@cc.usu.edu>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -93,8 +95,8 @@ static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
static int sctp_wait_for_accept(struct sock *sk, long timeo);
static void sctp_wait_for_close(struct sock *sk, long timeo);
static inline int sctp_verify_addr(struct sock *, union sctp_addr *, int);
-static int sctp_bindx_add(struct sock *, struct sockaddr_storage *, int);
-static int sctp_bindx_rem(struct sock *, struct sockaddr_storage *, int);
+static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
+static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
static int sctp_do_bind(struct sock *, union sctp_addr *, int);
static int sctp_autobind(struct sock *sk);
static void sctp_sock_migrate(struct sock *, struct sock *,
@@ -170,10 +172,7 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
* sd - the socket descriptor returned by socket().
* addr - the address structure (struct sockaddr_in or struct
* sockaddr_in6 [RFC 2553]),
- * addrlen - the size of the address structure.
- *
- * The caller should use struct sockaddr_storage described in RFC 2553
- * to represent addr for portability reason.
+ * addr_len - the size of the address structure.
*/
int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
@@ -298,112 +297,6 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
return ret;
}
-/* API 8.1 sctp_bindx()
- *
- * The syntax of sctp_bindx() is,
- *
- * ret = sctp_bindx(int sd,
- * struct sockaddr_storage *addrs,
- * int addrcnt,
- * int flags);
- *
- * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
- * If the sd is an IPv6 socket, the addresses passed can either be IPv4
- * or IPv6 addresses.
- *
- * A single address may be specified as INADDR_ANY or IPV6_ADDR_ANY, see
- * section 3.1.2 for this usage.
- *
- * addrs is a pointer to an array of one or more socket addresses. Each
- * address is contained in a struct sockaddr_storage, so each address is
- * fixed length. The caller specifies the number of addresses in the
- * array with addrcnt.
- *
- * On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns -1,
- * and sets errno to the appropriate error code. [ Editor's note: need
- * to fill in all error code? ]
- *
- * For SCTP, the port given in each socket address must be the same, or
- * sctp_bindx() will fail, setting errno to EINVAL .
- *
- * The flags parameter is formed from the bitwise OR of zero or
- * more of the following currently defined flags:
- *
- * SCTP_BINDX_ADD_ADDR
- * SCTP_BINDX_REM_ADDR
- *
- * SCTP_BIND_ADD_ADDR directs SCTP to add the given addresses to the
- * association, and SCTP_BIND_REM_ADDR directs SCTP to remove the given
- * addresses from the association. The two flags are mutually exclusive;
- * if both are given, sctp_bindx() will fail with EINVAL. A caller may not
- * remove all addresses from an association; sctp_bindx() will reject such
- * an attempt with EINVAL.
- *
- * An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
- * additional addresses with an endpoint after calling bind(). Or use
- * sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening
- * socket is associated with so that no new association accepted will be
- * associated with those addresses.
- *
- * SCTP_BIND_ADD_ADDR is defined as 0, so that it becomes the default
- * behavior for sctp_bindx() when no flags are given.
- *
- * Adding and removing addresses from a connected association is optional
- * functionality. Implementations that do not support this functionality
- * should return EOPNOTSUPP.
- *
- * NOTE: This could be integrated into sctp_setsockopt_bindx(),
- * but keeping it this way makes it easier if sometime sys_bindx is
- * added.
- */
-
-/* Unprotected by locks. Call only with socket lock sk->sk_lock held! See
- * sctp_bindx() for a lock-protected call.
- */
-
-static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
- int addrcnt, int flags)
-{
- int retval = 0;
-
- SCTP_DEBUG_PRINTK("__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
- "flags: %s)\n", sk, addrs, addrcnt,
- (SCTP_BINDX_ADD_ADDR == flags) ? "ADD" :
- ((SCTP_BINDX_REM_ADDR == flags) ? "REM" : "BOGUS"));
-
- switch (flags) {
- case SCTP_BINDX_ADD_ADDR:
- retval = sctp_bindx_add(sk, addrs, addrcnt);
- break;
-
- case SCTP_BINDX_REM_ADDR:
- retval = sctp_bindx_rem(sk, addrs, addrcnt);
- break;
-
- default:
- retval = -EINVAL;
- break;
- };
-
- return retval;
-}
-
-/* BINDX with locks.
- *
- * NOTE: Currently unused at all ...
- */
-int sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt,
- int flags)
-{
- int retval;
-
- sctp_lock_sock(sk);
- retval = __sctp_bindx(sk, addrs, addrcnt, flags);
- sctp_release_sock(sk);
-
- return retval;
-}
-
/* Add a list of addresses as bind addresses to local endpoint or
* association.
*
@@ -414,41 +307,39 @@ int sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt,
* If any of them fails, then the operation will be reversed and the
* ones that were added will be removed.
*
- * Only __sctp_bindx() is supposed to call this function.
+ * Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
+int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt)
{
int cnt;
int retval = 0;
- int addr_len;
+ void *addr_buf;
+ struct sockaddr *sa_addr;
+ struct sctp_af *af;
SCTP_DEBUG_PRINTK("sctp_bindx_add (sk: %p, addrs: %p, addrcnt: %d)\n",
sk, addrs, addrcnt);
+ addr_buf = addrs;
for (cnt = 0; cnt < addrcnt; cnt++) {
/* The list may contain either IPv4 or IPv6 address;
* determine the address length for walking thru the list.
*/
- switch (((struct sockaddr *)&addrs[cnt])->sa_family) {
- case AF_INET:
- addr_len = sizeof(struct sockaddr_in);
- break;
-
- case AF_INET6:
- addr_len = sizeof(struct sockaddr_in6);
- break;
-
- default:
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+ if (!af) {
retval = -EINVAL;
goto err_bindx_add;
- };
+ }
- retval = sctp_do_bind(sk, (union sctp_addr *)&addrs[cnt],
- addr_len);
+ retval = sctp_do_bind(sk, (union sctp_addr *)sa_addr,
+ af->sockaddr_len);
+
+ addr_buf += af->sockaddr_len;
err_bindx_add:
if (retval < 0) {
- /* Failed. Cleanup the ones that has been added */
+ /* Failed. Cleanup the ones that have been added */
if (cnt > 0)
sctp_bindx_rem(sk, addrs, cnt);
return retval;
@@ -471,9 +362,9 @@ err_bindx_add:
* At least one address has to be left; if only one address is
* available, the operation will return -EBUSY.
*
- * Only __sctp_bindx() is supposed to call this function.
+ * Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
+int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
{
struct sctp_opt *sp = sctp_sk(sk);
struct sctp_endpoint *ep = sp->ep;
@@ -481,50 +372,41 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
struct sctp_bind_addr *bp = &ep->base.bind_addr;
int retval = 0;
union sctp_addr saveaddr;
+ void *addr_buf;
+ struct sockaddr *sa_addr;
+ struct sctp_af *af;
SCTP_DEBUG_PRINTK("sctp_bindx_rem (sk: %p, addrs: %p, addrcnt: %d)\n",
sk, addrs, addrcnt);
+ addr_buf = addrs;
for (cnt = 0; cnt < addrcnt; cnt++) {
- /* If there is only one bind address, there is nothing more
- * to be removed (we need at least one address here).
+ /* If the bind address list is empty or if there is only one
+ * bind address, there is nothing more to be removed (we need
+ * at least one address here).
*/
- if (list_empty(&bp->address_list)) {
+ if (list_empty(&bp->address_list) ||
+ (sctp_list_single_entry(&bp->address_list))) {
retval = -EBUSY;
goto err_bindx_rem;
}
/* The list may contain either IPv4 or IPv6 address;
- * determine the address length for walking thru the list.
+ * determine the address length to copy the address to
+ * saveaddr.
*/
- switch (((struct sockaddr *)&addrs[cnt])->sa_family) {
- case AF_INET:
- saveaddr = *((union sctp_addr *)
- &addrs[cnt]);
- saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
- /* Verify the port. */
- if (saveaddr.v4.sin_port != bp->port) {
- retval = -EINVAL;
- goto err_bindx_rem;
- }
- break;
-
- case AF_INET6:
- saveaddr = *((union sctp_addr *)
- &addrs[cnt]);
- saveaddr.v6.sin6_port =
- ntohs(saveaddr.v6.sin6_port);
- /* verify the port */
- if (saveaddr.v6.sin6_port != bp->port) {
- retval = -EINVAL;
- goto err_bindx_rem;
- }
- break;
-
- default:
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+ if (!af) {
retval = -EINVAL;
goto err_bindx_rem;
- };
+ }
+ memcpy(&saveaddr, sa_addr, af->sockaddr_len);
+ saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
+ if (saveaddr.v4.sin_port != bp->port) {
+ retval = -EINVAL;
+ goto err_bindx_rem;
+ }
/* FIXME - There is probably a need to check if sk->sk_saddr and
* sk->sk_rcv_addr are currently set to one of the addresses to
@@ -541,6 +423,7 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
sctp_write_unlock(&ep->base.addr_lock);
sctp_local_bh_enable();
+ addr_buf += af->sockaddr_len;
err_bindx_rem:
if (retval < 0) {
/* Failed. Add the ones that has been removed back */
@@ -553,18 +436,62 @@ err_bindx_rem:
return retval;
}
-/* Helper for tunneling sys_bindx() requests through sctp_setsockopt()
+/* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
+ *
+ * API 8.1
+ * int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt,
+ * int flags);
+ *
+ * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+ * If the sd is an IPv6 socket, the addresses passed can either be IPv4
+ * or IPv6 addresses.
+ *
+ * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
+ * Section 3.1.2 for this usage.
+ *
+ * addrs is a pointer to an array of one or more socket addresses. Each
+ * address is contained in its appropriate structure (i.e. struct
+ * sockaddr_in or struct sockaddr_in6) the family of the address type
+ * must be used to distengish the address length (note that this
+ * representation is termed a "packed array" of addresses). The caller
+ * specifies the number of addresses in the array with addrcnt.
+ *
+ * On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns
+ * -1, and sets errno to the appropriate error code.
+ *
+ * For SCTP, the port given in each socket address must be the same, or
+ * sctp_bindx() will fail, setting errno to EINVAL.
+ *
+ * The flags parameter is formed from the bitwise OR of zero or more of
+ * the following currently defined flags:
+ *
+ * SCTP_BINDX_ADD_ADDR
+ *
+ * SCTP_BINDX_REM_ADDR
+ *
+ * SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the
+ * association, and SCTP_BINDX_REM_ADDR directs SCTP to remove the given
+ * addresses from the association. The two flags are mutually exclusive;
+ * if both are given, sctp_bindx() will fail with EINVAL. A caller may
+ * not remove all addresses from an association; sctp_bindx() will
+ * reject such an attempt with EINVAL.
+ *
+ * An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
+ * additional addresses with an endpoint after calling bind(). Or use
+ * sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening
+ * socket is associated with so that no new association accepted will be
+ * associated with those addresses. If the endpoint supports dynamic
+ * address a SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause a
+ * endpoint to send the appropriate message to the peer to change the
+ * peers address lists.
+ *
+ * Adding and removing addresses from a connected association is
+ * optional functionality. Implementations that do not support this
+ * functionality should return EOPNOTSUPP.
*
* Basically do nothing but copying the addresses from user to kernel
- * land and invoking sctp_bindx on the sk. This is used for tunneling
- * the sctp_bindx() [sys_bindx()] request through sctp_setsockopt()
- * from userspace.
- *
- * Note I don't use move_addr_to_kernel(): the reason is we would be
- * iterating over an array of struct sockaddr_storage passing always
- * what we know is a good size (sizeof (struct sock...)), so it is
- * pointless. Instead check the whole area for read access and copy
- * it.
+ * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
+ * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace.
*
* We don't use copy_from_user() for optimization: we first do the
* sanity checks (buffer size -fast- and access check-healthy
@@ -584,38 +511,70 @@ err_bindx_rem:
*
* Returns 0 if ok, <0 errno code on error.
*/
-SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
- struct sockaddr_storage *addrs,
- int addrssize, int op)
+SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr *addrs,
+ int addrs_size, int op)
{
- struct sockaddr_storage *kaddrs;
+ struct sockaddr *kaddrs;
int err;
- size_t addrcnt;
+ int addrcnt = 0;
+ int walk_size = 0;
+ struct sockaddr *sa_addr;
+ void *addr_buf;
+ struct sctp_af *af;
- SCTP_DEBUG_PRINTK("sctp_do_setsocktopt_bindx: sk %p addrs %p"
- " addrssize %d opt %d\n", sk, addrs, addrssize, op);
+ SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p"
+ " addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
- /* Do we have an integer number of structs sockaddr_storage? */
- if (unlikely(addrssize <= 0 ||
- addrssize % sizeof(struct sockaddr_storage) != 0))
+ if (unlikely(addrs_size <= 0))
return -EINVAL;
/* Check the user passed a healthy pointer. */
- if (unlikely(!access_ok(VERIFY_READ, addrs, addrssize)))
+ if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
return -EFAULT;
/* Alloc space for the address array in kernel memory. */
- kaddrs = (struct sockaddr_storage *) kmalloc(addrssize, GFP_KERNEL);
+ kaddrs = (struct sockaddr *)kmalloc(addrs_size, GFP_KERNEL);
if (unlikely(!kaddrs))
return -ENOMEM;
- if (copy_from_user(kaddrs, addrs, addrssize)) {
+ if (__copy_from_user(kaddrs, addrs, addrs_size)) {
kfree(kaddrs);
return -EFAULT;
}
- addrcnt = addrssize / sizeof(struct sockaddr_storage);
- err = __sctp_bindx(sk, kaddrs, addrcnt, op); /* Do the work. */
+ /* Walk through the addrs buffer and count the number of addresses. */
+ addr_buf = kaddrs;
+ while (walk_size < addrs_size) {
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+
+ /* If the address family is not supported or if this address
+ * causes the address buffer to overflow return EINVAL.
+ */
+ if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
+ kfree(kaddrs);
+ return -EINVAL;
+ }
+ addrcnt++;
+ addr_buf += af->sockaddr_len;
+ walk_size += af->sockaddr_len;
+ }
+
+ /* Do the work. */
+ switch (op) {
+ case SCTP_BINDX_ADD_ADDR:
+ err = sctp_bindx_add(sk, kaddrs, addrcnt);
+ break;
+
+ case SCTP_BINDX_REM_ADDR:
+ err = sctp_bindx_rem(sk, kaddrs, addrcnt);
+ break;
+
+ default:
+ err = -EINVAL;
+ break;
+ };
+
kfree(kaddrs);
return err;
@@ -1476,7 +1435,7 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char *optval, int optlen)
}
/*
- * 7.1.14 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
*
* Applications that wish to use the sendto() system call may wish to
* specify a default set of parameters that would normally be supplied
@@ -1522,7 +1481,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
return 0;
}
-/* 7.1.10 Set Peer Primary Address (SCTP_PRIMARY_ADDR)
+/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
*
* Requests that the local SCTP stack use the enclosed peer address as
* the association primary. The enclosed address must be one of the
@@ -1727,6 +1686,62 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char *optval, int optlen)
return 0;
}
+
+/*
+ * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+ *
+ * Requests that the peer mark the enclosed address as the association
+ * primary. The enclosed address must be one of the association's
+ * locally bound addresses. The following structure is used to make a
+ * set primary request:
+ */
+static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
+ int optlen)
+{
+ struct sctp_opt *sp;
+ struct sctp_endpoint *ep;
+ struct sctp_association *asoc = NULL;
+ struct sctp_setpeerprim prim;
+ struct sctp_chunk *chunk;
+ int err;
+
+ sp = sctp_sk(sk);
+ ep = sp->ep;
+
+ if (optlen != sizeof(struct sctp_setpeerprim))
+ return -EINVAL;
+
+ if (copy_from_user(&prim, optval, optlen))
+ return -EFAULT;
+
+ asoc = sctp_id2assoc(sk, prim.sspp_assoc_id);
+ if (!asoc)
+ return -EINVAL;
+
+ if (!sctp_state(asoc, ESTABLISHED))
+ return -ENOTCONN;
+
+ if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
+ return -EADDRNOTAVAIL;
+
+ /* Create an ASCONF chunk with SET_PRIMARY parameter */
+ chunk = sctp_make_asconf_set_prim(asoc,
+ (union sctp_addr *)&prim.sspp_addr);
+ if (!chunk)
+ return -ENOMEM;
+
+ err = sctp_primitive_ASCONF(asoc, chunk);
+ if (err) {
+ sctp_chunk_free(chunk);
+ return err;
+ }
+
+ SCTP_DEBUG_PRINTK("We set peer primary addr primitively.\n");
+
+ return 0;
+}
+
+
/* API 6.2 setsockopt(), getsockopt()
*
* Applications use setsockopt() and getsockopt() to set or retrieve
@@ -1771,16 +1786,14 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
switch (optname) {
case SCTP_SOCKOPT_BINDX_ADD:
/* 'optlen' is the size of the addresses buffer. */
- retval = sctp_setsockopt_bindx(sk, (struct sockaddr_storage *)
- optval, optlen,
- SCTP_BINDX_ADD_ADDR);
+ retval = sctp_setsockopt_bindx(sk, (struct sockaddr *)optval,
+ optlen, SCTP_BINDX_ADD_ADDR);
break;
case SCTP_SOCKOPT_BINDX_REM:
/* 'optlen' is the size of the addresses buffer. */
- retval = sctp_setsockopt_bindx(sk, (struct sockaddr_storage *)
- optval, optlen,
- SCTP_BINDX_REM_ADDR);
+ retval = sctp_setsockopt_bindx(sk, (struct sockaddr *)optval,
+ optlen, SCTP_BINDX_REM_ADDR);
break;
case SCTP_DISABLE_FRAGMENTS:
@@ -1809,6 +1822,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_PRIMARY_ADDR:
retval = sctp_setsockopt_primary_addr(sk, optval, optlen);
break;
+ case SCTP_SET_PEER_PRIMARY_ADDR:
+ retval = sctp_setsockopt_peer_primary_addr(sk, optval, optlen);
+ break;
case SCTP_NODELAY:
retval = sctp_setsockopt_nodelay(sk, optval, optlen);
break;
@@ -2056,9 +2072,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
return -ESOCKTNOSUPPORT;
}
- /* FIXME: The next draft (04) of the SCTP Sockets Extensions
- * should include a socket option for manipulating these
- * message parameters (and a few others).
+ /* Initialize default send parameters. These parameters can be
+ * modified with the SCTP_DEFAULT_SEND_PARAM socket option.
*/
sp->default_stream = 0;
sp->default_ppid = 0;
@@ -2077,7 +2092,6 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
/* Initialize default RTO related parameters. These parameters can
* be modified for with the SCTP_RTOINFO socket option.
- * FIXME: These are not used yet.
*/
sp->rtoinfo.srto_initial = (sctp_rto_initial / HZ) * 1000;
sp->rtoinfo.srto_max = (sctp_rto_max / HZ) * 1000;
@@ -2093,15 +2107,10 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->assocparams.sasoc_cookie_life = (sctp_valid_cookie_life / HZ)
* 1000;
- /* Initialize default event subscriptions.
- * the struct sock is initialized to zero, so only
- * enable the events needed. By default, UDP-style
- * sockets enable io and association change notifications.
+ /* Initialize default event subscriptions. By default, all the
+ * options are off.
*/
- if (sctp_style(sk, UDP)) {
- sp->subscribe.sctp_data_io_event = 1;
- sp->subscribe.sctp_association_event = 1;
- }
+ memset(&sp->subscribe, 0, sizeof(struct sctp_event_subscribe));
/* Default Peer Address Parameters. These defaults can
* be modified via SCTP_PEER_ADDR_PARAMS
@@ -2552,7 +2561,7 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int *
}
static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
sctp_assoc_t id;
struct sctp_association *asoc;
@@ -2565,9 +2574,7 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
if (copy_from_user(&id, optval, sizeof(sctp_assoc_t)))
return -EFAULT;
- /*
- * For UDP-style sockets, id specifies the association to query.
- */
+ /* For UDP-style sockets, id specifies the association to query. */
asoc = sctp_id2assoc(sk, id);
if (!asoc)
return -EINVAL;
@@ -2582,16 +2589,17 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
}
static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
struct sctp_association *asoc;
struct list_head *pos;
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_transport *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2600,21 +2608,21 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return -EFAULT;
if (getaddrs.addr_num <= 0) return -EINVAL;
- /*
- * For UDP-style sockets, id specifies the association to query.
- */
+
+ /* For UDP-style sockets, id specifies the association to query. */
asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
if (!asoc)
return -EINVAL;
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &asoc->peer.transport_addr_list) {
from = list_entry(pos, struct sctp_transport, transports);
memcpy(&temp, &from->ipaddr, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
- if (copy_to_user(to, &temp, sizeof(temp)))
+ addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+ if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
- to ++;
+ to += addrlen ;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
@@ -2673,9 +2681,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_sockaddr_entry *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2699,16 +2708,17 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
bp = &asoc->base.bind_addr;
}
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &bp->address_list) {
from = list_entry(pos,
struct sctp_sockaddr_entry,
list);
memcpy(&temp, &from->a, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
- if (copy_to_user(to, &temp, sizeof(temp)))
+ addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+ if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
- to ++;
+ to += addrlen;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
@@ -2759,7 +2769,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
/*
*
- * 7.1.14 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
*
* Applications that wish to use the sendto() system call may wish to
* specify a default set of parameters that would normally be supplied
@@ -3331,9 +3341,19 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
if (!sctp_style(sk, UDP))
return -EINVAL;
+ /* If backlog is zero, disable listening. */
+ if (!backlog) {
+ if (sctp_sstate(sk, CLOSED))
+ return 0;
+
+ sctp_unhash_endpoint(ep);
+ sk->sk_state = SCTP_SS_CLOSED;
+ }
+
+ /* Return if we are already listening. */
if (sctp_sstate(sk, LISTENING))
return 0;
-
+
/*
* If a bind() or sctp_bindx() is not called prior to a listen()
* call that allows new associations to be accepted, the system
@@ -3364,6 +3384,15 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
struct sctp_opt *sp = sctp_sk(sk);
struct sctp_endpoint *ep = sp->ep;
+ /* If backlog is zero, disable listening. */
+ if (!backlog) {
+ if (sctp_sstate(sk, CLOSED))
+ return 0;
+
+ sctp_unhash_endpoint(ep);
+ sk->sk_state = SCTP_SS_CLOSED;
+ }
+
if (sctp_sstate(sk, LISTENING))
return 0;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index cdcf6d09d24f..edffe9cc8f21 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -214,7 +214,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (olen != sizeof (int))
return -EINVAL;
}
- if (put_user((*(int *)(table->data) / HZ) * 1000,
+ if (put_user((*(int *)(table->data) * 1000) / HZ,
(int *)oldval) ||
(oldlenp && put_user(sizeof (int), oldlenp)))
return -EFAULT;
@@ -228,7 +228,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (get_user(new, (int *)newval))
return -EFAULT;
- *(int *)(table->data) = (new * HZ) * 1000;
+ *(int *)(table->data) = (new * HZ) / 1000;
}
return 1;
}
diff --git a/net/socket.c b/net/socket.c
index 74fd11fdd7a8..f0a1a3da7500 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1894,6 +1894,8 @@ int sock_register(struct net_proto_family *ops)
err = 0;
}
net_family_write_unlock();
+ printk(KERN_INFO "NET: Registered protocol family %d\n",
+ ops->family);
return err;
}
@@ -1911,6 +1913,8 @@ int sock_unregister(int family)
net_family_write_lock();
net_families[family]=NULL;
net_family_write_unlock();
+ printk(KERN_INFO "NET: Unregistered protocol family %d\n",
+ family);
return 0;
}
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 4ba7f3d5c2e4..67a13170c6d7 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -20,7 +20,6 @@
#include <linux/proc_fs.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svcsock.h>
-#include <linux/init.h>
#define RPCDBG_FACILITY RPCDBG_MISC
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d9dd8a2f3914..549c7e303144 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -111,6 +111,7 @@
#include <linux/tcp.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
@@ -1805,25 +1806,52 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
#ifdef CONFIG_PROC_FS
-static int unix_read_proc(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
+static struct sock *unix_seq_idx(int *iter, loff_t pos)
{
- off_t pos=0;
- off_t begin=0;
- int len=0;
- int i;
+ loff_t off = 0;
struct sock *s;
-
- len+= sprintf(buffer,"Num RefCount Protocol Flags Type St "
- "Inode Path\n");
+ for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
+ if (off == pos)
+ return s;
+ ++off;
+ }
+ return NULL;
+}
+
+
+static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
+{
read_lock(&unix_table_lock);
- forall_unix_sockets (i,s)
- {
+ return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
+}
+
+static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+
+ if (v == (void *)1)
+ return first_unix_socket(seq->private);
+ return next_unix_socket(seq->private, v);
+}
+
+static void unix_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&unix_table_lock);
+}
+
+static int unix_seq_show(struct seq_file *seq, void *v)
+{
+
+ if (v == (void *)1)
+ seq_puts(seq, "Num RefCount Protocol Flags Type St "
+ "Inode Path\n");
+ else {
+ struct sock *s = v;
struct unix_sock *u = unix_sk(s);
unix_state_rlock(s);
- len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5lu",
+ seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
s,
atomic_read(&s->sk_refcnt),
0,
@@ -1835,39 +1863,61 @@ static int unix_read_proc(char *buffer, char **start, off_t offset,
sock_i_ino(s));
if (u->addr) {
- buffer[len++] = ' ';
- memcpy(buffer+len, u->addr->name->sun_path,
- u->addr->len-sizeof(short));
- if (!UNIX_ABSTRACT(s))
- len--;
- else
- buffer[len] = '@';
- len += u->addr->len - sizeof(short);
- }
- unix_state_runlock(s);
+ int i;
+ seq_putc(seq, ' ');
+
+ for (i = 0; i < u->addr->len-sizeof(short); i++)
+ seq_putc(seq, u->addr->name->sun_path[i]);
- buffer[len++]='\n';
-
- pos = begin + len;
- if(pos<offset)
- {
- len=0;
- begin=pos;
+ if (UNIX_ABSTRACT(s))
+ seq_putc(seq, '@');
}
- if(pos>offset+length)
- goto done;
+ unix_state_runlock(s);
+ seq_putc(seq, '\n');
}
- *eof = 1;
-done:
- read_unlock(&unix_table_lock);
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- if (len < 0)
- len = 0;
- return len;
+
+ return 0;
}
+
+struct seq_operations unix_seq_ops = {
+ .start = unix_seq_start,
+ .next = unix_seq_next,
+ .stop = unix_seq_stop,
+ .show = unix_seq_show,
+};
+
+
+static int unix_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+ int *iter = kmalloc(sizeof(int), GFP_KERNEL);
+
+ if (!iter)
+ goto out;
+
+ rc = seq_open(file, &unix_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+ seq->private = iter;
+ *iter = 0;
+out:
+ return rc;
+out_kfree:
+ kfree(iter);
+ goto out;
+}
+
+static struct file_operations unix_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = unix_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
#endif
struct proto_ops unix_stream_ops = {
@@ -1926,13 +1976,10 @@ static inline void unix_sysctl_register(void) {}
static inline void unix_sysctl_unregister(void) {}
#endif
-static char banner[] __initdata = KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n";
-
static int __init af_unix_init(void)
{
struct sk_buff *dummy_skb;
- printk(banner);
if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
return -1;
@@ -1947,7 +1994,7 @@ static int __init af_unix_init(void)
sock_register(&unix_family_ops);
#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL);
+ proc_net_fops_create("unix", 0, &unix_seq_fops);
#endif
unix_sysctl_register();
return 0;
@@ -1957,7 +2004,7 @@ static void __exit af_unix_exit(void)
{
sock_unregister(PF_UNIX);
unix_sysctl_unregister();
- remove_proc_entry("net/unix", 0);
+ proc_net_remove("unix");
kmem_cache_destroy(unix_sk_cachep);
}
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 3bc431d4617f..ac4d772d77ad 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -3,11 +3,14 @@ config SECURITY_SELINUX
depends on SECURITY
default n
help
- This enables NSA Security-Enhanced Linux (SELinux).
+ This selects NSA Security-Enhanced Linux (SELinux).
You will also need a policy configuration and a labeled filesystem.
You can obtain the policy compiler (checkpolicy), the utility for
labeling filesystems (setfiles), and an example policy configuration
from http://www.nsa.gov/selinux.
+ SELinux needs to be explicitly enabled on the kernel command line with
+ selinux=1. If you specify selinux=0 or do not use this parameter,
+ SELinux will not be enabled.
If you are unsure how to answer this question, answer N.
config SECURITY_SELINUX_DEVELOP
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fc514f4517e9..d8c724a9ec7c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -73,6 +73,15 @@ static int __init enforcing_setup(char *str)
__setup("enforcing=", enforcing_setup);
#endif
+int selinux_enabled = 0;
+
+static int __init selinux_enabled_setup(char *str)
+{
+ selinux_enabled = simple_strtol(str, NULL, 0);
+ return 1;
+}
+__setup("selinux=", selinux_enabled_setup);
+
/* Original (dummy) security module. */
static struct security_operations *original_ops = NULL;
@@ -3347,6 +3356,11 @@ __init int selinux_init(void)
{
struct task_security_struct *tsec;
+ if (!selinux_enabled) {
+ printk(KERN_INFO "SELinux: Not enabled at boot.\n");
+ return 0;
+ }
+
printk(KERN_INFO "SELinux: Initializing.\n");
/* Set the security state for the initial task. */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 1b3aa3f62782..8fa2533b0042 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -17,6 +17,8 @@
#include "security.h"
#include "objsec.h"
+extern int selinux_enabled;
+
/* Check whether a task is allowed to use a security operation. */
int task_has_security(struct task_struct *tsk,
u32 perms)
@@ -587,7 +589,7 @@ static struct file_system_type sel_fs_type = {
static int __init init_sel_fs(void)
{
- return register_filesystem(&sel_fs_type);
+ return selinux_enabled ? register_filesystem(&sel_fs_type) : 0;
}
__initcall(init_sel_fs);
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 2fd75db6ea71..6f5956b25f0b 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -1145,10 +1145,18 @@ config SOUND_ALI5455
config SOUND_FORTE
tristate "ForteMedia FM801 driver"
depends on SOUND_PRIME!=n && PCI
+ help
+ Say Y or M if you want driver support for the ForteMedia FM801 PCI
+ audio controller (Abit AU10, Genius Sound Maker, HP Workstation
+ zx2000, and others).
config SOUND_RME96XX
tristate "RME Hammerfall (RME96XX) support"
depends on SOUND_PRIME!=n && PCI
+ help
+ Say Y or M if you have a Hammerfall or Hammerfall light
+ multichannel card from RME. If you want to acess advanced
+ features of the card, read Documentation/sound/rme96xx.
config SOUND_AD1980
tristate "AD1980 front/back switch plugin"