aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem <davem>2001-12-11 04:55:46 +0000
committerdavem <davem>2001-12-11 04:55:46 +0000
commit470e747d5619a63fadeda686b0a73cde195c787c (patch)
treedf79ee75a66ca2f98ba1f35057ca4a358f587bb8
parenta190194a9dcbbd6b2d87b15682209454fb7d42e9 (diff)
downloadnetdev-vger-cvs-470e747d5619a63fadeda686b0a73cde195c787c.tar.gz
Merge mainline to 2.5.1-pre8
This is being checked in knowing it is BROKEN on sparc64. My SBUS/ESP workstation gets full on filesystem corruption with this tree. I would advise staying away from this tree until I figure things out.
-rw-r--r--CREDITS20
-rw-r--r--Documentation/Changes37
-rw-r--r--Documentation/Configure.help433
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl77
-rw-r--r--Documentation/filesystems/devfs/ChangeLog25
-rw-r--r--Documentation/usb/error-codes.txt29
-rw-r--r--Makefile11
-rw-r--r--README18
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c1
-rw-r--r--arch/alpha/kernel/irq.c38
-rw-r--r--arch/arm/kernel/fiq.c10
-rw-r--r--arch/arm/kernel/irq.c18
-rw-r--r--arch/cris/kernel/irq.c13
-rw-r--r--arch/i386/boot/bootsect.S2
-rw-r--r--arch/i386/defconfig2
-rw-r--r--arch/i386/kernel/apm.c18
-rw-r--r--arch/i386/kernel/dmi_scan.c8
-rw-r--r--arch/i386/kernel/irq.c45
-rw-r--r--arch/i386/kernel/mtrr.c2
-rw-r--r--arch/i386/kernel/pci-pc.c46
-rw-r--r--arch/i386/kernel/semaphore.c49
-rw-r--r--arch/i386/kernel/setup.c11
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/ia64/kernel/irq.c42
-rw-r--r--arch/m68k/amiga/amiints.c23
-rw-r--r--arch/m68k/amiga/cia.c13
-rw-r--r--arch/m68k/amiga/config.c4
-rw-r--r--arch/m68k/apollo/config.c4
-rw-r--r--arch/m68k/apollo/dn_ints.c2
-rw-r--r--arch/m68k/atari/ataints.c19
-rw-r--r--arch/m68k/atari/config.c4
-rw-r--r--arch/m68k/atari/joystick.c2
-rw-r--r--arch/m68k/bvme6000/bvmeints.c9
-rw-r--r--arch/m68k/bvme6000/config.c4
-rw-r--r--arch/m68k/hp300/config.c4
-rw-r--r--arch/m68k/hp300/ints.c2
-rw-r--r--arch/m68k/kernel/ints.c14
-rw-r--r--arch/m68k/kernel/setup.c2
-rw-r--r--arch/m68k/mac/config.c4
-rw-r--r--arch/m68k/mac/macints.c20
-rw-r--r--arch/m68k/mvme147/147ints.c9
-rw-r--r--arch/m68k/mvme147/config.c4
-rw-r--r--arch/m68k/mvme16x/16xints.c9
-rw-r--r--arch/m68k/mvme16x/config.c4
-rw-r--r--arch/m68k/mvme16x/rtc.c12
-rw-r--r--arch/m68k/q40/config.c4
-rw-r--r--arch/m68k/q40/q40ints.c12
-rw-r--r--arch/m68k/sun3/config.c4
-rw-r--r--arch/m68k/sun3/sun3ints.c3
-rw-r--r--arch/m68k/sun3x/config.c2
-rw-r--r--arch/mips/baget/irq.c13
-rw-r--r--arch/mips/dec/irq.c39
-rw-r--r--arch/mips/ite-boards/generic/irq.c29
-rw-r--r--arch/mips/kernel/irq.c26
-rw-r--r--arch/mips/kernel/old-irq.c13
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c13
-rw-r--r--arch/mips/philips/nino/irq.c13
-rw-r--r--arch/mips64/mips-boards/atlas/atlas_int.c13
-rw-r--r--arch/mips64/mips-boards/malta/malta_int.c19
-rw-r--r--arch/mips64/sgi-ip22/ip22-int.c19
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c13
-rw-r--r--arch/mips64/sgi-ip27/ip27-rtc.c25
-rw-r--r--arch/parisc/kernel/irq.c40
-rw-r--r--arch/ppc/amiga/amiints.c21
-rw-r--r--arch/ppc/amiga/cia.c13
-rw-r--r--arch/ppc/amiga/config.c5
-rw-r--r--arch/ppc/amiga/ints.c15
-rw-r--r--arch/ppc/kernel/apus_setup.c8
-rw-r--r--arch/ppc/kernel/irq.c43
-rw-r--r--arch/s390/kernel/irq.c36
-rw-r--r--arch/s390x/kernel/irq.c32
-rw-r--r--arch/sh/kernel/irq.c24
-rw-r--r--arch/sparc/kernel/irq.c25
-rw-r--r--arch/sparc/kernel/sun4d_irq.c21
-rw-r--r--arch/sparc64/kernel/iommu_common.c20
-rw-r--r--arch/sparc64/kernel/irq.c27
-rw-r--r--arch/sparc64/kernel/signal.c3
-rw-r--r--arch/sparc64/kernel/signal32.c3
-rw-r--r--arch/sparc64/solaris/misc.c3
-rw-r--r--arch/sparc64/solaris/socksys.c4
-rw-r--r--drivers/acorn/scsi/arxescsi.h1
-rw-r--r--drivers/acorn/scsi/cumana_2.c1
-rw-r--r--drivers/acorn/scsi/eesox.c1
-rw-r--r--drivers/acorn/scsi/powertec.c1
-rw-r--r--drivers/block/DAC960.c250
-rw-r--r--drivers/block/DAC960.h15
-rw-r--r--drivers/block/Makefile4
-rw-r--r--drivers/block/acsi.c23
-rw-r--r--drivers/block/acsi_slm.c28
-rw-r--r--drivers/block/amiflop.c3
-rw-r--r--drivers/block/blkpg.c58
-rw-r--r--drivers/block/block_ioctl.c80
-rw-r--r--drivers/block/cciss.c295
-rw-r--r--drivers/block/cciss.h11
-rw-r--r--drivers/block/cciss_cmd.h2
-rw-r--r--drivers/block/cpqarray.c222
-rw-r--r--drivers/block/cpqarray.h8
-rw-r--r--drivers/block/elevator.c220
-rw-r--r--drivers/block/floppy.c119
-rw-r--r--drivers/block/genhd.c36
-rw-r--r--drivers/block/ida_cmd.h2
-rw-r--r--drivers/block/ll_rw_blk.c1435
-rw-r--r--drivers/block/loop.c238
-rw-r--r--drivers/block/nbd.c67
-rw-r--r--drivers/block/paride/pcd.c18
-rw-r--r--drivers/block/paride/pd.c161
-rw-r--r--drivers/block/paride/pf.c99
-rw-r--r--drivers/block/paride/pg.c15
-rw-r--r--drivers/block/paride/pt.c24
-rw-r--r--drivers/block/ps2esdi.c53
-rw-r--r--drivers/block/rd.c73
-rw-r--r--drivers/block/xd.c41
-rw-r--r--drivers/cdrom/cdrom.c4
-rw-r--r--drivers/cdrom/cdu31a.c7
-rw-r--r--drivers/cdrom/cm206.c4
-rw-r--r--drivers/cdrom/sbpcd.c9
-rw-r--r--drivers/char/acquirewdt.c2
-rw-r--r--drivers/char/advantechwdt.c2
-rw-r--r--drivers/char/agp/agp.h2
-rw-r--r--drivers/char/agp/agpgart_be.c92
-rw-r--r--drivers/char/agp/agpgart_fe.c14
-rw-r--r--drivers/char/busmouse.c4
-rw-r--r--drivers/char/dtlk.c4
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c29
-rw-r--r--drivers/char/joystick/ns558.c12
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/mixcomwd.c3
-rw-r--r--drivers/char/nvram.c15
-rw-r--r--drivers/char/pc110pad.c28
-rw-r--r--drivers/char/pc_keyb.c38
-rw-r--r--drivers/char/pcwd.c17
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/qpmouse.c10
-rw-r--r--drivers/char/qtronix.c2
-rw-r--r--drivers/char/raw.c28
-rw-r--r--drivers/char/sbc60xxwdt.c2
-rw-r--r--drivers/char/serial.c2
-rw-r--r--drivers/char/softdog.c2
-rw-r--r--drivers/char/tpqic02.c2
-rw-r--r--drivers/char/tty_io.c11
-rw-r--r--drivers/char/w83877f_wdt.c2
-rw-r--r--drivers/char/wdt.c9
-rw-r--r--drivers/char/wdt285.c2
-rw-r--r--drivers/char/wdt977.c2
-rw-r--r--drivers/char/wdt_pci.c12
-rw-r--r--drivers/fc4/fc.c8
-rw-r--r--drivers/fc4/soc.c5
-rw-r--r--drivers/fc4/soc.h1
-rw-r--r--drivers/fc4/socal.c5
-rw-r--r--drivers/fc4/socal.h1
-rw-r--r--drivers/i2c/i2c-dev.c5
-rw-r--r--drivers/ide/aec62xx.c1
-rw-r--r--drivers/ide/amd74xx.c33
-rw-r--r--drivers/ide/cmd64x.c2
-rw-r--r--drivers/ide/cs5530.c5
-rw-r--r--drivers/ide/cy82c693.c1
-rw-r--r--drivers/ide/hd.c45
-rw-r--r--drivers/ide/hpt34x.c1
-rw-r--r--drivers/ide/hpt366.c1
-rw-r--r--drivers/ide/ide-cd.c272
-rw-r--r--drivers/ide/ide-cd.h2
-rw-r--r--drivers/ide/ide-cs.c19
-rw-r--r--drivers/ide/ide-disk.c71
-rw-r--r--drivers/ide/ide-dma.c174
-rw-r--r--drivers/ide/ide-floppy.c63
-rw-r--r--drivers/ide/ide-pci.c34
-rw-r--r--drivers/ide/ide-probe.c34
-rw-r--r--drivers/ide/ide-proc.c2
-rw-r--r--drivers/ide/ide-tape.c8
-rw-r--r--drivers/ide/ide.c357
-rw-r--r--drivers/ide/pdc202xx.c1
-rw-r--r--drivers/ide/piix.c32
-rw-r--r--drivers/ide/serverworks.c1
-rw-r--r--drivers/ide/sis5513.c1
-rw-r--r--drivers/ide/slc90e66.c1
-rw-r--r--drivers/ide/via82cxxx.c1
-rw-r--r--drivers/ieee1394/raw1394.c2
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/input/joydev.c4
-rw-r--r--drivers/input/mousedev.c4
-rw-r--r--drivers/isdn/hisax/st5481_b.c2
-rw-r--r--drivers/isdn/hisax/st5481_d.c2
-rw-r--r--drivers/isdn/hisax/st5481_usb.c6
-rw-r--r--drivers/macintosh/adb.c2
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/md/linear.c13
-rw-r--r--drivers/md/lvm-snap.c12
-rw-r--r--drivers/md/lvm.c85
-rw-r--r--drivers/md/md.c38
-rw-r--r--drivers/md/raid0.c17
-rw-r--r--drivers/media/video/saa7146.h1
-rw-r--r--drivers/media/video/stradis.c98
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptscsih.c38
-rw-r--r--drivers/message/fusion/mptscsih.h1
-rw-r--r--drivers/message/i2o/i2o_block.c233
-rw-r--r--drivers/message/i2o/i2o_config.c2
-rw-r--r--drivers/message/i2o/i2o_core.c2
-rw-r--r--drivers/message/i2o/i2o_scsi.c13
-rw-r--r--drivers/mtd/ftl.c33
-rw-r--r--drivers/mtd/mtdblock.c14
-rw-r--r--drivers/mtd/nftlcore.c58
-rw-r--r--drivers/net/3c509.c20
-rw-r--r--drivers/net/3c515.c14
-rw-r--r--drivers/net/fc/iph5526.c1
-rw-r--r--drivers/net/hamradio/baycom_epp.c3
-rw-r--r--drivers/net/irda/irda-usb.c34
-rw-r--r--drivers/net/ppp_generic.c2
-rw-r--r--drivers/net/smc-ultra.c10
-rw-r--r--drivers/net/tlan.c4
-rw-r--r--drivers/net/wan/cosa.c2
-rw-r--r--drivers/pci/setup-res.c5
-rw-r--r--drivers/pcmcia/ds.c2
-rw-r--r--drivers/pcmcia/i82365.c10
-rw-r--r--drivers/pnp/isapnp_proc.c4
-rw-r--r--drivers/s390/block/dasd.c61
-rw-r--r--drivers/s390/block/xpram.c9
-rw-r--r--drivers/s390/char/tapeblock.c7
-rw-r--r--drivers/sbus/char/jsflash.c1
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/53c7,8xx.c8
-rw-r--r--drivers/scsi/53c700.c1
-rw-r--r--drivers/scsi/Config.in4
-rw-r--r--drivers/scsi/Makefile8
-rw-r--r--drivers/scsi/advansys.h1
-rw-r--r--drivers/scsi/aha152x.h3
-rw-r--r--drivers/scsi/aha1542.h5
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_linux.c33
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_linux_host.h2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h17
-rw-r--r--drivers/scsi/aic7xxx_old.c14
-rw-r--r--drivers/scsi/aic7xxx_old/aic7xxx.h1
-rw-r--r--drivers/scsi/atp870u.h1
-rw-r--r--drivers/scsi/cpqfcTS.h1
-rw-r--r--drivers/scsi/dc390.h1
-rw-r--r--drivers/scsi/dpt_i2o.c1
-rw-r--r--drivers/scsi/dpti.h1
-rw-r--r--drivers/scsi/eata.h1
-rw-r--r--drivers/scsi/esp.c45
-rw-r--r--drivers/scsi/esp.h5
-rw-r--r--drivers/scsi/fcal.h1
-rw-r--r--drivers/scsi/gdth.h6
-rw-r--r--drivers/scsi/hosts.c5
-rw-r--r--drivers/scsi/hosts.h11
-rw-r--r--drivers/scsi/ide-scsi.c90
-rw-r--r--drivers/scsi/imm.c18
-rw-r--r--drivers/scsi/imm.h1
-rw-r--r--drivers/scsi/in2000.h1
-rw-r--r--drivers/scsi/ini9100u.h1
-rw-r--r--drivers/scsi/inia100.h1
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/mac53c94.h1
-rw-r--r--drivers/scsi/mac_esp.h3
-rw-r--r--drivers/scsi/megaraid.c30
-rw-r--r--drivers/scsi/megaraid.h3
-rw-r--r--drivers/scsi/mesh.h1
-rw-r--r--drivers/scsi/pci2000.h1
-rw-r--r--drivers/scsi/pci2220i.h1
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c1
-rw-r--r--drivers/scsi/pluto.h1
-rw-r--r--drivers/scsi/ppa.h1
-rw-r--r--drivers/scsi/qla1280.h1
-rw-r--r--drivers/scsi/qlogicfc.c15
-rw-r--r--drivers/scsi/qlogicfc.h3
-rw-r--r--drivers/scsi/qlogicisp.c12
-rw-r--r--drivers/scsi/qlogicpti.h2
-rw-r--r--drivers/scsi/scsi.c152
-rw-r--r--drivers/scsi/scsi.h9
-rw-r--r--drivers/scsi/scsi_debug.h1
-rw-r--r--drivers/scsi/scsi_error.c67
-rw-r--r--drivers/scsi/scsi_lib.c194
-rw-r--r--drivers/scsi/scsi_merge.c670
-rw-r--r--drivers/scsi/scsi_queue.c5
-rw-r--r--drivers/scsi/scsi_syms.c1
-rw-r--r--drivers/scsi/sd.c244
-rw-r--r--drivers/scsi/sg.c3
-rw-r--r--drivers/scsi/sim710.h3
-rw-r--r--drivers/scsi/sr.c81
-rw-r--r--drivers/scsi/sym53c8xx.c20
-rw-r--r--drivers/scsi/sym53c8xx.h5
-rw-r--r--drivers/scsi/sym53c8xx_2/sym53c8xx.h4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c38
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c18
-rw-r--r--drivers/scsi/u14-34f.h1
-rw-r--r--drivers/scsi/wd7000.h1
-rw-r--r--drivers/sgi/char/graphics.c2
-rw-r--r--drivers/sgi/char/shmiq.c44
-rw-r--r--drivers/sgi/char/streamable.c2
-rw-r--r--drivers/sound/ad1816.c8
-rw-r--r--drivers/sound/awe_wave.c10
-rw-r--r--drivers/sound/cmpci.c2
-rw-r--r--drivers/sound/maestro3.c7
-rw-r--r--drivers/sound/opl3sa2.c20
-rw-r--r--drivers/sound/sb_card.c14
-rw-r--r--drivers/sound/sound_core.c2
-rw-r--r--drivers/usb/CDCEther.c23
-rw-r--r--drivers/usb/Config.in2
-rw-r--r--drivers/usb/audio.c58
-rw-r--r--drivers/usb/bluetooth.c123
-rw-r--r--drivers/usb/dabusb.c2
-rw-r--r--drivers/usb/dc2xx.c4
-rw-r--r--drivers/usb/devio.c7
-rw-r--r--drivers/usb/hid-core.c26
-rw-r--r--drivers/usb/hid.h91
-rw-r--r--drivers/usb/hiddev.c2
-rw-r--r--drivers/usb/hpusbscsi.h1
-rw-r--r--drivers/usb/inode.c16
-rw-r--r--drivers/usb/kaweth.c7
-rw-r--r--drivers/usb/mdc800.c112
-rw-r--r--drivers/usb/microtek.c1
-rw-r--r--drivers/usb/pegasus.c20
-rw-r--r--drivers/usb/pegasus.h5
-rw-r--r--drivers/usb/rio500.c6
-rw-r--r--drivers/usb/scanner.c4
-rw-r--r--drivers/usb/serial/belkin_sa.c148
-rw-r--r--drivers/usb/serial/cyberjack.c8
-rw-r--r--drivers/usb/serial/digi_acceleport.c47
-rw-r--r--drivers/usb/serial/empeg.c7
-rw-r--r--drivers/usb/serial/ftdi_sio.c11
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_tables.h12
-rw-r--r--drivers/usb/serial/ir-usb.c8
-rw-r--r--drivers/usb/serial/keyspan.c22
-rw-r--r--drivers/usb/serial/keyspan.h45
-rw-r--r--drivers/usb/serial/keyspan_pda.c36
-rw-r--r--drivers/usb/serial/mct_u232.c89
-rw-r--r--drivers/usb/serial/mct_u232.h24
-rw-r--r--drivers/usb/serial/omninet.c11
-rw-r--r--drivers/usb/serial/pl2303.c13
-rw-r--r--drivers/usb/serial/usb-serial.h44
-rw-r--r--drivers/usb/serial/usbserial.c135
-rw-r--r--drivers/usb/serial/visor.c119
-rw-r--r--drivers/usb/serial/whiteheat.c89
-rw-r--r--drivers/usb/serial/whiteheat_fw.h1671
-rw-r--r--drivers/usb/storage/scsiglue.c1
-rw-r--r--drivers/usb/usb-ohci.c12
-rw-r--r--drivers/usb/usb-ohci.h32
-rw-r--r--drivers/usb/usb.c585
-rw-r--r--drivers/usb/usbkbd.c9
-rw-r--r--drivers/usb/usbmouse.c5
-rw-r--r--drivers/usb/usbnet.c7
-rw-r--r--drivers/usb/uss720.c2
-rw-r--r--drivers/video/modedb.c25
-rw-r--r--fs/Makefile7
-rw-r--r--fs/affs/file.c4
-rw-r--r--fs/autofs4/root.c4
-rw-r--r--fs/bfs/file.c2
-rw-r--r--fs/bio.c701
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/buffer.c198
-rw-r--r--fs/devfs/base.c118
-rw-r--r--fs/driverfs/Makefile8
-rw-r--r--fs/driverfs/inode.c822
-rw-r--r--fs/efs/file.c2
-rw-r--r--fs/efs/inode.c2
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext3/inode.c4
-rw-r--r--fs/fat/file.c2
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/inode.c13
-rw-r--r--fs/intermezzo/psdev.c2
-rw-r--r--fs/iobuf.c44
-rw-r--r--fs/isofs/inode.c4
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/minix/itree_common.c2
-rw-r--r--fs/namei.c2
-rw-r--r--fs/namespace.c205
-rw-r--r--fs/partitions/check.c86
-rw-r--r--fs/partitions/check.h2
-rw-r--r--fs/partitions/ldm.c1
-rw-r--r--fs/proc/proc_misc.c69
-rw-r--r--fs/readdir.c4
-rw-r--r--fs/reiserfs/inode.c141
-rw-r--r--fs/reiserfs/journal.c26
-rw-r--r--fs/super.c635
-rw-r--r--fs/sysv/itree.c2
-rw-r--r--fs/udf/inode.c4
-rw-r--r--fs/ufs/inode.c2
-rw-r--r--include/asm-alpha/io.h2
-rw-r--r--include/asm-alpha/page.h1
-rw-r--r--include/asm-arm/mach/irq.h2
-rw-r--r--include/asm-i386/checksum.h106
-rw-r--r--include/asm-i386/floppy.h44
-rw-r--r--include/asm-i386/kmap_types.h1
-rw-r--r--include/asm-m68k/machdep.h5
-rw-r--r--include/asm-m68k/macintosh.h4
-rw-r--r--include/asm-m68k/sun3ints.h3
-rw-r--r--include/asm-ppc/kmap_types.h1
-rw-r--r--include/asm-sparc/kmap_types.h1
-rw-r--r--include/asm-sparc64/io.h5
-rw-r--r--include/linux/bio.h179
-rw-r--r--include/linux/blk.h148
-rw-r--r--include/linux/blkdev.h278
-rw-r--r--include/linux/bootmem.h5
-rw-r--r--include/linux/devfs_fs_kernel.h2
-rw-r--r--include/linux/device.h253
-rw-r--r--include/linux/driverfs_fs.h73
-rw-r--r--include/linux/elevator.h61
-rw-r--r--include/linux/fs.h42
-rw-r--r--include/linux/genhd.h33
-rw-r--r--include/linux/highmem.h42
-rw-r--r--include/linux/ide.h83
-rw-r--r--include/linux/iobuf.h12
-rw-r--r--include/linux/iso_fs.h2
-rw-r--r--include/linux/kbd_kern.h1
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/loop.h4
-rw-r--r--include/linux/lvm.h7
-rw-r--r--include/linux/msdos_fs.h2
-rw-r--r--include/linux/nbd.h17
-rw-r--r--include/linux/pci_ids.h6
-rw-r--r--include/linux/raid/md_k.h2
-rw-r--r--include/linux/reiserfs_fs.h526
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/seq_file.h5
-rw-r--r--include/linux/types.h11
-rw-r--r--include/linux/usb.h1001
-rw-r--r--include/linux/vt_kern.h1
-rw-r--r--init/do_mounts.c559
-rw-r--r--init/main.c272
-rw-r--r--ipc/shm.c27
-rw-r--r--kernel/Makefile5
-rw-r--r--kernel/device.c950
-rw-r--r--kernel/exit.c19
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/ksyms.c5
-rw-r--r--kernel/softirq.c6
-rw-r--r--mm/bootmem.c1
-rw-r--r--mm/filemap.c1
-rw-r--r--mm/highmem.c296
-rw-r--r--mm/page_io.c2
-rw-r--r--mm/slab.c12
-rw-r--r--mm/swapfile.c22
-rw-r--r--net/ipv4/ipconfig.c3
439 files changed, 12533 insertions, 9259 deletions
diff --git a/CREDITS b/CREDITS
index 5ea4b775f..382a935bf 100644
--- a/CREDITS
+++ b/CREDITS
@@ -140,9 +140,11 @@ D: Aladdin 1533/1543(C) chipset IDE
D: VIA MVP-3/TX Pro III chipset IDE
N: Jens Axboe
-E: axboe@image.dk
-D: Linux CD-ROM maintainer
-D: jiffies wrap fixes + schedule timeouts depending on HZ == 100
+E: axboe@suse.de
+D: Linux CD-ROM maintainer, DVD support
+D: elevator + block layer rewrites
+D: highmem I/O support
+D: misc hacking on IDE, SCSI, block drivers, etc
S: Peter Bangs Vej 258, 2TH
S: 2500 Valby
S: Denmark
@@ -1157,6 +1159,16 @@ S: 5000 Forbes Avenue
S: Pittsburgh, Pennsylvania 15213
S: USA
+N: Jan Harkes
+E: jaharkes@cs.cmu.edu
+W: http://www.coda.cs.cmu.edu/
+D: Coda file system
+S: Computer Science Department
+S: Carnegie Mellon University
+S: 5000 Forbes Avenue
+S: Pittsburgh, Pennsylvania 15213
+S: USA
+
N: Kai Harrekilde-Petersen
E: kai.harrekilde@get2net.dk
D: Original author of the ftape-HOWTO, i82078 fdc detection code.
@@ -2080,7 +2092,7 @@ S: Richardson, Texas 75081
S: USA
N: Patrick Mochel
-E: pat@osdl.org
+E: mochel@osdl.org
E: mochelp@infinity.powertie.org
D: PCI Power Management, ACPI work
S: 15275 SW Koll Parkway, Suite H
diff --git a/Documentation/Changes b/Documentation/Changes
index d4c8e8c31..f7e251222 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -2,13 +2,13 @@ Intro
=====
This document is designed to provide a list of the minimum levels of
-software necessary to run the 2.4 kernels, as well as provide brief
+software necessary to run the 2.5 kernels, as well as provide brief
instructions regarding any other "Gotchas" users may encounter when
-trying life on the Bleeding Edge. If upgrading from a pre-2.2.x
-kernel, please consult the Changes file included with 2.2.x kernels for
+trying life on the Bleeding Edge. If upgrading from a pre-2.4.x
+kernel, please consult the Changes file included with 2.4.x kernels for
additional information; most of that information will not be repeated
here. Basically, this document assumes that your system is already
-functional and running at least 2.2.x kernels.
+functional and running at least 2.4.x kernels.
This document is originally based on my "Changes" file for 2.0.x kernels
and therefore owes credit to the same people as that file (Jared Mauch,
@@ -31,7 +31,7 @@ al español de este documento en varios formatos.
Eine deutsche Version dieser Datei finden Sie unter
<http://www.stefan-winter.de/Changes-2.4.0.txt>.
-Last updated: May 9, 2001
+Last updated: November 29, 2001
Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
@@ -43,14 +43,14 @@ encountered a bug! If you're unsure what version you're currently
running, the suggested command should tell you.
Again, keep in mind that this list assumes you are already
-functionally running a Linux 2.2 kernel. Also, not all tools are
+functionally running a Linux 2.4 kernel. Also, not all tools are
necessary on all systems; obviously, if you don't have any PCMCIA (PC
Card) hardware, for example, you probably needn't concern yourself
with pcmcia-cs.
o Gnu C 2.95.3 # gcc --version
o Gnu make 3.77 # make --version
-o binutils 2.9.1.0.25 # ld -v
+o binutils 2.9.5.0.24 # ld -v
o util-linux 2.10o # fdformat --version
o modutils 2.4.2 # insmod -V
o e2fsprogs 1.25 # tune2fs
@@ -70,9 +70,9 @@ computer. The next paragraph applies to users of x86 CPUs, but not
necessarily to users of other CPUs. Users of other CPUs should obtain
information about their gcc version requirements from another source.
-The recommended compiler for the kernel is gcc 2.95.3 or .4, and it
+The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it
should be used when you need absolute stability. You may use gcc 3.0.x
-instead if you wish, although it may cause problems. Later versions of gcc
+instead if you wish, although it may cause problems. Later versions of gcc
have not received much testing for Linux kernel compilation, and there are
almost certainly bugs (mainly, but not exclusively, in the kernel) that
will need to be fixed in order to use these compilers. In any case, using
@@ -106,12 +106,6 @@ assembling the 16-bit boot code, removing the need for as86 to compile
your kernel. This change does, however, mean that you need a recent
release of binutils.
-If you can, upgrade to the latest 2.9.5 or 2.10 binutils release. Older
-releases such as 2.8, 2.8.xx, and the FSF's 2.9.1 should be avoided if
-at all possible. The later releases of 2.9.1.0.x (anything where x >= 22)
-can and do compile the kernel properly, but there are many benefits in
-upgrading to 2.9.5 or 2.10 if you're up to it.
-
System utils
============
@@ -276,7 +270,7 @@ o <ftp://sourceware.cygnus.com/pub/gcc/releases/egcs-1.1.2/egcs-1.1.2.tar.bz2>
gcc 2.95.3
----------
-o <ftp://ftp.gnu.org/pub/gnu/gcc/gcc-2.95.3.tar.gz>
+o <ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz>
Gnu Make
********
@@ -287,21 +281,14 @@ o <ftp://ftp.gnu.org/gnu/make/make-3.77.tar.gz>
Binutils
********
-
-2.9.1 series
-------------
-o <ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz>
-
-2.9.5 and 2.10 series
----------------------
-o <ftp://ftp.valinux.com/pub/support/hjl/binutils/>
+o <ftp://ftp.kernel.org/pub/linux/devel/binutils/>
System utilities
****************
Util-linux
----------
-o <ftp://ftp.kernel.org/pub/linux/utils/util-linux/util-linux-2.10o.tar.gz>
+o <ftp://ftp.kernel.org/pub/linux/utils/util-linux/>
Ksymoops
--------
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index b5d4a2df7..aeca339e8 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -2,7 +2,7 @@
# Eric S. Raymond <mailto:esr@thyrsus.com>
# Steven Cole <mailto:elenstev@mesatop.com>
#
-# Merged version 2.67: current with 2.4.17-pre5/2.5.1-pre6.
+# Merged version 2.61: current with 2.4.16/2.5.1-pre1.
#
# This version of the Linux kernel configuration help texts
# corresponds to kernel versions 2.4.x and 2.5.x.
@@ -241,7 +241,7 @@ CONFIG_MULTIQUAD
You will need a new lynxer.elf file to flash your firmware with - send
email to Martin.Bligh@us.ibm.com
-IO-APIC support on uniprocessors
+IO-APIC Support on Uniprocessors
CONFIG_X86_UP_IOAPIC
An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
SMP-capable replacement for PC-style interrupt controllers. Most
@@ -341,7 +341,7 @@ CONFIG_NOHIGHMEM
"high memory".
If you are compiling a kernel which will never run on a machine with
- more than 960 megabytes of total physical RAM, answer "off" here (default
+ more than 1 Gigabyte total physical RAM, answer "off" here (default
choice and suitable for most users). This will result in a "3GB/1GB"
split: 3GB are mapped so that each process sees a 3GB virtual memory
space and the remaining part of the 4GB virtual memory space is used
@@ -358,10 +358,10 @@ CONFIG_NOHIGHMEM
processors (Pentium Pro and better). NOTE: If you say "64GB" here,
then the kernel will not boot on CPUs that don't support PAE!
- The actual amount of total physical memory will either be auto
- detected or can be forced by using a kernel command line option such
- as "mem=256M". (Try "man bootparam" or see the documentation of your
- boot loader (grub, lilo or loadlin) about how to pass options to the
+ The actual amount of total physical memory will either be
+ auto detected or can be forced by using a kernel command line option
+ such as "mem=256M". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
If unsure, say "off".
@@ -376,7 +376,7 @@ CONFIG_HIGHMEM64G
Select this if you have a 32-bit processor and more than 4
gigabytes of physical RAM.
-Normal floppy disk support
+Normal PC floppy disk support
CONFIG_BLK_DEV_FD
If you want to use the floppy disk drive(s) of your PC under Linux,
say Y. Information about this driver, especially important for IBM
@@ -972,7 +972,7 @@ CONFIG_WDC_ALI15X3
SAY N!
-AMD Viper (7401/7409/7411) chipset support
+AMD Viper support
CONFIG_BLK_DEV_AMD74XX
This driver ensures (U)DMA support for the AMD756/760 Viper
chipsets.
@@ -983,7 +983,7 @@ CONFIG_BLK_DEV_AMD74XX
If unsure, say N.
-AMD Viper ATA-66 Override support (WIP)
+AMD Viper ATA-66 Override (WIP)
CONFIG_AMD74XX_OVERRIDE
This option auto-forces the ata66 flag.
This effect can be also invoked by calling "idex=ata66"
@@ -1595,7 +1595,7 @@ CONFIG_PARIDE_FIT2
(low speed) adapter that is used in some portable hard drives. If
you chose to build PARIDE support into your kernel, you may answer Y
here to build in the protocol driver, otherwise you should answer M
- to build it as a loadable module. The module will be called fit2.o.
+ to build it as a loadable module. The module will be called ktti.o.
You must also have a high-level driver for the type of device that
you want to support.
@@ -1963,13 +1963,13 @@ CONFIG_SNI_RM200_PCI
Technology and now in turn merged with Fujitsu. Say Y here to
support this machine type.
-Support for SGI-IP22 (Indy/Indigo2)
+Support for SGI IP22
CONFIG_SGI_IP22
This are the SGI Indy, Challenge S and Indigo2, as well as certain
OEM variants like the Tandem CMN B006S. To compile a Linux kernel
that runs on these, say Y here.
-Support for SGI IP27 (Origin200/2000)
+Support for SGI IP27
CONFIG_SGI_IP27
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
@@ -2025,26 +2025,13 @@ CONFIG_DZ
DZ11-family serial controllers for VAXstations, including the
DC7085, M7814, and M7819.
+
TURBOchannel support
CONFIG_TC
TurboChannel is a DEC (now Compaq) bus for Alpha and MIPS processors.
Documentation on writing device drivers for TurboChannel is available at:
<http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>.
-# Choice: galileo_clock
-75
-CONFIG_SYSCLK_75
- Configure the kernel for clock speed of your Galileo board.
- The choices are 75MHz, 83.3MHz, and 100MHz.
-
-83.3
-CONFIG_SYSCLK_83
- Configure the Galileo kernel for a clock speed of 83.3 MHz.
-
-100
-CONFIG_SYSCLK_100
- Configure the Galileo kernel for a clock speed of 100 MHz.
-
Z85C30 Serial Support
CONFIG_ZS
Documentation on the Zilog 85C350 serial communications controller
@@ -2199,7 +2186,7 @@ CONFIG_NUMA
Access). This option is for configuring high-end multiprocessor
server machines. If in doubt, say N.
-R41xx
+CPU type
CONFIG_CPU_VR41XX
The options selects support for the NEC VR41xx series of processors.
Only choose this option if you have one of these processors as a
@@ -2211,7 +2198,7 @@ CONFIG_CPU_ADVANCED
Saying yes here allows you to select support for various features
your CPU may or may not have. Most people should say N here.
-ll and sc instructions available
+ll/sc Instructions available
CONFIG_CPU_HAS_LLSC
MIPS R4000 series and later provide the Load Linked (ll)
and Store Conditional (sc) instructions. More information is
@@ -2221,7 +2208,7 @@ CONFIG_CPU_HAS_LLSC
for better performance, N if you don't know. You must say Y here
for multiprocessor machines.
-lld and scd instructions available
+lld and scd instructions
CONFIG_CPU_HAS_LLDSCD
Say Y here if your CPU has the lld and scd instructions, the 64-bit
equivalents of ll and sc. Say Y here for better performance, N if
@@ -2354,7 +2341,7 @@ CONFIG_IP_NF_CONNTRACK
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
-IRC Send/Chat protocol support
+IRC Send/Chat support
CONFIG_IP_NF_IRC
There is a commonly-used extension to IRC called
Direct Client-to-Client Protocol (DCC). This enables users to send
@@ -2438,7 +2425,7 @@ CONFIG_IP_NF_MATCH_TTL
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
-LENGTH match support
+length match support
CONFIG_IP_NF_MATCH_LENGTH
This option allows you to match the length of a packet against a
specific value or range of values.
@@ -2982,11 +2969,6 @@ EV5 CPU(s) (model 5/xxx)
CONFIG_ALPHA_GAMMA
Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
-EV67 (or later) CPU (speed > 600MHz)?
-CONFIG_ALPHA_EV67
- Is this a machine based on the EV67 core? If in doubt, select N here
- and the machine will be treated as an EV6.
-
Use SRM as bootloader
CONFIG_ALPHA_SRM
There are two different types of booting firmware on Alphas: SRM,
@@ -3332,7 +3314,7 @@ CONFIG_PCI_NAMES
When in doubt, say Y.
-Generic PCI hotplug support
+PCI Hotplug support
CONFIG_HOTPLUG_PCI
Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is
@@ -3346,7 +3328,7 @@ CONFIG_HOTPLUG_PCI
When in doubt, say N.
-Compaq PCI Hotplug driver
+PCI Compaq Hotplug controller
CONFIG_HOTPLUG_PCI_COMPAQ
Say Y here if you have a motherboard with a Compaq PCI Hotplug
controller.
@@ -3663,6 +3645,7 @@ CONFIG_KCORE_ELF
don't understand what this means or are not a kernel hacker, just
leave it at its default value ELF.
+# Choice: kcore
Select a.out format for /proc/kcore
CONFIG_KCORE_AOUT
Not necessary unless you're using a very out-of-date binutils
@@ -3785,7 +3768,7 @@ CONFIG_ENVCTRL
The module will be called envctrl.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-# Choice: x86type
+# Choice: x86
Processor family
CONFIG_M386
This is the processor type of your CPU. This information is used for
@@ -4558,7 +4541,7 @@ CONFIG_FB_HIT
This is the frame buffer device driver for the Hitachi HD64461 LCD
frame buffer card.
-SIS acceleration
+SIS 630/540 display support
CONFIG_FB_SIS
This is the frame buffer device driver for the SiS 630 and 640 Super
Socket 7 UMA cards. Specs available at <http://www.sis.com.tw/>.
@@ -4781,7 +4764,7 @@ CONFIG_PARPORT_PC
If unsure, say Y.
-Parallel+serial PCI multi-IO card support
+Parallel+serial PCI card support
CONFIG_PARPORT_SERIAL
This adds support for multi-IO PCI cards that have parallel and
serial ports. You should say Y or M here. If you say M, the module
@@ -5206,7 +5189,6 @@ CONFIG_IPV6
It is safe to say N here for now.
-# 2.5 tree only
IPv6: routing messages via old netlink
CONFIG_IPV6_NETLINK
You can say Y here to receive routing messages from the IPv6 code
@@ -5967,34 +5949,6 @@ CONFIG_PACKET_MMAP
If unsure, say N.
-# 2.5 tree only
-Kernel/User network link driver
-CONFIG_NETLINK
- This driver allows for two-way communication between the kernel and
- user processes. It does so by creating a new socket family,
- PF_NETLINK. Over this socket, the kernel can send and receive
- datagrams carrying information. It is documented on many systems in
- netlink(7).
-
- So far, the kernel uses this feature to publish some network related
- information if you say Y to "Routing messages", below. You also need
- to say Y here if you want to use arpd, a daemon that helps keep the
- internal ARP cache (a mapping between IP addresses and hardware
- addresses on the local network) small. The ethertap device, which
- lets user space programs read and write raw Ethernet frames, also
- needs the network link driver.
-
- If unsure, say Y.
-
-# 2.5 tree only
-Routing messages
-CONFIG_RTNETLINK
- If you say Y here, user space programs can receive some network
- related routing information over the netlink. 'rtmon', supplied
- with the iproute2 package (<ftp://ftp.inr.ac.ru/>), can read and
- interpret this data. Information sent to the kernel over this link
- is ignored.
-
Netlink device emulation
CONFIG_NETLINK_DEV
This option will be removed soon. Any programs that want to use
@@ -6300,13 +6254,6 @@ CONFIG_ATM_IA_DEBUG
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
-Efficient Networks Speedstream 3010
-CONFIG_ATM_LANAI
- Supports ATM cards based on the Efficient Networks "Lanai"
- chipset such as the Speedstream 3010 and the ENI-25p. The
- Speedstream 3060 is currently not supported since we don't
- have the code to drive the on-board Alcatel DSL chipset (yet).
-
Linux telephony support
CONFIG_PHONE
Say Y here if you have a telephony card, which for example allows
@@ -6425,13 +6372,6 @@ CONFIG_ATM_FORE200E_DEBUG
the performances of the driver, and the size of your syslog files!
Keep the debugging level to 0 during normal operations.
-PPP over ATM
-CONFIG_PPPOATM
- Support PPP (Point to Point Protocol) encapsulated in ATM frames.
- This implementation does not yet comply with section 8 of RFC2364,
- which can lead to bad results idf the ATM peer loses state and
- changes its encapsulation unilaterally.
-
Fusion MPT device support
CONFIG_FUSION
LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
@@ -6818,7 +6758,7 @@ CONFIG_SCSI_AIC7XXX
intended to replace the previous aic7xxx driver maintained by Doug
Ledford since Doug is no longer maintaining that driver.
-Adaptec I2O RAID support
+Adaptec I2O RAID controllers
CONFIG_SCSI_DPT_I2O
This driver supports all of Adaptec's I2O based RAID controllers as
well as the DPT SmartRaid V cards. This is an Adaptec maintained
@@ -7171,7 +7111,7 @@ CONFIG_SCSI_NCR_D700
Unless you have an NCR manufactured machine, the chances are that
you do not have this SCSI card, so say N.
-HP LASI SCSI support for 53c700/710
+HP LASI SCSI support for 53c700
CONFIG_SCSI_LASI700
This is a driver for the lasi baseboard in some parisc machines
which is based on the 53c700 chip. Will also support LASI subsystems
@@ -7883,7 +7823,7 @@ CONFIG_SCSI_MEGARAID
say M here and read <file:Documentation/modules.txt>. The module
will be called megaraid.o.
-Intel/ICP (former GDT SCSI Disk Array) RAID Controller support
+Intel/ICP (former GDT SCSI Disk Array) RAID Controller Support
CONFIG_SCSI_GDTH
Formerly called GDT SCSI Disk Array Controller Support.
@@ -8173,7 +8113,7 @@ CONFIG_IEEE1394_PCILYNX_PORTS
# say M here and read <file:Documentation/modules.txt>. The module
# will be called aic5800.o.
#
-OHCI-1394 (Open Host Controller Interface) support
+OHCI-1394 support
CONFIG_IEEE1394_OHCI1394
Enable this driver if you have an IEEE 1394 controller based on the
OHCI-1394 specification. The current driver is only tested with OHCI
@@ -8735,19 +8675,6 @@ CONFIG_PCMCIA_PCNET
a module, say M here and read <file:Documentation/modules.txt>. If
unsure, say N.
-Asix AX88190 PCMCIA support
-CONFIG_PCMCIA_AXNET
- Say Y here if you intend to attach an Asix AX88190-based PCMCIA
- (PC-card) Fast Ethernet card to your computer. These cards are
- nearly NE2000 compatible but need a separate driver due to a few
- misfeatures.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want).
- The module will be called axnet_cs.o. If you want to compile it as
- a module, say M here and read <file:Documentation/modules.txt>. If
- unsure, say N.
-
New Media PCMCIA support
CONFIG_PCMCIA_NMCLAN
Say Y here if you intend to attach a New Media Ethernet or LiveWire
@@ -8803,7 +8730,7 @@ CONFIG_PCMCIA_IBMTR
The module will be called ibmtr_cs.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
-Xircom Tulip-like CardBus support (old driver)
+Xircom Tulip-like CardBus support
CONFIG_PCMCIA_XIRTULIP
This driver is for the Digital "Tulip" Ethernet CardBus adapters.
It should work with most DEC 21*4*-based chips/ethercards, as well
@@ -9074,7 +9001,7 @@ CONFIG_SYNCLINK_SYNCPPP
of the Cisco HDLC/PPP driver (syncppp.c).
The SyncLink WAN driver (in character devices) must also be enabled.
-FarSync T-Series X.21 (and V.35/V.24) cards
+FarSync T-Series support
CONFIG_FARSYNC
This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
from FarSite Communications Ltd.
@@ -9648,7 +9575,7 @@ CONFIG_SBNI
Say N if unsure.
-SBNI multiple-line feature support
+SBNI Adapters Multiline feature
CONFIG_SBNI_MULTILINE
Schedule traffic for some parallel lines, via SBNI12 adapters.
If you have two computers connected with two parallel lines it's
@@ -10962,13 +10889,6 @@ CONFIG_TULIP_MWI
If unsure, say N.
-Use PCI shared memory for NIC registers
-CONFIG_TULIP_MMIO
- Use PCI shared memory for the NIC registers, rather than going through
- the Tulip's PIO (programmed I/O ports). Faster, but could produce
- obscure bugs if your mainboard has memory controller timing issues.
- If in doubt, say N.
-
Digi Intl. RightSwitch SE-X support
CONFIG_DGRS
This is support for the Digi International RightSwitch series of
@@ -11056,17 +10976,6 @@ CONFIG_VIA_RHINE
a module, say M here and read <file:Documentation/modules.txt> as
well as <file:Documentation/networking/net-modules.txt>.
-VIA Rhine MMIO support (EXPERIMENTAL)
-CONFIG_VIA_RHINE_MMIO
- This instructs the driver to use PCI shared memory (MMIO) instead of
- programmed I/O ports (PIO). Enabling this gives an improvement in
- processing time in parts of the driver.
-
- It is not known if this works reliably on all "rhine" based cards,
- but it has been tested successfully on some DFE-530TX adapters.
-
- If unsure, say N.
-
Davicom DM910x/DM980x support
CONFIG_DM9102
This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
@@ -11968,7 +11877,7 @@ CONFIG_NFTL_RW
<linux-mtd@lists.infradead.org> if you want to help to make it more
reliable.
-Detect flash chips by Common Flash Interface (CFI) probe
+Common Flash Interface (CFI) support
CONFIG_MTD_CFI
The Common Flash Interface specification was developed by Intel,
AMD and other flash manufactures that provides a universal method
@@ -12025,7 +11934,7 @@ CONFIG_MTD_CFI_I4
If your flash chips are interleaved in fours - i.e. you have four
flash chips addressed by each bus cycle, then say 'Y'.
-# Choice: mtd_data_swap
+# Choice: mtd_swap_data
Flash cmd/query data swapping
CONFIG_MTD_CFI_NOSWAP
This option defines the way in which the CPU attempts to arrange
@@ -12165,7 +12074,7 @@ CONFIG_MTD_PNC2000
PNC-2000 is the name of Network Camera product from PHOTRON
Ltd. in Japan. It uses CFI-compliant flash.
-Flash chip mapping on RPXlite or CLLF PPC board
+Flash chip mapping on RPXlite PPC board
CONFIG_MTD_RPXLITE
The RPXLite PowerPC board has CFI-compliant chips mapped in
a strange sparse mapping. This 'mapping' driver supports that
@@ -12241,26 +12150,26 @@ CONFIG_MTD_CSTM_MIPS_IXX
allow a window into the flash. Both CFI and JEDEC probes are
called.
-Physical start location of flash chip mapping
+Physical start location of flash mapping
CONFIG_MTD_CSTM_MIPS_IXX_START
This is the physical memory location that the MTD driver will
use for the flash chips on your particular target board.
Refer to the memory map which should hopefully be in the
documentation for your board.
-Physical length of flash chip mapping
+Physical length of flash mapping
CONFIG_MTD_CSTM_MIPS_IXX_LEN
This is the total length that the MTD driver will use for the
flash chips on your particular board. Refer to the memory
map which should hopefully be in the documentation for your
board.
-Physical bus width of flash mapping in bytes
+Physical bus width of flash mapping
CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH
This is the total bus width of the mapping of the flash chips
on your particular board.
-JEDEC Flash device mapped on Mixcom piggyback card
+Flash chip mapping on Mixcom piggyback card
CONFIG_MTD_MIXMEM
This supports the paging arrangement for access to flash chips
on the MixCOM piggyback card, allowing the flash chip drivers
@@ -12269,14 +12178,14 @@ CONFIG_MTD_MIXMEM
you probably want to enable this mapping driver. More info is at
<http://www.itc.hu/>.
-JEDEC Flash device mapped on Octagon 5066 SBC
+Flash chip mapping on Octagon 5066 SBC
CONFIG_MTD_OCTAGON
This provides a 'mapping' driver which supports the way in which
the flash chips are connected in the Octagon-5066 Single Board
Computer. More information on the board is available at
<http://www.octagonsystems.com/Products/5066/5066.html>.
-JEDEC Flash device mapped on Tempustech VMAX SBC301
+Flash chip mapping on Tempustech VMAX SBC301
CONFIG_MTD_VMAX
This provides a 'mapping' driver which supports the way in which
the flash chips are connected in the Tempustech VMAX SBC301 Single
@@ -12447,7 +12356,7 @@ CONFIG_MTDRAM_ABS_POS
allocating space from Linux's available memory. Otherwise, leave
this set to zero. Most people will want to leave this as zero.
-CFI Flash device mapping on the Flaga Digital Module
+Flash chip mapping on the Flaga Digital Module
CONFIG_MTD_CFI_FLAGADM
Mapping for the Flaga digital module. If you don´t have one, ignore
this setting.
@@ -12467,7 +12376,7 @@ CONFIG_MTD_ABSENT
the system regardless of media presence. Device nodes created
with this driver will return -ENODEV upon access.
-MTD emulation using block device
+MTD Emulation using block device
CONFIG_MTD_BLKMTD
This driver allows a block device to appear as an MTD. It would
generally be used in the following cases:
@@ -12520,7 +12429,7 @@ CONFIG_MTD_SOLUTIONENGINE
This enables access to the flash chips on the Hitachi SolutionEngine and
similar boards. Say 'Y' if you are building a kernel for such a board.
-CFI Flash device mapped on TQM8XXL PPC board
+Flash chip mapping on TQM8xxL PPC board
CONFIG_MTD_TQM8XXL
The TQM8xxL PowerPC board has up to two banks of CFI-compliant
chips, currently uses AMD one. This 'mapping' driver supports
@@ -12596,7 +12505,7 @@ CONFIG_USB_LARGE_CONFIG
If you have an APC UPS, say Y; otherwise say N.
-USB long timeout for slow-responding devices (some MGE Ellipse UPSes)
+USB long timeout
CONFIG_USB_LONG_TIMEOUT
This option makes the standard time out a bit longer. Basically,
some devices are just slow to respond, so this makes usb more
@@ -12917,6 +12826,17 @@ CONFIG_USB_SERIAL_IR
The module will be called ir-usb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
+USB IR Dongle Serial Driver
+CONFIG_USB_SERIAL_IR
+ Say Y here if you want to enable simple serial support for USB IrDA
+ devices. This is useful if you do not want to use the full IrDA
+ stack.
+
+ This code is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called ir-usb.o. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt>.
+
USB Belkin and Paracom Single Port Serial Driver
CONFIG_USB_SERIAL_BELKIN
Say Y here if you want to use a Belkin USB Serial single port
@@ -13166,7 +13086,7 @@ CONFIG_USB_OV511
The module will be called ov511.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-USB Communication Class Ethernet device support
+USB Communication Class Ethernet driver
CONFIG_USB_CDCETHER
This driver supports devices conforming to the Communication Device
Class Ethernet Control Model. This is used in some cable modems.
@@ -13235,7 +13155,7 @@ CONFIG_USB_PEGASUS
The module will be called pegasus.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-USB KLSI KL5USB101-based Ethernet device support
+USB KLSI KL5USB101-based Ethernet device support '
CONFIG_USB_KAWETH
Say Y here if you want to use one of the following 10Mbps only
USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
@@ -13333,7 +13253,7 @@ CONFIG_USB_STORAGE_DEBUG
Say Y here in order to have the USB Mass Storage code generate
verbose debugging messages.
-ISD-200 USB/ATA Bridge support
+ISD-200 USB/ATA driver
CONFIG_USB_STORAGE_ISD200
Say Y here if you want to use USB Mass Store devices based
on the In-Systems Design ISD-200 USB/ATA bridge.
@@ -13453,7 +13373,7 @@ CONFIG_USB_STORAGE_DPCM
reader, details at <http://www.microtechint.com/zio/index.html>.
This driver treats the flash card as a removable storage device.
-SanDisk SDDR-09 (and other SmartMedia) support
+Sandisk SDDR-09 SmartMedia reader support
CONFIG_USB_STORAGE_SDDR09
Say Y here to include additional code to support the Sandisk SDDR-09
SmartMedia reader in the USB Mass Storage driver.
@@ -13736,7 +13656,7 @@ CONFIG_USB_MICROTEK
and work. SANE 1.0.4 or newer is needed to make use of your scanner.
This driver can be compiled as a module.
-HP53xx and Minolta Dual Scanner support
+HP 53xx and Minolta Dual Scanner support
CONFIG_USB_HPUSBSCSI
Say Y here if you want support for the HP 53xx series of scanners
and the Minolta Scan Dual. This driver is experimental.
@@ -13775,7 +13695,7 @@ CONFIG_MINIX_FS
Reiserfs support
CONFIG_REISERFS_FS
Stores not just filenames but the files themselves in a balanced
- tree. Uses journalling.
+ tree. Uses journaling.
Balanced trees are more efficient than traditional file system
architectural foundations.
@@ -13864,13 +13784,13 @@ CONFIG_EXT2_FS
be compiled as a module, and so this could be dangerous. Most
everyone wants to say Y here.
-Ext3 journalling file system support (EXPERIMENTAL)
+Ext3 journaling file system support (EXPERIMENTAL)
CONFIG_EXT3_FS
- This is the journalling version of the Second extended file system
- (often called ext2), the de facto standard Linux file system
+ This is the journaling version of the Second extended file system
+ (often called ext3), the de facto standard Linux file system
(method to organize files on a storage device) for hard disks.
- The journalling code included in this driver means you do not have
+ The journaling code included in this driver means you do not have
to run e2fsck (file system checker) on your file systems after a
crash. The journal keeps track of any changes that were being made
at the time the system crashed, and can ensure that your file system
@@ -13898,7 +13818,7 @@ CONFIG_EXT3_FS
Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
CONFIG_JBD
- This is a generic journalling layer for block devices. It is
+ This is a generic journaling layer for block devices. It is
currently used by the ext3 file system, but it could also be used to
add journal support to other file systems or block devices such as
RAID or LVM.
@@ -13984,14 +13904,9 @@ CONFIG_CMS_FS
mainframe systems. Only the basic format is supported so far. If
you don't know what CMS is you probably don't want to know any more.
-# When the 2.5 version of configure.help goes away, the part of this that
-# duplicates Documentation/filesystems/tmpfs.txt can drop out.
Virtual memory file system support
CONFIG_TMPFS
Tmpfs is a file system which keeps all files in virtual memory.
- Everything in tmpfs is temporary in the sense that no files will be
- created on your hard drive. If you reboot, everything in tmpfs will
- be lost.
In contrast to RAM disks, which get allocated a fixed amount of
physical RAM, tmpfs grows and shrinks to accommodate the files it
@@ -14018,8 +13933,6 @@ CONFIG_TMPFS
The initial permissions of the root directory can be set with the
mount option "mode".
- See <file:Documentation/filesystems/tmpfs.txt> for details.
-
Simple RAM-based file system support
CONFIG_RAMFS
Ramfs is a file system which keeps all files in RAM. It allows
@@ -14602,7 +14515,7 @@ CONFIG_EFS_FS
Journalling Flash File System (JFFS) support
CONFIG_JFFS_FS
- JFFS is the Journalling Flash File System developed by Axis
+ JFFS is the Journaling Flash File System developed by Axis
Communications in Sweden, aimed at providing a crash/powerdown-safe
file system for disk-less embedded devices. Further information is
available at (<http://developer.axis.com/software/jffs/>).
@@ -14724,7 +14637,7 @@ CONFIG_MAC_PARTITION
Say Y here if you would like to use hard disks under Linux which
were partitioned on a Macintosh.
-Windows Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL)
+Windows' Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL)
CONFIG_LDM_PARTITION
Say Y here if you would like to use hard disks under Linux which
were partitioned using Windows 2000's or XP's Logical Disk Manager.
@@ -14744,7 +14657,7 @@ CONFIG_LDM_PARTITION
If unsure, say N.
-Windows LDM extra logging
+Windows' LDM extra logging
CONFIG_LDM_DEBUG
Say Y here if you would like LDM to log verbosely. This could be
helpful if the driver doesn't work as expected and you'd like to
@@ -14976,7 +14889,7 @@ CONFIG_CODA_FS
whenever you want), say M here and read
<file:Documentation/modules.txt>. The module will be called coda.o.
-InterMezzo file system support (replicating fs)
+InterMezzo file system support (experimental, replicating fs)
CONFIG_INTERMEZZO_FS
InterMezzo is a networked file system with disconnected operation
and kernel level write back caching. It is most often used for
@@ -15556,7 +15469,6 @@ CONFIG_SCC_ENET
Enable Ethernet support via the Motorola MPC8xx serial
commmunications controller.
-# Choice: scc_ethernet
Ethernet on SCC1
CONFIG_SCC1_ENET
Use MPC8xx serial communications controller 1 to drive Ethernet
@@ -16333,7 +16245,7 @@ CONFIG_I2C_CHARDEV
<file:Documentation/modules.txt>.
The module will be called i2c-dev.o.
-I2C /proc interface (required for hardware sensors)
+I2C /proc support
CONFIG_I2C_PROC
This provides support for i2c device entries in the /proc filesystem.
The entries will be found in /proc/sys/dev/sensors.
@@ -17462,24 +17374,23 @@ CONFIG_TOSHIBA
Say Y if you intend to run this kernel on a Toshiba portable.
Say N otherwise.
-Dell laptop support
+Dell Inspiron 8000 support
CONFIG_I8K
This adds a driver to safely access the System Management Mode
- of the CPU on the Dell Inspiron and Latitude laptops. The System
- Management Mode is used to read cpu temperature, cooling fan
- status and Fn-keys status on Dell laptops. It can also be used
- to switch the fans on and off.
+ of the CPU on the Dell Inspiron 8000. The System Management Mode
+ is used to read cpu temperature and cooling fan status and to
+ control the fans on the I8K portables.
- The driver has been developed and tested on an Inspiron 8000
- but it should work on any Dell Inspiron or Latitude laptop.
- You can force loading on unsupported models by passing the
- parameter `force=1' to the module. Use at your own risk.
+ This driver has been tested only on the Inspiron 8000 but it may
+ also work with other Dell laptops. You can force loading on other
+ models by passing the parameter `force=1' to the module. Use at
+ your own risk.
- For more information on this driver and for utilities that make
- use of the module see the I8K Linux Utilities web site at:
- <http://www.debian.org/~dz/i8k/>.
+ For information on utilities to make use of this driver see the
+ I8K Linux utilities web site at:
+ <http://www.debian.org/~dz/i8k/>
- Say Y if you intend to run this kernel on a Dell laptop.
+ Say Y if you intend to run this kernel on a Dell Inspiron 8000.
Say N otherwise.
/dev/cpu/microcode - Intel IA32 CPU microcode support
@@ -18604,7 +18515,7 @@ CONFIG_SOUND_EMU10K1
Userspace tools to create new patches and load/unload them can be
found at <http://opensource.creative.com/dist.html>.
-Creative SBLive! (EMU10K1) MIDI
+Creative EMU10K1 MIDI
CONFIG_MIDI_EMU10K1
Say Y if you want to be able to use the OSS /dev/sequencer
interface. This code is still experimental.
@@ -18857,21 +18768,20 @@ CONFIG_NINO
website at <http://www.realitydiluted.com/projects/nino/index.html>
will have more information.
-# Choice: nino_model
-CONFIG_NINO_4MB
- Say Y here to build a kernel specifically for Nino Palm PCs with
- 4MB of memory. These include models 300/301/302/319.
+Model-500/510
+CONFIG_NINO_16MB
+ Say Y here to build a kernel specifically for Nino 500/501 color
+ Palm PCs from Philips (INCOMPLETE).
Model-200/210/312/320/325/350/390
CONFIG_NINO_8MB
Say Y here to build a kernel specifically for Nino Palm PCs with
8MB of memory. These include models 200/210/312/320/325/350/390.
-Model-500/510
-CONFIG_NINO_16MB
- Say Y here to build a kernel specifically for Nino 500/501 color
- Palm PCs from Philips (INCOMPLETE).
Model-300/301/302/319
+CONFIG_NINO_4MB
+ Say Y here to build a kernel specifically for Nino Palm PCs with
+ 4MB of memory. These include models 300/301/302/319.
Low-level debugging
CONFIG_LL_DEBUG
@@ -18895,26 +18805,6 @@ CONFIG_MIPS_UNCACHED
hardware debugging with a logic analyzer and need to see all traffic
on the bus.
-AU1000 serial console
-CONFIG_AU1000_SERIAL_CONSOLE
- If you have an Alchemy AU1000 processor (MIPS based) and you want
- to use a console on a serial port, say Y. Otherwise, say N.
-
-AU1000 serial support
-CONFIG_AU1000_UART
- If you have an Alchemy AU1000 processor (MIPS based) and you want
- to use serial ports, say Y. Otherwise, say N.
-
-AU1000 ethernet controller on SGI MIPS system
-CONFIG_MIPS_AU1000_ENET
- If you have an Alchemy Semi AU1000 ethernet controller
- on an SGI MIPS system, say Y. Otherwise, say N.
-
-WD93 SCSI Controller on SGI MIPS system
-CONFIG_SGIWD93_SCSI
- If you have a Western Digital WD93 SCSI controller on
- an SGI MIPS system, say Y. Otherwise, say N.
-
Magic System Request Key support
CONFIG_MAGIC_SYSRQ
If you say Y here, you will have some control over the system even
@@ -19337,7 +19227,7 @@ CONFIG_HISAX_SEDLBAUER_CS
This enables the PCMCIA client driver for the Sedlbauer Speed Star
and Speed Star II cards.
-ST5481 USB ISDN modem
+ST5481 USB ISDN adapter
CONFIG_HISAX_ST5481
This enables the driver for ST5481 based USB ISDN adapters,
e.g. the BeWan Gazel 128 USB
@@ -19851,12 +19741,6 @@ CONFIG_Q40
Q60. Select your CPU below. For 68LC060 don't forget to enable FPU
emulation.
-Q40/Q60 IDE interface support
-CONFIG_BLK_DEV_Q40IDE
- Enable the on-board IDE controller in the Q40/Q60. This should
- normally be on; disable it only if you are running a custom hard
- drive subsystem through an expansion card.
-
Sun 3 support
CONFIG_SUN3
This option enables support for the Sun 3 series of workstations.
@@ -20465,7 +20349,7 @@ CONFIG_8260
If in doubt, say N.
-# Choice: ppc4xxtype
+# Choice: Machine type
Oak
CONFIG_OAK
Select Oak if you have an IBM 403GCX "Oak" Evaluation Board.
@@ -20510,14 +20394,13 @@ CONFIG_8xx_CPU6
If in doubt, say N here.
-MPC8xx direct IDE support on PCMCIA port
+MPC8xx IDE support
CONFIG_BLK_DEV_MPC8xx_IDE
This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details.
If unsure, say N.
-# Choice: mpc8xxtype
Type of MPC8xx IDE interface
CONFIG_IDE_8xx_PCCARD
Select how the IDE devices are connected to the MPC8xx system:
@@ -20592,7 +20475,7 @@ CONFIG_APUS
More information is available at:
<http://linux-apus.sourceforge.net/>.
-AltiVec kernel support
+AltiVec Kernel Support
CONFIG_ALTIVEC
This option enables kernel support for the Altivec extensions to the
PowerPC processor. The kernel currently supports saving and restoring
@@ -20948,7 +20831,7 @@ CONFIG_MAC_ADBKEYCODES
If unsure, say Y here.
I2C/SPI Microcode Patch
-CONFIG_UCODE_PATCH
+UCODE_PATCH
Motorola releases microcode updates for their 8xx CPM modules. The
microcode update file has updates for IIC, SMC and USB. Currently only
the USB update is available by default, if the MPC8xx USB option is
@@ -21337,7 +21220,7 @@ CONFIG_RADIO_MAESTRO
Guillemot MAXI Radio FM 2000 Radio Card
CONFIG_RADIO_MAXIRADIO
Choose Y here if you have this radio card. This card may also be
- found as GemTek PCI FM.
+ found as Gemtek PCI FM.
In order to control your radio card, you will need to use programs
that are compatible with the Video For Linux API. Information on
@@ -21368,10 +21251,10 @@ GemTek I/O port
CONFIG_RADIO_GEMTEK_PORT
Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
0x34c, if you haven't changed the jumper setting on the card. On
- Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM GemTek), the I/O
+ Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
port is 0x28c.
-GemTek PCI Radio Card support
+Gemtek PCI Radio
CONFIG_RADIO_GEMTEK_PCI
Choose Y here if you have this PCI FM radio card.
@@ -21449,7 +21332,7 @@ CONFIG_VIDEO_BT848
whenever you want). If you want to compile it as a module, say M
here and read <file:Documentation/modules.txt>.
-BT878 audio DMA
+BT878 Audio DMA
CONFIG_SOUND_BT878
Audio DMA support for bt878 based grabber boards. As you might have
already noticed, bt878 is listed with two functions in /proc/pci.
@@ -21528,7 +21411,7 @@ CONFIG_VIDEO_CQCAM
as a module (c-qcam.o).
Read <file:Documentation/video4linux/CQcam.txt> for more information.
-W9966 Webcam (FlyCam Supra and others) Video For Linux
+Winbond W9966CF Webcam Video For Linux
CONFIG_VIDEO_W9966
Video4linux driver for Winbond's w9966 based Webcams.
Currently tested with the LifeView FlyCam Supra.
@@ -21536,8 +21419,8 @@ CONFIG_VIDEO_W9966
otherwise say N.
This driver is also available as a module (w9966.o).
- Check out <file:drivers/media/video4linux/w9966.txt> and
- <file:drivers/media/video/w9966.c> for more information.
+ Check out <file:Documentation/video4linux/w9966.txt> for more
+ information.
CPiA Video For Linux
CONFIG_VIDEO_CPIA
@@ -21576,7 +21459,7 @@ CONFIG_VIDEO_PMS
it as a module, say M here and read
<file:Documentation/modules.txt>.
-Sony Vaio Picturebook Motion Eye Video For Linux
+Sony Vaio Picturebook Motion Eye Video for Linux
CONFIG_VIDEO_MEYE
This is the video4linux driver for the Motion Eye camera found
in the Vaio Picturebook laptops. Please read the material in
@@ -21639,16 +21522,16 @@ CONFIG_S390_PARTITION
attached to another IBM mainframe operation system (OS/390,
VM/ESA, VSE/ESA).
-Support for ECKD hard disks
+ECKD devices
CONFIG_DASD_ECKD
- ECKD devices are the most commonly used devices. You should enable
- this option unless you are very sure you have no ECKD device.
+ ECKD devices are the most commonly used devices. you should enable
+ this option unless you are very sure to have no ECKD device.
CKD devices
CONFIG_DASD_CKD
CKD devices are currently unsupported.
-Support for FBA hard disks
+FBA devices
CONFIG_DASD_FBA
FBA devices are currently unsupported.
@@ -22011,38 +21894,6 @@ CONFIG_SA1100_VICTOR
<http://www.visuaide.com/pagevictor.en.html> for information on
this system.
-# Choice: cerf_ram
-Cerf on-board RAM size
-CONFIG_SA1100_CERF_8MB
- Declare the size of the CerfBoard's on-board RAM.
- Alternatives are 8, 16, 32, and 64MB.
-
-16MB
-CONFIG_SA1100_CERF_16MB
- Declare that the CerfBoard has 16MB RAM.
-
-32MB
-CONFIG_SA1100_CERF_32MB
- Declare that the CerfBoard has 32MB RAM.
-
-64MB
-CONFIG_SA1100_CERF_64MB
- Declare that the CerfBoard has 64MB RAM.
-
-# Choice: cerf_flash
-Cerf flash memory size
-CONFIG_SA1100_CERF_FLASH_8MB
- Tell the Cerf kernel the size of on-board memory. The choices
- are 8MB, 16MB, or 32MB.
-
-16MB
-CONFIG_SA1100_CERF_FLASH_16MB
- Configure the Cerf kernel to expect 16MB of flash memory.
-
-32MB
-CONFIG_SA1100_CERF_FLASH_32MB
- Configure the Cerf kernel to expect 32MB of flash memory.
-
Support ARM610 processor
CONFIG_CPU_ARM610
The ARM610 is the successor to the ARM3 processor
@@ -22541,7 +22392,7 @@ CONFIG_NSC_FIR
<file:Documentation/modules.txt>. The module will be called
nsc-ircc.o.
-National Semiconductor DP83820 support
+National Semiconductor DP83820 series driver
CONFIG_NS83820
This is a driver for the National Semiconductor DP83820 series
of gigabit ethernet MACs. Cards using this chipset include
@@ -22565,7 +22416,7 @@ CONFIG_SMC_IRCC_FIR
here and read <file:Documentation/modules.txt>. The module will be
called smc-ircc.o.
-ALi M5123 FIR controller driver
+ALi M5123 FIR Controller Driver
CONFIG_ALI_FIR
Say Y here if you want to build support for the ALi M5123 FIR
Controller. The ALi M5123 FIR Controller is embedded in ALi M1543C,
@@ -22576,7 +22427,7 @@ CONFIG_ALI_FIR
<file:Documentation/modules.txt>. The module will be called
ali-ircc.o.
-VLSI 82C147 PCI-IrDA SIR/MIR/FIR Controller driver
+VLSI 82C147 PCI-IrDA Controller Driver
CONFIG_VLSI_FIR
Say Y here if you want to build support for the VLSI 82C147
PCI-IrDA Controller. This controller is used by the HP OmniBook 800
@@ -22787,7 +22638,6 @@ ETRAX Flash Memory configuration
CONFIG_ETRAX_FLASH_BUSWIDTH
Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
-# Choice: crisleds
LED configuration on PA
CONFIG_ETRAX_PA_LEDS
The Etrax network driver is responsible for flashing LED's when
@@ -23272,7 +23122,6 @@ Etrax100 I2C EEPROM (NVRAM) size/8kB
CONFIG_ETRAX_I2C_EEPROM_8KB
Use a 8kB EEPROM.
-# Choice: etrax_eeprom
Etrax100 I2C EEPROM (NVRAM) size/probe
CONFIG_ETRAX_I2C_EEPROM_PROBE
Specifies size or auto probe of the EEPROM size.
@@ -23320,7 +23169,7 @@ Etrax 100 IDE Reset
CONFIG_ETRAX_IDE_CSPE1_16_RESET
Configures the pin used to reset the IDE bus.
-Delay for drives to regain consciousness
+Etrax 100 ATA/IDE support
CONFIG_ETRAX_IDE_DELAY
Sets the time to wait for disks to regain consciousness after reset.
@@ -23328,7 +23177,6 @@ Etrax 100 IDE Reset
CONFIG_ETRAX_IDE_G27_RESET
Configures the pin used to reset the IDE bus.
-# Choice: ide_reset
IDE reset on PB Bit 7
CONFIG_ETRAX_IDE_PB7_RESET
Configures the pin used to reset the IDE bus.
@@ -23655,42 +23503,6 @@ CONFIG_EFI_VARS
To use this option, you have to check that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
-Physical memory granularity (16 MB)
-CONFIG_IA64_GRANULE_16MB
- IA64 identity-mapped regions use a large page size. We'll call such
- large pages "granules". If you can think of a better name that's
- unambiguous, let us know... Unless your identity-mapped regions are
- very large, select a granule size of 16MB.
-
-Physical memory granularity (64 MB)
-CONFIG_IA64_GRANULE_64MB
- IA64 identity-mapped regions use a large page size. We'll call such
- large pages "granules". If you can think of a better name that's
- unambiguous, let us know... Unless your identity-mapped regions are
- very large, select a granule size of 16MB. (This is the "large" choice.)
-
-Enable SGI SN extra debugging code
-CONFIG_IA64_SGI_SN_DEBUG
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform
- for IA64. Unless you are debugging problems on an SGI SN IA64 box,
- say N.
-
-Enable SGI Medusa Simulator Support
-CONFIG_IA64_SGI_SN_SIM
- If you are compiling a kernel that will run under SGI's IA64
- simulator (Medusa) then say Y, otherwise say N.
-
-PCIBA Support
-CONFIG_PCIBA
- IRIX PCIBA-inspired user mode PCI interface for the SGI SN (Scalable
- NUMA) platform for IA64. Unless you are compiling a kernel for an SGI SN IA64 box, say N.
-
-Enable protocol mode for the L1 console
-SERIAL_SGI_L1_PROTOCOL
- Uses protocol mode instead of raw mode for the level 1 console on the
- SGI SN (Scalable NUMA) platform for IA64. If you are compiling for
- an SGI SN box then Y is the recommended value, otherwise say N.
-
Directly Connected Compact Flash support
CONFIG_CF_ENABLER
Compact Flash is a small, removable mass storage device introduced
@@ -23716,7 +23528,7 @@ CONFIG_DEBUG_SLAB
allocation as well as poisoning memory on free to catch use of freed
memory.
-Memory mapped I/O debugging
+Memory mapped I/O debug support
CONFIG_DEBUG_IOVIRT
Say Y here to get warned whenever an attempt is made to do I/O on
obviously invalid addresses such as those generated when ioremap()
@@ -23732,19 +23544,6 @@ CONFIG_DEBUG_SPINLOCK
best used in conjunction with the NMI watchdog so that spinlock
deadlocks are also debuggable.
-Read-write spinlock debugging
-CONFIG_DEBUG_RWLOCK
- If you say Y here then read-write lock processing will count how many
- times it has tried to get the lock and issue an error message after
- too many attempts. If you suspect a rwlock problem or a kernel
- hacker asks for this option then say Y. Otherwise say N.
-
-Semaphore debugging
-CONFIG_DEBUG_SEMAPHORE
- If you say Y here then semaphore processing will issue lots of
- verbose debugging messages. If you suspect a semaphore problem or a
- kernel hacker asks for this option then say Y. Otherwise say N.
-
Verbose BUG() reporting (adds 70K)
CONFIG_DEBUG_BUGVERBOSE
Say Y here to make BUG() panics output the file name and line number
@@ -24160,10 +23959,10 @@ CONFIG_GDB_CONSOLE
# LocalWords: filesystems smbfs ATA ppp PCTech RZ www powerquest txt CMD ESDI
# LocalWords: chipset FB multicast MROUTE appletalk ifconfig IBMTR multiport
# LocalWords: Multisession STALDRV EasyIO EC EasyConnection ISTALLION ONboard
-# LocalWords: Brumby pci TNC cis ohio faq usenet NETLINK dev hydra ca Tyne mem
+# LocalWords: Brumby pci TNC cis ohio faq usenet dev hydra ca Tyne mem
# LocalWords: carleton DECstation SUNFD JENSEN Noname XXXM SLiRP LILO's amifb
# LocalWords: pppd Zilog ZS SRM bootloader ez mainmenu rarp ipfwadm paride pcd
-# LocalWords: RTNETLINK mknod xos MTU lwared Macs netatalk macs cs Wolff
+# LocalWords: mknod xos MTU lwared Macs netatalk macs cs Wolff
# LocalWords: dartmouth flowerpt MultiMaster FlashPoint tudelft etherexpress
# LocalWords: ICL EtherTeam ETH IDESCSI TXC SmartRAID SmartCache httpd sjc dlp
# LocalWords: thesphere TwoServers BOOTP DHCP ncpfs BPQETHER BPQ MG HIPPI cern
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 168a1b2f6..9c9db8684 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -108,7 +108,9 @@ APISOURCES := $(TOPDIR)/drivers/media/video/videodev.c \
$(TOPDIR)/drivers/video/modedb.c \
$(TOPDIR)/fs/devfs/base.c \
$(TOPDIR)/fs/locks.c \
+ $(TOPDIR)/fs/bio.c \
$(TOPDIR)/include/asm-i386/bitops.h \
+ $(TOPDIR)/include/linux/usb.h \
$(TOPDIR)/kernel/pm.c \
$(TOPDIR)/kernel/ksyms.c \
$(TOPDIR)/kernel/kmod.c \
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 40bb76f62..a3de95e34 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -204,8 +204,83 @@
</chapter>
<chapter id="usb">
- <title>USB Devices</title>
+ <title>USB Devices</title>
+
+ <para>Drivers for USB devices talk to the "usbcore" APIs, and are
+ exposed through driver frameworks such as block, character,
+ or network devices.
+ There are two types of public "usbcore" APIs: those intended for
+ general driver use, and those which are only public to drivers that
+ are part of the core.
+ The drivers that are part of the core are involved in managing a USB bus.
+ They include the "hub" driver, which manages trees of USB devices, and
+ several different kinds of "host controller" driver (HCD), which control
+ individual busses.
+ </para>
+
+ <para>The device model seen by USB drivers is relatively complex.
+ </para>
+
+ <itemizedlist>
+
+ <listitem><para>USB supports four kinds of data transfer
+ (control, bulk, interrupt, and isochronous). Two transfer
+ types use bandwidth as it's available (control and bulk),
+ while the other two types of transfer (interrupt and isochronous)
+ are scheduled to provide guaranteed bandwidth.
+ </para></listitem>
+
+ <listitem><para>The device description model includes one or more
+ "configurations" per device, only one of which is active at a time.
+ </para></listitem>
+
+ <listitem><para>Configurations have one or more "interface", each
+ of which may have "alternate settings". Interfaces may be
+ standardized by USB "Class" specifications, or may be specific to
+ a vendor or device.</para>
+
+ <para>USB device drivers actually bind to interfaces, not devices.
+ Think of them as "interface drivers", though you
+ may not see many devices where the distinction is important.
+ Most USB devices are simple, with only one configuration,
+ one interface, and one alternate setting.
+ </para></listitem>
+
+ <listitem><para>Interfaces have one or more "endpoints", each of
+ which supports one type and direction of data transfer such as
+ "bulk out" or "interrupt in". The entire configuration may have
+ up to sixteen endpoints in each direction, allocated as needed
+ among all the interfaces.
+ </para></listitem>
+
+ <listitem><para>Data transfer on USB is packetized; each endpoint
+ has a maximum packet size.
+ Drivers must often be aware of conventions such as flagging the end
+ of bulk transfers using "short" (including zero length) packets.
+ </para></listitem>
+
+ <listitem><para>The Linux USB API supports synchronous calls for
+ control and bulk messaging.
+ It also supports asynchnous calls for all kinds of data transfer,
+ using request structures called "URBs" (USB Request Blocks).
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>Accordingly, the USB Core API exposed to device drivers
+ covers quite a lot of territory. You'll probably need to consult
+ the USB 2.0 specification, available online from www.usb.org at
+ no cost, as well as class or device specifications.
+ </para>
+
+ <sect1><title>Data Types and Macros</title>
+!Iinclude/linux/usb.h
+ </sect1>
+
+ <sect1><title>USB Core APIs</title>
!Edrivers/usb/usb.c
+ </sect1>
+
</chapter>
<chapter id="uart16x50">
diff --git a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog
index 29198d7cc..0a8efe9bd 100644
--- a/Documentation/filesystems/devfs/ChangeLog
+++ b/Documentation/filesystems/devfs/ChangeLog
@@ -1794,28 +1794,3 @@ Changes for patch v198
- Use "existing" directory in <_devfs_make_parent_for_leaf>
- Use slab cache rather than fixed buffer for devfsd events
-===============================================================================
-Changes for patch v199
-
-- Removed obsolete usage of DEVFS_FL_NO_PERSISTENCE
-
-- Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>
-
-- Fixed locking bug in <devfs_d_revalidate_wait> due to typo
-
-- Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from devfsd
- or children
-===============================================================================
-Changes for patch v199.1
-
-- Fixed bug in <devfsd_read>: was dereferencing freed pointer
-===============================================================================
-Changes for patch v199.2
-
-- Fixed bug in <devfsd_close>: was dereferencing freed pointer
-
-- Added process group check for devfsd privileges
-===============================================================================
-Changes for patch v199.3
-
-- Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index a89dce8cc..8eed59f17 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -1,14 +1,9 @@
-Revised: 2000-Dec-05.
+Revised: 2001-Dec-06.
This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from the host controller drivers
and from usbcore.
-NOTE:
-The USB_ST_* codes are deprecated and are only listed for compatibility;
-new software should use only -E* instead!
-
-
**************************************************************************
* Error codes returned by usb_submit_urb *
@@ -16,7 +11,6 @@ new software should use only -E* instead!
Non-USB-specific:
-USB_ST_NOERROR
0 URB submission went fine
-ENOMEM no memory for allocation of internal structures
@@ -25,12 +19,10 @@ USB-specific:
-ENODEV specified USB-device or bus doesn't exist
-USB_ST_REQUEST_ERROR
-ENXIO a control or interrupt URB is already queued to this endpoint; or
a bulk URB is already queued to this endpoint and
USB_QUEUE_BULK wasn't used (UHCI HCDs only)
-USB_ST_URB_INVALID_ERROR
-EINVAL a) Invalid transfer type specified (or not supported)
b) Invalid interrupt interval (0<=n<256)
c) more than one interrupt packet requested
@@ -42,12 +34,10 @@ USB_ST_URB_INVALID_ERROR
-EFBIG too much ISO frames requested (currently uhci>900)
-USB_ST_STALL
-EPIPE specified pipe-handle is already stalled
-EMSGSIZE endpoint message size is zero, do interface/alternate setting
-USB_ST_BANDWIDTH_ERROR
-ENOSPC The host controller's bandwidth is already consumed and
this request would push it past its allowed limit.
@@ -60,60 +50,43 @@ USB_ST_BANDWIDTH_ERROR
* or in iso_frame_desc[n].status (for ISO) *
**************************************************************************
-USB_ST_NOERROR
0 Transfer completed successfully
-USB_ST_URB_KILLED
-ENOENT URB was canceled by usb_unlink_urb
-USB_ST_URB_PENDING
-EINPROGRESS URB still pending, no results yet
(actually no error until now;-)
-USB_ST_BITSTUFF
-USB_ST_INTERNALERROR
-EPROTO a) bitstuff error
b) unknown USB error
-USB_ST_CRC
-EILSEQ CRC mismatch
-USB_ST_STALL
-EPIPE endpoint stalled
-USB_ST_BUFFEROVERRUN
-ECOMM During an IN transfer, the host controller
received data from an endpoint faster than it
could be written to system memory
-USB_ST_BUFFERUNDERRUN
-ENOSR During an OUT transfer, the host controller
could not retrieve data from system memory fast
enough to keep up with the USB data rate
-USB_ST_DATAOVERRUN
-EOVERFLOW The amount of data returned by the endpoint was
greater than either the max packet size of the
endpoint or the remaining buffer size. "Babble".
-USB_ST_DATAUNDERRUN
-EREMOTEIO The endpoint returned less than max packet size
and that amount did not fill the specified buffer
-USB_ST_NORESPONSE
-USB_ST_TIMEOUT
-ETIMEDOUT transfer timed out, NAK
-USB_ST_REMOVED
-ENODEV device was removed
-USB_ST_SHORT_PACKET
-EREMOTEIO short packet detected
-USB_ST_PARTIAL_ERROR
-EXDEV ISO transfer only partially completed
look at individual frame status for details
-USB_ST_URB_INVALID_ERROR
-EINVAL ISO madness, if this happens: Log off and go home
-ECONNRESET the URB is being unlinked asynchronously
diff --git a/Makefile b/Makefile
index 1e5d1cbe6..8fe142a3a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 5
-SUBLEVEL = 0
-EXTRAVERSION =
+SUBLEVEL = 1
+EXTRAVERSION =-pre8
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
@@ -257,8 +257,8 @@ Version: dummy
boot: vmlinux
@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
-vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
- $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
+vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
+ $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
--start-group \
$(CORE_FILES) \
$(DRIVERS) \
@@ -335,6 +335,9 @@ init/version.o: init/version.c include/linux/compile.h include/config/MARKER
init/main.o: init/main.c include/config/MARKER
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
+init/do_mounts.o: init/do_mounts.c include/config/MARKER
+ $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
+
fs lib mm ipc kernel drivers net: dummy
$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
diff --git a/README b/README
index 6b626329e..1d429957e 100644
--- a/README
+++ b/README
@@ -1,9 +1,12 @@
- Linux kernel release 2.4.xx
+ Linux kernel release 2.5.xx
-These are the release notes for Linux version 2.4. Read them carefully,
+These are the release notes for Linux version 2.5. Read them carefully,
as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong.
+NOTE! As with all odd-numbered releases, 2.5.x is a development kernel.
+For stable kernels, see the 2.4.x maintained by Marcelo Tosatti.
+
WHAT IS LINUX?
Linux is a Unix clone written from scratch by Linus Torvalds with
@@ -52,7 +55,7 @@ INSTALLING the kernel:
directory where you have permissions (eg. your home directory) and
unpack it:
- gzip -cd linux-2.4.XX.tar.gz | tar xvf -
+ gzip -cd linux-2.5.XX.tar.gz | tar xvf -
Replace "XX" with the version number of the latest kernel.
@@ -61,7 +64,7 @@ INSTALLING the kernel:
files. They should match the library, and not get messed up by
whatever the kernel-du-jour happens to be.
- - You can also upgrade between 2.4.xx releases by patching. Patches are
+ - You can also upgrade between 2.5.xx releases by patching. Patches are
distributed in the traditional gzip and the new bzip2 format. To
install by patching, get all the newer patch files, enter the
directory in which you unpacked the kernel source and execute:
@@ -96,7 +99,7 @@ INSTALLING the kernel:
SOFTWARE REQUIREMENTS
- Compiling and running the 2.4.xx kernels requires up-to-date
+ Compiling and running the 2.5.xx kernels requires up-to-date
versions of various software packages. Consult
./Documentation/Changes for the minimum version numbers required
and how to get updates for these packages. Beware that using
@@ -150,13 +153,12 @@ CONFIGURING the kernel:
COMPILING the kernel:
- - Make sure you have gcc-2.91.66 (egcs-1.1.2) available. gcc 2.95.2 may
+ - Make sure you have gcc 2.95.3 available. gcc 2.91.66 (egcs-1.1.2) may
also work but is not as safe, and *gcc 2.7.2.3 is no longer supported*.
Also remember to upgrade your binutils package (for as/ld/nm and company)
if necessary. For more information, refer to ./Documentation/Changes.
- Please note that you can still run a.out user programs with this
- kernel.
+ Please note that you can still run a.out user programs with this kernel.
- Do a "make bzImage" to create a compressed kernel image. If you want
to make a boot disk (without root filesystem or LILO), insert a floppy
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index d6043ed64..e2cc14540 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -109,6 +109,7 @@ EXPORT_SYMBOL(strchr);
EXPORT_SYMBOL(strrchr);
EXPORT_SYMBOL(memcmp);
EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memscan);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(__memsetw);
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index a84e68667..a83d387a4 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -514,64 +515,63 @@ free_irq(unsigned int irq, void *dev_id)
}
int
-get_irq_list(char *buf)
+show_interrupts(struct seq_file *p, void *v)
{
#ifdef CONFIG_SMP
int j;
#endif
int i;
struct irqaction * action;
- char *p = buf;
#ifdef CONFIG_SMP
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (i = 0; i < smp_num_cpus; i++)
- p += sprintf(p, "CPU%d ", i);
+ seq_printf(p, "CPU%d ", i);
#ifdef DO_BROADCAST_INTS
for (i = 0; i < smp_num_cpus; i++)
- p += sprintf(p, "TRY%d ", i);
+ seq_printf(p, "TRY%d ", i);
#endif
- *p++ = '\n';
+ seq_putc(p, '\n');
#endif
for (i = 0; i < NR_IRQS; i++) {
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
+ seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#ifdef DO_BROADCAST_INTS
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10lu ",
+ seq_printf(p, "%10lu ",
irq_attempt(cpu_logical_map(j), i));
#endif
#endif
- p += sprintf(p, " %14s", irq_desc[i].handler->typename);
- p += sprintf(p, " %c%s",
+ seq_printf(p, " %14s", irq_desc[i].handler->typename);
+ seq_printf(p, " %c%s",
(action->flags & SA_INTERRUPT)?'+':' ',
action->name);
for (action=action->next; action; action = action->next) {
- p += sprintf(p, ", %c%s",
+ seq_printf(p, ", %c%s",
(action->flags & SA_INTERRUPT)?'+':' ',
action->name);
}
- *p++ = '\n';
+ seq_putc(p, '\n');
}
#if CONFIG_SMP
- p += sprintf(p, "IPI: ");
+ seq_puts(p, "IPI: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10lu ",
+ seq_printf(p, "%10lu ",
cpu_data[cpu_logical_map(j)].ipi_count);
- p += sprintf(p, "\n");
+ seq_putc(p, '\n');
#endif
- p += sprintf(p, "ERR: %10lu\n", irq_err_count);
- return p - buf;
+ seq_printf(p, "ERR: %10lu\n", irq_err_count);
+ return 0;
}
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index e82fafb6a..e0ce969ea 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -40,6 +40,7 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/fiq.h>
#include <asm/io.h>
@@ -92,15 +93,12 @@ static struct fiq_handler default_owner = {
static struct fiq_handler *current_fiq = &default_owner;
-int get_fiq_list(char *buf)
+int show_fiq_list(struct seq_file *p, void *v)
{
- char *p = buf;
-
if (current_fiq != &default_owner)
- p += sprintf(p, "FIQ: %s\n",
- current_fiq->name);
+ seq_printf(p, "FIQ: %s\n", current_fiq->name);
- return p - buf;
+ return 0;
}
void set_fiq_handler(void *start, unsigned int length)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 168470eb4..60049c59d 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -28,6 +28,7 @@
#include <linux/random.h>
#include <linux/smp.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -95,29 +96,28 @@ void enable_irq(unsigned int irq)
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i;
struct irqaction * action;
- char *p = buf;
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i));
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
+ seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next) {
- p += sprintf(p, ", %s", action->name);
+ seq_printf(p, ", %s", action->name);
}
- *p++ = '\n';
+ seq_putc(p, '\n');
}
#ifdef CONFIG_ARCH_ACORN
- p += get_fiq_list(p);
+ show_fiq_list(p);
#endif
- p += sprintf(p, "Err: %10lu\n", irq_err_count);
- return p - buf;
+ seq_printf(p, "Err: %10lu\n", irq_err_count);
+ return 0;
}
/*
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index a66a11510..9dd53469b 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -223,27 +224,27 @@ static struct irqaction *irq_action[NR_IRQS] = {
NULL, NULL, NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction * action;
for (i = 0; i < NR_IRQS; i++) {
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %10u %c %s",
+ seq_printf(p, "%2d: %10u %c %s",
i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action = action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
/* called by the assembler IRQ entry functions defined in irq.h
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
index 909c0b870..f72d7e55b 100644
--- a/arch/i386/boot/bootsect.S
+++ b/arch/i386/boot/bootsect.S
@@ -236,7 +236,7 @@ die: jne die # %es must be at 64kB boundary
rp_read:
#ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge
bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the
- lcall bootsect_kludge # bootsector + bootsect_kludge offset
+ lcall *bootsect_kludge # bootsector + bootsect_kludge offset
#else
movw %es, %ax
subw $SYSSEG, %ax
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index f22509101..c73c7bb74 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -286,7 +286,6 @@ CONFIG_SD_EXTRA_DEVS=40
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
-CONFIG_SCSI_DEBUG_QUEUES=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
@@ -431,6 +430,7 @@ CONFIG_EEPRO100=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_NET_POCKET is not set
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 3a9299653..02a1a5d09 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -387,6 +387,7 @@ static int broken_psr;
static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
static struct apm_user * user_list;
+static spinlock_t user_list_lock = SPIN_LOCK_UNLOCKED;
static char driver_version[] = "1.15"; /* no spaces */
@@ -526,7 +527,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+ "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
"setc %%al\n\t"
"popl %%ebp\n\t"
"popl %%edi\n\t"
@@ -573,7 +574,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+ "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
"setc %%bl\n\t"
"popl %%ebp\n\t"
"popl %%edi\n\t"
@@ -1053,8 +1054,9 @@ static void queue_event(apm_event_t event, struct apm_user *sender)
{
struct apm_user * as;
+ spin_lock(&user_list_lock);
if (user_list == NULL)
- return;
+ goto out;
for (as = user_list; as != NULL; as = as->next) {
if ((as == sender) || (!as->reader))
continue;
@@ -1084,6 +1086,8 @@ static void queue_event(apm_event_t event, struct apm_user *sender)
}
}
wake_up_interruptible(&apm_waitqueue);
+out:
+ spin_unlock(&user_list_lock);
}
static void set_time(void)
@@ -1179,10 +1183,12 @@ static int suspend(void)
send_event(APM_NORMAL_RESUME);
sti();
queue_event(APM_NORMAL_RESUME, NULL);
+ spin_lock(&user_list_lock);
for (as = user_list; as != NULL; as = as->next) {
as->suspend_wait = 0;
as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO);
}
+ spin_unlock(&user_list_lock);
ignore_normal_resume = 1;
wake_up_interruptible(&apm_suspend_waitqueue);
return err;
@@ -1519,7 +1525,6 @@ static int do_release(struct inode * inode, struct file * filp)
if (check_apm_user(as, "release"))
return 0;
filp->private_data = NULL;
- lock_kernel();
if (as->standbys_pending > 0) {
standbys_pending -= as->standbys_pending;
if (standbys_pending <= 0)
@@ -1530,6 +1535,7 @@ static int do_release(struct inode * inode, struct file * filp)
if (suspends_pending <= 0)
(void) suspend();
}
+ spin_lock(&user_list_lock);
if (user_list == as)
user_list = as->next;
else {
@@ -1544,7 +1550,7 @@ static int do_release(struct inode * inode, struct file * filp)
else
as1->next = as->next;
}
- unlock_kernel();
+ spin_unlock(&user_list_lock);
kfree(as);
return 0;
}
@@ -1573,8 +1579,10 @@ static int do_open(struct inode * inode, struct file * filp)
as->suser = capable(CAP_SYS_ADMIN);
as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
+ spin_lock(&user_list_lock);
as->next = user_list;
user_list = as;
+ spin_unlock(&user_list_lock);
filp->private_data = as;
return 0;
}
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index a1b538a7a..c35058c2f 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -191,6 +191,7 @@ struct dmi_blacklist
* corruption problems
*/
+#if 0
static __init int disable_ide_dma(struct dmi_blacklist *d)
{
#ifdef CONFIG_BLK_DEV_IDE
@@ -203,6 +204,7 @@ static __init int disable_ide_dma(struct dmi_blacklist *d)
#endif
return 0;
}
+#endif
/*
* Reboot options and system auto-detection code provided by
@@ -523,6 +525,12 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
MATCH(DMI_BIOS_DATE, "05/11/00"), NO_MATCH
} },
+ { swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
+ MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ MATCH(DMI_BIOS_VERSION, "WME01Z1"),
+ MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH
+ } },
+
{ swab_apm_power_in_minutes, "Sony VAIO", { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
MATCH(DMI_BIOS_VERSION, "R0203D0"),
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index fa17d0044..75637e655 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -32,6 +32,7 @@
#include <linux/kernel_stat.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -131,58 +132,54 @@ atomic_t irq_mis_count;
* Generic, controller-independent functions:
*/
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
- char *p = buf;
- p += sprintf(p, " ");
+ seq_printf(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
+ seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
- p += sprintf(p, " %14s", irq_desc[i].handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, " %14s", irq_desc[i].handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
- p += sprintf(p, ", %s", action->name);
- *p++ = '\n';
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
}
- p += sprintf(p, "NMI: ");
+ seq_printf(p, "NMI: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
- nmi_count(cpu_logical_map(j)));
- p += sprintf(p, "\n");
+ seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j)));
+ seq_putc(p, '\n');
#if CONFIG_X86_LOCAL_APIC
- p += sprintf(p, "LOC: ");
+ seq_printf(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
- apic_timer_irqs[cpu_logical_map(j)]);
- p += sprintf(p, "\n");
+ seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]);
+ seq_putc(p, '\n');
#endif
- p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
#ifdef CONFIG_X86_IO_APIC
#ifdef APIC_MISMATCH_DEBUG
- p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
#endif
#endif
- return p - buf;
+ return 0;
}
-
/*
* Global interrupt locks for SMP. Allow interrupts to come in on any
* CPU, yet make cli/sti act globally to protect critical regions..
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index fc6248324..0a85edcc9 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -1788,7 +1788,6 @@ static int mtrr_close (struct inode *ino, struct file *file)
unsigned int *fcount = file->private_data;
if (fcount == NULL) return 0;
- lock_kernel();
max = get_num_var_ranges ();
for (i = 0; i < max; ++i)
{
@@ -1798,7 +1797,6 @@ static int mtrr_close (struct inode *ino, struct file *file)
--fcount[i];
}
}
- unlock_kernel();
kfree (fcount);
file->private_data = NULL;
return 0;
diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c
index 364bf52bb..bf3fad221 100644
--- a/arch/i386/kernel/pci-pc.c
+++ b/arch/i386/kernel/pci-pc.c
@@ -458,7 +458,7 @@ static unsigned long bios32_service(unsigned long service)
unsigned long flags;
__save_flags(flags); __cli();
- __asm__("lcall (%%edi); cld"
+ __asm__("lcall *(%%edi); cld"
: "=a" (return_code),
"=b" (address),
"=c" (length),
@@ -499,7 +499,7 @@ static int __devinit check_pcibios(void)
__save_flags(flags); __cli();
__asm__(
- "lcall (%%edi); cld\n\t"
+ "lcall *(%%edi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -544,7 +544,7 @@ static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short
unsigned short bx;
unsigned short ret;
- __asm__("lcall (%%edi); cld\n\t"
+ __asm__("lcall *(%%edi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -573,7 +573,7 @@ static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u
switch (len) {
case 1:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -585,7 +585,7 @@ static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u
"S" (&pci_indirect));
break;
case 2:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -597,7 +597,7 @@ static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u
"S" (&pci_indirect));
break;
case 4:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -628,7 +628,7 @@ static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len,
switch (len) {
case 1:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -640,7 +640,7 @@ static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len,
"S" (&pci_indirect));
break;
case 2:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -652,7 +652,7 @@ static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len,
"S" (&pci_indirect));
break;
case 4:
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -875,7 +875,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
__asm__("push %%es\n\t"
"push %%ds\n\t"
"pop %%es\n\t"
- "lcall (%%esi); cld\n\t"
+ "lcall *(%%esi); cld\n\t"
"pop %%es\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
@@ -908,7 +908,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
{
int ret;
- __asm__("lcall (%%esi); cld\n\t"
+ __asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -1114,17 +1114,26 @@ static void __devinit pci_fixup_piix4_acpi(struct pci_dev *d)
* But it does seem to fix some unspecified problem
* with 'movntq' copies on Athlons.
*
- * VIA 8363 chipset:
- * - bit 7 at offset 0x55: Debug (RW)
+ * VIA 8363,8622,8361 Northbridges:
+ * - bits 5, 6, 7 at offset 0x55 need to be turned off
+ * VIA 8367 (KT266x) Northbridges:
+ * - bits 5, 6, 7 at offset 0x95 need to be turned off
*/
static void __init pci_fixup_via_athlon_bug(struct pci_dev *d)
{
u8 v;
- pci_read_config_byte(d, 0x55, &v);
- if (v & 0x80) {
+ int where = 0x55;
+
+ if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
+ where = 0x95; /* the memory write queue timer register is
+ different for the kt266x's: 0x95 not 0x55 */
+ }
+
+ pci_read_config_byte(d, where, &v);
+ if (v & 0xe0) {
printk("Trying to stomp on Athlon bug...\n");
- v &= 0x7f; /* clear bit 55.7 */
- pci_write_config_byte(d, 0x55, v);
+ v &= 0x1f; /* clear bits 5, 6, 7 */
+ pci_write_config_byte(d, where, v);
}
}
@@ -1138,6 +1147,9 @@ struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_athlon_bug },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_athlon_bug },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_athlon_bug },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_athlon_bug },
{ 0 }
};
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
index c2ff936a5..09c0852e5 100644
--- a/arch/i386/kernel/semaphore.c
+++ b/arch/i386/kernel/semaphore.c
@@ -238,31 +238,30 @@ asm(
*/
#if defined(CONFIG_SMP)
asm(
-"
-.align 4
-.globl __write_lock_failed
-__write_lock_failed:
- " LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)
-1: rep; nop
- cmpl $" RW_LOCK_BIAS_STR ",(%eax)
- jne 1b
-
- " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)
- jnz __write_lock_failed
- ret
-
-
-.align 4
-.globl __read_lock_failed
-__read_lock_failed:
- lock ; incl (%eax)
-1: rep; nop
- cmpl $1,(%eax)
- js 1b
+".text\n"
+".align 4\n"
+".globl __write_lock_failed\n"
+"__write_lock_failed:\n\t"
+ LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n"
+"1: rep; nop\n\t"
+ "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+ "jne 1b\n\t"
+ LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+ "jnz __write_lock_failed\n\t"
+ "ret"
+);
- lock ; decl (%eax)
- js __read_lock_failed
- ret
-"
+asm(
+".text\n"
+".align 4\n"
+".globl __read_lock_failed\n"
+"__read_lock_failed:\n\t"
+ LOCK "incl (%eax)\n"
+"1: rep; nop\n\t"
+ "cmpl $1,(%eax)\n\t"
+ "js 1b\n\t"
+ LOCK "decl (%eax)\n\t"
+ "js __read_lock_failed\n\t"
+ "ret"
);
#endif
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index d85fff88d..4b6c92b34 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -157,6 +157,7 @@ unsigned char aux_device_present;
extern void mcheck_init(struct cpuinfo_x86 *c);
extern int root_mountflags;
extern char _text, _etext, _edata, _end;
+extern int blk_nohighio;
static int disable_x86_serial_nr __initdata = 1;
static int disable_x86_fxsr __initdata = 0;
@@ -782,7 +783,7 @@ static void __init parse_mem_cmdline (char ** cmdline_p)
void __init setup_arch(char **cmdline_p)
{
unsigned long bootmap_size, low_mem_size;
- unsigned long start_pfn, max_pfn, max_low_pfn;
+ unsigned long start_pfn, max_low_pfn;
int i;
#ifdef CONFIG_VISWS
@@ -1067,6 +1068,14 @@ static int __init tsc_setup(char *str)
__setup("notsc", tsc_setup);
#endif
+static int __init highio_setup(char *str)
+{
+ printk("i386: disabling HIGHMEM block I/O\n");
+ blk_nohighio = 1;
+ return 1;
+}
+__setup("nohighio", highio_setup);
+
static int __init get_model_name(struct cpuinfo_x86 *c)
{
unsigned int *v;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index d0e694913..f0d730fd9 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -697,7 +697,7 @@ asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
*/
asmlinkage void math_state_restore(struct pt_regs regs)
{
- __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */
+ clts(); /* Allow maths ops (or we recurse) */
if (current->used_math) {
restore_fpu(current);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index bed1221ec..e0cb4b60e 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -334,7 +334,7 @@ void __init paging_init(void)
{
pagetable_init();
- __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir)));
+ __asm__( "movl %0,%%cr3\n" ::"r"(__pa(swapper_pg_dir)));
#if CONFIG_X86_PAE
/*
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 32f1decef..5c8d8013f 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -32,6 +32,7 @@
#include <linux/kernel_stat.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -131,55 +132,54 @@ atomic_t irq_mis_count;
* Generic, controller-independent functions:
*/
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
irq_desc_t *idesc;
- char *p = buf;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) {
idesc = irq_desc(i);
action = idesc->action;
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
+ seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
- p += sprintf(p, " %14s", idesc->handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, " %14s", idesc->handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
- p += sprintf(p, ", %s", action->name);
- *p++ = '\n';
+ seq_printf(p, ", %s", action->name);
+ seq_putc('\n');
}
- p += sprintf(p, "NMI: ");
+ seq_puts(p, "NMI: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
nmi_count(cpu_logical_map(j)));
- p += sprintf(p, "\n");
+ seq_putc(p, '\n');
#if defined(CONFIG_SMP) && defined(CONFIG_X86)
- p += sprintf(p, "LOC: ");
+ seq_puts(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
apic_timer_irqs[cpu_logical_map(j)]);
- p += sprintf(p, "\n");
+ seq_putc(p, '\n');
#endif
- p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
#if defined(CONFIG_X86) && defined(CONFIG_X86_IO_APIC) && defined(APIC_MISMATCH_DEBUG)
- p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
#endif
- return p - buf;
+ return 0;
}
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 0902518f9..1a33eef68 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -40,6 +40,7 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/irq.h>
@@ -53,7 +54,7 @@ extern int cia_request_irq(struct ciabase *base,int irq,
unsigned long flags, const char *devname, void *dev_id);
extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id);
extern void cia_init_IRQ(struct ciabase *base);
-extern int cia_get_irq_list(struct ciabase *base, char *buf);
+extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p);
/* irq node variables for amiga interrupt sources */
static irq_node_t *ami_irq_list[AMI_STD_IRQS];
@@ -468,28 +469,28 @@ void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
ami_int4, ami_int5, ami_badint, ami_int7
};
-int amiga_get_irq_list(char *buf)
+int show_amiga_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
irq_node_t *node;
for (i = 0; i < AMI_STD_IRQS; i++) {
if (!(node = ami_irq_list[i]))
continue;
- len += sprintf(buf+len, "ami %2d: %10u ", i,
+ seq_printf(p, "ami %2d: %10u ", i,
kstat.irqs[0][SYS_IRQS + i]);
do {
if (node->flags & SA_INTERRUPT)
- len += sprintf(buf+len, "F ");
+ seq_puts(p, "F ");
else
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", node->devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", node->devname);
if ((node = node->next))
- len += sprintf(buf+len, " ");
+ seq_puts(p, " ");
} while (node);
}
- len += cia_get_irq_list(&ciaa_base, buf+len);
- len += cia_get_irq_list(&ciab_base, buf+len);
- return len;
+ cia_get_irq_list(&ciaa_base, p);
+ cia_get_irq_list(&ciab_base, p);
+ return 0;
}
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index bf80ddb8a..68abf6287 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
@@ -158,16 +159,16 @@ void __init cia_init_IRQ(struct ciabase *base)
custom.intena = IF_SETCLR | base->int_mask;
}
-int cia_get_irq_list(struct ciabase *base, char *buf)
+int cia_get_irq_list(struct ciabase *base, struct seq_file *p)
{
- int i, j, len = 0;
+ int i, j;
j = base->cia_irq;
for (i = 0; i < CIA_IRQS; i++) {
- len += sprintf(buf+len, "cia %2d: %10d ", j + i,
+ seq_printf(p, "cia %2d: %10d ", j + i,
kstat.irqs[0][SYS_IRQS + j + i]);
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", base->irq_list[i].devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", base->irq_list[i].devname);
}
- return len;
+ return 0;
}
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 5d8c8eb10..5dc8ca17b 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -86,7 +86,7 @@ extern void amiga_enable_irq (unsigned int);
extern void amiga_disable_irq (unsigned int);
static void amiga_get_model(char *model);
static int amiga_get_hardware_list(char *buffer);
-extern int amiga_get_irq_list (char *);
+extern int show_amiga_interrupts (struct seq_file *, void *);
/* amiga specific timer functions */
static unsigned long amiga_gettimeoffset (void);
static void a3000_gettod (int *, int *, int *, int *, int *, int *);
@@ -403,7 +403,7 @@ void __init config_amiga(void)
disable_irq = amiga_disable_irq;
mach_get_model = amiga_get_model;
mach_get_hardware_list = amiga_get_hardware_list;
- mach_get_irq_list = amiga_get_irq_list;
+ mach_get_irq_list = show_amiga_interrupts;
mach_gettimeoffset = amiga_gettimeoffset;
if (AMIGAHW_PRESENT(A3000_CLK)){
mach_gettod = a3000_gettod;
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 5f3d7ef7c..189bea1e3 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -31,7 +31,7 @@ extern int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct
extern void dn_free_irq(unsigned int irq, void *dev_id);
extern void dn_enable_irq(unsigned int);
extern void dn_disable_irq(unsigned int);
-extern int dn_get_irq_list(char *);
+extern int show_dn_interrupts(struct seq_file *, void *);
extern unsigned long dn_gettimeoffset(void);
extern void dn_gettod(int *, int *, int *, int *, int *, int *);
extern int dn_dummy_hwclk(int, struct hwclk_time *);
@@ -173,7 +173,7 @@ void config_apollo(void) {
mach_free_irq = dn_free_irq;
enable_irq = dn_enable_irq;
disable_irq = dn_disable_irq;
- mach_get_irq_list = dn_get_irq_list;
+ mach_get_irq_list = show_dn_interrupts;
mach_gettimeoffset = dn_gettimeoffset;
mach_gettod = dn_gettod; /* */
mach_max_dma_address = 0xffffffff;
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 0f5c012c3..95097695d 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -104,7 +104,7 @@ void dn_disable_irq(unsigned int irq) {
}
-int dn_get_irq_list(char *buf) {
+int show_dn_interrupts(struct seq_file *p, void *v) {
printk("dn get irq list\n");
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index f92c45f60..4574d7de2 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -40,6 +40,7 @@
#include <linux/ptrace.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/traps.h>
@@ -609,37 +610,37 @@ void atari_unregister_vme_int(unsigned long irq)
}
-int atari_get_irq_list(char *buf)
+int show_atari_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
for (i = 0; i < NUM_INT_SOURCES; ++i) {
if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt)
continue;
if (i < STMFP_SOURCE_BASE)
- len += sprintf(buf+len, "auto %2d: %10u ",
+ seq_printf(p,, "auto %2d: %10u ",
i, kstat.irqs[0][i]);
else
- len += sprintf(buf+len, "vec $%02x: %10u ",
+ seq_printf(p,, "vec $%02x: %10u ",
IRQ_SOURCE_TO_VECTOR(i),
kstat.irqs[0][i]);
if (irq_handler[i].handler != atari_call_irq_list) {
- len += sprintf(buf+len, "%s\n", irq_param[i].devname);
+ seq_printf(p,, "%s\n", irq_param[i].devname);
}
else {
irq_node_t *p;
for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {
- len += sprintf(buf+len, "%s\n", p->devname);
+ seq_printf(p,, "%s\n", p->devname);
if (p->next)
- len += sprintf( buf+len, " " );
+ seq_puts(p,, " " );
}
}
}
if (num_spurious)
- len += sprintf(buf+len, "spurio.: %10u\n", num_spurious);
+ seq_printf(p, "spurio.: %10u\n", num_spurious);
- return len;
+ return 0;
}
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 70a32fb65..b96532afc 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -70,7 +70,7 @@ extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, str
extern void atari_free_irq (unsigned int irq, void *dev_id);
extern void atari_enable_irq (unsigned int);
extern void atari_disable_irq (unsigned int);
-extern int atari_get_irq_list (char *buf);
+extern int show_atari_interrupts (struct seq_file *, void *);
extern void atari_mksound( unsigned int count, unsigned int ticks );
#ifdef CONFIG_HEARTBEAT
static void atari_heartbeat( int on );
@@ -265,7 +265,7 @@ void __init config_atari(void)
disable_irq = atari_disable_irq;
mach_get_model = atari_get_model;
mach_get_hardware_list = atari_get_hardware_list;
- mach_get_irq_list = atari_get_irq_list;
+ mach_get_irq_list = show_atari_interrupts;
mach_gettimeoffset = atari_gettimeoffset;
mach_reset = atari_reset;
#ifdef CONFIG_ATARI_FLOPPY
diff --git a/arch/m68k/atari/joystick.c b/arch/m68k/atari/joystick.c
index df41b38d8..440114eb9 100644
--- a/arch/m68k/atari/joystick.c
+++ b/arch/m68k/atari/joystick.c
@@ -61,13 +61,11 @@ static int release_joystick(struct inode *inode, struct file *file)
{
int minor = DEVICE_NR(inode->i_rdev);
- lock_kernel();
joystick[minor].active = 0;
joystick[minor].ready = 0;
if ((joystick[0].active == 0) && (joystick[1].active == 0))
ikbd_joystick_disable();
- unlock_kernel();
return 0;
}
diff --git a/arch/m68k/bvme6000/bvmeints.c b/arch/m68k/bvme6000/bvmeints.c
index 04633375f..4f2038c3d 100644
--- a/arch/m68k/bvme6000/bvmeints.c
+++ b/arch/m68k/bvme6000/bvmeints.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/seq_file.h>
#include <asm/ptrace.h>
#include <asm/system.h>
@@ -127,17 +128,17 @@ void bvme6000_process_int (unsigned long vec, struct pt_regs *fp)
}
}
-int bvme6000_get_irq_list (char *buf)
+int show_bvme6000_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
for (i = 0; i < 256; i++) {
if (irq_tab[i].count)
- len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n",
+ seq_printf(p, "Vec 0x%02x: %8d %s\n",
i, irq_tab[i].count,
irq_tab[i].devname ? irq_tab[i].devname : "free");
}
- return len;
+ return 0;
}
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index 43b01370f..002c9a684 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -36,7 +36,7 @@
extern void bvme6000_process_int (int level, struct pt_regs *regs);
extern void bvme6000_init_IRQ (void);
extern void bvme6000_free_irq (unsigned int, void *);
-extern int bvme6000_get_irq_list (char *);
+extern int show_bvme6000_interrupts(struct seq_file *, void *);
extern void bvme6000_enable_irq (unsigned int);
extern void bvme6000_disable_irq (unsigned int);
static void bvme6000_get_model(char *model);
@@ -145,7 +145,7 @@ void __init config_bvme6000(void)
mach_reset = bvme6000_reset;
mach_free_irq = bvme6000_free_irq;
mach_process_int = bvme6000_process_int;
- mach_get_irq_list = bvme6000_get_irq_list;
+ mach_get_irq_list = show_bvme6000_interrupts;
mach_request_irq = bvme6000_request_irq;
enable_irq = bvme6000_enable_irq;
disable_irq = bvme6000_disable_irq;
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
index d998d6ff9..6694c253f 100644
--- a/arch/m68k/hp300/config.c
+++ b/arch/m68k/hp300/config.c
@@ -25,7 +25,7 @@
extern void hp300_reset(void);
extern void (*hp300_default_handler[])(int, void *, struct pt_regs *);
-extern int hp300_get_irq_list(char *buf);
+extern int show_hp300_interrupts(struct seq_file *, void *);
#ifdef CONFIG_VT
extern int hp300_keyb_init(void);
@@ -70,7 +70,7 @@ void __init config_hp300(void)
mach_request_irq = hp300_request_irq;
mach_free_irq = hp300_free_irq;
mach_get_model = hp300_get_model;
- mach_get_irq_list = hp300_get_irq_list;
+ mach_get_irq_list = show_hp300_interrupts;
mach_gettimeoffset = hp300_gettimeoffset;
mach_default_handler = &hp300_default_handler;
#if 0
diff --git a/arch/m68k/hp300/ints.c b/arch/m68k/hp300/ints.c
index 497400575..bc459adcb 100644
--- a/arch/m68k/hp300/ints.c
+++ b/arch/m68k/hp300/ints.c
@@ -148,7 +148,7 @@ void hp300_free_irq(unsigned int irq, void *dev_id)
spin_unlock_irqrestore(&irqlist_lock, flags);
}
-int hp300_get_irq_list(char *buf)
+int show_hp300_interrupts(struct seq_file *p, void *v)
{
return 0;
}
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 240bb3c7c..b69407501 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -242,22 +242,22 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
}
}
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
/* autovector interrupts */
if (mach_default_handler) {
for (i = 0; i < SYS_IRQS; i++) {
- len += sprintf(buf+len, "auto %2d: %10u ", i,
+ seq_printf(p, "auto %2d: %10u ", i,
i ? kstat.irqs[0][i] : num_spurious);
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", irq_list[i].devname);
}
}
- len += mach_get_irq_list(buf+len);
- return len;
+ mach_get_irq_list(p, v);
+ return 0;
}
void init_irq_proc(void)
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 9291702fc..86007efb1 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -80,7 +80,7 @@ void (*mach_init_IRQ) (void) __initdata = NULL;
void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
void (*mach_get_model) (char *model) = NULL;
int (*mach_get_hardware_list) (char *buffer) = NULL;
-int (*mach_get_irq_list) (char *) = NULL;
+int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
void (*mach_process_int) (int, struct pt_regs *) = NULL;
/* machine dependent timer functions */
unsigned long (*mach_gettimeoffset) (void);
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 94fdb4d34..02b391dbb 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -66,7 +66,7 @@ extern void mac_gettod (int *, int *, int *, int *, int *, int *);
extern unsigned long mac_gettimeoffset (void);
extern int mac_hwclk (int, struct hwclk_time *);
extern int mac_set_clock_mmss (unsigned long);
-extern int mac_get_irq_list(char *);
+extern int show_mac_interrupts(struct seq_file *, void *);
extern void iop_preinit(void);
extern void iop_init(void);
extern void via_init(void);
@@ -241,7 +241,7 @@ void __init config_mac(void)
disable_irq = mac_disable_irq;
mach_get_model = mac_get_model;
mach_default_handler = &mac_handlers;
- mach_get_irq_list = mac_get_irq_list;
+ mach_get_irq_list = show_mac_interrupts;
mach_gettimeoffset = mac_gettimeoffset;
mach_gettod = mac_gettod;
mach_hwclk = mac_hwclk;
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index a5ca36475..630c0aaa5 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -120,6 +120,7 @@
#include <linux/kernel_stat.h>
#include <linux/interrupt.h> /* for intr_count */
#include <linux/delay.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/irq.h>
@@ -576,9 +577,9 @@ void mac_free_irq(unsigned int irq, void *dev_id)
* displayed for us as autovector irq 0.
*/
-int mac_get_irq_list (char *buf)
+int show_mac_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
irq_node_t *node;
char *base;
@@ -618,25 +619,24 @@ int mac_get_irq_list (char *buf)
case 8: base = "bbn";
break;
}
- len += sprintf(buf+len, "%4s %2d: %10u ",
- base, i, kstat.irqs[0][i]);
+ seq_printf(p, "%4s %2d: %10u ", base, i, kstat.irqs[0][i]);
do {
if (node->flags & IRQ_FLG_FAST) {
- len += sprintf(buf+len, "F ");
+ seq_puts(p, "F ");
} else if (node->flags & IRQ_FLG_SLOW) {
- len += sprintf(buf+len, "S ");
+ seq_puts(p, "S ");
} else {
- len += sprintf(buf+len, " ");
+ seq_puts(p, " ");
}
- len += sprintf(buf+len, "%s\n", node->devname);
+ seq_printf(p, "%s\n", node->devname);
if ((node = node->next)) {
- len += sprintf(buf+len, " ");
+ seq_puts(p, " ");
}
} while(node);
}
- return len;
+ return 0;
}
void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/arch/m68k/mvme147/147ints.c b/arch/m68k/mvme147/147ints.c
index 3121ad94f..d58edccba 100644
--- a/arch/m68k/mvme147/147ints.c
+++ b/arch/m68k/mvme147/147ints.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/seq_file.h>
#include <asm/ptrace.h>
#include <asm/system.h>
@@ -112,17 +113,17 @@ void mvme147_process_int (unsigned long vec, struct pt_regs *fp)
}
}
-int mvme147_get_irq_list (char *buf)
+int show_mvme147_interrupts (struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
for (i = 0; i < 256; i++) {
if (irq_tab[i].count)
- len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n",
+ seq_printf(p, "Vec 0x%02x: %8d %s\n",
i, irq_tab[i].count,
irq_tab[i].devname ? irq_tab[i].devname : "free");
}
- return len;
+ return 0;
}
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 7da8eeb6c..4a85a6e1c 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -36,7 +36,7 @@
extern void mvme147_process_int (int level, struct pt_regs *regs);
extern void mvme147_init_IRQ (void);
extern void mvme147_free_irq (unsigned int, void *);
-extern int mvme147_get_irq_list (char *);
+extern int show_mvme147_interrupts (struct seq_file *, void *);
extern void mvme147_enable_irq (unsigned int);
extern void mvme147_disable_irq (unsigned int);
static void mvme147_get_model(char *model);
@@ -113,7 +113,7 @@ void __init config_mvme147(void)
mach_reset = mvme147_reset;
mach_free_irq = mvme147_free_irq;
mach_process_int = mvme147_process_int;
- mach_get_irq_list = mvme147_get_irq_list;
+ mach_get_irq_list = show_mvme147_interrupts;
mach_request_irq = mvme147_request_irq;
enable_irq = mvme147_enable_irq;
disable_irq = mvme147_disable_irq;
diff --git a/arch/m68k/mvme16x/16xints.c b/arch/m68k/mvme16x/16xints.c
index 9cc0d39d1..198d01a68 100644
--- a/arch/m68k/mvme16x/16xints.c
+++ b/arch/m68k/mvme16x/16xints.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/ptrace.h>
@@ -114,17 +115,17 @@ void mvme16x_process_int (unsigned long vec, struct pt_regs *fp)
}
}
-int mvme16x_get_irq_list (char *buf)
+int show_mvme16x_interrupts (struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
for (i = 0; i < 192; i++) {
if (irq_tab[i].count)
- len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n",
+ seq_printf(p, "Vec 0x%02x: %8d %s\n",
i+64, irq_tab[i].count,
irq_tab[i].devname ? irq_tab[i].devname : "free");
}
- return len;
+ return 0;
}
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index 83190d62f..70fa43ac8 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -40,7 +40,7 @@ static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
extern void mvme16x_process_int (int level, struct pt_regs *regs);
extern void mvme16x_init_IRQ (void);
extern void mvme16x_free_irq (unsigned int, void *);
-extern int mvme16x_get_irq_list (char *);
+extern int show_mvme16x_interrupts (struct seq_file *, void *);
extern void mvme16x_enable_irq (unsigned int);
extern void mvme16x_disable_irq (unsigned int);
static void mvme16x_get_model(char *model);
@@ -156,7 +156,7 @@ void __init config_mvme16x(void)
mach_reset = mvme16x_reset;
mach_free_irq = mvme16x_free_irq;
mach_process_int = mvme16x_process_int;
- mach_get_irq_list = mvme16x_get_irq_list;
+ mach_get_irq_list = show_mvme16x_interrupts;
mach_request_irq = mvme16x_request_irq;
enable_irq = mvme16x_enable_irq;
disable_irq = mvme16x_disable_irq;
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index fd683ff1e..c80b402e7 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -36,7 +36,7 @@
static unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static char rtc_status = 0;
+static atomic_t rtc_ready = ATOMIC_INIT(1);
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
@@ -130,18 +130,18 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int rtc_open(struct inode *inode, struct file *file)
{
- if(rtc_status)
+ if( !atomic_dec_and_test(&rtc_ready) )
+ {
+ atomic_inc( &rtc_ready );
return -EBUSY;
+ }
- rtc_status = 1;
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
- lock_kernel();
- rtc_status = 0;
- unlock_kernel();
+ atomic_inc( &rtc_ready );
return 0;
}
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index e35bcf62e..23690901c 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -45,7 +45,7 @@ extern void q40_process_int (int level, struct pt_regs *regs);
extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
extern void q40_init_IRQ (void);
extern void q40_free_irq (unsigned int, void *);
-extern int q40_get_irq_list (char *);
+extern int show_q40_interrupts (struct seq_file *, void *);
extern void q40_enable_irq (unsigned int);
extern void q40_disable_irq (unsigned int);
static void q40_get_model(char *model);
@@ -236,7 +236,7 @@ void __init config_q40(void)
mach_reset = q40_reset;
mach_free_irq = q40_free_irq;
mach_process_int = q40_process_int;
- mach_get_irq_list = q40_get_irq_list;
+ mach_get_irq_list = show_q40_interrupts;
mach_request_irq = q40_request_irq;
enable_irq = q40_enable_irq;
disable_irq = q40_disable_irq;
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 70d61c73c..1fe6de7dd 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/sched.h>
+#include <linux/seq_file.h>
#include <asm/rtc.h>
#include <asm/ptrace.h>
@@ -431,21 +432,20 @@ void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
}
}
-int q40_get_irq_list (char *buf)
+int show_q40_interrupts (struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
- for (i = 0; i <= Q40_IRQ_MAX; i++)
- {
+ for (i = 0; i <= Q40_IRQ_MAX; i++) {
if (irq_tab[i].count)
- len += sprintf (buf+len, "%sIRQ %02d: %8d %s%s\n",
+ seq_printf(p, "%sIRQ %02d: %8d %s%s\n",
(i<=15) ? "ISA-" : " " ,
i, irq_tab[i].count,
irq_tab[i].devname[0] ? irq_tab[i].devname : "?",
irq_tab[i].handler == q40_defhand ?
" (now unassigned)" : "");
}
- return len;
+ return 0;
}
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index d57719a1b..7835991e0 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -36,7 +36,7 @@ extern char _text, _end;
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
extern unsigned long sun3_gettimeoffset(void);
-extern int sun3_get_irq_list (char *);
+extern int show_sun3_interrupts (char *);
extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *));
extern void sun3_get_model (char* model);
extern void idprom_init (void);
@@ -145,7 +145,7 @@ void __init config_sun3(void)
enable_irq = sun3_enable_irq;
disable_irq = sun3_disable_irq;
mach_process_int = sun3_process_int;
- mach_get_irq_list = sun3_get_irq_list;
+ mach_get_irq_list = show_sun3_interrupts;
mach_gettod = sun3_gettod;
mach_reset = sun3_reboot;
mach_gettimeoffset = sun3_gettimeoffset;
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 5a41e6174..f4270ca85 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -15,6 +15,7 @@
#include <asm/intersil.h>
#include <asm/oplib.h>
#include <asm/sun3ints.h>
+#include <linux/seq_file.h>
extern void sun3_leds (unsigned char);
@@ -62,7 +63,7 @@ inline void sun3_do_irq(int irq, struct pt_regs *fp)
*sun3_intreg |= (1<<irq);
}
-int sun3_get_irq_list(char *buf)
+int show_sun3_interrupts(struct seq_file *p, void *v)
{
return 0;
}
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index fcdf79429..0e5fc55f9 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -58,7 +58,7 @@ void __init config_sun3x(void)
sun3x_prom_init();
- mach_get_irq_list = sun3_get_irq_list;
+ mach_get_irq_list = show_sun3_interrupts;
mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
mach_keyb_init = sun3x_keyb_init;
diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
index 3cac91647..d346ec871 100644
--- a/arch/mips/baget/irq.c
+++ b/arch/mips/baget/irq.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -141,27 +142,27 @@ void enable_irq(unsigned int irq_nr)
*/
static struct irqaction *irq_action[BAGET_IRQ_NR] = { NULL, };
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction * action;
for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
diff --git a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c
index ce1ccb994..d460583f3 100644
--- a/arch/mips/dec/irq.c
+++ b/arch/mips/dec/irq.c
@@ -15,6 +15,7 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -92,27 +93,27 @@ static struct irqaction *irq_action[32] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
- struct irqaction *action;
-
- for (i = 0; i < 32; i++) {
- action = irq_action[i];
- if (!action)
- continue;
- len += sprintf(buf + len, "%2d: %8d %c %s",
- i, kstat.irqs[0][i],
- (action->flags & SA_INTERRUPT) ? '+' : ' ',
- action->name);
- for (action = action->next; action; action = action->next) {
- len += sprintf(buf + len, ",%s %s",
- (action->flags & SA_INTERRUPT) ? " +" : "",
- action->name);
+ int i;
+ struct irqaction *action;
+
+ for (i = 0; i < 32; i++) {
+ action = irq_action[i];
+ if (!action)
+ continue;
+ seq_printf(p, "%2d: %8d %c %s",
+ i, kstat.irqs[0][i],
+ (action->flags & SA_INTERRUPT) ? '+' : ' ',
+ action->name);
+ for (action = action->next; action; action = action->next) {
+ seq_printf(p, ",%s %s",
+ (action->flags & SA_INTERRUPT) ? " +" : "",
+ action->name);
+ }
+ seq_putc(p, '\n');
}
- len += sprintf(buf + len, "\n");
- }
- return len;
+ return 0;
}
/*
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
index 28ad5d35b..53585e39f 100644
--- a/arch/mips/ite-boards/generic/irq.c
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -46,6 +46,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/serial_reg.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -217,34 +218,34 @@ static struct hw_interrupt_type it8172_irq_type = {
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0, j;
+ int i, j;
struct irqaction * action;
- len += sprintf(buf+len, " ");
+ seq_printf(p, " ");
for (j=0; j<smp_num_cpus; j++)
- len += sprintf(buf+len, "CPU%d ",j);
- *(char *)(buf+len++) = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_desc[i].action;
if ( !action || !action->handler )
continue;
- len += sprintf(buf+len, "%3d: ", i);
- len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%3d: ", i);
+ seq_printf(p, "%10u ", kstat_irqs(i));
if ( irq_desc[i].handler )
- len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
+ seq_printf(p, " %s ", irq_desc[i].handler->typename );
else
- len += sprintf(buf+len, " None ");
- len += sprintf(buf+len, " %s",action->name);
+ seq_puts(p, " None ");
+ seq_printf(p, " %s",action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ", %s", action->name);
+ seq_printf(p, ", %s", action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- len += sprintf(buf+len, "BAD: %10lu\n", spurious_count);
- return len;
+ seq_printf(p, "BAD: %10lu\n", spurious_count);
+ return 0;
}
asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 8cde3950b..77e00450a 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
@@ -69,32 +70,31 @@ volatile unsigned long irq_err_count, spurious_count;
* Generic, controller-independent functions:
*/
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
struct irqaction * action;
- char *p = buf;
int i;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (i=0; i < 1 /*smp_num_cpus*/; i++)
- p += sprintf(p, "CPU%d ", i);
- *p++ = '\n';
+ seq_printf(p, "CPU%d ", i);
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
- p += sprintf(p, "%10u ", kstat_irqs(i));
- p += sprintf(p, " %14s", irq_desc[i].handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, "%3d: ",i);
+ seq_printf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, " %14s", irq_desc[i].handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
- p += sprintf(p, ", %s", action->name);
- *p++ = '\n';
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
}
- p += sprintf(p, "ERR: %10lu\n", irq_err_count);
- return p - buf;
+ seq_printf(p, "ERR: %10lu\n", irq_err_count);
+ return 0;
}
/*
diff --git a/arch/mips/kernel/old-irq.c b/arch/mips/kernel/old-irq.c
index ddc83d18a..50f0807a7 100644
--- a/arch/mips/kernel/old-irq.c
+++ b/arch/mips/kernel/old-irq.c
@@ -24,6 +24,7 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -123,27 +124,27 @@ static struct irqaction *irq_action[NR_IRQS] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction * action;
for (i = 0 ; i < 32 ; i++) {
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
static inline void i8259_mask_and_ack_irq(int irq)
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index c5035ad0b..c13cf568d 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/mips-boards/atlas.h>
@@ -93,9 +94,9 @@ static struct hw_interrupt_type atlas_irq_type = {
NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
int num = 0;
struct irqaction *action;
@@ -103,18 +104,18 @@ int get_irq_list(char *buf)
action = irq_desc[i].action;
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [hw0]\n");
+ seq_printf(p, " [hw0]\n");
}
- return len;
+ return 0;
}
int request_irq(unsigned int irq,
diff --git a/arch/mips/philips/nino/irq.c b/arch/mips/philips/nino/irq.c
index 6772b8f22..40ad3adc0 100644
--- a/arch/mips/philips/nino/irq.c
+++ b/arch/mips/philips/nino/irq.c
@@ -23,6 +23,7 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -114,27 +115,27 @@ static struct irqaction *irq_action[NR_IRQS] =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction *action;
for (i = 0; i < NR_IRQS; i++) {
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf + len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action = action->next; action; action = action->next) {
- len += sprintf(buf + len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf + len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
atomic_t __mips_bh_counter;
diff --git a/arch/mips64/mips-boards/atlas/atlas_int.c b/arch/mips64/mips-boards/atlas/atlas_int.c
index b25ea834c..667c2bdd4 100644
--- a/arch/mips64/mips-boards/atlas/atlas_int.c
+++ b/arch/mips64/mips-boards/atlas/atlas_int.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/mips-boards/atlas.h>
@@ -89,9 +90,9 @@ static struct hw_interrupt_type atlas_irq_type = {
NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
int num = 0;
struct irqaction *action;
@@ -99,18 +100,18 @@ int get_irq_list(char *buf)
action = irq_desc[i].action;
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [hw0]\n");
+ seq_puts(p, " [hw0]\n");
}
- return len;
+ return 0;
}
int request_irq(unsigned int irq,
diff --git a/arch/mips64/mips-boards/malta/malta_int.c b/arch/mips64/mips-boards/malta/malta_int.c
index 9db1254a1..d58af8391 100644
--- a/arch/mips64/mips-boards/malta/malta_int.c
+++ b/arch/mips64/mips-boards/malta/malta_int.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/random.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -119,9 +120,9 @@ void enable_irq(unsigned int irq_nr)
}
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
int num = 0;
struct irqaction *action;
@@ -129,33 +130,33 @@ int get_irq_list(char *buf)
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [on-chip]\n");
+ seq_puts(p, " [on-chip]\n");
}
for (i = 0; i < MALTAINT_END; i++, num++) {
action = hw0_irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [hw0]\n");
+ seq_puts(p, " [hw0]\n");
}
- return len;
+ return 0;
}
int request_irq(unsigned int irq,
diff --git a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c
index d849422cd..e87fd162f 100644
--- a/arch/mips64/sgi-ip22/ip22-int.c
+++ b/arch/mips64/sgi-ip22/ip22-int.c
@@ -8,6 +8,7 @@
*/
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
@@ -231,9 +232,9 @@ static struct irqaction *irq_action[16] = {
NULL, NULL, NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
int num = 0;
struct irqaction * action;
@@ -241,33 +242,33 @@ int get_irq_list(char *buf)
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [on-chip]\n");
+ seq_puts(p, " [on-chip]\n");
}
for (i = 0 ; i < 24 ; i++, num++) {
action = local_irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s",
+ seq_printf(p, "%2d: %8d %c %s",
num, kstat.irqs[0][num],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, " [local]\n");
+ seq_puts(p, " [local]\n");
}
- return len;
+ return 0;
}
/*
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 0e6369c2b..b25c98ddb 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -20,6 +20,7 @@
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/seq_file.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -136,27 +137,27 @@ void enable_irq(unsigned int irq_nr)
/* This is stupid for an Origin which can have thousands of IRQs ... */
static struct irqaction *irq_action[NR_IRQS];
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction * action;
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_action[i];
if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i],
+ seq_printf(p, "%2d: %8d %c %s", i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT)
? " +" : "",
action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
/*
diff --git a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c
index b29af3d73..c893d10cf 100644
--- a/arch/mips64/sgi-ip27/ip27-rtc.c
+++ b/arch/mips64/sgi-ip27/ip27-rtc.c
@@ -53,14 +53,7 @@ static int rtc_read_proc(char *page, char **start, off_t off,
static void get_rtc_time(struct rtc_time *rtc_tm);
-/*
- * Bits in rtc_status. (6 bits of room for future expansion)
- */
-
-#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
-#define RTC_TIMER_ON 0x02 /* missed irq timer active */
-
-static unsigned char rtc_status; /* bitmapped status byte. */
+static atomic_t rtc_ready = ATOMIC_INIT(1);
static unsigned long rtc_freq; /* Current periodic IRQ rate */
static struct m48t35_rtc *rtc;
@@ -166,23 +159,17 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int rtc_open(struct inode *inode, struct file *file)
{
- if(rtc_status & RTC_IS_OPEN)
+ if( atomic_dec_and_test( &rtc_ready ) )
+ {
+ atomic_inc( &rtc_ready );
return -EBUSY;
-
- rtc_status |= RTC_IS_OPEN;
+ }
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
- /*
- * Turn off all interrupts once the device is no longer
- * in use, and clear the data.
- */
-
- lock_kernel();
- rtc_status &= ~RTC_IS_OPEN;
- unlock_kernel();
+ atomic_inc( &rtc_ready );
return 0;
}
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index b3914a1b1..45411f217 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -39,6 +39,7 @@
#include <linux/random.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/seq_file.h>
#include <asm/cache.h>
@@ -160,19 +161,18 @@ void enable_irq(int irq)
BUG();
}
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
#ifdef CONFIG_PROC_FS
- char *p = buf;
int i, j;
int regnr, irq_no;
struct irq_region *region;
struct irqaction *action, *mainaction;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (regnr = 0; regnr < NR_IRQ_REGS; regnr++) {
region = irq_region[regnr];
@@ -188,40 +188,34 @@ int get_irq_list(char *buf)
irq_no = IRQ_FROM_REGION(regnr) + i;
- p += sprintf(p, "%3d: ", irq_no);
+ seq_printf(p, "%3d: ", irq_no);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(irq_no));
+ seq_printf(p, "%10u ", kstat_irqs(irq_no));
#else
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][irq_no]);
#endif
- p += sprintf(p, " %14s",
+ seq_printf(p, " %14s",
region->data.name ? region->data.name : "N/A");
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
- p += sprintf(p, ", %s", action->name);
- *p++ = '\n';
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
}
}
- p += sprintf(p, "\n");
+ seq_putc(p, '\n');
#if CONFIG_SMP
- p += sprintf(p, "LOC: ");
+ seq_puts(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
+ seq_printf(p, "%10u ",
apic_timer_irqs[cpu_logical_map(j)]);
- p += sprintf(p, "\n");
+ seq_putc(p, '\n');
#endif
-
- return p - buf;
-
-#else /* CONFIG_PROC_FS */
-
- return 0;
-
#endif /* CONFIG_PROC_FS */
+ return 0;
}
diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
index 1b6879b9c..dd6ea8bac 100644
--- a/arch/ppc/amiga/amiints.c
+++ b/arch/ppc/amiga/amiints.c
@@ -44,6 +44,7 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/irq.h>
@@ -61,7 +62,7 @@ extern int cia_request_irq(int irq,
unsigned long flags, const char *devname, void *dev_id);
extern void cia_free_irq(unsigned int irq, void *dev_id);
extern void cia_init_IRQ(struct ciabase *base);
-extern int cia_get_irq_list(struct ciabase *base, char *buf);
+extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p);
/* irq node variables for amiga interrupt sources */
static irq_node_t *ami_irq_list[AMI_STD_IRQS];
@@ -480,28 +481,28 @@ void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
};
#endif
-int amiga_get_irq_list(char *buf)
+int show_amiga_intreeupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
irq_node_t *node;
for (i = 0; i < AMI_STD_IRQS; i++) {
if (!(node = ami_irq_list[i]))
continue;
- len += sprintf(buf+len, "ami %2d: %10u ", i,
+ seq_printf(p, "ami %2d: %10u ", i,
kstat.irqs[0][SYS_IRQS + i]);
do {
if (node->flags & SA_INTERRUPT)
- len += sprintf(buf+len, "F ");
+ seq_puts(p, "F ");
else
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", node->devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", node->devname);
if ((node = node->next))
- len += sprintf(buf+len, " ");
+ seq_puts(p, " ");
} while (node);
}
- len += cia_get_irq_list(&ciaa_base, buf+len);
- len += cia_get_irq_list(&ciab_base, buf+len);
+ cia_get_irq_list(&ciaa_base, p);
+ cia_get_irq_list(&ciab_base, p);
return len;
}
diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c
index 37ebba24d..21f03c0a5 100644
--- a/arch/ppc/amiga/cia.c
+++ b/arch/ppc/amiga/cia.c
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
@@ -222,16 +223,16 @@ void __init cia_init_IRQ(struct ciabase *base)
custom.intena = IF_SETCLR | base->int_mask;
}
-int cia_get_irq_list(struct ciabase *base, char *buf)
+int cia_get_irq_list(struct ciabase *base, struct seq_file *p)
{
- int i, j, len = 0;
+ int i, j;
j = base->cia_irq;
for (i = 0; i < CIA_IRQS; i++) {
- len += sprintf(buf+len, "cia %2d: %10d ", j + i,
+ seq_printf(p, "cia %2d: %10d ", j + i,
kstat.irqs[0][SYS_IRQS + j + i]);
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", base->irq_list[i].devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", base->irq_list[i].devname);
}
- return len;
+ return 0;
}
diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c
index 34ac4047a..c26b6fdd3 100644
--- a/arch/ppc/amiga/config.c
+++ b/arch/ppc/amiga/config.c
@@ -28,6 +28,7 @@
#ifdef CONFIG_ZORRO
#include <linux/zorro.h>
#endif
+#include <linux/seq_file.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>
@@ -91,7 +92,7 @@ extern void amiga_enable_irq (unsigned int);
extern void amiga_disable_irq (unsigned int);
static void amiga_get_model(char *model);
static int amiga_get_hardware_list(char *buffer);
-extern int amiga_get_irq_list (char *);
+extern int show_amiga_interrupts (struct seq_file *, void *);
/* amiga specific timer functions */
static unsigned long amiga_gettimeoffset (void);
static void a3000_gettod (int *, int *, int *, int *, int *, int *);
@@ -422,7 +423,7 @@ void __init config_amiga(void)
#endif
mach_get_model = amiga_get_model;
mach_get_hardware_list = amiga_get_hardware_list;
- mach_get_irq_list = amiga_get_irq_list;
+ mach_get_irq_list = show_amiga_interrupts;
mach_gettimeoffset = amiga_gettimeoffset;
if (AMIGAHW_PRESENT(A3000_CLK)){
mach_gettod = a3000_gettod;
diff --git a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c
index 3ca420bdf..9bec7e2cc 100644
--- a/arch/ppc/amiga/ints.c
+++ b/arch/ppc/amiga/ints.c
@@ -13,6 +13,7 @@
#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/setup.h>
#include <asm/system.h>
@@ -143,20 +144,20 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
}
}
-int m68k_get_irq_list(char *buf)
+int m68k_get_irq_list(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
/* autovector interrupts */
if (mach_default_handler) {
for (i = 0; i < SYS_IRQS; i++) {
- len += sprintf(buf+len, "auto %2d: %10u ", i,
+ seq_printf(p, "auto %2d: %10u ", i,
i ? kstat.irqs[0][i] : num_spurious);
- len += sprintf(buf+len, " ");
- len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+ seq_puts(p, " ");
+ seq_printf(p, "%s\n", irq_list[i].devname);
}
}
- len += mach_get_irq_list(buf+len);
- return len;
+ mach_get_irq_list(p, v);
+ return 0;
}
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c
index e1f8cf807..bdbc452bc 100644
--- a/arch/ppc/kernel/apus_setup.c
+++ b/arch/ppc/kernel/apus_setup.c
@@ -95,7 +95,7 @@ void (*mach_init_IRQ) (void) __initdata = NULL;
void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
void (*mach_get_model) (char *model) = NULL;
int (*mach_get_hardware_list) (char *buffer) = NULL;
-int (*mach_get_irq_list) (char *) = NULL;
+int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
void (*mach_process_int) (int, struct pt_regs *) = NULL;
/* machine dependent timer functions */
unsigned long (*mach_gettimeoffset) (void);
@@ -671,12 +671,12 @@ static unsigned int apus_irq_cannonicalize(unsigned int irq)
return irq;
}
-int apus_get_irq_list(char *buf)
+int show_apus_interrupts(struct seq_file *p, void *v)
{
#ifdef CONFIG_APUS
- extern int amiga_get_irq_list(char *buf);
+ extern int show_amiga_interrupts(struct seq_file *p, void *v)
- return amiga_get_irq_list (buf);
+ return show_amiga_interrupts(p, v);
#else
return 0;
#endif
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index a4734093f..c5f422016 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -47,6 +47,7 @@
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
+#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
@@ -371,58 +372,58 @@ void enable_irq(unsigned int irq)
spin_unlock_irqrestore(&desc->lock, flags);
}
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
#ifdef CONFIG_APUS
- return apus_get_irq_list (buf);
+ return show_apus_interrupts(p, v);
#else
- int i, len = 0, j;
+ int i, j;
struct irqaction * action;
- len += sprintf(buf+len, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- len += sprintf(buf+len, "CPU%d ",j);
- *(char *)(buf+len++) = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) {
action = irq_desc[i].action;
if ( !action || !action->handler )
continue;
- len += sprintf(buf+len, "%3d: ", i);
+ seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP
for (j = 0; j < smp_num_cpus; j++)
- len += sprintf(buf+len, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#else
- len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#endif /* CONFIG_SMP */
if ( irq_desc[i].handler )
- len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
+ seq_printf(p, " %s ", irq_desc[i].handler->typename );
else
- len += sprintf(buf+len, " None ");
- len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
- len += sprintf(buf+len, " %s",action->name);
+ seq_puts(p, " None ");
+ seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
+ seq_printf(p, " %s",action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ", %s", action->name);
+ seq_printf(p, ", %s", action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
#ifdef CONFIG_TAU_INT
if (tau_initialized){
- len += sprintf(buf+len, "TAU: ");
+ seq_puts(p, "TAU: ");
for (j = 0; j < smp_num_cpus; j++)
- len += sprintf(buf+len, "%10u ",
+ seq_printf(p, "%10u ",
tau_interrupts(j));
- len += sprintf(buf+len, " PowerPC Thermal Assist (cpu temp)\n");
+ seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
}
#endif
#ifdef CONFIG_SMP
/* should this be per processor send/receive? */
- len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n",
+ seq_printf(p, "IPI (recv/sent): %10u/%u\n",
atomic_read(&ipi_recv), atomic_read(&ipi_sent));
#endif
- len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
- return len;
+ seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+ return 0;
#endif /* CONFIG_APUS */
}
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index ff02b77b6..864fe1a78 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -28,6 +28,7 @@
#include <linux/threads.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -59,22 +60,19 @@ BUILD_SMP_INTERRUPT(mtrr_interrupt)
BUILD_SMP_INTERRUPT(spurious_interrupt)
#endif
-#if 0
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
- char *p = buf;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
+ seq_printf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_putc(p, '\n');
- for (i = 0 ; i < NR_IRQS ; i++)
- {
+ for (i = 0 ; i < NR_IRQS ; i++) {
if (ioinfo[i] == INVALID_STORAGE_AREA)
continue;
@@ -83,35 +81,33 @@ int get_irq_list(char *buf)
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
+ seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j=0; j<smp_num_cpus; j++)
- p += sprintf( p, "%10u ",
+ seq_printf( p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
- p += sprintf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
{
- p += sprintf(p, ", %s", action->name);
+ seq_printf(p, ", %s", action->name);
} /* endfor */
- *p++ = '\n';
+ seq_putc(p, '\n');
} /* endfor */
- p += sprintf(p, "NMI: %10u\n", nmi_counter);
+ seq_printf(p, "NMI: %10u\n", nmi_counter);
#ifdef CONFIG_SMP
- p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count));
+ seq_printf(p, "IPI: %10u\n", atomic_read(&ipi_count));
#endif
-
- return p - buf;
+ return 0;
}
-#endif
/*
* Global interrupt locks for SMP. Allow interrupts to come in on any
diff --git a/arch/s390x/kernel/irq.c b/arch/s390x/kernel/irq.c
index 92023c04b..25dcf173c 100644
--- a/arch/s390x/kernel/irq.c
+++ b/arch/s390x/kernel/irq.c
@@ -28,6 +28,7 @@
#include <linux/threads.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -59,19 +60,17 @@ BUILD_SMP_INTERRUPT(mtrr_interrupt)
BUILD_SMP_INTERRUPT(spurious_interrupt)
#endif
-#if 0
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
- char *p = buf;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
+ seq_printf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++)
{
@@ -83,35 +82,34 @@ int get_irq_list(char *buf)
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
+ seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
- p += sprintf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j=0; j<smp_num_cpus; j++)
- p += sprintf( p, "%10u ",
+ seq_printf( p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
- p += sprintf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
{
- p += sprintf(p, ", %s", action->name);
+ seq_printf(p, ", %s", action->name);
} /* endfor */
- *p++ = '\n';
+ seq_putc(p, '\n');
} /* endfor */
- p += sprintf(p, "NMI: %10u\n", nmi_counter);
+ seq_printf(p, "NMI: %10u\n", nmi_counter);
#ifdef CONFIG_SMP
- p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count));
+ seq_printf(p, "IPI: %10u\n", atomic_read(&ipi_count));
#endif
- return p - buf;
+ return 0;
}
-#endif
/*
* Global interrupt locks for SMP. Allow interrupts to come in on any
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 7f793dc4e..0986f51d3 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -27,6 +27,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -84,31 +85,30 @@ struct hw_interrupt_type no_irq_type = {
*/
#if defined(CONFIG_PROC_FS)
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
- char *p = buf;
- p += sprintf(p, " ");
+ seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "CPU%d ",j);
- *p++ = '\n';
+ seq_printf(p, "CPU%d ",j);
+ seq_putc(p, '\n');
for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
action = irq_desc[i].action;
if (!action)
continue;
- p += sprintf(p, "%3d: ",i);
- p += sprintf(p, "%10u ", kstat_irqs(i));
- p += sprintf(p, " %14s", irq_desc[i].handler->typename);
- p += sprintf(p, " %s", action->name);
+ seq_printf(p, "%3d: ",i);
+ seq_printf(p, "%10u ", kstat_irqs(i));
+ seq_printf(p, " %14s", irq_desc[i].handler->typename);
+ seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
- p += sprintf(p, ", %s", action->name);
- *p++ = '\n';
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
}
- return p - buf;
+ return 0;
}
#endif
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index aff8e18ef..3cc38e38a 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.113 2001-07-17 16:17:33 anton Exp $
+/* $Id: irq.c,v 1.114 2001-12-11 04:55:51 davem Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
@@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
+#include <linux/seq_file.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
@@ -97,42 +98,42 @@ struct irqaction *irq_action[NR_IRQS+1] = {
NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
};
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction * action;
#ifdef CONFIG_SMP
int j;
#endif
if (sparc_cpu_model == sun4d) {
- extern int sun4d_get_irq_list(char *);
+ extern int show_sun4d_interrupts(struct seq_file *, void *);
- return sun4d_get_irq_list(buf);
+ return show_sun4d_interrupts(p, v);
}
for (i = 0 ; i < (NR_IRQS+1) ; i++) {
action = *(i + irq_action);
if (!action)
continue;
- len += sprintf(buf+len, "%3d: ", i);
+ seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
- len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
- len += sprintf(buf+len, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
- len += sprintf(buf+len, " %c %s",
+ seq_printf(p, " %c %s",
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
void free_irq(unsigned int irq, void *dev_id)
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index aae91f90f..77abe1db6 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -1,4 +1,4 @@
-/* $Id: sun4d_irq.c,v 1.28 2001-07-17 16:17:33 anton Exp $
+/* $Id: sun4d_irq.c,v 1.29 2001-12-11 04:55:51 davem Exp $
* arch/sparc/kernel/sun4d_irq.c:
* SS1000/SC2000 interrupt handling.
*
@@ -20,6 +20,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
+#include <linux/seq_file.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
@@ -72,9 +73,9 @@ static int nsbi;
spinlock_t sun4d_imsk_lock = SPIN_LOCK_UNLOCKED;
#endif
-int sun4d_get_irq_list(char *buf)
+int show_sun4d_interrupts(struct seq_file *p, void *v)
{
- int i, j = 0, k = 0, len = 0, sbusl;
+ int i, j = 0, k = 0, sbusl;
struct irqaction * action;
#ifdef CONFIG_SMP
int x;
@@ -94,21 +95,21 @@ int sun4d_get_irq_list(char *buf)
}
continue;
}
-found_it: len += sprintf(buf+len, "%3d: ", i);
+found_it: seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
- len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (x = 0; x < smp_num_cpus; x++)
- len += sprintf(buf+len, "%10u ",
+ seq_printf(p, "%10u ",
kstat.irqs[cpu_logical_map(x)][i]);
#endif
- len += sprintf(buf+len, "%c %s",
+ seq_printf(p, "%c %s",
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
action = action->next;
for (;;) {
for (; action; action = action->next) {
- len += sprintf(buf+len, ",%s %s",
+ seq_printf(p, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
@@ -123,9 +124,9 @@ found_it: len += sprintf(buf+len, "%3d: ", i);
action = sbus_actions [(j << 5) + (sbusl << 2)].action;
}
}
- len += sprintf(buf+len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
void sun4d_free_irq(unsigned int irq, void *dev_id)
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index 28024a483..084d8a242 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -1,4 +1,4 @@
-/* $Id: iommu_common.c,v 1.6 2001-10-09 02:24:33 davem Exp $
+/* $Id: iommu_common.c,v 1.7 2001-12-11 04:55:51 davem Exp $
* iommu_common.c: UltraSparc SBUS/PCI common iommu code.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -66,7 +66,9 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
daddr = dma_sg->dma_address;
sglen = sg->length;
- sgaddr = (unsigned long) sg->address;
+ sgaddr = (unsigned long) (sg->address ?
+ sg->address :
+ page_address(sg->page) + sg->offset);
while (dlen > 0) {
unsigned long paddr;
@@ -116,7 +118,9 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
sg++;
if (--nents <= 0)
break;
- sgaddr = (unsigned long) sg->address;
+ sgaddr = (unsigned long) (sg->address ?
+ sg->address :
+ page_address(sg->page) + sg->offset);
sglen = sg->length;
}
if (dlen < 0) {
@@ -197,14 +201,18 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
unsigned long prev;
u32 dent_addr, dent_len;
- prev = (unsigned long) sg->address;
+ prev = (unsigned long) (sg->address ?
+ sg->address :
+ page_address(sg->page) + sg->offset);
prev += (unsigned long) (dent_len = sg->length);
- dent_addr = (u32) ((unsigned long)sg->address & (IO_PAGE_SIZE - 1UL));
+ dent_addr = (u32) (prev & (IO_PAGE_SIZE - 1UL));
while (--nents) {
unsigned long addr;
sg++;
- addr = (unsigned long) sg->address;
+ addr = (unsigned long) (sg->address ?
+ sg->address :
+ page_address(sg->page) + sg->offset);
if (! VCONTIG(prev, addr)) {
dma_sg->dma_address = dent_addr;
dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 87e2a4f78..003fad140 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.112 2001-11-16 00:04:54 kanoj Exp $
+/* $Id: irq.c,v 1.113 2001-12-11 04:55:51 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/kbd_ll.h>
#include <asm/ptrace.h>
@@ -106,9 +107,9 @@ static void register_irq_proc (unsigned int irq);
#define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff)
#define get_smpaff_in_irqaction(action) ((action)->mask)
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
{
- int i, len = 0;
+ int i;
struct irqaction *action;
#ifdef CONFIG_SMP
int j;
@@ -117,23 +118,23 @@ int get_irq_list(char *buf)
for(i = 0; i < (NR_IRQS + 1); i++) {
if(!(action = *(i + irq_action)))
continue;
- len += sprintf(buf + len, "%3d: ", i);
+ seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
- len += sprintf(buf + len, "%10u ", kstat_irqs(i));
+ seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
- len += sprintf(buf + len, "%10u ",
- kstat.irqs[cpu_logical_map(j)][i]);
+ seq_printf(p, "%10u ",
+ kstat.irqs[cpu_logical_map(j)][i]);
#endif
- len += sprintf(buf + len, " %s:%lx", action->name, \
- get_ino_in_irqaction(action));
+ seq_printf(p, " %s:%lx", action->name,
+ get_ino_in_irqaction(action));
for(action = action->next; action; action = action->next) {
- len += sprintf(buf+len, ", %s:%lx", action->name, \
- get_ino_in_irqaction(action));
+ seq_printf(p, ", %s:%lx", action->name,
+ get_ino_in_irqaction(action));
}
- len += sprintf(buf + len, "\n");
+ seq_putc(p, '\n');
}
- return len;
+ return 0;
}
/* Now these are always passed a true fully specified sun4u INO. */
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index e65bf1531..8b01365e0 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.56 2001-03-21 11:46:20 davem Exp $
+/* $Id: signal.c,v 1.57 2001-12-11 04:55:51 davem Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -17,6 +17,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/mm.h>
+#include <linux/tty.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 829b68777..8ba9fc4f6 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.70 2001-04-24 01:09:12 davem Exp $
+/* $Id: signal32.c,v 1.71 2001-12-11 04:55:51 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -16,6 +16,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/mm.h>
+#include <linux/tty.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index ecd930c9f..8071cec21 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.33 2001-09-18 22:29:06 davem Exp $
+/* $Id: misc.c,v 1.34 2001-12-11 04:55:51 davem Exp $
* misc.c: Miscelaneous syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -15,6 +15,7 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/timex.h>
+#include <linux/major.h>
#include <asm/uaccess.h>
#include <asm/string.h>
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index 73d735043..70c1969e3 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -1,4 +1,4 @@
-/* $Id: socksys.c,v 1.18 2001-02-13 01:16:44 davem Exp $
+/* $Id: socksys.c,v 1.19 2001-12-11 04:55:51 davem Exp $
* socksys.c: /dev/inet/ stuff for Solaris emulation.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -118,7 +118,6 @@ static int socksys_release(struct inode * inode, struct file * filp)
struct T_primsg *it;
/* XXX: check this */
- lock_kernel();
sock = (struct sol_socket_struct *)filp->private_data;
SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
it = sock->pfirst;
@@ -132,7 +131,6 @@ static int socksys_release(struct inode * inode, struct file * filp)
filp->private_data = NULL;
SOLDD(("socksys_release %016lx\n", sock));
mykfree((char*)sock);
- unlock_kernel();
return 0;
}
diff --git a/drivers/acorn/scsi/arxescsi.h b/drivers/acorn/scsi/arxescsi.h
index b95c9340a..bf083484a 100644
--- a/drivers/acorn/scsi/arxescsi.h
+++ b/drivers/acorn/scsi/arxescsi.h
@@ -61,7 +61,6 @@ eh_host_reset_handler: fas216_eh_host_reset, \
eh_bus_reset_handler: fas216_eh_bus_reset, \
eh_device_reset_handler: fas216_eh_device_reset, \
eh_abort_handler: fas216_eh_abort, \
-use_new_eh_code: 1 \
}
#ifndef HOSTS_C
diff --git a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c
index 1a049d345..c5a9ce6cc 100644
--- a/drivers/acorn/scsi/cumana_2.c
+++ b/drivers/acorn/scsi/cumana_2.c
@@ -575,7 +575,6 @@ static Scsi_Host_Template cumanascsi2_template = {
eh_bus_reset_handler: fas216_eh_bus_reset,
eh_device_reset_handler: fas216_eh_device_reset,
eh_abort_handler: fas216_eh_abort,
- use_new_eh_code: 1
};
static int __init cumanascsi2_init(void)
diff --git a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c
index f2c0c9fc0..bb19890ed 100644
--- a/drivers/acorn/scsi/eesox.c
+++ b/drivers/acorn/scsi/eesox.c
@@ -577,7 +577,6 @@ static Scsi_Host_Template eesox_template = {
eh_bus_reset_handler: fas216_eh_bus_reset,
eh_device_reset_handler: fas216_eh_device_reset,
eh_abort_handler: fas216_eh_abort,
- use_new_eh_code: 1
};
static int __init eesox_init(void)
diff --git a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c
index 97b1d07ce..06a3c3043 100644
--- a/drivers/acorn/scsi/powertec.c
+++ b/drivers/acorn/scsi/powertec.c
@@ -477,7 +477,6 @@ static Scsi_Host_Template powertecscsi_template = {
eh_bus_reset_handler: fas216_eh_bus_reset,
eh_device_reset_handler: fas216_eh_device_reset,
eh_abort_handler: fas216_eh_abort,
- use_new_eh_code: 1
};
static int __init powertecscsi_init(void)
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index f5ffef757..55d3fbe7e 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -30,6 +30,7 @@
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/blkpg.h>
#include <linux/interrupt.h>
@@ -306,9 +307,9 @@ static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
{
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&Controller->RequestQueue->queue_lock);
__wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&Controller->RequestQueue->queue_lock);
}
@@ -1922,76 +1923,6 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
/*
- DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver.
-*/
-
-static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue,
- IO_Request_T *Request,
- BufferHeader_T *BufferHeader,
- int MaxSegments)
-{
- DAC960_Controller_T *Controller =
- (DAC960_Controller_T *) RequestQueue->queuedata;
- if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data)
- return true;
- if (Request->nr_segments < MaxSegments &&
- Request->nr_segments < Controller->DriverScatterGatherLimit)
- {
- Request->nr_segments++;
- return true;
- }
- return false;
-}
-
-
-/*
- DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver.
-*/
-
-static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue,
- IO_Request_T *Request,
- BufferHeader_T *BufferHeader,
- int MaxSegments)
-{
- DAC960_Controller_T *Controller =
- (DAC960_Controller_T *) RequestQueue->queuedata;
- if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data)
- return true;
- if (Request->nr_segments < MaxSegments &&
- Request->nr_segments < Controller->DriverScatterGatherLimit)
- {
- Request->nr_segments++;
- return true;
- }
- return false;
-}
-
-
-/*
- DAC960_MergeRequestsFunction is the Merge Requests Function for the
- DAC960 driver.
-*/
-
-static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue,
- IO_Request_T *Request,
- IO_Request_T *NextRequest,
- int MaxSegments)
-{
- DAC960_Controller_T *Controller =
- (DAC960_Controller_T *) RequestQueue->queuedata;
- int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
- if (Request->bhtail->b_data + Request->bhtail->b_size
- == NextRequest->bh->b_data)
- TotalSegments--;
- if (TotalSegments > MaxSegments ||
- TotalSegments > Controller->DriverScatterGatherLimit)
- return false;
- Request->nr_segments = TotalSegments;
- return true;
-}
-
-
-/*
DAC960_RegisterBlockDevice registers the Block Device structures
associated with Controller.
*/
@@ -2016,14 +1947,13 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
*/
RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
blk_init_queue(RequestQueue, DAC960_RequestFunction);
- blk_queue_headactive(RequestQueue, 0);
- RequestQueue->back_merge_fn = DAC960_BackMergeFunction;
- RequestQueue->front_merge_fn = DAC960_FrontMergeFunction;
- RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction;
RequestQueue->queuedata = Controller;
+ RequestQueue->max_segments = Controller->DriverScatterGatherLimit;
+ RequestQueue->max_sectors = Controller->MaxBlocksPerCommand;
Controller->RequestQueue = RequestQueue;
/*
- Initialize the Max Sectors per Request array.
+ Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
+ array, and Max Sectors per Request array.
*/
for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
Controller->MaxSectorsPerRequest[MinorNumber] =
@@ -2031,7 +1961,6 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
Controller->GenericDiskInfo.part = Controller->DiskPartitions;
Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
blksize_size[MajorNumber] = Controller->BlockSizes;
- max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
/*
Initialize Read Ahead to 128 sectors.
*/
@@ -2080,9 +2009,7 @@ static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
*/
Controller->GenericDiskInfo.part = NULL;
Controller->GenericDiskInfo.sizes = NULL;
- blk_size[MajorNumber] = NULL;
- blksize_size[MajorNumber] = NULL;
- max_sectors[MajorNumber] = NULL;
+ blk_clear(MajorNumber);
/*
Remove the Generic Disk Information structure from the list.
*/
@@ -2813,23 +2740,24 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
while (BufferHeader != NULL)
{
- if (BufferHeader->b_data == LastDataEndPointer)
+ if (bio_data(BufferHeader) == LastDataEndPointer)
{
ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
- BufferHeader->b_size;
- LastDataEndPointer += BufferHeader->b_size;
+ bio_size(BufferHeader);
+ LastDataEndPointer += bio_size(BufferHeader);
}
else
{
ScatterGatherList[SegmentNumber].SegmentDataPointer =
- Virtual_to_Bus32(BufferHeader->b_data);
+ Virtual_to_Bus32(bio_data(BufferHeader));
ScatterGatherList[SegmentNumber].SegmentByteCount =
- BufferHeader->b_size;
- LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
+ bio_size(BufferHeader);
+ LastDataEndPointer = bio_data(BufferHeader) +
+ bio_size(BufferHeader);
if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
panic("DAC960: Scatter/Gather Segment Overflow\n");
}
- BufferHeader = BufferHeader->b_reqnext;
+ BufferHeader = BufferHeader->bi_next;
}
if (SegmentNumber != Command->SegmentCount)
panic("DAC960: SegmentNumber != SegmentCount\n");
@@ -2903,23 +2831,24 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
.ScatterGatherSegments;
while (BufferHeader != NULL)
{
- if (BufferHeader->b_data == LastDataEndPointer)
+ if (bio_data(BufferHeader) == LastDataEndPointer)
{
ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
- BufferHeader->b_size;
- LastDataEndPointer += BufferHeader->b_size;
+ bio_size(BufferHeader);
+ LastDataEndPointer += bio_size(BufferHeader);
}
else
{
ScatterGatherList[SegmentNumber].SegmentDataPointer =
- Virtual_to_Bus64(BufferHeader->b_data);
+ Virtual_to_Bus64(bio_data(BufferHeader));
ScatterGatherList[SegmentNumber].SegmentByteCount =
- BufferHeader->b_size;
- LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
+ bio_size(BufferHeader);
+ LastDataEndPointer = bio_data(BufferHeader) +
+ bio_size(BufferHeader);
if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
panic("DAC960: Scatter/Gather Segment Overflow\n");
}
- BufferHeader = BufferHeader->b_reqnext;
+ BufferHeader = BufferHeader->bi_next;
}
if (SegmentNumber != Command->SegmentCount)
panic("DAC960: SegmentNumber != SegmentCount\n");
@@ -2947,7 +2876,7 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
while (true)
{
if (list_empty(RequestQueueHead)) return false;
- Request = blkdev_entry_next_request(RequestQueueHead);
+ Request = elv_next_request(RequestQueue);
Command = DAC960_AllocateCommand(Controller);
if (Command != NULL) break;
if (!WaitForCommand) return false;
@@ -2958,12 +2887,10 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
else Command->CommandType = DAC960_WriteCommand;
Command->Completion = Request->waiting;
Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
- Command->BlockNumber =
- Request->sector
- + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
+ Command->BlockNumber = Request->sector;
Command->BlockCount = Request->nr_sectors;
Command->SegmentCount = Request->nr_segments;
- Command->BufferHeader = Request->bh;
+ Command->BufferHeader = Request->bio;
Command->RequestBuffer = Request->buffer;
blkdev_dequeue_request(Request);
blkdev_release_request(Request);
@@ -3016,8 +2943,10 @@ static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
boolean SuccessfulIO)
{
- blk_finished_io(BufferHeader->b_size >> 9);
- BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
+ if (SuccessfulIO)
+ set_bit(BIO_UPTODATE, &BufferHeader->bi_flags);
+ blk_finished_io(bio_sectors(BufferHeader));
+ BufferHeader->bi_end_io(BufferHeader);
}
@@ -3071,13 +3000,13 @@ static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber, Command->BlockNumber,
Command->BlockNumber + Command->BlockCount - 1);
- if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
+ if (DAC960_PartitionNumber(Command->BufferHeader->bi_dev) > 0)
DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber,
- DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
- Command->BufferHeader->b_rsector,
- Command->BufferHeader->b_rsector + Command->BlockCount - 1);
+ DAC960_PartitionNumber(Command->BufferHeader->bi_dev),
+ Command->BufferHeader->bi_sector,
+ Command->BufferHeader->bi_sector + Command->BlockCount - 1);
}
@@ -3104,8 +3033,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
*/
while (BufferHeader != NULL)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
DAC960_ProcessCompletedBuffer(BufferHeader, true);
BufferHeader = NextBufferHeader;
}
@@ -3119,7 +3048,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
CommandStatus == DAC960_V1_BadDataEncountered) &&
BufferHeader != NULL &&
- BufferHeader->b_reqnext != NULL)
+ BufferHeader->bi_next != NULL)
{
DAC960_V1_CommandMailbox_T *CommandMailbox =
&Command->V1.CommandMailbox;
@@ -3133,10 +3062,10 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->CommandType = DAC960_WriteRetryCommand;
CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
}
- Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
+ Command->BlockCount = bio_size(BufferHeader) >> DAC960_BlockSizeBits;
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.BusAddress =
- Virtual_to_Bus32(BufferHeader->b_data);
+ Virtual_to_Bus32(bio_data(BufferHeader));
DAC960_QueueCommand(Command);
return;
}
@@ -3149,8 +3078,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
*/
while (BufferHeader != NULL)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
DAC960_ProcessCompletedBuffer(BufferHeader, false);
BufferHeader = NextBufferHeader;
}
@@ -3164,8 +3093,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
/*
Perform completion processing for this single buffer.
*/
@@ -3182,14 +3111,14 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DAC960_V1_CommandMailbox_T *CommandMailbox =
&Command->V1.CommandMailbox;
Command->BlockNumber +=
- BufferHeader->b_size >> DAC960_BlockSizeBits;
+ bio_size(BufferHeader) >> DAC960_BlockSizeBits;
Command->BlockCount =
- NextBufferHeader->b_size >> DAC960_BlockSizeBits;
+ bio_size(NextBufferHeader) >> DAC960_BlockSizeBits;
Command->BufferHeader = NextBufferHeader;
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
CommandMailbox->Type5.BusAddress =
- Virtual_to_Bus32(NextBufferHeader->b_data);
+ Virtual_to_Bus32(bio_data(NextBufferHeader));
DAC960_QueueCommand(Command);
return;
}
@@ -3935,13 +3864,13 @@ static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber, Command->BlockNumber,
Command->BlockNumber + Command->BlockCount - 1);
- if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
+ if (DAC960_PartitionNumber(Command->BufferHeader->bi_dev) > 0)
DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber,
- DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
- Command->BufferHeader->b_rsector,
- Command->BufferHeader->b_rsector + Command->BlockCount - 1);
+ DAC960_PartitionNumber(Command->BufferHeader->bi_dev),
+ Command->BufferHeader->bi_sector,
+ Command->BufferHeader->bi_sector + Command->BlockCount - 1);
}
@@ -4210,8 +4139,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
*/
while (BufferHeader != NULL)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
DAC960_ProcessCompletedBuffer(BufferHeader, true);
BufferHeader = NextBufferHeader;
}
@@ -4225,19 +4154,19 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (Command->V2.RequestSense.SenseKey
== DAC960_SenseKey_MediumError &&
BufferHeader != NULL &&
- BufferHeader->b_reqnext != NULL)
+ BufferHeader->bi_next != NULL)
{
if (CommandType == DAC960_ReadCommand)
Command->CommandType = DAC960_ReadRetryCommand;
else Command->CommandType = DAC960_WriteRetryCommand;
- Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
+ Command->BlockCount = bio_size(BufferHeader) >> DAC960_BlockSizeBits;
CommandMailbox->SCSI_10.CommandControlBits
.AdditionalScatterGatherListMemory = false;
CommandMailbox->SCSI_10.DataTransferSize =
Command->BlockCount << DAC960_BlockSizeBits;
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0].SegmentDataPointer =
- Virtual_to_Bus64(BufferHeader->b_data);
+ Virtual_to_Bus64(bio_data(BufferHeader));
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0].SegmentByteCount =
CommandMailbox->SCSI_10.DataTransferSize;
@@ -4255,8 +4184,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
*/
while (BufferHeader != NULL)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
DAC960_ProcessCompletedBuffer(BufferHeader, false);
BufferHeader = NextBufferHeader;
}
@@ -4270,8 +4199,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
- BufferHeader->b_reqnext = NULL;
+ BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
+ BufferHeader->bi_next = NULL;
/*
Perform completion processing for this single buffer.
*/
@@ -4286,16 +4215,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
if (NextBufferHeader != NULL)
{
Command->BlockNumber +=
- BufferHeader->b_size >> DAC960_BlockSizeBits;
+ bio_size(BufferHeader) >> DAC960_BlockSizeBits;
Command->BlockCount =
- NextBufferHeader->b_size >> DAC960_BlockSizeBits;
+ bio_size(NextBufferHeader) >> DAC960_BlockSizeBits;
Command->BufferHeader = NextBufferHeader;
CommandMailbox->SCSI_10.DataTransferSize =
Command->BlockCount << DAC960_BlockSizeBits;
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(NextBufferHeader->b_data);
+ Virtual_to_Bus64(bio_data(NextBufferHeader));
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -5416,7 +5345,8 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
DiskGeometry_T Geometry, *UserGeometry;
DAC960_Controller_T *Controller;
- int PartitionNumber;
+ int res;
+
if (File != NULL && (File->f_flags & O_NONBLOCK))
return DAC960_UserIOCTL(Inode, File, Request, Argument);
if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
@@ -5465,61 +5395,27 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
LogicalDeviceInfo->ConfigurableDeviceSize
/ (Geometry.heads * Geometry.sectors);
}
- Geometry.start =
- Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
+ Geometry.start = get_start_sect(Inode->i_rdev);
return (copy_to_user(UserGeometry, &Geometry,
sizeof(DiskGeometry_T)) ? -EFAULT : 0);
case BLKGETSIZE:
- /* Get Device Size. */
- if ((unsigned long *) Argument == NULL) return -EINVAL;
- return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
- .nr_sects,
- (unsigned long *) Argument);
case BLKGETSIZE64:
- if ((u64 *) Argument == NULL) return -EINVAL;
- return put_user((u64) Controller->GenericDiskInfo
- .part[MINOR(Inode->i_rdev)]
- .nr_sects << 9,
- (u64 *) Argument);
case BLKRAGET:
case BLKRASET:
case BLKFLSBUF:
case BLKBSZGET:
case BLKBSZSET:
return blk_ioctl(Inode->i_rdev, Request, Argument);
+
case BLKRRPART:
/* Re-Read Partition Table. */
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
return -EBUSY;
- for (PartitionNumber = 0;
- PartitionNumber < DAC960_MaxPartitions;
- PartitionNumber++)
- {
- KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
- LogicalDriveNumber,
- PartitionNumber);
- int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
- PartitionNumber);
- if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
- continue;
- /*
- Flush all changes and invalidate buffered state.
- */
- invalidate_device(Device, 1);
- /*
- Clear existing partition sizes.
- */
- if (PartitionNumber > 0)
- {
- Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
- Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
- }
- /*
- Reset the Block Size so that the partition table can be read.
- */
- set_blocksize(Device, BLOCK_SIZE);
- }
+ res = wipe_partitions(Inode->i_rdev);
+ if (res) /* nothing */
+ return res;
+
DAC960_RegisterDisk(Controller, LogicalDriveNumber);
return 0;
}
@@ -5641,11 +5537,11 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
while (Controller->V1.DirectCommandActive[DCDB.Channel]
[DCDB.TargetID])
{
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&Controller->RequestQueue->queue_lock);
__wait_event(Controller->CommandWaitQueue,
!Controller->V1.DirectCommandActive
[DCDB.Channel][DCDB.TargetID]);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&Controller->RequestQueue->queue_lock);
}
Controller->V1.DirectCommandActive[DCDB.Channel]
[DCDB.TargetID] = true;
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 98a937f66..71e7db452 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2191,7 +2191,7 @@ static char
of the Linux Kernel and I/O Subsystem.
*/
-typedef struct buffer_head BufferHeader_T;
+typedef struct bio BufferHeader_T;
typedef struct file File_T;
typedef struct block_device_operations BlockDeviceOperations_T;
typedef struct completion Completion_T;
@@ -2475,7 +2475,6 @@ typedef struct DAC960_Controller
DiskPartition_T DiskPartitions[DAC960_MinorCount];
int PartitionSizes[DAC960_MinorCount];
int BlockSizes[DAC960_MinorCount];
- int MaxSectorsPerRequest[DAC960_MinorCount];
unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
unsigned char UserStatusBuffer[DAC960_UserMessageSize];
}
@@ -2509,7 +2508,7 @@ static inline
void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+ spin_lock_irqsave(&Controller->RequestQueue->queue_lock, *ProcessorFlags);
}
@@ -2521,13 +2520,13 @@ static inline
void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+ spin_unlock_irqrestore(&Controller->RequestQueue->queue_lock, *ProcessorFlags);
}
/*
DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
- but is only called from the request function with the io_request_lock held.
+ but is only called from the request function with the queue lock held.
*/
static inline
@@ -2539,7 +2538,7 @@ void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
/*
DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
- but is only called from the request function with the io_request_lock held.
+ but is only called from the request function with the queue lock held.
*/
static inline
@@ -2558,7 +2557,7 @@ static inline
void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+ spin_lock_irqsave(&Controller->RequestQueue->queue_lock, *ProcessorFlags);
}
@@ -2571,7 +2570,7 @@ static inline
void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+ spin_unlock_irqrestore(&Controller->RequestQueue->queue_lock, *ProcessorFlags);
}
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 04fb8fe66..d072654f1 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -10,9 +10,9 @@
O_TARGET := block.o
-export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o
+export-objs := elevator.o ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o block_ioctl.o
-obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o
+obj-y := elevator.o ll_rw_blk.o blkpg.o genhd.o block_ioctl.o
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 4975d1b2c..916a192e5 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -1011,7 +1011,6 @@ static void redo_acsi_request( void )
goto repeat;
}
- block += acsi_part[dev].start_sect;
target = acsi_info[DEVICE_NR(dev)].target;
lun = acsi_info[DEVICE_NR(dev)].lun;
@@ -1123,7 +1122,7 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
put_user( 64, &geo->heads );
put_user( 32, &geo->sectors );
put_user( acsi_info[dev].size >> 11, &geo->cylinders );
- put_user( acsi_part[MINOR(inode->i_rdev)].start_sect, &geo->start );
+ put_user(get_start_sect(inode->i_rdev), &geo->start);
return 0;
}
@@ -1852,7 +1851,7 @@ static int revalidate_acsidisk( int dev, int maxusage )
{
int device;
struct gendisk * gdev;
- int max_p, start, i;
+ int res;
struct acsi_info_struct *aip;
device = DEVICE_NR(MINOR(dev));
@@ -1867,16 +1866,7 @@ static int revalidate_acsidisk( int dev, int maxusage )
DEVICE_BUSY = 1;
sti();
- max_p = gdev->max_p;
- start = device << gdev->minor_shift;
-
- for( i = max_p - 1; i >= 0 ; i-- ) {
- if (gdev->part[start + i].nr_sects != 0) {
- invalidate_device(MKDEV(MAJOR_NR, start + i), 1);
- gdev->part[start + i].nr_sects = 0;
- }
- gdev->part[start+i].start_sect = 0;
- };
+ res = wipe_partitions(dev);
stdma_lock( NULL, NULL );
@@ -1891,12 +1881,13 @@ static int revalidate_acsidisk( int dev, int maxusage )
ENABLE_IRQ();
stdma_release();
-
- grok_partitions(gdev, device, (aip->type==HARDDISK)?1<<4:1, aip->size);
+
+ if (!res)
+ grok_partitions(dev, aip->size);
DEVICE_BUSY = 0;
wake_up(&busy_wait);
- return 0;
+ return res;
}
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 3788073c6..59ceb6203 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -121,8 +121,8 @@ static char slmmselect_cmd[6] = { 0x15, 0, 0, 0, 0, 0 };
static struct slm {
unsigned target; /* target number */
unsigned lun; /* LUN in target controller */
- unsigned wbusy : 1; /* output part busy */
- unsigned rbusy : 1; /* status part busy */
+ atomic_t wr_ok; /* set to 0 if output part busy */
+ atomic_t rd_ok; /* set to 0 if status part busy */
} slm_info[MAX_SLM];
int N_SLM_Printers = 0;
@@ -778,15 +778,17 @@ static int slm_open( struct inode *inode, struct file *file )
if (file->f_mode & 2) {
/* open for writing is exclusive */
- if (sip->wbusy)
+ if ( !atomic_dec_and_test(&sip->wr_ok) ) {
+ atomic_inc(&sip->wr_ok);
return( -EBUSY );
- sip->wbusy = 1;
+ }
}
if (file->f_mode & 1) {
- /* open for writing is exclusive */
- if (sip->rbusy)
- return( -EBUSY );
- sip->rbusy = 1;
+ /* open for reading is exclusive */
+ if ( !atomic_dec_and_test(&sip->rd_ok) ) {
+ atomic_inc(&sip->rd_ok);
+ return( -EBUSY );
+ }
}
return( 0 );
@@ -801,12 +803,10 @@ static int slm_release( struct inode *inode, struct file *file )
device = MINOR(inode->i_rdev);
sip = &slm_info[device];
- lock_kernel();
if (file->f_mode & 2)
- sip->wbusy = 0;
+ atomic_inc( &sip->wr_ok );
if (file->f_mode & 1)
- sip->rbusy = 0;
- unlock_kernel();
+ atomic_inc( &sip->rd_ok );
return( 0 );
}
@@ -983,8 +983,8 @@ int attach_slm( int target, int lun )
slm_info[N_SLM_Printers].target = target;
slm_info[N_SLM_Printers].lun = lun;
- slm_info[N_SLM_Printers].wbusy = 0;
- slm_info[N_SLM_Printers].rbusy = 0;
+ atomic_set(&slm_info[N_SLM_Printers].wr_ok, 1 );
+ atomic_set(&slm_info[N_SLM_Printers].rd_ok, 1 );
printk( KERN_INFO " Printer: %s\n", SLMBuffer );
printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 068b1f5c4..45d30ce45 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1895,10 +1895,9 @@ void cleanup_module(void)
free_irq(IRQ_AMIGA_DSKBLK, NULL);
custom.dmacon = DMAF_DISK; /* disable DMA */
amiga_chip_free(raw_buf);
- blk_size[MAJOR_NR] = NULL;
- blksize_size[MAJOR_NR] = NULL;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR, "fd");
+ blk_clear(MAJOR_NR);
}
#endif
diff --git a/drivers/block/blkpg.c b/drivers/block/blkpg.c
index 8ffecbb3d..579e2513b 100644
--- a/drivers/block/blkpg.c
+++ b/drivers/block/blkpg.c
@@ -63,7 +63,8 @@
* or has the same number as an existing one
* 0: all OK.
*/
-int add_partition(kdev_t dev, struct blkpg_partition *p) {
+int add_partition(kdev_t dev, struct blkpg_partition *p)
+{
struct gendisk *g;
long long ppstart, pplength;
long pstart, plength;
@@ -123,7 +124,8 @@ int add_partition(kdev_t dev, struct blkpg_partition *p) {
*
* Note that the dev argument refers to the entire disk, not the partition.
*/
-int del_partition(kdev_t dev, struct blkpg_partition *p) {
+int del_partition(kdev_t dev, struct blkpg_partition *p)
+{
struct gendisk *g;
kdev_t devp;
int drive, first_minor, minor;
@@ -192,16 +194,21 @@ int blkpg_ioctl(kdev_t dev, struct blkpg_ioctl_arg *arg)
/*
* Common ioctl's for block devices
*/
-
+extern int block_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg);
int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
{
+ request_queue_t *q;
struct gendisk *g;
u64 ullval = 0;
- int intval;
+ int intval, *iptr;
if (!dev)
return -EINVAL;
+ intval = block_ioctl(dev, cmd, arg);
+ if (intval != -ENOTTY)
+ return intval;
+
switch (cmd) {
case BLKROSET:
if (!capable(CAP_SYS_ADMIN))
@@ -226,8 +233,26 @@ int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
return -EINVAL;
return put_user(read_ahead[MAJOR(dev)], (long *) arg);
+ case BLKFRASET:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (!(iptr = max_readahead[MAJOR(dev)]))
+ return -EINVAL;
+ iptr[MINOR(dev)] = arg;
+ return 0;
+
+ case BLKFRAGET:
+ if (!(iptr = max_readahead[MAJOR(dev)]))
+ return -EINVAL;
+ return put_user(iptr[MINOR(dev)], (long *) arg);
+
+ case BLKSECTGET:
+ if ((q = blk_get_queue(dev)))
+ return put_user(q->max_sectors, (unsigned short *)arg);
+ return -EINVAL;
+
case BLKFLSBUF:
- if(!capable(CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN))
return -EACCES;
fsync_dev(dev);
invalidate_buffers(dev);
@@ -246,8 +271,7 @@ int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
if (cmd == BLKGETSIZE)
return put_user((unsigned long)ullval, (unsigned long *)arg);
- else
- return put_user(ullval, (u64 *)arg);
+ return put_user(ullval, (u64 *)arg);
#if 0
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN))
@@ -258,34 +282,34 @@ int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
case BLKPG:
return blkpg_ioctl(dev, (struct blkpg_ioctl_arg *) arg);
+ /*
+ * deprecated, use the /proc/iosched interface instead
+ */
case BLKELVGET:
- return blkelvget_ioctl(&blk_get_queue(dev)->elevator,
- (blkelv_ioctl_arg_t *) arg);
case BLKELVSET:
- return blkelvset_ioctl(&blk_get_queue(dev)->elevator,
- (blkelv_ioctl_arg_t *) arg);
+ return -ENOTTY;
case BLKBSZGET:
/* get the logical block size (cf. BLKSSZGET) */
intval = BLOCK_SIZE;
if (blksize_size[MAJOR(dev)])
intval = blksize_size[MAJOR(dev)][MINOR(dev)];
- return put_user (intval, (int *) arg);
+ return put_user(intval, (int *) arg);
case BLKBSZSET:
/* set the logical block size */
- if (!capable (CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!dev || !arg)
+ if (!arg)
return -EINVAL;
- if (get_user (intval, (int *) arg))
+ if (get_user(intval, (int *) arg))
return -EFAULT;
if (intval > PAGE_SIZE || intval < 512 ||
(intval & (intval - 1)))
return -EINVAL;
- if (is_mounted (dev) || is_swap_partition (dev))
+ if (is_mounted(dev) || is_swap_partition(dev))
return -EBUSY;
- set_blocksize (dev, intval);
+ set_blocksize(dev, intval);
return 0;
default:
diff --git a/drivers/block/block_ioctl.c b/drivers/block/block_ioctl.c
new file mode 100644
index 000000000..a89488848
--- /dev/null
+++ b/drivers/block/block_ioctl.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
+ *
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/locks.h>
+#include <linux/swap.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/module.h>
+#include <linux/blk.h>
+
+#include <linux/cdrom.h>
+
+int blk_do_rq(request_queue_t *q, struct request *rq)
+{
+ DECLARE_COMPLETION(wait);
+ int err = 0;
+
+ rq->flags |= REQ_BARRIER;
+ rq->waiting = &wait;
+ elv_add_request(q, rq, 1);
+ generic_unplug_device(q);
+ wait_for_completion(&wait);
+
+ /*
+ * for now, never retry anything
+ */
+ if (rq->errors)
+ err = -EIO;
+
+ return err;
+}
+
+int block_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
+{
+ request_queue_t *q;
+ struct request *rq;
+ int close = 0, err;
+
+ q = blk_get_queue(dev);
+ if (!q)
+ return -ENXIO;
+
+ switch (cmd) {
+ case CDROMCLOSETRAY:
+ close = 1;
+ case CDROMEJECT:
+ rq = blk_get_request(q, WRITE, __GFP_WAIT);
+ rq->flags = REQ_BLOCK_PC;
+ memset(rq->cmd, 0, sizeof(rq->cmd));
+ rq->cmd[0] = GPCMD_START_STOP_UNIT;
+ rq->cmd[4] = 0x02 + (close != 0);
+ err = blk_do_rq(q, rq);
+ blk_put_request(rq);
+ break;
+ default:
+ err = -ENOTTY;
+ }
+
+ return err;
+}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 14fbe6ffb..371755761 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -84,7 +84,7 @@ static struct board_type products[] = {
#define MAX_CONFIG_WAIT 1000
#define READ_AHEAD 128
-#define NR_CMDS 128 /* #commands that can be outstanding */
+#define NR_CMDS 384 /* #commands that can be outstanding */
#define MAX_CTLR 8
#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
@@ -147,7 +147,6 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
" IRQ: %d\n"
" Logical drives: %d\n"
" Current Q depth: %d\n"
- " Current # commands on controller %d\n"
" Max Q depth since init: %d\n"
" Max # commands on controller since init: %d\n"
" Max SG entries since init: %d\n\n",
@@ -158,8 +157,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
(unsigned long)h->vaddr,
(unsigned int)h->intr,
h->num_luns,
- h->Qdepth, h->commands_outstanding,
- h->maxQsinceinit, h->max_outstanding, h->maxSG);
+ h->Qdepth, h->maxQsinceinit, h->max_outstanding, h->maxSG);
pos += size; len += size;
for(i=0; i<h->num_luns; i++) {
@@ -237,7 +235,7 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
if (i == NR_CMDS)
return NULL;
- } while(test_and_set_bit(i%32, h->cmd_pool_bits+(i/32)) != 0);
+ } while(test_and_set_bit(i & 31, h->cmd_pool_bits+(i/32)) != 0);
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
#endif
@@ -308,13 +306,10 @@ static void cciss_geninit( int ctlr)
/* for each partition */
for(j=0; j<MAX_PART; j++)
- {
hba[ctlr]->blocksizes[(i<<NWD_SHIFT) + j] = 1024;
- hba[ctlr]->hardsizes[ (i<<NWD_SHIFT) + j] =
- drv->block_size;
- }
hba[ctlr]->gendisk.nr_real++;
+ (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size;
}
}
/*
@@ -377,8 +372,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
{
int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT;
- int diskinfo[4];
- struct hd_geometry *geo = (struct hd_geometry *)arg;
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
@@ -386,6 +379,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
switch(cmd) {
case HDIO_GETGEO:
+ {
+ struct hd_geometry *geo = (struct hd_geometry *)arg;
+ int diskinfo[4];
+
if (hba[ctlr]->drv[dsk].cylinders) {
diskinfo[0] = hba[ctlr]->drv[dsk].heads;
diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
@@ -393,20 +390,18 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
} else {
diskinfo[0] = 0xff;
diskinfo[1] = 0x3f;
- diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); }
+ diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);
+ }
put_user(diskinfo[0], &geo->heads);
put_user(diskinfo[1], &geo->sectors);
put_user(diskinfo[2], &geo->cylinders);
- put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect, &geo->start);
- return 0;
- case BLKGETSIZE:
- put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
- return 0;
- case BLKGETSIZE64:
- put_user((u64)hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects << 9, (u64*)arg);
+ put_user(get_start_sect(inode->i_rdev), &geo->start);
return 0;
+ }
case BLKRRPART:
return revalidate_logvol(inode->i_rdev, 1);
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKFLSBUF:
case BLKBSZSET:
case BLKBSZGET:
@@ -415,9 +410,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case BLKRASET:
case BLKRAGET:
case BLKPG:
- case BLKELVGET:
- case BLKELVSET:
- return( blk_ioctl(inode->i_rdev, cmd, arg));
+ return blk_ioctl(inode->i_rdev, cmd, arg);
case CCISS_GETPCIINFO:
{
cciss_pci_info_struct pciinfo;
@@ -459,16 +452,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
// printk("cciss_ioctl: delay and count cannot be 0\n");
return( -EINVAL);
}
- spin_lock_irqsave(&io_request_lock, flags);
- /* Can only safely update if no commands outstanding */
- if (c->commands_outstanding > 0 )
- {
-// printk("cciss_ioctl: cannot change coalasing "
-// "%d commands outstanding on controller\n",
-// c->commands_outstanding);
- spin_unlock_irqrestore(&io_request_lock, flags);
- return(-EINVAL);
- }
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* Update the field, and then ring the doorbell */
writel( intinfo.delay,
&(c->cfgtable->HostWrite.CoalIntDelay));
@@ -484,7 +468,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* delay and try again */
udelay(1000);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
if (i >= MAX_CONFIG_WAIT)
return( -EFAULT);
return(0);
@@ -515,7 +499,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if (copy_from_user(NodeName, (void *) arg, sizeof( NodeName_type)))
return -EFAULT;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* Update the field, and then ring the doorbell */
for(i=0;i<16;i++)
@@ -531,7 +515,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* delay and try again */
udelay(1000);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
if (i >= MAX_CONFIG_WAIT)
return( -EFAULT);
return(0);
@@ -658,11 +642,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
c->SG[0].Ext = 0; // we are not chaining
}
/* Put the request on the tail of the request queue */
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
addQ(&h->reqQ, c);
h->Qdepth++;
start_io(h);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
/* Wait for completion */
while(c->cmd_type != CMD_IOCTL_DONE)
@@ -710,42 +694,32 @@ static int revalidate_logvol(kdev_t dev, int maxusage)
int ctlr, target;
struct gendisk *gdev;
unsigned long flags;
- int max_p;
- int start;
- int i;
+ int res;
target = MINOR(dev) >> NWD_SHIFT;
ctlr = MAJOR(dev) - MAJOR_NR;
gdev = &(hba[ctlr]->gendisk);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (hba[ctlr]->drv[target].usage_count > maxusage) {
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
printk(KERN_WARNING "cciss: Device busy for "
"revalidation (usage=%d)\n",
hba[ctlr]->drv[target].usage_count);
return -EBUSY;
}
hba[ctlr]->drv[target].usage_count++;
- spin_unlock_irqrestore(&io_request_lock, flags);
-
- max_p = gdev->max_p;
- start = target << gdev->minor_shift;
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- for(i=max_p-1; i>=0; i--) {
- int minor = start+i;
- invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
- gdev->part[minor].start_sect = 0;
- gdev->part[minor].nr_sects = 0;
+ res = wipe_partitions(dev);
+ if (res)
+ goto leave;
- /* reset the blocksize so we can read the partition table */
- blksize_size[MAJOR_NR+ctlr][minor] = 1024;
- }
/* setup partitions per disk */
- grok_partitions(gdev, target, MAX_PART,
- hba[ctlr]->drv[target].nr_blocks);
+ grok_partitions(dev, hba[ctlr]->drv[target].nr_blocks);
+leave:
hba[ctlr]->drv[target].usage_count--;
- return 0;
+ return res;
}
static int frevalidate_logvol(kdev_t dev)
@@ -776,15 +750,15 @@ static int revalidate_allvol(kdev_t dev)
if (MINOR(dev) != 0)
return -ENXIO;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (hba[ctlr]->usage_count > 1) {
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
printk(KERN_WARNING "cciss: Device busy for volume"
" revalidation (usage=%d)\n", hba[ctlr]->usage_count);
return -EBUSY;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
hba[ctlr]->usage_count++;
+ spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
/*
* Set the partition and block size structures for all volumes
@@ -793,7 +767,6 @@ static int revalidate_allvol(kdev_t dev)
memset(hba[ctlr]->hd, 0, sizeof(struct hd_struct) * 256);
memset(hba[ctlr]->sizes, 0, sizeof(int) * 256);
memset(hba[ctlr]->blocksizes, 0, sizeof(int) * 256);
- memset(hba[ctlr]->hardsizes, 0, sizeof(int) * 256);
memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct)
* CISS_MAX_LUN);
hba[ctlr]->gendisk.nr_real = 0;
@@ -1089,11 +1062,11 @@ static void start_io( ctlr_info_t *h)
while(( c = h->reqQ) != NULL )
{
/* can't do anything if fifo is full */
- if ((h->access.fifo_full(h)))
- {
- printk(KERN_WARNING "cciss: fifo full \n");
- return;
+ if ((h->access.fifo_full(h))) {
+ printk(KERN_WARNING "cciss: fifo full\n");
+ break;
}
+
/* Get the frist entry from the Request Q */
removeQ(&(h->reqQ), c);
h->Qdepth--;
@@ -1106,18 +1079,18 @@ static void start_io( ctlr_info_t *h)
}
}
-static inline void complete_buffers( struct buffer_head *bh, int status)
+static inline void complete_buffers(struct bio *bio, int status)
{
- struct buffer_head *xbh;
-
- while(bh)
- {
- xbh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- blk_finished_io(bh->b_size >> 9);
- bh->b_end_io(bh, status);
- bh = xbh;
+ while (bio) {
+ int nsecs = bio_sectors(bio);
+
+ struct bio *xbh = bio->bi_next;
+ bio->bi_next = NULL;
+ blk_finished_io(nsecs);
+ bio_endio(bio, status, nsecs);
+ bio = xbh;
}
+
}
/* checks the status of the job and calls complete buffers to mark all
* buffers for the completed job.
@@ -1135,7 +1108,7 @@ static inline void complete_command( CommandList_struct *cmd, int timeout)
{
temp64.val32.lower = cmd->SG[i].Addr.lower;
temp64.val32.upper = cmd->SG[i].Addr.upper;
- pci_unmap_single(hba[cmd->ctlr]->pdev,
+ pci_unmap_page(hba[cmd->ctlr]->pdev,
temp64.val, cmd->SG[i].Len,
(cmd->Request.Type.Direction == XFER_READ) ?
PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
@@ -1214,83 +1187,38 @@ static inline void complete_command( CommandList_struct *cmd, int timeout)
status=0;
}
}
- complete_buffers(cmd->rq->bh, status);
+
+ complete_buffers(cmd->rq->bio, status);
#ifdef CCISS_DEBUG
printk("Done with %p\n", cmd->rq);
#endif /* CCISS_DEBUG */
- end_that_request_last(cmd->rq);
-}
-
-
-static inline int cpq_new_segment(request_queue_t *q, struct request *rq,
- int max_segments)
-{
- if (rq->nr_segments < MAXSGENTRIES) {
- rq->nr_segments++;
- return 1;
- }
- return 0;
-}
-static int cpq_back_merge_fn(request_queue_t *q, struct request *rq,
- struct buffer_head *bh, int max_segments)
-{
- if (rq->bhtail->b_data + rq->bhtail->b_size == bh->b_data)
- return 1;
- return cpq_new_segment(q, rq, max_segments);
-}
-
-static int cpq_front_merge_fn(request_queue_t *q, struct request *rq,
- struct buffer_head *bh, int max_segments)
-{
- if (bh->b_data + bh->b_size == rq->bh->b_data)
- return 1;
- return cpq_new_segment(q, rq, max_segments);
-}
-
-static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq,
- struct request *nxt, int max_segments)
-{
- int total_segments = rq->nr_segments + nxt->nr_segments;
-
- if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data)
- total_segments--;
-
- if (total_segments > MAXSGENTRIES)
- return 0;
-
- rq->nr_segments = total_segments;
- return 1;
+ end_that_request_last(cmd->rq);
}
/*
* Get a request and submit it to the controller.
- * Currently we do one request at a time. Ideally we would like to send
- * everything to the controller on the first call, but there is a danger
- * of holding the io_request_lock for to long.
*/
static void do_cciss_request(request_queue_t *q)
{
ctlr_info_t *h= q->queuedata;
CommandList_struct *c;
int log_unit, start_blk, seg;
- char *lastdataend;
- struct buffer_head *bh;
struct list_head *queue_head = &q->queue_head;
struct request *creq;
u64bit temp64;
- struct my_sg tmp_sg[MAXSGENTRIES];
- int i;
+ struct scatterlist tmp_sg[MAXSGENTRIES];
+ int i, dir;
- if (q->plugged)
+ if (blk_queue_plugged(q))
goto startio;
-queue_next:
+queue:
if (list_empty(queue_head))
goto startio;
- creq = blkdev_entry_next_request(queue_head);
+ creq = elv_next_request(q);
if (creq->nr_segments > MAXSGENTRIES)
BUG();
@@ -1299,7 +1227,7 @@ queue_next:
printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
h->ctlr, creq->rq_dev, creq);
blkdev_dequeue_request(creq);
- complete_buffers(creq->bh, 0);
+ complete_buffers(creq->bio, 0);
end_that_request_last(creq);
goto startio;
}
@@ -1309,10 +1237,9 @@ queue_next:
blkdev_dequeue_request(creq);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
- c->cmd_type = CMD_RWREQ;
- bh = creq->bh;
+ c->cmd_type = CMD_RWREQ;
c->rq = creq;
/* fill in the request */
@@ -1325,44 +1252,29 @@ queue_next:
c->Request.Type.Type = TYPE_CMD; // It is a command.
c->Request.Type.Attribute = ATTR_SIMPLE;
c->Request.Type.Direction =
- (creq->cmd == READ) ? XFER_READ: XFER_WRITE;
+ (rq_data_dir(creq) == READ) ? XFER_READ: XFER_WRITE;
c->Request.Timeout = 0; // Don't time out
- c->Request.CDB[0] = (creq->cmd == READ) ? CCISS_READ : CCISS_WRITE;
- start_blk = hba[h->ctlr]->hd[MINOR(creq->rq_dev)].start_sect + creq->sector;
+ c->Request.CDB[0] = (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE;
+ start_blk = creq->sector;
#ifdef CCISS_DEBUG
- if (bh == NULL)
- panic("cciss: bh== NULL?");
printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",(int) creq->sector,
(int) creq->nr_sectors);
#endif /* CCISS_DEBUG */
- seg = 0;
- lastdataend = NULL;
- while(bh)
- {
- if (bh->b_data == lastdataend)
- { // tack it on to the last segment
- tmp_sg[seg-1].len +=bh->b_size;
- lastdataend += bh->b_size;
- } else
- {
- if (seg == MAXSGENTRIES)
- BUG();
- tmp_sg[seg].len = bh->b_size;
- tmp_sg[seg].start_addr = bh->b_data;
- lastdataend = bh->b_data + bh->b_size;
- seg++;
- }
- bh = bh->b_reqnext;
- }
+
+ seg = blk_rq_map_sg(q, creq, tmp_sg);
+
/* get the DMA records for the setup */
+ if (c->Request.Type.Direction == XFER_READ)
+ dir = PCI_DMA_FROMDEVICE;
+ else
+ dir = PCI_DMA_TODEVICE;
+
for (i=0; i<seg; i++)
{
- c->SG[i].Len = tmp_sg[i].len;
- temp64.val = (__u64) pci_map_single( h->pdev,
- tmp_sg[i].start_addr,
- tmp_sg[i].len,
- (c->Request.Type.Direction == XFER_READ) ?
- PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ c->SG[i].Len = tmp_sg[i].length;
+ temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+ tmp_sg[i].offset, tmp_sg[i].length,
+ dir);
c->SG[i].Addr.lower = temp64.val32.lower;
c->SG[i].Addr.upper = temp64.val32.upper;
c->SG[i].Ext = 0; // we are not chaining
@@ -1386,14 +1298,14 @@ queue_next:
c->Request.CDB[8]= creq->nr_sectors & 0xff;
c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
addQ(&(h->reqQ),c);
h->Qdepth++;
if(h->Qdepth > h->maxQsinceinit)
h->maxQsinceinit = h->Qdepth;
- goto queue_next;
+ goto queue;
startio:
start_io(h);
}
@@ -1414,7 +1326,7 @@ static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
* If there are completed commands in the completion queue,
* we had better do something about it.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
while( h->access.intr_pending(h))
{
while((a = h->access.command_completed(h)) != FIFO_EMPTY)
@@ -1447,11 +1359,12 @@ static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
}
}
}
+
/*
* See if we can queue up some more IO
*/
do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
}
/*
* We cannot read the structure directly, for portablity we must use
@@ -1873,7 +1786,18 @@ static int __init cciss_init_one(struct pci_dev *pdev,
sprintf(hba[i]->devname, "cciss%d", i);
hba[i]->ctlr = i;
hba[i]->pdev = pdev;
-
+
+ /* configure PCI DMA stuff */
+ if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff))
+ printk("cciss: using DAC cycles\n");
+ else if (!pci_set_dma_mask(pdev, 0xffffffff))
+ printk("cciss: not using DAC cycles\n");
+ else {
+ printk("cciss: no suitable DMA available\n");
+ free_hba(i);
+ return -ENODEV;
+ }
+
if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))
{
printk(KERN_ERR "cciss: Unable to get major number "
@@ -1943,19 +1867,14 @@ static int __init cciss_init_one(struct pci_dev *pdev,
q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
q->queuedata = hba[i];
blk_init_queue(q, do_cciss_request);
- blk_queue_headactive(q, 0);
+ blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
+ blk_queue_max_segments(q, MAXSGENTRIES);
+ blk_queue_max_sectors(q, 512);
/* fill in the other Kernel structs */
blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
- hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
read_ahead[MAJOR_NR+i] = READ_AHEAD;
- /* Set the pointers to queue functions */
- q->back_merge_fn = cpq_back_merge_fn;
- q->front_merge_fn = cpq_front_merge_fn;
- q->merge_requests_fn = cpq_merge_requests_fn;
-
-
/* Fill in the gendisk data */
hba[i]->gendisk.major = MAJOR_NR + i;
hba[i]->gendisk.major_name = "cciss";
@@ -2004,12 +1923,11 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
remove_proc_entry(hba[i]->devname, proc_cciss);
-
/* remove it from the disk list */
del_gendisk(&(hba[i]->gendisk));
- pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
- hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
+ pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
kfree(hba[i]->cmd_pool_bits);
@@ -2017,32 +1935,31 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
}
static struct pci_driver cciss_pci_driver = {
- name: "cciss",
- probe: cciss_init_one,
- remove: __devexit_p(cciss_remove_one),
- id_table: cciss_pci_device_id, /* id_table */
+ name: "cciss",
+ probe: cciss_init_one,
+ remove: cciss_remove_one,
+ id_table: cciss_pci_device_id, /* id_table */
};
/*
-* This is it. Register the PCI driver information for the cards we control
-* the OS will call our registered routines when it finds one of our cards.
-*/
+ * This is it. Register the PCI driver information for the cards we control
+ * the OS will call our registered routines when it finds one of our cards.
+ */
int __init cciss_init(void)
{
-
printk(KERN_INFO DRIVER_NAME "\n");
+
/* Register for out PCI devices */
if (pci_register_driver(&cciss_pci_driver) > 0 )
return 0;
else
return -ENODEV;
- }
+}
EXPORT_NO_SYMBOLS;
static int __init init_cciss_module(void)
{
-
return ( cciss_init());
}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index cb5dcc20b..357088d21 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -15,11 +15,6 @@
#define MAJOR_NR COMPAQ_CISS_MAJOR
-struct my_sg {
- int len;
- char *start_addr;
-};
-
struct ctlr_info;
typedef struct ctlr_info ctlr_info_t;
@@ -85,9 +80,8 @@ struct ctlr_info
struct gendisk gendisk;
// indexed by minor numbers
struct hd_struct hd[256];
- int sizes[256];
+ int sizes[256];
int blocksizes[256];
- int hardsizes[256];
};
/* Defining the diffent access_menthods */
@@ -247,5 +241,8 @@ struct board_type {
char *product_name;
struct access_method *access;
};
+
+#define CCISS_LOCK(i) (&((BLK_DEFAULT_QUEUE(MAJOR_NR + i))->queue_lock))
+
#endif /* CCISS_H */
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index 7faf6f05c..544b047c5 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -7,7 +7,7 @@
//general boundary defintions
#define SENSEINFOBYTES 32//note that this value may vary between host implementations
-#define MAXSGENTRIES 31
+#define MAXSGENTRIES 32
#define MAXREPLYQS 256
//Command Status value
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index da76b0bc7..4ff77277d 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -100,7 +100,6 @@ static struct board_type products[] = {
static struct hd_struct * ida;
static int * ida_sizes;
static int * ida_blocksizes;
-static int * ida_hardsizes;
static struct gendisk ida_gendisk[MAX_CTLR];
static struct proc_dir_entry *proc_array;
@@ -145,7 +144,7 @@ static void start_io(ctlr_info_t *h);
static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
-static inline void complete_buffers(struct buffer_head *bh, int ok);
+static inline void complete_buffers(struct bio *bio, int ok);
static inline void complete_command(cmdlist_t *cmd, int timeout);
static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
@@ -176,12 +175,11 @@ static void ida_geninit(int ctlr)
ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)] =
drv->nr_blks;
- for(j=0; j<16; j++) {
+ for(j=0; j<16; j++)
ida_blocksizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
1024;
- ida_hardsizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
- drv->blk_size;
- }
+
+ (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
ida_gendisk[ctlr].nr_real++;
}
@@ -341,52 +339,10 @@ void cleanup_module(void)
remove_proc_entry("cpqarray", proc_root_driver);
kfree(ida);
kfree(ida_sizes);
- kfree(ida_hardsizes);
kfree(ida_blocksizes);
}
#endif /* MODULE */
-static inline int cpq_new_segment(request_queue_t *q, struct request *rq,
- int max_segments)
-{
- if (rq->nr_segments < SG_MAX) {
- rq->nr_segments++;
- return 1;
- }
- return 0;
-}
-
-static int cpq_back_merge_fn(request_queue_t *q, struct request *rq,
- struct buffer_head *bh, int max_segments)
-{
- if (rq->bhtail->b_data + rq->bhtail->b_size == bh->b_data)
- return 1;
- return cpq_new_segment(q, rq, max_segments);
-}
-
-static int cpq_front_merge_fn(request_queue_t *q, struct request *rq,
- struct buffer_head *bh, int max_segments)
-{
- if (bh->b_data + bh->b_size == rq->bh->b_data)
- return 1;
- return cpq_new_segment(q, rq, max_segments);
-}
-
-static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq,
- struct request *nxt, int max_segments)
-{
- int total_segments = rq->nr_segments + nxt->nr_segments;
-
- if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data)
- total_segments--;
-
- if (total_segments > SG_MAX)
- return 0;
-
- rq->nr_segments = total_segments;
- return 1;
-}
-
/*
* This is it. Find all the controllers and register them. I really hate
* stealing all these major device numbers.
@@ -433,20 +389,9 @@ int __init cpqarray_init(void)
return(num_cntlrs_reg);
}
- ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
- if(ida_hardsizes==NULL)
- {
- kfree(ida);
- kfree(ida_sizes);
- kfree(ida_blocksizes);
- printk( KERN_ERR "cpqarray: out of memory");
- return(num_cntlrs_reg);
- }
-
memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
memset(ida_blocksizes, 0, sizeof(int)*nr_ctlr*NWD*16);
- memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
/*
@@ -504,7 +449,6 @@ int __init cpqarray_init(void)
{
kfree(ida);
kfree(ida_sizes);
- kfree(ida_hardsizes);
kfree(ida_blocksizes);
}
return(num_cntlrs_reg);
@@ -524,15 +468,11 @@ int __init cpqarray_init(void)
q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
q->queuedata = hba[i];
blk_init_queue(q, do_ida_request);
- blk_queue_headactive(q, 0);
+ blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);
+ blk_queue_max_segments(q, SG_MAX);
blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
- hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
read_ahead[MAJOR_NR+i] = READ_AHEAD;
- q->back_merge_fn = cpq_back_merge_fn;
- q->front_merge_fn = cpq_front_merge_fn;
- q->merge_requests_fn = cpq_merge_requests_fn;
-
ida_gendisk[i].major = MAJOR_NR + i;
ida_gendisk[i].major_name = "ida";
ida_gendisk[i].minor_shift = NWD_SHIFT;
@@ -911,21 +851,19 @@ static void do_ida_request(request_queue_t *q)
{
ctlr_info_t *h = q->queuedata;
cmdlist_t *c;
- char *lastdataend;
struct list_head * queue_head = &q->queue_head;
- struct buffer_head *bh;
struct request *creq;
- struct my_sg tmp_sg[SG_MAX];
- int i, seg;
+ struct scatterlist tmp_sg[SG_MAX];
+ int i, dir, seg;
- if (q->plugged)
+ if (blk_queue_plugged(q))
goto startio;
queue_next:
if (list_empty(queue_head))
goto startio;
- creq = blkdev_entry_next_request(queue_head);
+ creq = elv_next_request(q);
if (creq->nr_segments > SG_MAX)
BUG();
@@ -934,7 +872,7 @@ queue_next:
printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
h->ctlr, creq->rq_dev, creq);
blkdev_dequeue_request(creq);
- complete_buffers(creq->bh, 0);
+ complete_buffers(creq->bio, 0);
end_that_request_last(creq);
goto startio;
}
@@ -944,55 +882,40 @@ queue_next:
blkdev_dequeue_request(creq);
- spin_unlock_irq(&io_request_lock);
-
- bh = creq->bh;
+ spin_unlock_irq(&q->queue_lock);
c->ctlr = h->ctlr;
c->hdr.unit = MINOR(creq->rq_dev) >> NWD_SHIFT;
c->hdr.size = sizeof(rblk_t) >> 2;
c->size += sizeof(rblk_t);
- c->req.hdr.blk = ida[(h->ctlr<<CTLR_SHIFT) + MINOR(creq->rq_dev)].start_sect + creq->sector;
+ c->req.hdr.blk = creq->sector;
c->rq = creq;
DBGPX(
- if (bh == NULL)
- panic("bh == NULL?");
-
printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
);
- seg = 0; lastdataend = NULL;
- while(bh) {
- if (bh->b_data == lastdataend) {
- tmp_sg[seg-1].size += bh->b_size;
- lastdataend += bh->b_size;
- } else {
- if (seg == SG_MAX)
- BUG();
- tmp_sg[seg].size = bh->b_size;
- tmp_sg[seg].start_addr = bh->b_data;
- lastdataend = bh->b_data + bh->b_size;
- seg++;
- }
- bh = bh->b_reqnext;
- }
+ seg = blk_rq_map_sg(q, creq, tmp_sg);
+
/* Now do all the DMA Mappings */
+ if (rq_data_dir(creq) == READ)
+ dir = PCI_DMA_FROMDEVICE;
+ else
+ dir = PCI_DMA_TODEVICE;
for( i=0; i < seg; i++)
{
- c->req.sg[i].size = tmp_sg[i].size;
- c->req.sg[i].addr = (__u32) pci_map_single(
- h->pci_dev, tmp_sg[i].start_addr,
- tmp_sg[i].size,
- (creq->cmd == READ) ?
- PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ c->req.sg[i].size = tmp_sg[i].length;
+ c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
+ tmp_sg[i].page,
+ tmp_sg[i].offset,
+ tmp_sg[i].length, dir);
}
-DBGPX( printk("Submitting %d sectors in %d segments\n", sect, seg); );
+DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); );
c->req.hdr.sg_cnt = seg;
c->req.hdr.blk_cnt = creq->nr_sectors;
- c->req.hdr.cmd = (creq->cmd == READ) ? IDA_READ : IDA_WRITE;
+ c->req.hdr.cmd = (rq_data_dir(creq) == READ) ? IDA_READ : IDA_WRITE;
c->type = CMD_RWREQ;
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
/* Put the request on the tail of the request queue */
addQ(&h->reqQ, c);
@@ -1033,17 +956,19 @@ static void start_io(ctlr_info_t *h)
}
}
-static inline void complete_buffers(struct buffer_head *bh, int ok)
+static inline void complete_buffers(struct bio *bio, int ok)
{
- struct buffer_head *xbh;
- while(bh) {
- xbh = bh->b_reqnext;
- bh->b_reqnext = NULL;
+ struct bio *xbh;
+ while(bio) {
+ int nsecs = bio_sectors(bio);
+
+ xbh = bio->bi_next;
+ bio->bi_next = NULL;
- blk_finished_io(bh->b_size >> 9);
- bh->b_end_io(bh, ok);
+ blk_finished_io(nsecs);
+ bio_endio(bio, ok, nsecs);
- bh = xbh;
+ bio = xbh;
}
}
/*
@@ -1052,7 +977,7 @@ static inline void complete_buffers(struct buffer_head *bh, int ok)
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
int ok=1;
- int i;
+ int i, ddir;
if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
(hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
@@ -1074,19 +999,18 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
}
if (timeout) ok = 0;
/* unmap the DMA mapping for all the scatter gather elements */
+ if (cmd->req.hdr.cmd == IDA_READ)
+ ddir = PCI_DMA_FROMDEVICE;
+ else
+ ddir = PCI_DMA_TODEVICE;
for(i=0; i<cmd->req.hdr.sg_cnt; i++)
- {
- pci_unmap_single(hba[cmd->ctlr]->pci_dev,
- cmd->req.sg[i].addr, cmd->req.sg[i].size,
- (cmd->req.hdr.cmd == IDA_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
- }
+ pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
+ cmd->req.sg[i].size, ddir);
- complete_buffers(cmd->rq->bh, ok);
+ complete_buffers(cmd->rq->bio, ok);
- DBGPX(printk("Done with %p\n", cmd->rq););
+ DBGPX(printk("Done with %p\n", cmd->rq););
end_that_request_last(cmd->rq);
-
-
}
/*
@@ -1111,7 +1035,7 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
* If there are completed commands in the completion queue,
* we had better do something about it.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(IDA_LOCK(h->ctlr), flags);
if (istat & FIFO_NOT_EMPTY) {
while((a = h->access.command_completed(h))) {
a1 = a; a &= ~3;
@@ -1155,7 +1079,7 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
* See if we can queue up some more IO
*/
do_ida_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags);
}
/*
@@ -1201,14 +1125,10 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
put_user(diskinfo[0], &geo->heads);
put_user(diskinfo[1], &geo->sectors);
put_user(diskinfo[2], &geo->cylinders);
- put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].start_sect, &geo->start);
+ put_user(get_start_sect(inode->i_rdev), &geo->start);
return 0;
case IDAGETDRVINFO:
return copy_to_user(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t));
- case BLKGETSIZE:
- return put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
- case BLKGETSIZE64:
- return put_user((u64)(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
case BLKRRPART:
return revalidate_logvol(inode->i_rdev, 1);
case IDAPASSTHRU:
@@ -1244,6 +1164,8 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
return(0);
}
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKFLSBUF:
case BLKBSZSET:
case BLKBSZGET:
@@ -1251,8 +1173,6 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
case BLKROGET:
case BLKRASET:
case BLKRAGET:
- case BLKELVGET:
- case BLKELVSET:
case BLKPG:
return blk_ioctl(inode->i_rdev, cmd, arg);
@@ -1352,11 +1272,11 @@ static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
}
/* Put the request on the tail of the request queue */
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(IDA_LOCK(ctlr), flags);
addQ(&h->reqQ, c);
h->Qdepth++;
start_io(h);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
/* Wait for completion */
while(c->type != CMD_IOCTL_DONE)
@@ -1570,15 +1490,15 @@ static int revalidate_allvol(kdev_t dev)
if (MINOR(dev) != 0)
return -ENXIO;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(IDA_LOCK(ctlr), flags);
if (hba[ctlr]->usage_count > 1) {
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
printk(KERN_WARNING "cpqarray: Device busy for volume"
" revalidation (usage=%d)\n", hba[ctlr]->usage_count);
return -EBUSY;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
hba[ctlr]->usage_count++;
+ spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
/*
* Set the partition and block size structures for all volumes
@@ -1587,7 +1507,6 @@ static int revalidate_allvol(kdev_t dev)
memset(ida+(ctlr*256), 0, sizeof(struct hd_struct)*NWD*16);
memset(ida_sizes+(ctlr*256), 0, sizeof(int)*NWD*16);
memset(ida_blocksizes+(ctlr*256), 0, sizeof(int)*NWD*16);
- memset(ida_hardsizes+(ctlr*256), 0, sizeof(int)*NWD*16);
memset(hba[ctlr]->drv, 0, sizeof(drv_info_t)*NWD);
ida_gendisk[ctlr].nr_real = 0;
@@ -1615,17 +1534,15 @@ static int revalidate_logvol(kdev_t dev, int maxusage)
int ctlr, target;
struct gendisk *gdev;
unsigned long flags;
- int max_p;
- int start;
- int i;
+ int res;
target = DEVICE_NR(dev);
ctlr = MAJOR(dev) - MAJOR_NR;
gdev = &ida_gendisk[ctlr];
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(IDA_LOCK(ctlr), flags);
if (hba[ctlr]->drv[target].usage_count > maxusage) {
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
printk(KERN_WARNING "cpqarray: Device busy for "
"revalidation (usage=%d)\n",
hba[ctlr]->drv[target].usage_count);
@@ -1633,25 +1550,14 @@ static int revalidate_logvol(kdev_t dev, int maxusage)
}
hba[ctlr]->drv[target].usage_count++;
- spin_unlock_irqrestore(&io_request_lock, flags);
-
- max_p = gdev->max_p;
- start = target << gdev->minor_shift;
+ spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
- for(i=max_p-1; i>=0; i--) {
- int minor = start+i;
- invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
- gdev->part[minor].start_sect = 0;
- gdev->part[minor].nr_sects = 0;
+ res = wipe_partitions(dev);
+ if (!res)
+ grok_partitions(dev, hba[ctlr]->drv[target].nr_blks);
- /* reset the blocksize so we can read the partition table */
- blksize_size[MAJOR_NR+ctlr][minor] = 1024;
- }
-
- /* 16 minors per disk... */
- grok_partitions(gdev, target, 16, hba[ctlr]->drv[target].nr_blks);
hba[ctlr]->drv[target].usage_count--;
- return 0;
+ return res;
}
diff --git a/drivers/block/cpqarray.h b/drivers/block/cpqarray.h
index 6d44796ff..bdb8e4108 100644
--- a/drivers/block/cpqarray.h
+++ b/drivers/block/cpqarray.h
@@ -56,11 +56,6 @@ typedef struct {
#ifdef __KERNEL__
-struct my_sg {
- int size;
- char *start_addr;
-};
-
struct ctlr_info;
typedef struct ctlr_info ctlr_info_t;
@@ -121,6 +116,9 @@ struct ctlr_info {
struct timer_list timer;
unsigned int misc_tflags;
};
+
+#define IDA_LOCK(i) (&((BLK_DEFAULT_QUEUE(MAJOR_NR + i))->queue_lock))
+
#endif
#endif /* CPQARRAY_H */
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index c6bc85fd6..c6a23542e 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -18,48 +18,70 @@
* Removed tests for max-bomb-segments, which was breaking elvtune
* when run without -bN
*
+ * Jens:
+ * - Rework again to work with bio instead of buffer_heads
+ * - loose bi_dev comparisons, partition handling is right now
+ * - completely modularize elevator setup and teardown
+ *
*/
-
+#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/blk.h>
+#include <linux/config.h>
#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+
#include <asm/uaccess.h>
/*
- * This is a bit tricky. It's given that bh and rq are for the same
+ * This is a bit tricky. It's given that bio and rq are for the same
* device, but the next request might of course not be. Run through
* the tests below to check if we want to insert here if we can't merge
- * bh into an existing request
+ * bio into an existing request
*/
-inline int bh_rq_in_between(struct buffer_head *bh, struct request *rq,
- struct list_head *head)
+inline int bio_rq_in_between(struct bio *bio, struct request *rq,
+ struct list_head *head)
{
struct list_head *next;
struct request *next_rq;
- next = rq->queue.next;
+ /*
+ * if .next is a valid request
+ */
+ next = rq->queuelist.next;
if (next == head)
return 0;
+ next_rq = list_entry(next, struct request, queuelist);
+
+ BUG_ON(next_rq->flags & REQ_STARTED);
+
/*
- * if the device is different (usually on a different partition),
- * just check if bh is after rq
+ * not a sector based request
+ */
+ if (!(next_rq->flags & REQ_CMD))
+ return 0;
+
+ /*
+ * if the device is different (not a normal case) just check if
+ * bio is after rq
*/
- next_rq = blkdev_entry_to_request(next);
if (next_rq->rq_dev != rq->rq_dev)
- return bh->b_rsector > rq->sector;
+ return bio->bi_sector > rq->sector;
/*
- * ok, rq, next_rq and bh are on the same device. if bh is in between
+ * ok, rq, next_rq and bio are on the same device. if bio is in between
* the two, this is the sweet spot
*/
- if (bh->b_rsector < next_rq->sector && bh->b_rsector > rq->sector)
+ if (bio->bi_sector < next_rq->sector && bio->bi_sector > rq->sector)
return 1;
/*
- * next_rq is ordered wrt rq, but bh is not in between the two
+ * next_rq is ordered wrt rq, but bio is not in between the two
*/
if (next_rq->sector > rq->sector)
return 0;
@@ -68,47 +90,77 @@ inline int bh_rq_in_between(struct buffer_head *bh, struct request *rq,
* next_rq and rq not ordered, if we happen to be either before
* next_rq or after rq insert here anyway
*/
- if (bh->b_rsector > rq->sector || bh->b_rsector < next_rq->sector)
+ if (bio->bi_sector > rq->sector || bio->bi_sector < next_rq->sector)
return 1;
return 0;
}
+/*
+ * can we safely merge with this request?
+ */
+inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
+{
+ if (!(rq->flags & REQ_CMD))
+ return 0;
+
+ /*
+ * different data direction or already started, don't merge
+ */
+ if (bio_data_dir(bio) != rq_data_dir(rq))
+ return 0;
+ if (rq->flags & REQ_NOMERGE)
+ return 0;
+
+ /*
+ * same device and no special stuff set, merge is ok
+ */
+ if (rq->rq_dev == bio->bi_dev && !rq->waiting && !rq->special)
+ return 1;
+
+ return 0;
+}
int elevator_linus_merge(request_queue_t *q, struct request **req,
- struct list_head * head,
- struct buffer_head *bh, int rw,
- int max_sectors)
+ struct list_head *head, struct bio *bio)
{
+ unsigned int count = bio_sectors(bio);
struct list_head *entry = &q->queue_head;
- unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE;
+ int ret = ELEVATOR_NO_MERGE;
+ struct request *__rq;
+ entry = &q->queue_head;
while ((entry = entry->prev) != head) {
- struct request *__rq = blkdev_entry_to_request(entry);
+ __rq = list_entry_rq(entry);
+
+ prefetch(list_entry_rq(entry->prev));
/*
* simply "aging" of requests in queue
*/
if (__rq->elevator_sequence-- <= 0)
break;
-
- if (__rq->waiting)
- continue;
- if (__rq->rq_dev != bh->b_rdev)
+ if (__rq->flags & (REQ_BARRIER | REQ_STARTED))
+ break;
+ if (!(__rq->flags & REQ_CMD))
continue;
- if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head))
+
+ if (!*req && bio_rq_in_between(bio, __rq, &q->queue_head))
*req = __rq;
- if (__rq->cmd != rw)
- continue;
- if (__rq->nr_sectors + count > max_sectors)
+ if (!elv_rq_merge_ok(__rq, bio))
continue;
+
if (__rq->elevator_sequence < count)
break;
- if (__rq->sector + __rq->nr_sectors == bh->b_rsector) {
+
+ /*
+ * we can merge and sequence is ok, check if it's possible
+ */
+ if (__rq->sector + __rq->nr_sectors == bio->bi_sector) {
ret = ELEVATOR_BACK_MERGE;
*req = __rq;
break;
- } else if (__rq->sector - count == bh->b_rsector) {
+ } else if (__rq->sector - count == bio->bi_sector) {
ret = ELEVATOR_FRONT_MERGE;
__rq->elevator_sequence -= count;
*req = __rq;
@@ -121,13 +173,18 @@ int elevator_linus_merge(request_queue_t *q, struct request **req,
void elevator_linus_merge_cleanup(request_queue_t *q, struct request *req, int count)
{
- struct list_head *entry = &req->queue, *head = &q->queue_head;
+ struct list_head *entry;
+
+ BUG_ON(req->q != q);
/*
* second pass scan of requests that got passed over, if any
*/
- while ((entry = entry->next) != head) {
- struct request *tmp = blkdev_entry_to_request(entry);
+ entry = &req->queuelist;
+ while ((entry = entry->next) != &q->queue_head) {
+ struct request *tmp;
+ prefetch(list_entry_rq(entry->next));
+ tmp = list_entry_rq(entry);
tmp->elevator_sequence -= count;
}
}
@@ -138,42 +195,66 @@ void elevator_linus_merge_req(struct request *req, struct request *next)
req->elevator_sequence = next->elevator_sequence;
}
+void elv_add_request_fn(request_queue_t *q, struct request *rq,
+ struct list_head *insert_here)
+{
+ list_add(&rq->queuelist, insert_here);
+}
+
+struct request *elv_next_request_fn(request_queue_t *q)
+{
+ if (!blk_queue_empty(q))
+ return list_entry(q->queue_head.next, struct request, queuelist);
+
+ return NULL;
+}
+
+int elv_linus_init(request_queue_t *q, elevator_t *e)
+{
+ return 0;
+}
+
+void elv_linus_exit(request_queue_t *q, elevator_t *e)
+{
+}
+
/*
* See if we can find a request that this buffer can be coalesced with.
*/
int elevator_noop_merge(request_queue_t *q, struct request **req,
- struct list_head * head,
- struct buffer_head *bh, int rw,
- int max_sectors)
+ struct list_head *head, struct bio *bio)
{
- struct list_head *entry;
- unsigned int count = bh->b_size >> 9;
-
- if (list_empty(&q->queue_head))
- return ELEVATOR_NO_MERGE;
+ unsigned int count = bio_sectors(bio);
+ struct list_head *entry = &q->queue_head;
+ struct request *__rq;
entry = &q->queue_head;
while ((entry = entry->prev) != head) {
- struct request *__rq = blkdev_entry_to_request(entry);
+ __rq = list_entry_rq(entry);
- if (__rq->cmd != rw)
- continue;
- if (__rq->rq_dev != bh->b_rdev)
- continue;
- if (__rq->nr_sectors + count > max_sectors)
+ prefetch(list_entry_rq(entry->prev));
+
+ if (__rq->flags & (REQ_BARRIER | REQ_STARTED))
+ break;
+
+ if (!(__rq->flags & REQ_CMD))
continue;
- if (__rq->waiting)
+
+ if (!elv_rq_merge_ok(__rq, bio))
continue;
- if (__rq->sector + __rq->nr_sectors == bh->b_rsector) {
+
+ /*
+ * we can merge and sequence is ok, check if it's possible
+ */
+ if (__rq->sector + __rq->nr_sectors == bio->bi_sector) {
*req = __rq;
return ELEVATOR_BACK_MERGE;
- } else if (__rq->sector - count == bh->b_rsector) {
+ } else if (__rq->sector - count == bio->bi_sector) {
*req = __rq;
return ELEVATOR_FRONT_MERGE;
}
}
- *req = blkdev_entry_to_request(q->queue_head.prev);
return ELEVATOR_NO_MERGE;
}
@@ -181,42 +262,27 @@ void elevator_noop_merge_cleanup(request_queue_t *q, struct request *req, int co
void elevator_noop_merge_req(struct request *req, struct request *next) {}
-int blkelvget_ioctl(elevator_t * elevator, blkelv_ioctl_arg_t * arg)
+int elevator_init(request_queue_t *q, elevator_t *e, elevator_t type)
{
- blkelv_ioctl_arg_t output;
+ *e = type;
- output.queue_ID = elevator->queue_ID;
- output.read_latency = elevator->read_latency;
- output.write_latency = elevator->write_latency;
- output.max_bomb_segments = 0;
+ INIT_LIST_HEAD(&q->queue_head);
- if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t)))
- return -EFAULT;
+ if (e->elevator_init_fn)
+ return e->elevator_init_fn(q, e);
return 0;
}
-int blkelvset_ioctl(elevator_t * elevator, const blkelv_ioctl_arg_t * arg)
+void elevator_exit(request_queue_t *q, elevator_t *e)
{
- blkelv_ioctl_arg_t input;
-
- if (copy_from_user(&input, arg, sizeof(blkelv_ioctl_arg_t)))
- return -EFAULT;
-
- if (input.read_latency < 0)
- return -EINVAL;
- if (input.write_latency < 0)
- return -EINVAL;
-
- elevator->read_latency = input.read_latency;
- elevator->write_latency = input.write_latency;
- return 0;
+ if (e->elevator_exit_fn)
+ e->elevator_exit_fn(q, e);
}
-void elevator_init(elevator_t * elevator, elevator_t type)
+int elevator_global_init(void)
{
- static unsigned int queue_ID;
-
- *elevator = type;
- elevator->queue_ID = queue_ID++;
+ return 0;
}
+
+module_init(elevator_global_init);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 30f23d214..ef79fcd0e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -576,7 +576,7 @@ static int fdc; /* current fdc */
static struct floppy_struct *_floppy = floppy_type;
static unsigned char current_drive;
static long current_count_sectors;
-static unsigned char sector_t; /* sector in track */
+static unsigned char fsector_t; /* sector in track */
static unsigned char in_sector_offset; /* offset within physical sector,
* expressed in units of 512 bytes */
@@ -2276,8 +2276,8 @@ static int do_format(kdev_t device, struct format_descr *tmp_format_req)
* logical buffer */
static void request_done(int uptodate)
{
- int block;
unsigned long flags;
+ int block;
probing = 0;
reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
@@ -2296,7 +2296,7 @@ static void request_done(int uptodate)
DRS->maxtrack = 1;
/* unlock chained buffers */
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&QUEUE->queue_lock, flags);
while (current_count_sectors && !QUEUE_EMPTY &&
current_count_sectors >= CURRENT->current_nr_sectors){
current_count_sectors -= CURRENT->current_nr_sectors;
@@ -2304,7 +2304,7 @@ static void request_done(int uptodate)
CURRENT->sector += CURRENT->current_nr_sectors;
end_request(1);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock, flags);
if (current_count_sectors && !QUEUE_EMPTY){
/* "unlock" last subsector */
@@ -2319,7 +2319,7 @@ static void request_done(int uptodate)
DPRINT("request list destroyed in floppy request done\n");
} else {
- if (CURRENT->cmd == WRITE) {
+ if (rq_data_dir(CURRENT) == WRITE) {
/* record write error information */
DRWE->write_errors++;
if (DRWE->write_errors == 1) {
@@ -2329,9 +2329,9 @@ static void request_done(int uptodate)
DRWE->last_error_sector = CURRENT->sector;
DRWE->last_error_generation = DRS->generation;
}
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&QUEUE->queue_lock, flags);
end_request(0);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock, flags);
}
}
@@ -2377,7 +2377,7 @@ static void rw_interrupt(void)
printk("rt=%d t=%d\n", R_TRACK, TRACK);
printk("heads=%d eoc=%d\n", heads, eoc);
printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
- sector_t, ssize);
+ fsector_t, ssize);
printk("in_sector_offset=%d\n", in_sector_offset);
}
#endif
@@ -2424,7 +2424,7 @@ static void rw_interrupt(void)
} else if (CT(COMMAND) == FD_READ){
buffer_track = raw_cmd->track;
buffer_drive = current_drive;
- INFBOUND(buffer_max, nr_sectors + sector_t);
+ INFBOUND(buffer_max, nr_sectors + fsector_t);
}
cont->redo();
}
@@ -2432,34 +2432,33 @@ static void rw_interrupt(void)
/* Compute maximal contiguous buffer size. */
static int buffer_chain_size(void)
{
- struct buffer_head *bh;
+ struct bio *bio;
int size;
char *base;
base = CURRENT->buffer;
- size = CURRENT->current_nr_sectors << 9;
- bh = CURRENT->bh;
+ size = 0;
- if (bh){
- bh = bh->b_reqnext;
- while (bh && bh->b_data == base + size){
- size += bh->b_size;
- bh = bh->b_reqnext;
- }
+ rq_for_each_bio(bio, CURRENT) {
+ if (bio_data(bio) != base + size)
+ break;
+
+ size += bio->bi_size;
}
+
return size >> 9;
}
/* Compute the maximal transfer size */
static int transfer_size(int ssize, int max_sector, int max_size)
{
- SUPBOUND(max_sector, sector_t + max_size);
+ SUPBOUND(max_sector, fsector_t + max_size);
/* alignment */
max_sector -= (max_sector % _floppy->sect) % ssize;
/* transfer size, beginning not aligned */
- current_count_sectors = max_sector - sector_t ;
+ current_count_sectors = max_sector - fsector_t ;
return max_sector;
}
@@ -2470,7 +2469,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{
int remaining; /* number of transferred 512-byte sectors */
- struct buffer_head *bh;
+ struct bio *bio;
char *buffer, *dma_buffer;
int size;
@@ -2479,8 +2478,8 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
CURRENT->nr_sectors);
if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
- buffer_max > sector_t + CURRENT->nr_sectors)
- current_count_sectors = minimum(buffer_max - sector_t,
+ buffer_max > fsector_t + CURRENT->nr_sectors)
+ current_count_sectors = minimum(buffer_max - fsector_t,
CURRENT->nr_sectors);
remaining = current_count_sectors << 9;
@@ -2491,7 +2490,7 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
printk("current_count_sectors=%ld\n", current_count_sectors);
printk("remaining=%d\n", remaining >> 9);
printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
- printk("CURRENT->current_nr_sectors=%ld\n",
+ printk("CURRENT->current_nr_sectors=%u\n",
CURRENT->current_nr_sectors);
printk("max_sector=%d\n", max_sector);
printk("ssize=%d\n", ssize);
@@ -2500,9 +2499,9 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
buffer_max = maximum(max_sector, buffer_max);
- dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
+ dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9);
- bh = CURRENT->bh;
+ bio = CURRENT->bio;
size = CURRENT->current_nr_sectors << 9;
buffer = CURRENT->buffer;
@@ -2514,8 +2513,8 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
dma_buffer < floppy_track_buffer){
DPRINT("buffer overrun in copy buffer %d\n",
(int) ((floppy_track_buffer - dma_buffer) >>9));
- printk("sector_t=%d buffer_min=%d\n",
- sector_t, buffer_min);
+ printk("fsector_t=%d buffer_min=%d\n",
+ fsector_t, buffer_min);
printk("current_count_sectors=%ld\n",
current_count_sectors);
if (CT(COMMAND) == FD_READ)
@@ -2536,15 +2535,15 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
break;
dma_buffer += size;
- bh = bh->b_reqnext;
+ bio = bio->bi_next;
#ifdef FLOPPY_SANITY_CHECK
- if (!bh){
+ if (!bio){
DPRINT("bh=null in copy buffer after copy\n");
break;
}
#endif
- size = bh->b_size;
- buffer = bh->b_data;
+ size = bio->bi_size;
+ buffer = bio_data(bio);
}
#ifdef FLOPPY_SANITY_CHECK
if (remaining){
@@ -2622,10 +2621,10 @@ static int make_raw_rw_request(void)
raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
FD_RAW_NEED_SEEK;
raw_cmd->cmd_count = NR_RW;
- if (CURRENT->cmd == READ){
+ if (rq_data_dir(CURRENT) == READ) {
raw_cmd->flags |= FD_RAW_READ;
COMMAND = FM_MODE(_floppy,FD_READ);
- } else if (CURRENT->cmd == WRITE){
+ } else if (rq_data_dir(CURRENT) == WRITE){
raw_cmd->flags |= FD_RAW_WRITE;
COMMAND = FM_MODE(_floppy,FD_WRITE);
} else {
@@ -2636,7 +2635,7 @@ static int make_raw_rw_request(void)
max_sector = _floppy->sect * _floppy->head;
TRACK = CURRENT->sector / max_sector;
- sector_t = CURRENT->sector % max_sector;
+ fsector_t = CURRENT->sector % max_sector;
if (_floppy->track && TRACK >= _floppy->track) {
if (CURRENT->current_nr_sectors & 1) {
current_count_sectors = 1;
@@ -2644,17 +2643,17 @@ static int make_raw_rw_request(void)
} else
return 0;
}
- HEAD = sector_t / _floppy->sect;
+ HEAD = fsector_t / _floppy->sect;
if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) &&
- sector_t < _floppy->sect)
+ fsector_t < _floppy->sect)
max_sector = _floppy->sect;
/* 2M disks have phantom sectors on the first track */
if ((_floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){
max_sector = 2 * _floppy->sect / 3;
- if (sector_t >= max_sector){
- current_count_sectors = minimum(_floppy->sect - sector_t,
+ if (fsector_t >= max_sector){
+ current_count_sectors = minimum(_floppy->sect - fsector_t,
CURRENT->nr_sectors);
return 1;
}
@@ -2676,7 +2675,7 @@ static int make_raw_rw_request(void)
GAP = _floppy->gap;
CODE2SIZE;
SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
- SECTOR = ((sector_t % _floppy->sect) << 2 >> SIZECODE) + 1;
+ SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + 1;
/* tracksize describes the size which can be filled up with sectors
* of size ssize.
@@ -2684,11 +2683,11 @@ static int make_raw_rw_request(void)
tracksize = _floppy->sect - _floppy->sect % ssize;
if (tracksize < _floppy->sect){
SECT_PER_TRACK ++;
- if (tracksize <= sector_t % _floppy->sect)
+ if (tracksize <= fsector_t % _floppy->sect)
SECTOR--;
/* if we are beyond tracksize, fill up using smaller sectors */
- while (tracksize <= sector_t % _floppy->sect){
+ while (tracksize <= fsector_t % _floppy->sect){
while(tracksize + ssize > _floppy->sect){
SIZECODE--;
ssize >>= 1;
@@ -2704,12 +2703,12 @@ static int make_raw_rw_request(void)
max_sector = _floppy->sect;
}
- in_sector_offset = (sector_t % _floppy->sect) % ssize;
- aligned_sector_t = sector_t - in_sector_offset;
+ in_sector_offset = (fsector_t % _floppy->sect) % ssize;
+ aligned_sector_t = fsector_t - in_sector_offset;
max_size = CURRENT->nr_sectors;
if ((raw_cmd->track == buffer_track) &&
(current_drive == buffer_drive) &&
- (sector_t >= buffer_min) && (sector_t < buffer_max)) {
+ (fsector_t >= buffer_min) && (fsector_t < buffer_max)) {
/* data already in track buffer */
if (CT(COMMAND) == FD_READ) {
copy_buffer(1, max_sector, buffer_max);
@@ -2717,8 +2716,8 @@ static int make_raw_rw_request(void)
}
} else if (in_sector_offset || CURRENT->nr_sectors < ssize){
if (CT(COMMAND) == FD_WRITE){
- if (sector_t + CURRENT->nr_sectors > ssize &&
- sector_t + CURRENT->nr_sectors < ssize + ssize)
+ if (fsector_t + CURRENT->nr_sectors > ssize &&
+ fsector_t + CURRENT->nr_sectors < ssize + ssize)
max_size = ssize + ssize;
else
max_size = ssize;
@@ -2731,7 +2730,7 @@ static int make_raw_rw_request(void)
int direct, indirect;
indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
- sector_t;
+ fsector_t;
/*
* Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide
@@ -2746,7 +2745,7 @@ static int make_raw_rw_request(void)
if (CROSS_64KB(CURRENT->buffer, max_size << 9))
max_size = (K_64 -
((unsigned long)CURRENT->buffer) % K_64)>>9;
- direct = transfer_size(ssize,max_sector,max_size) - sector_t;
+ direct = transfer_size(ssize,max_sector,max_size) - fsector_t;
/*
* We try to read tracks, but if we get too many errors, we
* go back to reading just one sector at a time.
@@ -2765,8 +2764,8 @@ static int make_raw_rw_request(void)
raw_cmd->length = current_count_sectors << 9;
if (raw_cmd->length == 0){
DPRINT("zero dma transfer attempted from make_raw_request\n");
- DPRINT("indirect=%d direct=%d sector_t=%d",
- indirect, direct, sector_t);
+ DPRINT("indirect=%d direct=%d fsector_t=%d",
+ indirect, direct, fsector_t);
return 0;
}
/* check_dma_crossing(raw_cmd->kernel_data,
@@ -2784,12 +2783,12 @@ static int make_raw_rw_request(void)
/* claim buffer track if needed */
if (buffer_track != raw_cmd->track || /* bad track */
buffer_drive !=current_drive || /* bad drive */
- sector_t > buffer_max ||
- sector_t < buffer_min ||
+ fsector_t > buffer_max ||
+ fsector_t < buffer_min ||
((CT(COMMAND) == FD_READ ||
(!in_sector_offset && CURRENT->nr_sectors >= ssize))&&
max_sector > 2 * max_buffer_sectors + buffer_min &&
- max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
+ max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
/* not enough space */){
buffer_track = -1;
buffer_drive = current_drive;
@@ -2836,7 +2835,7 @@ static int make_raw_rw_request(void)
floppy_track_buffer) >> 9),
current_count_sectors);
printk("st=%d ast=%d mse=%d msi=%d\n",
- sector_t, aligned_sector_t, max_sector, max_size);
+ fsector_t, aligned_sector_t, max_sector, max_size);
printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
COMMAND, SECTOR, HEAD, TRACK);
@@ -2854,8 +2853,8 @@ static int make_raw_rw_request(void)
raw_cmd->kernel_data + raw_cmd->length >
floppy_track_buffer + (max_buffer_sectors << 10)){
DPRINT("buffer overrun in schedule dma\n");
- printk("sector_t=%d buffer_min=%d current_count=%ld\n",
- sector_t, buffer_min,
+ printk("fsector_t=%d buffer_min=%d current_count=%ld\n",
+ fsector_t, buffer_min,
raw_cmd->length >> 9);
printk("current_count_sectors=%ld\n",
current_count_sectors);
@@ -2908,8 +2907,6 @@ static void redo_fd_request(void)
}
if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
panic(DEVICE_NAME ": request list destroyed");
- if (CURRENT->bh && !buffer_locked(CURRENT->bh))
- panic(DEVICE_NAME ": block not locked");
device = CURRENT->rq_dev;
set_fdc(DRIVE(device));
@@ -2977,7 +2974,7 @@ static void do_fd_request(request_queue_t * q)
if (usage_count == 0) {
printk("warning: usage count=0, CURRENT=%p exiting\n", CURRENT);
- printk("sect=%ld cmd=%d\n", CURRENT->sector, CURRENT->cmd);
+ printk("sect=%ld flags=%lx\n", CURRENT->sector, CURRENT->flags);
return;
}
if (fdc_busy){
@@ -3917,7 +3914,7 @@ static void __init register_devfs_entries (int drive)
{NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in};
base_minor = (drive < 4) ? drive : (124 + drive);
- if (UDP->cmos <= NUMBER(default_drive_params)) {
+ if (UDP->cmos < NUMBER(default_drive_params)) {
i = 0;
do {
char name[16];
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 12e19a164..2ecc7c6d3 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -28,14 +28,8 @@ static rwlock_t gendisk_lock;
/*
* Global kernel list of partitioning information.
- *
- * XXX: you should _never_ access this directly.
- * the only reason this is exported is source compatiblity.
*/
-/*static*/ struct gendisk *gendisk_head;
-
-EXPORT_SYMBOL(gendisk_head);
-
+static struct gendisk *gendisk_head;
/**
* add_gendisk - add partitioning information to kernel list
@@ -123,6 +117,30 @@ get_gendisk(kdev_t dev)
EXPORT_SYMBOL(get_gendisk);
+unsigned long
+get_start_sect(kdev_t dev)
+{
+ struct gendisk *gp;
+
+ gp = get_gendisk(dev);
+ if (gp)
+ return gp->part[MINOR(dev)].start_sect;
+ return 0;
+}
+
+EXPORT_SYMBOL(get_start_sect);
+
+unsigned long
+get_nr_sects(kdev_t dev)
+{
+ struct gendisk *gp;
+
+ gp = get_gendisk(dev);
+ if (gp)
+ return gp->part[MINOR(dev)].nr_sects;
+ return 0;
+}
+
#ifdef CONFIG_PROC_FS
int
get_partition_list(char *page, char **start, off_t offset, int count)
@@ -165,7 +183,6 @@ extern int blk_dev_init(void);
extern int fusion_init(void);
#endif
extern int net_dev_init(void);
-extern void console_map_init(void);
extern int soc_probe(void);
extern int atmdev_init(void);
extern int i2o_init(void);
@@ -195,9 +212,6 @@ int __init device_init(void)
#ifdef CONFIG_ATM
(void) atmdev_init();
#endif
-#ifdef CONFIG_VT
- console_map_init();
-#endif
return 0;
}
diff --git a/drivers/block/ida_cmd.h b/drivers/block/ida_cmd.h
index e5f096e26..299748f44 100644
--- a/drivers/block/ida_cmd.h
+++ b/drivers/block/ida_cmd.h
@@ -67,7 +67,7 @@ typedef struct {
__u8 reserved;
} rhdr_t;
-#define SG_MAX 32
+#define SG_MAX 31
typedef struct {
rhdr_t hdr;
sg_t sg[SG_MAX];
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 1700c3759..0f7a51edc 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -6,6 +6,7 @@
* Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
* Queue request tables / lock, selectable elevator, Jens Axboe <axboe@suse.de>
* kernel-doc documentation started by NeilBrown <neilb@cse.unsw.edu.au> - July2000
+ * bio rewrite, highmem i/o, etc, Jens Axboe <axboe@suse.de> - may 2001
*/
/*
@@ -22,7 +23,10 @@
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
+#include <linux/bootmem.h>
#include <linux/completion.h>
+#include <linux/compiler.h>
+#include <scsi/scsi.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -50,27 +54,13 @@ static kmem_cache_t *request_cachep;
*/
DECLARE_TASK_QUEUE(tq_disk);
-/*
- * Protect the request list against multiple users..
- *
- * With this spinlock the Linux block IO subsystem is 100% SMP threaded
- * from the IRQ event side, and almost 100% SMP threaded from the syscall
- * side (we still have protect against block device array operations, and
- * the do_request() side is casually still unsafe. The kernel lock protects
- * this part currently.).
- *
- * there is a fair chance that things will work just OK if these functions
- * are called with no global kernel lock held ...
- */
-spinlock_t io_request_lock = SPIN_LOCK_UNLOCKED;
-
/* This specifies how many sectors to read ahead on the disk. */
int read_ahead[MAX_BLKDEV];
/* blk_dev_struct is:
- * *request_fn
- * *current_request
+ * request_queue
+ * *queue
*/
struct blk_dev_struct blk_dev[MAX_BLKDEV]; /* initialized by blk_dev_init() */
@@ -94,42 +84,29 @@ int * blk_size[MAX_BLKDEV];
int * blksize_size[MAX_BLKDEV];
/*
- * hardsect_size contains the size of the hardware sector of a device.
- *
- * hardsect_size[MAJOR][MINOR]
- *
- * if (!hardsect_size[MAJOR])
- * then 512 bytes is assumed.
- * else
- * sector_size is hardsect_size[MAJOR][MINOR]
- * This is currently set by some scsi devices and read by the msdos fs driver.
- * Other uses may appear later.
- */
-int * hardsect_size[MAX_BLKDEV];
-
-/*
* The following tunes the read-ahead algorithm in mm/filemap.c
*/
int * max_readahead[MAX_BLKDEV];
/*
- * Max number of sectors per request
- */
-int * max_sectors[MAX_BLKDEV];
-
-/*
* How many reqeusts do we allocate per queue,
* and how many do we "batch" on freeing them?
*/
-static int queue_nr_requests, batch_requests;
-
-static inline int get_max_sectors(kdev_t dev)
-{
- if (!max_sectors[MAJOR(dev)])
- return MAX_SECTORS;
- return max_sectors[MAJOR(dev)][MINOR(dev)];
-}
+int queue_nr_requests, batch_requests;
+unsigned long blk_max_low_pfn, blk_max_pfn;
+int blk_nohighio = 0;
+/**
+ * blk_get_queue: - return the queue that matches the given device
+ * @dev: device
+ *
+ * Description:
+ * Given a specific device, return the queue that will hold I/O
+ * for it. This is either a &struct blk_dev_struct lookup and a
+ * call to the ->queue() function defined, or the default queue
+ * stored in the same location.
+ *
+ **/
inline request_queue_t *blk_get_queue(kdev_t dev)
{
struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);
@@ -140,144 +117,334 @@ inline request_queue_t *blk_get_queue(kdev_t dev)
return &blk_dev[MAJOR(dev)].request_queue;
}
-static int __blk_cleanup_queue(struct request_list *list)
+/**
+ * blk_queue_make_request - define an alternate make_request function for a device
+ * @q: the request queue for the device to be affected
+ * @mfn: the alternate make_request function
+ *
+ * Description:
+ * The normal way for &struct bios to be passed to a device
+ * driver is for them to be collected into requests on a request
+ * queue, and then to allow the device driver to select requests
+ * off that queue when it is ready. This works well for many block
+ * devices. However some block devices (typically virtual devices
+ * such as md or lvm) do not benefit from the processing on the
+ * request queue, and are served best by having the requests passed
+ * directly to them. This can be achieved by providing a function
+ * to blk_queue_make_request().
+ *
+ * Caveat:
+ * The driver that does this *must* be able to deal appropriately
+ * with buffers in "highmemory". This can be accomplished by either calling
+ * bio_kmap() to get a temporary kernel mapping, or by calling
+ * blk_queue_bounce() to create a buffer in normal memory.
+ **/
+void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
{
- struct list_head *head = &list->free;
- struct request *rq;
- int i = 0;
-
- while (!list_empty(head)) {
- rq = list_entry(head->next, struct request, queue);
- list_del(&rq->queue);
- kmem_cache_free(request_cachep, rq);
- i++;
- };
-
- if (i != list->count)
- printk("request list leak!\n");
+ /*
+ * set defaults
+ */
+ q->max_segments = MAX_SEGMENTS;
+ q->make_request_fn = mfn;
+ blk_queue_max_sectors(q, MAX_SECTORS);
+ blk_queue_hardsect_size(q, 512);
- list->count = 0;
- return i;
+ init_waitqueue_head(&q->queue_wait);
}
/**
- * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
- * @q: the request queue to be released
+ * blk_queue_bounce_limit - set bounce buffer limit for queue
+ * @q: the request queue for the device
+ * @dma_addr: bus address limit
*
* Description:
- * blk_cleanup_queue is the pair to blk_init_queue(). It should
- * be called when a request queue is being released; typically
- * when a block device is being de-registered. Currently, its
- * primary task it to free all the &struct request structures that
- * were allocated to the queue.
- * Caveat:
- * Hopefully the low level driver will have finished any
- * outstanding requests first...
+ * Different hardware can have different requirements as to what pages
+ * it can do I/O directly to. A low level driver can call
+ * blk_queue_bounce_limit to have lower memory pages allocated as bounce
+ * buffers for doing I/O to pages residing above @page. By default
+ * the block layer sets this to the highest numbered "low" memory page.
**/
-void blk_cleanup_queue(request_queue_t * q)
+void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr)
{
- int count = queue_nr_requests;
-
- count -= __blk_cleanup_queue(&q->rq[READ]);
- count -= __blk_cleanup_queue(&q->rq[WRITE]);
+ unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT;
+ unsigned long mb = dma_addr >> 20;
+ static request_queue_t *last_q;
- if (count)
- printk("blk_cleanup_queue: leaked requests (%d)\n", count);
+ /*
+ * keep this for debugging for now...
+ */
+ if (dma_addr != BLK_BOUNCE_HIGH && q != last_q) {
+ printk("blk: queue %p, ", q);
+ if (dma_addr == BLK_BOUNCE_ANY)
+ printk("no I/O memory limit\n");
+ else
+ printk("I/O limit %luMb (mask 0x%Lx)\n", mb, (long long) dma_addr);
+ }
- memset(q, 0, sizeof(*q));
+ q->bounce_pfn = bounce_pfn;
+ last_q = q;
}
+
/**
- * blk_queue_headactive - indicate whether head of request queue may be active
- * @q: The queue which this applies to.
- * @active: A flag indication where the head of the queue is active.
+ * blk_queue_max_sectors - set max sectors for a request for this queue
+ * @q: the request queue for the device
+ * @max_sectors: max sectors in the usual 512b unit
*
* Description:
- * The driver for a block device may choose to leave the currently active
- * request on the request queue, removing it only when it has completed.
- * The queue handling routines assume this by default for safety reasons
- * and will not involve the head of the request queue in any merging or
- * reordering of requests when the queue is unplugged (and thus may be
- * working on this particular request).
- *
- * If a driver removes requests from the queue before processing them, then
- * it may indicate that it does so, there by allowing the head of the queue
- * to be involved in merging and reordering. This is done be calling
- * blk_queue_headactive() with an @active flag of %0.
- *
- * If a driver processes several requests at once, it must remove them (or
- * at least all but one of them) from the request queue.
+ * Enables a low level driver to set an upper limit on the size of
+ * received requests.
+ **/
+void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
+{
+ q->max_sectors = max_sectors;
+}
+
+/**
+ * blk_queue_max_segments - set max segments for a request for this queue
+ * @q: the request queue for the device
+ * @max_segments: max number of segments
*
- * When a queue is plugged the head will be assumed to be inactive.
+ * Description:
+ * Enables a low level driver to set an upper limit on the number of
+ * data segments in a request
**/
-
-void blk_queue_headactive(request_queue_t * q, int active)
+void blk_queue_max_segments(request_queue_t *q, unsigned short max_segments)
{
- q->head_active = active;
+ q->max_segments = max_segments;
}
/**
- * blk_queue_make_request - define an alternate make_request function for a device
- * @q: the request queue for the device to be affected
- * @mfn: the alternate make_request function
+ * blk_queue_max_segment_size - set max segment size for blk_rq_map_sg
+ * @q: the request queue for the device
+ * @max_size: max size of segment in bytes
*
* Description:
- * The normal way for &struct buffer_heads to be passed to a device
- * driver is for them to be collected into requests on a request
- * queue, and then to allow the device driver to select requests
- * off that queue when it is ready. This works well for many block
- * devices. However some block devices (typically virtual devices
- * such as md or lvm) do not benefit from the processing on the
- * request queue, and are served best by having the requests passed
- * directly to them. This can be achieved by providing a function
- * to blk_queue_make_request().
+ * Enables a low level driver to set an upper limit on the size of a
+ * coalesced segment
+ **/
+void blk_queue_max_segment_size(request_queue_t *q, unsigned int max_size)
+{
+ q->max_segment_size = max_size;
+}
+
+/**
+ * blk_queue_hardsect_size - set hardware sector size for the queue
+ * @q: the request queue for the device
+ * @size: the hardware sector size, in bytes
*
- * Caveat:
- * The driver that does this *must* be able to deal appropriately
- * with buffers in "highmemory", either by calling bh_kmap() to get
- * a kernel mapping, to by calling create_bounce() to create a
- * buffer in normal memory.
+ * Description:
+ * This should typically be set to the lowest possible sector size
+ * that the hardware can operate on (possible without reverting to
+ * even internal read-modify-write operations). Usually the default
+ * of 512 covers most hardware.
**/
+void blk_queue_hardsect_size(request_queue_t *q, unsigned short size)
+{
+ q->hardsect_size = size;
+}
-void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
+/**
+ * blk_queue_segment_boundary - set boundary rules for segment merging
+ * @q: the request queue for the device
+ * @mask: the memory boundary mask
+ **/
+void blk_queue_segment_boundary(request_queue_t *q, unsigned long mask)
{
- q->make_request_fn = mfn;
+ q->seg_boundary_mask = mask;
+}
+
+static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER",
+ "REQ_CMD", "REQ_NOMERGE", "REQ_STARTED",
+ "REQ_DONTPREP", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK",
+ "REQ_PC", "REQ_SENSE", "REQ_SPECIAL" };
+
+void blk_dump_rq_flags(struct request *rq, char *msg)
+{
+ int bit;
+
+ printk("%s: dev %x: ", msg, rq->rq_dev);
+ bit = 0;
+ do {
+ if (rq->flags & (1 << bit))
+ printk("%s ", rq_flags[bit]);
+ bit++;
+ } while (bit < __REQ_NR_BITS);
+
+ if (rq->flags & REQ_CMD)
+ printk("sector %lu, nr/cnr %lu/%u\n", rq->sector,
+ rq->nr_sectors,
+ rq->current_nr_sectors);
+
+ printk("\n");
+}
+
+/*
+ * standard prep_rq_fn that builds 10 byte cmds
+ */
+static int ll_10byte_cmd_build(request_queue_t *q, struct request *rq)
+{
+ int hard_sect = get_hardsect_size(rq->rq_dev);
+ sector_t block = rq->hard_sector / (hard_sect >> 9);
+ unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
+
+ if (!(rq->flags & REQ_CMD))
+ return 0;
+
+ memset(rq->cmd, 0, sizeof(rq->cmd));
+
+ if (rq_data_dir(rq) == READ)
+ rq->cmd[0] = READ_10;
+ else
+ rq->cmd[0] = WRITE_10;
+
+ /*
+ * fill in lba
+ */
+ rq->cmd[2] = (block >> 24) & 0xff;
+ rq->cmd[3] = (block >> 16) & 0xff;
+ rq->cmd[4] = (block >> 8) & 0xff;
+ rq->cmd[5] = block & 0xff;
+
+ /*
+ * and transfer length
+ */
+ rq->cmd[7] = (blocks >> 8) & 0xff;
+ rq->cmd[8] = blocks & 0xff;
+
+ return 0;
+}
+
+/*
+ * can we merge the two segments, or do we need to start a new one?
+ */
+inline int blk_same_segment(request_queue_t *q, struct bio *bio,
+ struct bio *nxt)
+{
+ /*
+ * not contigous, just forget it
+ */
+ if (!BIO_CONTIG(bio, nxt))
+ return 0;
+
+ /*
+ * bio and nxt are contigous in memory, check if the queue allows
+ * these two to be merged into one
+ */
+ if (BIO_SEG_BOUNDARY(q, bio, nxt))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * map a request to scatterlist, return number of sg entries setup. Caller
+ * must make sure sg can hold rq->nr_segments entries
+ */
+int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg)
+{
+ unsigned long long lastend;
+ struct bio_vec *bvec;
+ struct bio *bio;
+ int nsegs, i, cluster;
+
+ nsegs = 0;
+ bio = rq->bio;
+ lastend = ~0ULL;
+ cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
+
+ /*
+ * for each bio in rq
+ */
+ rq_for_each_bio(bio, rq) {
+ /*
+ * for each segment in bio
+ */
+ bio_for_each_segment(bvec, bio, i) {
+ int nbytes = bvec->bv_len;
+
+ BIO_BUG_ON(i > bio->bi_vcnt);
+
+ if (cluster && bvec_to_phys(bvec) == lastend) {
+ if (sg[nsegs - 1].length + nbytes > q->max_segment_size)
+ goto new_segment;
+
+ /*
+ * make sure to not map a segment across a
+ * boundary that the queue doesn't want
+ */
+ if (!__BIO_SEG_BOUNDARY(lastend, lastend + nbytes, q->seg_boundary_mask))
+ lastend = ~0ULL;
+ else
+ lastend += nbytes;
+
+ sg[nsegs - 1].length += nbytes;
+ } else {
+new_segment:
+ if (nsegs > q->max_segments) {
+ printk("map: %d >= %d\n", nsegs, q->max_segments);
+ BUG();
+ }
+
+ sg[nsegs].address = NULL;
+ sg[nsegs].page = bvec->bv_page;
+ sg[nsegs].length = nbytes;
+ sg[nsegs].offset = bvec->bv_offset;
+
+ lastend = bvec_to_phys(bvec) + nbytes;
+ nsegs++;
+ }
+ } /* segments in bio */
+ } /* bios in rq */
+
+ return nsegs;
}
-static inline int ll_new_segment(request_queue_t *q, struct request *req, int max_segments)
+/*
+ * the standard queue merge functions, can be overridden with device
+ * specific ones if so desired
+ */
+static inline int ll_new_segment(request_queue_t *q, struct request *req,
+ struct bio *bio)
{
- if (req->nr_segments < max_segments) {
- req->nr_segments++;
+ if (req->nr_segments + bio->bi_vcnt <= q->max_segments) {
+ req->nr_segments += bio->bi_vcnt;
return 1;
}
return 0;
}
static int ll_back_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int max_segments)
+ struct bio *bio)
{
- if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors)
+ return 0;
+ if (blk_same_segment(q, req->biotail, bio))
return 1;
- return ll_new_segment(q, req, max_segments);
+
+ return ll_new_segment(q, req, bio);
}
static int ll_front_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int max_segments)
+ struct bio *bio)
{
- if (bh->b_data + bh->b_size == req->bh->b_data)
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors)
+ return 0;
+ if (blk_same_segment(q, bio, req->bio))
return 1;
- return ll_new_segment(q, req, max_segments);
+
+ return ll_new_segment(q, req, bio);
}
static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
- struct request *next, int max_segments)
+ struct request *next)
{
int total_segments = req->nr_segments + next->nr_segments;
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ if (blk_same_segment(q, req->biotail, next->bio))
total_segments--;
- if (total_segments > max_segments)
+ if (total_segments > q->max_segments)
return 0;
req->nr_segments = total_segments;
@@ -292,16 +459,16 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
* This is called with interrupts off and no requests on the queue.
* (and with the request spinlock acquired)
*/
-static void generic_plug_device(request_queue_t *q, kdev_t dev)
+void blk_plug_device(request_queue_t *q)
{
/*
- * no need to replug device
+ * common case
*/
- if (!list_empty(&q->queue_head) || q->plugged)
+ if (!elv_queue_empty(q))
return;
- q->plugged = 1;
- queue_task(&q->plug_tq, &tq_disk);
+ if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
+ queue_task(&q->plug_tq, &tq_disk);
}
/*
@@ -309,25 +476,93 @@ static void generic_plug_device(request_queue_t *q, kdev_t dev)
*/
static inline void __generic_unplug_device(request_queue_t *q)
{
- if (q->plugged) {
- q->plugged = 0;
- if (!list_empty(&q->queue_head))
- q->request_fn(q);
- }
+ /*
+ * not plugged
+ */
+ if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
+ return;
+
+ /*
+ * was plugged, fire request_fn if queue has stuff to do
+ */
+ if (!elv_queue_empty(q))
+ q->request_fn(q);
}
+/**
+ * generic_unplug_device - fire a request queue
+ * @q: The &request_queue_t in question
+ *
+ * Description:
+ * Linux uses plugging to build bigger requests queues before letting
+ * the device have at them. If a queue is plugged, the I/O scheduler
+ * is still adding and merging requests on the queue. Once the queue
+ * gets unplugged (either by manually calling this function, or by
+ * running the tq_disk task queue), the request_fn defined for the
+ * queue is invoked and transfers started.
+ **/
void generic_unplug_device(void *data)
{
request_queue_t *q = (request_queue_t *) data;
unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&q->queue_lock, flags);
__generic_unplug_device(q);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
+}
+
+static int __blk_cleanup_queue(struct request_list *list)
+{
+ struct list_head *head = &list->free;
+ struct request *rq;
+ int i = 0;
+
+ while (!list_empty(head)) {
+ rq = list_entry(head->next, struct request, queuelist);
+ list_del(&rq->queuelist);
+ kmem_cache_free(request_cachep, rq);
+ i++;
+ }
+
+ if (i != list->count)
+ printk("request list leak!\n");
+
+ list->count = 0;
+ return i;
+}
+
+/**
+ * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
+ * @q: the request queue to be released
+ *
+ * Description:
+ * blk_cleanup_queue is the pair to blk_init_queue(). It should
+ * be called when a request queue is being released; typically
+ * when a block device is being de-registered. Currently, its
+ * primary task it to free all the &struct request structures that
+ * were allocated to the queue.
+ * Caveat:
+ * Hopefully the low level driver will have finished any
+ * outstanding requests first...
+ **/
+void blk_cleanup_queue(request_queue_t * q)
+{
+ int count = queue_nr_requests;
+
+ count -= __blk_cleanup_queue(&q->rq[READ]);
+ count -= __blk_cleanup_queue(&q->rq[WRITE]);
+
+ if (count)
+ printk("blk_cleanup_queue: leaked requests (%d)\n", count);
+
+ elevator_exit(q, &q->elevator);
+
+ memset(q, 0, sizeof(*q));
}
-static void blk_init_free_list(request_queue_t *q)
+static int blk_init_free_list(request_queue_t *q)
{
+ struct request_list *rl;
struct request *rq;
int i;
@@ -339,24 +574,34 @@ static void blk_init_free_list(request_queue_t *q)
/*
* Divide requests in half between read and write
*/
+ rl = &q->rq[READ];
for (i = 0; i < queue_nr_requests; i++) {
rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
- if (rq == NULL) {
- /* We'll get a `leaked requests' message from blk_cleanup_queue */
- printk(KERN_EMERG "blk_init_free_list: error allocating requests\n");
- break;
- }
+ if (!rq)
+ goto nomem;
+
+ /*
+ * half way through, switch to WRITE list
+ */
+ if (i == queue_nr_requests / 2)
+ rl = &q->rq[WRITE];
+
memset(rq, 0, sizeof(struct request));
rq->rq_status = RQ_INACTIVE;
- list_add(&rq->queue, &q->rq[i&1].free);
- q->rq[i&1].count++;
+ list_add(&rq->queuelist, &rl->free);
+ rl->count++;
}
- init_waitqueue_head(&q->wait_for_request);
+ init_waitqueue_head(&q->rq[READ].wait);
+ init_waitqueue_head(&q->rq[WRITE].wait);
spin_lock_init(&q->queue_lock);
+ return 0;
+nomem:
+ blk_cleanup_queue(q);
+ return 1;
}
-static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh);
+static int __make_request(request_queue_t *, struct bio *);
/**
* blk_init_queue - prepare a request queue for use with a block device
@@ -379,45 +624,50 @@ static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh);
* requests on the queue, it is responsible for arranging that the requests
* get dealt with eventually.
*
- * A global spin lock $io_request_lock must be held while manipulating the
- * requests on the request queue.
- *
- * The request on the head of the queue is by default assumed to be
- * potentially active, and it is not considered for re-ordering or merging
- * whenever the given queue is unplugged. This behaviour can be changed with
- * blk_queue_headactive().
+ * The queue spin lock must be held while manipulating the requests on the
+ * request queue.
*
* Note:
* blk_init_queue() must be paired with a blk_cleanup_queue() call
* when the block device is deactivated (such as at module unload).
**/
-void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
+int blk_init_queue(request_queue_t *q, request_fn_proc *rfn)
{
- INIT_LIST_HEAD(&q->queue_head);
- elevator_init(&q->elevator, ELEVATOR_LINUS);
- blk_init_free_list(q);
+ int ret;
+
+ if (blk_init_free_list(q))
+ return -ENOMEM;
+
+ if ((ret = elevator_init(q, &q->elevator, ELEVATOR_LINUS))) {
+ blk_cleanup_queue(q);
+ return ret;
+ }
+
q->request_fn = rfn;
q->back_merge_fn = ll_back_merge_fn;
q->front_merge_fn = ll_front_merge_fn;
q->merge_requests_fn = ll_merge_requests_fn;
- q->make_request_fn = __make_request;
+ q->prep_rq_fn = ll_10byte_cmd_build;
q->plug_tq.sync = 0;
q->plug_tq.routine = &generic_unplug_device;
q->plug_tq.data = q;
- q->plugged = 0;
+ q->queue_flags = (1 << QUEUE_FLAG_CLUSTER);
+
/*
- * These booleans describe the queue properties. We set the
- * default (and most common) values here. Other drivers can
- * use the appropriate functions to alter the queue properties.
- * as appropriate.
+ * by default assume old behaviour and bounce for any highmem page
*/
- q->plug_device_fn = generic_plug_device;
- q->head_active = 1;
+ blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
+
+ blk_queue_segment_boundary(q, 0xffffffff);
+
+ blk_queue_make_request(q, __make_request);
+ blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
+ return 0;
}
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
+#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
/*
- * Get a free request. io_request_lock must be held and interrupts
+ * Get a free request. queue lock must be held and interrupts
* disabled on the way in.
*/
static inline struct request *get_request(request_queue_t *q, int rw)
@@ -427,11 +677,13 @@ static inline struct request *get_request(request_queue_t *q, int rw)
if (!list_empty(&rl->free)) {
rq = blkdev_free_rq(&rl->free);
- list_del(&rq->queue);
+ list_del(&rq->queuelist);
rl->count--;
+ rq->flags = 0;
rq->rq_status = RQ_ACTIVE;
rq->special = NULL;
rq->q = q;
+ rq->rl = rl;
}
return rq;
@@ -440,36 +692,46 @@ static inline struct request *get_request(request_queue_t *q, int rw)
/*
* No available requests for this queue, unplug the device.
*/
-static struct request *__get_request_wait(request_queue_t *q, int rw)
+static struct request *get_request_wait(request_queue_t *q, int rw)
{
- register struct request *rq;
DECLARE_WAITQUEUE(wait, current);
+ struct request_list *rl = &q->rq[rw];
+ struct request *rq;
+
+ spin_lock_prefetch(&q->queue_lock);
generic_unplug_device(q);
- add_wait_queue(&q->wait_for_request, &wait);
+ add_wait_queue(&rl->wait, &wait);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (q->rq[rw].count < batch_requests)
+ if (rl->count < batch_requests)
schedule();
- spin_lock_irq(&io_request_lock);
- rq = get_request(q,rw);
- spin_unlock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
+ rq = get_request(q, rw);
+ spin_unlock_irq(&q->queue_lock);
} while (rq == NULL);
- remove_wait_queue(&q->wait_for_request, &wait);
+ remove_wait_queue(&rl->wait, &wait);
current->state = TASK_RUNNING;
return rq;
}
-static inline struct request *get_request_wait(request_queue_t *q, int rw)
+struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
{
- register struct request *rq;
+ struct request *rq;
+
+ BUG_ON(rw != READ && rw != WRITE);
- spin_lock_irq(&io_request_lock);
rq = get_request(q, rw);
- spin_unlock_irq(&io_request_lock);
- if (rq)
- return rq;
- return __get_request_wait(q, rw);
+
+ if (!rq && (gfp_mask & __GFP_WAIT))
+ rq = get_request_wait(q, rw);
+
+ return rq;
+}
+
+void blk_put_request(struct request *rq)
+{
+ blkdev_release_request(rq);
}
/* RO fail safe mechanism */
@@ -497,13 +759,13 @@ void set_device_ro(kdev_t dev,int flag)
else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
}
-inline void drive_stat_acct (kdev_t dev, int rw,
- unsigned long nr_sectors, int new_io)
+void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
{
- unsigned int major = MAJOR(dev);
+ unsigned int major = MAJOR(rq->rq_dev);
+ int rw = rq_data_dir(rq);
unsigned int index;
- index = disk_index(dev);
+ index = disk_index(rq->rq_dev);
if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
return;
@@ -520,204 +782,235 @@ inline void drive_stat_acct (kdev_t dev, int rw,
/*
* add-request adds a request to the linked list.
- * io_request_lock is held and interrupts disabled, as we muck with the
+ * queue lock is held and interrupts disabled, as we muck with the
* request queue list.
- *
- * By this point, req->cmd is always either READ/WRITE, never READA,
- * which is important for drive_stat_acct() above.
*/
static inline void add_request(request_queue_t * q, struct request * req,
struct list_head *insert_here)
{
- drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1);
+ drive_stat_acct(req, req->nr_sectors, 1);
+
+ /*
+ * debug stuff...
+ */
+ if (insert_here == &q->queue_head) {
+ struct request *__rq = __elv_next_request(q);
- if (!q->plugged && q->head_active && insert_here == &q->queue_head) {
- spin_unlock_irq(&io_request_lock);
- BUG();
+ BUG_ON(__rq && (__rq->flags & REQ_STARTED));
}
/*
* elevator indicated where it wants this request to be
* inserted at elevator_merge time
*/
- list_add(&req->queue, insert_here);
+ q->elevator.elevator_add_req_fn(q, req, insert_here);
}
/*
- * Must be called with io_request_lock held and interrupts disabled
+ * Must be called with queue lock held and interrupts disabled
*/
-inline void blkdev_release_request(struct request *req)
+void blkdev_release_request(struct request *req)
{
- request_queue_t *q = req->q;
- int rw = req->cmd;
+ struct request_list *rl = req->rl;
req->rq_status = RQ_INACTIVE;
req->q = NULL;
+ req->rl = NULL;
/*
* Request may not have originated from ll_rw_blk. if not,
- * assume it has free buffers and check waiters
+ * it didn't come out of our reserved rq pools
*/
- if (q) {
- list_add(&req->queue, &q->rq[rw].free);
- if (++q->rq[rw].count >= batch_requests && waitqueue_active(&q->wait_for_request))
- wake_up(&q->wait_for_request);
+ if (rl) {
+ list_add(&req->queuelist, &rl->free);
+
+ if (++rl->count >= batch_requests &&waitqueue_active(&rl->wait))
+ wake_up(&rl->wait);
}
}
/*
* Has to be called with the request spinlock acquired
*/
-static void attempt_merge(request_queue_t * q,
- struct request *req,
- int max_sectors,
- int max_segments)
+static void attempt_merge(request_queue_t *q, struct request *req)
{
- struct request *next;
-
- next = blkdev_next_request(req);
+ struct request *next = blkdev_next_request(req);
+
+ /*
+ * not a rw command
+ */
+ if (!(next->flags & REQ_CMD))
+ return;
+
+ /*
+ * not contigious
+ */
if (req->sector + req->nr_sectors != next->sector)
return;
- if (req->cmd != next->cmd
+
+ /*
+ * don't touch NOMERGE rq, or one that has been started by driver
+ */
+ if (next->flags & (REQ_NOMERGE | REQ_STARTED))
+ return;
+
+ if (rq_data_dir(req) != rq_data_dir(next)
|| req->rq_dev != next->rq_dev
- || req->nr_sectors + next->nr_sectors > max_sectors
- || next->waiting)
+ || req->nr_sectors + next->nr_sectors > q->max_sectors
+ || next->waiting || next->special)
return;
+
/*
* If we are not allowed to merge these requests, then
* return. If we are allowed to merge, then the count
* will have been updated to the appropriate number,
* and we shouldn't do it here too.
*/
- if (!q->merge_requests_fn(q, req, next, max_segments))
- return;
+ if (q->merge_requests_fn(q, req, next)) {
+ q->elevator.elevator_merge_req_fn(req, next);
+
+ blkdev_dequeue_request(next);
+
+ req->biotail->bi_next = next->bio;
+ req->biotail = next->biotail;
- q->elevator.elevator_merge_req_fn(req, next);
- req->bhtail->b_reqnext = next->bh;
- req->bhtail = next->bhtail;
- req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
- list_del(&next->queue);
- blkdev_release_request(next);
+ req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
+
+ blkdev_release_request(next);
+ }
}
-static inline void attempt_back_merge(request_queue_t * q,
- struct request *req,
- int max_sectors,
- int max_segments)
+static inline void attempt_back_merge(request_queue_t *q, struct request *rq)
{
- if (&req->queue == q->queue_head.prev)
- return;
- attempt_merge(q, req, max_sectors, max_segments);
+ if (&rq->queuelist != q->queue_head.prev)
+ attempt_merge(q, rq);
}
-static inline void attempt_front_merge(request_queue_t * q,
- struct list_head * head,
- struct request *req,
- int max_sectors,
- int max_segments)
+static inline void attempt_front_merge(request_queue_t *q,
+ struct list_head *head,
+ struct request *rq)
{
- struct list_head * prev;
+ struct list_head *prev = rq->queuelist.prev;
- prev = req->queue.prev;
- if (head == prev)
- return;
- attempt_merge(q, blkdev_entry_to_request(prev), max_sectors, max_segments);
+ if (prev != head)
+ attempt_merge(q, blkdev_entry_to_request(prev));
}
-static int __make_request(request_queue_t * q, int rw,
- struct buffer_head * bh)
+static inline void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
{
- unsigned int sector, count;
- int max_segments = MAX_SEGMENTS;
- struct request * req, *freereq = NULL;
- int rw_ahead, max_sectors, el_ret;
- struct list_head *head, *insert_here;
- int latency;
- elevator_t *elevator = &q->elevator;
-
- count = bh->b_size >> 9;
- sector = bh->b_rsector;
+ if (rq->queuelist.next != &q->queue_head)
+ attempt_merge(q, rq);
+}
- rw_ahead = 0; /* normal case; gets changed below for READA */
- switch (rw) {
- case READA:
- rw_ahead = 1;
- rw = READ; /* drop into READ */
- case READ:
- case WRITE:
- latency = elevator_request_latency(elevator, rw);
- break;
- default:
- BUG();
- goto end_io;
- }
+/**
+ * blk_attempt_remerge - attempt to remerge active head with next request
+ * @q: The &request_queue_t belonging to the device
+ * @rq: The head request (usually)
+ *
+ * Description:
+ * For head-active devices, the queue can easily be unplugged so quickly
+ * that proper merging is not done on the front request. This may hurt
+ * performance greatly for some devices. The block layer cannot safely
+ * do merging on that first request for these queues, but the driver can
+ * call this function and make it happen any way. Only the driver knows
+ * when it is safe to do so.
+ **/
+void blk_attempt_remerge(request_queue_t *q, struct request *rq)
+{
+ unsigned long flags;
- /* We'd better have a real physical mapping!
- Check this bit only if the buffer was dirty and just locked
- down by us so at this point flushpage will block and
- won't clear the mapped bit under us. */
- if (!buffer_mapped(bh))
- BUG();
+ spin_lock_irqsave(&q->queue_lock, flags);
+ __blk_attempt_remerge(q, rq);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
+}
- /*
- * Temporary solution - in 2.5 this will be done by the lowlevel
- * driver. Create a bounce buffer if the buffer data points into
- * high memory - keep the original buffer otherwise.
- */
-#if CONFIG_HIGHMEM
- bh = create_bounce(rw, bh);
+static int __make_request(request_queue_t *q, struct bio *bio)
+{
+ struct request *req, *freereq = NULL;
+ int el_ret, latency = 0, rw, nr_sectors, cur_nr_sectors, barrier;
+ struct list_head *head, *insert_here;
+ elevator_t *elevator = &q->elevator;
+ sector_t sector;
+
+ sector = bio->bi_sector;
+ nr_sectors = bio_sectors(bio);
+ cur_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+ rw = bio_data_dir(bio);
+
+#error ONLY RUN 2.5.1-PRE KERNELS IF LOSING YOUR FILESYSTEMS IS OK
+#if 0
+ if (rw & WRITE) {
+ set_bit(BIO_UPTODATE, &bio->bi_flags);
+ bio->bi_end_io(bio, nr_sectors);
+ return 0;
+ }
#endif
-
-/* look for a free request. */
/*
- * Try to coalesce the new request with old requests
+ * low level driver can indicate that it wants pages above a
+ * certain limit bounced to low memory (ie for highmem, or even
+ * ISA dma in theory)
*/
- max_sectors = get_max_sectors(bh->b_rdev);
+ blk_queue_bounce(q, &bio);
+
+ spin_lock_prefetch(&q->queue_lock);
+
+ latency = elevator_request_latency(elevator, rw);
+ barrier = test_bit(BIO_RW_BARRIER, &bio->bi_rw);
again:
req = NULL;
head = &q->queue_head;
- /*
- * Now we acquire the request spinlock, we have to be mega careful
- * not to schedule or do something nonatomic
- */
- spin_lock_irq(&io_request_lock);
+
+ spin_lock_irq(&q->queue_lock);
insert_here = head->prev;
- if (list_empty(head)) {
- q->plug_device_fn(q, bh->b_rdev); /* is atomic */
+ if (blk_queue_empty(q) || barrier) {
+ blk_plug_device(q);
goto get_rq;
- } else if (q->head_active && !q->plugged)
- head = head->next;
+ } else if ((req = __elv_next_request(q))) {
+ if (req->flags & REQ_STARTED)
+ head = head->next;
- el_ret = elevator->elevator_merge_fn(q, &req, head, bh, rw,max_sectors);
- switch (el_ret) {
+ req = NULL;
+ }
+ el_ret = elevator->elevator_merge_fn(q, &req, head, bio);
+ switch (el_ret) {
case ELEVATOR_BACK_MERGE:
- if (!q->back_merge_fn(q, req, bh, max_segments))
+ BUG_ON(req->flags & REQ_STARTED);
+ BUG_ON(req->flags & REQ_NOMERGE);
+ if (!q->back_merge_fn(q, req, bio))
break;
- elevator->elevator_merge_cleanup_fn(q, req, count);
- req->bhtail->b_reqnext = bh;
- req->bhtail = bh;
- req->nr_sectors = req->hard_nr_sectors += count;
- blk_started_io(count);
- drive_stat_acct(req->rq_dev, req->cmd, count, 0);
- attempt_back_merge(q, req, max_sectors, max_segments);
+ elevator->elevator_merge_cleanup_fn(q, req, nr_sectors);
+
+ req->biotail->bi_next = bio;
+ req->biotail = bio;
+ req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+ drive_stat_acct(req, nr_sectors, 0);
+ attempt_back_merge(q, req);
goto out;
case ELEVATOR_FRONT_MERGE:
- if (!q->front_merge_fn(q, req, bh, max_segments))
+ BUG_ON(req->flags & REQ_STARTED);
+ BUG_ON(req->flags & REQ_NOMERGE);
+ if (!q->front_merge_fn(q, req, bio))
break;
- elevator->elevator_merge_cleanup_fn(q, req, count);
- bh->b_reqnext = req->bh;
- req->bh = bh;
- req->buffer = bh->b_data;
- req->current_nr_sectors = count;
+ elevator->elevator_merge_cleanup_fn(q, req, nr_sectors);
+
+ bio->bi_next = req->bio;
+ req->bio = bio;
+ /*
+ * may not be valid. if the low level driver said
+ * it didn't need a bounce buffer then it better
+ * not touch req->buffer either...
+ */
+ req->buffer = bio_data(bio);
+ req->current_nr_sectors = cur_nr_sectors;
+ req->hard_cur_sectors = cur_nr_sectors;
req->sector = req->hard_sector = sector;
- req->nr_sectors = req->hard_nr_sectors += count;
- blk_started_io(count);
- drive_stat_acct(req->rq_dev, req->cmd, count, 0);
- attempt_front_merge(q, head, req, max_sectors, max_segments);
+ req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+ drive_stat_acct(req, nr_sectors, 0);
+ attempt_front_merge(q, head, req);
goto out;
/*
@@ -730,14 +1023,14 @@ again:
* of the queue
*/
if (req)
- insert_here = &req->queue;
+ insert_here = &req->queuelist;
break;
default:
printk("elevator returned crap (%d)\n", el_ret);
BUG();
}
-
+
/*
* Grab a free request from the freelist - if that is empty, check
* if we are doing read ahead and abort instead of blocking for
@@ -748,107 +1041,140 @@ get_rq:
req = freereq;
freereq = NULL;
} else if ((req = get_request(q, rw)) == NULL) {
- spin_unlock_irq(&io_request_lock);
- if (rw_ahead)
+
+ spin_unlock_irq(&q->queue_lock);
+
+ /*
+ * READA bit set
+ */
+ if (bio->bi_rw & (1 << BIO_RW_AHEAD)) {
+ set_bit(BIO_RW_BLOCK, &bio->bi_flags);
goto end_io;
+ }
- freereq = __get_request_wait(q, rw);
+ freereq = get_request_wait(q, rw);
goto again;
}
-/* fill up the request-info, and add it to the queue */
+ /*
+ * fill up the request-info, and add it to the queue
+ */
req->elevator_sequence = latency;
- req->cmd = rw;
+
+ /*
+ * first three bits are identical in rq->flags and bio->bi_rw,
+ * see bio.h and blkdev.h
+ */
+ req->flags = (bio->bi_rw & 7) | REQ_CMD;
+
+ /*
+ * REQ_BARRIER implies no merging, but lets make it explicit
+ */
+ if (barrier)
+ req->flags |= (REQ_BARRIER | REQ_NOMERGE);
+
req->errors = 0;
req->hard_sector = req->sector = sector;
- req->hard_nr_sectors = req->nr_sectors = count;
- req->current_nr_sectors = count;
- req->nr_segments = 1; /* Always 1 for a new request. */
- req->nr_hw_segments = 1; /* Always 1 for a new request. */
- req->buffer = bh->b_data;
+ req->hard_nr_sectors = req->nr_sectors = nr_sectors;
+ req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors;
+ req->nr_segments = bio->bi_vcnt;
+ req->nr_hw_segments = req->nr_segments;
+ req->buffer = bio_data(bio); /* see ->buffer comment above */
req->waiting = NULL;
- req->bh = bh;
- req->bhtail = bh;
- req->rq_dev = bh->b_rdev;
- blk_started_io(count);
+ req->bio = req->biotail = bio;
+ req->rq_dev = bio->bi_dev;
add_request(q, req, insert_here);
out:
if (freereq)
blkdev_release_request(freereq);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
return 0;
+
end_io:
- bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+ bio->bi_end_io(bio, nr_sectors);
return 0;
}
+
+/*
+ * If bio->bi_dev is a partition, remap the location
+ */
+static inline void blk_partition_remap(struct bio *bio)
+{
+ int major, minor, drive, minor0;
+ struct gendisk *g;
+ kdev_t dev0;
+
+ major = MAJOR(bio->bi_dev);
+ if ((g = get_gendisk(bio->bi_dev))) {
+ minor = MINOR(bio->bi_dev);
+ drive = (minor >> g->minor_shift);
+ minor0 = (drive << g->minor_shift); /* whole disk device */
+ /* that is, minor0 = (minor & ~((1<<g->minor_shift)-1)); */
+ dev0 = MKDEV(major, minor0);
+ if (dev0 != bio->bi_dev) {
+ bio->bi_dev = dev0;
+ bio->bi_sector += g->part[minor].start_sect;
+ }
+ /* lots of checks are possible */
+ }
+}
+
/**
- * generic_make_request: hand a buffer head to it's device driver for I/O
- * @rw: READ, WRITE, or READA - what sort of I/O is desired.
- * @bh: The buffer head describing the location in memory and on the device.
+ * generic_make_request: hand a buffer to it's device driver for I/O
+ * @bio: The bio describing the location in memory and on the device.
*
* generic_make_request() is used to make I/O requests of block
- * devices. It is passed a &struct buffer_head and a &rw value. The
- * %READ and %WRITE options are (hopefully) obvious in meaning. The
- * %READA value means that a read is required, but that the driver is
- * free to fail the request if, for example, it cannot get needed
- * resources immediately.
+ * devices. It is passed a &struct bio, which describes the I/O that needs
+ * to be done.
*
* generic_make_request() does not return any status. The
* success/failure status of the request, along with notification of
- * completion, is delivered asynchronously through the bh->b_end_io
+ * completion, is delivered asynchronously through the bio->bi_end_io
* function described (one day) else where.
*
- * The caller of generic_make_request must make sure that b_page,
- * b_addr, b_size are set to describe the memory buffer, that b_rdev
- * and b_rsector are set to describe the device address, and the
- * b_end_io and optionally b_private are set to describe how
- * completion notification should be signaled. BH_Mapped should also
- * be set (to confirm that b_dev and b_blocknr are valid).
+ * The caller of generic_make_request must make sure that bi_io_vec
+ * are set to describe the memory buffer, and that bi_dev and bi_sector are
+ * set to describe the device address, and the
+ * bi_end_io and optionally bi_private are set to describe how
+ * completion notification should be signaled.
*
- * generic_make_request and the drivers it calls may use b_reqnext,
- * and may change b_rdev and b_rsector. So the values of these fields
+ * generic_make_request and the drivers it calls may use bi_next if this
+ * bio happens to be merged with someone else, and may change bi_dev and
+ * bi_sector for remaps as it sees fit. So the values of these fields
* should NOT be depended on after the call to generic_make_request.
- * Because of this, the caller should record the device address
- * information in b_dev and b_blocknr.
*
- * Apart from those fields mentioned above, no other fields, and in
- * particular, no other flags, are changed by generic_make_request or
- * any lower level drivers.
* */
-void generic_make_request (int rw, struct buffer_head * bh)
+void generic_make_request(struct bio *bio)
{
- int major = MAJOR(bh->b_rdev);
- int minorsize = 0;
+ int major = MAJOR(bio->bi_dev);
+ int minor = MINOR(bio->bi_dev);
request_queue_t *q;
+ sector_t minorsize = 0;
+ int nr_sectors = bio_sectors(bio);
- if (!bh->b_end_io)
- BUG();
-
- /* Test device size, when known. */
+ /* Test device or partition size, when known. */
if (blk_size[major])
- minorsize = blk_size[major][MINOR(bh->b_rdev)];
+ minorsize = blk_size[major][minor];
if (minorsize) {
unsigned long maxsector = (minorsize << 1) + 1;
- unsigned long sector = bh->b_rsector;
- unsigned int count = bh->b_size >> 9;
-
- if (maxsector < count || maxsector - count < sector) {
- /* Yecch */
- bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped);
-
- /* This may well happen - the kernel calls bread()
- without checking the size of the device, e.g.,
- when mounting a device. */
- printk(KERN_INFO
- "attempt to access beyond end of device\n");
- printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n",
- kdevname(bh->b_rdev), rw,
- (sector + count)>>1, minorsize);
-
- /* Yecch again */
- bh->b_end_io(bh, 0);
- return;
+ unsigned long sector = bio->bi_sector;
+
+ if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
+ if (blk_size[major][minor]) {
+
+ /* This may well happen - the kernel calls
+ * bread() without checking the size of the
+ * device, e.g., when mounting a device. */
+ printk(KERN_INFO
+ "attempt to access beyond end of device\n");
+ printk(KERN_INFO "%s: rw=%ld, want=%ld, limit=%Lu\n",
+ kdevname(bio->bi_dev), bio->bi_rw,
+ (sector + nr_sectors)>>1,
+ (long long) blk_size[major][minor]);
+ }
+ set_bit(BIO_EOF, &bio->bi_flags);
+ goto end_io;
}
}
@@ -856,63 +1182,120 @@ void generic_make_request (int rw, struct buffer_head * bh)
* Resolve the mapping until finished. (drivers are
* still free to implement/resolve their own stacking
* by explicitly returning 0)
- */
- /* NOTE: we don't repeat the blk_size check for each new device.
+ *
+ * NOTE: we don't repeat the blk_size check for each new device.
* Stacking drivers are expected to know what they are doing.
*/
do {
- q = blk_get_queue(bh->b_rdev);
+ q = blk_get_queue(bio->bi_dev);
if (!q) {
printk(KERN_ERR
- "generic_make_request: Trying to access "
- "nonexistent block-device %s (%ld)\n",
- kdevname(bh->b_rdev), bh->b_rsector);
- buffer_IO_error(bh);
+ "generic_make_request: Trying to access nonexistent block-device %s (%Lu)\n",
+ kdevname(bio->bi_dev), (long long) bio->bi_sector);
+end_io:
+ bio->bi_end_io(bio, nr_sectors);
break;
}
- } while (q->make_request_fn(q, rw, bh));
+
+ /*
+ * this needs to be handled by q->make_request_fn, to just
+ * setup a part of the bio in the request to enable easy
+ * multiple passing
+ */
+ BUG_ON(bio_sectors(bio) > q->max_sectors);
+
+ /*
+ * If this device has partitions, remap block n
+ * of partition p to block n+start(p) of the disk.
+ */
+ blk_partition_remap(bio);
+
+ } while (q->make_request_fn(q, bio));
}
+/*
+ * our default bio end_io callback handler for a buffer_head mapping.
+ */
+static int end_bio_bh_io_sync(struct bio *bio, int nr_sectors)
+{
+ struct buffer_head *bh = bio->bi_private;
+
+ BIO_BUG_ON(nr_sectors != (bh->b_size >> 9));
+
+ bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags));
+ bio_put(bio);
+ return 0;
+}
/**
- * submit_bh: submit a buffer_head to the block device later for I/O
+ * submit_bio: submit a bio to the block device layer for I/O
* @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
- * @bh: The &struct buffer_head which describes the I/O
+ * @bio: The &struct bio which describes the I/O
*
- * submit_bh() is very similar in purpose to generic_make_request(), and
- * uses that function to do most of the work.
+ * submit_bio() is very similar in purpose to generic_make_request(), and
+ * uses that function to do most of the work. Both are fairly rough
+ * interfaces, @bio must be presetup and ready for I/O.
*
- * The extra functionality provided by submit_bh is to determine
- * b_rsector from b_blocknr and b_size, and to set b_rdev from b_dev.
- * This is is appropriate for IO requests that come from the buffer
- * cache and page cache which (currently) always use aligned blocks.
*/
-void submit_bh(int rw, struct buffer_head * bh)
+int submit_bio(int rw, struct bio *bio)
+{
+ int count = bio_sectors(bio);
+
+ /*
+ * do some validity checks...
+ */
+ BUG_ON(!bio->bi_end_io);
+
+ BIO_BUG_ON(!bio->bi_size);
+ BIO_BUG_ON(!bio->bi_io_vec);
+
+ bio->bi_rw = rw;
+
+ if (rw & WRITE)
+ kstat.pgpgout += count;
+ else
+ kstat.pgpgin += count;
+
+ generic_make_request(bio);
+ return 1;
+}
+
+/**
+ * submit_bh: submit a buffer_head to the block device layer for I/O
+ * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
+ * @bh: The &struct buffer_head which describes the I/O
+ *
+ **/
+int submit_bh(int rw, struct buffer_head * bh)
{
- int count = bh->b_size >> 9;
+ struct bio *bio;
- if (!test_bit(BH_Lock, &bh->b_state))
- BUG();
+ BUG_ON(!test_bit(BH_Lock, &bh->b_state));
+ BUG_ON(!buffer_mapped(bh));
+ BUG_ON(!bh->b_end_io);
set_bit(BH_Req, &bh->b_state);
/*
- * First step, 'identity mapping' - RAID or LVM might
- * further remap this.
+ * from here on down, it's all bio -- do the initial mapping,
+ * submit_bio -> generic_make_request may further map this bio around
*/
- bh->b_rdev = bh->b_dev;
- bh->b_rsector = bh->b_blocknr * count;
+ bio = bio_alloc(GFP_NOIO, 1);
- generic_make_request(rw, bh);
+ bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+ bio->bi_dev = bh->b_dev;
+ bio->bi_io_vec[0].bv_page = bh->b_page;
+ bio->bi_io_vec[0].bv_len = bh->b_size;
+ bio->bi_io_vec[0].bv_offset = bh_offset(bh);
- switch (rw) {
- case WRITE:
- kstat.pgpgout += count;
- break;
- default:
- kstat.pgpgin += count;
- break;
- }
+ bio->bi_vcnt = 1;
+ bio->bi_idx = 0;
+ bio->bi_size = bh->b_size;
+
+ bio->bi_end_io = end_bio_bh_io_sync;
+ bio->bi_private = bh;
+
+ return submit_bio(rw, bio);
}
/**
@@ -944,8 +1327,9 @@ void submit_bh(int rw, struct buffer_head * bh)
*
* Caveat:
* All of the buffers must be for the same device, and must also be
- * of the current approved size for the device. */
-
+ * a multiple of the current approved size for the device.
+ *
+ **/
void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
{
unsigned int major;
@@ -963,7 +1347,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
/* Verify requested block sizes. */
for (i = 0; i < nr; i++) {
struct buffer_head *bh = bhs[i];
- if (bh->b_size % correct_size) {
+ if (bh->b_size & (correct_size - 1)) {
printk(KERN_NOTICE "ll_rw_block: device %s: "
"only %d-char blocks implemented (%u)\n",
kdevname(bhs[0]->b_dev),
@@ -1024,12 +1408,33 @@ sorry:
extern int stram_device_init (void);
#endif
+inline void blk_recalc_request(struct request *rq, int nsect)
+{
+ rq->hard_sector += nsect;
+ rq->hard_nr_sectors -= nsect;
+ rq->sector = rq->hard_sector;
+ rq->nr_sectors = rq->hard_nr_sectors;
+
+ rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+ rq->hard_cur_sectors = rq->current_nr_sectors;
+
+ /*
+ * if total number of sectors is less than the first segment
+ * size, something has gone terribly wrong
+ */
+ if (rq->nr_sectors < rq->current_nr_sectors) {
+ printk("blk: request botched\n");
+ rq->nr_sectors = rq->current_nr_sectors;
+ }
+
+ rq->buffer = bio_data(rq->bio);
+}
/**
* end_that_request_first - end I/O on one buffer.
* @req: the request being processed
* @uptodate: 0 for I/O error
- * @name: the name printed for an I/O error
+ * @nr_sectors: number of sectors to end I/O on
*
* Description:
* Ends I/O on the first buffer attached to @req, and sets it up
@@ -1038,49 +1443,65 @@ extern int stram_device_init (void);
* Return:
* 0 - we are done with this request, call end_that_request_last()
* 1 - still buffers pending for this request
- *
- * Caveat:
- * Drivers implementing their own end_request handling must call
- * blk_finished_io() appropriately.
**/
-int end_that_request_first (struct request *req, int uptodate, char *name)
+int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
{
- struct buffer_head * bh;
- int nsect;
+ int nsect, total_nsect;
+ struct bio *bio;
req->errors = 0;
if (!uptodate)
- printk("end_request: I/O error, dev %s (%s), sector %lu\n",
- kdevname(req->rq_dev), name, req->sector);
-
- if ((bh = req->bh) != NULL) {
- nsect = bh->b_size >> 9;
- blk_finished_io(nsect);
- req->bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- bh->b_end_io(bh, uptodate);
- if ((bh = req->bh) != NULL) {
- req->hard_sector += nsect;
- req->hard_nr_sectors -= nsect;
- req->sector = req->hard_sector;
- req->nr_sectors = req->hard_nr_sectors;
-
- req->current_nr_sectors = bh->b_size >> 9;
- if (req->nr_sectors < req->current_nr_sectors) {
- req->nr_sectors = req->current_nr_sectors;
- printk("end_request: buffer-list destroyed\n");
- }
- req->buffer = bh->b_data;
+ printk("end_request: I/O error, dev %s, sector %lu\n",
+ kdevname(req->rq_dev), req->sector);
+
+ total_nsect = 0;
+ while ((bio = req->bio)) {
+ nsect = bio_iovec(bio)->bv_len >> 9;
+
+ bio->bi_size -= bio_iovec(bio)->bv_len;
+
+ /*
+ * not a complete bvec done
+ */
+ if (unlikely(nsect > nr_sectors)) {
+ int residual = (nsect - nr_sectors) << 9;
+
+ bio_iovec(bio)->bv_offset += residual;
+ bio_iovec(bio)->bv_len -= residual;
+ blk_recalc_request(req, nr_sectors);
return 1;
}
+
+ nr_sectors -= nsect;
+ total_nsect += nsect;
+
+ if (++bio->bi_idx >= bio->bi_vcnt) {
+ req->bio = bio->bi_next;
+
+ if (unlikely(bio_endio(bio, uptodate, total_nsect)))
+ BUG();
+
+ total_nsect = 0;
+ }
+
+ if ((bio = req->bio)) {
+ blk_recalc_request(req, nsect);
+
+ /*
+ * end more in this run, or just return 'not-done'
+ */
+ if (unlikely(nr_sectors <= 0))
+ return 1;
+ }
}
+
return 0;
}
void end_that_request_last(struct request *req)
{
- if (req->waiting != NULL)
+ if (req->waiting)
complete(req->waiting);
blkdev_release_request(req);
@@ -1105,7 +1526,6 @@ int __init blk_dev_init(void)
memset(ro_bits,0,sizeof(ro_bits));
memset(max_readahead, 0, sizeof(max_readahead));
- memset(max_sectors, 0, sizeof(max_sectors));
total_ram = nr_free_pages() << (PAGE_SHIFT - 10);
@@ -1115,129 +1535,48 @@ int __init blk_dev_init(void)
*/
queue_nr_requests = 64;
if (total_ram > MB(32))
- queue_nr_requests = 128;
+ queue_nr_requests = 256;
/*
* Batch frees according to queue length
*/
- batch_requests = queue_nr_requests/4;
+ if ((batch_requests = queue_nr_requests / 4) > 32)
+ batch_requests = 32;
printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests);
-#ifdef CONFIG_AMIGA_Z2RAM
- z2_init();
-#endif
-#ifdef CONFIG_STRAM_SWAP
- stram_device_init();
-#endif
-#ifdef CONFIG_BLK_DEV_RAM
- rd_init();
-#endif
-#ifdef CONFIG_ISP16_CDI
- isp16_init();
-#endif
+ blk_max_low_pfn = max_low_pfn;
+ blk_max_pfn = max_pfn;
+
#if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_IDE)
ide_init(); /* this MUST precede hd_init */
#endif
#if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD)
hd_init();
#endif
-#ifdef CONFIG_BLK_DEV_PS2
- ps2esdi_init();
-#endif
-#ifdef CONFIG_BLK_DEV_XD
- xd_init();
-#endif
-#ifdef CONFIG_BLK_DEV_MFM
- mfm_init();
-#endif
-#ifdef CONFIG_PARIDE
- { extern void paride_init(void); paride_init(); };
-#endif
-#ifdef CONFIG_MAC_FLOPPY
- swim3_init();
-#endif
-#ifdef CONFIG_BLK_DEV_SWIM_IOP
- swimiop_init();
-#endif
-#ifdef CONFIG_AMIGA_FLOPPY
- amiga_floppy_init();
-#endif
-#ifdef CONFIG_ATARI_FLOPPY
- atari_floppy_init();
-#endif
-#ifdef CONFIG_BLK_DEV_FD
- floppy_init();
-#else
#if defined(__i386__) /* Do we even need this? */
outb_p(0xc, 0x3f2);
#endif
-#endif
-#ifdef CONFIG_CDU31A
- cdu31a_init();
-#endif
-#ifdef CONFIG_ATARI_ACSI
- acsi_init();
-#endif
-#ifdef CONFIG_MCD
- mcd_init();
-#endif
-#ifdef CONFIG_MCDX
- mcdx_init();
-#endif
-#ifdef CONFIG_SBPCD
- sbpcd_init();
-#endif
-#ifdef CONFIG_AZTCD
- aztcd_init();
-#endif
-#ifdef CONFIG_CDU535
- sony535_init();
-#endif
-#ifdef CONFIG_GSCD
- gscd_init();
-#endif
-#ifdef CONFIG_CM206
- cm206_init();
-#endif
-#ifdef CONFIG_OPTCD
- optcd_init();
-#endif
-#ifdef CONFIG_SJCD
- sjcd_init();
-#endif
-#ifdef CONFIG_APBLOCK
- ap_init();
-#endif
-#ifdef CONFIG_DDV
- ddv_init();
-#endif
-#ifdef CONFIG_MDISK
- mdisk_init();
-#endif
-#ifdef CONFIG_DASD
- dasd_init();
-#endif
-#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_BLOCK)
- tapeblock_init();
-#endif
-#ifdef CONFIG_BLK_DEV_XPRAM
- xpram_init();
-#endif
-#ifdef CONFIG_SUN_JSFLASH
- jsfd_init();
-#endif
return 0;
};
-EXPORT_SYMBOL(io_request_lock);
EXPORT_SYMBOL(end_that_request_first);
EXPORT_SYMBOL(end_that_request_last);
EXPORT_SYMBOL(blk_init_queue);
EXPORT_SYMBOL(blk_get_queue);
EXPORT_SYMBOL(blk_cleanup_queue);
-EXPORT_SYMBOL(blk_queue_headactive);
EXPORT_SYMBOL(blk_queue_make_request);
+EXPORT_SYMBOL(blk_queue_bounce_limit);
EXPORT_SYMBOL(generic_make_request);
EXPORT_SYMBOL(blkdev_release_request);
EXPORT_SYMBOL(generic_unplug_device);
+EXPORT_SYMBOL(blk_attempt_remerge);
+EXPORT_SYMBOL(blk_max_low_pfn);
+EXPORT_SYMBOL(blk_queue_max_sectors);
+EXPORT_SYMBOL(blk_queue_max_segments);
+EXPORT_SYMBOL(blk_queue_max_segment_size);
+EXPORT_SYMBOL(blk_queue_hardsect_size);
+EXPORT_SYMBOL(blk_rq_map_sg);
+EXPORT_SYMBOL(blk_nohighio);
+EXPORT_SYMBOL(blk_dump_rq_flags);
+EXPORT_SYMBOL(submit_bio);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b46648a7f..b5c18e74b 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -168,8 +168,7 @@ static void figure_loop_size(struct loop_device *lo)
lo->lo_device);
}
-static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize,
- loff_t pos)
+static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
{
struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
@@ -183,8 +182,8 @@ static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize,
down(&mapping->host->i_sem);
index = pos >> PAGE_CACHE_SHIFT;
offset = pos & (PAGE_CACHE_SIZE - 1);
- len = bh->b_size;
- data = bh->b_data;
+ len = bio->bi_size;
+ data = bio_data(bio);
while (len > 0) {
int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
int transfer_result;
@@ -263,18 +262,17 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l
return size;
}
-static int lo_receive(struct loop_device *lo, struct buffer_head *bh, int bsize,
- loff_t pos)
+static int lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
{
struct lo_read_data cookie;
read_descriptor_t desc;
struct file *file;
cookie.lo = lo;
- cookie.data = bh->b_data;
+ cookie.data = bio_data(bio);
cookie.bsize = bsize;
desc.written = 0;
- desc.count = bh->b_size;
+ desc.count = bio->bi_size;
desc.buf = (char*)&cookie;
desc.error = 0;
spin_lock_irq(&lo->lo_lock);
@@ -310,46 +308,52 @@ static inline unsigned long loop_get_iv(struct loop_device *lo,
return IV;
}
-static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw)
+static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
{
loff_t pos;
int ret;
- pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset;
+ pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
- if (rw == WRITE)
- ret = lo_send(lo, bh, loop_get_bs(lo), pos);
- else
- ret = lo_receive(lo, bh, loop_get_bs(lo), pos);
+ do {
+ if (bio_rw(bio) == WRITE)
+ ret = lo_send(lo, bio, loop_get_bs(lo), pos);
+ else
+ ret = lo_receive(lo, bio, loop_get_bs(lo), pos);
+
+ } while (++bio->bi_idx < bio->bi_vcnt);
return ret;
}
-static void loop_end_io_transfer(struct buffer_head *bh, int uptodate);
-static void loop_put_buffer(struct buffer_head *bh)
+static int loop_end_io_transfer(struct bio *, int);
+static void loop_put_buffer(struct bio *bio)
{
/*
- * check b_end_io, may just be a remapped bh and not an allocated one
+ * check bi_end_io, may just be a remapped bio
*/
- if (bh && bh->b_end_io == loop_end_io_transfer) {
- __free_page(bh->b_page);
- kmem_cache_free(bh_cachep, bh);
+ if (bio && bio->bi_end_io == loop_end_io_transfer) {
+ int i;
+ for (i = 0; i < bio->bi_vcnt; i++)
+ __free_page(bio->bi_io_vec[i].bv_page);
+
+ bio_put(bio);
}
}
/*
- * Add buffer_head to back of pending list
+ * Add bio to back of pending list
*/
-static void loop_add_bh(struct loop_device *lo, struct buffer_head *bh)
+static void loop_add_bio(struct loop_device *lo, struct bio *bio)
{
unsigned long flags;
spin_lock_irqsave(&lo->lo_lock, flags);
- if (lo->lo_bhtail) {
- lo->lo_bhtail->b_reqnext = bh;
- lo->lo_bhtail = bh;
+ if (lo->lo_biotail) {
+ lo->lo_biotail->bi_next = bio;
+ lo->lo_biotail = bio;
} else
- lo->lo_bh = lo->lo_bhtail = bh;
+ lo->lo_bio = lo->lo_biotail = bio;
spin_unlock_irqrestore(&lo->lo_lock, flags);
up(&lo->lo_bh_mutex);
@@ -358,112 +362,84 @@ static void loop_add_bh(struct loop_device *lo, struct buffer_head *bh)
/*
* Grab first pending buffer
*/
-static struct buffer_head *loop_get_bh(struct loop_device *lo)
+static struct bio *loop_get_bio(struct loop_device *lo)
{
- struct buffer_head *bh;
+ struct bio *bio;
spin_lock_irq(&lo->lo_lock);
- if ((bh = lo->lo_bh)) {
- if (bh == lo->lo_bhtail)
- lo->lo_bhtail = NULL;
- lo->lo_bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
+ if ((bio = lo->lo_bio)) {
+ if (bio == lo->lo_biotail)
+ lo->lo_biotail = NULL;
+ lo->lo_bio = bio->bi_next;
+ bio->bi_next = NULL;
}
spin_unlock_irq(&lo->lo_lock);
- return bh;
+ return bio;
}
/*
- * when buffer i/o has completed. if BH_Dirty is set, this was a WRITE
- * and lo->transfer stuff has already been done. if not, it was a READ
- * so queue it for the loop thread and let it do the transfer out of
- * b_end_io context (we don't want to do decrypt of a page with irqs
+ * if this was a WRITE lo->transfer stuff has already been done. for READs,
+ * queue it for the loop thread and let it do the transfer out of
+ * bi_end_io context (we don't want to do decrypt of a page with irqs
* disabled)
*/
-static void loop_end_io_transfer(struct buffer_head *bh, int uptodate)
+static int loop_end_io_transfer(struct bio *bio, int nr_sectors)
{
- struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)];
+ struct loop_device *lo = &loop_dev[MINOR(bio->bi_dev)];
+ int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
- if (!uptodate || test_bit(BH_Dirty, &bh->b_state)) {
- struct buffer_head *rbh = bh->b_private;
+ if (!uptodate || bio_rw(bio) == WRITE) {
+ struct bio *rbh = bio->bi_private;
- rbh->b_end_io(rbh, uptodate);
+ bio_endio(rbh, uptodate, nr_sectors);
if (atomic_dec_and_test(&lo->lo_pending))
up(&lo->lo_bh_mutex);
- loop_put_buffer(bh);
+ loop_put_buffer(bio);
} else
- loop_add_bh(lo, bh);
+ loop_add_bio(lo, bio);
+
+ return 0;
}
-static struct buffer_head *loop_get_buffer(struct loop_device *lo,
- struct buffer_head *rbh)
+static struct bio *loop_get_buffer(struct loop_device *lo, struct bio *rbh)
{
- struct buffer_head *bh;
+ struct bio *bio;
/*
* for xfer_funcs that can operate on the same bh, do that
*/
if (lo->lo_flags & LO_FLAGS_BH_REMAP) {
- bh = rbh;
+ bio = rbh;
goto out_bh;
}
- do {
- bh = kmem_cache_alloc(bh_cachep, SLAB_NOIO);
- if (bh)
- break;
-
- run_task_queue(&tq_disk);
- schedule_timeout(HZ);
- } while (1);
- memset(bh, 0, sizeof(*bh));
+ bio = bio_copy(rbh, GFP_NOIO, rbh->bi_rw & WRITE);
- bh->b_size = rbh->b_size;
- bh->b_dev = rbh->b_rdev;
- bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock);
-
- /*
- * easy way out, although it does waste some memory for < PAGE_SIZE
- * blocks... if highmem bounce buffering can get away with it,
- * so can we :-)
- */
- do {
- bh->b_page = alloc_page(GFP_NOIO);
- if (bh->b_page)
- break;
-
- run_task_queue(&tq_disk);
- schedule_timeout(HZ);
- } while (1);
-
- bh->b_data = page_address(bh->b_page);
- bh->b_end_io = loop_end_io_transfer;
- bh->b_private = rbh;
- init_waitqueue_head(&bh->b_wait);
+ bio->bi_end_io = loop_end_io_transfer;
+ bio->bi_private = rbh;
out_bh:
- bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9);
+ bio->bi_sector = rbh->bi_sector + (lo->lo_offset >> 9);
+ bio->bi_rw = rbh->bi_rw;
spin_lock_irq(&lo->lo_lock);
- bh->b_rdev = lo->lo_device;
+ bio->bi_dev = lo->lo_device;
spin_unlock_irq(&lo->lo_lock);
- return bh;
+ return bio;
}
-static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh)
+static int loop_make_request(request_queue_t *q, struct bio *rbh)
{
- struct buffer_head *bh = NULL;
+ struct bio *bh = NULL;
struct loop_device *lo;
unsigned long IV;
+ int rw = bio_rw(rbh);
- if (!buffer_locked(rbh))
- BUG();
-
- if (MINOR(rbh->b_rdev) >= max_loop)
+ if (MINOR(rbh->bi_dev) >= max_loop)
goto out;
- lo = &loop_dev[MINOR(rbh->b_rdev)];
+ lo = &loop_dev[MINOR(rbh->bi_dev)];
spin_lock_irq(&lo->lo_lock);
if (lo->lo_state != Lo_bound)
goto inactive;
@@ -476,25 +452,17 @@ static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh
} else if (rw == READA) {
rw = READ;
} else if (rw != READ) {
- printk(KERN_ERR "loop: unknown command (%d)\n", rw);
+ printk(KERN_ERR "loop: unknown command (%x)\n", rw);
goto err;
}
-#if CONFIG_HIGHMEM
- rbh = create_bounce(rw, rbh);
-#endif
+ blk_queue_bounce(q, &rbh);
/*
* file backed, queue for loop_thread to handle
*/
if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
- /*
- * rbh locked at this point, noone else should clear
- * the dirty flag
- */
- if (rw == WRITE)
- set_bit(BH_Dirty, &rbh->b_state);
- loop_add_bh(lo, rbh);
+ loop_add_bio(lo, rbh);
return 0;
}
@@ -502,15 +470,14 @@ static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh
* piggy old buffer on original, and submit for I/O
*/
bh = loop_get_buffer(lo, rbh);
- IV = loop_get_iv(lo, rbh->b_rsector);
+ IV = loop_get_iv(lo, rbh->bi_sector);
if (rw == WRITE) {
- set_bit(BH_Dirty, &bh->b_state);
- if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data,
- bh->b_size, IV))
+ if (lo_do_transfer(lo, WRITE, bio_data(bh), bio_data(rbh),
+ bh->bi_size, IV))
goto err;
}
- generic_make_request(rw, bh);
+ generic_make_request(bh);
return 0;
err:
@@ -518,14 +485,32 @@ err:
up(&lo->lo_bh_mutex);
loop_put_buffer(bh);
out:
- buffer_IO_error(rbh);
+ bio_io_error(rbh);
return 0;
inactive:
spin_unlock_irq(&lo->lo_lock);
goto out;
}
-static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh)
+static int do_bio_blockbacked(struct loop_device *lo, struct bio *bio,
+ struct bio *rbh)
+{
+ unsigned long IV = loop_get_iv(lo, rbh->bi_sector);
+ struct bio_vec *to;
+ char *vto, *vfrom;
+ int ret = 0, i;
+
+ bio_for_each_segment(to, bio, i) {
+ vfrom = page_address(rbh->bi_io_vec[i].bv_page) + rbh->bi_io_vec[i].bv_offset;
+ vto = page_address(to->bv_page) + to->bv_offset;
+ ret |= lo_do_transfer(lo, bio_data_dir(bio), vto, vfrom,
+ to->bv_len, IV);
+ }
+
+ return ret;
+}
+
+static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
{
int ret;
@@ -533,19 +518,15 @@ static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh)
* For block backed loop, we know this is a READ
*/
if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
- int rw = !!test_and_clear_bit(BH_Dirty, &bh->b_state);
-
- ret = do_bh_filebacked(lo, bh, rw);
- bh->b_end_io(bh, !ret);
+ ret = do_bio_filebacked(lo, bio);
+ bio_endio(bio, !ret, bio_sectors(bio));
} else {
- struct buffer_head *rbh = bh->b_private;
- unsigned long IV = loop_get_iv(lo, rbh->b_rsector);
+ struct bio *rbh = bio->bi_private;
- ret = lo_do_transfer(lo, READ, bh->b_data, rbh->b_data,
- bh->b_size, IV);
+ ret = do_bio_blockbacked(lo, bio, rbh);
- rbh->b_end_io(rbh, !ret);
- loop_put_buffer(bh);
+ bio_endio(rbh, !ret, bio_sectors(bio));
+ loop_put_buffer(bio);
}
}
@@ -558,7 +539,7 @@ static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh)
static int loop_thread(void *data)
{
struct loop_device *lo = data;
- struct buffer_head *bh;
+ struct bio *bio;
daemonize();
exit_files(current);
@@ -592,12 +573,12 @@ static int loop_thread(void *data)
if (!atomic_read(&lo->lo_pending))
break;
- bh = loop_get_bh(lo);
- if (!bh) {
- printk("loop: missing bh\n");
+ bio = loop_get_bio(lo);
+ if (!bio) {
+ printk("loop: missing bio\n");
continue;
}
- loop_handle_bh(lo, bh);
+ loop_handle_bio(lo, bio);
/*
* upped both for pending work and tear-down, lo_pending
@@ -687,7 +668,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, kdev_t dev,
set_blocksize(dev, bs);
- lo->lo_bh = lo->lo_bhtail = NULL;
+ lo->lo_bio = lo->lo_biotail = NULL;
kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
down(&lo->lo_sem);
@@ -877,7 +858,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
err = -ENXIO;
break;
}
- err = put_user((unsigned long)loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
+ err = put_user((unsigned long) loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
break;
case BLKGETSIZE64:
if (lo->lo_state != Lo_bound) {
@@ -1023,11 +1004,11 @@ int __init loop_init(void)
loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
if (!loop_sizes)
- goto out_sizes;
+ goto out_mem;
loop_blksizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
if (!loop_blksizes)
- goto out_blksizes;
+ goto out_mem;
blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), loop_make_request);
@@ -1051,9 +1032,8 @@ int __init loop_init(void)
printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
return 0;
-out_sizes:
+out_mem:
kfree(loop_dev);
-out_blksizes:
kfree(loop_sizes);
printk(KERN_ERR "loop: ran out of memory\n");
return -ENOMEM;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 42df43b5d..22e5b4a60 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -149,30 +149,41 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
void nbd_send_req(struct socket *sock, struct request *req)
{
- int result;
+ int result, rw, i, flags;
struct nbd_request request;
unsigned long size = req->nr_sectors << 9;
DEBUG("NBD: sending control, ");
request.magic = htonl(NBD_REQUEST_MAGIC);
- request.type = htonl(req->cmd);
+ request.type = htonl(req->flags);
request.from = cpu_to_be64( (u64) req->sector << 9);
request.len = htonl(size);
memcpy(request.handle, &req, sizeof(req));
- result = nbd_xmit(1, sock, (char *) &request, sizeof(request), req->cmd == WRITE ? MSG_MORE : 0);
+ rw = rq_data_dir(req);
+
+ result = nbd_xmit(1, sock, (char *) &request, sizeof(request), rw & WRITE ? MSG_MORE : 0);
if (result <= 0)
FAIL("Sendmsg failed for control.");
- if (req->cmd == WRITE) {
- struct buffer_head *bh = req->bh;
- DEBUG("data, ");
- do {
- result = nbd_xmit(1, sock, bh->b_data, bh->b_size, bh->b_reqnext == NULL ? 0 : MSG_MORE);
- if (result <= 0)
- FAIL("Send data failed.");
- bh = bh->b_reqnext;
- } while(bh);
+ if (rw & WRITE) {
+ struct bio *bio;
+ /*
+ * we are really probing at internals to determine
+ * whether to set MSG_MORE or not...
+ */
+ rq_for_each_bio(bio, req) {
+ struct bio_vec *bvec;
+ bio_for_each_segment(bvec, bio, i) {
+ flags = 0;
+ if ((i < (bio->bi_vcnt - 1)) || bio->bi_next)
+ flags = MSG_MORE;
+ DEBUG("data, ");
+ result = nbd_xmit(1, sock, page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, flags);
+ if (result <= 0)
+ FAIL("Send data failed.");
+ }
+ }
}
return;
@@ -204,15 +215,15 @@ struct request *nbd_read_stat(struct nbd_device *lo)
HARDFAIL("Not enough magic.");
if (ntohl(reply.error))
FAIL("Other side returned error.");
- if (req->cmd == READ) {
- struct buffer_head *bh = req->bh;
+ if (rq_data_dir(req) == READ) {
+ struct bio *bio = req->bio;
DEBUG("data, ");
do {
- result = nbd_xmit(0, lo->sock, bh->b_data, bh->b_size, MSG_WAITALL);
+ result = nbd_xmit(0, lo->sock, bio_data(bio), bio->bi_size, MSG_WAITALL);
if (result <= 0)
HARDFAIL("Recv data failed.");
- bh = bh->b_reqnext;
- } while(bh);
+ bio = bio->bi_next;
+ } while(bio);
}
DEBUG("done.\n");
return req;
@@ -250,7 +261,7 @@ void nbd_do_it(struct nbd_device *lo)
goto out;
}
#endif
- list_del(&req->queue);
+ blkdev_dequeue_request(req);
up (&lo->queue_lock);
nbd_end_request(req);
@@ -285,7 +296,7 @@ void nbd_clear_que(struct nbd_device *lo)
}
#endif
req->errors++;
- list_del(&req->queue);
+ blkdev_dequeue_request(req);
up(&lo->queue_lock);
nbd_end_request(req);
@@ -321,10 +332,13 @@ static void do_nbd_request(request_queue_t * q)
if (dev >= MAX_NBD)
FAIL("Minor too big."); /* Probably can not happen */
#endif
+ if (!(req->flags & REQ_CMD))
+ goto error_out;
+
lo = &nbd_dev[dev];
if (!lo->file)
FAIL("Request when not-ready.");
- if ((req->cmd == WRITE) && (lo->flags & NBD_READ_ONLY))
+ if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_READ_ONLY))
FAIL("Write on read-only");
#ifdef PARANOIA
if (lo->magic != LO_MAGIC)
@@ -333,22 +347,22 @@ static void do_nbd_request(request_queue_t * q)
#endif
req->errors = 0;
blkdev_dequeue_request(req);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
down (&lo->queue_lock);
- list_add(&req->queue, &lo->queue_head);
+ list_add(&req->queuelist, &lo->queue_head);
nbd_send_req(lo->sock, req); /* Why does this block? */
up (&lo->queue_lock);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
continue;
error_out:
req->errors++;
blkdev_dequeue_request(req);
- spin_unlock(&io_request_lock);
+ spin_unlock(&q->queue_lock);
nbd_end_request(req);
- spin_lock(&io_request_lock);
+ spin_lock(&q->queue_lock);
}
return;
}
@@ -374,7 +388,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case NBD_DISCONNECT:
printk("NBD_DISCONNECT\n") ;
- sreq.cmd=2 ; /* shutdown command */
+ sreq.flags = REQ_SPECIAL; /* FIXME: interpet as shutdown cmd */
if (!lo->sock) return -EINVAL ;
nbd_send_req(lo->sock,&sreq) ;
return 0 ;
@@ -502,7 +516,6 @@ static int __init nbd_init(void)
blksize_size[MAJOR_NR] = nbd_blksizes;
blk_size[MAJOR_NR] = nbd_sizes;
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request);
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
for (i = 0; i < MAX_NBD; i++) {
nbd_dev[i].refcnt = 0;
nbd_dev[i].file = NULL;
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index e3048d01c..61e50fec5 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -768,7 +768,7 @@ static void do_pcd_request (request_queue_t * q)
while (1) {
if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return;
INIT_REQUEST;
- if (CURRENT->cmd == READ) {
+ if (rq_data_dir(CURRENT) == READ) {
unit = MINOR(CURRENT->rq_dev);
if (unit != pcd_unit) {
pcd_bufblk = -1;
@@ -821,11 +821,11 @@ static void pcd_start( void )
if (pcd_command(unit,rd_cmd,2048,"read block")) {
pcd_bufblk = -1;
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
pcd_busy = 0;
end_request(0);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
@@ -845,11 +845,11 @@ static void do_pcd_read( void )
pcd_retries = 0;
pcd_transfer();
if (!pcd_count) {
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
pcd_busy = 0;
do_pcd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
@@ -868,19 +868,19 @@ static void do_pcd_read_drq( void )
pi_do_claimed(PI,pcd_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
pcd_busy = 0;
pcd_bufblk = -1;
end_request(0);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
do_pcd_read();
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
/* the audio_ioctl stuff is adapted from sr_ioctl.c */
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 740bc08eb..1430fcb80 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -287,7 +287,6 @@ static void pd_eject( int unit);
static struct hd_struct pd_hd[PD_DEVS];
static int pd_sizes[PD_DEVS];
static int pd_blocksizes[PD_DEVS];
-static int pd_maxsectors[PD_DEVS];
#define PD_NAMELEN 8
@@ -330,7 +329,6 @@ static int pd_run; /* sectors in current cluster */
static int pd_cmd; /* current command READ/WRITE */
static int pd_unit; /* unit of current request */
static int pd_dev; /* minor of current request */
-static int pd_poffs; /* partition offset of current minor */
static char * pd_buf; /* buffer for request in progress */
static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open);
@@ -397,6 +395,7 @@ int pd_init (void)
}
q = BLK_DEFAULT_QUEUE(MAJOR_NR);
blk_init_queue(q, DEVICE_REQUEST);
+ blk_queue_max_sectors(q, cluster);
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
pd_gendisk.major = major;
@@ -406,9 +405,6 @@ int pd_init (void)
for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
blksize_size[MAJOR_NR] = pd_blocksizes;
- for(i=0;i<PD_DEVS;i++) pd_maxsectors[i] = cluster;
- max_sectors[MAJOR_NR] = pd_maxsectors;
-
printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
name,name,PD_VERSION,major,cluster,nice);
pd_init_units();
@@ -444,41 +440,41 @@ static int pd_open (struct inode *inode, struct file *file)
static int pd_ioctl(struct inode *inode,struct file *file,
unsigned int cmd, unsigned long arg)
+{
+ struct hd_geometry *geo = (struct hd_geometry *) arg;
+ int err, unit;
-{ struct hd_geometry *geo = (struct hd_geometry *) arg;
- int dev, err, unit;
-
- if ((!inode) || (!inode->i_rdev)) return -EINVAL;
- dev = MINOR(inode->i_rdev);
+ if (!inode || !inode->i_rdev)
+ return -EINVAL;
unit = DEVICE_NR(inode->i_rdev);
- if (dev >= PD_DEVS) return -EINVAL;
- if (!PD.present) return -ENODEV;
+ if (!PD.present)
+ return -ENODEV;
- switch (cmd) {
+ switch (cmd) {
case CDROMEJECT:
if (PD.access == 1) pd_eject(unit);
return 0;
- case HDIO_GETGEO:
- if (!geo) return -EINVAL;
- err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
- if (err) return err;
+ case HDIO_GETGEO:
+ if (!geo) return -EINVAL;
+ err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
+ if (err) return err;
if (PD.alt_geom) {
- put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS),
+ put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS),
(short *) &geo->cylinders);
- put_user(PD_LOG_HEADS, (char *) &geo->heads);
- put_user(PD_LOG_SECTS, (char *) &geo->sectors);
+ put_user(PD_LOG_HEADS, (char *) &geo->heads);
+ put_user(PD_LOG_SECTS, (char *) &geo->sectors);
} else {
- put_user(PD.cylinders, (short *) &geo->cylinders);
- put_user(PD.heads, (char *) &geo->heads);
- put_user(PD.sectors, (char *) &geo->sectors);
+ put_user(PD.cylinders, (short *) &geo->cylinders);
+ put_user(PD.heads, (char *) &geo->heads);
+ put_user(PD.sectors, (char *) &geo->sectors);
}
- put_user(pd_hd[dev].start_sect,(long *)&geo->start);
- return 0;
- case BLKRRPART:
+ put_user(get_start_sect(inode->i_rdev), (long *)&geo->start);
+ return 0;
+ case BLKRRPART:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- return pd_revalidate(inode->i_rdev);
+ return pd_revalidate(inode->i_rdev);
case BLKGETSIZE:
case BLKGETSIZE64:
case BLKROSET:
@@ -488,9 +484,9 @@ static int pd_ioctl(struct inode *inode,struct file *file,
case BLKFLSBUF:
case BLKPG:
return blk_ioctl(inode->i_rdev, cmd, arg);
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
}
static int pd_release (struct inode *inode, struct file *file)
@@ -526,36 +522,32 @@ static int pd_check_media( kdev_t dev)
}
static int pd_revalidate(kdev_t dev)
+{
+ int unit, res;
+ long flags;
-{ int p, unit, minor;
- long flags;
-
- unit = DEVICE_NR(dev);
- if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
-
- save_flags(flags);
- cli();
- if (PD.access > 1) {
- restore_flags(flags);
- return -EBUSY;
- }
- pd_valid = 0;
- restore_flags(flags);
-
- for (p=(PD_PARTNS-1);p>=0;p--) {
- minor = p + unit*PD_PARTNS;
- invalidate_device(MKDEV(MAJOR_NR, minor), 1);
- pd_hd[minor].start_sect = 0;
- pd_hd[minor].nr_sects = 0;
- }
+ unit = DEVICE_NR(dev);
+ if ((unit >= PD_UNITS) || !PD.present)
+ return -ENODEV;
+
+ save_flags(flags);
+ cli();
+ if (PD.access > 1) {
+ restore_flags(flags);
+ return -EBUSY;
+ }
+ pd_valid = 0;
+ restore_flags(flags);
- if (pd_identify(unit))
- grok_partitions(&pd_gendisk,unit,1<<PD_BITS,PD.capacity);
+ res = wipe_partitions(dev);
- pd_valid = 1;
- wake_up(&pd_wait_open);
+ if (res == 0 && pd_identify(unit))
+ grok_partitions(dev, PD.capacity);
- return 0;
+ pd_valid = 1;
+ wake_up(&pd_wait_open);
+
+ return res;
}
#ifdef MODULE
@@ -580,15 +572,13 @@ void cleanup_module(void)
{
int unit;
- devfs_unregister_blkdev(MAJOR_NR,name);
+ devfs_unregister_blkdev(MAJOR_NR, name);
del_gendisk(&pd_gendisk);
- for (unit=0;unit<PD_UNITS;unit++)
- if (PD.present) pi_release(PI);
-
- max_sectors[MAJOR_NR] = NULL;
+ for (unit=0; unit<PD_UNITS; unit++)
+ if (PD.present)
+ pi_release(PI);
}
-
#endif
#define WR(c,r,v) pi_write_regr(PI,c,r,v)
@@ -848,8 +838,7 @@ static int pd_ready( void )
}
static void do_pd_request (request_queue_t * q)
-
-{ struct buffer_head * bh;
+{
int unit;
if (pd_busy) return;
@@ -863,17 +852,13 @@ repeat:
pd_run = CURRENT->nr_sectors;
pd_count = CURRENT->current_nr_sectors;
- bh = CURRENT->bh;
-
if ((pd_dev >= PD_DEVS) ||
((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
end_request(0);
goto repeat;
}
- pd_cmd = CURRENT->cmd;
- pd_poffs = pd_hd[pd_dev].start_sect;
- pd_block += pd_poffs;
+ pd_cmd = rq_data_dir(CURRENT);
pd_buf = CURRENT->buffer;
pd_retries = 0;
@@ -890,25 +875,25 @@ static void pd_next_buf( int unit )
{ long saved_flags;
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
- if (!pd_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ if (!pd_run) { spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
/* paranoia */
if (QUEUE_EMPTY ||
- (CURRENT->cmd != pd_cmd) ||
+ (rq_data_dir(CURRENT) != pd_cmd) ||
(MINOR(CURRENT->rq_dev) != pd_dev) ||
(CURRENT->rq_status == RQ_INACTIVE) ||
- (CURRENT->sector+pd_poffs != pd_block))
+ (CURRENT->sector != pd_block))
printk("%s: OUCH: request list changed unexpectedly\n",
PD.name);
pd_count = CURRENT->current_nr_sectors;
pd_buf = CURRENT->buffer;
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
static void do_pd_read( void )
@@ -931,11 +916,11 @@ static void do_pd_read_start( void )
pi_do_claimed(PI,do_pd_read_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pd_ide_command(unit,IDE_READ,pd_block,pd_run);
@@ -955,11 +940,11 @@ static void do_pd_read_drq( void )
pi_do_claimed(PI,do_pd_read_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_read_block(PI,pd_buf,512);
@@ -970,11 +955,11 @@ static void do_pd_read_drq( void )
if (!pd_count) pd_next_buf(unit);
}
pi_disconnect(PI);
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
static void do_pd_write( void )
@@ -997,11 +982,11 @@ static void do_pd_write_start( void )
pi_do_claimed(PI,do_pd_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pd_ide_command(unit,IDE_WRITE,pd_block,pd_run);
@@ -1013,11 +998,11 @@ static void do_pd_write_start( void )
pi_do_claimed(PI,do_pd_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_write_block(PI,pd_buf,512);
@@ -1042,19 +1027,19 @@ static void do_pd_write_done( void )
pi_do_claimed(PI,do_pd_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_disconnect(PI);
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
pd_busy = 0;
do_pd_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
/* end of pd.c */
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 8ec90ae47..3feca299a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -340,56 +340,6 @@ void pf_init_units( void )
}
}
-static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments)
-{
- if (max_segments > cluster)
- max_segments = cluster;
-
- if (req->nr_segments < max_segments) {
- req->nr_segments++;
- return 1;
- }
- return 0;
-}
-
-static int pf_back_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int max_segments)
-{
- if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
- return 1;
- return pf_new_segment(q, req, max_segments);
-}
-
-static int pf_front_merge_fn(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int max_segments)
-{
- if (bh->b_data + bh->b_size == req->bh->b_data)
- return 1;
- return pf_new_segment(q, req, max_segments);
-}
-
-static int pf_merge_requests_fn(request_queue_t *q, struct request *req,
- struct request *next, int max_segments)
-{
- int total_segments = req->nr_segments + next->nr_segments;
- int same_segment;
-
- if (max_segments > cluster)
- max_segments = cluster;
-
- same_segment = 0;
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
- total_segments--;
- same_segment = 1;
- }
-
- if (total_segments > max_segments)
- return 0;
-
- req->nr_segments = total_segments;
- return 1;
-}
-
int pf_init (void) /* preliminary initialisation */
{ int i;
@@ -409,9 +359,7 @@ int pf_init (void) /* preliminary initialisation */
}
q = BLK_DEFAULT_QUEUE(MAJOR_NR);
blk_init_queue(q, DEVICE_REQUEST);
- q->back_merge_fn = pf_back_merge_fn;
- q->front_merge_fn = pf_front_merge_fn;
- q->merge_requests_fn = pf_merge_requests_fn;
+ blk_queue_max_segments(q, cluster);
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
@@ -458,7 +406,7 @@ static int pf_ioctl(struct inode *inode,struct file *file,
if (PF.access == 1) {
pf_eject(unit);
return 0;
- }
+ }
case HDIO_GETGEO:
if (!geo) return -EINVAL;
err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
@@ -894,8 +842,7 @@ static int pf_ready( void )
}
static void do_pf_request (request_queue_t * q)
-
-{ struct buffer_head * bh;
+{
int unit;
if (pf_busy) return;
@@ -908,14 +855,12 @@ repeat:
pf_run = CURRENT->nr_sectors;
pf_count = CURRENT->current_nr_sectors;
- bh = CURRENT->bh;
-
if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
end_request(0);
goto repeat;
}
- pf_cmd = CURRENT->cmd;
+ pf_cmd = rq_data_dir(CURRENT);
pf_buf = CURRENT->buffer;
pf_retries = 0;
@@ -932,16 +877,16 @@ static void pf_next_buf( int unit )
{ long saved_flags;
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
- if (!pf_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ if (!pf_run) { spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
/* paranoia */
if (QUEUE_EMPTY ||
- (CURRENT->cmd != pf_cmd) ||
+ (rq_data_dir(CURRENT) != pf_cmd) ||
(DEVICE_NR(CURRENT->rq_dev) != pf_unit) ||
(CURRENT->rq_status == RQ_INACTIVE) ||
(CURRENT->sector != pf_block))
@@ -950,7 +895,7 @@ static void pf_next_buf( int unit )
pf_count = CURRENT->current_nr_sectors;
pf_buf = CURRENT->buffer;
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
static void do_pf_read( void )
@@ -974,11 +919,11 @@ static void do_pf_read_start( void )
pi_do_claimed(PI,do_pf_read_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pf_mask = STAT_DRQ;
@@ -1000,11 +945,11 @@ static void do_pf_read_drq( void )
pi_do_claimed(PI,do_pf_read_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_read_block(PI,pf_buf,512);
@@ -1015,11 +960,11 @@ static void do_pf_read_drq( void )
if (!pf_count) pf_next_buf(unit);
}
pi_disconnect(PI);
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
static void do_pf_write( void )
@@ -1041,11 +986,11 @@ static void do_pf_write_start( void )
pi_do_claimed(PI,do_pf_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
@@ -1058,11 +1003,11 @@ static void do_pf_write_start( void )
pi_do_claimed(PI,do_pf_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_write_block(PI,pf_buf,512);
@@ -1088,19 +1033,19 @@ static void do_pf_write_done( void )
pi_do_claimed(PI,do_pf_write_start);
return;
}
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(0);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
return;
}
pi_disconnect(PI);
- spin_lock_irqsave(&io_request_lock,saved_flags);
+ spin_lock_irqsave(&QUEUE->queue_lock,saved_flags);
end_request(1);
pf_busy = 0;
do_pf_request(NULL);
- spin_unlock_irqrestore(&io_request_lock,saved_flags);
+ spin_unlock_irqrestore(&QUEUE->queue_lock,saved_flags);
}
/* end of pf.c */
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 1d68f97c9..19b715eb8 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -276,7 +276,7 @@ void pg_init_units( void )
pg_drive_count = 0;
for (unit=0;unit<PG_UNITS;unit++) {
PG.pi = & PG.pia;
- PG.access = 0;
+ set_bit( 0, &PG.access );
PG.busy = 0;
PG.present = 0;
PG.bufptr = NULL;
@@ -574,10 +574,7 @@ static int pg_open (struct inode *inode, struct file *file)
if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
- PG.access++;
-
- if (PG.access > 1) {
- PG.access--;
+ if ( test_and_set_bit(0, &PG.access) ) {
return -EBUSY;
}
@@ -591,7 +588,7 @@ static int pg_open (struct inode *inode, struct file *file)
PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL);
if (PG.bufptr == NULL) {
- PG.access--;
+ clear_bit( 0, &PG.access ) ;
printk("%s: buffer allocation failed\n",PG.name);
return -ENOMEM;
}
@@ -603,15 +600,13 @@ static int pg_release (struct inode *inode, struct file *file)
{
int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PG_UNITS) || (PG.access <= 0))
+ if ( unit >= PG_UNITS || !test_bit(0,&PG.access) )
return -EINVAL;
- lock_kernel();
- PG.access--;
+ clear_bit( 0, &PG.access);
kfree(PG.bufptr);
PG.bufptr = NULL;
- unlock_kernel();
return 0;
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 8d24f5acf..b0c43d9fe 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -244,7 +244,7 @@ struct pt_unit {
int flags; /* various state flags */
int last_sense; /* result of last request sense */
int drive; /* drive */
- int access; /* count of active opens ... */
+ atomic_t available; /* 1 if access is available 0 otherwise */
int bs; /* block size */
int capacity; /* Size of tape in KB */
int present; /* device present ? */
@@ -279,7 +279,7 @@ void pt_init_units( void )
pt_drive_count = 0;
for (unit=0;unit<PT_UNITS;unit++) {
PT.pi = & PT.pia;
- PT.access = 0;
+ atomic_set( &PT.available, 1 );
PT.flags = 0;
PT.last_sense = 0;
PT.present = 0;
@@ -697,22 +697,20 @@ static int pt_open (struct inode *inode, struct file *file)
if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;
- PT.access++;
-
- if (PT.access > 1) {
- PT.access--;
+ if ( !atomic_dec_and_test(&PT.available) ) {
+ atomic_inc( &PT.available );
return -EBUSY;
}
pt_identify(unit);
if (!PT.flags & PT_MEDIA) {
- PT.access--;
+ atomic_inc( &PT.available );
return -ENODEV;
}
if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
- PT.access--;
+ atomic_inc( &PT.available );
return -EROFS;
}
@@ -721,7 +719,7 @@ static int pt_open (struct inode *inode, struct file *file)
PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
if (PT.bufptr == NULL) {
- PT.access--;
+ atomic_inc( &PT.available );
printk("%s: buffer allocation failed\n",PT.name);
return -ENOMEM;
}
@@ -776,20 +774,18 @@ static int pt_release (struct inode *inode, struct file *file)
{
int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PT_UNITS) || (PT.access <= 0))
+ if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1))
return -EINVAL;
- lock_kernel();
if (PT.flags & PT_WRITING) pt_write_fm(unit);
if (PT.flags & PT_REWIND) pt_rewind(unit);
- PT.access--;
-
kfree(PT.bufptr);
PT.bufptr = NULL;
- unlock_kernel();
+ atomic_inc( &PT.available );
+
return 0;
}
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index bbb8e682b..40ef290e7 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -66,6 +66,7 @@
#define TYPE_0_CMD_BLK_LENGTH 2
#define TYPE_1_CMD_BLK_LENGTH 4
+#define PS2ESDI_LOCK (&((BLK_DEFAULT_QUEUE(MAJOR_NR))->queue_lock))
static void reset_ctrl(void);
@@ -118,7 +119,6 @@ static int access_count[MAX_HD];
static char ps2esdi_valid[MAX_HD];
static int ps2esdi_sizes[MAX_HD << 6];
static int ps2esdi_blocksizes[MAX_HD << 6];
-static int ps2esdi_maxsect[MAX_HD << 6];
static int ps2esdi_drives;
static struct hd_struct ps2esdi[MAX_HD << 6];
static u_short io_base;
@@ -221,8 +221,7 @@ int init_module(void) {
}
void
-cleanup_module(void)
-{
+cleanup_module(void) {
if(ps2esdi_slot) {
mca_mark_as_unused(ps2esdi_slot);
mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
@@ -231,8 +230,9 @@ cleanup_module(void)
free_dma(dma_arb_level);
free_irq(PS2ESDI_IRQ, NULL);
devfs_unregister_blkdev(MAJOR_NR, "ed");
- del_gendisk(&ps2esdi_gendisk);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ del_gendisk(&ps2esdi_gendisk);
+ blk_clear(MAJOR_NR);
}
#endif /* MODULE */
@@ -415,16 +415,13 @@ static void __init ps2esdi_geninit(void)
ps2esdi_gendisk.nr_real = ps2esdi_drives;
- /* 128 was old default, maybe maxsect=255 is ok too? - Paul G. */
- for (i = 0; i < (MAX_HD << 6); i++) {
- ps2esdi_maxsect[i] = 128;
+ for (i = 0; i < (MAX_HD << 6); i++)
ps2esdi_blocksizes[i] = 1024;
- }
request_dma(dma_arb_level, "ed");
request_region(io_base, 4, "ed");
blksize_size[MAJOR_NR] = ps2esdi_blocksizes;
- max_sectors[MAJOR_NR] = ps2esdi_maxsect;
+ blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128);
for (i = 0; i < ps2esdi_drives; i++) {
register_disk(&ps2esdi_gendisk,MKDEV(MAJOR_NR,i<<6),1<<6,
@@ -495,13 +492,9 @@ static void do_ps2esdi_request(request_queue_t * q)
CURRENT->current_nr_sectors);
#endif
-
- block = CURRENT->sector + ps2esdi[MINOR(CURRENT->rq_dev)].start_sect;
-
-#if 0
- printk("%s: blocknumber : %d\n", DEVICE_NAME, block);
-#endif
+ block = CURRENT->sector;
count = CURRENT->current_nr_sectors;
+
switch (CURRENT->cmd) {
case READ:
ps2esdi_readwrite(READ, CURRENT_DEV, block, count);
@@ -958,10 +951,10 @@ static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
break;
}
if(ending != -1) {
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(PS2ESDI_LOCK, flags);
end_request(ending);
do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(PS2ESDI_LOCK, flags);
}
} /* handle interrupts */
@@ -1100,10 +1093,10 @@ static int ps2esdi_ioctl(struct inode *inode,
put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
- put_user(ps2esdi[MINOR(inode->i_rdev)].start_sect,
+ put_user(get_start_sect(inode->i_rdev),
(long *) &geometry->start);
- return (0);
+ return 0;
}
break;
@@ -1132,8 +1125,7 @@ static int ps2esdi_ioctl(struct inode *inode,
static int ps2esdi_reread_partitions(kdev_t dev)
{
int target = DEVICE_NR(dev);
- int start = target << ps2esdi_gendisk.minor_shift;
- int partition;
+ int res;
cli();
ps2esdi_valid[target] = (access_count[target] != 1);
@@ -1141,21 +1133,16 @@ static int ps2esdi_reread_partitions(kdev_t dev)
if (ps2esdi_valid[target])
return (-EBUSY);
- for (partition = ps2esdi_gendisk.max_p - 1;
- partition >= 0; partition--) {
- int minor = (start | partition);
- invalidate_device(MKDEV(MAJOR_NR, minor), 1);
- ps2esdi_gendisk.part[minor].start_sect = 0;
- ps2esdi_gendisk.part[minor].nr_sects = 0;
- }
-
- grok_partitions(&ps2esdi_gendisk, target, 1<<6,
- ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect);
-
+ res = wipe_partitions(dev);
+ if (res == 0)
+ grok_partitions(dev, ps2esdi_info[target].head
+ * ps2esdi_info[target].cyl
+ * ps2esdi_info[target].sect);
+
ps2esdi_valid[target] = 1;
wake_up(&ps2esdi_wait_open);
- return (0);
+ return (res);
}
static void ps2esdi_reset_timer(unsigned long unused)
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 7be6d0492..67e124c4a 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -89,6 +89,7 @@ static int crd_load(struct file *fp, struct file *outfp);
#ifdef CONFIG_BLK_DEV_INITRD
static int initrd_users;
+static spinlock_t initrd_users_lock = SPIN_LOCK_UNLOCKED;
#endif
#endif
@@ -98,7 +99,7 @@ static int initrd_users;
static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */
static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */
static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */
-static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
+static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
static devfs_handle_t devfs_handle;
static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
@@ -227,19 +228,19 @@ static struct address_space_operations ramdisk_aops = {
commit_write: ramdisk_commit_write,
};
-static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
+static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec,
+ sector_t sector, int minor)
{
struct address_space * mapping;
unsigned long index;
int offset, size, err;
- err = -EIO;
err = 0;
mapping = rd_bdev[minor]->bd_inode->i_mapping;
- index = sbh->b_rsector >> (PAGE_CACHE_SHIFT - 9);
- offset = (sbh->b_rsector << 9) & ~PAGE_CACHE_MASK;
- size = sbh->b_size;
+ index = sector >> (PAGE_CACHE_SHIFT - 9);
+ offset = (sector << 9) & ~PAGE_CACHE_MASK;
+ size = vec->bv_len;
do {
int count;
@@ -276,18 +277,18 @@ static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
if (rw == READ) {
src = kmap(page);
src += offset;
- dst = bh_kmap(sbh);
+ dst = kmap(vec->bv_page) + vec->bv_offset;
} else {
dst = kmap(page);
dst += offset;
- src = bh_kmap(sbh);
+ src = kmap(vec->bv_page) + vec->bv_offset;
}
offset = 0;
memcpy(dst, src, count);
kunmap(page);
- bh_kunmap(sbh);
+ kunmap(vec->bv_page);
if (rw == READ) {
flush_dcache_page(page);
@@ -303,6 +304,22 @@ static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
return err;
}
+static int rd_blkdev_bio_IO(struct bio *bio, unsigned int minor)
+{
+ struct bio_vec *bvec;
+ sector_t sector;
+ int ret = 0, i, rw;
+
+ sector = bio->bi_sector;
+ rw = bio_data_dir(bio);
+ bio_for_each_segment(bvec, bio, i) {
+ ret |= rd_blkdev_pagecache_IO(rw, bvec, sector, minor);
+ sector += bvec->bv_len >> 9;
+ }
+
+ return ret;
+}
+
/*
* Basically, my strategy here is to set up a buffer-head which can't be
* deleted, and make that my Ramdisk. If the request is outside of the
@@ -311,19 +328,19 @@ static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
* 19-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Added devfs support
*
*/
-static int rd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh)
+static int rd_make_request(request_queue_t * q, struct bio *sbh)
{
unsigned int minor;
unsigned long offset, len;
+ int rw = sbh->bi_rw;
- minor = MINOR(sbh->b_rdev);
+ minor = MINOR(sbh->bi_dev);
if (minor >= NUM_RAMDISKS)
goto fail;
-
- offset = sbh->b_rsector << 9;
- len = sbh->b_size;
+ offset = sbh->bi_sector << 9;
+ len = sbh->bi_size;
if ((offset + len) > rd_length[minor])
goto fail;
@@ -335,13 +352,14 @@ static int rd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh)
goto fail;
}
- if (rd_blkdev_pagecache_IO(rw, sbh, minor))
+ if (rd_blkdev_bio_IO(sbh, minor))
goto fail;
- sbh->b_end_io(sbh,1);
+ set_bit(BIO_UPTODATE, &sbh->bi_flags);
+ sbh->bi_end_io(sbh, len >> 9);
return 0;
fail:
- sbh->b_end_io(sbh,0);
+ bio_io_error(sbh);
return 0;
}
@@ -408,12 +426,15 @@ static int initrd_release(struct inode *inode,struct file *file)
{
extern void free_initrd_mem(unsigned long, unsigned long);
- lock_kernel();
+ spin_lock(&initrd_users_lock);
if (!--initrd_users) {
+ spin_unlock(&initrd_users_lock);
free_initrd_mem(initrd_start, initrd_end);
initrd_start = 0;
+ } else {
+ spin_unlock(&initrd_users_lock);
}
- unlock_kernel();
+
blkdev_put(inode->i_bdev, BDEV_FILE);
return 0;
}
@@ -433,8 +454,11 @@ static int rd_open(struct inode * inode, struct file * filp)
#ifdef CONFIG_BLK_DEV_INITRD
if (unit == INITRD_MINOR) {
- if (!initrd_start) return -ENODEV;
+ spin_lock(&initrd_users_lock);
initrd_users++;
+ spin_unlock(&initrd_users_lock);
+ if (!initrd_start)
+ return -ENODEV;
filp->f_op = &initrd_fops;
return 0;
}
@@ -461,7 +485,6 @@ static struct block_device_operations rd_bd_op = {
ioctl: rd_ioctl,
};
-#ifdef MODULE
/* Before freeing the module, invalidate all of the protected buffers! */
static void __exit rd_cleanup (void)
{
@@ -477,11 +500,8 @@ static void __exit rd_cleanup (void)
devfs_unregister (devfs_handle);
unregister_blkdev( MAJOR_NR, "ramdisk" );
- hardsect_size[MAJOR_NR] = NULL;
- blksize_size[MAJOR_NR] = NULL;
- blk_size[MAJOR_NR] = NULL;
+ blk_clear(MAJOR_NR);
}
-#endif
/* This is the registration and initialization section of the RAM disk driver */
int __init rd_init (void)
@@ -524,7 +544,6 @@ int __init rd_init (void)
register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1);
#endif
- hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
@@ -536,10 +555,8 @@ int __init rd_init (void)
return 0;
}
-#ifdef MODULE
module_init(rd_init);
module_exit(rd_cleanup);
-#endif
/* loadable module support */
MODULE_PARM (rd_size, "1i");
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 43d856343..4357b317b 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -121,7 +121,6 @@ static unsigned int xd_bases[] __initdata =
static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
static int xd_blocksizes[XD_MAXDRIVES << 6];
-static int xd_maxsect[XD_MAXDRIVES << 6];
extern struct block_device_operations xd_fops;
@@ -246,8 +245,7 @@ static void __init xd_geninit (void)
}
/* xd_maxsectors depends on controller - so set after detection */
- for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors;
- max_sectors[MAJOR_NR] = xd_maxsect;
+ blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors);
for (i = 0; i < xd_drives; i++) {
xd_valid[i] = 1;
@@ -257,7 +255,6 @@ static void __init xd_geninit (void)
}
xd_gendisk.nr_real = xd_drives;
-
}
/* xd_open: open a device */
@@ -292,14 +289,14 @@ static void do_xd_request (request_queue_t * q)
if (CURRENT_DEV < xd_drives
&& CURRENT->sector + CURRENT->nr_sectors
<= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
- block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
+ block = CURRENT->sector;
count = CURRENT->nr_sectors;
- switch (CURRENT->cmd) {
+ switch (rq_data_dir(CURRENT)) {
case READ:
case WRITE:
for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
- code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
+ code = xd_readwrite(rq_data_dir(CURRENT),CURRENT_DEV,CURRENT->buffer,block,count);
break;
default:
printk("do_xd_request: unknown request\n");
@@ -329,7 +326,7 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
g.heads = xd_info[dev].heads;
g.sectors = xd_info[dev].sectors;
g.cylinders = xd_info[dev].cylinders;
- g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
+ g.start = get_start_sect(inode->i_rdev);
return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
}
case HDIO_SET_DMA:
@@ -337,7 +334,8 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
if (xdc_busy) return -EBUSY;
nodma = !arg;
if (nodma && xd_dma_buffer) {
- xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
+ xd_dma_mem_free((unsigned long)xd_dma_buffer,
+ xd_maxsectors * 0x200);
xd_dma_buffer = 0;
}
return 0;
@@ -378,11 +376,9 @@ static int xd_release (struct inode *inode, struct file *file)
static int xd_reread_partitions(kdev_t dev)
{
int target;
- int start;
- int partition;
+ int res;
target = DEVICE_NR(dev);
- start = target << xd_gendisk.minor_shift;
cli();
xd_valid[target] = (xd_access[target] != 1);
@@ -390,20 +386,16 @@ static int xd_reread_partitions(kdev_t dev)
if (xd_valid[target])
return -EBUSY;
- for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
- int minor = (start | partition);
- invalidate_device(MKDEV(MAJOR_NR, minor), 1);
- xd_gendisk.part[minor].start_sect = 0;
- xd_gendisk.part[minor].nr_sects = 0;
- };
-
- grok_partitions(&xd_gendisk, target, 1<<6,
- xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors);
+ res = wipe_partitions(dev);
+ if (!res)
+ grok_partitions(dev, xd_info[target].heads
+ * xd_info[target].cylinders
+ * xd_info[target].sectors);
xd_valid[target] = 1;
wake_up(&xd_wait_open);
- return 0;
+ return res;
}
/* xd_readwrite: handle a read/write request */
@@ -1105,12 +1097,9 @@ MODULE_LICENSE("GPL");
static void xd_done (void)
{
- blksize_size[MAJOR_NR] = NULL;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- blk_size[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
- read_ahead[MAJOR_NR] = 0;
del_gendisk(&xd_gendisk);
+ blk_clear(MAJOR_NR);
release_region(xd_iobase,4);
}
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index f23e0a4f2..ac2d341b7 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -247,7 +247,7 @@
/* Define this to remove _all_ the debugging messages */
/* #define ERRLOGMASK CD_NOTHING */
-#define ERRLOGMASK (CD_WARNING)
+#define ERRLOGMASK CD_WARNING
/* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
/* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
@@ -1987,7 +1987,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
return -EINVAL;
/* FIXME: we need upper bound checking, too!! */
- if (lba < 0 || ra.nframes <= 0)
+ if (lba < 0 || ra.nframes <= 0 || ra.nframes > 64)
return -EINVAL;
/*
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index c23717512..94c94fd9a 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -1583,7 +1583,10 @@ static void do_cdu31a_request(request_queue_t * q)
/* Make sure we have a valid TOC. */
sony_get_toc();
- spin_unlock_irq(&io_request_lock);
+ /*
+ * jens: driver has lots of races
+ */
+ spin_unlock_irq(&q->queue_lock);
/* Make sure the timer is cancelled. */
del_timer(&cdu31a_abort_timer);
@@ -1730,7 +1733,7 @@ static void do_cdu31a_request(request_queue_t * q)
}
end_do_cdu31a_request:
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
#if 0
/* After finished, cancel any pending operations. */
abort_read();
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index 0e9f740ae..f9b1af285 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -866,7 +866,7 @@ static void do_cm206_request(request_queue_t * q)
end_request(0);
continue;
}
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
error = 0;
for (i = 0; i < CURRENT->nr_sectors; i++) {
int e1, e2;
@@ -893,7 +893,7 @@ static void do_cm206_request(request_queue_t * q)
debug(("cm206_request: %d %d\n", e1, e2));
}
}
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
end_request(!error);
}
}
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index c477caaf8..b79c01f8b 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -4930,7 +4930,7 @@ static void DO_SBPCD_REQUEST(request_queue_t * q)
sbpcd_end_request(req, 0);
if (req -> sector == -1)
sbpcd_end_request(req, 0);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
down(&ioctl_read_sem);
if (req->cmd != READ)
@@ -4970,7 +4970,7 @@ static void DO_SBPCD_REQUEST(request_queue_t * q)
xnr, req, req->sector, req->nr_sectors, jiffies);
#endif
up(&ioctl_read_sem);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
sbpcd_end_request(req, 1);
goto request_loop;
}
@@ -5011,7 +5011,7 @@ static void DO_SBPCD_REQUEST(request_queue_t * q)
xnr, req, req->sector, req->nr_sectors, jiffies);
#endif
up(&ioctl_read_sem);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
sbpcd_end_request(req, 1);
goto request_loop;
}
@@ -5027,7 +5027,7 @@ static void DO_SBPCD_REQUEST(request_queue_t * q)
#endif
up(&ioctl_read_sem);
sbp_sleep(0); /* wait a bit, try again */
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
sbpcd_end_request(req, 0);
goto request_loop;
}
@@ -5870,7 +5870,6 @@ int __init SBPCD_INIT(void)
(BLK_DEFAULT_QUEUE(MAJOR_NR))->front_merge_fn = dont_bh_merge_fn;
(BLK_DEFAULT_QUEUE(MAJOR_NR))->merge_requests_fn = dont_merge_requests_fn;
#endif
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
read_ahead[MAJOR_NR] = buffers * (CD_FRAMESIZE / 512);
request_region(CDo_command,4,major_name);
diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c
index c03133abc..0712b3322 100644
--- a/drivers/char/acquirewdt.c
+++ b/drivers/char/acquirewdt.c
@@ -141,7 +141,6 @@ static int acq_open(struct inode *inode, struct file *file)
static int acq_close(struct inode *inode, struct file *file)
{
- lock_kernel();
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
spin_lock(&acq_lock);
@@ -151,7 +150,6 @@ static int acq_close(struct inode *inode, struct file *file)
acq_is_open=0;
spin_unlock(&acq_lock);
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/advantechwdt.c b/drivers/char/advantechwdt.c
index a63ca8307..dfb2663ec 100644
--- a/drivers/char/advantechwdt.c
+++ b/drivers/char/advantechwdt.c
@@ -151,7 +151,6 @@ advwdt_open(struct inode *inode, struct file *file)
static int
advwdt_close(struct inode *inode, struct file *file)
{
- lock_kernel();
if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
spin_lock(&advwdt_lock);
#ifndef CONFIG_WATCHDOG_NOWAYOUT
@@ -160,7 +159,6 @@ advwdt_close(struct inode *inode, struct file *file)
advwdt_is_open = 0;
spin_unlock(&advwdt_lock);
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 1b70fabaa..b6b2355e9 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -276,6 +276,8 @@ struct agp_bridge_data {
#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5)
#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3)
+#define INTEL_I830_ERRSTS 0x92
+
/* intel i820 registers */
#define INTEL_I820_RDCR 0x51
#define INTEL_I820_ERRSTS 0xc8
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index 1f3cba6d8..e28fd5eed 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -1409,10 +1409,6 @@ static int __init intel_i830_setup(struct pci_dev *i830_dev)
}
#endif /* CONFIG_AGP_I810 */
-
- #ifdef CONFIG_AGP_INTEL
-
-#endif /* CONFIG_AGP_I810 */
#ifdef CONFIG_AGP_INTEL
@@ -1715,6 +1711,38 @@ static int intel_860_configure(void)
return 0;
}
+static int intel_830mp_configure(void)
+{
+ u32 temp;
+ u16 temp2;
+ aper_size_info_8 *current_size;
+
+ current_size = A_SIZE_8(agp_bridge.current_size);
+
+ /* aperture size */
+ pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+ current_size->size_value);
+
+ /* address to map to */
+ pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+ /* attbase - aperture base */
+ pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
+ agp_bridge.gatt_bus_addr);
+
+ /* agpctrl */
+ pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+
+ /* gmch */
+ pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
+ pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
+ temp2 | (1 << 9));
+ /* clear any possible AGP-related error conditions */
+ pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c);
+ return 0;
+}
+
static unsigned long intel_mask_memory(unsigned long addr, int type)
{
/* Memory type is ignored */
@@ -1755,6 +1783,14 @@ static aper_size_info_16 intel_generic_sizes[7] =
{4, 1024, 0, 63}
};
+static aper_size_info_8 intel_830mp_sizes[4] =
+{
+ {256, 65536, 6, 0},
+ {128, 32768, 5, 32},
+ {64, 16384, 4, 48},
+ {32, 8192, 3, 56}
+};
+
static int __init intel_generic_setup (struct pci_dev *pdev)
{
agp_bridge.masks = intel_generic_masks;
@@ -1819,6 +1855,35 @@ static int __init intel_820_setup (struct pci_dev *pdev)
(void) pdev; /* unused */
}
+static int __init intel_830mp_setup (struct pci_dev *pdev)
+{
+ agp_bridge.masks = intel_generic_masks;
+ agp_bridge.num_of_masks = 1;
+ agp_bridge.aperture_sizes = (void *) intel_830mp_sizes;
+ agp_bridge.size_type = U8_APER_SIZE;
+ agp_bridge.num_aperture_sizes = 4;
+ agp_bridge.dev_private_data = NULL;
+ agp_bridge.needs_scratch_page = FALSE;
+ agp_bridge.configure = intel_830mp_configure;
+ agp_bridge.fetch_size = intel_8xx_fetch_size;
+ agp_bridge.cleanup = intel_8xx_cleanup;
+ agp_bridge.tlb_flush = intel_8xx_tlbflush;
+ agp_bridge.mask_memory = intel_mask_memory;
+ agp_bridge.agp_enable = agp_generic_agp_enable;
+ agp_bridge.cache_flush = global_cache_flush;
+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+ agp_bridge.insert_memory = agp_generic_insert_memory;
+ agp_bridge.remove_memory = agp_generic_remove_memory;
+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+ agp_bridge.free_by_type = agp_generic_free_by_type;
+ agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+ agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+
+ return 0;
+
+ (void) pdev; /* unused */
+}
static int __init intel_840_setup (struct pci_dev *pdev)
{
@@ -3505,12 +3570,6 @@ static struct {
"AMD",
"Irongate",
amd_irongate_setup },
- { PCI_DEVICE_ID_AMD_762_0,
- PCI_VENDOR_ID_AMD,
- AMD_IRONGATE,
- "AMD",
- "AMD 760MP",
- amd_irongate_setup },
{ PCI_DEVICE_ID_AMD_761_0,
PCI_VENDOR_ID_AMD,
AMD_761,
@@ -3567,7 +3626,7 @@ static struct {
INTEL_I830_M,
"Intel",
"i830M",
- intel_generic_setup },
+ intel_830mp_setup },
{ PCI_DEVICE_ID_INTEL_840_0,
PCI_VENDOR_ID_INTEL,
INTEL_I840,
@@ -3889,18 +3948,17 @@ static int __init agp_find_supported_device(void)
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_830_M_1,
NULL);
- if(PCI_FUNC(i810_dev->devfn) != 0) {
+ if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_830_M_1,
i810_dev);
}
if (i810_dev == NULL) {
- printk(KERN_ERR PFX "Detected an "
- "Intel 830M, but could not find the"
- " secondary device.\n");
- agp_bridge.type = NOT_SUPPORTED;
- return -ENODEV;
+ /* Intel 830MP with external graphic card */
+ /* It will be initialized later */
+ agp_bridge.type = INTEL_I830_M;
+ break;
}
printk(KERN_INFO PFX "Detected an Intel "
"830M Chipset.\n");
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
index fab2e5a5b..2e6a7f63e 100644
--- a/drivers/char/agp/agpgart_fe.c
+++ b/drivers/char/agp/agpgart_fe.c
@@ -606,17 +606,14 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
agp_file_private *priv = (agp_file_private *) file->private_data;
agp_kern_info kerninfo;
- lock_kernel();
AGP_LOCK();
if (agp_fe.backend_acquired != TRUE) {
AGP_UNLOCK();
- unlock_kernel();
return -EPERM;
}
if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) {
AGP_UNLOCK();
- unlock_kernel();
return -EPERM;
}
agp_copy_info(&kerninfo);
@@ -628,51 +625,42 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
if ((size + offset) > current_size) {
AGP_UNLOCK();
- unlock_kernel();
return -EINVAL;
}
client = agp_find_client_by_pid(current->pid);
if (client == NULL) {
AGP_UNLOCK();
- unlock_kernel();
return -EPERM;
}
if (!agp_find_seg_in_client(client, offset,
size, vma->vm_page_prot)) {
AGP_UNLOCK();
- unlock_kernel();
return -EINVAL;
}
if (remap_page_range(vma->vm_start,
(kerninfo.aper_base + offset),
size, vma->vm_page_prot)) {
AGP_UNLOCK();
- unlock_kernel();
return -EAGAIN;
}
AGP_UNLOCK();
- unlock_kernel();
return 0;
}
if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
if (size != current_size) {
AGP_UNLOCK();
- unlock_kernel();
return -EINVAL;
}
if (remap_page_range(vma->vm_start, kerninfo.aper_base,
size, vma->vm_page_prot)) {
AGP_UNLOCK();
- unlock_kernel();
return -EAGAIN;
}
AGP_UNLOCK();
- unlock_kernel();
return 0;
}
AGP_UNLOCK();
- unlock_kernel();
return -EPERM;
}
@@ -680,7 +668,6 @@ static int agp_release(struct inode *inode, struct file *file)
{
agp_file_private *priv = (agp_file_private *) file->private_data;
- lock_kernel();
AGP_LOCK();
if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
@@ -702,7 +689,6 @@ static int agp_release(struct inode *inode, struct file *file)
agp_remove_file_private(priv);
kfree(priv);
AGP_UNLOCK();
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c
index 42bdc16a0..95a66df49 100644
--- a/drivers/char/busmouse.c
+++ b/drivers/char/busmouse.c
@@ -171,6 +171,7 @@ static int busmouse_release(struct inode *inode, struct file *file)
lock_kernel();
busmouse_fasync(-1, file, 0);
+ down(&mouse_sem); /* to protect mse->active */
if (--mse->active == 0) {
if (mse->ops->release)
ret = mse->ops->release(inode, file);
@@ -179,7 +180,8 @@ static int busmouse_release(struct inode *inode, struct file *file)
mse->ready = 0;
}
unlock_kernel();
-
+ up( &mouse_sem);
+
return ret;
}
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 44c06f458..86299fbdc 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -328,10 +328,8 @@ static int dtlk_release(struct inode *inode, struct file *file)
break;
}
TRACE_RET;
-
- lock_kernel();
+
del_timer(&dtlk_timer);
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index e64425dc2..ee5e51fe0 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -68,7 +68,8 @@ const ftape_info *zft_status;
/* Local vars.
*/
-static int busy_flag = 0;
+static int busy_flag;
+
static sigset_t orig_sigmask;
/* the interface to the kernel vfs layer
@@ -113,14 +114,13 @@ static int zft_open(struct inode *ino, struct file *filep)
TRACE_FUN(ft_t_flow);
TRACE(ft_t_flow, "called for minor %d", MINOR(ino->i_rdev));
- if (busy_flag) {
+ if ( test_and_set_bit(0,&busy_flag) ) {
TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy");
}
- busy_flag = 1;
if ((MINOR(ino->i_rdev) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND))
>
FTAPE_SEL_D) {
- busy_flag = 0;
+ clear_bit(0,&busy_flag);
TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr");
}
orig_sigmask = current->blocked;
@@ -128,7 +128,7 @@ static int zft_open(struct inode *ino, struct file *filep)
result = _zft_open(MINOR(ino->i_rdev), filep->f_flags & O_ACCMODE);
if (result < 0) {
current->blocked = orig_sigmask; /* restore mask */
- busy_flag = 0;
+ clear_bit(0,&busy_flag);
TRACE_ABORT(result, ft_t_err, "_ftape_open failed");
} else {
/* Mask signals that will disturb proper operation of the
@@ -147,10 +147,8 @@ static int zft_close(struct inode *ino, struct file *filep)
int result;
TRACE_FUN(ft_t_flow);
- lock_kernel();
- if (!busy_flag || MINOR(ino->i_rdev) != zft_unit) {
+ if ( !test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit) {
TRACE(ft_t_err, "failed: not busy or wrong unit");
- unlock_kernel();
TRACE_EXIT 0;
}
sigfillset(&current->blocked);
@@ -159,8 +157,7 @@ static int zft_close(struct inode *ino, struct file *filep)
TRACE(ft_t_err, "_zft_close failed");
}
current->blocked = orig_sigmask; /* restore before open state */
- busy_flag = 0;
- unlock_kernel();
+ clear_bit(0,&busy_flag);
TRACE_EXIT 0;
}
@@ -173,7 +170,7 @@ static int zft_ioctl(struct inode *ino, struct file *filep,
sigset_t old_sigmask;
TRACE_FUN(ft_t_flow);
- if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
+ if ( !test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
TRACE_ABORT(-EIO, ft_t_err,
"failed: not busy, failure or wrong unit");
}
@@ -193,7 +190,7 @@ static int zft_mmap(struct file *filep, struct vm_area_struct *vma)
sigset_t old_sigmask;
TRACE_FUN(ft_t_flow);
- if (!busy_flag ||
+ if ( !test_bit(0,&busy_flag) ||
MINOR(filep->f_dentry->d_inode->i_rdev) != zft_unit ||
ft_failure)
{
@@ -202,14 +199,12 @@ static int zft_mmap(struct file *filep, struct vm_area_struct *vma)
}
old_sigmask = current->blocked; /* save mask */
sigfillset(&current->blocked);
- lock_kernel();
if ((result = ftape_mmap(vma)) >= 0) {
#ifndef MSYNC_BUG_WAS_FIXED
static struct vm_operations_struct dummy = { NULL, };
vma->vm_ops = &dummy;
#endif
}
- unlock_kernel();
current->blocked = old_sigmask; /* restore mask */
TRACE_EXIT result;
}
@@ -225,7 +220,7 @@ static ssize_t zft_read(struct file *fp, char *buff,
TRACE_FUN(ft_t_flow);
TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len);
- if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
+ if (!test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
TRACE_ABORT(-EIO, ft_t_err,
"failed: not busy, failure or wrong unit");
}
@@ -248,7 +243,7 @@ static ssize_t zft_write(struct file *fp, const char *buff,
TRACE_FUN(ft_t_flow);
TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len);
- if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
+ if (!test_bit(0,&busy_flag) || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
TRACE_ABORT(-EIO, ft_t_err,
"failed: not busy, failure or wrong unit");
}
@@ -403,7 +398,7 @@ KERN_INFO
*/
static int can_unload(void)
{
- return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0;
+ return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||test_bit(0,&busy_flag))?-EBUSY:0;
}
/* Called by modules package when installing the driver
*/
diff --git a/drivers/char/joystick/ns558.c b/drivers/char/joystick/ns558.c
index b1579fb6d..4cefeabd7 100644
--- a/drivers/char/joystick/ns558.c
+++ b/drivers/char/joystick/ns558.c
@@ -153,11 +153,7 @@ static struct ns558* ns558_isa_probe(int io, struct ns558 *next)
return port;
}
-#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
-#define NSS558_ISAPNP
-#endif
-
-#ifdef NSS558_ISAPNP
+#ifdef __ISAPNP__
static struct isapnp_device_id pnp_devids[] = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('@','P','@'), ISAPNP_DEVICE(0x0001), 0 },
@@ -229,7 +225,7 @@ deactivate:
int __init ns558_init(void)
{
int i = 0;
-#ifdef NSS558_ISAPNP
+#ifdef __ISAPNP__
struct isapnp_device_id *devid;
struct pci_dev *dev = NULL;
#endif
@@ -245,7 +241,7 @@ int __init ns558_init(void)
* Probe for PnP ports.
*/
-#ifdef NSS558_ISAPNP
+#ifdef __ISAPNP__
for (devid = pnp_devids; devid->vendor; devid++) {
while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev))) {
ns558 = ns558_pnp_probe(dev, ns558);
@@ -264,7 +260,7 @@ void __exit ns558_exit(void)
gameport_unregister_port(&port->gameport);
switch (port->type) {
-#ifdef NSS558_ISAPNP
+#ifdef __ISAPNP__
case NS558_PNP:
if (port->dev->deactivate)
port->dev->deactivate(port->dev);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 670d5d871..e4c0130c7 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -494,11 +494,9 @@ static int lp_release(struct inode * inode, struct file * file)
parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
lp_release_parport (&lp_table[minor]);
- lock_kernel();
kfree(lp_table[minor].lp_buffer);
lp_table[minor].lp_buffer = NULL;
LP_F(minor) &= ~LP_BUSY;
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/mixcomwd.c b/drivers/char/mixcomwd.c
index 2a07641a3..3f6e87a7c 100644
--- a/drivers/char/mixcomwd.c
+++ b/drivers/char/mixcomwd.c
@@ -101,11 +101,9 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
static int mixcomwd_release(struct inode *inode, struct file *file)
{
- lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
if(mixcomwd_timer_alive) {
printk(KERN_ERR "mixcomwd: release called while internal timer alive");
- unlock_kernel();
return -EBUSY;
}
init_timer(&mixcomwd_timer);
@@ -117,7 +115,6 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
#endif
clear_bit(0,&mixcomwd_opened);
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 1959e9ed3..fae1d0e94 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -108,7 +108,10 @@
#include <asm/system.h>
static int nvram_open_cnt; /* #times opened */
-static int nvram_open_mode; /* special open modes */
+static int nvram_open_mode; /* special open modes */
+static spinlock_t nvram_open_lock = SPIN_LOCK_UNLOCKED;
+ /* guards nvram_open_cnt and
+ nvram_open_mode */
#define NVRAM_WRITE 1 /* opened for writing (exclusive) */
#define NVRAM_EXCL 2 /* opened with O_EXCL */
@@ -326,29 +329,33 @@ static int nvram_ioctl( struct inode *inode, struct file *file,
static int nvram_open( struct inode *inode, struct file *file )
{
+ spin_lock( &nvram_open_lock );
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
(nvram_open_mode & NVRAM_EXCL) ||
((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE)))
+ {
+ spin_unlock( &nvram_open_lock );
return( -EBUSY );
+ }
if (file->f_flags & O_EXCL)
nvram_open_mode |= NVRAM_EXCL;
if (file->f_mode & 2)
nvram_open_mode |= NVRAM_WRITE;
nvram_open_cnt++;
+ spin_unlock( &nvram_open_lock );
return( 0 );
}
static int nvram_release( struct inode *inode, struct file *file )
{
- lock_kernel();
+ spin_lock( &nvram_open_lock );
nvram_open_cnt--;
if (file->f_flags & O_EXCL)
nvram_open_mode &= ~NVRAM_EXCL;
if (file->f_mode & 2)
nvram_open_mode &= ~NVRAM_WRITE;
- unlock_kernel();
-
+ spin_unlock( &nvram_open_lock );
return( 0 );
}
diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c
index 365348742..9a9020ac7 100644
--- a/drivers/char/pc110pad.c
+++ b/drivers/char/pc110pad.c
@@ -68,7 +68,9 @@ static struct pc110pad_params current_params;
/* driver/filesystem interface management */
static wait_queue_head_t queue;
static struct fasync_struct *asyncptr;
-static int active; /* number of concurrent open()s */
+static int active_count = 0; /* number of concurrent open()s */
+static spinlock_t pc110_lock = SPIN_LOCK_UNLOCKED;
+/* this lock should be held when referencing active_count */
static struct semaphore reader_lock;
/**
@@ -480,15 +482,14 @@ static void sample_debug(int d[3])
int thisd, thisdd, thisx, thisy;
int b;
unsigned long flags;
-
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&pc110_lock, flags);
read_raw_pad(&thisd, &thisdd, &thisx, &thisy);
d[0]=(thisd?0x80:0) | (thisdd?0x40:0) | bounce;
d[1]=(recent_transition?0x80:0)+transition_count;
read_button(&b);
d[2]=(synthesize_tap<<4) | (b?0x01:0);
- restore_flags(flags);
+ spin_unlock_irqrestore(&pc110_lock, flags);
}
/**
@@ -584,11 +585,12 @@ static int fasync_pad(int fd, struct file *filp, int on)
static int close_pad(struct inode * inode, struct file * file)
{
- lock_kernel();
+ unsigned long flags;
fasync_pad(-1, file, 0);
- if (!--active)
+ spin_lock_irqsave(&pc110_lock, flags);
+ if (!--active_count)
outb(0x30, current_params.io+2); /* switch off digitiser */
- unlock_kernel();
+ spin_unlock_irqrestore(&active_lock, flags);
return 0;
}
@@ -608,11 +610,13 @@ static int open_pad(struct inode * inode, struct file * file)
{
unsigned long flags;
- if (active++)
+ spin_lock_irqsave(&pc110_lock, flags);
+ if (active_count++)
+ {
+ spin_unlock_irqrestore(&pc110_lock, flags);
return 0;
+ }
- save_flags(flags);
- cli();
outb(0x30, current_params.io+2); /* switch off digitiser */
pad_irq(0,0,0); /* read to flush any pending bytes */
pad_irq(0,0,0); /* read to flush any pending bytes */
@@ -627,7 +631,7 @@ static int open_pad(struct inode * inode, struct file * file)
synthesize_tap=0;
del_timer(&bounce_timer);
del_timer(&tap_timer);
- restore_flags(flags);
+ spin_unlock_irqrestore(&pc110_lock, flags);
return 0;
}
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index 45aa4efc3..2fc5e15be 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -90,6 +90,7 @@ static int __init psaux_init(void);
static struct aux_queue *queue; /* Mouse data buffer. */
static int aux_count;
+static spinlock_t aux_count_lock = SPIN_LOCK_UNLOCKED;
/* used when we send commands to the mouse that expect an ACK. */
static unsigned char mouse_reply_expected;
@@ -405,8 +406,9 @@ int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data)
if (rqst == PM_RESUME) {
if (queue) { /* Aux port detected */
- if (aux_count == 0) { /* Mouse not in use */
- spin_lock_irqsave(&kbd_controller_lock, flags);
+ spin_lock_irqsave(&aux_count_lock, flags);
+ if ( aux_count == 0) { /* Mouse not in use */
+ spin_lock(&kbd_controller_lock);
/*
* Dell Lat. C600 A06 enables mouse after resume.
* When user touches the pad, it posts IRQ 12
@@ -418,8 +420,9 @@ int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data)
kbd_write_command(KBD_CCMD_WRITE_MODE);
kb_wait();
kbd_write_output(AUX_INTS_OFF);
- spin_unlock_irqrestore(&kbd_controller_lock, flags);
+ spin_unlock(&kbd_controller_lock);
}
+ spin_unlock_irqrestore(&aux_count_lock, flags);
}
}
#endif
@@ -430,6 +433,7 @@ int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data)
static inline void handle_mouse_event(unsigned char scancode)
{
#ifdef CONFIG_PSMOUSE
+ unsigned long flags;
static unsigned char prev_code;
if (mouse_reply_expected) {
if (scancode == AUX_ACK) {
@@ -448,7 +452,8 @@ static inline void handle_mouse_event(unsigned char scancode)
prev_code = scancode;
add_mouse_randomness(scancode);
- if (aux_count) {
+ spin_lock_irqsave(&aux_count_lock, flags);
+ if ( aux_count ) {
int head = queue->head;
queue->buf[head] = scancode;
@@ -459,6 +464,7 @@ static inline void handle_mouse_event(unsigned char scancode)
wake_up_interruptible(&queue->proc_list);
}
}
+ spin_unlock_irqrestore(&aux_count_lock, flags);
#endif
}
@@ -1046,16 +1052,17 @@ static int fasync_aux(int fd, struct file *filp, int on)
static int release_aux(struct inode * inode, struct file * file)
{
- lock_kernel();
+ unsigned long flags;
fasync_aux(-1, file, 0);
- if (--aux_count) {
- unlock_kernel();
+ spin_lock_irqsave(&aux_count_lock, flags);
+ if ( --aux_count ) {
+ spin_unlock_irqrestore(&aux_count_lock, flags);
return 0;
}
+ spin_unlock_irqrestore(&aux_count_lock, flags);
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
aux_free_irq(AUX_DEV);
- unlock_kernel();
return 0;
}
@@ -1066,14 +1073,24 @@ static int release_aux(struct inode * inode, struct file * file)
static int open_aux(struct inode * inode, struct file * file)
{
- if (aux_count++) {
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&aux_count_lock, flags);
+ if ( aux_count++ ) {
+ spin_unlock_irqrestore(&aux_count_lock, flags);
return 0;
}
queue->head = queue->tail = 0; /* Flush input queue */
- if (aux_request_irq(keyboard_interrupt, AUX_DEV)) {
+ spin_unlock_irqrestore(&aux_count_lock, flags);
+ ret = aux_request_irq(keyboard_interrupt, AUX_DEV);
+ spin_lock_irqsave(&aux_count_lock, flags);
+ if (ret) {
aux_count--;
+ spin_unlock_irqrestore(&aux_count_lock, flags);
return -EBUSY;
}
+ spin_unlock_irqrestore(&aux_count_lock, flags);
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the
auxiliary port on
controller. */
@@ -1083,7 +1100,6 @@ static int open_aux(struct inode * inode, struct file * file)
mdelay(2); /* Ensure we follow the kbc access delay rules.. */
send_data(KBD_CMD_ENABLE); /* try to workaround toshiba4030cdt problem */
-
return 0;
}
diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c
index c6631159e..c85da8a94 100644
--- a/drivers/char/pcwd.c
+++ b/drivers/char/pcwd.c
@@ -100,7 +100,8 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
#define WD_SRLY2 0x80 /* Software external relay triggered */
static int current_readport, revision, temp_panic;
-static int is_open, initial_status, supports_temp, mode_debug;
+static atomic_t open_allowed = ATOMIC_INIT(1);
+static int initial_status, supports_temp, mode_debug;
static spinlock_t io_lock;
/*
@@ -402,9 +403,12 @@ static int pcwd_open(struct inode *ino, struct file *filep)
switch (MINOR(ino->i_rdev))
{
case WATCHDOG_MINOR:
- if (is_open)
+ if ( !atomic_dec_and_test(&open_allowed) )
+ {
+ atomic_inc( &open_allowed );
return -EBUSY;
- MOD_INC_USE_COUNT;
+ }
+ MOD_INC_USE_COUNT;
/* Enable the port */
if (revision == PCWD_REVISION_C)
{
@@ -412,7 +416,6 @@ static int pcwd_open(struct inode *ino, struct file *filep)
outb_p(0x00, current_readport + 3);
spin_unlock(&io_lock);
}
- is_open = 1;
return(0);
case TEMP_MINOR:
return(0);
@@ -452,8 +455,6 @@ static int pcwd_close(struct inode *ino, struct file *filep)
{
if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)
{
- lock_kernel();
- is_open = 0;
#ifndef CONFIG_WATCHDOG_NOWAYOUT
/* Disable the board */
if (revision == PCWD_REVISION_C) {
@@ -462,8 +463,8 @@ static int pcwd_close(struct inode *ino, struct file *filep)
outb_p(0xA5, current_readport + 3);
spin_unlock(&io_lock);
}
+ atomic_inc( &open_allowed );
#endif
- unlock_kernel();
}
return 0;
}
@@ -574,7 +575,7 @@ static int __init pcwatchdog_init(void)
printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
/* Initial variables */
- is_open = 0;
+ set_bit( 0, &open_allowed );
supports_temp = 0;
mode_debug = 0;
temp_panic = 0;
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 2e9e326b0..2a2dea8fa 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -646,7 +646,6 @@ static int pp_release (struct inode * inode, struct file * file)
struct pp_struct *pp = file->private_data;
int compat_negot;
- lock_kernel();
compat_negot = 0;
if (!(pp->flags & PP_CLAIMED) && pp->pdev &&
(pp->state.mode != IEEE1284_MODE_COMPAT)) {
@@ -695,7 +694,6 @@ static int pp_release (struct inode * inode, struct file * file)
printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n",
minor);
}
- unlock_kernel();
kfree (pp);
diff --git a/drivers/char/qpmouse.c b/drivers/char/qpmouse.c
index e8228cc9e..a83dabff3 100644
--- a/drivers/char/qpmouse.c
+++ b/drivers/char/qpmouse.c
@@ -111,6 +111,7 @@ static int fasync_qp(int fd, struct file *filp, int on)
static int qp_present;
static int qp_count;
+static spinlock_t qp_count_lock = SPIN_LOCK_UNLOCKED;
static int qp_data = QP_DATA;
static int qp_status = QP_STATUS;
@@ -141,8 +142,8 @@ static int release_qp(struct inode * inode, struct file * file)
{
unsigned char status;
- lock_kernel();
fasync_qp(-1, file, 0);
+ spin_lock( &qp_count_lock );
if (!--qp_count) {
if (!poll_qp_status())
printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n");
@@ -152,7 +153,7 @@ static int release_qp(struct inode * inode, struct file * file)
printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n");
free_irq(QP_IRQ, NULL);
}
- unlock_kernel();
+ spin_unlock( &qp_count_lock );
return 0;
}
@@ -168,8 +169,13 @@ static int open_qp(struct inode * inode, struct file * file)
if (!qp_present)
return -EINVAL;
+ spin_lock( &qp_count_lock );
if (qp_count++)
+ {
+ spin_unlock( &qp_count_lock );
return 0;
+ }
+ spin_unlock( &qp_count_lock );
if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) {
qp_count--;
diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
index 28e7668ce..50089019f 100644
--- a/drivers/char/qtronix.c
+++ b/drivers/char/qtronix.c
@@ -492,10 +492,8 @@ static int fasync_aux(int fd, struct file *filp, int on)
static int release_aux(struct inode * inode, struct file * file)
{
- lock_kernel();
fasync_aux(-1, file, 0);
aux_count--;
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index d90d9723c..e9a963319 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -126,10 +126,8 @@ int raw_open(struct inode *inode, struct file *filp)
if (is_mounted(rdev)) {
if (blksize_size[MAJOR(rdev)])
sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)];
- } else {
- if (hardsect_size[MAJOR(rdev)])
- sector_size = hardsect_size[MAJOR(rdev)][MINOR(rdev)];
- }
+ } else
+ sector_size = get_hardsect_size(rdev);
set_blocksize(rdev, sector_size);
raw_devices[minor].sector_size = sector_size;
@@ -273,16 +271,14 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
struct kiobuf * iobuf;
int new_iobuf;
int err = 0;
- unsigned long blocknr, blocks;
+ unsigned long blocks;
size_t transferred;
int iosize;
- int i;
int minor;
kdev_t dev;
unsigned long limit;
-
int sector_size, sector_bits, sector_mask;
- int max_sectors;
+ sector_t blocknr;
/*
* First, a few checks on device size limits
@@ -307,7 +303,6 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
sector_size = raw_devices[minor].sector_size;
sector_bits = raw_devices[minor].sector_bits;
sector_mask = sector_size- 1;
- max_sectors = KIO_MAX_SECTORS >> (sector_bits - 9);
if (blk_size[MAJOR(dev)])
limit = (((loff_t) blk_size[MAJOR(dev)][MINOR(dev)]) << BLOCK_SIZE_BITS) >> sector_bits;
@@ -325,18 +320,10 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
if ((*offp >> sector_bits) >= limit)
goto out_free;
- /*
- * Split the IO into KIO_MAX_SECTORS chunks, mapping and
- * unmapping the single kiobuf as we go to perform each chunk of
- * IO.
- */
-
transferred = 0;
blocknr = *offp >> sector_bits;
while (size > 0) {
blocks = size >> sector_bits;
- if (blocks > max_sectors)
- blocks = max_sectors;
if (blocks > limit - blocknr)
blocks = limit - blocknr;
if (!blocks)
@@ -348,10 +335,7 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
if (err)
break;
- for (i=0; i < blocks; i++)
- iobuf->blocks[i] = blocknr++;
-
- err = brw_kiovec(rw, 1, &iobuf, dev, iobuf->blocks, sector_size);
+ err = brw_kiovec(rw, 1, &iobuf, dev, &blocknr, sector_size);
if (rw == READ && err > 0)
mark_dirty_kiobuf(iobuf, err);
@@ -362,6 +346,8 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
buf += err;
}
+ blocknr += blocks;
+
unmap_kiobuf(iobuf);
if (err != iosize)
diff --git a/drivers/char/sbc60xxwdt.c b/drivers/char/sbc60xxwdt.c
index aae5ad190..e38516fc3 100644
--- a/drivers/char/sbc60xxwdt.c
+++ b/drivers/char/sbc60xxwdt.c
@@ -214,7 +214,6 @@ static int fop_open(struct inode * inode, struct file * file)
static int fop_close(struct inode * inode, struct file * file)
{
- lock_kernel();
if(MINOR(inode->i_rdev) == WATCHDOG_MINOR)
{
if(wdt_expect_close)
@@ -225,7 +224,6 @@ static int fop_close(struct inode * inode, struct file * file)
}
}
wdt_is_open = 0;
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index adbe3ffa8..604dfc34a 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -122,7 +122,7 @@ static char *serial_revdate = "2001-07-08";
#define ENABLE_SERIAL_ACPI
#endif
-#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
+#ifdef __ISAPNP__
#ifndef ENABLE_SERIAL_PNP
#define ENABLE_SERIAL_PNP
#endif
diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c
index 8342877b3..7635904d9 100644
--- a/drivers/char/softdog.c
+++ b/drivers/char/softdog.c
@@ -100,12 +100,10 @@ static int softdog_release(struct inode *inode, struct file *file)
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
- lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
del_timer(&watchdog_ticktock);
#endif
timer_alive=0;
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c
index c4c41773d..1bdc186d9 100644
--- a/drivers/char/tpqic02.c
+++ b/drivers/char/tpqic02.c
@@ -2395,7 +2395,6 @@ static int qic02_tape_release(struct inode *inode, struct file *filp)
{
kdev_t dev = inode->i_rdev;
- lock_kernel();
if (TP_DIAGS(dev)) {
printk("qic02_tape_release: dev=%s\n", kdevname(dev));
}
@@ -2419,7 +2418,6 @@ static int qic02_tape_release(struct inode *inode, struct file *filp)
(void) do_qic_cmd(QCMD_REWIND, TIM_R);
}
}
- unlock_kernel();
return 0;
} /* qic02_tape_release */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e8d2daa4d..befe38e54 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -102,10 +102,6 @@
#include <linux/kmod.h>
-#ifdef CONFIG_VT
-extern void con_init_devfs (void);
-#endif
-
#define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
#define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1)
@@ -2246,6 +2242,8 @@ static struct tty_driver dev_tty_driver, dev_syscons_driver;
static struct tty_driver dev_ptmx_driver;
#endif
#ifdef CONFIG_VT
+extern void con_init_devfs (void);
+extern void console_map_init(void);
static struct tty_driver dev_console_driver;
#endif
@@ -2317,7 +2315,9 @@ void __init tty_init(void)
if (tty_register_driver(&dev_console_driver))
panic("Couldn't register /dev/tty0 driver\n");
+ vcs_init();
kbd_init();
+ console_map_init();
#endif
#ifdef CONFIG_ESPSERIAL /* init ESP before rs, so rs doesn't see the port */
@@ -2363,9 +2363,6 @@ void __init tty_init(void)
#ifdef CONFIG_MOXA_INTELLIO
moxa_init();
#endif
-#ifdef CONFIG_VT
- vcs_init();
-#endif
#ifdef CONFIG_TN3270
tub3270_init();
#endif
diff --git a/drivers/char/w83877f_wdt.c b/drivers/char/w83877f_wdt.c
index 1ea6abb2b..f621c158f 100644
--- a/drivers/char/w83877f_wdt.c
+++ b/drivers/char/w83877f_wdt.c
@@ -214,7 +214,6 @@ static int fop_open(struct inode * inode, struct file * file)
static int fop_close(struct inode * inode, struct file * file)
{
- lock_kernel();
if(MINOR(inode->i_rdev) == WATCHDOG_MINOR)
{
if(wdt_expect_close)
@@ -225,7 +224,6 @@ static int fop_close(struct inode * inode, struct file * file)
}
}
wdt_is_open = 0;
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c
index 7ff3e7d3d..fbf26d0a6 100644
--- a/drivers/char/wdt.c
+++ b/drivers/char/wdt.c
@@ -50,7 +50,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
-static int wdt_is_open;
+static unsigned long wdt_is_open;
/*
* You must set these - there is no sane way to probe for this board.
@@ -337,13 +337,12 @@ static int wdt_open(struct inode *inode, struct file *file)
switch(MINOR(inode->i_rdev))
{
case WATCHDOG_MINOR:
- if(wdt_is_open)
+ if(test_and_set_bit(0, &wdt_is_open))
return -EBUSY;
/*
* Activate
*/
- wdt_is_open=1;
inb_p(WDT_DC); /* Disable */
wdt_ctr_mode(0,3);
wdt_ctr_mode(1,2);
@@ -374,16 +373,14 @@ static int wdt_open(struct inode *inode, struct file *file)
static int wdt_release(struct inode *inode, struct file *file)
{
- lock_kernel();
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
#ifndef CONFIG_WATCHDOG_NOWAYOUT
inb_p(WDT_DC); /* Disable counters */
wdt_ctr_load(2,0); /* 0 length reset pulses now */
#endif
- wdt_is_open=0;
+ clear_bit(0, &wdt_is_open);
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/char/wdt285.c b/drivers/char/wdt285.c
index ca1b76328..ee59d8f94 100644
--- a/drivers/char/wdt285.c
+++ b/drivers/char/wdt285.c
@@ -94,10 +94,8 @@ static int watchdog_open(struct inode *inode, struct file *file)
static int watchdog_release(struct inode *inode, struct file *file)
{
#ifdef ONLY_TESTING
- lock_kernel();
free_irq(IRQ_TIMER4, NULL);
timer_alive = 0;
- unlock_kernel();
#else
/*
* It's irreversible!
diff --git a/drivers/char/wdt977.c b/drivers/char/wdt977.c
index 74f1fcdbb..7f9dde05c 100644
--- a/drivers/char/wdt977.c
+++ b/drivers/char/wdt977.c
@@ -92,7 +92,6 @@ static int wdt977_release(struct inode *inode, struct file *file)
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
#ifndef CONFIG_WATCHDOG_NOWAYOUT
- lock_kernel();
// unlock the SuperIO chip
outb(0x87,0x370);
@@ -124,7 +123,6 @@ static int wdt977_release(struct inode *inode, struct file *file)
outb(0xAA,0x370);
timer_alive=0;
- unlock_kernel();
printk(KERN_INFO "Watchdog: shutdown.\n");
#endif
diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c
index e4c8e9950..8dac309cf 100644
--- a/drivers/char/wdt_pci.c
+++ b/drivers/char/wdt_pci.c
@@ -71,7 +71,7 @@
#define PCI_DEVICE_ID_WDG_CSM 0x22c0
#endif
-static int wdt_is_open;
+static unsigned long wdt_is_open;
/*
* You must set these - there is no sane way to probe for this board.
@@ -353,16 +353,16 @@ static int wdtpci_open(struct inode *inode, struct file *file)
switch(MINOR(inode->i_rdev))
{
case WATCHDOG_MINOR:
- if(wdt_is_open)
+ if( test_and_set_bit(0,&wdt_is_open) )
+ {
return -EBUSY;
+ }
#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
#endif
/*
* Activate
*/
-
- wdt_is_open=1;
inb_p(WDT_DC); /* Disable */
@@ -412,13 +412,11 @@ static int wdtpci_release(struct inode *inode, struct file *file)
{
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
- lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
inb_p(WDT_DC); /* Disable counters */
wdtpci_ctr_load(2,0); /* 0 length reset pulses now */
#endif
- wdt_is_open=0;
- unlock_kernel();
+ clear_bit(0, &wdt_is_open );
}
return 0;
}
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index 6a1282923..9068ede28 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -767,8 +767,12 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */
static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
if (FCP_CMND(SCpnt)->done)
FCP_CMND(SCpnt)->done(SCpnt);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
}
static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
@@ -913,8 +917,12 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
*/
if (++fc->abort_count < (fc->can_queue >> 1)) {
+ unsigned long flags;
+
SCpnt->result = DID_ABORT;
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
fcmd->done(SCpnt);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
printk("FC: soft abort\n");
return SUCCESS;
} else {
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index 924de1cb7..19aee0628 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -341,14 +341,14 @@ static void soc_intr(int irq, void *dev_id, struct pt_regs *regs)
unsigned long flags;
register struct soc *s = (struct soc *)dev_id;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&s->lock, flags);
cmd = sbus_readl(s->regs + CMD);
for (; (cmd = SOC_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) {
if (cmd & SOC_CMD_RSP_Q1) soc_unsolicited (s);
if (cmd & SOC_CMD_RSP_Q0) soc_solicited (s);
if (cmd & SOC_CMD_REQ_QALL) soc_request (s, cmd);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&s->lock, flags);
}
#define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port))
@@ -559,6 +559,7 @@ static inline void soc_init(struct sbus_dev *sdev, int no)
if (s == NULL)
return;
memset (s, 0, sizeof(struct soc));
+ spin_lock_init(&s->lock);
s->soc_no = no;
SOD(("socs %08lx soc_intr %08lx soc_hw_enque %08x\n",
diff --git a/drivers/fc4/soc.h b/drivers/fc4/soc.h
index 740e1a395..c9c6d1d9d 100644
--- a/drivers/fc4/soc.h
+++ b/drivers/fc4/soc.h
@@ -265,6 +265,7 @@ typedef struct {
} soc_cq;
struct soc {
+ spinlock_t lock;
soc_port port[2]; /* Every SOC has one or two FC ports */
soc_cq req[2]; /* Request CQs */
soc_cq rsp[2]; /* Response CQs */
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c
index bec516733..447a4de67 100644
--- a/drivers/fc4/socal.c
+++ b/drivers/fc4/socal.c
@@ -411,7 +411,7 @@ static void socal_intr(int irq, void *dev_id, struct pt_regs *regs)
unsigned long flags;
register struct socal *s = (struct socal *)dev_id;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&s->lock, flags);
cmd = sbus_readl(s->regs + CMD);
for (; (cmd = SOCAL_INTR (s, cmd)); cmd = sbus_readl(s->regs + CMD)) {
#ifdef SOCALDEBUG
@@ -428,7 +428,7 @@ static void socal_intr(int irq, void *dev_id, struct pt_regs *regs)
if (cmd & SOCAL_CMD_REQ_QALL)
socal_request (s, cmd);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&s->lock, flags);
}
#define TOKEN(proto, port, token) (((proto)<<12)|(token)|(port))
@@ -667,6 +667,7 @@ static inline void socal_init(struct sbus_dev *sdev, int no)
s = kmalloc (sizeof (struct socal), GFP_KERNEL);
if (!s) return;
memset (s, 0, sizeof(struct socal));
+ spin_lock_init(&s->lock);
s->socal_no = no;
SOD(("socals %08lx socal_intr %08lx socal_hw_enque %08lx\n",
diff --git a/drivers/fc4/socal.h b/drivers/fc4/socal.h
index 8e8c7f451..a853fad92 100644
--- a/drivers/fc4/socal.h
+++ b/drivers/fc4/socal.h
@@ -290,6 +290,7 @@ typedef struct {
} socal_cq;
struct socal {
+ spinlock_t lock;
socal_port port[2]; /* Every SOCAL has one or two FC ports */
socal_cq req[4]; /* Request CQs */
socal_cq rsp[4]; /* Response CQs */
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index a7b80f932..6d3ab3825 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -423,14 +423,9 @@ static int i2cdev_release (struct inode *inode, struct file *file)
#endif
#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
MOD_DEC_USE_COUNT;
-#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
- lock_kernel();
#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
if (i2cdev_adaps[minor]->dec_use)
i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]);
-#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
- unlock_kernel();
-#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
return 0;
}
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 2f3d2fc3a..c97c89f99 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -557,6 +557,7 @@ void __init ide_init_aec62xx (ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base)
hwif->dmaproc = &aec62xx_dmaproc;
+ hwif->highmem = 1;
#else /* !CONFIG_BLK_DEV_IDEDMA */
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 54796da6f..382ac234f 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -75,7 +75,8 @@ static unsigned int amd74xx_swdma_check (struct pci_dev *dev)
{
unsigned int class_rev;
- if (dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
+ if ((dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ||
+ (dev->device == PCI_DEVICE_ID_AMD_VIPER_7441))
return 0;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
@@ -122,8 +123,8 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
pci_read_config_byte(dev, 0x4c, &pio_timing);
#ifdef DEBUG
- printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
- drive->name, ultra_timing, dma_pio_timing, pio_timing);
+ printk("%s:%d: Speed 0x%02x UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+ drive->name, drive->dn, speed, ultra_timing, dma_pio_timing, pio_timing);
#endif
ultra_timing &= ~0xC7;
@@ -131,22 +132,19 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
pio_timing &= ~(0x03 << drive->dn);
#ifdef DEBUG
- printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
- ultra_timing, dma_pio_timing, pio_timing);
+ printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+ drive->name, ultra_timing, dma_pio_timing, pio_timing);
#endif
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
+ case XFER_UDMA_7:
+ case XFER_UDMA_6:
+ speed = XFER_UDMA_5;
case XFER_UDMA_5:
-#undef __CAN_MODE_5
-#ifdef __CAN_MODE_5
ultra_timing |= 0x46;
dma_pio_timing |= 0x20;
break;
-#else
- printk("%s: setting to mode 4, driver problems in mode 5.\n", drive->name);
- speed = XFER_UDMA_4;
-#endif /* __CAN_MODE_5 */
case XFER_UDMA_4:
ultra_timing |= 0x45;
dma_pio_timing |= 0x20;
@@ -222,8 +220,8 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
pci_write_config_byte(dev, 0x4c, pio_timing);
#ifdef DEBUG
- printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
- ultra_timing, dma_pio_timing, pio_timing);
+ printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
+ drive->name, ultra_timing, dma_pio_timing, pio_timing);
#endif
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -303,11 +301,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
struct pci_dev *dev = hwif->pci_dev;
struct hd_driveid *id = drive->id;
byte udma_66 = eighty_ninty_three(drive);
- byte udma_100 = (dev->device==PCI_DEVICE_ID_AMD_VIPER_7411) ? 1 : 0;
+ byte udma_100 = ((dev->device==PCI_DEVICE_ID_AMD_VIPER_7411)||
+ (dev->device==PCI_DEVICE_ID_AMD_VIPER_7441)) ? 1 : 0;
byte speed = 0x00;
int rval;
- if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) {
+ if ((id->dma_ultra & 0x0020) && (udma_66) && (udma_100)) {
speed = XFER_UDMA_5;
} else if ((id->dma_ultra & 0x0010) && (udma_66)) {
speed = XFER_UDMA_4;
@@ -331,7 +330,7 @@ static int config_chipset_for_dma (ide_drive_t *drive)
(void) amd74xx_tune_chipset(drive, speed);
- rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
ide_dma_off_quietly);
@@ -352,7 +351,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x002F) {
+ if (id->dma_ultra & 0x003F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 80688e5a3..85f985487 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -795,5 +795,7 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif)
default:
break;
}
+
+ hwif->highmem = 1;
#endif /* CONFIG_BLK_DEV_IDEDMA */
}
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index c975a0d72..9a3678442 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -352,9 +352,10 @@ void __init ide_init_cs5530 (ide_hwif_t *hwif)
unsigned int basereg, d0_timings;
#ifdef CONFIG_BLK_DEV_IDEDMA
- hwif->dmaproc = &cs5530_dmaproc;
+ hwif->dmaproc = &cs5530_dmaproc;
+ hwif->highmem = 1;
#else
- hwif->autodma = 0;
+ hwif->autodma = 0;
#endif /* CONFIG_BLK_DEV_IDEDMA */
hwif->tuneproc = &cs5530_tuneproc;
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 3363e4a1f..964dfc9fe 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -441,6 +441,7 @@ void __init ide_init_cy82c693(ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
+ hwif->highmem = 1;
hwif->dmaproc = &cy82c693_dmaproc;
if (!noautodma)
hwif->autodma = 1;
diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c
index 3df63cace..38c077747 100644
--- a/drivers/ide/hd.c
+++ b/drivers/ide/hd.c
@@ -107,7 +107,6 @@ static struct hd_struct hd[MAX_HD<<6];
static int hd_sizes[MAX_HD<<6];
static int hd_blocksizes[MAX_HD<<6];
static int hd_hardsectsizes[MAX_HD<<6];
-static int hd_maxsect[MAX_HD<<6];
static struct timer_list device_timer;
@@ -560,19 +559,18 @@ repeat:
dev = MINOR(CURRENT->rq_dev);
block = CURRENT->sector;
nsect = CURRENT->nr_sectors;
- if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
-#ifdef DEBUG
- if (dev >= (NR_HD<<6))
+ if (dev >= (NR_HD<<6) || (dev & 0x3f) ||
+ block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
+ if (dev >= (NR_HD<<6) || (dev & 0x3f))
printk("hd: bad minor number: device=%s\n",
kdevname(CURRENT->rq_dev));
else
printk("hd%c: bad access: block=%d, count=%d\n",
(MINOR(CURRENT->rq_dev)>>6)+'a', block, nsect);
-#endif
end_request(0);
goto repeat;
}
- block += hd[dev].start_sect;
+
dev >>= 6;
if (special_op[dev]) {
if (do_special_op(dev))
@@ -634,22 +632,17 @@ static int hd_ioctl(struct inode * inode, struct file * file,
g.heads = hd_info[dev].head;
g.sectors = hd_info[dev].sect;
g.cylinders = hd_info[dev].cyl;
- g.start = hd[MINOR(inode->i_rdev)].start_sect;
+ g.start = get_start_sect(inode->i_rdev);
return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
}
- case BLKGETSIZE: /* Return device size */
- return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
- (unsigned long *) arg);
- case BLKGETSIZE64:
- return put_user((u64)hd[MINOR(inode->i_rdev)].nr_sects << 9,
- (u64 *) arg);
-
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return revalidate_hddisk(inode->i_rdev, 1);
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKROSET:
case BLKROGET:
case BLKRASET:
@@ -733,11 +726,9 @@ static void __init hd_geninit(void)
for(drive=0; drive < (MAX_HD << 6); drive++) {
hd_blocksizes[drive] = 1024;
hd_hardsectsizes[drive] = 512;
- hd_maxsect[drive]=255;
}
blksize_size[MAJOR_NR] = hd_blocksizes;
hardsect_size[MAJOR_NR] = hd_hardsectsizes;
- max_sectors[MAJOR_NR] = hd_maxsect;
#ifdef __i386__
if (!NR_HD) {
@@ -840,6 +831,7 @@ int __init hd_init(void)
return -1;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+ blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 255);
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
add_gendisk(&hd_gendisk);
init_timer(&device_timer);
@@ -868,9 +860,7 @@ static int revalidate_hddisk(kdev_t dev, int maxusage)
{
int target;
struct gendisk * gdev;
- int max_p;
- int start;
- int i;
+ int res;
long flags;
target = DEVICE_NR(dev);
@@ -885,25 +875,20 @@ static int revalidate_hddisk(kdev_t dev, int maxusage)
DEVICE_BUSY = 1;
restore_flags(flags);
- max_p = gdev->max_p;
- start = target << gdev->minor_shift;
-
- for (i=max_p - 1; i >=0 ; i--) {
- int minor = start + i;
- invalidate_device(MKDEV(MAJOR_NR, minor), 1);
- gdev->part[minor].start_sect = 0;
- gdev->part[minor].nr_sects = 0;
- }
+ res = wipe_partitions(dev);
+ if (res)
+ goto leave;
#ifdef MAYBE_REINIT
MAYBE_REINIT;
#endif
- grok_partitions(gdev, target, 1<<6, CAPACITY);
+ grok_partitions(dev, CAPACITY);
+leave:
DEVICE_BUSY = 0;
wake_up(&busy_wait);
- return 0;
+ return res;
}
static int parse_hd_setup (char *line) {
diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c
index d305e59a6..296d02958 100644
--- a/drivers/ide/hpt34x.c
+++ b/drivers/ide/hpt34x.c
@@ -425,6 +425,7 @@ void __init ide_init_hpt34x (ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->dmaproc = &hpt34x_dmaproc;
+ hwif->highmem = 1;
} else {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 9e98c5696..f216dfeb3 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -730,6 +730,7 @@ void __init ide_init_hpt366 (ide_hwif_t *hwif)
hwif->autodma = 1;
else
hwif->autodma = 0;
+ hwif->highmem = 1;
} else {
hwif->autodma = 0;
hwif->drives[0].autotune = 1;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 00d36a8b7..6046904e3 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -533,8 +533,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive,
/* stuff the sense request in front of our current request */
rq = &info->request_sense_request;
ide_init_drive_cmd(rq);
- rq->cmd = REQUEST_SENSE_COMMAND;
- rq->buffer = (char *) pc;
+ rq->flags = REQ_SENSE;
+ rq->special = (char *) pc;
rq->waiting = wait;
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
@@ -544,17 +544,17 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) {
- struct packet_command *pc = (struct packet_command *) rq->buffer;
+ if ((rq->flags & REQ_SENSE) && uptodate) {
+ struct packet_command *pc = (struct packet_command *) rq->special;
cdrom_analyze_sense_data(drive,
(struct packet_command *) pc->sense,
(struct request_sense *) (pc->buffer - pc->c[4]));
}
- if (rq->cmd == READ || rq->cmd == WRITE)
- if (!rq->current_nr_sectors)
- uptodate = 1;
- ide_end_request (uptodate, HWGROUP(drive));
+ if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
+ uptodate = 1;
+
+ ide_end_request(uptodate, HWGROUP(drive));
}
@@ -584,21 +584,20 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
return 1;
}
- if (rq->cmd == REQUEST_SENSE_COMMAND) {
+ if (rq->flags & REQ_SENSE) {
/* We got an error trying to get sense info
from the drive (probably while trying
to recover from a former error). Just give up. */
- pc = (struct packet_command *) rq->buffer;
+ pc = (struct packet_command *) rq->special;
pc->stat = 1;
cdrom_end_request (1, drive);
*startstop = ide_error (drive, "request sense failure", stat);
return 1;
-
- } else if (rq->cmd == PACKET_COMMAND) {
+ } else if (rq->flags & REQ_PC) {
/* All other functions, except for READ. */
struct completion *wait = NULL;
- pc = (struct packet_command *) rq->buffer;
+ pc = (struct packet_command *) rq->special;
/* Check for tray open. */
if (sense_key == NOT_READY) {
@@ -632,7 +631,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
if ((stat & ERR_STAT) != 0)
cdrom_queue_request_sense(drive, wait, pc->sense, pc);
- } else {
+ } else if (rq->flags & REQ_CMD) {
/* Handle errors from READ and WRITE requests. */
if (sense_key == NOT_READY) {
@@ -671,7 +670,8 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
queue a request sense command. */
if ((stat & ERR_STAT) != 0)
cdrom_queue_request_sense(drive, NULL, NULL, NULL);
- }
+ } else
+ blk_dump_rq_flags(rq, "ide-cd bad flags");
/* Retry, or handle the next request. */
*startstop = ide_stopped;
@@ -681,7 +681,6 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
static int cdrom_timer_expiry(ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *) rq->buffer;
unsigned long wait = 0;
/*
@@ -690,7 +689,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
* this, but not all commands/drives support that. Let
* ide_timer_expiry keep polling us for these.
*/
- switch (pc->c[0]) {
+ switch (rq->cmd[0]) {
case GPCMD_BLANK:
case GPCMD_FORMAT_UNIT:
case GPCMD_RESERVE_RZONE_TRACK:
@@ -700,6 +699,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
wait = 0;
break;
}
+
return wait;
}
@@ -891,7 +891,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
int stat;
int ireason, len, sectors_to_transfer, nskip;
struct cdrom_info *info = drive->driver_data;
- int i, dma = info->dma, dma_error = 0;
+ int dma = info->dma, dma_error = 0;
ide_startstop_t startstop;
struct request *rq = HWGROUP(drive)->rq;
@@ -908,10 +908,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
if (dma) {
if (!dma_error) {
- for (i = rq->nr_sectors; i > 0;) {
- i -= rq->current_nr_sectors;
- ide_end_request(1, HWGROUP(drive));
- }
+ __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors);
return ide_stopped;
} else
return ide_error (drive, "dma error", stat);
@@ -926,7 +923,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
/* If we're not done filling the current buffer, complain.
Otherwise, complete the command normally. */
if (rq->current_nr_sectors > 0) {
- printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n",
+ printk ("%s: cdrom_read_intr: data underrun (%u blocks)\n",
drive->name, rq->current_nr_sectors);
cdrom_end_request (0, drive);
} else
@@ -959,8 +956,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
/* First, figure out if we need to bit-bucket
any of the leading sectors. */
- nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)),
- sectors_to_transfer);
+ nskip = MIN(rq->current_nr_sectors - bio_sectors(rq->bio), sectors_to_transfer);
while (nskip > 0) {
/* We need to throw away a sector. */
@@ -1058,7 +1054,7 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
represent the number of sectors to skip at the start of a transfer
will fail. I think that this will never happen, but let's be
paranoid and check. */
- if (rq->current_nr_sectors < (rq->bh->b_size >> SECTOR_BITS) &&
+ if (rq->current_nr_sectors < bio_sectors(rq->bio) &&
(rq->sector % SECTORS_PER_FRAME) != 0) {
printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
drive->name, rq->sector);
@@ -1097,9 +1093,9 @@ static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
nskip = (sector % SECTORS_PER_FRAME);
if (nskip > 0) {
/* Sanity check... */
- if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS) &&
+ if (rq->current_nr_sectors != bio_sectors(rq->bio) &&
(rq->sector % CD_FRAMESIZE != 0)) {
- printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n",
+ printk ("%s: cdrom_start_read_continuation: buffer botch (%u)\n",
drive->name, rq->current_nr_sectors);
cdrom_end_request (0, drive);
return ide_stopped;
@@ -1120,11 +1116,7 @@ static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
(65534 / CD_FRAMESIZE) : 65535);
/* Set up the command */
- memset (&pc.c, 0, sizeof (pc.c));
- pc.c[0] = GPCMD_READ_10;
- pc.c[7] = (nframes >> 8);
- pc.c[8] = (nframes & 0xff);
- put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
+ memcpy(pc.c, rq->cmd, sizeof(pc.c));
pc.timeout = WAIT_CMD;
/* Send the command to the drive and return. */
@@ -1174,7 +1166,7 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
sector -= nskip;
frame = sector / SECTORS_PER_FRAME;
- memset (&pc.c, 0, sizeof (pc.c));
+ memset(rq->cmd, 0, sizeof(rq->cmd));
pc.c[0] = GPCMD_SEEK;
put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
@@ -1192,68 +1184,23 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
return cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation);
}
-static inline int cdrom_merge_requests(struct request *rq, struct request *nxt)
-{
- int ret = 1;
-
- /*
- * partitions not really working, but better check anyway...
- */
- if (rq->cmd == nxt->cmd && rq->rq_dev == nxt->rq_dev) {
- rq->nr_sectors += nxt->nr_sectors;
- rq->hard_nr_sectors += nxt->nr_sectors;
- rq->bhtail->b_reqnext = nxt->bh;
- rq->bhtail = nxt->bhtail;
- list_del(&nxt->queue);
- blkdev_release_request(nxt);
- ret = 0;
- }
-
- return ret;
-}
-
/*
- * the current request will always be the first one on the list
+ * Fix up a possibly partially-processed request so that we can
+ * start it over entirely -- remember to call prep_rq_fn again since we
+ * may have changed the layout
*/
-static void cdrom_attempt_remerge(ide_drive_t *drive, struct request *rq)
-{
- struct list_head *entry;
- struct request *nxt;
- unsigned long flags;
-
- spin_lock_irqsave(&io_request_lock, flags);
-
- while (1) {
- entry = rq->queue.next;
- if (entry == &drive->queue.queue_head)
- break;
-
- nxt = blkdev_entry_to_request(entry);
- if (rq->sector + rq->nr_sectors != nxt->sector)
- break;
- else if (rq->nr_sectors + nxt->nr_sectors > SECTORS_MAX)
- break;
-
- if (cdrom_merge_requests(rq, nxt))
- break;
- }
-
- spin_unlock_irqrestore(&io_request_lock, flags);
-}
-
-/* Fix up a possibly partially-processed request so that we can
- start it over entirely, or even put it back on the request queue. */
static void restore_request (struct request *rq)
{
- if (rq->buffer != rq->bh->b_data) {
- int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE;
- rq->buffer = rq->bh->b_data;
+ if (rq->buffer != bio_data(rq->bio)) {
+ int n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
+ rq->buffer = bio_data(rq->bio);
rq->nr_sectors += n;
rq->sector -= n;
}
- rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS;
+ rq->hard_cur_sectors = rq->current_nr_sectors = bio_sectors(rq->bio);
rq->hard_nr_sectors = rq->nr_sectors;
rq->hard_sector = rq->sector;
+ rq->q->prep_rq_fn(rq->q, rq);
}
/*
@@ -1263,25 +1210,14 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
{
struct cdrom_info *info = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
- int minor = MINOR (rq->rq_dev);
-
- /* If the request is relative to a partition, fix it up to refer to the
- absolute address. */
- if (minor & PARTN_MASK) {
- rq->sector = block;
- minor &= ~PARTN_MASK;
- rq->rq_dev = MKDEV(MAJOR(rq->rq_dev), minor);
- }
- /* We may be retrying this request after an error. Fix up
- any weirdness which might be present in the request packet. */
restore_request(rq);
/* Satisfy whatever we can of this request from our cached sector. */
if (cdrom_read_from_buffer(drive))
return ide_stopped;
- cdrom_attempt_remerge(drive, rq);
+ blk_attempt_remerge(&drive->queue, rq);
/* Clear the local sector buffer. */
info->nsectors_buffered = 0;
@@ -1311,7 +1247,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
{
int ireason, len, stat, thislen;
struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
+ struct packet_command *pc = (struct packet_command *) rq->special;
ide_startstop_t startstop;
/* Check for errors. */
@@ -1407,7 +1343,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
+ struct packet_command *pc = (struct packet_command *) rq->special;
if (!pc->timeout)
pc->timeout = WAIT_CMD;
@@ -1421,7 +1357,7 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
{
int len;
struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
+ struct packet_command *pc = (struct packet_command *) rq->special;
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
@@ -1460,8 +1396,8 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
/* Start of retry loop. */
do {
ide_init_drive_cmd (&req);
- req.cmd = PACKET_COMMAND;
- req.buffer = (char *)pc;
+ req.flags = REQ_PC;
+ req.special = (char *) pc;
if (ide_do_drive_cmd (drive, &req, ide_wait)) {
printk("%s: do_drive_cmd returned stat=%02x,err=%02x\n",
drive->name, req.buffer[0], req.buffer[1]);
@@ -1532,7 +1468,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
{
int stat, ireason, len, sectors_to_transfer, uptodate;
struct cdrom_info *info = drive->driver_data;
- int i, dma_error = 0, dma = info->dma;
+ int dma_error = 0, dma = info->dma;
ide_startstop_t startstop;
struct request *rq = HWGROUP(drive)->rq;
@@ -1559,10 +1495,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
return ide_error(drive, "dma error", stat);
rq = HWGROUP(drive)->rq;
- for (i = rq->nr_sectors; i > 0;) {
- i -= rq->current_nr_sectors;
- ide_end_request(1, HWGROUP(drive));
- }
+ __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors);
return ide_stopped;
}
@@ -1577,7 +1510,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
*/
uptodate = 1;
if (rq->current_nr_sectors > 0) {
- printk("%s: write_intr: data underrun (%ld blocks)\n",
+ printk("%s: write_intr: data underrun (%u blocks)\n",
drive->name, rq->current_nr_sectors);
uptodate = 0;
}
@@ -1639,18 +1572,10 @@ static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
nframes = rq->nr_sectors >> 2;
frame = rq->sector >> 2;
- memset(&pc.c, 0, sizeof(pc.c));
- /*
- * we might as well use WRITE_12, but none of the device I have
- * support the streaming feature anyway, so who cares.
- */
- pc.c[0] = GPCMD_WRITE_10;
+ memcpy(pc.c, rq->cmd, sizeof(pc.c));
#if 0 /* the immediate bit */
pc.c[1] = 1 << 3;
#endif
- pc.c[7] = (nframes >> 8) & 0xff;
- pc.c[8] = nframes & 0xff;
- put_unaligned(cpu_to_be32(frame), (unsigned int *)&pc.c[2]);
pc.timeout = 2 * WAIT_CMD;
return cdrom_transfer_packet_command(drive, &pc, cdrom_write_intr);
@@ -1674,7 +1599,7 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
* remerge requests, often the plugging will not have had time
* to do this properly
*/
- cdrom_attempt_remerge(drive, rq);
+ blk_attempt_remerge(&drive->queue, rq);
info->nsectors_buffered = 0;
@@ -1687,6 +1612,28 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
}
+/*
+ * just wrap this around cdrom_do_packet_command
+ */
+static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
+{
+ struct packet_command pc;
+ ide_startstop_t startstop;
+
+ memset(&pc, 0, sizeof(pc));
+ memcpy(pc.c, rq->cmd, sizeof(pc.c));
+ pc.quiet = 1;
+ pc.timeout = 60 * HZ;
+ rq->special = (char *) &pc;
+
+ startstop = cdrom_do_packet_command(drive);
+ if (pc.stat)
+ rq->errors++;
+
+ return startstop;
+}
+
+
/****************************************************************************
* cdrom driver request routine.
*/
@@ -1696,50 +1643,45 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block)
ide_startstop_t action;
struct cdrom_info *info = drive->driver_data;
- switch (rq->cmd) {
- case WRITE:
- case READ: {
- if (CDROM_CONFIG_FLAGS(drive)->seeking) {
- unsigned long elpased = jiffies - info->start_seek;
- int stat = GET_STAT();
-
- if ((stat & SEEK_STAT) != SEEK_STAT) {
- if (elpased < IDECD_SEEK_TIMEOUT) {
- ide_stall_queue(drive, IDECD_SEEK_TIMER);
- return ide_stopped;
- }
- printk ("%s: DSC timeout\n", drive->name);
+ if (rq->flags & REQ_CMD) {
+ if (CDROM_CONFIG_FLAGS(drive)->seeking) {
+ unsigned long elpased = jiffies - info->start_seek;
+ int stat = GET_STAT();
+
+ if ((stat & SEEK_STAT) != SEEK_STAT) {
+ if (elpased < IDECD_SEEK_TIMEOUT) {
+ ide_stall_queue(drive, IDECD_SEEK_TIMER);
+ return ide_stopped;
}
- CDROM_CONFIG_FLAGS(drive)->seeking = 0;
+ printk ("%s: DSC timeout\n", drive->name);
}
- if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
- action = cdrom_start_seek (drive, block);
- else {
- if (rq->cmd == READ)
- action = cdrom_start_read(drive, block);
- else
- action = cdrom_start_write(drive, rq);
- }
- info->last_block = block;
- return action;
- }
-
- case PACKET_COMMAND:
- case REQUEST_SENSE_COMMAND: {
- return cdrom_do_packet_command(drive);
+ CDROM_CONFIG_FLAGS(drive)->seeking = 0;
}
-
- case RESET_DRIVE_COMMAND: {
- cdrom_end_request(1, drive);
- return ide_do_reset(drive);
- }
-
- default: {
- printk("ide-cd: bad cmd %d\n", rq->cmd);
- cdrom_end_request(0, drive);
- return ide_stopped;
+ if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
+ action = cdrom_start_seek (drive, block);
+ else {
+ if (rq_data_dir(rq) == READ)
+ action = cdrom_start_read(drive, block);
+ else
+ action = cdrom_start_write(drive, rq);
}
+ info->last_block = block;
+ return action;
+ } else if (rq->flags & (REQ_PC | REQ_SENSE)) {
+ return cdrom_do_packet_command(drive);
+ } else if (rq->flags & REQ_SPECIAL) {
+ /*
+ * right now this can only be a reset...
+ */
+ cdrom_end_request(1, drive);
+ return ide_do_reset(drive);
+ } else if (rq->flags & REQ_BLOCK_PC) {
+ return cdrom_do_block_pc(drive, rq);
}
+
+ blk_dump_rq_flags(rq, "ide-cd bad flags");
+ cdrom_end_request(0, drive);
+ return ide_stopped;
}
@@ -2202,9 +2144,13 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
pc.quiet = cgc->quiet;
pc.timeout = cgc->timeout;
pc.sense = cgc->sense;
- return cgc->stat = cdrom_queue_packet_command(drive, &pc);
+ cgc->stat = cdrom_queue_packet_command(drive, &pc);
+ if (!cgc->stat)
+ cgc->buflen -= pc.buflen;
+ return cgc->stat;
}
+
static
int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
unsigned int cmd, unsigned long arg)
@@ -2338,7 +2284,7 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
int ret;
ide_init_drive_cmd (&req);
- req.cmd = RESET_DRIVE_COMMAND;
+ req.flags = REQ_SPECIAL;
ret = ide_do_drive_cmd(drive, &req, ide_wait);
/*
@@ -2711,7 +2657,6 @@ static void ide_cdrom_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL);
ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL);
- ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
}
@@ -2728,6 +2673,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
*/
set_device_ro(MKDEV(HWIF(drive)->major, minor), 1);
set_blocksize(MKDEV(HWIF(drive)->major, minor), CD_FRAMESIZE);
+ blk_queue_hardsect_size(&drive->queue, CD_FRAMESIZE);
drive->special.all = 0;
drive->ready_stat = 0;
@@ -2875,7 +2821,7 @@ int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
MOD_INC_USE_COUNT;
if (info->buffer == NULL)
info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
- if ((info->buffer == NULL) || (rc = cdrom_open(ip, fp))) {
+ if ((info->buffer == NULL) || (rc = cdrom_open(ip, fp))) {
drive->usage--;
MOD_DEC_USE_COUNT;
}
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index aa46a912a..9a5de53a6 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -435,7 +435,7 @@ struct atapi_mechstat_header {
byte curlba[3];
byte nslots;
- __u8 short slot_tablelen;
+ __u16 slot_tablelen;
};
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 8af34e955..62a719ad8 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -42,6 +42,7 @@
#include <linux/ioport.h>
#include <linux/hdreg.h>
#include <linux/major.h>
+#include <linux/ide.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -226,6 +227,16 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
#define CFG_CHECK(fn, args...) \
if (CardServices(fn, args) != 0) goto next_entry
+int idecs_register (int io_base, int ctl_base, int irq)
+{
+ hw_regs_t hw;
+ ide_init_hwif_ports(&hw, (ide_ioreg_t) io_base, (ide_ioreg_t) ctl_base, NULL);
+ hw.irq = irq;
+ hw.chipset = ide_pci; // this enables IRQ sharing w/ PCI irqs
+ return ide_register_hw(&hw, NULL);
+}
+
+
void ide_config(dev_link_t *link)
{
client_handle_t handle = link->handle;
@@ -327,12 +338,16 @@ void ide_config(dev_link_t *link)
if (link->io.NumPorts2)
release_region(link->io.BasePort2, link->io.NumPorts2);
+ /* disable drive interrupts during IDE probe */
+ if(ctl_base)
+ outb(0x02, ctl_base);
+
/* retry registration in case device is still spinning up */
for (i = 0; i < 10; i++) {
- hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ);
+ hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
if (hd >= 0) break;
if (link->io.NumPorts1 == 0x20) {
- hd = ide_register(io_base+0x10, ctl_base+0x10,
+ hd = idecs_register(io_base+0x10, ctl_base+0x10,
link->irq.AssignedIRQ);
if (hd >= 0) {
io_base += 0x10; ctl_base += 0x10;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 784e5267c..9206953f2 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -27,6 +27,7 @@
* Version 1.09 added increment of rq->sector in ide_multwrite
* added UDMA 3/4 reporting
* Version 1.10 request queue changes, Ultra DMA 100
+ * Version 1.11 Highmem I/O support, Jens Axboe <axboe@suse.de>
*/
#define IDEDISK_VERSION "1.10"
@@ -139,7 +140,9 @@ static ide_startstop_t read_intr (ide_drive_t *drive)
byte stat;
int i;
unsigned int msect, nsect;
+ unsigned long flags;
struct request *rq;
+ char *to;
/* new way for dealing with premature shared PCI interrupts */
if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
@@ -150,8 +153,8 @@ static ide_startstop_t read_intr (ide_drive_t *drive)
ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
return ide_started;
}
+
msect = drive->mult_count;
-
read_next:
rq = HWGROUP(drive)->rq;
if (msect) {
@@ -160,14 +163,15 @@ read_next:
msect -= nsect;
} else
nsect = 1;
- idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
+ to = ide_map_buffer(rq, &flags);
+ idedisk_input_data(drive, to, nsect * SECTOR_WORDS);
#ifdef DEBUG
printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
drive->name, rq->sector, rq->sector+nsect-1,
(unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect);
#endif
+ ide_unmap_buffer(to, &flags);
rq->sector += nsect;
- rq->buffer += nsect<<9;
rq->errors = 0;
i = (rq->nr_sectors -= nsect);
if (((long)(rq->current_nr_sectors -= nsect)) <= 0)
@@ -201,14 +205,16 @@ static ide_startstop_t write_intr (ide_drive_t *drive)
#endif
if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) {
rq->sector++;
- rq->buffer += 512;
rq->errors = 0;
i = --rq->nr_sectors;
--rq->current_nr_sectors;
if (((long)rq->current_nr_sectors) <= 0)
ide_end_request(1, hwgroup);
if (i > 0) {
- idedisk_output_data (drive, rq->buffer, SECTOR_WORDS);
+ unsigned long flags;
+ char *to = ide_map_buffer(rq, &flags);
+ idedisk_output_data (drive, to, SECTOR_WORDS);
+ ide_unmap_buffer(to, &flags);
ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
return ide_started;
}
@@ -238,28 +244,28 @@ int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
do {
char *buffer;
int nsect = rq->current_nr_sectors;
-
+ unsigned long flags;
+
if (nsect > mcount)
nsect = mcount;
mcount -= nsect;
- buffer = rq->buffer;
+ buffer = ide_map_buffer(rq, &flags);
rq->sector += nsect;
- rq->buffer += nsect << 9;
rq->nr_sectors -= nsect;
rq->current_nr_sectors -= nsect;
/* Do we move to the next bh after this? */
if (!rq->current_nr_sectors) {
- struct buffer_head *bh = rq->bh->b_reqnext;
+ struct bio *bio = rq->bio->bi_next;
/* end early early we ran out of requests */
- if (!bh) {
+ if (!bio) {
mcount = 0;
} else {
- rq->bh = bh;
- rq->current_nr_sectors = bh->b_size >> 9;
- rq->buffer = bh->b_data;
+ rq->bio = bio;
+ rq->current_nr_sectors = bio_sectors(bio);
+ rq->hard_cur_sectors = rq->current_nr_sectors;
}
}
@@ -268,6 +274,7 @@ int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
* re-entering us on the last transfer.
*/
idedisk_output_data(drive, buffer, nsect<<7);
+ ide_unmap_buffer(buffer, &flags);
} while (mcount);
return 0;
@@ -279,7 +286,6 @@ int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
static ide_startstop_t multwrite_intr (ide_drive_t *drive)
{
byte stat;
- int i;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
struct request *rq = &hwgroup->wrq;
@@ -302,10 +308,8 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
*/
if (!rq->nr_sectors) { /* all done? */
rq = hwgroup->rq;
- for (i = rq->nr_sectors; i > 0;){
- i -= rq->current_nr_sectors;
- ide_end_request(1, hwgroup);
- }
+
+ __ide_end_request(hwgroup, 1, rq->nr_sectors);
return ide_stopped;
}
}
@@ -367,6 +371,8 @@ static ide_startstop_t recal_intr (ide_drive_t *drive)
*/
static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
{
+ unsigned long flags;
+
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
OUT_BYTE(0x00, IDE_FEATURE_REG);
@@ -378,7 +384,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
#endif /* CONFIG_BLK_DEV_PDC4030 */
#ifdef DEBUG
printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
- drive->name, (rq->cmd==READ)?"read":"writ",
+ drive->name, (rq_data_dir(rq)==READ)?"read":"writ",
block, rq->nr_sectors, (unsigned long) rq->buffer);
#endif
OUT_BYTE(block,IDE_SECTOR_REG);
@@ -397,7 +403,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
OUT_BYTE(head|drive->select.all,IDE_SELECT_REG);
#ifdef DEBUG
printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n",
- drive->name, (rq->cmd==READ)?"read":"writ", cyl,
+ drive->name, (rq_data_dir(rq)==READ)?"read":"writ", cyl,
head, sect, rq->nr_sectors, (unsigned long) rq->buffer);
#endif
}
@@ -407,7 +413,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
return do_pdc4030_io (drive, rq);
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
- if (rq->cmd == READ) {
+ if (rq_data_dir(rq) == READ) {
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
return ide_started;
@@ -416,7 +422,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
return ide_started;
}
- if (rq->cmd == WRITE) {
+ if (rq_data_dir(rq) == WRITE) {
ide_startstop_t startstop;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive)))
@@ -444,20 +450,21 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsig
hwgroup->wrq = *rq; /* scratchpad */
ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
if (ide_multwrite(drive, drive->mult_count)) {
- unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
hwgroup->handler = NULL;
del_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
}
} else {
+ char *buffer = ide_map_buffer(rq, &flags);
ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
- idedisk_output_data(drive, rq->buffer, SECTOR_WORDS);
+ idedisk_output_data(drive, buffer, SECTOR_WORDS);
+ ide_unmap_buffer(buffer, &flags);
}
return ide_started;
}
- printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd);
+ printk(KERN_ERR "%s: bad command: %lx\n", drive->name, rq->flags);
ide_end_request(0, HWGROUP(drive));
return ide_stopped;
}
@@ -482,7 +489,8 @@ static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t
{
if (drive->removable && !drive->usage) {
invalidate_bdev(inode->i_bdev, 0);
- if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
+ if (drive->doorlocking &&
+ ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
drive->doorlocking = 0;
}
MOD_DEC_USE_COUNT;
@@ -495,9 +503,7 @@ static int idedisk_media_change (ide_drive_t *drive)
static void idedisk_revalidate (ide_drive_t *drive)
{
- grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
- 1<<PARTN_BITS,
- current_capacity(drive));
+ ide_revalidate_drive(drive);
}
/*
@@ -673,7 +679,7 @@ static int set_nowerr(ide_drive_t *drive, int arg)
return -EBUSY;
drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&ide_lock);
return 0;
}
@@ -691,7 +697,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr);
ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL);
ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, 4096, PAGE_SIZE, 1024, &max_readahead[major][minor], NULL);
- ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL);
ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 3ad4c48e6..cc0d6b992 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -203,30 +203,10 @@ const char *bad_dma_drives[] = {"WDC AC11000H",
#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
/*
- * Our Physical Region Descriptor (PRD) table should be large enough
- * to handle the biggest I/O request we are likely to see. Since requests
- * can have no more than 256 sectors, and since the typical blocksize is
- * two or more sectors, we could get by with a limit of 128 entries here for
- * the usual worst case. Most requests seem to include some contiguous blocks,
- * further reducing the number of table entries required.
- *
- * The driver reverts to PIO mode for individual requests that exceed
- * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling
- * 100% of all crazy scenarios here is not necessary.
- *
- * As it turns out though, we must allocate a full 4KB page for this,
- * so the two PRD tables (ide0 & ide1) will each get half of that,
- * allowing each to have about 256 entries (8 bytes each) from this.
- */
-#define PRD_BYTES 8
-#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
-
-/*
* dma_intr() is the handler for disk read/write DMA interrupts
*/
ide_startstop_t ide_dma_intr (ide_drive_t *drive)
{
- int i;
byte stat, dma_stat;
dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
@@ -234,11 +214,8 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
struct request *rq = HWGROUP(drive)->rq;
- rq = HWGROUP(drive)->rq;
- for (i = rq->nr_sectors; i > 0;) {
- i -= rq->current_nr_sectors;
- ide_end_request(1, HWGROUP(drive));
- }
+
+ __ide_end_request(HWGROUP(drive), 1, rq->nr_sectors);
return ide_stopped;
}
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
@@ -249,35 +226,18 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq)
{
- struct buffer_head *bh;
struct scatterlist *sg = hwif->sg_table;
- int nents = 0;
+ int nents;
- if (hwif->sg_dma_active)
- BUG();
-
- if (rq->cmd == READ)
+ nents = blk_rq_map_sg(rq->q, rq, hwif->sg_table);
+
+ if (nents > rq->nr_segments)
+ printk("ide-dma: received %d segments, build %d\n", rq->nr_segments, nents);
+
+ if (rq_data_dir(rq) == READ)
hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
else
hwif->sg_dma_direction = PCI_DMA_TODEVICE;
- bh = rq->bh;
- do {
- unsigned char *virt_addr = bh->b_data;
- unsigned int size = bh->b_size;
-
- if (nents >= PRD_ENTRIES)
- return 0;
-
- while ((bh = bh->b_reqnext) != NULL) {
- if ((virt_addr + size) != (unsigned char *) bh->b_data)
- break;
- size += bh->b_size;
- }
- memset(&sg[nents], 0, sizeof(*sg));
- sg[nents].address = virt_addr;
- sg[nents].length = size;
- nents++;
- } while (bh != NULL);
return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
}
@@ -289,9 +249,10 @@ static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq)
*/
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
{
- unsigned int *table = HWIF(drive)->dmatable_cpu;
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned int *table = hwif->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
- unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290);
+ unsigned int is_trm290_chipset = (hwif->chipset == ide_trm290);
#else
const int is_trm290_chipset = 0;
#endif
@@ -299,13 +260,12 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
int i;
struct scatterlist *sg;
- HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
-
+ hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
if (!i)
return 0;
- sg = HWIF(drive)->sg_table;
- while (i && sg_dma_len(sg)) {
+ sg = hwif->sg_table;
+ while (i) {
u32 cur_addr;
u32 cur_len;
@@ -319,55 +279,53 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
*/
while (cur_len) {
+ u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
+
if (count++ >= PRD_ENTRIES) {
- printk("%s: DMA table too small\n", drive->name);
- goto use_pio_instead;
- } else {
- u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
-
- if (bcount > cur_len)
- bcount = cur_len;
- *table++ = cpu_to_le32(cur_addr);
- xcount = bcount & 0xffff;
- if (is_trm290_chipset)
- xcount = ((xcount >> 2) - 1) << 16;
- if (xcount == 0x0000) {
- /*
- * Most chipsets correctly interpret a length of 0x0000 as 64KB,
- * but at least one (e.g. CS5530) misinterprets it as zero (!).
- * So here we break the 64KB entry into two 32KB entries instead.
- */
- if (count++ >= PRD_ENTRIES) {
- printk("%s: DMA table too small\n", drive->name);
- goto use_pio_instead;
- }
- *table++ = cpu_to_le32(0x8000);
- *table++ = cpu_to_le32(cur_addr + 0x8000);
- xcount = 0x8000;
+ printk("ide-dma: req %p\n", HWGROUP(drive)->rq);
+ printk("count %d, sg_nents %d, cur_len %d, cur_addr %u\n", count, hwif->sg_nents, cur_len, cur_addr);
+ BUG();
+ }
+
+ if (bcount > cur_len)
+ bcount = cur_len;
+ *table++ = cpu_to_le32(cur_addr);
+ xcount = bcount & 0xffff;
+ if (is_trm290_chipset)
+ xcount = ((xcount >> 2) - 1) << 16;
+ if (xcount == 0x0000) {
+ /*
+ * Most chipsets correctly interpret a length of
+ * 0x0000 as 64KB, but at least one (e.g. CS5530)
+ * misinterprets it as zero (!). So here we break
+ * the 64KB entry into two 32KB entries instead.
+ */
+ if (count++ >= PRD_ENTRIES) {
+ pci_unmap_sg(hwif->pci_dev, sg,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
+ return 0;
}
- *table++ = cpu_to_le32(xcount);
- cur_addr += bcount;
- cur_len -= bcount;
+
+ *table++ = cpu_to_le32(0x8000);
+ *table++ = cpu_to_le32(cur_addr + 0x8000);
+ xcount = 0x8000;
}
+ *table++ = cpu_to_le32(xcount);
+ cur_addr += bcount;
+ cur_len -= bcount;
}
sg++;
i--;
}
- if (count) {
- if (!is_trm290_chipset)
- *--table |= cpu_to_le32(0x80000000);
- return count;
- }
- printk("%s: empty DMA table?\n", drive->name);
-use_pio_instead:
- pci_unmap_sg(HWIF(drive)->pci_dev,
- HWIF(drive)->sg_table,
- HWIF(drive)->sg_nents,
- HWIF(drive)->sg_dma_direction);
- HWIF(drive)->sg_dma_active = 0;
- return 0; /* revert to PIO for this request */
+ if (!count)
+ printk("%s: empty DMA table?\n", drive->name);
+ else if (!is_trm290_chipset)
+ *--table |= cpu_to_le32(0x80000000);
+
+ return count;
}
/* Teardown mappings after DMA has completed. */
@@ -378,7 +336,6 @@ void ide_destroy_dmatable (ide_drive_t *drive)
int nents = HWIF(drive)->sg_nents;
pci_unmap_sg(dev, sg, nents, HWIF(drive)->sg_dma_direction);
- HWIF(drive)->sg_dma_active = 0;
}
/*
@@ -532,6 +489,20 @@ static ide_startstop_t ide_dma_timeout_revovery (ide_drive_t *drive)
}
#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+static void ide_toggle_bounce(ide_drive_t *drive, int on)
+{
+ dma64_addr_t addr = BLK_BOUNCE_HIGH;
+
+ if (on && drive->media == ide_disk && HWIF(drive)->highmem) {
+ if (!PCI_DMA_BUS_IS_PHYS)
+ addr = BLK_BOUNCE_ANY;
+ else
+ addr = HWIF(drive)->pci_dev->dma_mask;
+ }
+
+ blk_queue_bounce_limit(&drive->queue, addr);
+}
+
/*
* ide_dmaproc() initiates/aborts DMA read/write operations on a drive.
*
@@ -550,19 +521,20 @@ static ide_startstop_t ide_dma_timeout_revovery (ide_drive_t *drive)
*/
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
-// ide_hwgroup_t *hwgroup = HWGROUP(drive);
- ide_hwif_t *hwif = HWIF(drive);
- unsigned long dma_base = hwif->dma_base;
- byte unit = (drive->select.b.unit & 0x01);
- unsigned int count, reading = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long dma_base = hwif->dma_base;
+ byte unit = (drive->select.b.unit & 0x01);
+ unsigned int count, reading = 0, set_high = 1;
byte dma_stat;
switch (func) {
case ide_dma_off:
printk("%s: DMA disabled\n", drive->name);
+ set_high = 0;
case ide_dma_off_quietly:
outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
case ide_dma_on:
+ ide_toggle_bounce(drive, set_high);
drive->using_dma = (func == ide_dma_on);
if (drive->using_dma)
outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 2897ca4f3..44634ba23 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -707,24 +707,24 @@ static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
{
struct request *rq = pc->rq;
- struct buffer_head *bh = rq->bh;
+ struct bio *bio = rq->bio;
int count;
while (bcount) {
- if (pc->b_count == bh->b_size) {
+ if (pc->b_count == bio->bi_size) {
rq->sector += rq->current_nr_sectors;
rq->nr_sectors -= rq->current_nr_sectors;
idefloppy_end_request (1, HWGROUP(drive));
- if ((bh = rq->bh) != NULL)
+ if ((bio = rq->bio) != NULL)
pc->b_count = 0;
}
- if (bh == NULL) {
- printk (KERN_ERR "%s: bh == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
+ if (bio == NULL) {
+ printk (KERN_ERR "%s: bio == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_discard_data (drive, bcount);
return;
}
- count = IDEFLOPPY_MIN (bh->b_size - pc->b_count, bcount);
- atapi_input_bytes (drive, bh->b_data + pc->b_count, count);
+ count = IDEFLOPPY_MIN (bio->bi_size - pc->b_count, bcount);
+ atapi_input_bytes (drive, bio_data(bio) + pc->b_count, count);
bcount -= count; pc->b_count += count;
}
}
@@ -732,7 +732,7 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
{
struct request *rq = pc->rq;
- struct buffer_head *bh = rq->bh;
+ struct bio *bio = rq->bio;
int count;
while (bcount) {
@@ -740,13 +740,13 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
rq->sector += rq->current_nr_sectors;
rq->nr_sectors -= rq->current_nr_sectors;
idefloppy_end_request (1, HWGROUP(drive));
- if ((bh = rq->bh) != NULL) {
- pc->b_data = bh->b_data;
- pc->b_count = bh->b_size;
+ if ((bio = rq->bio) != NULL) {
+ pc->b_data = bio_data(bio);
+ pc->b_count = bio->bi_size;
}
}
- if (bh == NULL) {
- printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
+ if (bio == NULL) {
+ printk (KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_write_zeros (drive, bcount);
return;
}
@@ -760,9 +760,9 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
{
struct request *rq = pc->rq;
- struct buffer_head *bh = rq->bh;
+ struct bio *bio = rq->bio;
- while ((bh = rq->bh) != NULL)
+ while ((bio = rq->bio) != NULL)
idefloppy_end_request (1, HWGROUP(drive));
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -1210,7 +1210,7 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
pc->callback = &idefloppy_rw_callback;
pc->rq = rq;
pc->b_data = rq->buffer;
- pc->b_count = rq->cmd == READ ? 0 : rq->bh->b_size;
+ pc->b_count = rq->cmd == READ ? 0 : rq->bio->bi_size;
if (rq->cmd == WRITE)
set_bit (PC_WRITING, &pc->flags);
pc->buffer = NULL;
@@ -1778,9 +1778,7 @@ static int idefloppy_media_change (ide_drive_t *drive)
*/
static void idefloppy_revalidate (ide_drive_t *drive)
{
- grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
- 1<<PARTN_BITS,
- current_capacity(drive));
+ ide_revalidate_drive(drive);
}
/*
@@ -1920,7 +1918,6 @@ static void idefloppy_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL);
ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL);
- ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
}
@@ -1930,8 +1927,7 @@ static void idefloppy_add_settings(ide_drive_t *drive)
static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
{
struct idefloppy_id_gcw gcw;
- int major = HWIF(drive)->major, i;
- int minor = drive->select.b.unit << PARTN_BITS;
+ int i;
*((unsigned short *) &gcw) = drive->id->config;
drive->driver_data = floppy;
@@ -1953,35 +1949,18 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
*/
if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0)
- {
- for (i = 0; i < 1 << PARTN_BITS; i++)
- max_sectors[major][minor + i] = 64;
- }
- /*
- * Guess what? The IOMEGA Clik! drive also needs the
- * above fix. It makes nasty clicking noises without
- * it, so please don't remove this.
- */
- if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
- {
- for (i = 0; i < 1 << PARTN_BITS; i++)
- max_sectors[major][minor + i] = 64;
- set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
- }
+ blk_queue_max_sectors(&drive->queue, 64);
/*
* Guess what? The IOMEGA Clik! drive also needs the
* above fix. It makes nasty clicking noises without
* it, so please don't remove this.
*/
- if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
- {
- for (i = 0; i < 1 << PARTN_BITS; i++)
- max_sectors[major][minor + i] = 64;
+ if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) {
+ blk_queue_max_sectors(&drive->queue, 64);
set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
}
-
(void) idefloppy_get_capacity (drive);
idefloppy_add_settings(drive);
for (i = 0; i < MAX_DRIVES; ++i) {
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index cb192f3b7..e75d36b28 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -30,14 +30,14 @@
#define DEVID_MPIIX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX})
#define DEVID_PIIX3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1})
#define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB})
-#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1})
+#define DEVID_ICH0 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1})
#define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1})
-#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})
+#define DEVID_ICH ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})
#define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1})
#define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX})
-#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9})
-#define DEVID_PIIX4U4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8})
-#define DEVID_PIIX4U5 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10})
+#define DEVID_ICH2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9})
+#define DEVID_ICH2M ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8})
+#define DEVID_ICH3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10})
#define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561})
#define DEVID_MR_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1})
#define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1})
@@ -79,6 +79,7 @@
#define DEVID_AMD7401 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401})
#define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409})
#define DEVID_AMD7411 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411})
+#define DEVID_AMD7441 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7441})
#define DEVID_PDCADMA ((ide_pci_devid_t){PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841})
#define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1})
#define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE})
@@ -379,14 +380,14 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_MPIIX, "MPIIX", NULL, NULL, INIT_PIIX, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX3, "PIIX3", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
- {DEVID_PIIX4E, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_ICH0, "ICH0", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
- {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_ICH, "ICH", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
- {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
- {DEVID_PIIX4U4, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
- {DEVID_PIIX4U5, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_ICH2, "ICH2", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_ICH2M, "ICH2-M", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_ICH3, "ICH3", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_MR_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 },
{DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 },
@@ -437,6 +438,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_AMD7401, "AMD7401", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_AMD7409, "AMD7409", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 },
{DEVID_AMD7411, "AMD7411", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 },
+ {DEVID_AMD7441, "AMD7441", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 },
{DEVID_PDCADMA, "PDCADMA", PCI_PDCADMA, ATA66_PDCADMA, INIT_PDCADMA, DMA_PDCADMA, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 },
{DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_OSB4, "ServerWorks OSB4", PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
@@ -840,7 +842,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
switch(class_rev) {
case 4:
- case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+ case 3: printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name);
ide_setup_pci_device(dev, d);
return;
default: break;
@@ -869,12 +871,12 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
break;
}
}
- printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+ printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name);
ide_setup_pci_device(dev, d);
if (!dev2)
return;
d2 = d;
- printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn);
+ printk("%s: IDE controller on PCI slot %s\n", d2->name, dev2->slot_name);
ide_setup_pci_device(dev2, d2);
}
@@ -904,10 +906,10 @@ void __init ide_scan_pcidev (struct pci_dev *dev)
hpt366_device_order_fixup(dev, d);
else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
- printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",
- d->name, dev->bus->number, dev->devfn, devid.vid, devid.did);
+ printk("%s: unknown IDE controller on PCI slot %s, VID=%04x, DID=%04x\n",
+ d->name, dev->slot_name, devid.vid, devid.did);
else
- printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+ printk("%s: IDE controller on PCI slot %s\n", d->name, dev->slot_name);
ide_setup_pci_device(dev, d);
}
}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index b1a13a3b7..82123b2e0 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -594,9 +594,22 @@ static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
static void ide_init_queue(ide_drive_t *drive)
{
request_queue_t *q = &drive->queue;
+ int max_sectors;
q->queuedata = HWGROUP(drive);
blk_init_queue(q, do_ide_request);
+ blk_queue_segment_boundary(q, 0xffff);
+
+ /* IDE can do up to 128K per request, pdc4030 needs smaller limit */
+#ifdef CONFIG_BLK_DEV_PDC4030
+ max_sectors = 127;
+#else
+ max_sectors = 255;
+#endif
+ blk_queue_max_sectors(q, max_sectors);
+
+ /* IDE DMA can do PRD_ENTRIES number of segments */
+ q->max_segments = PRD_ENTRIES;
}
/*
@@ -670,7 +683,7 @@ static int init_irq (ide_hwif_t *hwif)
hwgroup->rq = NULL;
hwgroup->handler = NULL;
hwgroup->drive = NULL;
- hwgroup->busy = 0;
+ hwgroup->flags = 0;
init_timer(&hwgroup->timer);
hwgroup->timer.function = &ide_timer_expiry;
hwgroup->timer.data = (unsigned long) hwgroup;
@@ -749,7 +762,7 @@ static void init_gendisk (ide_hwif_t *hwif)
{
struct gendisk *gd;
unsigned int unit, units, minors;
- int *bs, *max_sect, *max_ra;
+ int *bs, *max_ra;
extern devfs_handle_t ide_devfs_handle;
/* figure out maximum drive number on the interface */
@@ -762,24 +775,16 @@ static void init_gendisk (ide_hwif_t *hwif)
gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
bs = kmalloc (minors*sizeof(int), GFP_KERNEL);
- max_sect = kmalloc (minors*sizeof(int), GFP_KERNEL);
max_ra = kmalloc (minors*sizeof(int), GFP_KERNEL);
memset(gd->part, 0, minors * sizeof(struct hd_struct));
/* cdroms and msdos f/s are examples of non-1024 blocksizes */
blksize_size[hwif->major] = bs;
- max_sectors[hwif->major] = max_sect;
max_readahead[hwif->major] = max_ra;
for (unit = 0; unit < minors; ++unit) {
*bs++ = BLOCK_SIZE;
-#ifdef CONFIG_BLK_DEV_PDC4030
- *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 255);
-#else
- /* IDE can do up to 128K per request. */
- *max_sect++ = 255;
-#endif
- *max_ra++ = vm_max_readahead;
+ *max_ra++ = MAX_READAHEAD;
}
for (unit = 0; unit < units; ++unit)
@@ -870,13 +875,6 @@ static int hwif_init (ide_hwif_t *hwif)
read_ahead[hwif->major] = 8; /* (4kB) */
hwif->present = 1; /* success */
-#if (DEBUG_SPINLOCK > 0)
-{
- static int done = 0;
- if (!done++)
- printk("io_request_lock is %p\n", &io_request_lock); /* FIXME */
-}
-#endif
return hwif->present;
}
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 3d642f17b..4c905cf0f 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -190,7 +190,7 @@ static int proc_ide_write_config
if (hwif->mate && hwif->mate->hwgroup)
mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
cli(); /* all CPUs; ensure all writes are done together */
- while (mygroup->busy || (mategroup && mategroup->busy)) {
+ while (test_bit(IDE_BUSY, &mygroup->flags) || (mategroup && test_bit(IDE_BUSY, &mategroup->flags))) {
sti(); /* all CPUs */
if (0 < (signed long)(jiffies - timeout)) {
printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index a29fc5488..2faa1bab9 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1887,8 +1887,7 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
printk("ide-tape: %s: skipping over config parition..\n", tape->name);
#endif
tape->onstream_write_error = OS_PART_ERROR;
- if (tape->waiting)
- complete(tape->waiting);
+ complete(tape->waiting);
}
}
remove_stage = 1;
@@ -1904,8 +1903,7 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
tape->nr_pending_stages++;
tape->next_stage = tape->first_stage;
rq->current_nr_sectors = rq->nr_sectors;
- if (tape->waiting)
- complete(tape->waiting);
+ complete(tape->waiting);
}
}
} else if (rq->cmd == IDETAPE_READ_RQ) {
@@ -5488,7 +5486,6 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp)
idetape_pc_t pc;
unsigned int minor=MINOR (inode->i_rdev);
- lock_kernel();
tape = drive->driver_data;
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3)
@@ -5519,7 +5516,6 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp)
MOD_DEC_USE_COUNT;
}
clear_bit (IDETAPE_BUSY, &tape->flags);
- unlock_kernel();
return 0;
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 6568f5afe..a9ff55e85 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -113,6 +113,8 @@
* Version 6.31 Debug Share INTR's and request queue streaming
* Native ATA-100 support
* Prep for Cascades Project
+ * Version 6.32 4GB highmem support for DMA, and mapping of those for
+ * PIO transfer (Jens Axboe)
*
* Some additional driver compile-time options are in ./include/linux/ide.h
*
@@ -121,8 +123,8 @@
*
*/
-#define REVISION "Revision: 6.31"
-#define VERSION "Id: ide.c 6.31 2000/06/09"
+#define REVISION "Revision: 6.32"
+#define VERSION "Id: ide.c 6.32 2001/05/24"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -149,6 +151,7 @@
#include <linux/ide.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/completion.h>
+#include <linux/cdrom.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -171,6 +174,14 @@ static int idebus_parameter; /* holds the "idebus=" parameter */
static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */
+/*
+ * protects global structures etc, we want to split this into per-hwgroup
+ * instead.
+ *
+ * anti-deadlock ordering: ide_lock -> DRIVE_LOCK
+ */
+spinlock_t ide_lock = SPIN_LOCK_UNLOCKED;
+
#ifdef CONFIG_BLK_DEV_IDEPCI
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
#endif /* CONFIG_BLK_DEV_IDEPCI */
@@ -180,7 +191,7 @@ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
* ide_lock is used by the Atari code to obtain access to the IDE interrupt,
* which is shared between several drivers.
*/
-static int ide_lock;
+static int ide_intr_lock;
#endif /* __mc68000__ || CONFIG_APUS */
int noautodma = 0;
@@ -542,18 +553,25 @@ static inline int drive_is_ready (ide_drive_t *drive)
return 1; /* drive ready: *might* be interrupting */
}
-/*
- * This is our end_request replacement function.
- */
-void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+inline int __ide_end_request(ide_hwgroup_t *hwgroup, int uptodate, int nr_secs)
{
+ ide_drive_t *drive = hwgroup->drive;
struct request *rq;
unsigned long flags;
- ide_drive_t *drive = hwgroup->drive;
+ int ret = 1;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
rq = hwgroup->rq;
+ BUG_ON(!(rq->flags & REQ_STARTED));
+
+ /*
+ * small hack to eliminate locking from ide_end_request to grab
+ * the first segment number of sectors
+ */
+ if (!nr_secs)
+ nr_secs = rq->hard_cur_sectors;
+
/*
* decide whether to reenable DMA -- 3 is a random magic for now,
* if we DMA timeout more than 3 times, just stay in PIO
@@ -563,13 +581,26 @@ void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
hwgroup->hwif->dmaproc(ide_dma_on, drive);
}
- if (!end_that_request_first(rq, uptodate, hwgroup->drive->name)) {
+ if (!end_that_request_first(rq, uptodate, nr_secs)) {
add_blkdev_randomness(MAJOR(rq->rq_dev));
+ spin_lock(DRIVE_LOCK(drive));
blkdev_dequeue_request(rq);
hwgroup->rq = NULL;
end_that_request_last(rq);
+ spin_unlock(DRIVE_LOCK(drive));
+ ret = 0;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return ret;
+}
+
+/*
+ * This is our end_request replacement function.
+ */
+int ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+{
+ return __ide_end_request(hwgroup, uptodate, 0);
}
/*
@@ -585,7 +616,7 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
if (hwgroup->handler != NULL) {
printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n",
drive->name, hwgroup->handler, handler);
@@ -594,7 +625,7 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
add_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
}
/*
@@ -844,11 +875,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err)
unsigned long flags;
struct request *rq;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
rq = HWGROUP(drive)->rq;
- spin_unlock_irqrestore(&io_request_lock, flags);
- if (rq->cmd == IDE_DRIVE_CMD) {
+ if (rq->flags & REQ_DRIVE_CMD) {
byte *args = (byte *) rq->buffer;
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
if (args) {
@@ -856,7 +886,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err)
args[1] = err;
args[2] = IN_BYTE(IDE_NSECTOR_REG);
}
- } else if (rq->cmd == IDE_DRIVE_TASK) {
+ } else if (rq->flags & REQ_DRIVE_TASK) {
byte *args = (byte *) rq->buffer;
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
if (args) {
@@ -869,11 +899,14 @@ void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err)
args[6] = IN_BYTE(IDE_SELECT_REG);
}
}
- spin_lock_irqsave(&io_request_lock, flags);
+
+ spin_lock(DRIVE_LOCK(drive));
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
end_that_request_last(rq);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock(DRIVE_LOCK(drive));
+
+ spin_unlock_irqrestore(&ide_lock, flags);
}
/*
@@ -975,7 +1008,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) {
+ if (!(rq->flags & REQ_CMD)) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
@@ -995,7 +1028,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL;
}
- if ((stat & DRQ_STAT) && rq->cmd != WRITE)
+ if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
try_to_flush_leftover_data(drive);
}
if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
@@ -1142,7 +1175,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
{
byte *args = rq->buffer;
- if (args && rq->cmd == IDE_DRIVE_TASK) {
+ if (args && (rq->flags & REQ_DRIVE_TASK)) {
byte sel;
#ifdef DEBUG
printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n",
@@ -1192,17 +1225,19 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq
/*
* start_request() initiates handling of a new I/O request
*/
-static ide_startstop_t start_request (ide_drive_t *drive)
+static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
ide_startstop_t startstop;
- unsigned long block, blockend;
- struct request *rq = blkdev_entry_next_request(&drive->queue.queue_head);
+ unsigned long block;
unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS;
ide_hwif_t *hwif = HWIF(drive);
+ BUG_ON(!(rq->flags & REQ_STARTED));
+
#ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
#endif
+
/* bail early if we've exceeded max_failures */
if (drive->max_failures && (drive->failures > drive->max_failures)) {
goto kill_rq;
@@ -1219,16 +1254,11 @@ static ide_startstop_t start_request (ide_drive_t *drive)
}
#endif
block = rq->sector;
- blockend = block + rq->nr_sectors;
- if ((rq->cmd == READ || rq->cmd == WRITE) &&
+ /* Strange disk manager remap */
+ if ((rq->flags & REQ_CMD) &&
(drive->media == ide_disk || drive->media == ide_floppy)) {
- if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) {
- printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name,
- (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors);
- goto kill_rq;
- }
- block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
+ block += drive->sect0;
}
/* Yecch - this will shift the entire interval,
possibly killing some innocent following sector */
@@ -1240,18 +1270,20 @@ static ide_startstop_t start_request (ide_drive_t *drive)
#endif
SELECT_DRIVE(hwif, drive);
- if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
+ if (ide_wait_stat(&startstop, drive, drive->ready_stat,
+ BUSY_STAT|DRQ_STAT, WAIT_READY)) {
printk("%s: drive not ready for command\n", drive->name);
return startstop;
}
if (!drive->special.all) {
- if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
return execute_drive_cmd(drive, rq);
- }
+
if (drive->driver != NULL) {
return (DRIVER(drive)->do_request(drive, rq, block));
}
- printk("%s: media type %d not supported\n", drive->name, drive->media);
+ printk("%s: media type %d not supported\n",
+ drive->name, drive->media);
goto kill_rq;
}
return do_special(drive);
@@ -1267,13 +1299,15 @@ ide_startstop_t restart_request (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long flags;
+ struct request *rq;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
hwgroup->handler = NULL;
del_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ rq = hwgroup->rq;
+ spin_unlock_irqrestore(&ide_lock, flags);
- return start_request(drive);
+ return start_request(drive, rq);
}
/*
@@ -1305,7 +1339,7 @@ repeat:
|| (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
|| (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
{
- if( !drive->queue.plugged )
+ if (!blk_queue_plugged(&drive->queue))
best = drive;
}
}
@@ -1334,7 +1368,7 @@ repeat:
/*
* Issue a new request to a drive from hwgroup
- * Caller must have already done spin_lock_irqsave(&io_request_lock, ..);
+ * Caller must have already done spin_lock_irqsave(DRIVE_LOCK(drive), ...)
*
* A hwgroup is a serialized group of IDE interfaces. Usually there is
* exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
@@ -1346,39 +1380,34 @@ repeat:
* possibly along with many other devices. This is especially common in
* PCI-based systems with off-board IDE controller cards.
*
- * The IDE driver uses the single global io_request_lock spinlock to protect
- * access to the request queues, and to protect the hwgroup->busy flag.
+ * The IDE driver uses the queue spinlock to protect access to the request
+ * queues.
*
* The first thread into the driver for a particular hwgroup sets the
- * hwgroup->busy flag to indicate that this hwgroup is now active,
+ * hwgroup->flags IDE_BUSY flag to indicate that this hwgroup is now active,
* and then initiates processing of the top request from the request queue.
*
* Other threads attempting entry notice the busy setting, and will simply
- * queue their new requests and exit immediately. Note that hwgroup->busy
- * remains set even when the driver is merely awaiting the next interrupt.
+ * queue their new requests and exit immediately. Note that hwgroup->flags
+ * remains busy even when the driver is merely awaiting the next interrupt.
* Thus, the meaning is "this hwgroup is busy processing a request".
*
* When processing of a request completes, the completing thread or IRQ-handler
* will start the next request from the queue. If no more work remains,
- * the driver will clear the hwgroup->busy flag and exit.
- *
- * The io_request_lock (spinlock) is used to protect all access to the
- * hwgroup->busy flag, but is otherwise not needed for most processing in
- * the driver. This makes the driver much more friendlier to shared IRQs
- * than previous designs, while remaining 100% (?) SMP safe and capable.
+ * the driver will clear the hwgroup->flags IDE_BUSY flag and exit.
*/
static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
{
ide_drive_t *drive;
ide_hwif_t *hwif;
ide_startstop_t startstop;
+ struct request *rq;
- ide_get_lock(&ide_lock, ide_intr, hwgroup); /* for atari only: POSSIBLY BROKEN HERE(?) */
+ ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
__cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */
- while (!hwgroup->busy) {
- hwgroup->busy = 1;
+ while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
drive = choose_drive(hwgroup);
if (drive == NULL) {
unsigned long sleep = 0;
@@ -1401,13 +1430,13 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
if (timer_pending(&hwgroup->timer))
printk("ide_set_handler: timer already active\n");
#endif
- hwgroup->sleeping = 1; /* so that ide_timer_expiry knows what to do */
+ set_bit(IDE_SLEEP, &hwgroup->flags);
mod_timer(&hwgroup->timer, sleep);
- /* we purposely leave hwgroup->busy==1 while sleeping */
+ /* we purposely leave hwgroup busy while sleeping */
} else {
/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_disk? */
- ide_release_lock(&ide_lock); /* for atari only */
- hwgroup->busy = 0;
+ ide_release_lock(&ide_intr_lock);/* for atari only */
+ clear_bit(IDE_BUSY, &hwgroup->flags);
}
return; /* no more work for this hwgroup (for now) */
}
@@ -1421,9 +1450,16 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
drive->sleep = 0;
drive->service_start = jiffies;
- if ( drive->queue.plugged ) /* paranoia */
- printk("%s: Huh? nuking plugged queue\n", drive->name);
- hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head);
+ if (blk_queue_plugged(&drive->queue))
+ BUG();
+
+ /*
+ * just continuing an interrupted request maybe
+ */
+ spin_lock(DRIVE_LOCK(drive));
+ rq = hwgroup->rq = elv_next_request(&drive->queue);
+ spin_unlock(DRIVE_LOCK(drive));
+
/*
* Some systems have trouble with IDE IRQs arriving while
* the driver is still setting things up. So, here we disable
@@ -1434,14 +1470,14 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
*/
if (masked_irq && hwif->irq != masked_irq)
disable_irq_nosync(hwif->irq);
- spin_unlock(&io_request_lock);
+ spin_unlock(&ide_lock);
ide__sti(); /* allow other IRQs while we start this request */
- startstop = start_request(drive);
- spin_lock_irq(&io_request_lock);
+ startstop = start_request(drive, rq);
+ spin_lock_irq(&ide_lock);
if (masked_irq && hwif->irq != masked_irq)
enable_irq(hwif->irq);
if (startstop == ide_stopped)
- hwgroup->busy = 0;
+ clear_bit(IDE_BUSY, &hwgroup->flags);
}
}
@@ -1460,7 +1496,19 @@ request_queue_t *ide_get_queue (kdev_t dev)
*/
void do_ide_request(request_queue_t *q)
{
+ unsigned long flags;
+
+ /*
+ * release queue lock, grab IDE global lock and restore when
+ * we leave...
+ */
+ spin_unlock(&q->queue_lock);
+
+ spin_lock_irqsave(&ide_lock, flags);
ide_do_request(q->queuedata, 0);
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ spin_lock(&q->queue_lock);
}
/*
@@ -1501,9 +1549,14 @@ void ide_dma_timeout_retry(ide_drive_t *drive)
HWGROUP(drive)->rq = NULL;
rq->errors = 0;
- rq->sector = rq->bh->b_rsector;
- rq->current_nr_sectors = rq->bh->b_size >> 9;
- rq->buffer = rq->bh->b_data;
+ rq->sector = rq->bio->bi_sector;
+ rq->current_nr_sectors = bio_sectors(rq->bio);
+
+ /*
+ * just to make sure...
+ */
+ if (rq->bio)
+ rq->buffer = NULL;
}
/*
@@ -1519,7 +1572,11 @@ void ide_timer_expiry (unsigned long data)
unsigned long flags;
unsigned long wait;
- spin_lock_irqsave(&io_request_lock, flags);
+ /*
+ * a global lock protects timers etc -- shouldn't get contention
+ * worth mentioning
+ */
+ spin_lock_irqsave(&ide_lock, flags);
del_timer(&hwgroup->timer);
if ((handler = hwgroup->handler) == NULL) {
@@ -1529,10 +1586,8 @@ void ide_timer_expiry (unsigned long data)
* or we were "sleeping" to give other devices a chance.
* Either way, we don't really want to complain about anything.
*/
- if (hwgroup->sleeping) {
- hwgroup->sleeping = 0;
- hwgroup->busy = 0;
- }
+ if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags))
+ clear_bit(IDE_BUSY, &hwgroup->flags);
} else {
ide_drive_t *drive = hwgroup->drive;
if (!drive) {
@@ -1541,17 +1596,16 @@ void ide_timer_expiry (unsigned long data)
} else {
ide_hwif_t *hwif;
ide_startstop_t startstop;
- if (!hwgroup->busy) {
- hwgroup->busy = 1; /* paranoia */
- printk("%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name);
- }
+ /* paranoia */
+ if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags))
+ printk("%s: ide_timer_expiry: hwgroup was not busy??\n", drive->name);
if ((expiry = hwgroup->expiry) != NULL) {
/* continue */
if ((wait = expiry(drive)) != 0) {
/* reset timer */
hwgroup->timer.expires = jiffies + wait;
add_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
return;
}
}
@@ -1561,7 +1615,7 @@ void ide_timer_expiry (unsigned long data)
* the handler() function, which means we need to globally
* mask the specific IRQ:
*/
- spin_unlock(&io_request_lock);
+ spin_unlock(&ide_lock);
hwif = HWIF(drive);
#if DISABLE_IRQ_NOSYNC
disable_irq_nosync(hwif->irq);
@@ -1587,13 +1641,13 @@ void ide_timer_expiry (unsigned long data)
set_recovery_timer(hwif);
drive->service_time = jiffies - drive->service_start;
enable_irq(hwif->irq);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&ide_lock);
if (startstop == ide_stopped)
- hwgroup->busy = 0;
+ clear_bit(IDE_BUSY, &hwgroup->flags);
}
}
ide_do_request(hwgroup, 0);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
}
/*
@@ -1656,13 +1710,11 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
ide_handler_t *handler;
ide_startstop_t startstop;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
hwif = hwgroup->hwif;
- if (!ide_ack_intr(hwif)) {
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
+ if (!ide_ack_intr(hwif))
+ goto out_lock;
if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) {
/*
@@ -1694,16 +1746,14 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
(void) IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
#endif /* CONFIG_BLK_DEV_IDEPCI */
}
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
+ goto out_lock;
}
drive = hwgroup->drive;
if (!drive) {
/*
* This should NEVER happen, and there isn't much we could do about it here.
*/
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
+ goto out_lock;
}
if (!drive_is_ready(drive)) {
/*
@@ -1712,21 +1762,19 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
* the IRQ before their status register is up to date. Hopefully we have
* enough advance overhead that the latter isn't a problem.
*/
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
- if (!hwgroup->busy) {
- hwgroup->busy = 1; /* paranoia */
- printk("%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
+ goto out_lock;
}
+ /* paranoia */
+ if (!test_and_set_bit(IDE_BUSY, &hwgroup->flags))
+ printk("%s: ide_intr: hwgroup was not busy??\n", drive->name);
hwgroup->handler = NULL;
del_timer(&hwgroup->timer);
- spin_unlock(&io_request_lock);
+ spin_unlock(&ide_lock);
if (drive->unmask)
ide__sti(); /* local CPU only */
startstop = handler(drive); /* service this interrupt, may set handler for next interrupt */
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&ide_lock);
/*
* Note that handler() may have set things up for another
@@ -1739,13 +1787,15 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
drive->service_time = jiffies - drive->service_start;
if (startstop == ide_stopped) {
if (hwgroup->handler == NULL) { /* paranoia */
- hwgroup->busy = 0;
+ clear_bit(IDE_BUSY, &hwgroup->flags);
ide_do_request(hwgroup, hwif->irq);
} else {
printk("%s: ide_intr: huh? expected NULL handler on exit\n", drive->name);
}
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+
+out_lock:
+ spin_unlock_irqrestore(&ide_lock, flags);
}
/*
@@ -1755,9 +1805,6 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
ide_drive_t *get_info_ptr (kdev_t i_rdev)
{
int major = MAJOR(i_rdev);
-#if 0
- int minor = MINOR(i_rdev) & PARTN_MASK;
-#endif
unsigned int h;
for (h = 0; h < MAX_HWIFS; ++h) {
@@ -1766,11 +1813,7 @@ ide_drive_t *get_info_ptr (kdev_t i_rdev)
unsigned unit = DEVICE_NR(i_rdev);
if (unit < MAX_DRIVES) {
ide_drive_t *drive = &hwif->drives[unit];
-#if 0
- if ((drive->present) && (drive->part[minor].nr_sects))
-#else
if (drive->present)
-#endif
return drive;
}
break;
@@ -1785,7 +1828,7 @@ ide_drive_t *get_info_ptr (kdev_t i_rdev)
void ide_init_drive_cmd (struct request *rq)
{
memset(rq, 0, sizeof(*rq));
- rq->cmd = IDE_DRIVE_CMD;
+ rq->flags = REQ_DRIVE_CMD;
}
/*
@@ -1818,7 +1861,8 @@ 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);
unsigned int major = HWIF(drive)->major;
- struct list_head *queue_head = &drive->queue.queue_head;
+ request_queue_t *q = &drive->queue;
+ struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
@@ -1830,8 +1874,9 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
rq->rq_dev = MKDEV(major,(drive->select.b.unit)<<PARTN_BITS);
if (action == ide_wait)
rq->waiting = &wait;
- spin_lock_irqsave(&io_request_lock, flags);
- if (list_empty(queue_head) || action == ide_preempt) {
+ spin_lock_irqsave(&ide_lock, flags);
+ spin_lock(DRIVE_LOCK(drive));
+ if (blk_queue_empty(&drive->queue) || action == ide_preempt) {
if (action == ide_preempt)
hwgroup->rq = NULL;
} else {
@@ -1840,9 +1885,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
} else
queue_head = queue_head->next;
}
- list_add(&rq->queue, queue_head);
+ q->elevator.elevator_add_req_fn(q, rq, queue_head);
+ spin_unlock(DRIVE_LOCK(drive));
ide_do_request(hwgroup, 0);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
if (action == ide_wait) {
wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */
@@ -1851,6 +1897,16 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
}
+/* Common for ide-floppy.c and ide-disk.c */
+void ide_revalidate_drive (ide_drive_t *drive)
+{
+ struct gendisk *g = HWIF(drive)->gd;
+ int minor = (drive->select.b.unit << g->minor_shift);
+ kdev_t dev = MKDEV(g->major, minor);
+
+ grok_partitions(dev, current_capacity(drive));
+}
+
/*
* This routine is called to flush all partitions and partition tables
* for a changed disk, and then re-read the new partition table.
@@ -1863,40 +1919,33 @@ int ide_revalidate_disk (kdev_t i_rdev)
{
ide_drive_t *drive;
ide_hwgroup_t *hwgroup;
- unsigned int p, major, minor;
- long flags;
+ unsigned long flags;
+ int res;
if ((drive = get_info_ptr(i_rdev)) == NULL)
return -ENODEV;
- major = MAJOR(i_rdev);
- minor = drive->select.b.unit << PARTN_BITS;
hwgroup = HWGROUP(drive);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
if (drive->busy || (drive->usage > 1)) {
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
return -EBUSY;
- };
+ }
drive->busy = 1;
MOD_INC_USE_COUNT;
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
- for (p = 0; p < (1<<PARTN_BITS); ++p) {
- if (drive->part[p].nr_sects > 0) {
- kdev_t devp = MKDEV(major, minor+p);
- invalidate_device(devp, 1);
- set_blocksize(devp, 1024);
- }
- drive->part[p].start_sect = 0;
- drive->part[p].nr_sects = 0;
- };
+ res = wipe_partitions(i_rdev);
+ if (res)
+ goto leave;
if (DRIVER(drive)->revalidate)
DRIVER(drive)->revalidate(drive);
+ leave:
drive->busy = 0;
wake_up(&drive->wqueue);
MOD_DEC_USE_COUNT;
- return 0;
+ return res;
}
static void revalidate_drives (void)
@@ -2169,11 +2218,10 @@ void ide_unregister (unsigned int index)
*/
unregister_blkdev(hwif->major, hwif->name);
kfree(blksize_size[hwif->major]);
- kfree(max_sectors[hwif->major]);
kfree(max_readahead[hwif->major]);
blk_dev[hwif->major].data = NULL;
blk_dev[hwif->major].queue = NULL;
- blksize_size[hwif->major] = NULL;
+ blk_clear(hwif->major);
gd = hwif->gd;
if (gd) {
del_gendisk(gd);
@@ -2293,6 +2341,7 @@ found:
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
hwif->irq = hw->irq;
hwif->noprobe = 0;
+ hwif->chipset = hw->chipset;
if (!initializing) {
ide_probe_module();
@@ -2403,7 +2452,7 @@ int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
unsigned long flags;
if ((setting->rw & SETTING_READ)) {
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&ide_lock, flags);
switch(setting->data_type) {
case TYPE_BYTE:
val = *((u8 *) setting->data);
@@ -2416,7 +2465,7 @@ int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
val = *((u32 *) setting->data);
break;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&ide_lock, flags);
}
return val;
}
@@ -2426,11 +2475,11 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long timeout = jiffies + (3 * HZ);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&ide_lock);
- while (hwgroup->busy) {
+ while (test_bit(IDE_BUSY, &hwgroup->flags)) {
unsigned long lflags;
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&ide_lock);
__save_flags(lflags); /* local CPU only */
__sti(); /* local CPU only; needed for jiffies */
if (0 < (signed long)(jiffies - timeout)) {
@@ -2439,7 +2488,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
return -EBUSY;
}
__restore_flags(lflags); /* local CPU only */
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&ide_lock);
}
return 0;
}
@@ -2480,7 +2529,7 @@ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
*p = val;
break;
}
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&ide_lock);
return 0;
}
@@ -2560,7 +2609,7 @@ int ide_wait_cmd_task (ide_drive_t *drive, byte *buf)
struct request rq;
ide_init_drive_cmd(&rq);
- rq.cmd = IDE_DRIVE_TASK;
+ rq.flags = REQ_DRIVE_TASK;
rq.buffer = buf;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
@@ -2633,6 +2682,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
{
struct hd_big_geometry *loc = (struct hd_big_geometry *) arg;
if (!loc || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;
+
if (put_user(drive->bios_head, (byte *) &loc->heads)) return -EFAULT;
if (put_user(drive->bios_sect, (byte *) &loc->sectors)) return -EFAULT;
if (put_user(drive->bios_cyl, (unsigned int *) &loc->cylinders)) return -EFAULT;
@@ -2653,11 +2703,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
return 0;
}
- case BLKGETSIZE: /* Return device size */
- return put_user(drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects, (unsigned long *) arg);
- case BLKGETSIZE64:
- return put_user((u64)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects << 9, (u64 *) arg);
-
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
return ide_revalidate_disk(inode->i_rdev);
@@ -2775,6 +2820,8 @@ static int ide_ioctl (struct inode *inode, struct file *file,
}
return 0;
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKROSET:
case BLKROGET:
case BLKFLSBUF:
@@ -2786,6 +2833,13 @@ static int ide_ioctl (struct inode *inode, struct file *file,
case BLKBSZSET:
return blk_ioctl(inode->i_rdev, cmd, arg);
+ /*
+ * uniform packet command handling
+ */
+ case CDROMEJECT:
+ case CDROMCLOSETRAY:
+ return block_ioctl(inode->i_rdev, cmd, arg);
+
case HDIO_GET_BUSSTATE:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -3409,7 +3463,7 @@ void __init ide_init_builtin_drivers (void)
#ifdef CONFIG_BLK_DEV_IDE
#if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
- ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */
+ ide_get_lock(&ide_intr_lock, NULL, NULL);/* for atari only */
disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */
// disable_irq_nosync(ide_hwifs[0].irq);
}
@@ -3420,7 +3474,7 @@ void __init ide_init_builtin_drivers (void)
#if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
enable_irq(ide_hwifs[0].irq);
- ide_release_lock(&ide_lock); /* for atari only */
+ ide_release_lock(&ide_intr_lock);/* for atari only */
}
#endif /* __mc68000__ || CONFIG_APUS */
#endif /* CONFIG_BLK_DEV_IDE */
@@ -3685,6 +3739,7 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ide_end_drive_cmd);
EXPORT_SYMBOL(ide_end_request);
+EXPORT_SYMBOL(__ide_end_request);
EXPORT_SYMBOL(ide_revalidate_disk);
EXPORT_SYMBOL(ide_cmd);
EXPORT_SYMBOL(ide_wait_cmd);
diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c
index 5c17b6c6e..eedad0daa 100644
--- a/drivers/ide/pdc202xx.c
+++ b/drivers/ide/pdc202xx.c
@@ -893,6 +893,7 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->dmaproc = &pdc202xx_dmaproc;
+ hwif->highmem = 1;
if (!noautodma)
hwif->autodma = 1;
} else {
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index ca6629e9e..0f64f4ed1 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -88,33 +88,9 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
u8 c0 = 0, c1 = 0;
u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0;
- switch(bmide_dev->device) {
- case PCI_DEVICE_ID_INTEL_82801BA_8:
- case PCI_DEVICE_ID_INTEL_82801BA_9:
- case PCI_DEVICE_ID_INTEL_82801CA_10:
- p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n");
- break;
- case PCI_DEVICE_ID_INTEL_82372FB_1:
- case PCI_DEVICE_ID_INTEL_82801AA_1:
- p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n");
- break;
- case PCI_DEVICE_ID_INTEL_82451NX:
- case PCI_DEVICE_ID_INTEL_82801AB_1:
- case PCI_DEVICE_ID_INTEL_82443MX_1:
- case PCI_DEVICE_ID_INTEL_82371AB:
- p += sprintf(p, "\n Intel PIIX4 Ultra 33 Chipset.\n");
- break;
- case PCI_DEVICE_ID_INTEL_82371SB_1:
- p += sprintf(p, "\n Intel PIIX3 Chipset.\n");
- break;
- case PCI_DEVICE_ID_INTEL_82371MX:
- p += sprintf(p, "\n Intel MPIIX Chipset.\n");
- return p-buffer; /* => must be less than 4k! */
- case PCI_DEVICE_ID_INTEL_82371FB_1:
- case PCI_DEVICE_ID_INTEL_82371FB_0:
- default:
- p += sprintf(p, "\n Intel PIIX Chipset.\n");
- break;
+ if (bmide_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
+ p += sprintf(p, "\n Intel MPIIX Chipset.\n");
+ return p-buffer; /* => must be less than 4k! */
}
pci_read_config_word(bmide_dev, 0x40, &reg40);
@@ -136,6 +112,7 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
c0 = inb_p((unsigned short)bibma + 0x02);
c1 = inb_p((unsigned short)bibma + 0x0a);
+ p += sprintf(p, "\n %s Chipset.\n", bmide_dev->name);
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
p += sprintf(p, " %sabled %sabled\n",
(c0&0x80) ? "dis" : " en",
@@ -523,6 +500,7 @@ void __init ide_init_piix (ide_hwif_t *hwif)
if (!hwif->dma_base)
return;
+ hwif->highmem = 1;
#ifndef CONFIG_BLK_DEV_IDEDMA
hwif->autodma = 0;
#else /* CONFIG_BLK_DEV_IDEDMA */
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index a09ba7545..60bccdab6 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -593,6 +593,7 @@ void __init ide_init_svwks (ide_hwif_t *hwif)
if (!noautodma)
hwif->autodma = 1;
hwif->dmaproc = &svwks_dmaproc;
+ hwif->highmem = 1;
} else {
hwif->autodma = 0;
hwif->drives[0].autotune = 1;
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index d8ed8be3f..53c53a54a 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -671,6 +671,7 @@ void __init ide_init_sis5513 (ide_hwif_t *hwif)
case PCI_DEVICE_ID_SI_5591:
if (!noautodma)
hwif->autodma = 1;
+ hwif->highmem = 1;
hwif->dmaproc = &sis5513_dmaproc;
break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index d811e228e..df824d20d 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -373,6 +373,7 @@ void __init ide_init_slc90e66 (ide_hwif_t *hwif)
return;
hwif->autodma = 0;
+ hwif->highmem = 1;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (!noautodma)
hwif->autodma = 1;
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 7c79f5bdd..f956272be 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -520,6 +520,7 @@ void __init ide_init_via82cxxx(ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
+ hwif->highmem = 1;
hwif->dmaproc = &via82cxxx_dmaproc;
#ifdef CONFIG_IDEDMA_AUTO
if (!noautodma)
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 903ddbcb7..670e3ea6e 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -949,7 +949,6 @@ static int raw1394_release(struct inode *inode, struct file *file)
struct pending_request *req;
int done = 0, i;
- lock_kernel();
for (i = 0; i < 64; i++) {
if (fi->listen_channels & (1ULL << i)) {
hpsb_unlisten_channel(hl_handle, fi->host, i);
@@ -990,7 +989,6 @@ static int raw1394_release(struct inode *inode, struct file *file)
kfree(fi);
V22_COMPAT_MOD_DEC_USE_COUNT;
- unlock_kernel();
return 0;
}
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ec72e8895..531b07edd 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -94,7 +94,6 @@ static int evdev_release(struct inode * inode, struct file * file)
struct evdev_list *list = file->private_data;
struct evdev_list **listptr;
- lock_kernel();
listptr = &list->evdev->list;
evdev_fasync(-1, file, 0);
@@ -113,7 +112,6 @@ static int evdev_release(struct inode * inode, struct file * file)
}
kfree(list);
- unlock_kernel();
return 0;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index b6e8f5756..8c1775d60 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -387,9 +387,7 @@ static int input_open_file(struct inode *inode, struct file *file)
old_fops = file->f_op;
file->f_op = new_fops;
- lock_kernel();
err = new_fops->open(inode, file);
- unlock_kernel();
if (err) {
fops_put(file->f_op);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 260f5d206..bf90692eb 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -164,8 +164,7 @@ static int joydev_release(struct inode * inode, struct file * file)
{
struct joydev_list *list = file->private_data;
struct joydev_list **listptr;
-
- lock_kernel();
+
listptr = &list->joydev->list;
joydev_fasync(-1, file, 0);
@@ -184,7 +183,6 @@ static int joydev_release(struct inode * inode, struct file * file)
}
kfree(list);
- unlock_kernel();
return 0;
}
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 9b8ad2391..f9993eded 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -169,8 +169,7 @@ static int mousedev_release(struct inode * inode, struct file * file)
{
struct mousedev_list *list = file->private_data;
struct mousedev_list **listptr;
-
- lock_kernel();
+
listptr = &list->mousedev->list;
mousedev_fasync(-1, file, 0);
@@ -208,7 +207,6 @@ static int mousedev_release(struct inode * inode, struct file * file)
}
kfree(list);
- unlock_kernel();
return 0;
}
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 0aa033579..06670d180 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -168,7 +168,7 @@ static void usb_b_out_complete(struct urb *urb)
test_and_clear_bit(buf_nr, &b_out->busy);
if (urb->status < 0) {
- if (urb->status != USB_ST_URB_KILLED) {
+ if (urb->status != -ENOENT) {
WARN("urb status %d",urb->status);
if (b_out->busy == 0) {
st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 1079bae6e..b0b3d0662 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -382,7 +382,7 @@ static void usb_d_out_complete(struct urb *urb)
test_and_clear_bit(buf_nr, &d_out->busy);
if (urb->status < 0) {
- if (urb->status != USB_ST_URB_KILLED) {
+ if (urb->status != -ENOENT) {
WARN("urb status %d",urb->status);
if (d_out->busy == 0) {
st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index a3098071f..902b6be6b 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -130,7 +130,7 @@ static void usb_ctrl_complete(struct urb *urb)
struct ctrl_msg *ctrl_msg;
if (urb->status < 0) {
- if (urb->status != USB_ST_URB_KILLED) {
+ if (urb->status != -ENOENT) {
WARN("urb status %d",urb->status);
} else {
DBG(1,"urb killed");
@@ -184,7 +184,7 @@ static void usb_int_complete(struct urb *urb)
int j;
if (urb->status < 0) {
- if (urb->status != USB_ST_URB_KILLED) {
+ if (urb->status != -ENOENT) {
WARN("urb status %d",urb->status);
urb->actual_length = 0;
} else {
@@ -470,7 +470,7 @@ static void usb_in_complete(struct urb *urb)
int len, count, status;
if (urb->status < 0) {
- if (urb->status != USB_ST_URB_KILLED) {
+ if (urb->status != -ENOENT) {
WARN("urb status %d",urb->status);
} else {
DBG(1,"urb killed");
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index c6a0e48f2..4a479ffbc 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -672,7 +672,6 @@ static int adb_release(struct inode *inode, struct file *file)
struct adbdev_state *state = file->private_data;
unsigned long flags;
- lock_kernel();
if (state) {
file->private_data = NULL;
spin_lock_irqsave(&state->lock, flags);
@@ -685,7 +684,6 @@ static int adb_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&state->lock, flags);
}
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 78b2dbb6d..ae2644f6a 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1983,7 +1983,6 @@ static int pmu_release(struct inode *inode, struct file *file)
struct pmu_private *pp = file->private_data;
unsigned long flags;
- lock_kernel();
if (pp != 0) {
file->private_data = 0;
spin_lock_irqsave(&all_pvt_lock, flags);
@@ -1991,7 +1990,6 @@ static int pmu_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&all_pvt_lock, flags);
kfree(pp);
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 6f0a79235..c40dd3a1b 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -119,22 +119,21 @@ static int linear_stop (mddev_t *mddev)
return 0;
}
-static int linear_make_request (mddev_t *mddev,
- int rw, struct buffer_head * bh)
+static int linear_make_request (mddev_t *mddev, int rw, struct bio *bio)
{
linear_conf_t *conf = mddev_to_conf(mddev);
struct linear_hash *hash;
dev_info_t *tmp_dev;
long block;
- block = bh->b_rsector >> 1;
+ block = bio->bi_sector >> 1;
hash = conf->hash_table + (block / conf->smallest->size);
if (block >= (hash->dev0->size + hash->dev0->offset)) {
if (!hash->dev1) {
printk ("linear_make_request : hash->dev1==NULL for block %ld\n",
block);
- buffer_IO_error(bh);
+ bio_io_error(bio);
return 0;
}
tmp_dev = hash->dev1;
@@ -144,11 +143,11 @@ static int linear_make_request (mddev_t *mddev,
if (block >= (tmp_dev->size + tmp_dev->offset)
|| block < tmp_dev->offset) {
printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, kdevname(tmp_dev->dev), tmp_dev->size, tmp_dev->offset);
- buffer_IO_error(bh);
+ bio_io_error(bio);
return 0;
}
- bh->b_rdev = tmp_dev->dev;
- bh->b_rsector = bh->b_rsector - (tmp_dev->offset << 1);
+ bio->bi_dev = tmp_dev->dev;
+ bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1);
return 1;
}
diff --git a/drivers/md/lvm-snap.c b/drivers/md/lvm-snap.c
index 8e5505ba3..9ec39b7a9 100644
--- a/drivers/md/lvm-snap.c
+++ b/drivers/md/lvm-snap.c
@@ -351,7 +351,7 @@ int lvm_snapshot_COW(kdev_t org_phys_dev,
blksize_snap = lvm_get_blksize(snap_phys_dev);
max_blksize = max(blksize_org, blksize_snap);
min_blksize = min(blksize_org, blksize_snap);
- max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
+ max_sectors = LVM_MAX_SECTORS * (min_blksize>>9);
if (chunk_size % (max_blksize>>9))
goto fail_blksize;
@@ -363,20 +363,20 @@ int lvm_snapshot_COW(kdev_t org_phys_dev,
iobuf->length = nr_sectors << 9;
- if(!lvm_snapshot_prepare_blocks(iobuf->blocks, org_start,
+ if(!lvm_snapshot_prepare_blocks(lv_snap->blocks, org_start,
nr_sectors, blksize_org))
goto fail_prepare;
if (brw_kiovec(READ, 1, &iobuf, org_phys_dev,
- iobuf->blocks, blksize_org) != (nr_sectors<<9))
+ lv_snap->blocks, blksize_org) != (nr_sectors<<9))
goto fail_raw_read;
- if(!lvm_snapshot_prepare_blocks(iobuf->blocks, snap_start,
+ if(!lvm_snapshot_prepare_blocks(lv_snap->blocks, snap_start,
nr_sectors, blksize_snap))
goto fail_prepare;
if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev,
- iobuf->blocks, blksize_snap) != (nr_sectors<<9))
+ lv_snap->blocks, blksize_snap) !=(nr_sectors<<9))
goto fail_raw_write;
}
@@ -505,7 +505,7 @@ int lvm_snapshot_alloc(lv_t * lv_snap)
ret = alloc_kiovec(1, &lv_snap->lv_iobuf);
if (ret) goto out;
- max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9);
+ max_sectors = LVM_MAX_SECTORS << (PAGE_SHIFT-9);
ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors);
if (ret) goto out_free_kiovec;
diff --git a/drivers/md/lvm.c b/drivers/md/lvm.c
index ca4ccff57..a3ab38cd3 100644
--- a/drivers/md/lvm.c
+++ b/drivers/md/lvm.c
@@ -236,7 +236,7 @@
/*
* External function prototypes
*/
-static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*);
+static int lvm_make_request_fn(request_queue_t*, struct bio *);
static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
static int lvm_blk_open(struct inode *, struct file *);
@@ -262,7 +262,7 @@ static void lvm_init_vars(void);
#ifdef LVM_HD_NAME
extern void (*lvm_hd_name_ptr) (char *, int);
#endif
-static int lvm_map(struct buffer_head *, int);
+static int lvm_map(struct bio *);
static int lvm_do_lock_lvm(void);
static int lvm_do_le_remap(vg_t *, void *);
@@ -291,9 +291,9 @@ static void lvm_geninit(struct gendisk *);
static void __update_hardsectsize(lv_t *lv);
-static void _queue_io(struct buffer_head *bh, int rw);
-static struct buffer_head *_dequeue_io(void);
-static void _flush_io(struct buffer_head *bh);
+static void _queue_io(struct bio *bh, int rw);
+static struct bio *_dequeue_io(void);
+static void _flush_io(struct bio *bh);
static int _open_pv(pv_t *pv);
static void _close_pv(pv_t *pv);
@@ -346,7 +346,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lvm_wait);
static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t lvm_snapshot_lock = SPIN_LOCK_UNLOCKED;
-static struct buffer_head *_pe_requests;
+static struct bio *_pe_requests;
static DECLARE_RWSEM(_pe_lock);
@@ -369,7 +369,6 @@ struct block_device_operations lvm_blk_dops =
/* gendisk structures */
static struct hd_struct lvm_hd_struct[MAX_LV];
static int lvm_blocksizes[MAX_LV];
-static int lvm_hardsectsizes[MAX_LV];
static int lvm_size[MAX_LV];
static struct gendisk lvm_gendisk =
@@ -451,9 +450,7 @@ static void lvm_cleanup(void)
del_gendisk(&lvm_gendisk);
- blk_size[MAJOR_NR] = NULL;
- blksize_size[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
+ blk_clear(MAJOR_NR);
#ifdef LVM_HD_NAME
/* reference from linux/drivers/block/genhd.c */
@@ -1037,25 +1034,25 @@ static int lvm_get_snapshot_use_rate(lv_t *lv, void *arg)
static int lvm_user_bmap(struct inode *inode, struct lv_bmap *user_result)
{
- struct buffer_head bh;
+ struct bio bio;
unsigned long block;
int err;
if (get_user(block, &user_result->lv_block))
return -EFAULT;
- memset(&bh,0,sizeof bh);
- bh.b_blocknr = block;
- bh.b_dev = bh.b_rdev = inode->i_rdev;
- bh.b_size = lvm_get_blksize(bh.b_dev);
- bh.b_rsector = block * (bh.b_size >> 9);
- if ((err=lvm_map(&bh, READ)) < 0) {
+ memset(&bio,0,sizeof(bio));
+ bio.bi_dev = inode->i_rdev;
+ bio.bi_io_vec.bv_len = lvm_get_blksize(bio.bi_dev);
+ bio.bi_sector = block * bio_sectors(&bio);
+ bio.bi_rw = READ;
+ if ((err=lvm_map(&bio)) < 0) {
printk("lvm map failed: %d\n", err);
return -EINVAL;
}
- return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
- put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ?
+ return put_user(kdev_t_to_nr(bio.bi_dev), &user_result->lv_dev) ||
+ put_user(bio.bi_sector/bio_sectors(&bio), &user_result->lv_block) ?
-EFAULT : 0;
}
@@ -1104,7 +1101,7 @@ static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) {
(sector < (pe_lock_req.data.pv_offset + pe_size)));
}
-static inline int _defer_extent(struct buffer_head *bh, int rw,
+static inline int _defer_extent(struct bio *bh, int rw,
kdev_t pv, ulong sector, uint32_t pe_size)
{
if (pe_lock_req.lock == LOCK_PE) {
@@ -1122,17 +1119,18 @@ static inline int _defer_extent(struct buffer_head *bh, int rw,
return 0;
}
-static int lvm_map(struct buffer_head *bh, int rw)
+static int lvm_map(struct bio *bh)
{
- int minor = MINOR(bh->b_rdev);
+ int minor = MINOR(bh->bi_dev);
ulong index;
ulong pe_start;
- ulong size = bh->b_size >> 9;
- ulong rsector_org = bh->b_rsector;
+ ulong size = bio_sectors(bh);
+ ulong rsector_org = bh->bi_sector;
ulong rsector_map;
kdev_t rdev_map;
vg_t *vg_this = vg[VG_BLK(minor)];
lv_t *lv = vg_this->lv[LV_BLK(minor)];
+ int rw = bio_data_dir(bh);
down_read(&lv->lv_lock);
@@ -1153,7 +1151,7 @@ static int lvm_map(struct buffer_head *bh, int rw)
P_MAP("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n",
lvm_name, minor,
- kdevname(bh->b_rdev),
+ kdevname(bh->bi_dev),
rsector_org, size);
if (rsector_org + size > lv->lv_size) {
@@ -1248,13 +1246,13 @@ static int lvm_map(struct buffer_head *bh, int rw)
}
out:
- bh->b_rdev = rdev_map;
- bh->b_rsector = rsector_map;
+ bh->bi_dev = rdev_map;
+ bh->bi_sector = rsector_map;
up_read(&lv->lv_lock);
return 1;
bad:
- buffer_IO_error(bh);
+ bio_io_error(bh);
up_read(&lv->lv_lock);
return -1;
} /* lvm_map() */
@@ -1287,10 +1285,9 @@ void lvm_hd_name(char *buf, int minor)
/*
* make request function
*/
-static int lvm_make_request_fn(request_queue_t *q,
- int rw,
- struct buffer_head *bh) {
- return (lvm_map(bh, rw) <= 0) ? 0 : 1;
+static int lvm_make_request_fn(request_queue_t *q, struct bio *bio)
+{
+ return (lvm_map(bio) <= 0) ? 0 : 1;
}
@@ -1331,7 +1328,7 @@ lock_try_again:
static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg)
{
pe_lock_req_t new_lock;
- struct buffer_head *bh;
+ struct bio *bh;
uint p;
if (vg_ptr == NULL) return -ENXIO;
@@ -1820,8 +1817,6 @@ static void __update_hardsectsize(lv_t *lv) {
max_hardsectsize = hardsectsize;
}
}
-
- lvm_hardsectsizes[MINOR(lv->lv_dev)] = max_hardsectsize;
}
/*
@@ -2665,7 +2660,6 @@ static void __init lvm_geninit(struct gendisk *lvm_gdisk)
blk_size[MAJOR_NR] = lvm_size;
blksize_size[MAJOR_NR] = lvm_blocksizes;
- hardsect_size[MAJOR_NR] = lvm_hardsectsizes;
return;
} /* lvm_gen_init() */
@@ -2673,16 +2667,16 @@ static void __init lvm_geninit(struct gendisk *lvm_gdisk)
/* Must have down_write(_pe_lock) when we enqueue buffers */
-static void _queue_io(struct buffer_head *bh, int rw) {
- if (bh->b_reqnext) BUG();
- bh->b_reqnext = _pe_requests;
+static void _queue_io(struct bio *bh, int rw) {
+ if (bh->bi_next) BUG();
+ bh->bi_next = _pe_requests;
_pe_requests = bh;
}
/* Must have down_write(_pe_lock) when we dequeue buffers */
-static struct buffer_head *_dequeue_io(void)
+static struct bio *_dequeue_io(void)
{
- struct buffer_head *bh = _pe_requests;
+ struct bio *bh = _pe_requests;
_pe_requests = NULL;
return bh;
}
@@ -2697,13 +2691,14 @@ static struct buffer_head *_dequeue_io(void)
* If, for some reason, the same PE is locked again before all of these writes
* have finished, then these buffers will just be re-queued (i.e. no danger).
*/
-static void _flush_io(struct buffer_head *bh)
+static void _flush_io(struct bio *bh)
{
while (bh) {
- struct buffer_head *next = bh->b_reqnext;
- bh->b_reqnext = NULL;
+ struct bio *next = bh->bi_next;
+ bh->bi_next = NULL;
/* resubmit this buffer head */
- generic_make_request(WRITE, bh);
+ bh->bi_rw = WRITE; /* needed? */
+ generic_make_request(bh);
bh = next;
}
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 71f1e0ce5..8fe839aff 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -105,7 +105,6 @@ static ctl_table raid_root_table[] = {
*/
struct hd_struct md_hd_struct[MAX_MD_DEVS];
static int md_blocksizes[MAX_MD_DEVS];
-static int md_hardsect_sizes[MAX_MD_DEVS];
static int md_maxreadahead[MAX_MD_DEVS];
static mdk_thread_t *md_recovery_thread;
@@ -172,14 +171,14 @@ void del_mddev_mapping(mddev_t * mddev, kdev_t dev)
mddev_map[minor].data = NULL;
}
-static int md_make_request(request_queue_t *q, int rw, struct buffer_head * bh)
+static int md_make_request (request_queue_t *q, struct bio *bio)
{
- mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
+ mddev_t *mddev = kdev_to_mddev(bio->bi_dev);
if (mddev && mddev->pers)
- return mddev->pers->make_request(mddev, rw, bh);
+ return mddev->pers->make_request(mddev, bio_rw(bio), bio);
else {
- buffer_IO_error(bh);
+ bio_io_error(bio);
return 0;
}
}
@@ -1701,19 +1700,14 @@ static int do_md_run(mddev_t * mddev)
* device.
* Also find largest hardsector size
*/
- md_hardsect_sizes[mdidx(mddev)] = 512;
ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev->faulty)
continue;
invalidate_device(rdev->dev, 1);
- if (get_hardsect_size(rdev->dev)
- > md_hardsect_sizes[mdidx(mddev)])
- md_hardsect_sizes[mdidx(mddev)] =
- get_hardsect_size(rdev->dev);
- }
- md_blocksizes[mdidx(mddev)] = 1024;
- if (md_blocksizes[mdidx(mddev)] < md_hardsect_sizes[mdidx(mddev)])
- md_blocksizes[mdidx(mddev)] = md_hardsect_sizes[mdidx(mddev)];
+ md_blocksizes[mdidx(mddev)] = 1024;
+ if (get_hardsect_size(rdev->dev) > md_blocksizes[mdidx(mddev)])
+ md_blocksizes[mdidx(mddev)] = get_hardsect_size(rdev->dev);
+ }
mddev->pers = pers[pnum];
err = mddev->pers->run(mddev);
@@ -2769,7 +2763,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
(short *) &loc->cylinders);
if (err)
goto abort_unlock;
- err = md_put_user (md_hd_struct[minor].start_sect,
+ err = md_put_user (get_start_sect(dev),
(long *) &loc->start);
goto done_unlock;
}
@@ -3621,13 +3615,11 @@ static void md_geninit(void)
for(i = 0; i < MAX_MD_DEVS; i++) {
md_blocksizes[i] = 1024;
md_size[i] = 0;
- md_hardsect_sizes[i] = 512;
md_maxreadahead[i] = MD_READAHEAD;
}
blksize_size[MAJOR_NR] = md_blocksizes;
blk_size[MAJOR_NR] = md_size;
max_readahead[MAJOR_NR] = md_maxreadahead;
- hardsect_size[MAJOR_NR] = md_hardsect_sizes;
dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
@@ -3670,7 +3662,8 @@ int md__init md_init(void)
md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
if (!md_recovery_thread)
- printk(KERN_ALERT "md: bug: couldn't allocate md_recovery_thread\n");
+ printk(KERN_ALERT
+ "md: bug: couldn't allocate md_recovery_thread\n");
md_register_reboot_notifier(&md_notifier);
raid_table_header = register_sysctl_table(raid_root_table, 1);
@@ -4008,15 +4001,10 @@ void cleanup_module(void)
#endif
del_gendisk(&md_gendisk);
-
blk_dev[MAJOR_NR].queue = NULL;
- blksize_size[MAJOR_NR] = NULL;
- blk_size[MAJOR_NR] = NULL;
- max_readahead[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
-
+ blk_clear(MAJOR_NR);
+
free_device_names();
-
}
#endif
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index fed885b57..8b21f612e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -223,8 +223,7 @@ static int raid0_stop (mddev_t *mddev)
* Of course, those facts may not be valid anymore (and surely won't...)
* Hey guys, there's some work out there ;-)
*/
-static int raid0_make_request (mddev_t *mddev,
- int rw, struct buffer_head * bh)
+static int raid0_make_request (mddev_t *mddev, int rw, struct bio *bio)
{
unsigned int sect_in_chunk, chunksize_bits, chunk_size;
raid0_conf_t *conf = mddev_to_conf(mddev);
@@ -235,11 +234,11 @@ static int raid0_make_request (mddev_t *mddev,
chunk_size = mddev->param.chunk_size >> 10;
chunksize_bits = ffz(~chunk_size);
- block = bh->b_rsector >> 1;
+ block = bio->bi_sector >> 1;
hash = conf->hash_table + block / conf->smallest->size;
/* Sanity check */
- if (chunk_size < (block % chunk_size) + (bh->b_size >> 10))
+ if (chunk_size < (block % chunk_size) + (bio->bi_size >> 10))
goto bad_map;
if (!hash)
@@ -255,7 +254,7 @@ static int raid0_make_request (mddev_t *mddev,
} else
zone = hash->zone0;
- sect_in_chunk = bh->b_rsector & ((chunk_size<<1) -1);
+ sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1);
chunk = (block - zone->zone_offset) / (zone->nb_dev << chunksize_bits);
tmp_dev = zone->dev[(block >> chunksize_bits) % zone->nb_dev];
rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)
@@ -265,8 +264,8 @@ static int raid0_make_request (mddev_t *mddev,
* The new BH_Lock semantics in ll_rw_blk.c guarantee that this
* is the only IO operation happening on this bh.
*/
- bh->b_rdev = tmp_dev->dev;
- bh->b_rsector = rsect;
+ bio->bi_dev = tmp_dev->dev;
+ bio->bi_sector = rsect;
/*
* Let the main block layer submit the IO and resolve recursion:
@@ -274,7 +273,7 @@ static int raid0_make_request (mddev_t *mddev,
return 1;
bad_map:
- printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10);
+ printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bio->bi_sector, bio->bi_size >> 10);
goto outerr;
bad_hash:
printk("raid0_make_request bug: hash==NULL for block %ld\n", block);
@@ -285,7 +284,7 @@ bad_zone0:
bad_zone1:
printk ("raid0_make_request bug: hash->zone1==NULL for block %ld\n", block);
outerr:
- buffer_IO_error(bh);
+ bio_io_error(bio);
return 0;
}
diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h
index 481308e6c..a028f2ed7 100644
--- a/drivers/media/video/saa7146.h
+++ b/drivers/media/video/saa7146.h
@@ -74,7 +74,6 @@ struct saa7146
unsigned int nr;
unsigned long irq; /* IRQ used by SAA7146 card */
unsigned short id;
- struct i2c_bus i2c;
struct pci_dev *dev;
unsigned char revision;
unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 9b099f579..ad8250401 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -45,7 +45,6 @@
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/videodev.h>
-#include <linux/i2c-old.h>
#include "saa7146.h"
#include "saa7146reg.h"
@@ -142,14 +141,13 @@ static void I2CWipe(struct saa7146 *saa)
!(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
schedule();
}
+
/* read I2C */
-static int I2CRead(struct i2c_bus *bus, unsigned char addr,
+static int I2CRead(struct saa7146 *saa, unsigned char addr,
unsigned char subaddr, int dosub)
{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
int i;
-
if (saaread(SAA7146_I2C_STATUS) & 0x3c)
I2CWipe(saa);
for (i = 0; i < 1000 &&
@@ -194,17 +192,12 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr,
printk("i2c read timeout\n");
return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
}
-static int I2CReadOld(struct i2c_bus *bus, unsigned char addr)
-{
- return I2CRead(bus, addr, 0, 0);
-}
/* set both to write both bytes, reset it to write only b1 */
-static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
+static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1,
unsigned char b2, int both)
{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
int i;
u32 data;
@@ -226,15 +219,14 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
return 0;
}
-static void attach_inform(struct i2c_bus *bus, int id)
+static void attach_inform(struct saa7146 *saa, int id)
{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
int i;
DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id));
if (id == 0xa0) { /* we have rev2 or later board, fill in info */
for (i = 0; i < 64; i++)
- saa->boardcfg[i] = I2CRead(bus, 0xa0, i, 1);
+ saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1);
#ifdef USE_RESCUE_EEPROM_SDM275
if (saa->boardcfg[0] != 0) {
printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr);
@@ -250,35 +242,20 @@ static void attach_inform(struct i2c_bus *bus, int id)
}
}
-static void detach_inform(struct i2c_bus *bus, int id)
+static void detach_inform(struct saa7146 *saa, int id)
{
- struct saa7146 *saa = (struct saa7146 *) bus->data;
int i;
i = saa->nr;
}
-static void I2CBusScan(struct i2c_bus *bus)
+static void I2CBusScan(struct saa7146 *saa)
{
int i;
for (i = 0; i < 0xff; i += 2)
- if ((I2CRead(bus, i, 0, 0)) >= 0)
- attach_inform(bus, i);
+ if ((I2CRead(saa, i, 0, 0)) >= 0)
+ attach_inform(saa, i);
}
-static struct i2c_bus saa7146_i2c_bus_template =
-{
- "saa7146",
- I2C_BUSID_BT848,
- NULL,
- SPIN_LOCK_UNLOCKED,
- attach_inform,
- detach_inform,
- NULL,
- NULL,
- I2CReadOld,
- I2CWrite,
-};
-
static int debiwait_maxwait = 0;
static int wait_for_debi_done(struct saa7146 *saa)
@@ -664,10 +641,8 @@ static int ibm_send_command(struct saa7146 *saa,
static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
{
- I2CWrite(&(saa->i2c), 0x22, 0x03,
- left > 94 ? 94 : left, 2);
- I2CWrite(&(saa->i2c), 0x22, 0x04,
- right > 94 ? 94 : right, 2);
+ I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2);
+ I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2);
}
static void initialize_cs4341(struct saa7146 *saa)
@@ -676,15 +651,15 @@ static void initialize_cs4341(struct saa7146 *saa)
for (i = 0; i < 200; i++) {
/* auto mute off, power on, no de-emphasis */
/* I2S data up to 24-bit 64xFs internal SCLK */
- I2CWrite(&(saa->i2c), 0x22, 0x01, 0x11, 2);
+ I2CWrite(saa, 0x22, 0x01, 0x11, 2);
/* ATAPI mixer settings */
- I2CWrite(&(saa->i2c), 0x22, 0x02, 0x49, 2);
+ I2CWrite(saa, 0x22, 0x02, 0x49, 2);
/* attenuation left 3db */
- I2CWrite(&(saa->i2c), 0x22, 0x03, 0x00, 2);
+ I2CWrite(saa, 0x22, 0x03, 0x00, 2);
/* attenuation right 3db */
- I2CWrite(&(saa->i2c), 0x22, 0x04, 0x00, 2);
- I2CWrite(&(saa->i2c), 0x22, 0x01, 0x10, 2);
- if (I2CRead(&(saa->i2c), 0x22, 0x02, 1) == 0x49)
+ I2CWrite(saa, 0x22, 0x04, 0x00, 2);
+ I2CWrite(saa, 0x22, 0x01, 0x10, 2);
+ if (I2CRead(saa, 0x22, 0x02, 1) == 0x49)
break;
schedule();
}
@@ -701,10 +676,10 @@ static void initialize_cs8420(struct saa7146 *saa, int pro)
else
sequence = mode8420con;
for (i = 0; i < INIT8420LEN; i++)
- I2CWrite(&(saa->i2c), 0x20, init8420[i * 2],
+ I2CWrite(saa, 0x20, init8420[i * 2],
init8420[i * 2 + 1], 2);
for (i = 0; i < MODE8420LEN; i++)
- I2CWrite(&(saa->i2c), 0x20, sequence[i * 2],
+ I2CWrite(saa, 0x20, sequence[i * 2],
sequence[i * 2 + 1], 2);
printk("stradis%d: CS8420 initialized\n", saa->nr);
}
@@ -722,39 +697,39 @@ static void initialize_saa7121(struct saa7146 *saa, int dopal)
for (i = 0; i < INIT7121LEN; i++) {
if (NewCard) { /* handle new card encoder differences */
if (sequence[i*2] == 0x3a)
- I2CWrite(&(saa->i2c), 0x88, 0x3a, 0x13, 2);
+ I2CWrite(saa, 0x88, 0x3a, 0x13, 2);
else if (sequence[i*2] == 0x6b)
- I2CWrite(&(saa->i2c), 0x88, 0x6b, 0x20, 2);
+ I2CWrite(saa, 0x88, 0x6b, 0x20, 2);
else if (sequence[i*2] == 0x6c)
- I2CWrite(&(saa->i2c), 0x88, 0x6c,
+ I2CWrite(saa, 0x88, 0x6c,
dopal ? 0x09 : 0xf5, 2);
else if (sequence[i*2] == 0x6d)
- I2CWrite(&(saa->i2c), 0x88, 0x6d,
+ I2CWrite(saa, 0x88, 0x6d,
dopal ? 0x20 : 0x00, 2);
else if (sequence[i*2] == 0x7a)
- I2CWrite(&(saa->i2c), 0x88, 0x7a,
+ I2CWrite(saa, 0x88, 0x7a,
dopal ? (PALFirstActive - 1) :
(NTSCFirstActive - 4), 2);
else if (sequence[i*2] == 0x7b)
- I2CWrite(&(saa->i2c), 0x88, 0x7b,
+ I2CWrite(saa, 0x88, 0x7b,
dopal ? PALLastActive :
NTSCLastActive, 2);
- else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2],
+ else I2CWrite(saa, 0x88, sequence[i * 2],
sequence[i * 2 + 1], 2);
} else {
if (sequence[i*2] == 0x6b && mod)
- I2CWrite(&(saa->i2c), 0x88, 0x6b,
+ I2CWrite(saa, 0x88, 0x6b,
(sequence[i * 2 + 1] ^ 0x09), 2);
else if (sequence[i*2] == 0x7a)
- I2CWrite(&(saa->i2c), 0x88, 0x7a,
+ I2CWrite(saa, 0x88, 0x7a,
dopal ? (PALFirstActive - 1) :
(NTSCFirstActive - 4), 2);
else if (sequence[i*2] == 0x7b)
- I2CWrite(&(saa->i2c), 0x88, 0x7b,
+ I2CWrite(saa, 0x88, 0x7b,
dopal ? PALLastActive :
NTSCLastActive, 2);
else
- I2CWrite(&(saa->i2c), 0x88, sequence[i * 2],
+ I2CWrite(saa, 0x88, sequence[i * 2],
sequence[i * 2 + 1], 2);
}
}
@@ -2060,10 +2035,7 @@ static int configure_saa7146(struct pci_dev *dev, int num)
if (!saa->saa7146_mem)
return -EIO;
- memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus));
memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
- sprintf(saa->i2c.name, "stradis%d", num);
- saa->i2c.data = saa;
saawrite(0, SAA7146_IER); /* turn off all interrupts */
result = request_irq(saa->irq, saa7146_irq,
SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);
@@ -2082,10 +2054,6 @@ static int configure_saa7146(struct pci_dev *dev, int num)
iounmap(saa->saa7146_mem);
return -1;
}
-#if 0
- /* i2c generic interface is currently BROKEN */
- i2c_register_bus(&saa->i2c);
-#endif
return 0;
}
@@ -2176,7 +2144,7 @@ static int init_saa7146(int i)
saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
SAA7146_MC2);
- I2CBusScan(&(saa->i2c));
+ I2CBusScan(saa);
return 0;
}
@@ -2194,10 +2162,6 @@ static void release_saa(void)
saawrite(0, SAA7146_MC2);
saawrite(0, SAA7146_IER);
saawrite(0xffffffffUL, SAA7146_ISR);
-#if 0
- /* unregister i2c_bus */
- i2c_unregister_bus((&saa->i2c));
-#endif
/* disable PCI bus-mastering */
pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 372583a05..6044b0531 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -69,6 +69,7 @@
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/major.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 1e7c77b39..9b6d48e9e 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -65,7 +65,7 @@
#include <linux/errno.h>
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
-#include <linux/blk.h> /* for io_request_lock (spinlock) decl */
+#include <linux/blk.h>
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
#include "../../scsi/sd.h"
@@ -246,9 +246,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r)
mf_chk = search_taskQ(1,sc,MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
if (mf_chk != NULL) {
sc->result = DID_ABORT << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&sc->host->host_lock, flags);
sc->scsi_done(sc);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&sc->host->host_lock, flags);
return 1;
}
}
@@ -426,9 +426,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r)
scsi_to_pci_dma_dir(sc->sc_data_direction));
}
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&sc->host->host_lock, flags);
sc->scsi_done(sc);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&sc->host->host_lock, flags);
}
return 1;
@@ -928,9 +928,9 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
SCpnt->resid = SCpnt->request_bufflen - mpt_sdev->sense_sz;
SCpnt->result = 0;
-/* spin_lock(&io_request_lock); */
+/* spin_lock(&SCpnt->host->host_lock); */
SCpnt->scsi_done(SCpnt);
-/* spin_unlock(&io_request_lock); */
+/* spin_unlock(&SCpnt->host->host_lock); */
return 0;
}
}
@@ -1333,9 +1333,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
if (ctx2abort == -1) {
printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
} else {
dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
@@ -1352,9 +1352,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
i, mf, SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
}
}
@@ -1428,9 +1428,9 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
i, mf, SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
}
@@ -1502,9 +1502,9 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
i, mf, SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
}
@@ -1748,9 +1748,9 @@ mptscsih_taskmgmt_bh(void *sc)
if (ctx2abort == -1) {
printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
continue;
}
@@ -1797,9 +1797,9 @@ mptscsih_taskmgmt_bh(void *sc)
!= 0) {
printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);
SCpnt->result = DID_SOFT_ERROR << 16;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
SCpnt->scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
} else {
/* Spin-Wait for TaskMgmt complete!!! */
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index ba144600d..ec2fbc81d 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -198,7 +198,6 @@ extern void x_scsi_taskmgmt_bh(void *);
cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 \
}
#else
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 971833f3a..bdf52592b 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -114,15 +114,16 @@
#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D
#define I2O_BSA_DSC_TIMEOUT 0x000E
+#define I2O_UNIT(dev) (i2ob_dev[MINOR((dev)) & 0xf0])
+#define I2O_LOCK(unit) (i2ob_dev[(unit)].req_queue->queue_lock)
+
/*
* Some of these can be made smaller later
*/
static int i2ob_blksizes[MAX_I2OB<<4];
-static int i2ob_hardsizes[MAX_I2OB<<4];
static int i2ob_sizes[MAX_I2OB<<4];
static int i2ob_media_change_flag[MAX_I2OB];
-static u32 i2ob_max_sectors[MAX_I2OB<<4];
static int i2ob_context;
@@ -252,9 +253,9 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
unsigned long mptr;
u64 offset;
struct request *req = ireq->req;
- struct buffer_head *bh = req->bh;
+ struct bio *bio = req->bio;
int count = req->nr_sectors<<9;
- char *last = NULL;
+ unsigned long last = ~0UL;
unsigned short size = 0;
// printk(KERN_INFO "i2ob_send called\n");
@@ -283,30 +284,30 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
if(req->cmd == READ)
{
__raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
- while(bh!=NULL)
+ while(bio)
{
- if(bh->b_data == last) {
- size += bh->b_size;
- last += bh->b_size;
- if(bh->b_reqnext)
+ if (bio_to_phys(bio) == last) {
+ size += bio->bi_size;
+ last += bio->bi_size;
+ if(bio->bi_next)
__raw_writel(0x14000000|(size), mptr-8);
else
__raw_writel(0xD4000000|(size), mptr-8);
}
else
{
- if(bh->b_reqnext)
- __raw_writel(0x10000000|(bh->b_size), mptr);
+ if(bio->bi_next)
+ __raw_writel(0x10000000|bio->bi_size, mptr);
else
- __raw_writel(0xD0000000|(bh->b_size), mptr);
- __raw_writel(virt_to_bus(bh->b_data), mptr+4);
+ __raw_writel(0xD0000000|bio->bi_size, mptr);
+ __raw_writel(bio_to_phys(bio), mptr+4);
mptr += 8;
- size = bh->b_size;
- last = bh->b_data + size;
+ size = bio->bi_size;
+ last = bio_to_phys(bio) + bio->bi_size;
}
- count -= bh->b_size;
- bh = bh->b_reqnext;
+ count -= bio->bi_size;
+ bio = bio->bi_next;
}
/*
* Heuristic for now since the block layer doesnt give
@@ -322,30 +323,30 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
else if(req->cmd == WRITE)
{
__raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
- while(bh!=NULL)
+ while(bio)
{
- if(bh->b_data == last) {
- size += bh->b_size;
- last += bh->b_size;
- if(bh->b_reqnext)
+ if (bio_to_phys(bio) == last) {
+ size += bio->bi_size;
+ last += bio->bi_size;
+ if(bio->bi_next)
__raw_writel(0x14000000|(size), mptr-8);
else
__raw_writel(0xD4000000|(size), mptr-8);
}
else
{
- if(bh->b_reqnext)
- __raw_writel(0x14000000|(bh->b_size), mptr);
+ if(bio->bi_next)
+ __raw_writel(0x14000000|bio->bi_size, mptr);
else
- __raw_writel(0xD4000000|(bh->b_size), mptr);
- __raw_writel(virt_to_bus(bh->b_data), mptr+4);
+ __raw_writel(0xD4000000|bio->bi_size, mptr);
+ __raw_writel(bio_to_phys(bio), mptr+4);
mptr += 8;
- size = bh->b_size;
- last = bh->b_data + size;
+ size = bio->bi_size;
+ last = bio_to_phys(bio) + bio->bi_size;
}
- count -= bh->b_size;
- bh = bh->b_reqnext;
+ count -= bio->bi_size;
+ bio = bio->bi_next;
}
if(c->battery)
@@ -409,7 +410,8 @@ static inline void i2ob_end_request(struct request *req)
* unlocked.
*/
- while (end_that_request_first( req, !req->errors, "i2o block" ));
+ while (end_that_request_first(req, !req->errors, req->hard_cur_sectors))
+ ;
/*
* It is now ok to complete the request.
@@ -417,61 +419,6 @@ static inline void i2ob_end_request(struct request *req)
end_that_request_last( req );
}
-/*
- * Request merging functions
- */
-static inline int i2ob_new_segment(request_queue_t *q, struct request *req,
- int __max_segments)
-{
- int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
-
- if (__max_segments < max_segments)
- max_segments = __max_segments;
-
- if (req->nr_segments < max_segments) {
- req->nr_segments++;
- return 1;
- }
- return 0;
-}
-
-static int i2ob_back_merge(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
-{
- if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
- return 1;
- return i2ob_new_segment(q, req, __max_segments);
-}
-
-static int i2ob_front_merge(request_queue_t *q, struct request *req,
- struct buffer_head *bh, int __max_segments)
-{
- if (bh->b_data + bh->b_size == req->bh->b_data)
- return 1;
- return i2ob_new_segment(q, req, __max_segments);
-}
-
-static int i2ob_merge_requests(request_queue_t *q,
- struct request *req,
- struct request *next,
- int __max_segments)
-{
- int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
- int total_segments = req->nr_segments + next->nr_segments;
-
- if (__max_segments < max_segments)
- max_segments = __max_segments;
-
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
- total_segments--;
-
- if (total_segments > max_segments)
- return 0;
-
- req->nr_segments = total_segments;
- return 1;
-}
-
static int i2ob_flush(struct i2o_controller *c, struct i2ob_device *d, int unit)
{
unsigned long msg;
@@ -512,12 +459,6 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)];
/*
- * Pull the lock over ready
- */
-
- spin_lock_prefetch(&io_request_lock);
-
- /*
* FAILed message
*/
if(m[0] & (1<<13))
@@ -535,10 +476,10 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
ireq->req->errors++;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
i2ob_unhook_request(ireq, c->unit);
i2ob_end_request(ireq->req);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
/* Now flush the message by making it a NOP */
m[0]&=0x00FFFFFF;
@@ -559,12 +500,12 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
if(msg->function == I2O_CMD_BLOCK_CFLUSH)
{
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
dev->constipated=0;
DEBUG(("unconstipated\n"));
if(i2ob_backlog_request(c, dev)==0)
i2ob_request(dev->req_queue);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
return;
}
@@ -580,10 +521,10 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
ireq=&i2ob_queues[c->unit]->request_queue[m[3]];
ireq->req->errors++;
printk(KERN_WARNING "I2O Block: Data transfer to deleted device!\n");
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
i2ob_unhook_request(ireq, c->unit);
i2ob_end_request(ireq->req);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
return;
}
@@ -629,7 +570,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
if(err==4)
{
/*
@@ -674,7 +615,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
*/
i2ob_request(dev->req_queue);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
/*
* and out
@@ -682,7 +623,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
return;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name,
bsa_errors[m[4]&0XFFFF]);
if(m[4]&0x00FF0000)
@@ -697,8 +638,8 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
* Dequeue the request. We use irqsave locks as one day we
* may be running polled controllers from a BH...
*/
-
- spin_lock_irqsave(&io_request_lock, flags);
+
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
i2ob_unhook_request(ireq, c->unit);
i2ob_end_request(ireq->req);
atomic_dec(&i2ob_queues[c->unit]->queue_depth);
@@ -710,7 +651,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
if(i2ob_backlog_request(c, dev)==0)
i2ob_request(dev->req_queue);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
}
/*
@@ -789,8 +730,7 @@ static int i2ob_evt(void *dummy)
for(i = unit; i <= unit+15; i++)
{
i2ob_sizes[i] = 0;
- i2ob_hardsizes[i] = 0;
- i2ob_max_sectors[i] = 0;
+ blk_queue_max_sectors(i2ob_dev[i].req_queue, 0);
i2ob[i].nr_sects = 0;
i2ob_gendisk.part[i].nr_sects = 0;
}
@@ -824,11 +764,11 @@ static int i2ob_evt(void *dummy)
if(i2ob_query_device(&i2ob_dev[unit], 0x0004, 0, &size, 8) !=0 )
i2ob_query_device(&i2ob_dev[unit], 0x0000, 4, &size, 8);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(unit), flags);
i2ob_sizes[unit] = (int)(size>>10);
i2ob_gendisk.part[unit].nr_sects = size>>9;
i2ob[unit].nr_sects = (int)(size>>9);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(unit), flags);
break;
}
@@ -881,13 +821,14 @@ static int i2ob_evt(void *dummy)
static void i2ob_timer_handler(unsigned long q)
{
+ request_queue_t *req_queue = (request_queue_t *) q;
unsigned long flags;
/*
* We cannot touch the request queue or the timer
- * flag without holding the io_request_lock.
+ * flag without holding the queue_lock
*/
- spin_lock_irqsave(&io_request_lock,flags);
+ spin_lock_irqsave(&req_queue->queue_lock,flags);
/*
* Clear the timer started flag so that
@@ -898,12 +839,12 @@ static void i2ob_timer_handler(unsigned long q)
/*
* Restart any requests.
*/
- i2ob_request((request_queue_t*)q);
+ i2ob_request(req_queue);
/*
* Free the lock.
*/
- spin_unlock_irqrestore(&io_request_lock,flags);
+ spin_unlock_irqrestore(&req_queue->queue_lock,flags);
}
static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev)
@@ -1132,34 +1073,23 @@ static int do_i2ob_revalidate(kdev_t dev, int maxu)
static int i2ob_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct i2ob_device *dev;
- int minor;
-
/* Anyone capable of this syscall can do *real bad* things */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (!inode)
+ if (!inode || !inode->i_rdev)
return -EINVAL;
- minor = MINOR(inode->i_rdev);
- if (minor >= (MAX_I2OB<<4))
- return -ENODEV;
- dev = &i2ob_dev[minor];
switch (cmd) {
- case BLKGETSIZE:
- return put_user(i2ob[minor].nr_sects, (long *) arg);
- case BLKGETSIZE64:
- return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg);
-
case HDIO_GETGEO:
{
struct hd_geometry g;
- int u=minor&0xF0;
+ int u = MINOR(inode->i_rdev) & 0xF0;
i2o_block_biosparam(i2ob_sizes[u]<<1,
&g.cylinders, &g.heads, &g.sectors);
- g.start = i2ob[minor].start_sect;
- return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
+ g.start = get_start_sect(inode->i_rdev);
+ return copy_to_user((void *)arg, &g, sizeof(g))
+ ? -EFAULT : 0;
}
case BLKRRPART:
@@ -1167,6 +1097,8 @@ static int i2ob_ioctl(struct inode *inode, struct file *file,
return -EACCES;
return do_i2ob_revalidate(inode->i_rdev,1);
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKFLSBUF:
case BLKROSET:
case BLKROGET:
@@ -1354,8 +1286,6 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
i2ob_query_device(dev, 0x0000, 5, &flags, 4);
i2ob_query_device(dev, 0x0000, 6, &status, 4);
i2ob_sizes[unit] = (int)(size>>10);
- for(i=unit; i <= unit+15 ; i++)
- i2ob_hardsizes[i] = blocksize;
i2ob_gendisk.part[unit].nr_sects = size>>9;
i2ob[unit].nr_sects = (int)(size>>9);
@@ -1366,26 +1296,27 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
/*
* Max number of Scatter-Gather Elements
*/
-
for(i=unit;i<=unit+15;i++)
{
- i2ob_max_sectors[i] = 256;
- i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
+ request_queue_t *q = i2ob_dev[unit].req_queue;
+
+ blk_queue_max_sectors(q, 256);
+ blk_queue_max_segments(q, (d->controller->status_block->inbound_frame_size - 8)/2);
if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 2)
i2ob_dev[i].depth = 32;
if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 1)
{
- i2ob_max_sectors[i] = 32;
- i2ob_dev[i].max_segments = 8;
+ blk_queue_max_sectors(q, 32);
+ blk_queue_max_segments(q, 8);
i2ob_dev[i].depth = 4;
}
if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
{
- i2ob_max_sectors[i] = 8;
- i2ob_dev[i].max_segments = 8;
+ blk_queue_max_sectors(q, 8);
+ blk_queue_max_segments(q, 8);
}
}
@@ -1430,7 +1361,7 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
}
printk(".\n");
printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n",
- d->dev_name, i2ob_max_sectors[unit]);
+ d->dev_name, i2ob_dev[unit].req_queue->max_sectors);
/*
* If this is the first I2O block device found on this IOP,
@@ -1450,7 +1381,7 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
*/
dev->req_queue = &i2ob_queues[c->unit]->req_queue;
- grok_partitions(&i2ob_gendisk, unit>>4, 1<<4, (long)(size>>9));
+ grok_partitions(MKDEV(MAJOR_NR, unit), (long)(size>>9));
/*
* Register for the events we're interested in and that the
@@ -1492,10 +1423,6 @@ static int i2ob_init_iop(unsigned int unit)
atomic_set(&i2ob_queues[unit]->queue_depth, 0);
blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request);
- blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0);
- i2ob_queues[unit]->req_queue.back_merge_fn = i2ob_back_merge;
- i2ob_queues[unit]->req_queue.front_merge_fn = i2ob_front_merge;
- i2ob_queues[unit]->req_queue.merge_requests_fn = i2ob_merge_requests;
i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit];
return 0;
@@ -1506,11 +1433,11 @@ static int i2ob_init_iop(unsigned int unit)
*/
static request_queue_t* i2ob_get_queue(kdev_t dev)
{
- int unit = MINOR(dev)&0xF0;
-
- return i2ob_dev[unit].req_queue;
+ return I2O_UNIT(dev).req_queue;
}
+
+
/*
* Probe the I2O subsytem for block class devices
*/
@@ -1708,7 +1635,7 @@ void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
int i = 0;
unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&I2O_LOCK(c->unit), flags);
/*
* Need to do this...we somtimes get two events from the IRTOS
@@ -1730,7 +1657,7 @@ void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
if(unit >= MAX_I2OB<<4)
{
printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n");
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
return;
}
@@ -1743,12 +1670,11 @@ void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
{
i2ob_dev[i].i2odev = NULL;
i2ob_sizes[i] = 0;
- i2ob_hardsizes[i] = 0;
- i2ob_max_sectors[i] = 0;
+ blk_queue_max_sectors(i2ob_dev[i].req_queue, 0);
i2ob[i].nr_sects = 0;
i2ob_gendisk.part[i].nr_sects = 0;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&I2O_LOCK(c->unit), flags);
/*
* Decrease usage count for module
@@ -1891,13 +1817,10 @@ int i2o_block_init(void)
*/
blksize_size[MAJOR_NR] = i2ob_blksizes;
- hardsect_size[MAJOR_NR] = i2ob_hardsizes;
blk_size[MAJOR_NR] = i2ob_sizes;
- max_sectors[MAJOR_NR] = i2ob_max_sectors;
blk_dev[MAJOR_NR].queue = i2ob_get_queue;
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request);
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
for (i = 0; i < MAX_I2OB << 4; i++) {
i2ob_dev[i].refcnt = 0;
@@ -1909,7 +1832,6 @@ int i2o_block_init(void)
i2ob_dev[i].tail = NULL;
i2ob_dev[i].depth = MAX_I2OB_DEPTH;
i2ob_blksizes[i] = 1024;
- i2ob_max_sectors[i] = 2;
}
/*
@@ -1978,7 +1900,6 @@ MODULE_AUTHOR("Red Hat Software");
MODULE_DESCRIPTION("I2O Block Device OSM");
MODULE_LICENSE("GPL");
-
void cleanup_module(void)
{
int i;
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index db81acf15..2d6d6b539 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -847,7 +847,6 @@ static int cfg_release(struct inode *inode, struct file *file)
struct i2o_cfg_info *p1, *p2;
unsigned long flags;
- lock_kernel();
p1 = p2 = NULL;
spin_lock_irqsave(&i2o_config_lock, flags);
@@ -870,7 +869,6 @@ static int cfg_release(struct inode *inode, struct file *file)
p1 = p1->next;
}
spin_unlock_irqrestore(&i2o_config_lock, flags);
- unlock_kernel();
return 0;
}
diff --git a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c
index 55b1f722c..801037a47 100644
--- a/drivers/message/i2o/i2o_core.c
+++ b/drivers/message/i2o/i2o_core.c
@@ -125,6 +125,7 @@ static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
* Function table to send to bus specific layers
* See <include/linux/i2o.h> for explanation of this
*/
+#ifdef CONFIG_I2O_PCI_MODULE
static struct i2o_core_func_table i2o_core_functions =
{
i2o_install_controller,
@@ -135,7 +136,6 @@ static struct i2o_core_func_table i2o_core_functions =
i2o_delete_controller
};
-#ifdef CONFIG_I2O_PCI_MODULE
extern int i2o_pci_core_attach(struct i2o_core_func_table *);
extern void i2o_pci_core_detach(void);
#endif /* CONFIG_I2O_PCI_MODULE */
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index cb59ae8f8..49d80260a 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -151,11 +151,10 @@ static void flush_pending(void)
static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
{
Scsi_Cmnd *current_command;
+ spinlock_t *lock;
u32 *m = (u32 *)msg;
u8 as,ds,st;
- spin_lock_prefetch(&io_request_lock);
-
if(m[0] & (1<<13))
{
printk("IOP fail.\n");
@@ -190,12 +189,13 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, stru
{
/* Create a scsi error for this */
current_command = (Scsi_Cmnd *)m[3];
+ lock = &current_command->host->host_lock;
printk("Aborted %ld\n", current_command->serial_number);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(lock);
current_command->result = DID_ERROR << 16;
current_command->scsi_done(current_command);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(lock);
/* Now flush the message by making it a NOP */
m[0]&=0x00FFFFFF;
@@ -284,9 +284,10 @@ static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, stru
* It worked maybe ?
*/
current_command->result = DID_OK << 16 | ds;
- spin_lock(&io_request_lock);
+ lock = &current_command->host->host_lock;
+ spin_lock(lock);
current_command->scsi_done(current_command);
- spin_unlock(&io_request_lock);
+ spin_unlock(lock);
return;
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index e05ed51ad..d15d74130 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1166,7 +1166,7 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
put_user(1, (char *)&geo->heads);
put_user(8, (char *)&geo->sectors);
put_user((sect>>3), (short *)&geo->cylinders);
- put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start);
+ put_user(get_start_sect(inode->i_rdev), (u_long *)&geo->start);
break;
case BLKGETSIZE:
ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);
@@ -1206,42 +1206,27 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
======================================================================*/
-static int ftl_reread_partitions(int minor)
+static int ftl_reread_partitions(kdev_t dev)
{
+ int minor = MINOR(dev);
partition_t *part = myparts[minor >> 4];
- int i, whole;
+ int res;
DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor);
if ((atomic_read(&part->open) > 1)) {
return -EBUSY;
}
- whole = minor & ~(MAX_PART-1);
- i = MAX_PART - 1;
- while (i-- > 0) {
- if (ftl_hd[whole+i].nr_sects > 0) {
- kdev_t rdev = MKDEV(FTL_MAJOR, whole+i);
-
- invalidate_device(rdev, 1);
- }
- ftl_hd[whole+i].start_sect = 0;
- ftl_hd[whole+i].nr_sects = 0;
- }
+ res = wipe_partitions(dev);
+ if (res)
+ goto leave;
scan_header(part);
register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART,
&ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
-#ifdef PCMCIA_DEBUG
- for (i = 0; i < MAX_PART; i++) {
- if (ftl_hd[whole+i].nr_sects > 0)
- printk(KERN_INFO " %d: start %ld size %ld\n", i,
- ftl_hd[whole+i].start_sect,
- ftl_hd[whole+i].nr_sects);
- }
-#endif
- return 0;
+ return res;
}
/*======================================================================
@@ -1431,7 +1416,7 @@ static void __exit cleanup_ftl(void)
unregister_blkdev(FTL_MAJOR, "ftl");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
- blksize_size[FTL_MAJOR] = NULL;
+ bklk_clear(FTL_MAJOR);
del_gendisk(&ftl_gendisk);
}
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index e61591fd8..21dc6c106 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -29,7 +29,7 @@
#if LINUX_VERSION_CODE < 0x20300
#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
#else
-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
+#define QUEUE_PLUGGED (blk_queue_plugged(QUEUE))
#endif
#ifdef CONFIG_DEVFS_FS
@@ -402,7 +402,7 @@ static release_t mtdblock_release(struct inode *inode, struct file *file)
/*
* This is a special request_fn because it is executed in a process context
- * to be able to sleep independently of the caller. The io_request_lock
+ * to be able to sleep independently of the caller. The queue_lock
* is held upon entry and exit.
* The head of our request queue is considered active so there is no need
* to dequeue requests before we are done.
@@ -416,7 +416,7 @@ static void handle_mtdblock_request(void)
for (;;) {
INIT_REQUEST;
req = CURRENT;
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&QUEUE->queue_lock);
mtdblk = mtdblks[MINOR(req->rq_dev)];
res = 0;
@@ -458,7 +458,7 @@ static void handle_mtdblock_request(void)
}
end_req:
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&QUEUE->queue_lock);
end_request(res);
}
}
@@ -490,16 +490,16 @@ int mtdblock_thread(void *dummy)
while (!leaving) {
add_wait_queue(&thr_wq, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&QUEUE->queue_lock);
if (QUEUE_EMPTY || QUEUE_PLUGGED) {
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&QUEUE->queue_lock);
schedule();
remove_wait_queue(&thr_wq, &wait);
} else {
remove_wait_queue(&thr_wq, &wait);
set_current_state(TASK_RUNNING);
handle_mtdblock_request();
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&QUEUE->queue_lock);
}
}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index f92fe3d66..dc955e661 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -59,11 +59,6 @@ static int nftl_blocksizes[256];
/* .. for the Linux partition table handling. */
struct hd_struct part_table[256];
-#if LINUX_VERSION_CODE < 0x20328
-static void dummy_init (struct gendisk *crap)
-{}
-#endif
-
static struct gendisk nftl_gendisk = {
major: MAJOR_NR,
major_name: "nftl",
@@ -166,7 +161,8 @@ static void NFTL_setup(struct mtd_info *mtd)
#if LINUX_VERSION_CODE < 0x20328
resetup_one_dev(&nftl_gendisk, firstfree);
#else
- grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
+ grok_partitions(MKDEV(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
+ nftl->nr_sects);
#endif
}
@@ -786,7 +782,7 @@ static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
struct NFTLrecord *nftl;
- int p;
+ int res;
nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];
@@ -799,16 +795,9 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
g.heads = nftl->heads;
g.sectors = nftl->sectors;
g.cylinders = nftl->cylinders;
- g.start = part_table[MINOR(inode->i_rdev)].start_sect;
+ g.start = get_start_sect(inode->i_rdev);
return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
}
- case BLKGETSIZE: /* Return device size */
- return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
- (unsigned long *) arg);
- case BLKGETSIZE64:
- return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
- (u64 *)arg);
-
case BLKFLSBUF:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
fsync_dev(inode->i_rdev);
@@ -825,27 +814,17 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
* or we won't be able to re-use the partitions,
* if there was a change and we don't want to reboot
*/
- p = (1<<NFTL_PARTN_BITS) - 1;
- while (p-- > 0) {
- kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
- if (part_table[p].nr_sects > 0)
- invalidate_device (devp, 1);
-
- part_table[MINOR(inode->i_dev)+p].start_sect = 0;
- part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
- }
-
-#if LINUX_VERSION_CODE < 0x20328
- resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
-#else
- grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
- 1<<NFTL_PARTN_BITS, nftl->nr_sects);
-#endif
- return 0;
+ res = wipe_partitions(inode->i_rdev);
+ if (!res)
+ grok_partitions(inode->i_rdev, nftl->nr_sects);
+
+ return res;
#if (LINUX_VERSION_CODE < 0x20303)
RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */
#else
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
case BLKROSET:
case BLKROGET:
case BLKSSZGET:
@@ -859,7 +838,7 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
void nftl_request(RQFUNC_ARG)
{
- unsigned int dev, block, nsect;
+ unsigned int dev, unit, block, nsect;
struct NFTLrecord *nftl;
char *buffer;
struct request *req;
@@ -871,10 +850,11 @@ void nftl_request(RQFUNC_ARG)
/* We can do this because the generic code knows not to
touch the request at the head of the queue */
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&QUEUE->queue_lock);
DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
- DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
(req->cmd == READ) ? "Read " : "Write",
req->sector, req->current_nr_sectors);
@@ -884,8 +864,8 @@ void nftl_request(RQFUNC_ARG)
buffer = req->buffer;
res = 1; /* succeed */
- if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
- /* there is no such partition */
+ unit = dev >> NFTL_PARTN_BITS;
+ if (unit >= MAX_NFTLS || dev != (unit << NFTL_PARTN_BITS)) {
printk("nftl: bad minor number: device = %s\n",
kdevname(req->rq_dev));
res = 0; /* fail */
@@ -906,8 +886,6 @@ void nftl_request(RQFUNC_ARG)
goto repeat;
}
- block += part_table[dev].start_sect;
-
if (req->cmd == READ) {
DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
"(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
@@ -953,7 +931,7 @@ void nftl_request(RQFUNC_ARG)
}
repeat:
DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&QUEUE->queue_lock);
end_request(res);
}
}
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 8b392f29f..e6eddb3f0 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -175,7 +175,7 @@ static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = {
};
#endif /* CONFIG_MCA */
-#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE)
+#ifdef __ISAPNP__
static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
@@ -206,7 +206,7 @@ MODULE_LICENSE("GPL");
static u16 el3_isapnp_phys_addr[8][3];
-#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+#endif /* __ISAPNP__ */
static int nopnp;
int __init el3_probe(struct net_device *dev)
@@ -217,9 +217,9 @@ int __init el3_probe(struct net_device *dev)
u16 phys_addr[3];
static int current_tag;
int mca_slot = -1;
-#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE)
+#ifdef __ISAPNP__
static int pnp_cards;
-#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+#endif /* __ISAPNP__ */
if (dev) SET_MODULE_OWNER(dev);
@@ -323,7 +323,7 @@ int __init el3_probe(struct net_device *dev)
}
#endif /* CONFIG_MCA */
-#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE)
+#ifdef __ISAPNP__
if (nopnp == 1)
goto no_pnp;
@@ -359,7 +359,7 @@ int __init el3_probe(struct net_device *dev)
}
}
no_pnp:
-#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+#endif /* __ISAPNP__ */
/* Select an open I/O location at 0x1*0 to do contention select. */
for ( ; id_port < 0x200; id_port += 0x10) {
@@ -405,7 +405,7 @@ no_pnp:
phys_addr[i] = htons(id_read_eeprom(i));
}
-#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE)
+#ifdef __ISAPNP__
if (nopnp == 0) {
/* The ISA PnP 3c509 cards respond to the ID sequence.
This check is needed in order not to register them twice. */
@@ -425,7 +425,7 @@ no_pnp:
}
}
}
-#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+#endif /* __ISAPNP__ */
{
unsigned int iobase = id_read_eeprom(8);
@@ -1017,10 +1017,10 @@ MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)");
MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)");
MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)");
MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt");
-#ifdef CONFIG_ISAPNP
+#ifdef __ISAPNP__
MODULE_PARM(nopnp, "i");
MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)");
-#endif /* CONFIG_ISAPNP */
+#endif /* __ISAPNP__ */
int
init_module(void)
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index be9a92d2f..de2013540 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -359,7 +359,7 @@ static struct media_table {
{ "Default", 0, 0xFF, XCVR_10baseT, 10000},
};
-#ifdef CONFIG_ISAPNP
+#ifdef __ISAPNP__
static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051),
@@ -372,7 +372,7 @@ MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
static int corkscrew_isapnp_phys_addr[3];
static int nopnp;
-#endif /* CONFIG_ISAPNP */
+#endif /* __ISAPNP__ */
static int corkscrew_scan(struct net_device *dev);
static struct net_device *corkscrew_found_device(struct net_device *dev,
@@ -450,12 +450,12 @@ static int corkscrew_scan(struct net_device *dev)
{
int cards_found = 0;
static int ioaddr;
-#ifdef CONFIG_ISAPNP
+#ifdef __ISAPNP__
short i;
static int pnp_cards;
#endif
-#ifdef CONFIG_ISAPNP
+#ifdef __ISAPNP__
if(nopnp == 1)
goto no_pnp;
for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) {
@@ -513,17 +513,17 @@ static int corkscrew_scan(struct net_device *dev)
}
}
no_pnp:
-#endif /* CONFIG_ISAPNP */
+#endif /* __ISAPNP__ */
/* Check all locations on the ISA bus -- evil! */
for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
int irq;
-#ifdef CONFIG_ISAPNP
+#ifdef __ISAPNP__
/* Make sure this was not already picked up by isapnp */
if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue;
if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue;
if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue;
-#endif /* CONFIG_ISAPNP */
+#endif /* __ISAPNP__ */
if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
continue;
/* Check the resource configuration for a matching ioaddr. */
diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c
index 4b7f58f9a..410ca6937 100644
--- a/drivers/net/fc/iph5526.c
+++ b/drivers/net/fc/iph5526.c
@@ -3802,7 +3802,6 @@ struct pci_dev *pdev = NULL;
fi->host = host;
//host->max_id = MAX_SCSI_TARGETS;
host->max_id = 5;
- host->hostt->use_new_eh_code = 1;
host->this_id = tmpt->this_id;
pci_maddr = pci_resource_start(pdev, 0);
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index e058dd89d..980998133 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -807,10 +807,11 @@ static int receive(struct net_device *dev, int cnt)
/* --------------------------------------------------------------------- */
#ifdef __i386__
+#include <asm/msr.h>
#define GETTICK(x) \
({ \
if (cpu_has_tsc) \
- __asm__ __volatile__("rdtsc" : "=a" (x) : : "dx");\
+ rdtscl(x); \
})
#else /* __i386__ */
#define GETTICK(x)
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 8c6fd5105..60defc2ad 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -256,7 +256,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
/* Grab the speed URB */
purb = &self->speed_urb;
- if (purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
WARNING(__FUNCTION__ "(), URB still in use!\n");
return;
}
@@ -301,7 +301,7 @@ static void speed_bulk_callback(purb_t purb)
}
/* Check for timeout and other USB nasties */
- if(purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
/* I get a lot of -ECONNABORTED = -103 here - Jean II */
IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags);
@@ -314,7 +314,7 @@ static void speed_bulk_callback(purb_t purb)
}
/* urb is now available */
- purb->status = USB_ST_NOERROR;
+ purb->status = 0;
/* If it was the speed URB, allow the stack to send more packets */
if(purb == &self->speed_urb) {
@@ -372,7 +372,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
}
}
- if (purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
WARNING(__FUNCTION__ "(), URB still in use!\n");
dev_kfree_skb(skb);
return 0;
@@ -490,7 +490,7 @@ static void write_bulk_callback(purb_t purb)
purb->context = NULL;
/* Check for timeout and other USB nasties */
- if(purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
/* I get a lot of -ECONNABORTED = -103 here - Jean II */
IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags);
@@ -504,7 +504,7 @@ static void write_bulk_callback(purb_t purb)
}
/* urb is now available */
- purb->status = USB_ST_NOERROR;
+ purb->status = 0;
/* If the network is closed, stop everything */
if ((!self->netopen) || (!self->present)) {
@@ -547,11 +547,11 @@ static void irda_usb_net_timeout(struct net_device *netdev)
/* Check speed URB */
purb = &(self->speed_urb);
- if (purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
IRDA_DEBUG(0, "%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
switch (purb->status) {
- case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */
+ case -EINPROGRESS:
usb_unlink_urb(purb);
/* Note : above will *NOT* call netif_wake_queue()
* in completion handler, we will come back here.
@@ -563,7 +563,7 @@ static void irda_usb_net_timeout(struct net_device *netdev)
case -ETIMEDOUT: /* -110 */
case -ENOENT: /* -2 (urb unlinked by us) */
default: /* ??? - Play safe */
- purb->status = USB_ST_NOERROR;
+ purb->status = 0;
netif_wake_queue(self->netdev);
done = 1;
break;
@@ -572,7 +572,7 @@ static void irda_usb_net_timeout(struct net_device *netdev)
/* Check Tx URB */
purb = &(self->tx_urb);
- if (purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
struct sk_buff *skb = purb->context;
IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
@@ -590,7 +590,7 @@ static void irda_usb_net_timeout(struct net_device *netdev)
#endif /* IU_BUG_KICK_TIMEOUT */
switch (purb->status) {
- case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */
+ case -EINPROGRESS:
usb_unlink_urb(purb);
/* Note : above will *NOT* call netif_wake_queue()
* in completion handler, because purb->status will
@@ -610,7 +610,7 @@ static void irda_usb_net_timeout(struct net_device *netdev)
dev_kfree_skb_any(skb);
purb->context = NULL;
}
- purb->status = USB_ST_NOERROR;
+ purb->status = 0;
netif_wake_queue(self->netdev);
done = 1;
break;
@@ -727,7 +727,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, purb_
purb->transfer_flags = USB_QUEUE_BULK;
/* Note : unlink *must* be synchronous because of the code in
* irda_usb_net_close() -> free the skb - Jean II */
- purb->status = USB_ST_NOERROR;
+ purb->status = 0;
purb->next = NULL; /* Don't auto resubmit URBs */
ret = usb_submit_urb(purb);
@@ -768,9 +768,9 @@ static void irda_usb_receive(purb_t purb)
}
/* Check the status */
- if(purb->status != USB_ST_NOERROR) {
+ if (purb->status != 0) {
switch (purb->status) {
- case USB_ST_CRC: /* -EILSEQ */
+ case -EILSEQ:
self->stats.rx_errors++;
self->stats.rx_crc_errors++;
break;
@@ -1442,9 +1442,9 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
ret = usb_set_interface(dev, ifnum, 0);
IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
switch (ret) {
- case USB_ST_NOERROR: /* 0 */
+ case 0:
break;
- case USB_ST_STALL: /* -EPIPE = -32 */
+ case -EPIPE: /* -EPIPE = -32 */
usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
IRDA_DEBUG(0, __FUNCTION__ "(), Clearing stall on control interface\n" );
break;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index c1bbdd30b..cb75c868a 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -325,7 +325,6 @@ static int ppp_release(struct inode *inode, struct file *file)
{
struct ppp_file *pf = (struct ppp_file *) file->private_data;
- lock_kernel();
if (pf != 0) {
file->private_data = 0;
if (atomic_dec_and_test(&pf->refcnt)) {
@@ -339,7 +338,6 @@ static int ppp_release(struct inode *inode, struct file *file)
}
}
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index f2807a644..f20b71f10 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -80,7 +80,7 @@ static unsigned int ultra_portlist[] __initdata =
int ultra_probe(struct net_device *dev);
static int ultra_probe1(struct net_device *dev, int ioaddr);
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static int ultra_probe_isapnp(struct net_device *dev);
#endif
@@ -100,7 +100,7 @@ static void ultra_pio_output(struct net_device *dev, int count,
const unsigned char *buf, const int start_page);
static int ultra_close_card(struct net_device *dev);
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static struct isapnp_device_id ultra_device_ids[] __initdata = {
{ ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
@@ -140,7 +140,7 @@ int __init ultra_probe(struct net_device *dev)
else if (base_addr != 0) /* Don't probe at all. */
return -ENXIO;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
/* Look for any installed ISAPnP cards */
if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
return 0;
@@ -279,7 +279,7 @@ out:
return retval;
}
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static int __init ultra_probe_isapnp(struct net_device *dev)
{
int i;
@@ -544,7 +544,7 @@ cleanup_module(void)
/* NB: ultra_close_card() does free_irq */
int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
struct pci_dev *idev = (struct pci_dev *)ei_status.priv;
if (idev)
idev->deactivate(idev);
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 6290b6b5e..b948c40b0 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -2265,8 +2265,8 @@ TLan_FinishReset( struct net_device *dev )
printk("TLAN: Partner capability: ");
for (i = 5; i <= 10; i++)
if (partner & (1<<i))
- printk("%s", media[i-5]);
- printk("\n");
+ printk("%s",media[i-5]);
+ printk("\n");
}
TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index bd77b4b7a..2b1a79a91 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -974,13 +974,11 @@ static int cosa_release(struct inode *inode, struct file *file)
struct cosa_data *cosa;
unsigned long flags;
- lock_kernel();
cosa = channel->cosa;
spin_lock_irqsave(&cosa->lock, flags);
cosa->usage--;
channel->usage--;
spin_unlock_irqrestore(&cosa->lock, flags);
- unlock_kernel();
return 0;
}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 92f1a6a0b..fafbf4c18 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -219,9 +219,8 @@ pdev_enable_device(struct pci_dev *dev)
cmd |= PCI_COMMAND_IO;
}
- /* ??? Always turn on bus mastering. If the device doesn't support
- it, the bit will go into the bucket. */
- cmd |= PCI_COMMAND_MASTER;
+ /* Do not enable bus mastering. A device could corrupt
+ * system memory by DMAing before a driver is ready for it. */
/* Set the cache line and default latency (32). */
pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 29ca88040..03c48321a 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -597,7 +597,6 @@ static int ds_release(struct inode *inode, struct file *file)
DEBUG(0, "ds_release(socket %d)\n", i);
if ((i >= sockets) || (sockets == 0))
return 0;
- lock_kernel();
s = &socket_table[i];
user = file->private_data;
if (CHECK_USER(user))
@@ -615,7 +614,6 @@ static int ds_release(struct inode *inode, struct file *file)
user->user_magic = 0;
kfree(user);
out:
- unlock_kernel();
return 0;
} /* ds_release */
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index a066eab9c..912286581 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -813,11 +813,7 @@ static void __init add_pcic(int ns, int type)
#ifdef CONFIG_ISA
-#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
-#define I82365_ISAPNP
-#endif
-
-#ifdef I82365_ISAPNP
+#ifdef __ISAPNP__
static struct isapnp_device_id id_table[] __initdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
@@ -836,7 +832,7 @@ static void __init isa_probe(void)
{
int i, j, sock, k, ns, id;
ioaddr_t port;
-#ifdef I82365_ISAPNP
+#ifdef __ISAPNP__
struct isapnp_device_id *devid;
struct pci_dev *dev;
@@ -1647,7 +1643,7 @@ static void __exit exit_i82365(void)
i365_set(i, I365_CSCINT, 0);
release_region(socket[i].ioaddr, 2);
}
-#if defined(CONFIG_ISA) && defined(I82365_ISAPNP)
+#if defined(CONFIG_ISA) && defined(__ISAPNP__)
if (i82365_pnpdev && i82365_pnpdev->deactivate)
i82365_pnpdev->deactivate(i82365_pnpdev);
#endif
diff --git a/drivers/pnp/isapnp_proc.c b/drivers/pnp/isapnp_proc.c
index 9f3cc0fc3..08085e106 100644
--- a/drivers/pnp/isapnp_proc.c
+++ b/drivers/pnp/isapnp_proc.c
@@ -170,12 +170,10 @@ static int isapnp_info_entry_open(struct inode *inode, struct file *file)
kfree(buffer);
return -ENOMEM;
}
- lock_kernel();
buffer->curr = buffer->buffer;
file->private_data = buffer;
if (mode == O_RDONLY)
isapnp_info_read(buffer);
- unlock_kernel();
return 0;
}
@@ -187,12 +185,10 @@ static int isapnp_info_entry_release(struct inode *inode, struct file *file)
if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL)
return -EINVAL;
mode = file->f_flags & O_ACCMODE;
- lock_kernel();
if (mode == O_WRONLY)
isapnp_info_write(buffer);
vfree(buffer->buffer);
kfree(buffer);
- unlock_kernel();
return 0;
}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 82131bcd6..8a0d94cf1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -730,13 +730,6 @@ dasd_register_major (major_info_t * major_info)
goto out_hardsect_size;
memset (hardsect_size[major], 0, (1 << MINORBITS) * sizeof (int));
- /* init max_sectors */
- max_sectors[major] =
- (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
- if (!max_sectors[major])
- goto out_max_sectors;
- memset (max_sectors[major], 0, (1 << MINORBITS) * sizeof (int));
-
/* finally do the gendisk stuff */
major_info->gendisk.part = kmalloc ((1 << MINORBITS) *
sizeof (struct hd_struct),
@@ -755,10 +748,6 @@ dasd_register_major (major_info_t * major_info)
/* error handling - free the prior allocated memory */
out_gendisk:
- kfree (max_sectors[major]);
- max_sectors[major] = NULL;
-
- out_max_sectors:
kfree (hardsect_size[major]);
hardsect_size[major] = NULL;
@@ -825,12 +814,8 @@ dasd_unregister_major (major_info_t * major_info)
kfree (blk_size[major]);
kfree (blksize_size[major]);
kfree (hardsect_size[major]);
- kfree (max_sectors[major]);
- blk_size[major] = NULL;
- blksize_size[major] = NULL;
- hardsect_size[major] = NULL;
- max_sectors[major] = NULL;
+ blk_clear(major);
rc = devfs_unregister_blkdev (major, DASD_NAME);
if (rc < 0) {
@@ -1704,10 +1689,6 @@ dasd_process_queues (dasd_device_t * device)
dasd_end_request (req, 0);
dasd_dequeue_request (queue,req);
} else {
- /* relocate request according to partition table */
- req->sector +=
- device->major_info->gendisk.
- part[MINOR (req->rq_dev)].start_sect;
cqr = device->discipline->build_cp_from_req (device, req);
if (cqr == NULL) {
@@ -1716,10 +1697,7 @@ dasd_process_queues (dasd_device_t * device)
"on request %p\n",
device->devinfo.devno,
req);
- /* revert relocation of request */
- req->sector -=
- device->major_info->gendisk.
- part[MINOR (req->rq_dev)].start_sect;
+
break; /* terminate request queue loop */
}
@@ -1769,10 +1747,10 @@ static void
dasd_run_bh (dasd_device_t * device)
{
long flags;
- spin_lock_irqsave (&io_request_lock, flags);
+ spin_lock_irqsave (&device->request_queue.queue_lock, flags);
atomic_set (&device->bh_scheduled, 0);
dasd_process_queues (device);
- spin_unlock_irqrestore (&io_request_lock, flags);
+ spin_unlock_irqrestore (&device->request_queue.queue_lock, flags);
}
/*
@@ -2468,14 +2446,12 @@ do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
dasd_info.chanq_len = 0;
if (device->request_queue->request_fn) {
struct list_head *l;
+ request_queue_t *q = drive->request_queue;
ccw_req_t *cqr = device->queue.head;
- spin_lock_irqsave (&io_request_lock, flags);
- list_for_each (l,
- &device->request_queue->
- queue_head) {
+ spin_lock_irqsave (&q->queue_lock, flags);
+ list_for_each (l, q->queue_head, queue_head)
dasd_info.req_queue_len++;
- }
- spin_unlock_irqrestore (&io_request_lock,
+ spin_unlock_irqrestore (&q->queue_lock,
flags);
s390irq_spin_lock_irqsave (device->devinfo.irq,
flags);
@@ -2668,7 +2644,7 @@ block_device_operations dasd_device_operations =
/* SECTION: Management of device list */
int
-dasd_fillgeo(int kdev,struct hd_geometry *geo)
+dasd_fillgeo(kdev_t kdev,struct hd_geometry *geo)
{
dasd_device_t *device = dasd_device_from_kdev (kdev);
@@ -2679,8 +2655,7 @@ dasd_fillgeo(int kdev,struct hd_geometry *geo)
return -EINVAL;
device->discipline->fill_geometry (device, geo);
- geo->start = device->major_info->gendisk.part[MINOR(kdev)].start_sect
- >> device->sizes.s2b_shift;;
+ geo->start = get_start_sect(kdev);
return 0;
}
@@ -3365,6 +3340,11 @@ dasd_setup_blkdev (dasd_device_t *device )
int major = MAJOR(device->kdev);
int minor = MINOR(device->kdev);
+ device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
+ device->request_queue->queuedata = device;
+ blk_init_queue (device->request_queue, do_dasd_request);
+ elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP);
+
for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
if (i == 0)
device->major_info->gendisk.sizes[minor] =
@@ -3374,17 +3354,11 @@ dasd_setup_blkdev (dasd_device_t *device )
device->major_info->gendisk.sizes[minor + i] = 0;
hardsect_size[major][minor + i] = device->sizes.bp_block;
blksize_size[major][minor + i] = device->sizes.bp_block;
- max_sectors[major][minor + i] =
- device->discipline->max_blocks <<
- device->sizes.s2b_shift;
+ blk_queue_max_sectors(device->request_queue,
+ device->discipline->max_blocks << device->sizes.s2b_shift);
device->major_info->gendisk.part[minor+i].start_sect = 0;
device->major_info->gendisk.part[minor+i].nr_sects = 0;
}
- device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
- device->request_queue->queuedata = device;
- blk_init_queue (device->request_queue, do_dasd_request);
- blk_queue_headactive (device->request_queue, 0);
- elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP);
return rc;
}
@@ -3411,7 +3385,6 @@ dasd_disable_blkdev (dasd_device_t *device )
device->major_info->gendisk.sizes[minor + i] = 0;
hardsect_size[major][minor + i] = 0;
blksize_size[major][minor + i] = 0;
- max_sectors[major][minor + i] = 0;
}
if (device->request_queue) {
blk_cleanup_queue (device->request_queue);
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 4ad262542..d6715d169 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -1041,7 +1041,6 @@ int xpram_init(void)
#elif (XPRAM_VERSION == 24)
q = BLK_DEFAULT_QUEUE (major);
blk_init_queue (q, xpram_request);
- blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0);
#endif /* V22/V24 */
read_ahead[major] = xpram_rahead;
@@ -1213,8 +1212,7 @@ void cleanup_module(void)
{
int i;
- /* first of all, flush it all and reset all the data structures */
-
+ /* first of all, flush it all and reset all the data structures */
for (i=0; i<xpram_devs; i++)
fsync_dev(MKDEV(xpram_major, i)); /* flush the devices */
@@ -1222,13 +1220,10 @@ void cleanup_module(void)
#if (XPRAM_VERSION == 22)
blk_dev[major].request_fn = NULL;
#endif /* V22 */
- read_ahead[major] = 0;
- blk_size[major] = NULL;
kfree(blksize_size[major]);
- blksize_size[major] = NULL;
kfree(hardsect_size[major]);
- hardsect_size[major] = NULL;
kfree(xpram_offsets);
+ blk_clear(major);
/* finally, the usual cleanup */
#if (XPRAM_VERSION == 22)
diff --git a/drivers/s390/char/tapeblock.c b/drivers/s390/char/tapeblock.c
index f93b199b2..133348595 100644
--- a/drivers/s390/char/tapeblock.c
+++ b/drivers/s390/char/tapeblock.c
@@ -77,7 +77,6 @@ tapeblock_setup(tape_info_t* ti) {
blksize_size[tapeblock_major][ti->blk_minor]=2048; // blocks are 2k by default.
hardsect_size[tapeblock_major][ti->blk_minor]=512;
blk_init_queue (&ti->request_queue, tape_request_fn);
- blk_queue_headactive (&ti->request_queue, 0);
#ifdef CONFIG_DEVFS_FS
tapeblock_mkdevfstree(ti);
#endif
@@ -366,12 +365,14 @@ do_tape_request (request_queue_t * queue) {
static void
run_tapeblock_exec_IO (tape_info_t* ti) {
long flags_390irq,flags_ior;
- spin_lock_irqsave (&io_request_lock, flags_ior);
+ request_queue_t *q = &tape->request_queue;
+
+ spin_lock_irqsave (&q->queue_lock, flags_ior);
s390irq_spin_lock_irqsave(ti->devinfo.irq,flags_390irq);
atomic_set(&ti->bh_scheduled,0);
tapeblock_exec_IO(ti);
s390irq_spin_unlock_irqrestore(ti->devinfo.irq,flags_390irq);
- spin_unlock_irqrestore (&io_request_lock, flags_ior);
+ spin_unlock_irqrestore (&q->queue_lock, flags_ior);
}
void
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 7ebbaf064..cc42d1577 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -662,7 +662,6 @@ int jsfd_init(void) {
blk_size[JSFD_MAJOR] = jsfd_sizes;
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
- /* blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); */
for (i = 0; i < JSF_MAX; i++) {
if ((i & JSF_PART_MASK) >= JSF_NPART) continue;
jsf = &jsf0; /* actually, &jsfv[i >> JSF_PART_BITS] */
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 44e5a499d..0302b83ae 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -461,7 +461,6 @@ void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
present : 0, \
unchecked_isa_dma : 0, \
use_clustering : ENABLE_CLUSTERING, \
- use_new_eh_code : 1, \
emulated : 1 \
}
#endif /* _3W_XXXX_H */
diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c
index 894170e75..81217c47e 100644
--- a/drivers/scsi/53c7,8xx.c
+++ b/drivers/scsi/53c7,8xx.c
@@ -1427,13 +1427,14 @@ ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,
return -1;
}
-#ifdef __powerpc__
if ( ! (command & PCI_COMMAND_MASTER)) {
- printk("SCSI: PCI Master Bit has not been set. Setting...\n");
+ printk(KERN_INFO "SCSI: PCI Master Bit has not been set. Setting...\n");
command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO;
pci_write_config_word(pdev, PCI_COMMAND, command);
+ }
- if (io_port >= 0x10000000 && is_prep ) {
+#ifdef __powerpc__
+ if (io_port >= 0x10000000 && is_prep ) {
/* Mapping on PowerPC can't handle this! */
unsigned long new_io_port;
new_io_port = (io_port & 0x00FFFFFF) | 0x01000000;
@@ -1441,7 +1442,6 @@ ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,
io_port = new_io_port;
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port);
pdev->base_address[0] = io_port;
- }
}
#endif
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 375a42d2b..6cebda8f4 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -267,7 +267,6 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
tpnt->cmd_per_lun = NCR_700_MAX_TAGS;
tpnt->use_clustering = DISABLE_CLUSTERING;
- tpnt->use_new_eh_code = 1;
tpnt->proc_info = NCR_700_proc_directory_info;
if(tpnt->name == NULL)
diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in
index ed5d7589f..522c2c8da 100644
--- a/drivers/scsi/Config.in
+++ b/drivers/scsi/Config.in
@@ -20,10 +20,6 @@ dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
-#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
-#fi
-
bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index e78f2978d..f3528a29e 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -133,11 +133,9 @@ obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
obj-$(CONFIG_CHR_DEV_SG) += sg.o
list-multi := scsi_mod.o sd_mod.o sr_mod.o initio.o a100u2w.o cpqfc.o
-scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o \
- scsicam.o scsi_proc.o scsi_error.o \
- scsi_obsolete.o scsi_queue.o scsi_lib.o \
- scsi_merge.o scsi_dma.o scsi_scan.o \
- scsi_syms.o
+scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \
+ scsi_proc.o scsi_error.o scsi_queue.o scsi_lib.o \
+ scsi_merge.o scsi_dma.o scsi_scan.o scsi_syms.o
sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
initio-objs := ini9100u.o i91uscsi.o
diff --git a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h
index 94643970f..22cdadd55 100644
--- a/drivers/scsi/advansys.h
+++ b/drivers/scsi/advansys.h
@@ -77,7 +77,6 @@ void advansys_setup(char *, int *);
release: advansys_release, \
info: advansys_info, \
queuecommand: advansys_queuecommand, \
- use_new_eh_code: 1, \
eh_bus_reset_handler: advansys_reset, \
bios_param: advansys_biosparam, \
/* \
diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h
index 324effd0e..d637e5d5e 100644
--- a/drivers/scsi/aha152x.h
+++ b/drivers/scsi/aha152x.h
@@ -49,8 +49,7 @@ int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int
cmd_per_lun: 1, \
present: 0, \
unchecked_isa_dma: 0, \
- use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 1 }
+ use_clustering: DISABLE_CLUSTERING }
#endif
diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h
index 7863ce193..030590b9d 100644
--- a/drivers/scsi/aha1542.h
+++ b/drivers/scsi/aha1542.h
@@ -166,7 +166,6 @@ static int aha1542_biosparam(Disk *, kdev_t, int*);
sg_tablesize: AHA1542_SCATTER, \
cmd_per_lun: AHA1542_CMDLUN, \
unchecked_isa_dma: 1, \
- use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1}
-
+ use_clustering: ENABLE_CLUSTERING \
+}
#endif
diff --git a/drivers/scsi/aic7xxx/aic7xxx_linux.c b/drivers/scsi/aic7xxx/aic7xxx_linux.c
index 345e2546c..2f5a22e3e 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_linux.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_linux.c
@@ -1123,9 +1123,9 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
if (host == NULL)
return (ENOMEM);
- ahc_lock(ahc, &s);
*((struct ahc_softc **)host->hostdata) = ahc;
ahc->platform_data->host = host;
+ ahc_lock(ahc, &s);
host->can_queue = AHC_MAX_QUEUE;
host->cmd_per_lun = 2;
host->sg_tablesize = AHC_NSEG;
@@ -1272,7 +1272,9 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
TAILQ_INIT(&ahc->platform_data->completeq);
TAILQ_INIT(&ahc->platform_data->device_runq);
ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
- ahc_lockinit(ahc);
+ /*
+ * ahc_lockinit done by scsi_register, as we don't own that lock
+ */
ahc_done_lockinit(ahc);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
@@ -1530,22 +1532,17 @@ ahc_linux_device_queue_depth(struct ahc_softc *ahc, Scsi_Device * device)
int
ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
{
- struct ahc_softc *ahc;
+ struct ahc_softc *ahc = *(struct ahc_softc **)cmd->host->hostdata;
struct ahc_linux_device *dev;
- u_long flags;
-
- ahc = *(struct ahc_softc **)cmd->host->hostdata;
/*
* Save the callback on completion function.
*/
cmd->scsi_done = scsi_done;
- ahc_lock(ahc, &flags);
dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
cmd->lun, /*alloc*/TRUE);
if (dev == NULL) {
- ahc_unlock(ahc, &flags);
printf("aic7xxx_linux_queue: Unable to allocate device!\n");
return (-ENOMEM);
}
@@ -1556,7 +1553,6 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
dev->flags |= AHC_DEV_ON_RUN_LIST;
ahc_linux_run_device_queues(ahc);
}
- ahc_unlock(ahc, &flags);
return (0);
}
@@ -2408,12 +2404,10 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
/*
- * It is a bug that the upper layer takes
- * this lock just prior to calling us.
+ * we used to drop io_request_lock and lock ahc from here, but
+ * now that the global lock is gone the upper layer have already
+ * done what ahc_lock would do /jens
*/
- spin_unlock_irq(&io_request_lock);
-
- ahc_lock(ahc, &s);
/*
* First determine if we currently own this command.
@@ -2661,7 +2655,7 @@ done:
ahc_unlock(ahc, &s);
if (acmd != NULL)
ahc_linux_run_complete_queue(ahc, acmd);
- spin_lock_irq(&io_request_lock);
+ ahc_lock(ahc, &s);
return (retval);
}
@@ -2704,14 +2698,7 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd)
u_long s;
int found;
- /*
- * It is a bug that the upper layer takes
- * this lock just prior to calling us.
- */
- spin_unlock_irq(&io_request_lock);
-
ahc = *(struct ahc_softc **)cmd->host->hostdata;
- ahc_lock(ahc, &s);
found = ahc_reset_channel(ahc, cmd->channel + 'A',
/*initiate reset*/TRUE);
acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
@@ -2724,7 +2711,7 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd)
if (acmd != NULL)
ahc_linux_run_complete_queue(ahc, acmd);
- spin_lock_irq(&io_request_lock);
+ ahc_lock(ahc, &s);
return SUCCESS;
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_linux_host.h b/drivers/scsi/aic7xxx/aic7xxx_linux_host.h
index 4dc4a2366..491b0eb49 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_linux_host.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_linux_host.h
@@ -89,7 +89,7 @@ int ahc_linux_abort(Scsi_Cmnd *);
present: 0, /* number of 7xxx's present */\
unchecked_isa_dma: 0, /* no memory DMA restrictions */\
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 \
+ highmem_io: 1 \
}
#endif /* _AIC7XXX_LINUX_HOST_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 9db3062a2..a6036ddd9 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -575,9 +575,6 @@ struct ahc_platform_data {
TAILQ_HEAD(, ahc_linux_device) device_runq;
struct ahc_completeq completeq;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
- spinlock_t spin_lock;
-#endif
u_int qfrozen;
struct timer_list reset_timer;
struct semaphore eh_sem;
@@ -716,20 +713,20 @@ static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
static __inline void
ahc_lockinit(struct ahc_softc *ahc)
{
- spin_lock_init(&ahc->platform_data->spin_lock);
+ spin_lock_init(&ahc->platform_data->host->host_lock);
}
static __inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
*flags = 0;
- spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
+ spin_lock_irqsave(&ahc->platform_data->host->host_lock, *flags);
}
static __inline void
ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
- spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
+ spin_unlock_irqrestore(&ahc->platform_data->host->host_lock, *flags);
}
static __inline void
@@ -741,14 +738,18 @@ ahc_done_lockinit(struct ahc_softc *ahc)
static __inline void
ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
{
+ struct Scsi_Host *host = ahc->platform_data->host;
+
*flags = 0;
- spin_lock_irqsave(&io_request_lock, *flags);
+ spin_lock_irqsave(&host->host_lock, *flags);
}
static __inline void
ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
- spin_unlock_irqrestore(&io_request_lock, *flags);
+ struct Scsi_Host *host = ahc->platform_data->host;
+
+ spin_unlock_irqrestore(&host->host_lock, *flags);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index b5b8b3945..9177efb73 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -3084,7 +3084,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
* we check data_cmnd[0]. This catches the conditions for st.c, but
* I'm still not sure if request.cmd is valid for sg devices.
*/
- if ( (cmd->request.cmd == WRITE) || (cmd->data_cmnd[0] == WRITE_6) ||
+ if ( (rq_data_dir(&cmd->request) == WRITE) || (cmd->data_cmnd[0] == WRITE_6) ||
(cmd->data_cmnd[0] == WRITE_FILEMARKS) )
{
sp->w_total++;
@@ -4127,7 +4127,7 @@ aic7xxx_timer(struct aic7xxx_host *p)
unsigned long cpu_flags = 0;
struct aic7xxx_scb *scb;
- spin_lock_irqsave(&io_request_lock, cpu_flags);
+ spin_lock_irqsave(&p->host->host_lock, cpu_flags);
p->dev_timer_active &= ~(0x01 << MAX_TARGETS);
if ( (p->dev_timer_active & (0x01 << p->scsi_id)) &&
time_after_eq(jiffies, p->dev_expires[p->scsi_id]) )
@@ -4184,7 +4184,7 @@ aic7xxx_timer(struct aic7xxx_host *p)
}
aic7xxx_run_waiting_queues(p);
- spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+ spin_unlock_irqrestore(&p->host->host_lock, cpu_flags);
}
/*+F*************************************************************************
@@ -4294,7 +4294,7 @@ aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb)
{
printk(INFO_LEAD "Underflow - Wanted %u, %s %u, residual SG "
"count %d.\n", p->host_no, CTL_OF_SCB(scb), cmd->underflow,
- (cmd->request.cmd == WRITE) ? "wrote" : "read", actual,
+ (rq_data_dir(&cmd->request) == WRITE) ? "wrote" : "read", actual,
hscb->residual_SG_segment_count);
printk(INFO_LEAD "status 0x%x.\n", p->host_no, CTL_OF_SCB(scb),
hscb->target_status);
@@ -7011,7 +7011,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
p = (struct aic7xxx_host *)dev_id;
if(!p)
return;
- spin_lock_irqsave(&io_request_lock, cpu_flags);
+ spin_lock_irqsave(&p->host->host_lock, cpu_flags);
p->flags |= AHC_IN_ISR;
do
{
@@ -7020,7 +7020,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
aic7xxx_done_cmds_complete(p);
aic7xxx_run_waiting_queues(p);
p->flags &= ~AHC_IN_ISR;
- spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+ spin_unlock_irqrestore(&p->host->host_lock, cpu_flags);
}
/*+F*************************************************************************
@@ -11148,7 +11148,7 @@ aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
disable_irq(p->irq);
aic7xxx_print_card(p);
aic7xxx_print_scratch_ram(p);
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&p->host->host_lock);
for(;;) barrier();
}
diff --git a/drivers/scsi/aic7xxx_old/aic7xxx.h b/drivers/scsi/aic7xxx_old/aic7xxx.h
index de438cac7..ce397e38d 100644
--- a/drivers/scsi/aic7xxx_old/aic7xxx.h
+++ b/drivers/scsi/aic7xxx_old/aic7xxx.h
@@ -55,7 +55,6 @@
present: 0, /* number of 7xxx's present */\
unchecked_isa_dma: 0, /* no memory DMA restrictions */\
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
index 39644040a..cda1a387c 100644
--- a/drivers/scsi/atp870u.h
+++ b/drivers/scsi/atp870u.h
@@ -65,7 +65,6 @@ extern int atp870u_proc_info(char *, char **, off_t, int, int, int);
present: 0, /* number of 7xxx's present */\
unchecked_isa_dma: 0, /* no memory DMA restrictions */\
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
#endif
diff --git a/drivers/scsi/cpqfcTS.h b/drivers/scsi/cpqfcTS.h
index b65eca0ce..529171e82 100644
--- a/drivers/scsi/cpqfcTS.h
+++ b/drivers/scsi/cpqfcTS.h
@@ -38,7 +38,6 @@ extern int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg);
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 \
}
#endif /* CPQFCTS_H */
diff --git a/drivers/scsi/dc390.h b/drivers/scsi/dc390.h
index 8e3a5c836..02fe82eaf 100644
--- a/drivers/scsi/dc390.h
+++ b/drivers/scsi/dc390.h
@@ -64,7 +64,6 @@ extern int DC390_proc_info(char *buffer, char **start, off_t offset, int length,
this_id: 7, \
sg_tablesize: SG_ALL, \
cmd_per_lun: 16, \
- NEW_EH \
unchecked_isa_dma: 0, \
use_clustering: DISABLE_CLUSTERING \
}
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index ccf9b9b36..db4e6c8a1 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -178,7 +178,6 @@ static int adpt_detect(Scsi_Host_Template* sht)
adpt_hba* pHba;
adpt_init();
- sht->use_new_eh_code = 1;
PINFO("Detecting Adaptec I2O RAID controllers...\n");
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index bf3e89b85..670afcc2c 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -95,7 +95,6 @@ static int adpt_device_reset(Scsi_Cmnd* cmd);
sg_tablesize: 0, /* max scatter-gather cmds */\
cmd_per_lun: 256, /* cmds per lun (linked cmds) */\
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1, \
proc_name: "dpt_i2o" /* this is the name of our proc node*/ \
}
#endif
diff --git a/drivers/scsi/eata.h b/drivers/scsi/eata.h
index e75fc5f11..afa5e2787 100644
--- a/drivers/scsi/eata.h
+++ b/drivers/scsi/eata.h
@@ -30,7 +30,6 @@ int eata2x_biosparam(Disk *, kdev_t, int *);
this_id: 7, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 /* Enable new error code */ \
}
#endif
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index 8391a61b1..8142c017a 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -1,4 +1,4 @@
-/* $Id: esp.c,v 1.99 2001-02-13 01:17:01 davem Exp $
+/* $Id: esp.c,v 1.100 2001-12-11 04:55:48 davem Exp $
* esp.c: EnhancedScsiProcessor Sun SCSI driver code.
*
* Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu)
@@ -1035,9 +1035,6 @@ static void __init esp_init_swstate(struct esp *esp)
{
int i;
- /* Driver spinlock... */
- spin_lock_init(&esp->lock);
-
/* Command queues... */
esp->current_SC = NULL;
esp->disconnected_SC = NULL;
@@ -1816,7 +1813,6 @@ after_nego_msg_built:
int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
struct esp *esp;
- unsigned long flags;
/* Set up func ptr and initial driver cmd-phase. */
SCpnt->scsi_done = done;
@@ -1834,8 +1830,6 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->SCp.Message = 0xff;
SCpnt->SCp.sent_command = 0;
- spin_lock_irqsave(&esp->lock, flags);
-
/* Place into our queue. */
if (SCpnt->cmnd[0] == REQUEST_SENSE) {
ESPQUEUE(("RQSENSE\n"));
@@ -1849,8 +1843,6 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
if (!esp->current_SC && !esp->resetting_bus)
esp_exec_cmd(esp);
- spin_unlock_irqrestore(&esp->lock, flags);
-
return 0;
}
@@ -1926,7 +1918,7 @@ int esp_abort(Scsi_Cmnd *SCptr)
unsigned long flags;
int don;
- spin_lock_irqsave(&esp->lock, flags);
+ spin_lock_irqsave(&esp->ehost->host_lock, flags);
ESPLOG(("esp%d: Aborting command\n", esp->esp_id));
esp_dump_state(esp);
@@ -1942,7 +1934,7 @@ int esp_abort(Scsi_Cmnd *SCptr)
esp->msgout_len = 1;
esp->msgout_ctr = 0;
esp_cmd(esp, ESP_CMD_SATN);
- spin_unlock_irqrestore(&esp->lock, flags);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
return SCSI_ABORT_PENDING;
}
@@ -1964,14 +1956,14 @@ int esp_abort(Scsi_Cmnd *SCptr)
*prev = (Scsi_Cmnd *) this->host_scribble;
this->host_scribble = NULL;
- spin_unlock_irqrestore(&esp->lock, flags);
-
esp_release_dmabufs(esp, this);
this->result = DID_ABORT << 16;
this->scsi_done(this);
+
if (don)
ESP_INTSON(esp->dregs);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
return SCSI_ABORT_SUCCESS;
}
}
@@ -1985,7 +1977,7 @@ int esp_abort(Scsi_Cmnd *SCptr)
if (esp->current_SC) {
if (don)
ESP_INTSON(esp->dregs);
- spin_unlock_irqrestore(&esp->lock, flags);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
return SCSI_ABORT_BUSY;
}
@@ -1998,7 +1990,7 @@ int esp_abort(Scsi_Cmnd *SCptr)
if (don)
ESP_INTSON(esp->dregs);
- spin_unlock_irqrestore(&esp->lock, flags);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
return SCSI_ABORT_SNOOZE;
}
@@ -2014,16 +2006,11 @@ static int esp_finish_reset(struct esp *esp)
/* Clean up currently executing command, if any. */
if (sp != NULL) {
esp->current_SC = NULL;
- spin_unlock(&esp->lock);
esp_release_dmabufs(esp, sp);
sp->result = (DID_RESET << 16);
- spin_lock(&io_request_lock);
sp->scsi_done(sp);
- spin_unlock(&io_request_lock);
-
- spin_lock(&esp->lock);
}
/* Clean up disconnected queue, they have been invalidated
@@ -2031,16 +2018,10 @@ static int esp_finish_reset(struct esp *esp)
*/
if (esp->disconnected_SC) {
while ((sp = remove_first_SC(&esp->disconnected_SC)) != NULL) {
- spin_unlock(&esp->lock);
-
esp_release_dmabufs(esp, sp);
sp->result = (DID_RESET << 16);
- spin_lock(&io_request_lock);
sp->scsi_done(sp);
- spin_unlock(&io_request_lock);
-
- spin_lock(&esp->lock);
}
}
@@ -2071,9 +2052,9 @@ int esp_reset(Scsi_Cmnd *SCptr, unsigned int how)
struct esp *esp = (struct esp *) SCptr->host->hostdata;
unsigned long flags;
- spin_lock_irqsave(&esp->lock, flags);
+ spin_lock_irqsave(&esp->ehost->host_lock, flags);
(void) esp_do_resetbus(esp);
- spin_unlock_irqrestore(&esp->lock, flags);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
return SCSI_RESET_PENDING;
}
@@ -2085,16 +2066,12 @@ static void esp_done(struct esp *esp, int error)
esp->current_SC = NULL;
- spin_unlock(&esp->lock);
esp_release_dmabufs(esp, done_SC);
done_SC->result = error;
- spin_lock(&io_request_lock);
done_SC->scsi_done(done_SC);
- spin_unlock(&io_request_lock);
/* Bus is free, issue any commands in the queue. */
- spin_lock(&esp->lock);
if (esp->issue_SC && !esp->current_SC)
esp_exec_cmd(esp);
@@ -4344,7 +4321,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
struct esp *esp = dev_id;
unsigned long flags;
- spin_lock_irqsave(&esp->lock, flags);
+ spin_lock_irqsave(&esp->ehost->host_lock, flags);
if (ESP_IRQ_P(esp->dregs)) {
ESP_INTSOFF(esp->dregs);
@@ -4354,7 +4331,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
ESP_INTSON(esp->dregs);
}
- spin_unlock_irqrestore(&esp->lock, flags);
+ spin_unlock_irqrestore(&esp->ehost->host_lock, flags);
}
int esp_revoke(Scsi_Device* SDptr)
diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h
index 79836abb3..00bbca129 100644
--- a/drivers/scsi/esp.h
+++ b/drivers/scsi/esp.h
@@ -1,4 +1,4 @@
-/* $Id: esp.h,v 1.28 2000-03-30 01:33:17 davem Exp $
+/* $Id: esp.h,v 1.29 2001-12-11 04:55:47 davem Exp $
* esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI
* Processor) driver under Linux.
*
@@ -64,7 +64,6 @@ enum esp_rev {
/* We get one of these for each ESP probed. */
struct esp {
- spinlock_t lock;
unsigned long eregs; /* ESP controller registers */
unsigned long dregs; /* DMA controller registers */
struct sbus_dma *dma; /* DMA controller sw state */
@@ -416,7 +415,7 @@ extern int esp_revoke(Scsi_Device* SDptr);
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
+ highmem_io: 1, \
}
/* For our interrupt engine. */
diff --git a/drivers/scsi/fcal.h b/drivers/scsi/fcal.h
index 2c8938953..8246571b9 100644
--- a/drivers/scsi/fcal.h
+++ b/drivers/scsi/fcal.h
@@ -35,7 +35,6 @@ int fcal_proc_info (char *, char **, off_t, int, int, int);
sg_tablesize: 1, \
cmd_per_lun: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: FCP_SCSI_USE_NEW_EH_CODE, \
abort: fcp_old_abort, \
eh_abort_handler: fcp_scsi_abort, \
eh_device_reset_handler:fcp_scsi_dev_reset, \
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index d97d88382..1b34a8810 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -1059,8 +1059,7 @@ int gdth_eh_host_reset(Scsi_Cmnd *scp);
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
- use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 /* use new error code */ }
+ use_clustering: ENABLE_CLUSTERING }
#elif LINUX_VERSION_CODE >= 0x02015F
int gdth_bios_param(Disk *,kdev_t,int *);
@@ -1091,8 +1090,7 @@ int gdth_eh_host_reset(Scsi_Cmnd *scp);
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
- use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 /* use new error code */ }
+ use_clustering: ENABLE_CLUSTERING }
#elif LINUX_VERSION_CODE >= 0x010300
int gdth_bios_param(Disk *,kdev_t,int *);
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index e37a7eb37..a33868d94 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -129,7 +129,7 @@ scsi_unregister(struct Scsi_Host * sh){
* once we are 100% sure that we want to use this host adapter - it is a
* pain to reverse this, so we try to avoid it
*/
-
+extern int blk_nohighio;
struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
struct Scsi_Host * retval, *shpnt, *o_shp;
Scsi_Host_Name *shn, *shn2;
@@ -160,6 +160,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
break;
}
}
+ spin_lock_init(&retval->host_lock);
atomic_set(&retval->host_active,0);
retval->host_busy = 0;
retval->host_failed = 0;
@@ -235,6 +236,8 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
retval->cmd_per_lun = tpnt->cmd_per_lun;
retval->unchecked_isa_dma = tpnt->unchecked_isa_dma;
retval->use_clustering = tpnt->use_clustering;
+ if (!blk_nohighio)
+ retval->highmem_io = tpnt->highmem_io;
retval->select_queue_depths = tpnt->select_queue_depths;
retval->max_sectors = tpnt->max_sectors;
diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
index e9e6e70a1..08f3ea280 100644
--- a/drivers/scsi/hosts.h
+++ b/drivers/scsi/hosts.h
@@ -280,17 +280,12 @@ typedef struct SHT
unsigned use_clustering:1;
/*
- * True if this driver uses the new error handling code. This flag is
- * really only temporary until all of the other drivers get converted
- * to use the new error handling code.
- */
- unsigned use_new_eh_code:1;
-
- /*
* True for emulated SCSI host adapters (e.g. ATAPI)
*/
unsigned emulated:1;
+ unsigned highmem_io:1;
+
/*
* Name of proc directory
*/
@@ -317,6 +312,7 @@ struct Scsi_Host
struct Scsi_Host * next;
Scsi_Device * host_queue;
+ spinlock_t host_lock;
struct task_struct * ehandler; /* Error recovery thread. */
struct semaphore * eh_wait; /* The error recovery thread waits on
@@ -390,6 +386,7 @@ struct Scsi_Host
unsigned in_recovery:1;
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
+ unsigned highmem_io:1;
/*
* True if this host was loaded as a loadable module
*/
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 576cbdb9a..d52e503fb 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -235,13 +235,13 @@ static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
kfree(atapi_buf);
}
-static inline void idescsi_free_bh (struct buffer_head *bh)
+static inline void idescsi_free_bio (struct bio *bio)
{
- struct buffer_head *bhp;
+ struct bio *bhp;
- while (bh) {
- bhp = bh;
- bh = bh->b_reqnext;
+ while (bio) {
+ bhp = bio;
+ bio = bio->bi_next;
kfree (bhp);
}
}
@@ -263,10 +263,11 @@ static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
struct request *rq = hwgroup->rq;
idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
+ struct Scsi_Host *host;
u8 *scsi_buf;
unsigned long flags;
- if (rq->cmd != IDESCSI_PC_RQ) {
+ if (!(rq->flags & REQ_SPECIAL)) {
ide_end_request (uptodate, hwgroup);
return;
}
@@ -291,10 +292,11 @@ static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
} else printk("\n");
}
}
- spin_lock_irqsave(&io_request_lock,flags);
+ host = pc->scsi_cmd->host;
+ spin_lock_irqsave(&host->host_lock, flags);
pc->done(pc->scsi_cmd);
- spin_unlock_irqrestore(&io_request_lock,flags);
- idescsi_free_bh (rq->bh);
+ spin_unlock_irqrestore(&host->host_lock, flags);
+ idescsi_free_bio (rq->bio);
kfree(pc); kfree(rq);
scsi->pc = NULL;
}
@@ -427,7 +429,7 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
pc->current_position=pc->buffer;
bcount = IDE_MIN (pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */
- if (drive->using_dma && rq->bh)
+ if (drive->using_dma && rq->bio)
dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
SELECT_DRIVE(HWIF(drive), drive);
@@ -461,10 +463,10 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDESCSI_DEBUG_LOG */
- if (rq->cmd == IDESCSI_PC_RQ) {
+ if (rq->flags & REQ_SPECIAL) {
return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->buffer);
}
- printk (KERN_ERR "ide-scsi: %s: unsupported command in request queue (%x)\n", drive->name, rq->cmd);
+ blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request (0,HWGROUP (drive));
return ide_stopped;
}
@@ -653,25 +655,25 @@ int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
return -EINVAL;
}
-static inline struct buffer_head *idescsi_kmalloc_bh (int count)
+static inline struct bio *idescsi_kmalloc_bio (int count)
{
- struct buffer_head *bh, *bhp, *first_bh;
+ struct bio *bh, *bhp, *first_bh;
- if ((first_bh = bhp = bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL)
+ if ((first_bh = bhp = bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
goto abort;
- memset (bh, 0, sizeof (struct buffer_head));
- bh->b_reqnext = NULL;
+ bio_init(bh);
while (--count) {
- if ((bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL)
+ if ((bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
goto abort;
- memset (bh, 0, sizeof (struct buffer_head));
- bhp->b_reqnext = bh;
+ bio_init(bh);
+ bh->bi_vcnt = 1;
+ bhp->bi_next = bh;
bhp = bh;
- bh->b_reqnext = NULL;
+ bh->bi_next = NULL;
}
return first_bh;
abort:
- idescsi_free_bh (first_bh);
+ idescsi_free_bio (first_bh);
return NULL;
}
@@ -689,9 +691,9 @@ static inline int idescsi_set_direction (idescsi_pc_t *pc)
}
}
-static inline struct buffer_head *idescsi_dma_bh (ide_drive_t *drive, idescsi_pc_t *pc)
+static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
{
- struct buffer_head *bh = NULL, *first_bh = NULL;
+ struct bio *bh = NULL, *first_bh = NULL;
int segments = pc->scsi_cmd->use_sg;
struct scatterlist *sg = pc->scsi_cmd->request_buffer;
@@ -700,25 +702,43 @@ static inline struct buffer_head *idescsi_dma_bh (ide_drive_t *drive, idescsi_pc
if (idescsi_set_direction(pc))
return NULL;
if (segments) {
- if ((first_bh = bh = idescsi_kmalloc_bh (segments)) == NULL)
+ if ((first_bh = bh = idescsi_kmalloc_bio (segments)) == NULL)
return NULL;
#if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10);
#endif /* IDESCSI_DEBUG_LOG */
while (segments--) {
- bh->b_data = sg->address;
- bh->b_size = sg->length;
- bh = bh->b_reqnext;
+ struct page *page = sg->page;
+ int offset = sg->offset;
+
+ if (!page) {
+ BUG_ON(!sg->address);
+ page = virt_to_page(sg->address);
+ offset = (unsigned long) sg->address & ~PAGE_MASK;
+ }
+
+ bh->bi_io_vec[0].bv_page = page;
+ bh->bi_io_vec[0].bv_len = sg->length;
+ bh->bi_io_vec[0].bv_offset = offset;
+ bh->bi_size = sg->length;
+ bh = bh->bi_next;
+ /*
+ * just until scsi_merge is fixed up...
+ */
+ BUG_ON(PageHighMem(page));
+ sg->address = page_address(page) + offset;
sg++;
}
} else {
- if ((first_bh = bh = idescsi_kmalloc_bh (1)) == NULL)
+ if ((first_bh = bh = idescsi_kmalloc_bio (1)) == NULL)
return NULL;
#if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10);
#endif /* IDESCSI_DEBUG_LOG */
- bh->b_data = pc->scsi_cmd->request_buffer;
- bh->b_size = pc->request_transfer;
+ bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer);
+ bh->bi_io_vec[0].bv_len = pc->request_transfer;
+ bh->bi_io_vec[0].bv_offset = (unsigned long) pc->scsi_cmd->request_buffer & ~PAGE_MASK;
+ bh->bi_size = pc->request_transfer;
}
return first_bh;
}
@@ -783,11 +803,11 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
ide_init_drive_cmd (rq);
rq->buffer = (char *) pc;
- rq->bh = idescsi_dma_bh (drive, pc);
- rq->cmd = IDESCSI_PC_RQ;
- spin_unlock_irq(&io_request_lock);
+ rq->bio = idescsi_dma_bio (drive, pc);
+ rq->flags = REQ_SPECIAL;
+ spin_unlock(&cmd->host->host_lock);
(void) ide_do_drive_cmd (drive, rq, ide_end);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&cmd->host->host_lock);
return 0;
abort:
if (pc) kfree (pc);
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 9290a59c0..933d02eb8 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -124,11 +124,6 @@ int imm_detect(Scsi_Host_Template * host)
int i, nhosts, try_again;
struct parport *pb;
- /*
- * unlock to allow the lowlevel parport driver to probe
- * the irqs
- */
- spin_unlock_irq(&io_request_lock);
pb = parport_enumerate();
printk("imm: Version %s\n", IMM_VERSION);
@@ -137,7 +132,6 @@ int imm_detect(Scsi_Host_Template * host)
if (!pb) {
printk("imm: parport reports no devices.\n");
- spin_lock_irq(&io_request_lock);
return 0;
}
retry_entry:
@@ -163,7 +157,6 @@ int imm_detect(Scsi_Host_Template * host)
"pardevice is owning the port for too longtime!\n",
i);
parport_unregister_device (imm_hosts[i].dev);
- spin_lock_irq(&io_request_lock);
return 0;
}
}
@@ -219,13 +212,11 @@ int imm_detect(Scsi_Host_Template * host)
}
if (nhosts == 0) {
if (try_again == 1) {
- spin_lock_irq(&io_request_lock);
return 0;
}
try_again = 1;
goto retry_entry;
} else {
- spin_lock_irq (&io_request_lock);
return 1; /* return number of hosts detected */
}
}
@@ -834,7 +825,7 @@ static int imm_completion(Scsi_Cmnd * cmd)
if (cmd->SCp.buffers_residual--) {
cmd->SCp.buffer++;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
+ cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
/*
* Make sure that we transfer even number of bytes
@@ -897,6 +888,7 @@ static void imm_interrupt(void *data)
{
imm_struct *tmp = (imm_struct *) data;
Scsi_Cmnd *cmd = tmp->cur_cmd;
+ struct Scsi_Host *host = cmd->host;
unsigned long flags;
if (!cmd) {
@@ -948,10 +940,10 @@ static void imm_interrupt(void *data)
if (cmd->SCp.phase > 0)
imm_pb_release(cmd->host->unique_id);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
tmp->cur_cmd = 0;
cmd->scsi_done(cmd);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
return;
}
@@ -1008,7 +1000,7 @@ static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd)
/* if many buffers are available, start filling the first */
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
+ cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
} else {
/* else fill the only available buffer */
cmd->SCp.buffer = NULL;
diff --git a/drivers/scsi/imm.h b/drivers/scsi/imm.h
index 9fff312a0..ab3c8a71c 100644
--- a/drivers/scsi/imm.h
+++ b/drivers/scsi/imm.h
@@ -175,7 +175,6 @@ int imm_biosparam(Disk *, kdev_t, int *);
eh_device_reset_handler: NULL, \
eh_bus_reset_handler: imm_reset, \
eh_host_reset_handler: imm_reset, \
- use_new_eh_code: 1, \
bios_param: imm_biosparam, \
this_id: 7, \
sg_tablesize: SG_ALL, \
diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
index 2b7121a9b..7fe39c451 100644
--- a/drivers/scsi/in2000.h
+++ b/drivers/scsi/in2000.h
@@ -423,7 +423,6 @@ int in2000_reset(Scsi_Cmnd *, unsigned int);
sg_tablesize: IN2000_SG, /* scatter-gather table size */ \
cmd_per_lun: IN2000_CPL, /* commands per lun */ \
use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \
- use_new_eh_code: 0 /* new error code - not using it yet */ \
}
#endif /* IN2000_H */
diff --git a/drivers/scsi/ini9100u.h b/drivers/scsi/ini9100u.h
index 910ea9aaf..557518771 100644
--- a/drivers/scsi/ini9100u.h
+++ b/drivers/scsi/ini9100u.h
@@ -115,7 +115,6 @@ extern int i91u_biosparam(Scsi_Disk *, kdev_t, int *); /*for linux v2.0 */
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
#define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i))
diff --git a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h
index b965af037..9c2ade883 100644
--- a/drivers/scsi/inia100.h
+++ b/drivers/scsi/inia100.h
@@ -110,7 +110,6 @@ extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *); /*for linux v2.0 */
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
#define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i))
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 514055e16..b0431ced9 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -472,7 +472,6 @@
present : 0, \
unchecked_isa_dma : 0, \
use_clustering : ENABLE_CLUSTERING, \
- use_new_eh_code : 1 \
}
#endif
diff --git a/drivers/scsi/mac53c94.h b/drivers/scsi/mac53c94.h
index 171eeb148..ee57f4bc6 100644
--- a/drivers/scsi/mac53c94.h
+++ b/drivers/scsi/mac53c94.h
@@ -28,7 +28,6 @@ int mac53c94_reset(Scsi_Cmnd *, unsigned int);
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, \
use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 1, \
}
/*
diff --git a/drivers/scsi/mac_esp.h b/drivers/scsi/mac_esp.h
index 4d17f665c..bcc497ee6 100644
--- a/drivers/scsi/mac_esp.h
+++ b/drivers/scsi/mac_esp.h
@@ -34,8 +34,7 @@ extern int esp_reset(Scsi_Cmnd *, unsigned int);
this_id: 7, \
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, \
- use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 0 }
+ use_clustering: DISABLE_CLUSTERING }
#endif /* MAC_ESP_H */
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 643fd3b03..e8acc9e46 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -586,8 +586,10 @@ MODULE_LICENSE ("GPL");
#define DRIVER_LOCK(p)
#define DRIVER_UNLOCK(p)
#define IO_LOCK_T unsigned long io_flags = 0
-#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
-#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
+#define IO_LOCK(host) spin_lock_irqsave(&(host)->host_lock,io_flags)
+#define IO_UNLOCK(host) spin_unlock_irqrestore(&(host)->host_lock,io_flags)
+#define IO_LOCK_IRQ(host) spin_lock_irq(&(host)->host_lock)
+#define IO_UNLOCK_IRQ(host) spin_unlock_irq(&(host)->host_lock)
#define queue_task_irq(a,b) queue_task(a,b)
#define queue_task_irq_off(a,b) queue_task(a,b)
@@ -612,8 +614,8 @@ MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
#define DRIVER_LOCK(p)
#define DRIVER_UNLOCK(p)
#define IO_LOCK_T unsigned long io_flags = 0
-#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
-#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
+#define IO_LOCK(host) spin_lock_irqsave(&io_request_lock,io_flags);
+#define IO_UNLOCK(host) spin_unlock_irqrestore(&io_request_lock,io_flags);
#define pci_free_consistent(a,b,c,d)
#define pci_unmap_single(a,b,c,d)
@@ -2101,7 +2103,7 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
completed[idx] = 0;
- IO_LOCK;
+ IO_LOCK(megaCfg->host);
megaCfg->nInterrupts++;
qCnt = 0xff;
@@ -2220,7 +2222,7 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
megaCfg->flag &= ~IN_ISR;
/* Loop through any pending requests */
mega_runpendq (megaCfg);
- IO_UNLOCK;
+ IO_UNLOCK(megaCfg->host);
}
@@ -3032,9 +3034,7 @@ static int mega_findCard (Scsi_Host_Template * pHostTmpl,
sizeof (mega_mailbox64),
&(megaCfg->dma_handle64));
- mega_register_mailbox (megaCfg,
- virt_to_bus ((void *) megaCfg->
- mailbox64ptr));
+ mega_register_mailbox (megaCfg, megaCfg->dma_handle64);
#else
mega_register_mailbox (megaCfg,
virt_to_bus ((void *) &megaCfg->
@@ -3800,7 +3800,7 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
init_MUTEX_LOCKED (&pScb->ioctl_sem);
- spin_unlock_irq (&io_request_lock);
+ IO_UNLOCK_IRQ(megaCfg->host);
down (&pScb->ioctl_sem);
user_area = (char *)*((u32*)&pScb->SCpnt->cmnd[4]);
if (copy_to_user
@@ -3809,7 +3809,7 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
("megaraid: Error copying ioctl return value to user buffer.\n");
pScb->SCpnt->result = (DID_ERROR << 16);
}
- spin_lock_irq (&io_request_lock);
+ IO_LOCK_IRQ(megaCfg->host);
DRIVER_LOCK (megaCfg);
kfree (pScb->buff_ptr);
pScb->buff_ptr = NULL;
@@ -4736,10 +4736,10 @@ static int megadev_ioctl (struct inode *inode, struct file *filep,
init_MUTEX_LOCKED(&mimd_ioctl_sem);
- IO_LOCK;
+ IO_LOCK(shpnt);
megaraid_queue(scsicmd, megadev_ioctl_done);
- IO_UNLOCK;
+ IO_UNLOCK(shpnt);
down(&mimd_ioctl_sem);
@@ -4885,10 +4885,10 @@ static int megadev_ioctl (struct inode *inode, struct file *filep,
init_MUTEX_LOCKED (&mimd_ioctl_sem);
- IO_LOCK;
+ IO_LOCK(shpnt);
megaraid_queue (scsicmd, megadev_ioctl_done);
- IO_UNLOCK;
+ IO_UNLOCK(shpnt);
down (&mimd_ioctl_sem);
if (!scsicmd->result && outlen) {
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 807168704..31183c3e5 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -223,7 +223,8 @@
cmd_per_lun: MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\
present: 0, /* Present */\
unchecked_isa_dma: 0, /* Default Unchecked ISA DMA */\
- use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\
+ use_clustering: ENABLE_CLUSTERING, /* Enable Clustering */\
+ highmem_io: 1, \
}
#endif
diff --git a/drivers/scsi/mesh.h b/drivers/scsi/mesh.h
index 19b2c9fc9..c2bb18100 100644
--- a/drivers/scsi/mesh.h
+++ b/drivers/scsi/mesh.h
@@ -28,7 +28,6 @@ int mesh_reset(Scsi_Cmnd *, unsigned int);
sg_tablesize: SG_ALL, \
cmd_per_lun: 2, \
use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 1, \
}
/*
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index 15652ca9f..fe990d4e9 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -218,7 +218,6 @@ int Pci2000_BiosParam (Disk *disk, kdev_t dev, int geom[]);
present: 0, \
unchecked_isa_dma:0, \
use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code:0 \
}
#endif
diff --git a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h
index 689e62573..e7aad4d95 100644
--- a/drivers/scsi/pci2220i.h
+++ b/drivers/scsi/pci2220i.h
@@ -56,6 +56,5 @@ int Pci2220i_BiosParam (Disk *disk, kdev_t dev, int geom[]);
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
#endif
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index dcfaabfcc..becd0ac8c 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -149,7 +149,6 @@ static Scsi_Host_Template driver_template = {
/* present: 0,*/
/* unchecked_isa_dma: 0,*/
use_clustering: DISABLE_CLUSTERING,
- use_new_eh_code: 0,
/* emulated: 0,*/
};
diff --git a/drivers/scsi/pluto.h b/drivers/scsi/pluto.h
index d965f5cd8..01d34564f 100644
--- a/drivers/scsi/pluto.h
+++ b/drivers/scsi/pluto.h
@@ -53,7 +53,6 @@ const char * pluto_info(struct Scsi_Host *);
sg_tablesize: 1, \
cmd_per_lun: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: FCP_SCSI_USE_NEW_EH_CODE, \
abort: fcp_old_abort, \
eh_abort_handler: fcp_scsi_abort, \
eh_device_reset_handler:fcp_scsi_dev_reset, \
diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h
index 9932cf3dc..7479092b9 100644
--- a/drivers/scsi/ppa.h
+++ b/drivers/scsi/ppa.h
@@ -183,7 +183,6 @@ int ppa_biosparam(Disk *, kdev_t, int *);
eh_device_reset_handler: NULL, \
eh_bus_reset_handler: ppa_reset, \
eh_host_reset_handler: ppa_reset, \
- use_new_eh_code: 1, \
bios_param: ppa_biosparam, \
this_id: -1, \
sg_tablesize: SG_ALL, \
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
index 9dc200174..4fd71135e 100644
--- a/drivers/scsi/qla1280.h
+++ b/drivers/scsi/qla1280.h
@@ -1726,7 +1726,6 @@ void qla1280_setup(char *s, int *dummy);
present: 0, /* number of 7xxx's present */\
unchecked_isa_dma: 0, /* no memory DMA restrictions */\
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0, \
emulated: 0 \
}
#endif
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
index d0291f28e..0a6795243 100644
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -734,7 +734,6 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
scsi_set_pci_device(host, pdev);
host->max_id = QLOGICFC_MAX_ID + 1;
host->max_lun = QLOGICFC_MAX_LUN;
- host->hostt->use_new_eh_code = 1;
hostdata = (struct isp2x00_hostdata *) host->hostdata;
memset(hostdata, 0, sizeof(struct isp2x00_hostdata));
@@ -1376,7 +1375,7 @@ static void redo_port_db(unsigned long arg)
hostdata->explore_timer.data = 0;
del_timer(&hostdata->explore_timer);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) {
isp2x00_make_portdb(host);
@@ -1423,7 +1422,7 @@ static void redo_port_db(unsigned long arg)
hostdata->adapter_state = AS_LOOP_GOOD;
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
}
@@ -1431,11 +1430,12 @@ static void redo_port_db(unsigned long arg)
void do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
+ struct Scsi_Host *host = dev_id;
unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
isp2x00_intr_handler(irq, dev_id, regs);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
}
void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
@@ -2042,10 +2042,7 @@ static int isp2x00_init(struct Scsi_Host *sh)
return 1;
}
- if (!(command & PCI_COMMAND_MASTER)) {
- printk("qlogicfc%d : bus mastering is disabled\n", hostdata->host_id);
- return 1;
- }
+ pci_set_master(pdev);
if (revision != ISP2100_REV_ID1 && revision != ISP2100_REV_ID3 && revision != ISP2200_REV_ID5)
printk("qlogicfc%d : new isp2x00 revision ID (%d)\n", hostdata->host_id, revision);
diff --git a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h
index 8128e9913..d8831ccb2 100644
--- a/drivers/scsi/qlogicfc.h
+++ b/drivers/scsi/qlogicfc.h
@@ -95,7 +95,8 @@ int isp2x00_biosparam(Disk *, kdev_t, int[]);
cmd_per_lun: QLOGICFC_CMD_PER_LUN, \
present: 0, \
unchecked_isa_dma: 0, \
- use_clustering: ENABLE_CLUSTERING \
+ use_clustering: ENABLE_CLUSTERING, \
+ highmem_io: 1 \
}
#endif /* _QLOGICFC_H */
diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c
index 31d2bae30..bc761211b 100644
--- a/drivers/scsi/qlogicisp.c
+++ b/drivers/scsi/qlogicisp.c
@@ -970,11 +970,12 @@ int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
void do_isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
+ struct Scsi_Host *host = dev_id;
unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
isp1020_intr_handler(irq, dev_id, regs);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
}
void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
@@ -1403,11 +1404,6 @@ static int isp1020_init(struct Scsi_Host *sh)
command &= ~PCI_COMMAND_MEMORY;
#endif
- if (!(command & PCI_COMMAND_MASTER)) {
- printk("qlogicisp : bus mastering is disabled\n");
- return 1;
- }
-
sh->io_port = io_base;
if (!request_region(sh->io_port, 0xff, "qlogicisp")) {
@@ -1472,6 +1468,8 @@ static int isp1020_init(struct Scsi_Host *sh)
goto out_unmap;
}
+ pci_set_master(pdev);
+
LEAVE("isp1020_init");
return 0;
diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h
index 5f9cf31db..6c49ea1df 100644
--- a/drivers/scsi/qlogicpti.h
+++ b/drivers/scsi/qlogicpti.h
@@ -524,7 +524,7 @@ struct qlogicpti {
sg_tablesize: QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN), \
cmd_per_lun: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
+ highmem_io: 1, \
}
/* For our interrupt engine. */
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index d156c7dcd..db5ec9c27 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -151,14 +151,6 @@ extern void scsi_times_out(Scsi_Cmnd * SCpnt);
void scsi_build_commandblocks(Scsi_Device * SDpnt);
/*
- * These are the interface to the old error handling code. It should go away
- * someday soon.
- */
-extern void scsi_old_done(Scsi_Cmnd * SCpnt);
-extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
-
-
-/*
* Function: scsi_initialize_queue()
*
* Purpose: Selects queue handler function for a device.
@@ -186,10 +178,21 @@ extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
* handler in the list - ultimately they call scsi_request_fn
* to do the dirty deed.
*/
-void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) {
- blk_init_queue(&SDpnt->request_queue, scsi_request_fn);
- blk_queue_headactive(&SDpnt->request_queue, 0);
- SDpnt->request_queue.queuedata = (void *) SDpnt;
+void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt)
+{
+ request_queue_t *q = &SDpnt->request_queue;
+
+ blk_init_queue(q, scsi_request_fn);
+ q->queuedata = (void *) SDpnt;
+#ifdef DMA_CHUNK_SIZE
+ blk_queue_max_segments(q, 64);
+#else
+ blk_queue_max_segments(q, SHpnt->sg_tablesize);
+#endif
+ blk_queue_max_sectors(q, SHpnt->max_sectors);
+
+ if (!SHpnt->use_clustering)
+ clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
}
#ifdef MODULE
@@ -227,9 +230,8 @@ static void scsi_wait_done(Scsi_Cmnd * SCpnt)
req = &SCpnt->request;
req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
- if (req->waiting != NULL) {
+ if (req->waiting)
complete(req->waiting);
- }
}
/*
@@ -620,8 +622,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
unsigned long flags = 0;
unsigned long timeout;
- ASSERT_LOCK(&io_request_lock, 0);
-
#if DEBUG
unsigned long *ret = 0;
#ifdef __mips__
@@ -633,6 +633,8 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
host = SCpnt->host;
+ ASSERT_LOCK(&host->host_lock, 0);
+
/* Assign a unique nonzero serial_number. */
if (++serial_number == 0)
serial_number = 1;
@@ -660,12 +662,8 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
mdelay(1 + 999 / HZ);
host->resetting = 0;
}
- if (host->hostt->use_new_eh_code) {
- scsi_add_timer(SCpnt, SCpnt->timeout_per_command, scsi_times_out);
- } else {
- scsi_add_timer(SCpnt, SCpnt->timeout_per_command,
- scsi_old_times_out);
- }
+
+ scsi_add_timer(SCpnt, SCpnt->timeout_per_command, scsi_times_out);
/*
* We will use a queued command if possible, otherwise we will emulate the
@@ -682,59 +680,37 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n",
host->hostt->queuecommand));
/*
- * Use the old error handling code if we haven't converted the driver
- * to use the new one yet. Note - only the new queuecommand variant
- * passes a meaningful return value.
+ * Before we queue this command, check if the command
+ * length exceeds what the host adapter can handle.
*/
- if (host->hostt->use_new_eh_code) {
- /*
- * Before we queue this command, check if the command
- * length exceeds what the host adapter can handle.
- */
- if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) {
- spin_lock_irqsave(&io_request_lock, flags);
- rtn = host->hostt->queuecommand(SCpnt, scsi_done);
- spin_unlock_irqrestore(&io_request_lock, flags);
- if (rtn != 0) {
- scsi_delete_timer(SCpnt);
- scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_HOST_BUSY);
- SCSI_LOG_MLQUEUE(3, printk("queuecommand : request rejected\n"));
- }
- } else {
- SCSI_LOG_MLQUEUE(3, printk("queuecommand : command too long.\n"));
- SCpnt->result = (DID_ABORT << 16);
- spin_lock_irqsave(&io_request_lock, flags);
- scsi_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
- rtn = 1;
+ if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) {
+ spin_lock_irqsave(&host->host_lock, flags);
+ rtn = host->hostt->queuecommand(SCpnt, scsi_done);
+ spin_unlock_irqrestore(&host->host_lock, flags);
+ if (rtn != 0) {
+ scsi_delete_timer(SCpnt);
+ scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_HOST_BUSY);
+ SCSI_LOG_MLQUEUE(3,
+ printk("queuecommand : request rejected\n"));
}
} else {
- /*
- * Before we queue this command, check if the command
- * length exceeds what the host adapter can handle.
- */
- if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) {
- spin_lock_irqsave(&io_request_lock, flags);
- host->hostt->queuecommand(SCpnt, scsi_old_done);
- spin_unlock_irqrestore(&io_request_lock, flags);
- } else {
- SCSI_LOG_MLQUEUE(3, printk("queuecommand : command too long.\n"));
- SCpnt->result = (DID_ABORT << 16);
- spin_lock_irqsave(&io_request_lock, flags);
- scsi_old_done(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
- rtn = 1;
- }
+ SCSI_LOG_MLQUEUE(3,
+ printk("queuecommand : command too long.\n"));
+ SCpnt->result = (DID_ABORT << 16);
+ spin_lock_irqsave(&host->host_lock, flags);
+ scsi_done(SCpnt);
+ spin_unlock_irqrestore(&host->host_lock, flags);
+ rtn = 1;
}
} else {
int temp;
SCSI_LOG_MLQUEUE(3, printk("command() : routine at %p\n", host->hostt->command));
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
temp = host->hostt->command(SCpnt);
SCpnt->result = temp;
#ifdef DEBUG_DELAY
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
clock = jiffies + 4 * HZ;
while (time_before(jiffies, clock)) {
barrier();
@@ -742,14 +718,10 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
}
printk("done(host = %d, result = %04x) : routine at %p\n",
host->host_no, temp, host->hostt->command);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
#endif
- if (host->hostt->use_new_eh_code) {
- scsi_done(SCpnt);
- } else {
- scsi_old_done(SCpnt);
- }
- spin_unlock_irqrestore(&io_request_lock, flags);
+ scsi_done(SCpnt);
+ spin_unlock_irqrestore(&host->host_lock, flags);
}
SCSI_LOG_MLQUEUE(3, printk("leaving scsi_dispatch_cmnd()\n"));
return rtn;
@@ -819,7 +791,7 @@ void scsi_do_req(Scsi_Request * SRpnt, const void *cmnd,
Scsi_Device * SDpnt = SRpnt->sr_device;
struct Scsi_Host *host = SDpnt->host;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&host->host_lock, 0);
SCSI_LOG_MLQUEUE(4,
{
@@ -916,7 +888,7 @@ void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt)
{
struct Scsi_Host *host = SCpnt->host;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&host->host_lock, 0);
SCpnt->owner = SCSI_OWNER_MIDLEVEL;
SRpnt->sr_command = SCpnt;
@@ -1006,7 +978,7 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
{
struct Scsi_Host *host = SCpnt->host;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&host->host_lock, 0);
SCpnt->pid = scsi_pid++;
SCpnt->owner = SCSI_OWNER_MIDLEVEL;
@@ -1357,11 +1329,11 @@ void scsi_finish_command(Scsi_Cmnd * SCpnt)
Scsi_Request * SRpnt;
unsigned long flags;
- ASSERT_LOCK(&io_request_lock, 0);
-
host = SCpnt->host;
device = SCpnt->device;
+ ASSERT_LOCK(&host->host_lock, 0);
+
/*
* We need to protect the decrement, as otherwise a race condition
* would exist. Fiddling with SCpnt isn't a problem as the
@@ -1369,10 +1341,10 @@ void scsi_finish_command(Scsi_Cmnd * SCpnt)
* one execution context, but the device and host structures are
* shared.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
host->host_busy--; /* Indicate that we are free */
device->device_busy--; /* Decrement device usage counter. */
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
/*
* Clear the flags which say that the device/host is no longer
@@ -1860,7 +1832,6 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
Scsi_Device *SDpnt;
struct Scsi_Device_Template *sdtpnt;
const char *name;
- unsigned long flags;
int out_of_space = 0;
if (tpnt->next || !tpnt->detect)
@@ -1870,7 +1841,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
/* If max_sectors isn't set, default to max */
if (!tpnt->max_sectors)
- tpnt->max_sectors = MAX_SECTORS;
+ tpnt->max_sectors = 1024;
pcount = next_scsi_host;
@@ -1878,18 +1849,12 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
/* The detect routine must carefully spinunlock/spinlock if
it enables interrupts, since all interrupt handlers do
- spinlock as well.
- All lame drivers are going to fail due to the following
- spinlock. For the time beeing let's use it only for drivers
- using the new scsi code. NOTE: the detect routine could
- redefine the value tpnt->use_new_eh_code. (DB, 13 May 1998) */
-
- if (tpnt->use_new_eh_code) {
- spin_lock_irqsave(&io_request_lock, flags);
- tpnt->present = tpnt->detect(tpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
- } else
- tpnt->present = tpnt->detect(tpnt);
+ spinlock as well. */
+
+ /*
+ * detect should do its own locking
+ */
+ tpnt->present = tpnt->detect(tpnt);
if (tpnt->present) {
if (pcount == next_scsi_host) {
@@ -1923,7 +1888,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
* handle error correction.
*/
for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
- if (shpnt->hostt == tpnt && shpnt->hostt->use_new_eh_code) {
+ if (shpnt->hostt == tpnt) {
DECLARE_MUTEX_LOCKED(sem);
shpnt->eh_notify = &sem;
@@ -2131,7 +2096,6 @@ static int scsi_unregister_host(Scsi_Host_Template * tpnt)
*/
for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
if (shpnt->hostt == tpnt
- && shpnt->hostt->use_new_eh_code
&& shpnt->ehandler != NULL) {
DECLARE_MUTEX_LOCKED(sem);
diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
index 7b434522f..3e6b1c3b3 100644
--- a/drivers/scsi/scsi.h
+++ b/drivers/scsi/scsi.h
@@ -386,15 +386,6 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#define ASKED_FOR_SENSE 0x20
#define SYNC_RESET 0x40
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#include <asm/pgtable.h>
-#define CONTIGUOUS_BUFFERS(X,Y) \
- (virt_to_phys((X)->b_data+(X)->b_size-1)+1==virt_to_phys((Y)->b_data))
-#else
-#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
-#endif
-
-
/*
* This is the crap from the old error handling code. We have it in a special
* place so that we can more easily delete it later on.
diff --git a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h
index 357b3f5fc..b0135317a 100644
--- a/drivers/scsi/scsi_debug.h
+++ b/drivers/scsi/scsi_debug.h
@@ -37,6 +37,5 @@ int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
cmd_per_lun: 3, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1, \
}
#endif
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 91a1e0258..af0bb409c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -423,8 +423,6 @@ STATIC int scsi_request_sense(Scsi_Cmnd * SCpnt)
unsigned char scsi_result0[256], *scsi_result = NULL;
int saved_result;
- ASSERT_LOCK(&io_request_lock, 0);
-
memcpy((void *) SCpnt->cmnd, (void *) generic_sense,
sizeof(generic_sense));
@@ -583,16 +581,14 @@ void scsi_sleep(int timeout)
STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
{
unsigned long flags;
- struct Scsi_Host *host;
-
- ASSERT_LOCK(&io_request_lock, 0);
+ struct Scsi_Host *host = SCpnt->host;
- host = SCpnt->host;
+ ASSERT_LOCK(&host->host_lock, 0);
- retry:
+retry:
/*
- * We will use a queued command if possible, otherwise we will emulate the
- * queuing and calling of completion function ourselves.
+ * We will use a queued command if possible, otherwise we will
+ * emulate the queuing and calling of completion function ourselves.
*/
SCpnt->owner = SCSI_OWNER_LOWLEVEL;
@@ -609,9 +605,9 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
SCpnt->host->eh_action = &sem;
SCpnt->request.rq_status = RQ_SCSI_BUSY;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
host->hostt->queuecommand(SCpnt, scsi_eh_done);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
down(&sem);
@@ -634,10 +630,10 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
* abort a timed out command or not. Not sure how
* we should treat them differently anyways.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
if (SCpnt->host->hostt->eh_abort_handler)
SCpnt->host->hostt->eh_abort_handler(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
SCpnt->request.rq_status = RQ_SCSI_DONE;
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
@@ -650,13 +646,13 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
int temp;
/*
- * We damn well had better never use this code. There is no timeout
- * protection here, since we would end up waiting in the actual low
- * level driver, we don't know how to wake it up.
+ * We damn well had better never use this code. There is no
+ * timeout protection here, since we would end up waiting in
+ * the actual low level driver, we don't know how to wake it up.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
temp = host->hostt->command(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
SCpnt->result = temp;
/* Fall through to code below to examine status. */
@@ -664,8 +660,8 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
}
/*
- * Now examine the actual status codes to see whether the command actually
- * did complete normally.
+ * Now examine the actual status codes to see whether the command
+ * actually did complete normally.
*/
if (SCpnt->eh_state == SUCCESS) {
int ret = scsi_eh_completed_normally(SCpnt);
@@ -776,9 +772,9 @@ STATIC int scsi_try_to_abort_command(Scsi_Cmnd * SCpnt, int timeout)
SCpnt->owner = SCSI_OWNER_LOWLEVEL;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
rtn = SCpnt->host->hostt->eh_abort_handler(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
return rtn;
}
@@ -808,9 +804,9 @@ STATIC int scsi_try_bus_device_reset(Scsi_Cmnd * SCpnt, int timeout)
}
SCpnt->owner = SCSI_OWNER_LOWLEVEL;
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
rtn = SCpnt->host->hostt->eh_device_reset_handler(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
if (rtn == SUCCESS)
SCpnt->eh_state = SUCCESS;
@@ -841,9 +837,9 @@ STATIC int scsi_try_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
rtn = SCpnt->host->hostt->eh_bus_reset_handler(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
if (rtn == SUCCESS)
SCpnt->eh_state = SUCCESS;
@@ -887,9 +883,9 @@ STATIC int scsi_try_host_reset(Scsi_Cmnd * SCpnt)
if (SCpnt->host->hostt->eh_host_reset_handler == NULL) {
return FAILED;
}
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&SCpnt->host->host_lock, flags);
rtn = SCpnt->host->hostt->eh_host_reset_handler(SCpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&SCpnt->host->host_lock, flags);
if (rtn == SUCCESS)
SCpnt->eh_state = SUCCESS;
@@ -1230,7 +1226,7 @@ STATIC void scsi_restart_operations(struct Scsi_Host *host)
Scsi_Device *SDpnt;
unsigned long flags;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&host->host_lock, 0);
/*
* Next free up anything directly waiting upon the host. This will be
@@ -1247,19 +1243,22 @@ STATIC void scsi_restart_operations(struct Scsi_Host *host)
* now that error recovery is done, we will need to ensure that these
* requests are started.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
- request_queue_t *q;
+ request_queue_t *q = &SDpnt->request_queue;
+
if ((host->can_queue > 0 && (host->host_busy >= host->can_queue))
|| (host->host_blocked)
|| (host->host_self_blocked)
|| (SDpnt->device_blocked)) {
break;
}
- q = &SDpnt->request_queue;
+
+ spin_lock(&q->queue_lock);
q->request_fn(q);
+ spin_unlock(&q->queue_lock);
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
}
/*
@@ -1306,7 +1305,7 @@ STATIC int scsi_unjam_host(struct Scsi_Host *host)
Scsi_Cmnd *SCdone;
int timed_out;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&host->host_lock, 0);
SCdone = NULL;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 2bb52ad2b..a723b3404 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -61,7 +61,7 @@
* data - private data
* at_head - insert request at head or tail of queue
*
- * Lock status: Assumed that io_request_lock is not held upon entry.
+ * Lock status: Assumed that queue lock is not held upon entry.
*
* Returns: Nothing
*/
@@ -70,11 +70,18 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
{
unsigned long flags;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&q->queue_lock, 0);
+
+ /*
+ * tell I/O scheduler that this isn't a regular read/write (ie it
+ * must not attempt merges on this) and that it acts as a soft
+ * barrier
+ */
+ rq->flags = REQ_SPECIAL | REQ_BARRIER;
- rq->cmd = SPECIAL;
rq->special = data;
rq->q = NULL;
+ rq->bio = rq->biotail = NULL;
rq->nr_segments = 0;
rq->elevator_sequence = 0;
@@ -84,15 +91,10 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
* head of the queue for things like a QUEUE_FULL message from a
* device, or a host that is unable to accept a particular command.
*/
- spin_lock_irqsave(&io_request_lock, flags);
-
- if (at_head)
- list_add(&rq->queue, &q->queue_head);
- else
- list_add_tail(&rq->queue, &q->queue_head);
-
+ spin_lock_irqsave(&q->queue_lock, flags);
+ __elv_add_request(q, rq, !at_head, 0);
q->request_fn(q);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
}
@@ -167,8 +169,6 @@ int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head)
*/
int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt)
{
- ASSERT_LOCK(&io_request_lock, 0);
-
SCpnt->owner = SCSI_OWNER_MIDLEVEL;
SCpnt->reset_chain = NULL;
SCpnt->serial_number = 0;
@@ -250,9 +250,9 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
Scsi_Device *SDpnt;
struct Scsi_Host *SHpnt;
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&q->queue_lock, 0);
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&q->queue_lock, flags);
if (SCpnt != NULL) {
/*
@@ -262,7 +262,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* the bad sector.
*/
SCpnt->request.special = (void *) SCpnt;
- list_add(&SCpnt->request.queue, &q->queue_head);
+ __elv_add_request(q, &SCpnt->request, 0, 0);
}
/*
@@ -280,14 +280,10 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* with special case code, then spin off separate versions and
* use function pointers to pick the right one.
*/
- if (SDpnt->single_lun
- && list_empty(&q->queue_head)
- && SDpnt->device_busy == 0) {
+ if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) {
request_queue_t *q;
- for (SDpnt = SHpnt->host_queue;
- SDpnt;
- SDpnt = SDpnt->next) {
+ for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
if (((SHpnt->can_queue > 0)
&& (SHpnt->host_busy >= SHpnt->can_queue))
|| (SHpnt->host_blocked)
@@ -295,6 +291,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
|| (SDpnt->device_blocked)) {
break;
}
+
q = &SDpnt->request_queue;
q->request_fn(q);
}
@@ -328,7 +325,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
SHpnt->some_device_starved = 0;
}
}
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
}
/*
@@ -360,57 +357,19 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
int requeue,
int frequeue)
{
- struct request *req;
- struct buffer_head *bh;
- Scsi_Device * SDpnt;
- int nsect;
+ request_queue_t *q = &SCpnt->device->request_queue;
+ struct request *req = &SCpnt->request;
- ASSERT_LOCK(&io_request_lock, 0);
-
- req = &SCpnt->request;
- req->errors = 0;
- if (!uptodate) {
- printk(" I/O error: dev %s, sector %lu\n",
- kdevname(req->rq_dev), req->sector);
- }
- do {
- if ((bh = req->bh) != NULL) {
- nsect = bh->b_size >> 9;
- blk_finished_io(nsect);
- req->bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- sectors -= nsect;
- bh->b_end_io(bh, uptodate);
- if ((bh = req->bh) != NULL) {
- req->hard_sector += nsect;
- req->hard_nr_sectors -= nsect;
- req->sector += nsect;
- req->nr_sectors -= nsect;
-
- req->current_nr_sectors = bh->b_size >> 9;
- if (req->nr_sectors < req->current_nr_sectors) {
- req->nr_sectors = req->current_nr_sectors;
- printk("scsi_end_request: buffer-list destroyed\n");
- }
- }
- }
- } while (sectors && bh);
+ ASSERT_LOCK(&q->queue_lock, 0);
/*
* If there are blocks left over at the end, set up the command
* to queue the remainder of them.
*/
- if (req->bh) {
- request_queue_t *q;
-
- if( !requeue )
- {
+ if (end_that_request_first(req, 1, sectors)) {
+ if (!requeue)
return SCpnt;
- }
- q = &SCpnt->device->request_queue;
-
- req->buffer = bh->b_data;
/*
* Bleah. Leftovers again. Stick the leftovers in
* the front of the queue, and goose the queue again.
@@ -418,17 +377,15 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
scsi_queue_next_request(q, SCpnt);
return SCpnt;
}
+
/*
* This request is done. If there is someone blocked waiting for this
- * request, wake them up. Typically used to wake up processes trying
- * to swap a page into memory.
+ * request, wake them up.
*/
- if (req->waiting != NULL) {
+ if (req->waiting)
complete(req->waiting);
- }
- add_blkdev_randomness(MAJOR(req->rq_dev));
- SDpnt = SCpnt->device;
+ add_blkdev_randomness(MAJOR(req->rq_dev));
/*
* This will goose the queue request function at the end, so we don't
@@ -436,12 +393,9 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
*/
__scsi_release_command(SCpnt);
- if( frequeue ) {
- request_queue_t *q;
+ if (frequeue)
+ scsi_queue_next_request(q, NULL);
- q = &SDpnt->request_queue;
- scsi_queue_next_request(q, NULL);
- }
return NULL;
}
@@ -489,7 +443,9 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
*/
static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
{
- ASSERT_LOCK(&io_request_lock, 0);
+ struct request *req = &SCpnt->request;
+
+ ASSERT_LOCK(&SCpnt->device->request_queue.queue_lock, 0);
/*
* Free up any indirection buffers we allocated for DMA purposes.
@@ -510,9 +466,8 @@ static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
}
scsi_free(SCpnt->request_buffer, SCpnt->sglist_len);
} else {
- if (SCpnt->request_buffer != SCpnt->request.buffer) {
- scsi_free(SCpnt->request_buffer, SCpnt->request_bufflen);
- }
+ if (SCpnt->request_buffer != req->buffer)
+ scsi_free(SCpnt->request_buffer,SCpnt->request_bufflen);
}
/*
@@ -548,6 +503,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
int result = SCpnt->result;
int this_count = SCpnt->bufflen >> 9;
request_queue_t *q = &SCpnt->device->request_queue;
+ struct request *req = &SCpnt->request;
/*
* We must do one of several things here:
@@ -562,7 +518,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* would be used if we just wanted to retry, for example.
*
*/
- ASSERT_LOCK(&io_request_lock, 0);
+ ASSERT_LOCK(&q->queue_lock, 0);
/*
* Free up any indirection buffers we allocated for DMA purposes.
@@ -580,7 +536,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
if (bbpnt) {
for (i = 0; i < SCpnt->use_sg; i++) {
if (bbpnt[i]) {
- if (SCpnt->request.cmd == READ) {
+ if (rq_data_dir(req) == READ) {
memcpy(bbpnt[i],
sgpnt[i].address,
sgpnt[i].length);
@@ -591,10 +547,13 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
}
scsi_free(SCpnt->buffer, SCpnt->sglist_len);
} else {
- if (SCpnt->buffer != SCpnt->request.buffer) {
- if (SCpnt->request.cmd == READ) {
- memcpy(SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
+ if (SCpnt->buffer != req->buffer) {
+ if (rq_data_dir(req) == READ) {
+ unsigned long flags;
+ char *to = bio_kmap_irq(req->bio, &flags);
+
+ memcpy(to, SCpnt->buffer, SCpnt->bufflen);
+ bio_kunmap_irq(to, &flags);
}
scsi_free(SCpnt->buffer, SCpnt->bufflen);
}
@@ -615,11 +574,10 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
*/
if (good_sectors > 0) {
SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d sectors done.\n",
- SCpnt->request.nr_sectors,
- good_sectors));
+ req->nr_sectors, good_sectors));
SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg));
- SCpnt->request.errors = 0;
+ req->errors = 0;
/*
* If multiple sectors are requested in one buffer, then
* they will have been finished off by the first command.
@@ -716,7 +674,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
break;
case NOT_READY:
printk(KERN_INFO "Device %s not ready.\n",
- kdevname(SCpnt->request.rq_dev));
+ kdevname(req->rq_dev));
SCpnt = scsi_end_request(SCpnt, 0, this_count);
return;
break;
@@ -760,7 +718,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* We sometimes get this cruft in the event that a medium error
* isn't properly reported.
*/
- SCpnt = scsi_end_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
+ SCpnt = scsi_end_request(SCpnt, 0, req->current_nr_sectors);
return;
}
}
@@ -774,7 +732,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* Arguments: request - I/O request we are preparing to queue.
*
* Lock status: No locks assumed to be held, but as it happens the
- * io_request_lock is held when this is called.
+ * q->queue_lock is held when this is called.
*
* Returns: Nothing
*
@@ -788,7 +746,7 @@ struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
kdev_t dev = req->rq_dev;
int major = MAJOR(dev);
- ASSERT_LOCK(&io_request_lock, 1);
+ ASSERT_LOCK(&req->q->queue_lock, 1);
for (spnt = scsi_devicelist; spnt; spnt = spnt->next) {
/*
@@ -846,7 +804,7 @@ void scsi_request_fn(request_queue_t * q)
struct Scsi_Host *SHpnt;
struct Scsi_Device_Template *STpnt;
- ASSERT_LOCK(&io_request_lock, 1);
+ ASSERT_LOCK(&q->queue_lock, 1);
SDpnt = (Scsi_Device *) q->queuedata;
if (!SDpnt) {
@@ -864,7 +822,7 @@ void scsi_request_fn(request_queue_t * q)
* released the lock and grabbed it again, so each time
* we need to check to see if the queue is plugged or not.
*/
- if (SHpnt->in_recovery || q->plugged)
+ if (SHpnt->in_recovery || blk_queue_plugged(q))
return;
/*
@@ -913,9 +871,9 @@ void scsi_request_fn(request_queue_t * q)
*/
SDpnt->was_reset = 0;
if (SDpnt->removable && !in_interrupt()) {
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
scsi_ioctl(SDpnt, SCSI_IOCTL_DOORLOCK, 0);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
continue;
}
}
@@ -924,14 +882,13 @@ void scsi_request_fn(request_queue_t * q)
* If we couldn't find a request that could be queued, then we
* can also quit.
*/
- if (list_empty(&q->queue_head))
+ if (blk_queue_empty(q))
break;
/*
- * Loop through all of the requests in this queue, and find
- * one that is queueable.
+ * get next queueable request.
*/
- req = blkdev_entry_next_request(&q->queue_head);
+ req = elv_next_request(q);
/*
* Find the actual device driver associated with this command.
@@ -943,7 +900,7 @@ void scsi_request_fn(request_queue_t * q)
* these two cases differently. We differentiate by looking
* at request.cmd, as this tells us the real story.
*/
- if (req->cmd == SPECIAL) {
+ if (req->flags & REQ_SPECIAL) {
STpnt = NULL;
SCpnt = (Scsi_Cmnd *) req->special;
SRpnt = (Scsi_Request *) req->special;
@@ -951,13 +908,12 @@ void scsi_request_fn(request_queue_t * q)
if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) {
SCpnt = scsi_allocate_device(SRpnt->sr_device,
FALSE, FALSE);
- if( !SCpnt ) {
+ if (!SCpnt)
break;
- }
scsi_init_cmd_from_req(SCpnt, SRpnt);
}
- } else {
+ } else if (req->flags & REQ_CMD) {
SRpnt = NULL;
STpnt = scsi_get_request_dev(req);
if (!STpnt) {
@@ -966,14 +922,14 @@ void scsi_request_fn(request_queue_t * q)
/*
* Now try and find a command block that we can use.
*/
- if( req->special != NULL ) {
+ if (req->special) {
SCpnt = (Scsi_Cmnd *) req->special;
/*
* We need to recount the number of
* scatter-gather segments here - the
* normal case code assumes this to be
* correct, as it would be a performance
- * lose to always recount. Handling
+ * loss to always recount. Handling
* errors is always unusual, of course.
*/
recount_segments(SCpnt);
@@ -985,9 +941,11 @@ void scsi_request_fn(request_queue_t * q)
* while the queue is locked and then break out of the
* loop. Otherwise loop around and try another request.
*/
- if (!SCpnt) {
+ if (!SCpnt)
break;
- }
+ } else {
+ blk_dump_rq_flags(req, "SCSI bad req");
+ break;
}
/*
@@ -1024,9 +982,9 @@ void scsi_request_fn(request_queue_t * q)
* another.
*/
req = NULL;
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irq(&q->queue_lock);
- if (SCpnt->request.cmd != SPECIAL) {
+ if (SCpnt->request.flags & REQ_CMD) {
/*
* This will do a couple of things:
* 1) Fill in the actual SCSI command.
@@ -1039,9 +997,9 @@ void scsi_request_fn(request_queue_t * q)
* some kinds of consistency checking may cause the
* request to be rejected immediately.
*/
- if (STpnt == NULL) {
- STpnt = scsi_get_request_dev(req);
- }
+ if (STpnt == NULL)
+ STpnt = scsi_get_request_dev(&SCpnt->request);
+
/*
* This sets up the scatter-gather table (allocating if
* required). Hosts that need bounce buffers will also
@@ -1054,7 +1012,7 @@ void scsi_request_fn(request_queue_t * q)
{
panic("Should not have leftover blocks\n");
}
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
SHpnt->host_busy--;
SDpnt->device_busy--;
continue;
@@ -1070,7 +1028,7 @@ void scsi_request_fn(request_queue_t * q)
{
panic("Should not have leftover blocks\n");
}
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
SHpnt->host_busy--;
SDpnt->device_busy--;
continue;
@@ -1091,7 +1049,7 @@ void scsi_request_fn(request_queue_t * q)
* Now we need to grab the lock again. We are about to mess
* with the request queue and try to find another command.
*/
- spin_lock_irq(&io_request_lock);
+ spin_lock_irq(&q->queue_lock);
}
}
diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c
index e0cf69e66..734ff2ebe 100644
--- a/drivers/scsi/scsi_merge.c
+++ b/drivers/scsi/scsi_merge.c
@@ -6,6 +6,7 @@
* Based upon conversations with large numbers
* of people at Linux Expo.
* Support for dynamic DMA mapping: Jakub Jelinek (jakub@redhat.com).
+ * Support for highmem I/O: Jens Axboe <axboe@suse.de>
*/
/*
@@ -71,51 +72,6 @@
*/
#define DMA_SEGMENT_SIZE_LIMITED
-#ifdef CONFIG_SCSI_DEBUG_QUEUES
-/*
- * Enable a bunch of additional consistency checking. Turn this off
- * if you are benchmarking.
- */
-static int dump_stats(struct request *req,
- int use_clustering,
- int dma_host,
- int segments)
-{
- struct buffer_head *bh;
-
- /*
- * Dump the information that we have. We know we have an
- * inconsistency.
- */
- printk("nr_segments is %x\n", req->nr_segments);
- printk("counted segments is %x\n", segments);
- printk("Flags %d %d\n", use_clustering, dma_host);
- for (bh = req->bh; bh->b_reqnext != NULL; bh = bh->b_reqnext)
- {
- printk("Segment 0x%p, blocks %d, addr 0x%lx\n",
- bh,
- bh->b_size >> 9,
- virt_to_phys(bh->b_data - 1));
- }
- panic("Ththththaats all folks. Too dangerous to continue.\n");
-}
-
-
-/*
- * Simple sanity check that we will use for the first go around
- * in order to ensure that we are doing the counting correctly.
- * This can be removed for optimization.
- */
-#define SANITY_CHECK(req, _CLUSTER, _DMA) \
- if( req->nr_segments != __count_segments(req, _CLUSTER, _DMA, NULL) ) \
- { \
- printk("Incorrect segment count at 0x%p", current_text_addr()); \
- dump_stats(req, _CLUSTER, _DMA, __count_segments(req, _CLUSTER, _DMA, NULL)); \
- }
-#else
-#define SANITY_CHECK(req, _CLUSTER, _DMA)
-#endif
-
static void dma_exhausted(Scsi_Cmnd * SCpnt, int i)
{
int jj;
@@ -151,15 +107,6 @@ static void dma_exhausted(Scsi_Cmnd * SCpnt, int i)
}
/*
- * FIXME(eric) - the original disk code disabled clustering for MOD
- * devices. I have no idea why we thought this was a good idea - my
- * guess is that it was an attempt to limit the size of requests to MOD
- * devices.
- */
-#define CLUSTERABLE_DEVICE(SH,SD) (SH->use_clustering && \
- SD->type != TYPE_MOD)
-
-/*
* This entire source file deals with the new queueing code.
*/
@@ -170,7 +117,6 @@ static void dma_exhausted(Scsi_Cmnd * SCpnt, int i)
*
* Arguments: q - Queue for which we are merging request.
* req - request into which we wish to merge.
- * use_clustering - 1 if this host wishes to use clustering
* dma_host - 1 if this host has ISA DMA issues (bus doesn't
* expose all of the address lines, so that DMA cannot
* be done from an arbitrary address).
@@ -185,84 +131,37 @@ static void dma_exhausted(Scsi_Cmnd * SCpnt, int i)
* Notes: This is only used for diagnostic purposes.
*/
__inline static int __count_segments(struct request *req,
- int use_clustering,
int dma_host,
int * remainder)
{
int ret = 1;
int reqsize = 0;
- struct buffer_head *bh;
- struct buffer_head *bhnext;
+ int i;
+ struct bio *bio;
+ struct bio_vec *bvec;
- if( remainder != NULL ) {
+ if (remainder)
reqsize = *remainder;
- }
/*
* Add in the size increment for the first buffer.
*/
- bh = req->bh;
+ bio = req->bio;
#ifdef DMA_SEGMENT_SIZE_LIMITED
- if( reqsize + bh->b_size > PAGE_SIZE ) {
+ if (reqsize + bio->bi_size > PAGE_SIZE)
ret++;
- reqsize = bh->b_size;
- } else {
- reqsize += bh->b_size;
- }
-#else
- reqsize += bh->b_size;
#endif
- for (bh = req->bh, bhnext = bh->b_reqnext;
- bhnext != NULL;
- bh = bhnext, bhnext = bh->b_reqnext) {
- if (use_clustering) {
- /*
- * See if we can do this without creating another
- * scatter-gather segment. In the event that this is a
- * DMA capable host, make sure that a segment doesn't span
- * the DMA threshold boundary.
- */
- if (dma_host &&
- virt_to_phys(bhnext->b_data) - 1 == ISA_DMA_THRESHOLD) {
- ret++;
- reqsize = bhnext->b_size;
- } else if (CONTIGUOUS_BUFFERS(bh, bhnext)) {
- /*
- * This one is OK. Let it go.
- */
-#ifdef DMA_SEGMENT_SIZE_LIMITED
- /* Note scsi_malloc is only able to hand out
- * chunks of memory in sizes of PAGE_SIZE or
- * less. Thus we need to keep track of
- * the size of the piece that we have
- * seen so far, and if we have hit
- * the limit of PAGE_SIZE, then we are
- * kind of screwed and we need to start
- * another segment.
- */
- if( dma_host
- && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD
- && reqsize + bhnext->b_size > PAGE_SIZE )
- {
- ret++;
- reqsize = bhnext->b_size;
- continue;
- }
-#endif
- reqsize += bhnext->b_size;
- continue;
- }
+ rq_for_each_bio(bio, req) {
+ bio_for_each_segment(bvec, bio, i)
ret++;
- reqsize = bhnext->b_size;
- } else {
- ret++;
- reqsize = bhnext->b_size;
- }
+
+ reqsize += bio->bi_size;
}
- if( remainder != NULL ) {
+
+ if (remainder)
*remainder = reqsize;
- }
+
return ret;
}
@@ -298,20 +197,17 @@ recount_segments(Scsi_Cmnd * SCpnt)
SHpnt = SCpnt->host;
SDpnt = SCpnt->device;
- req->nr_segments = __count_segments(req,
- CLUSTERABLE_DEVICE(SHpnt, SDpnt),
- SHpnt->unchecked_isa_dma, NULL);
+ req->nr_segments = __count_segments(req, SHpnt->unchecked_isa_dma,NULL);
}
#define MERGEABLE_BUFFERS(X,Y) \
-(((((long)(X)->b_data+(X)->b_size)|((long)(Y)->b_data)) & \
+((((bio_to_phys((X))+(X)->bi_size)|(bio_to_phys((Y)))) & \
(DMA_CHUNK_SIZE - 1)) == 0)
#ifdef DMA_CHUNK_SIZE
static inline int scsi_new_mergeable(request_queue_t * q,
struct request * req,
- struct Scsi_Host *SHpnt,
- int max_segments)
+ struct Scsi_Host *SHpnt)
{
/*
* pci_map_sg will be able to merge these two
@@ -320,47 +216,47 @@ static inline int scsi_new_mergeable(request_queue_t * q,
* scsi.c allocates for this purpose
* min(64,sg_tablesize) entries.
*/
- if (req->nr_segments >= max_segments ||
- req->nr_segments >= SHpnt->sg_tablesize)
+ if (req->nr_segments >= q->max_segments)
return 0;
+
req->nr_segments++;
return 1;
}
static inline int scsi_new_segment(request_queue_t * q,
struct request * req,
- struct Scsi_Host *SHpnt,
- int max_segments)
+ struct bio *bio)
{
/*
* pci_map_sg won't be able to map these two
* into a single hardware sg entry, so we have to
* check if things fit into sg_tablesize.
*/
- if (req->nr_hw_segments >= SHpnt->sg_tablesize ||
- req->nr_segments >= SHpnt->sg_tablesize)
+ if (req->nr_hw_segments >= q->max_segments)
return 0;
- req->nr_hw_segments++;
- req->nr_segments++;
+ else if (req->nr_segments + bio->bi_vcnt > q->max_segments)
+ return 0;
+
+ req->nr_hw_segments += bio->bi_vcnt;
+ req->nr_segments += bio->bi_vcnt;
return 1;
}
+
#else
+
static inline int scsi_new_segment(request_queue_t * q,
struct request * req,
- struct Scsi_Host *SHpnt,
- int max_segments)
+ struct bio *bio)
{
- if (req->nr_segments < SHpnt->sg_tablesize &&
- req->nr_segments < max_segments) {
- /*
- * This will form the start of a new segment. Bump the
- * counter.
- */
- req->nr_segments++;
- return 1;
- } else {
+ if (req->nr_segments + bio->bi_vcnt > q->max_segments)
return 0;
- }
+
+ /*
+ * This will form the start of a new segment. Bump the
+ * counter.
+ */
+ req->nr_segments += bio->bi_vcnt;
+ return 1;
}
#endif
@@ -371,8 +267,7 @@ static inline int scsi_new_segment(request_queue_t * q,
*
* Arguments: q - Queue for which we are merging request.
* req - request into which we wish to merge.
- * bh - Block which we may wish to merge into request
- * use_clustering - 1 if this host wishes to use clustering
+ * bio - Block which we may wish to merge into request
* dma_host - 1 if this host has ISA DMA issues (bus doesn't
* expose all of the address lines, so that DMA cannot
* be done from an arbitrary address).
@@ -380,7 +275,7 @@ static inline int scsi_new_segment(request_queue_t * q,
* Returns: 1 if it is OK to merge the block into the request. 0
* if it is not OK.
*
- * Lock status: io_request_lock is assumed to be held here.
+ * Lock status: queue lock is assumed to be held here.
*
* Notes: Some drivers have limited scatter-gather table sizes, and
* thus they cannot queue an infinitely large command. This
@@ -390,129 +285,45 @@ static inline int scsi_new_segment(request_queue_t * q,
*
* This function is not designed to be directly called. Instead
* it should be referenced from other functions where the
- * use_clustering and dma_host parameters should be integer
- * constants. The compiler should thus be able to properly
- * optimize the code, eliminating stuff that is irrelevant.
+ * dma_host parameter should be an integer constant. The
+ * compiler should thus be able to properly optimize the code,
+ * eliminating stuff that is irrelevant.
* It is more maintainable to do this way with a single function
* than to have 4 separate functions all doing roughly the
* same thing.
*/
__inline static int __scsi_back_merge_fn(request_queue_t * q,
struct request *req,
- struct buffer_head *bh,
- int max_segments,
- int use_clustering,
+ struct bio *bio,
int dma_host)
{
- unsigned int count;
- unsigned int segment_size = 0;
- Scsi_Device *SDpnt;
- struct Scsi_Host *SHpnt;
-
- SDpnt = (Scsi_Device *) q->queuedata;
- SHpnt = SDpnt->host;
-
-#ifdef DMA_CHUNK_SIZE
- if (max_segments > 64)
- max_segments = 64;
-#endif
-
- if ((req->nr_sectors + (bh->b_size >> 9)) > SHpnt->max_sectors)
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors)
+ return 0;
+ else if (!BIO_SEG_BOUNDARY(q, req->biotail, bio))
return 0;
- if (use_clustering) {
- /*
- * See if we can do this without creating another
- * scatter-gather segment. In the event that this is a
- * DMA capable host, make sure that a segment doesn't span
- * the DMA threshold boundary.
- */
- if (dma_host &&
- virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) {
- goto new_end_segment;
- }
- if (CONTIGUOUS_BUFFERS(req->bhtail, bh)) {
-#ifdef DMA_SEGMENT_SIZE_LIMITED
- if( dma_host
- && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) {
- segment_size = 0;
- count = __count_segments(req, use_clustering, dma_host, &segment_size);
- if( segment_size + bh->b_size > PAGE_SIZE ) {
- goto new_end_segment;
- }
- }
-#endif
- /*
- * This one is OK. Let it go.
- */
- return 1;
- }
- }
- new_end_segment:
#ifdef DMA_CHUNK_SIZE
- if (MERGEABLE_BUFFERS(req->bhtail, bh))
- return scsi_new_mergeable(q, req, SHpnt, max_segments);
+ if (MERGEABLE_BUFFERS(req->biotail, bio))
+ return scsi_new_mergeable(q, req, q->queuedata);
#endif
- return scsi_new_segment(q, req, SHpnt, max_segments);
+ return scsi_new_segment(q, req, bio);
}
__inline static int __scsi_front_merge_fn(request_queue_t * q,
struct request *req,
- struct buffer_head *bh,
- int max_segments,
- int use_clustering,
+ struct bio *bio,
int dma_host)
{
- unsigned int count;
- unsigned int segment_size = 0;
- Scsi_Device *SDpnt;
- struct Scsi_Host *SHpnt;
-
- SDpnt = (Scsi_Device *) q->queuedata;
- SHpnt = SDpnt->host;
-
-#ifdef DMA_CHUNK_SIZE
- if (max_segments > 64)
- max_segments = 64;
-#endif
-
- if ((req->nr_sectors + (bh->b_size >> 9)) > SHpnt->max_sectors)
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors)
+ return 0;
+ else if (!BIO_SEG_BOUNDARY(q, bio, req->bio))
return 0;
- if (use_clustering) {
- /*
- * See if we can do this without creating another
- * scatter-gather segment. In the event that this is a
- * DMA capable host, make sure that a segment doesn't span
- * the DMA threshold boundary.
- */
- if (dma_host &&
- virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) {
- goto new_start_segment;
- }
- if (CONTIGUOUS_BUFFERS(bh, req->bh)) {
-#ifdef DMA_SEGMENT_SIZE_LIMITED
- if( dma_host
- && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) {
- segment_size = bh->b_size;
- count = __count_segments(req, use_clustering, dma_host, &segment_size);
- if( count != req->nr_segments ) {
- goto new_start_segment;
- }
- }
-#endif
- /*
- * This one is OK. Let it go.
- */
- return 1;
- }
- }
- new_start_segment:
#ifdef DMA_CHUNK_SIZE
- if (MERGEABLE_BUFFERS(bh, req->bh))
- return scsi_new_mergeable(q, req, SHpnt, max_segments);
+ if (MERGEABLE_BUFFERS(bio, req->bio))
+ return scsi_new_mergeable(q, req, q->queuedata);
#endif
- return scsi_new_segment(q, req, SHpnt, max_segments);
+ return scsi_new_segment(q, req, bio);
}
/*
@@ -522,43 +333,34 @@ __inline static int __scsi_front_merge_fn(request_queue_t * q,
*
* Arguments: q - Queue for which we are merging request.
* req - request into which we wish to merge.
- * bh - Block which we may wish to merge into request
+ * bio - Block which we may wish to merge into request
*
* Returns: 1 if it is OK to merge the block into the request. 0
* if it is not OK.
*
- * Lock status: io_request_lock is assumed to be held here.
+ * Lock status: queue lock is assumed to be held here.
*
* Notes: Optimized for different cases depending upon whether
* ISA DMA is in use and whether clustering should be used.
*/
-#define MERGEFCT(_FUNCTION, _BACK_FRONT, _CLUSTER, _DMA) \
+#define MERGEFCT(_FUNCTION, _BACK_FRONT, _DMA) \
static int _FUNCTION(request_queue_t * q, \
struct request * req, \
- struct buffer_head * bh, \
- int max_segments) \
+ struct bio *bio) \
{ \
int ret; \
- SANITY_CHECK(req, _CLUSTER, _DMA); \
ret = __scsi_ ## _BACK_FRONT ## _merge_fn(q, \
req, \
- bh, \
- max_segments, \
- _CLUSTER, \
+ bio, \
_DMA); \
return ret; \
}
-/* Version with use_clustering 0 and dma_host 1 is not necessary,
- * since the only use of dma_host above is protected by use_clustering.
- */
-MERGEFCT(scsi_back_merge_fn_, back, 0, 0)
-MERGEFCT(scsi_back_merge_fn_c, back, 1, 0)
-MERGEFCT(scsi_back_merge_fn_dc, back, 1, 1)
+MERGEFCT(scsi_back_merge_fn_, back, 0)
+MERGEFCT(scsi_back_merge_fn_d, back, 1)
-MERGEFCT(scsi_front_merge_fn_, front, 0, 0)
-MERGEFCT(scsi_front_merge_fn_c, front, 1, 0)
-MERGEFCT(scsi_front_merge_fn_dc, front, 1, 1)
+MERGEFCT(scsi_front_merge_fn_, front, 0)
+MERGEFCT(scsi_front_merge_fn_d, front, 1)
/*
* Function: __scsi_merge_requests_fn()
@@ -568,7 +370,6 @@ MERGEFCT(scsi_front_merge_fn_dc, front, 1, 1)
* Arguments: q - Queue for which we are merging request.
* req - request into which we wish to merge.
* next - 2nd request that we might want to combine with req
- * use_clustering - 1 if this host wishes to use clustering
* dma_host - 1 if this host has ISA DMA issues (bus doesn't
* expose all of the address lines, so that DMA cannot
* be done from an arbitrary address).
@@ -576,28 +377,17 @@ MERGEFCT(scsi_front_merge_fn_dc, front, 1, 1)
* Returns: 1 if it is OK to merge the two requests. 0
* if it is not OK.
*
- * Lock status: io_request_lock is assumed to be held here.
+ * Lock status: queue lock is assumed to be held here.
*
* Notes: Some drivers have limited scatter-gather table sizes, and
* thus they cannot queue an infinitely large command. This
* function is called from ll_rw_blk before it attempts to merge
* a new block into a request to make sure that the request will
* not become too large.
- *
- * This function is not designed to be directly called. Instead
- * it should be referenced from other functions where the
- * use_clustering and dma_host parameters should be integer
- * constants. The compiler should thus be able to properly
- * optimize the code, eliminating stuff that is irrelevant.
- * It is more maintainable to do this way with a single function
- * than to have 4 separate functions all doing roughly the
- * same thing.
*/
__inline static int __scsi_merge_requests_fn(request_queue_t * q,
struct request *req,
struct request *next,
- int max_segments,
- int use_clustering,
int dma_host)
{
Scsi_Device *SDpnt;
@@ -609,31 +399,28 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
*/
if (req->special || next->special)
return 0;
+ else if (!BIO_SEG_BOUNDARY(q, req->biotail, next->bio))
+ return 0;
SDpnt = (Scsi_Device *) q->queuedata;
SHpnt = SDpnt->host;
#ifdef DMA_CHUNK_SIZE
- if (max_segments > 64)
- max_segments = 64;
-
/* If it would not fit into prepared memory space for sg chain,
* then don't allow the merge.
*/
- if (req->nr_segments + next->nr_segments - 1 > max_segments ||
- req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) {
+ if (req->nr_segments + next->nr_segments - 1 > q->max_segments)
return 0;
- }
- if (req->nr_hw_segments + next->nr_hw_segments - 1 > SHpnt->sg_tablesize) {
+
+ if (req->nr_hw_segments + next->nr_hw_segments - 1 > q->max_segments)
return 0;
- }
#else
/*
* If the two requests together are too large (even assuming that we
* can merge the boundary requests into one segment, then don't
* allow the merge.
*/
- if (req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) {
+ if (req->nr_segments + next->nr_segments - 1 > q->max_segments) {
return 0;
}
#endif
@@ -641,64 +428,17 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
if ((req->nr_sectors + next->nr_sectors) > SHpnt->max_sectors)
return 0;
- /*
- * The main question is whether the two segments at the boundaries
- * would be considered one or two.
- */
- if (use_clustering) {
- /*
- * See if we can do this without creating another
- * scatter-gather segment. In the event that this is a
- * DMA capable host, make sure that a segment doesn't span
- * the DMA threshold boundary.
- */
- if (dma_host &&
- virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) {
- goto dont_combine;
- }
-#ifdef DMA_SEGMENT_SIZE_LIMITED
- /*
- * We currently can only allocate scatter-gather bounce
- * buffers in chunks of PAGE_SIZE or less.
- */
- if (dma_host
- && CONTIGUOUS_BUFFERS(req->bhtail, next->bh)
- && virt_to_phys(req->bhtail->b_data) - 1 >= ISA_DMA_THRESHOLD )
- {
- int segment_size = 0;
- int count = 0;
-
- count = __count_segments(req, use_clustering, dma_host, &segment_size);
- count += __count_segments(next, use_clustering, dma_host, &segment_size);
- if( count != req->nr_segments + next->nr_segments ) {
- goto dont_combine;
- }
- }
-#endif
- if (CONTIGUOUS_BUFFERS(req->bhtail, next->bh)) {
- /*
- * This one is OK. Let it go.
- */
- req->nr_segments += next->nr_segments - 1;
#ifdef DMA_CHUNK_SIZE
- req->nr_hw_segments += next->nr_hw_segments - 1;
-#endif
- return 1;
- }
- }
- dont_combine:
-#ifdef DMA_CHUNK_SIZE
- if (req->nr_segments + next->nr_segments > max_segments ||
- req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) {
+ if (req->nr_segments + next->nr_segments > q->max_segments)
return 0;
- }
+
/* If dynamic DMA mapping can merge last segment in req with
* first segment in next, then the check for hw segments was
* done above already, so we can always merge.
*/
- if (MERGEABLE_BUFFERS (req->bhtail, next->bh)) {
+ if (MERGEABLE_BUFFERS(req->biotail, next->bio)) {
req->nr_hw_segments += next->nr_hw_segments - 1;
- } else if (req->nr_hw_segments + next->nr_hw_segments > SHpnt->sg_tablesize) {
+ } else if (req->nr_hw_segments + next->nr_hw_segments > q->max_segments) {
return 0;
} else {
req->nr_hw_segments += next->nr_hw_segments;
@@ -711,8 +451,7 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
* Make sure we can fix something that is the sum of the two.
* A slightly stricter test than we had above.
*/
- if (req->nr_segments + next->nr_segments > max_segments ||
- req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) {
+ if (req->nr_segments + next->nr_segments > q->max_segments) {
return 0;
} else {
/*
@@ -732,34 +471,28 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
*
* Arguments: q - Queue for which we are merging request.
* req - request into which we wish to merge.
- * bh - Block which we may wish to merge into request
+ * bio - Block which we may wish to merge into request
*
* Returns: 1 if it is OK to merge the block into the request. 0
* if it is not OK.
*
- * Lock status: io_request_lock is assumed to be held here.
+ * Lock status: queue lock is assumed to be held here.
*
* Notes: Optimized for different cases depending upon whether
* ISA DMA is in use and whether clustering should be used.
*/
-#define MERGEREQFCT(_FUNCTION, _CLUSTER, _DMA) \
+#define MERGEREQFCT(_FUNCTION, _DMA) \
static int _FUNCTION(request_queue_t * q, \
struct request * req, \
- struct request * next, \
- int max_segments) \
+ struct request * next) \
{ \
int ret; \
- SANITY_CHECK(req, _CLUSTER, _DMA); \
- ret = __scsi_merge_requests_fn(q, req, next, max_segments, _CLUSTER, _DMA); \
+ ret = __scsi_merge_requests_fn(q, req, next, _DMA); \
return ret; \
}
-/* Version with use_clustering 0 and dma_host 1 is not necessary,
- * since the only use of dma_host above is protected by use_clustering.
- */
-MERGEREQFCT(scsi_merge_requests_fn_, 0, 0)
-MERGEREQFCT(scsi_merge_requests_fn_c, 1, 0)
-MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1)
+MERGEREQFCT(scsi_merge_requests_fn_, 0)
+MERGEREQFCT(scsi_merge_requests_fn_d, 1)
/*
* Function: __init_io()
*
@@ -767,7 +500,6 @@ MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1)
*
* Arguments: SCpnt - Command descriptor we wish to initialize
* sg_count_valid - 1 if the sg count in the req is valid.
- * use_clustering - 1 if this host wishes to use clustering
* dma_host - 1 if this host has ISA DMA issues (bus doesn't
* expose all of the address lines, so that DMA cannot
* be done from an arbitrary address).
@@ -795,11 +527,10 @@ MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1)
*/
__inline static int __init_io(Scsi_Cmnd * SCpnt,
int sg_count_valid,
- int use_clustering,
int dma_host)
{
- struct buffer_head * bh;
- struct buffer_head * bhprev;
+ struct bio * bio;
+ struct bio * bioprev;
char * buff;
int count;
int i;
@@ -809,35 +540,13 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
int this_count;
void ** bbpnt;
- /*
- * FIXME(eric) - don't inline this - it doesn't depend on the
- * integer flags. Come to think of it, I don't think this is even
- * needed any more. Need to play with it and see if we hit the
- * panic. If not, then don't bother.
- */
- if (!SCpnt->request.bh) {
- /*
- * Case of page request (i.e. raw device), or unlinked buffer
- * Typically used for swapping, but this isn't how we do
- * swapping any more.
- */
- panic("I believe this is dead code. If we hit this, I was wrong");
-#if 0
- SCpnt->request_bufflen = SCpnt->request.nr_sectors << 9;
- SCpnt->request_buffer = SCpnt->request.buffer;
- SCpnt->use_sg = 0;
- /*
- * FIXME(eric) - need to handle DMA here.
- */
-#endif
- return 1;
- }
req = &SCpnt->request;
+
/*
* First we need to know how many scatter gather segments are needed.
*/
if (!sg_count_valid) {
- count = __count_segments(req, use_clustering, dma_host, NULL);
+ count = __count_segments(req, dma_host, NULL);
} else {
count = req->nr_segments;
}
@@ -848,16 +557,15 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
* buffer.
*/
if (dma_host && scsi_dma_free_sectors <= 10) {
- this_count = SCpnt->request.current_nr_sectors;
+ this_count = req->current_nr_sectors;
goto single_segment;
}
+
/*
- * Don't bother with scatter-gather if there is only one segment.
+ * we used to not use scatter-gather for single segment request,
+ * but now we do (it makes highmem I/O easier to support without
+ * kmapping pages)
*/
- if (count == 1) {
- this_count = SCpnt->request.nr_sectors;
- goto single_segment;
- }
SCpnt->use_sg = count;
/*
@@ -875,29 +583,27 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
* round it up.
*/
SCpnt->sglist_len = (SCpnt->sglist_len + 511) & ~511;
-
+
sgpnt = (struct scatterlist *) scsi_malloc(SCpnt->sglist_len);
- /*
- * Now fill the scatter-gather table.
- */
if (!sgpnt) {
+ struct Scsi_Host *SHpnt = SCpnt->host;
+
/*
* If we cannot allocate the scatter-gather table, then
* simply write the first buffer all by itself.
*/
printk("Warning - running *really* short on DMA buffers\n");
- this_count = SCpnt->request.current_nr_sectors;
+ this_count = req->current_nr_sectors;
+ printk("SCSI: depth is %d, # segs %d, # hw segs %d\n", SHpnt->host_busy, req->nr_segments, req->nr_hw_segments);
goto single_segment;
}
- /*
- * Next, walk the list, and fill in the addresses and sizes of
- * each segment.
- */
+
memset(sgpnt, 0, SCpnt->sglist_len);
SCpnt->request_buffer = (char *) sgpnt;
SCpnt->request_bufflen = 0;
- bhprev = NULL;
+ req->buffer = NULL;
+ bioprev = NULL;
if (dma_host)
bbpnt = (void **) ((char *)sgpnt +
@@ -907,62 +613,30 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
SCpnt->bounce_buffers = bbpnt;
- for (count = 0, bh = SCpnt->request.bh;
- bh; bh = bh->b_reqnext) {
- if (use_clustering && bhprev != NULL) {
- if (dma_host &&
- virt_to_phys(bhprev->b_data) - 1 == ISA_DMA_THRESHOLD) {
- /* Nothing - fall through */
- } else if (CONTIGUOUS_BUFFERS(bhprev, bh)) {
- /*
- * This one is OK. Let it go. Note that we
- * do not have the ability to allocate
- * bounce buffer segments > PAGE_SIZE, so
- * for now we limit the thing.
- */
- if( dma_host ) {
-#ifdef DMA_SEGMENT_SIZE_LIMITED
- if( virt_to_phys(bh->b_data) - 1 < ISA_DMA_THRESHOLD
- || sgpnt[count - 1].length + bh->b_size <= PAGE_SIZE ) {
- sgpnt[count - 1].length += bh->b_size;
- bhprev = bh;
- continue;
- }
-#else
- sgpnt[count - 1].length += bh->b_size;
- bhprev = bh;
- continue;
-#endif
- } else {
- sgpnt[count - 1].length += bh->b_size;
- SCpnt->request_bufflen += bh->b_size;
- bhprev = bh;
- continue;
- }
- }
- }
- count++;
- sgpnt[count - 1].address = bh->b_data;
- sgpnt[count - 1].page = NULL;
- sgpnt[count - 1].length += bh->b_size;
- if (!dma_host) {
- SCpnt->request_bufflen += bh->b_size;
- }
- bhprev = bh;
- }
+ /*
+ * Next, walk the list, and fill in the addresses and sizes of
+ * each segment.
+ */
+ SCpnt->request_bufflen = req->nr_sectors << 9;
+ count = blk_rq_map_sg(req->q, req, SCpnt->request_buffer);
/*
* Verify that the count is correct.
*/
- if (count != SCpnt->use_sg) {
+ if (count > SCpnt->use_sg) {
printk("Incorrect number of segments after building list\n");
-#ifdef CONFIG_SCSI_DEBUG_QUEUES
- dump_stats(req, use_clustering, dma_host, count);
-#endif
+ printk("counted %d, received %d\n", count, SCpnt->use_sg);
+ printk("req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors);
+ scsi_free(SCpnt->request_buffer, SCpnt->sglist_len);
+ this_count = req->current_nr_sectors;
+ goto single_segment;
}
- if (!dma_host) {
+
+ SCpnt->use_sg = count;
+
+ if (!dma_host)
return 1;
- }
+
/*
* Now allocate bounce buffers, if needed.
*/
@@ -971,7 +645,7 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
sectors = (sgpnt[i].length >> 9);
SCpnt->request_bufflen += sgpnt[i].length;
if (virt_to_phys(sgpnt[i].address) + sgpnt[i].length - 1 >
- ISA_DMA_THRESHOLD) {
+ ISA_DMA_THRESHOLD) {
if( scsi_dma_free_sectors - sectors <= 10 ) {
/*
* If this would nearly drain the DMA
@@ -989,9 +663,12 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
break;
}
- bbpnt[i] = sgpnt[i].address;
- sgpnt[i].address =
- (char *) scsi_malloc(sgpnt[i].length);
+ /*
+ * this is not a dma host, so it will never
+ * be a highmem page
+ */
+ bbpnt[i] = page_address(sgpnt[i].page) +sgpnt[i].offset;
+ sgpnt[i].address = (char *)scsi_malloc(sgpnt[i].length);
/*
* If we cannot allocate memory for this DMA bounce
* buffer, then queue just what we have done so far.
@@ -1005,10 +682,9 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
}
break;
}
- if (SCpnt->request.cmd == WRITE) {
+ if (rq_data_dir(req) == WRITE)
memcpy(sgpnt[i].address, bbpnt[i],
sgpnt[i].length);
- }
}
}
return 1;
@@ -1050,21 +726,20 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
* single-block requests if we had hundreds of free sectors.
*/
if( scsi_dma_free_sectors > 30 ) {
- for (this_count = 0, bh = SCpnt->request.bh;
- bh; bh = bh->b_reqnext) {
+ for (this_count = 0, bio = req->bio; bio; bio = bio->bi_next) {
if( scsi_dma_free_sectors - this_count < 30
|| this_count == sectors )
{
break;
}
- this_count += bh->b_size >> 9;
+ this_count += bio_sectors(bio);
}
} else {
/*
* Yow! Take the absolute minimum here.
*/
- this_count = SCpnt->request.current_nr_sectors;
+ this_count = req->current_nr_sectors;
}
/*
@@ -1077,28 +752,33 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
* segment. Possibly the entire request, or possibly a small
* chunk of the entire request.
*/
- bh = SCpnt->request.bh;
- buff = SCpnt->request.buffer;
- if (dma_host) {
+ bio = req->bio;
+ buff = req->buffer = bio_data(bio);
+
+ if (dma_host || PageHighMem(bio_page(bio))) {
/*
* Allocate a DMA bounce buffer. If the allocation fails, fall
* back and allocate a really small one - enough to satisfy
* the first buffer.
*/
- if (virt_to_phys(SCpnt->request.bh->b_data)
- + (this_count << 9) - 1 > ISA_DMA_THRESHOLD) {
+ if (bio_to_phys(bio) + bio->bi_size - 1 > ISA_DMA_THRESHOLD) {
buff = (char *) scsi_malloc(this_count << 9);
if (!buff) {
printk("Warning - running low on DMA memory\n");
- this_count = SCpnt->request.current_nr_sectors;
+ this_count = req->current_nr_sectors;
buff = (char *) scsi_malloc(this_count << 9);
if (!buff) {
dma_exhausted(SCpnt, 0);
+ return 0;
}
}
- if (SCpnt->request.cmd == WRITE)
- memcpy(buff, (char *) SCpnt->request.buffer, this_count << 9);
+ if (rq_data_dir(req) == WRITE) {
+ unsigned long flags;
+ char *buf = bio_kmap_irq(bio, &flags);
+ memcpy(buff, buf, this_count << 9);
+ bio_kunmap_irq(buf, &flags);
+ }
}
}
SCpnt->request_bufflen = this_count << 9;
@@ -1107,10 +787,10 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
return 1;
}
-#define INITIO(_FUNCTION, _VALID, _CLUSTER, _DMA) \
-static int _FUNCTION(Scsi_Cmnd * SCpnt) \
-{ \
- return __init_io(SCpnt, _VALID, _CLUSTER, _DMA); \
+#define INITIO(_FUNCTION, _VALID, _DMA) \
+static int _FUNCTION(Scsi_Cmnd * SCpnt) \
+{ \
+ return __init_io(SCpnt, _VALID, _DMA); \
}
/*
@@ -1119,10 +799,8 @@ static int _FUNCTION(Scsi_Cmnd * SCpnt) \
* We always force "_VALID" to 1. Eventually clean this up
* and get rid of the extra argument.
*/
-INITIO(scsi_init_io_v, 1, 0, 0)
-INITIO(scsi_init_io_vd, 1, 0, 1)
-INITIO(scsi_init_io_vc, 1, 1, 0)
-INITIO(scsi_init_io_vdc, 1, 1, 1)
+INITIO(scsi_init_io_v, 1, 0)
+INITIO(scsi_init_io_vd, 1, 1)
/*
* Function: initialize_merge_fn()
@@ -1139,21 +817,11 @@ INITIO(scsi_init_io_vdc, 1, 1, 1)
*/
void initialize_merge_fn(Scsi_Device * SDpnt)
{
- request_queue_t *q;
- struct Scsi_Host *SHpnt;
- SHpnt = SDpnt->host;
-
- q = &SDpnt->request_queue;
+ struct Scsi_Host *SHpnt = SDpnt->host;
+ request_queue_t *q = &SDpnt->request_queue;
+ dma64_addr_t bounce_limit;
/*
- * If the host has already selected a merge manager, then don't
- * pick a new one.
- */
-#if 0
- if (q->back_merge_fn && q->front_merge_fn)
- return;
-#endif
- /*
* If this host has an unlimited tablesize, then don't bother with a
* merge manager. The whole point of the operation is to make sure
* that requests don't grow too large, and this host isn't picky.
@@ -1164,25 +832,31 @@ void initialize_merge_fn(Scsi_Device * SDpnt)
* is simply easier to do it ourselves with our own functions
* rather than rely upon the default behavior of ll_rw_blk.
*/
- if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
+ if (SHpnt->unchecked_isa_dma == 0) {
q->back_merge_fn = scsi_back_merge_fn_;
q->front_merge_fn = scsi_front_merge_fn_;
q->merge_requests_fn = scsi_merge_requests_fn_;
SDpnt->scsi_init_io_fn = scsi_init_io_v;
- } else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
- q->back_merge_fn = scsi_back_merge_fn_;
- q->front_merge_fn = scsi_front_merge_fn_;
- q->merge_requests_fn = scsi_merge_requests_fn_;
+ } else {
+ q->back_merge_fn = scsi_back_merge_fn_d;
+ q->front_merge_fn = scsi_front_merge_fn_d;
+ q->merge_requests_fn = scsi_merge_requests_fn_d;
SDpnt->scsi_init_io_fn = scsi_init_io_vd;
- } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
- q->back_merge_fn = scsi_back_merge_fn_c;
- q->front_merge_fn = scsi_front_merge_fn_c;
- q->merge_requests_fn = scsi_merge_requests_fn_c;
- SDpnt->scsi_init_io_fn = scsi_init_io_vc;
- } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
- q->back_merge_fn = scsi_back_merge_fn_dc;
- q->front_merge_fn = scsi_front_merge_fn_dc;
- q->merge_requests_fn = scsi_merge_requests_fn_dc;
- SDpnt->scsi_init_io_fn = scsi_init_io_vdc;
}
+
+ /*
+ * now enable highmem I/O, if appropriate
+ */
+ bounce_limit = BLK_BOUNCE_HIGH;
+ if (SHpnt->highmem_io && (SDpnt->type == TYPE_DISK)) {
+ if (!PCI_DMA_BUS_IS_PHYS)
+ /* Platforms with virtual-DMA translation
+ * hardware have no practical limit.
+ */
+ bounce_limit = BLK_BOUNCE_ANY;
+ else
+ bounce_limit = SHpnt->pci_dev->dma_mask;
+ }
+
+ blk_queue_bounce_limit(q, bounce_limit);
}
diff --git a/drivers/scsi/scsi_queue.c b/drivers/scsi/scsi_queue.c
index c41f1ce06..b864fc045 100644
--- a/drivers/scsi/scsi_queue.c
+++ b/drivers/scsi/scsi_queue.c
@@ -80,6 +80,7 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
{
struct Scsi_Host *host;
unsigned long flags;
+ request_queue_t *q = &cmd->device->request_queue;
SCSI_LOG_MLQUEUE(1, printk("Inserting command %p into mlqueue\n", cmd));
@@ -137,10 +138,10 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
* Decrement the counters, since these commands are no longer
* active on the host/device.
*/
- spin_lock_irqsave(&io_request_lock, flags);
+ spin_lock_irqsave(&q->queue_lock, flags);
cmd->host->host_busy--;
cmd->device->device_busy--;
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
/*
* Insert this command at the head of the queue for it's device.
diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
index bdf2142b8..7fb246998 100644
--- a/drivers/scsi/scsi_syms.c
+++ b/drivers/scsi/scsi_syms.c
@@ -54,7 +54,6 @@ EXPORT_SYMBOL(scsi_need_isa_buffer);
EXPORT_SYMBOL(scsi_release_command);
EXPORT_SYMBOL(print_Scsi_Cmnd);
EXPORT_SYMBOL(scsi_block_when_processing_errors);
-EXPORT_SYMBOL(scsi_mark_host_reset);
EXPORT_SYMBOL(scsi_ioctl_send_command);
#if defined(CONFIG_SCSI_LOGGING) /* { */
EXPORT_SYMBOL(scsi_logging_level);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index f2392578f..eb93a833a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -61,10 +61,6 @@
#include <linux/genhd.h>
-/*
- * static const char RCSid[] = "$Header:";
- */
-
#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
#define SCSI_DISKS_PER_MAJOR 16
@@ -72,8 +68,7 @@
#define SD_MINOR_NUMBER(i) ((i) & 255)
#define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), (i) & 255)
#define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4)
-#define N_USED_SCSI_DISKS (sd_template.dev_max + SCSI_DISKS_PER_MAJOR - 1)
-#define N_USED_SD_MAJORS (N_USED_SCSI_DISKS / SCSI_DISKS_PER_MAJOR)
+#define N_USED_SD_MAJORS (1 + ((sd_template.dev_max - 1) >> 4))
#define MAX_RETRIES 5
@@ -89,7 +84,6 @@ struct hd_struct *sd;
static Scsi_Disk *rscsi_disks;
static int *sd_sizes;
static int *sd_blocksizes;
-static int *sd_hardsizes; /* Hardware sector size */
static int *sd_max_sectors;
static int check_scsidisk_media_change(kdev_t);
@@ -97,7 +91,6 @@ static int fop_revalidate_scsidisk(kdev_t);
static int sd_init_onedisk(int);
-
static int sd_init(void);
static void sd_finish(void);
static int sd_attach(Scsi_Device *);
@@ -124,7 +117,6 @@ static struct Scsi_Device_Template sd_template = {
init_command:sd_init_command,
};
-
static void rw_intr(Scsi_Cmnd * SCpnt);
#if defined(CONFIG_PPC)
@@ -191,11 +183,11 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
&diskinfo[0]);
else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)],
dev, &diskinfo[0]);
-
if (put_user(diskinfo[0], &loc->heads) ||
put_user(diskinfo[1], &loc->sectors) ||
put_user(diskinfo[2], &loc->cylinders) ||
- put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start))
+ put_user((unsigned) get_start_sect(inode->i_rdev),
+ (unsigned long *) &loc->start))
return -EFAULT;
return 0;
}
@@ -226,7 +218,8 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
if (put_user(diskinfo[0], &loc->heads) ||
put_user(diskinfo[1], &loc->sectors) ||
put_user(diskinfo[2], (unsigned int *) &loc->cylinders) ||
- put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start))
+ put_user((unsigned)get_start_sect(inode->i_rdev),
+ (unsigned long *)&loc->start))
return -EFAULT;
return 0;
}
@@ -239,8 +232,8 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
case BLKFLSBUF:
case BLKSSZGET:
case BLKPG:
- case BLKELVGET:
- case BLKELVSET:
+ case BLKELVGET:
+ case BLKELVSET:
case BLKBSZGET:
case BLKBSZSET:
return blk_ioctl(inode->i_rdev, cmd, arg);
@@ -251,7 +244,8 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
return revalidate_scsidisk(dev, 1);
default:
- return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg);
+ return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device,
+ cmd, (void *) arg);
}
}
@@ -292,6 +286,12 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
char nbuff[6];
#endif
+ /*
+ * don't support specials for nwo
+ */
+ if (!(SCpnt->request.flags & REQ_CMD))
+ return 0;
+
devm = SD_PARTITION(SCpnt->request.rq_dev);
dev = DEVICE_NR(SCpnt->request.rq_dev);
@@ -301,7 +301,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %d\n", devm, block));
dpnt = &rscsi_disks[dev];
- if (devm >= (sd_template.dev_max << 4) ||
+ if (devm >= (sd_template.dev_max << 4) || (devm & 0xf) ||
!dpnt ||
!dpnt->device->online ||
block + SCpnt->request.nr_sectors > sd[devm].nr_sects) {
@@ -309,7 +309,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
return 0;
}
- block += sd[devm].start_sect;
+
if (dpnt->device->changed) {
/*
* quietly refuse to do anything to a changed disc until the changed
@@ -360,21 +360,17 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
this_count = this_count >> 3;
}
}
- switch (SCpnt->request.cmd) {
- case WRITE:
+ if (rq_data_dir(&SCpnt->request) == WRITE) {
if (!dpnt->device->writeable) {
return 0;
}
SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
- break;
- case READ:
+ } else if (rq_data_dir(&SCpnt->request) == READ) {
SCpnt->cmnd[0] = READ_6;
SCpnt->sc_data_direction = SCSI_DATA_READ;
- break;
- default:
- panic("Unknown sd command %d\n", SCpnt->request.cmd);
- }
+ } else
+ panic("Unknown sd command %lx\n", SCpnt->request.flags);
SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
nbuff,
@@ -618,8 +614,8 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
(SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) |
SCpnt->sense_buffer[6];
- if (SCpnt->request.bh != NULL)
- block_sectors = SCpnt->request.bh->b_size >> 9;
+ if (SCpnt->request.bio != NULL)
+ block_sectors = bio_sectors(SCpnt->request.bio);
switch (SCpnt->device->sector_size) {
case 1024:
error_sector <<= 1;
@@ -642,7 +638,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
default:
break;
}
- error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;
+
error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request.sector;
if (good_sectors < 0 || good_sectors >= this_count)
@@ -970,15 +966,11 @@ static int sd_init_onedisk(int i)
* So I have created this table. See ll_rw_blk.c
* Jacques Gelinas (Jacques@solucorp.qc.ca)
*/
- int m;
int hard_sector = sector_size;
int sz = rscsi_disks[i].capacity * (hard_sector/256);
/* There are 16 minors allocated for each major device */
- for (m = i << 4; m < ((i + 1) << 4); m++) {
- sd_hardsizes[m] = hard_sector;
- }
-
+ blk_queue_hardsect_size(blk_get_queue(SD_MAJOR(i)), hard_sector);
printk("SCSI device %s: "
"%d %d-byte hdwr sectors (%d MB)\n",
nbuff, rscsi_disks[i].capacity,
@@ -1063,7 +1055,7 @@ static int sd_registered;
static int sd_init()
{
- int i;
+ int i, maxparts;
if (sd_template.dev_noticed == 0)
return 0;
@@ -1074,10 +1066,17 @@ static int sd_init()
if (sd_template.dev_max > N_SD_MAJORS * SCSI_DISKS_PER_MAJOR)
sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
+ /* At most 16 partitions on each scsi disk. */
+ maxparts = (sd_template.dev_max << 4);
+ if (maxparts == 0)
+ return 0;
+
if (!sd_registered) {
for (i = 0; i < N_USED_SD_MAJORS; i++) {
- if (devfs_register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) {
- printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i));
+ if (devfs_register_blkdev(SD_MAJOR(i), "sd",
+ &sd_fops)) {
+ printk("Unable to get major %d for SCSI disk\n",
+ SD_MAJOR(i));
return 1;
}
}
@@ -1087,32 +1086,26 @@ static int sd_init()
if (rscsi_disks)
return 0;
- rscsi_disks = kmalloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
- if (!rscsi_disks)
- goto cleanup_devfs;
- memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
-
- /* for every (necessary) major: */
- sd_sizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
- if (!sd_sizes)
- goto cleanup_disks;
- memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
-
- sd_blocksizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
- if (!sd_blocksizes)
- goto cleanup_sizes;
-
- sd_hardsizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
- if (!sd_hardsizes)
- goto cleanup_blocksizes;
+ /* allocate memory */
+#define init_mem_lth(x,n) x = kmalloc((n) * sizeof(*x), GFP_ATOMIC)
+#define zero_mem_lth(x,n) memset(x, 0, (n) * sizeof(*x))
+
+ init_mem_lth(rscsi_disks, sd_template.dev_max);
+ init_mem_lth(sd_sizes, maxparts);
+ init_mem_lth(sd_blocksizes, maxparts);
+ init_mem_lth(sd, maxparts);
+ init_mem_lth(sd_gendisks, N_USED_SD_MAJORS);
+ init_mem_lth(sd_max_sectors, sd_template.dev_max << 4);
+
+ if (!rscsi_disks || !sd_sizes || !sd_blocksizes || !sd || !sd_gendisks)
+ goto cleanup_mem;
- sd_max_sectors = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
- if (!sd_max_sectors)
- goto cleanup_max_sectors;
+ zero_mem_lth(rscsi_disks, sd_template.dev_max);
+ zero_mem_lth(sd_sizes, maxparts);
+ zero_mem_lth(sd, maxparts);
- for (i = 0; i < sd_template.dev_max << 4; i++) {
+ for (i = 0; i < maxparts; i++) {
sd_blocksizes[i] = 1024;
- sd_hardsizes[i] = 512;
/*
* Allow lowlevel device drivers to generate 512k large scsi
* commands if they know what they're doing and they ask for it
@@ -1122,45 +1115,34 @@ static int sd_init()
}
for (i = 0; i < N_USED_SD_MAJORS; i++) {
- blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4);
- hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4);
- max_sectors[SD_MAJOR(i)] = sd_max_sectors + i * (SCSI_DISKS_PER_MAJOR << 4);
- }
- /*
- * FIXME: should unregister blksize_size, hardsect_size and max_sectors when
- * the module is unloaded.
- */
- sd = kmalloc((sd_template.dev_max << 4) *
- sizeof(struct hd_struct),
- GFP_ATOMIC);
- if (!sd)
- goto cleanup_sd;
- memset(sd, 0, (sd_template.dev_max << 4) * sizeof(struct hd_struct));
-
- if (N_USED_SD_MAJORS > 1)
- sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
- if (!sd_gendisks)
- goto cleanup_sd_gendisks;
+ request_queue_t *q = blk_get_queue(SD_MAJOR(i));
+ int parts_per_major = (SCSI_DISKS_PER_MAJOR << 4);
+
+ blksize_size[SD_MAJOR(i)] =
+ sd_blocksizes + i * parts_per_major;
+ blk_queue_hardsect_size(q, 512);
+ }
+
for (i = 0; i < N_USED_SD_MAJORS; i++) {
+ int N = SCSI_DISKS_PER_MAJOR;
+
sd_gendisks[i] = sd_gendisk;
- sd_gendisks[i].de_arr = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr,
- GFP_ATOMIC);
- if (!sd_gendisks[i].de_arr)
- goto cleanup_gendisks_de_arr;
- memset (sd_gendisks[i].de_arr, 0,
- SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr);
- sd_gendisks[i].flags = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags,
- GFP_ATOMIC);
- if (!sd_gendisks[i].flags)
- goto cleanup_gendisks_flags;
- memset (sd_gendisks[i].flags, 0,
- SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags);
+
+ init_mem_lth(sd_gendisks[i].de_arr, N);
+ init_mem_lth(sd_gendisks[i].flags, N);
+
+ if (!sd_gendisks[i].de_arr || !sd_gendisks[i].flags)
+ goto cleanup_gendisks;
+
+ zero_mem_lth(sd_gendisks[i].de_arr, N);
+ zero_mem_lth(sd_gendisks[i].flags, N);
+
sd_gendisks[i].major = SD_MAJOR(i);
sd_gendisks[i].major_name = "sd";
sd_gendisks[i].minor_shift = 4;
sd_gendisks[i].max_p = 1 << 4;
- sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
- sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
+ sd_gendisks[i].part = sd + i * (N << 4);
+ sd_gendisks[i].sizes = sd_sizes + i * (N << 4);
sd_gendisks[i].nr_real = 0;
sd_gendisks[i].real_devices =
(void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR);
@@ -1168,27 +1150,21 @@ static int sd_init()
return 0;
-cleanup_gendisks_flags:
- kfree(sd_gendisks[i].de_arr);
-cleanup_gendisks_de_arr:
- while (--i >= 0 ) {
+#undef init_mem_lth
+#undef zero_mem_lth
+
+cleanup_gendisks:
+ /* kfree can handle NULL, so no test is required here */
+ for (i = 0; i < N_USED_SD_MAJORS; i++) {
kfree(sd_gendisks[i].de_arr);
kfree(sd_gendisks[i].flags);
}
+cleanup_mem:
kfree(sd_gendisks);
-cleanup_sd_gendisks:
kfree(sd);
-cleanup_sd:
- kfree(sd_max_sectors);
-cleanup_max_sectors:
- kfree(sd_hardsizes);
-cleanup_blocksizes:
kfree(sd_blocksizes);
-cleanup_sizes:
kfree(sd_sizes);
-cleanup_disks:
kfree(rscsi_disks);
-cleanup_devfs:
for (i = 0; i < N_USED_SD_MAJORS; i++) {
devfs_unregister_blkdev(SD_MAJOR(i), "sd");
}
@@ -1203,7 +1179,7 @@ static void sd_finish()
for (i = 0; i < N_USED_SD_MAJORS; i++) {
blk_dev[SD_MAJOR(i)].queue = sd_find_queue;
- add_gendisk(&sd_gendisks[i]);
+ add_gendisk(&(sd_gendisks[i]));
}
for (i = 0; i < sd_template.dev_max; ++i)
@@ -1293,9 +1269,7 @@ static int sd_attach(Scsi_Device * SDp)
int revalidate_scsidisk(kdev_t dev, int maxusage)
{
int target;
- int max_p;
- int start;
- int i;
+ int res;
target = DEVICE_NR(dev);
@@ -1305,36 +1279,18 @@ int revalidate_scsidisk(kdev_t dev, int maxusage)
}
DEVICE_BUSY = 1;
- max_p = sd_gendisks->max_p;
- start = target << sd_gendisks->minor_shift;
-
- for (i = max_p - 1; i >= 0; i--) {
- int index = start + i;
- invalidate_device(MKDEV_SD_PARTITION(index), 1);
- sd_gendisks->part[index].start_sect = 0;
- sd_gendisks->part[index].nr_sects = 0;
- /*
- * Reset the blocksize for everything so that we can read
- * the partition table. Technically we will determine the
- * correct block size when we revalidate, but we do this just
- * to make sure that everything remains consistent.
- */
- sd_blocksizes[index] = 1024;
- if (rscsi_disks[target].device->sector_size == 2048)
- sd_blocksizes[index] = 2048;
- else
- sd_blocksizes[index] = 1024;
- }
+ res = wipe_partitions(dev);
+ if (res)
+ goto leave;
#ifdef MAYBE_REINIT
MAYBE_REINIT;
#endif
- grok_partitions(&SD_GENDISK(target), target % SCSI_DISKS_PER_MAJOR,
- 1<<4, CAPACITY);
-
+ grok_partitions(dev, CAPACITY);
+leave:
DEVICE_BUSY = 0;
- return 0;
+ return res;
}
static int fop_revalidate_scsidisk(kdev_t dev)
@@ -1344,6 +1300,7 @@ static int fop_revalidate_scsidisk(kdev_t dev)
static void sd_detach(Scsi_Device * SDp)
{
Scsi_Disk *dpnt;
+ kdev_t dev;
int i, j;
int max_p;
int start;
@@ -1351,18 +1308,13 @@ static void sd_detach(Scsi_Device * SDp)
for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++)
if (dpnt->device == SDp) {
- /* If we are disconnecting a disk driver, sync and invalidate
- * everything */
max_p = sd_gendisk.max_p;
start = i << sd_gendisk.minor_shift;
+ dev = MKDEV_SD_PARTITION(start);
+ wipe_partitions(dev);
+ for (j = max_p - 1; j >= 0; j--)
+ sd_sizes[start + j] = 0;
- for (j = max_p - 1; j >= 0; j--) {
- int index = start + j;
- invalidate_device(MKDEV_SD_PARTITION(index), 1);
- sd_gendisks->part[index].start_sect = 0;
- sd_gendisks->part[index].nr_sects = 0;
- sd_sizes[index] = 0;
- }
devfs_register_partitions (&SD_GENDISK (i),
SD_MINOR_NUMBER (start), 1);
/* unregister_disk() */
@@ -1375,7 +1327,6 @@ static void sd_detach(Scsi_Device * SDp)
SD_GENDISK(i).nr_real--;
return;
}
- return;
}
static int __init init_sd(void)
@@ -1398,14 +1349,11 @@ static void __exit exit_sd(void)
kfree(rscsi_disks);
kfree(sd_sizes);
kfree(sd_blocksizes);
- kfree(sd_hardsizes);
kfree((char *) sd);
}
for (i = 0; i < N_USED_SD_MAJORS; i++) {
- del_gendisk(&sd_gendisks[i]);
- blk_size[SD_MAJOR(i)] = NULL;
- hardsect_size[SD_MAJOR(i)] = NULL;
- read_ahead[SD_MAJOR(i)] = 0;
+ del_gendisk(&(sd_gendisks[i]));
+ blk_clear(SD_MAJOR(i));
}
sd_template.dev_max = 0;
if (sd_gendisks != &sd_gendisk)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 5dfb403ff..8d5a291e4 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -341,9 +341,7 @@ static int sg_release(struct inode * inode, struct file * filp)
Sg_device * sdp;
Sg_fd * sfp;
- lock_kernel();
if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) {
- unlock_kernel();
return -ENXIO;
}
SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
@@ -357,7 +355,6 @@ static int sg_release(struct inode * inode, struct file * filp)
sdp->exclude = 0;
wake_up_interruptible(&sdp->o_excl_wait);
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/sim710.h b/drivers/scsi/sim710.h
index 5fed80efb..2fd837fea 100644
--- a/drivers/scsi/sim710.h
+++ b/drivers/scsi/sim710.h
@@ -37,8 +37,7 @@ int sim710_release(struct Scsi_Host *);
this_id: 7, \
sg_tablesize: 128, \
cmd_per_lun: 1, \
- use_clustering: DISABLE_CLUSTERING, \
- use_new_eh_code: 1}
+ use_clustering: DISABLE_CLUSTERING }
#ifndef HOSTS_C
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index e7574a9b5..1d1c27141 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -88,7 +88,6 @@ Scsi_CD *scsi_CDs;
static int *sr_sizes;
static int *sr_blocksizes;
-static int *sr_hardsizes;
static int sr_open(struct cdrom_device_info *, int);
void get_sectorsize(int);
@@ -218,8 +217,8 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
(SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) |
SCpnt->sense_buffer[6];
- if (SCpnt->request.bh != NULL)
- block_sectors = SCpnt->request.bh->b_size >> 9;
+ if (SCpnt->request.bio != NULL)
+ block_sectors = bio_sectors(SCpnt->request.bio);
if (block_sectors < 4)
block_sectors = 4;
if (scsi_CDs[device_nr].device->sector_size == 2048)
@@ -327,11 +326,14 @@ static int sr_scatter_pad(Scsi_Cmnd *SCpnt, int s_size)
}
if (old_sg) {
memcpy(sg + i, old_sg, SCpnt->use_sg * sizeof(struct scatterlist));
- memcpy(bbpnt + i, old_bbpnt, SCpnt->use_sg * sizeof(void *));
+ if (old_bbpnt)
+ memcpy(bbpnt + i, old_bbpnt, SCpnt->use_sg * sizeof(void *));
scsi_free(old_sg, (((SCpnt->use_sg * sizeof(struct scatterlist)) +
(SCpnt->use_sg * sizeof(void *))) + 511) & ~511);
} else {
- sg[i].address = SCpnt->request_buffer;
+ sg[i].address = NULL;
+ sg[i].page = virt_to_page(SCpnt->request_buffer);
+ sg[i].offset = (unsigned long) SCpnt->request_buffer&~PAGE_MASK;
sg[i].length = SCpnt->request_bufflen;
}
@@ -341,7 +343,9 @@ static int sr_scatter_pad(Scsi_Cmnd *SCpnt, int s_size)
SCpnt->use_sg += i;
if (bsize) {
- sg[SCpnt->use_sg].address = back;
+ sg[SCpnt->use_sg].address = NULL;
+ sg[SCpnt->use_sg].page = virt_to_page(back);
+ sg[SCpnt->use_sg].offset = (unsigned long) back & ~PAGE_MASK;
bbpnt[SCpnt->use_sg] = back;
sg[SCpnt->use_sg].length = bsize;
SCpnt->use_sg++;
@@ -384,7 +388,12 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return 0;
}
- if ((SCpnt->request.cmd == WRITE) && !scsi_CDs[dev].device->writeable)
+ if (!(SCpnt->request.flags & REQ_CMD)) {
+ blk_dump_rq_flags(&SCpnt->request, "sr unsup command");
+ return 0;
+ }
+
+ if (rq_data_dir(&SCpnt->request) == WRITE && !scsi_CDs[dev].device->writeable)
return 0;
/*
@@ -404,7 +413,18 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return 0;
}
- block = SCpnt->request.sector / (s_size >> 9);
+ if (rq_data_dir(&SCpnt->request) == WRITE) {
+ if (!scsi_CDs[dev].device->writeable)
+ return 0;
+ SCpnt->cmnd[0] = WRITE_10;
+ SCpnt->sc_data_direction = SCSI_DATA_WRITE;
+ } else if (rq_data_dir(&SCpnt->request) == READ) {
+ SCpnt->cmnd[0] = READ_10;
+ SCpnt->sc_data_direction = SCSI_DATA_READ;
+ } else {
+ blk_dump_rq_flags(&SCpnt->request, "Unknown sr command");
+ return 0;
+ }
/*
* request doesn't start on hw block boundary, add scatter pads
@@ -415,19 +435,6 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
- switch (SCpnt->request.cmd) {
- case WRITE:
- SCpnt->cmnd[0] = WRITE_10;
- SCpnt->sc_data_direction = SCSI_DATA_WRITE;
- break;
- case READ:
- SCpnt->cmnd[0] = READ_10;
- SCpnt->sc_data_direction = SCSI_DATA_READ;
- break;
- default:
- printk("Unknown sr command %d\n", SCpnt->request.cmd);
- return 0;
- }
SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n",
devm,
@@ -437,6 +444,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ?
((SCpnt->lun << 5) & 0xe0) : 0;
+ block = SCpnt->request.sector / (s_size >> 9);
+
if (this_count > 0xffff)
this_count = 0xffff;
@@ -663,6 +672,7 @@ void get_sectorsize(int i)
scsi_CDs[i].needs_sector_size = 0;
sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
};
+ blk_queue_hardsect_size(blk_get_queue(MAJOR_NR), sector_size);
scsi_free(buffer, 512);
}
@@ -811,21 +821,14 @@ static int sr_init()
if (!sr_blocksizes)
goto cleanup_sizes;
- sr_hardsizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
- if (!sr_hardsizes)
- goto cleanup_blocksizes;
/*
* These are good guesses for the time being.
*/
- for (i = 0; i < sr_template.dev_max; i++) {
+ for (i = 0; i < sr_template.dev_max; i++)
sr_blocksizes[i] = 2048;
- sr_hardsizes[i] = 2048;
- }
+
blksize_size[MAJOR_NR] = sr_blocksizes;
- hardsect_size[MAJOR_NR] = sr_hardsizes;
return 0;
-cleanup_blocksizes:
- kfree(sr_blocksizes);
cleanup_sizes:
kfree(sr_sizes);
cleanup_cds:
@@ -897,7 +900,6 @@ void sr_finish()
else
read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */
- return;
}
static void sr_detach(Scsi_Device * SDp)
@@ -905,17 +907,18 @@ static void sr_detach(Scsi_Device * SDp)
Scsi_CD *cpnt;
int i;
- for (cpnt = scsi_CDs, i = 0; i < sr_template.dev_max; i++, cpnt++)
+ for (cpnt = scsi_CDs, i = 0; i < sr_template.dev_max; i++, cpnt++) {
if (cpnt->device == SDp) {
/*
- * Since the cdrom is read-only, no need to sync the device.
+ * Since the cdrom is read-only, no need to sync
+ * the device.
* We should be kind to our buffer cache, however.
*/
invalidate_device(MKDEV(MAJOR_NR, i), 0);
/*
- * Reset things back to a sane state so that one can re-load a new
- * driver (perhaps the same one).
+ * Reset things back to a sane state so that one can
+ * re-load a new driver (perhaps the same one).
*/
unregister_cdrom(&(cpnt->cdi));
cpnt->device = NULL;
@@ -926,7 +929,7 @@ static void sr_detach(Scsi_Device * SDp)
sr_sizes[i] = 0;
return;
}
- return;
+ }
}
static int __init init_sr(void)
@@ -948,13 +951,9 @@ static void __exit exit_sr(void)
kfree(sr_blocksizes);
sr_blocksizes = NULL;
- kfree(sr_hardsizes);
- sr_hardsizes = NULL;
}
- blksize_size[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
- blk_size[MAJOR_NR] = NULL;
read_ahead[MAJOR_NR] = 0;
+ blk_clear(MAJOR_NR);
sr_template.dev_max = 0;
}
diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
index dd2dd8647..97ed8bb36 100644
--- a/drivers/scsi/sym53c8xx.c
+++ b/drivers/scsi/sym53c8xx.c
@@ -642,10 +642,10 @@ spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
#define NCR_LOCK_NCB(np, flags) spin_lock_irqsave(&np->smp_lock, flags)
#define NCR_UNLOCK_NCB(np, flags) spin_unlock_irqrestore(&np->smp_lock, flags)
-#define NCR_LOCK_SCSI_DONE(np, flags) \
- spin_lock_irqsave(&io_request_lock, flags)
-#define NCR_UNLOCK_SCSI_DONE(np, flags) \
- spin_unlock_irqrestore(&io_request_lock, flags)
+#define NCR_LOCK_SCSI_DONE(host, flags) \
+ spin_lock_irqsave(&((host)->host_lock), flags)
+#define NCR_UNLOCK_SCSI_DONE(host, flags) \
+ spin_unlock_irqrestore(&((host)->host_lock), flags)
#else
@@ -656,8 +656,8 @@ spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
#define NCR_LOCK_NCB(np, flags) do { save_flags(flags); cli(); } while (0)
#define NCR_UNLOCK_NCB(np, flags) do { restore_flags(flags); } while (0)
-#define NCR_LOCK_SCSI_DONE(np, flags) do {;} while (0)
-#define NCR_UNLOCK_SCSI_DONE(np, flags) do {;} while (0)
+#define NCR_LOCK_SCSI_DONE(host, flags) do {;} while (0)
+#define NCR_UNLOCK_SCSI_DONE(host, flags) do {;} while (0)
#endif
@@ -13676,9 +13676,9 @@ static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n");
if (done_list) {
- NCR_LOCK_SCSI_DONE(np, flags);
+ NCR_LOCK_SCSI_DONE(done_list->host, flags);
ncr_flush_done_cmds(done_list);
- NCR_UNLOCK_SCSI_DONE(np, flags);
+ NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
}
}
@@ -13699,9 +13699,9 @@ static void sym53c8xx_timeout(unsigned long npref)
NCR_UNLOCK_NCB(np, flags);
if (done_list) {
- NCR_LOCK_SCSI_DONE(np, flags);
+ NCR_LOCK_SCSI_DONE(done_list->host, flags);
ncr_flush_done_cmds(done_list);
- NCR_UNLOCK_SCSI_DONE(np, flags);
+ NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
}
}
diff --git a/drivers/scsi/sym53c8xx.h b/drivers/scsi/sym53c8xx.h
index 2f5df986f..6b4d584d5 100644
--- a/drivers/scsi/sym53c8xx.h
+++ b/drivers/scsi/sym53c8xx.h
@@ -96,8 +96,9 @@ int sym53c8xx_release(struct Scsi_Host *);
this_id: 7, \
sg_tablesize: SCSI_NCR_SG_TABLESIZE, \
cmd_per_lun: SCSI_NCR_CMD_PER_LUN, \
- max_sectors: MAX_SEGMENTS*8, \
- use_clustering: DISABLE_CLUSTERING}
+ max_sectors: MAX_SEGMENTS*8, \
+ use_clustering: DISABLE_CLUSTERING, \
+ highmem_io: 1}
#else
diff --git a/drivers/scsi/sym53c8xx_2/sym53c8xx.h b/drivers/scsi/sym53c8xx_2/sym53c8xx.h
index d1d611f43..0f6114bda 100644
--- a/drivers/scsi/sym53c8xx_2/sym53c8xx.h
+++ b/drivers/scsi/sym53c8xx_2/sym53c8xx.h
@@ -109,7 +109,6 @@ int sym53c8xx_release(struct Scsi_Host *);
release: sym53c8xx_release, \
info: sym53c8xx_info, \
queuecommand: sym53c8xx_queue_command, \
- use_new_eh_code: 1, \
eh_abort_handler: sym53c8xx_eh_abort_handler, \
eh_device_reset_handler:sym53c8xx_eh_device_reset_handler, \
eh_bus_reset_handler: sym53c8xx_eh_bus_reset_handler, \
@@ -119,7 +118,8 @@ int sym53c8xx_release(struct Scsi_Host *);
this_id: 7, \
sg_tablesize: 0, \
cmd_per_lun: 0, \
- use_clustering: DISABLE_CLUSTERING}
+ use_clustering: DISABLE_CLUSTERING, \
+ highmem_io: 1}
#endif /* defined(HOSTS_C) || defined(MODULE) */
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index fa43752c2..68157d736 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -138,18 +138,11 @@ 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.smp_lock);
-#define SYM_LOCK_HCB(np, flags) spin_lock_irqsave(&np->s.smp_lock, flags)
-#define SYM_UNLOCK_HCB(np, flags) spin_unlock_irqrestore(&np->s.smp_lock, flags)
-
-#define SYM_LOCK_SCSI(np, flags) \
- spin_lock_irqsave(&io_request_lock, flags)
-#define SYM_UNLOCK_SCSI(np, flags) \
- spin_unlock_irqrestore(&io_request_lock, flags)
-
-/* Ugly, but will make things easier if this locking will ever disappear */
-#define SYM_LOCK_SCSI_NOSAVE(np) spin_lock_irq(&io_request_lock)
-#define SYM_UNLOCK_SCSI_NORESTORE(np) spin_unlock_irq(&io_request_lock)
+#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)
+#define SYM_UNLOCK_HCB(np, flags) \
+ spin_unlock_irqrestore(&np->s.host->host_lock, flags)
/*
* These simple macros limit expression involving
@@ -966,14 +959,18 @@ int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
{
hcb_p np = SYM_SOFTC_PTR(cmd);
ucmd_p ucp = SYM_UCMD_PTR(cmd);
- u_long flags;
int sts = 0;
+#if 0
+ u_long flags;
+#endif
cmd->scsi_done = done;
cmd->host_scribble = NULL;
memset(ucp, 0, sizeof(*ucp));
+#if 0
SYM_LOCK_HCB(np, flags);
+#endif
/*
* Shorten our settle_time if needed for
@@ -999,7 +996,9 @@ int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
sym_insque_tail(&ucp->link_cmdq, &np->s.wait_cmdq);
}
out:
+#if 0
SYM_UNLOCK_HCB(np, flags);
+#endif
return 0;
}
@@ -1010,21 +1009,21 @@ out:
static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
{
unsigned long flags;
- unsigned long flags1;
hcb_p np = (hcb_p) dev_id;
if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("[");
- SYM_LOCK_SCSI(np, flags1);
SYM_LOCK_HCB(np, flags);
sym_interrupt(np);
+ /*
+ * push queue walk-through to tasklet
+ */
if (!sym_que_empty(&np->s.wait_cmdq) && !np->s.settle_time_valid)
sym_requeue_awaiting_cmds(np);
SYM_UNLOCK_HCB(np, flags);
- SYM_UNLOCK_SCSI(np, flags1);
if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n");
}
@@ -1036,9 +1035,7 @@ static void sym53c8xx_timer(unsigned long npref)
{
hcb_p np = (hcb_p) npref;
unsigned long flags;
- unsigned long flags1;
- SYM_LOCK_SCSI(np, flags1);
SYM_LOCK_HCB(np, flags);
sym_timer(np);
@@ -1047,7 +1044,6 @@ static void sym53c8xx_timer(unsigned long npref)
sym_requeue_awaiting_cmds(np);
SYM_UNLOCK_HCB(np, flags);
- SYM_UNLOCK_SCSI(np, flags1);
}
@@ -1209,9 +1205,7 @@ finish:
ep->timer.data = (u_long)cmd;
ep->timed_out = 1; /* Be pessimistic for once :) */
add_timer(&ep->timer);
- SYM_UNLOCK_SCSI_NORESTORE(np);
down(&ep->sem);
- SYM_LOCK_SCSI_NOSAVE(np);
if (ep->timed_out)
sts = -2;
}
@@ -1975,6 +1969,7 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
goto attach_failed;
#endif
host_data->ncb = np;
+ np->s.host = instance;
SYM_INIT_LOCK_HCB(np);
@@ -2140,6 +2135,7 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
instance->max_cmd_len = 16;
#endif
instance->select_queue_depths = sym53c8xx_select_queue_depths;
+ instance->highmem_io = 1;
SYM_UNLOCK_HCB(np, flags);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index d29896045..4db72ce33 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -455,11 +455,11 @@ struct sym_shcb {
char chip_name[8];
struct pci_dev *device;
+ struct Scsi_Host *host;
+
u_char bus; /* PCI BUS number */
u_char device_fn; /* PCI BUS device and function */
- spinlock_t smp_lock; /* Lock for SMP threading */
-
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 */
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 1160f8a5f..ce06b7222 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.17a"
+#define SYM_DRIVER_NAME "sym-2.1.16a"
#ifdef __FreeBSD__
#include <dev/sym/sym_glue.h>
@@ -4689,9 +4689,8 @@ out_reject:
return;
out_clrack:
OUTL_DSP (SCRIPTA_BA (np, clrack));
- return;
out_stuck:
- return;
+ ;
}
/*
@@ -5224,10 +5223,8 @@ static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln)
* And accept tagged commands now.
*/
lp->head.itlq_tbl_sa = cpu_to_scr(vtobus(lp->itlq_tbl));
-
- return;
fail:
- return;
+ ;
}
/*
@@ -5790,13 +5787,6 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw)
goto attach_failed;
/*
- * Allocate the array of lists of CCBs hashed by DSA.
- */
- np->ccbh = sym_calloc(sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
- if (!np->ccbh)
- goto attach_failed;
-
- /*
* Initialyze the CCB free and busy queues.
*/
sym_que_init(&np->free_ccbq);
@@ -5987,8 +5977,6 @@ void sym_hcb_free(hcb_p np)
sym_mfree_dma(cp, sizeof(*cp), "CCB");
}
}
- if (np->ccbh)
- sym_mfree(np->ccbh, sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
if (np->badluntbl)
sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
diff --git a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
index f832f96e4..1d2988d73 100644
--- a/drivers/scsi/u14-34f.h
+++ b/drivers/scsi/u14-34f.h
@@ -30,7 +30,6 @@ int u14_34f_biosparam(Disk *, kdev_t, int *);
this_id: 7, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 1 /* Enable new error code */ \
}
#endif
diff --git a/drivers/scsi/wd7000.h b/drivers/scsi/wd7000.h
index d941fdf2c..c90e07f78 100644
--- a/drivers/scsi/wd7000.h
+++ b/drivers/scsi/wd7000.h
@@ -57,6 +57,5 @@ int wd7000_biosparam (Disk *, kdev_t, int *);
cmd_per_lun: 1, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
- use_new_eh_code: 0 \
}
#endif
diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c
index 97b247fa3..9a413f217 100644
--- a/drivers/sgi/char/graphics.c
+++ b/drivers/sgi/char/graphics.c
@@ -196,7 +196,6 @@ sgi_graphics_close (struct inode *inode, struct file *file)
int board = GRAPHICS_CARD (inode->i_rdev);
/* Tell the rendering manager that one client is going away */
- lock_kernel();
rrm_close (inode, file);
/* Was this file handle from the board owner?, clear it */
@@ -206,7 +205,6 @@ sgi_graphics_close (struct inode *inode, struct file *file)
(*cards [board].g_reset_console)();
enable_gconsole ();
}
- unlock_kernel();
return 0;
}
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
index 8162e0eea..ec698d968 100644
--- a/drivers/sgi/char/shmiq.c
+++ b/drivers/sgi/char/shmiq.c
@@ -79,11 +79,13 @@ static struct {
/* /dev/qcntlN attached memory regions, location and size of the event queue */
static struct {
- int opened; /* if this device has been opened */
- void *shmiq_vaddr; /* mapping in kernel-land */
- int tail; /* our copy of the shmiq->tail */
- int events;
- int mapped;
+ int opened;
+ void *shmiq_vaddr; /* mapping in kernel-land */
+ spinlock_t shmiq_lock:SPIN_LOCK_UNLOCKED;
+ /* protects vaddr and opened */
+ int tail; /* our copy of the shmiq->tail */
+ int events;
+ int mapped;
wait_queue_head_t proc_list;
struct fasync_struct *fasync;
@@ -328,12 +330,11 @@ shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma)
size = vma->vm_end - vma->vm_start;
start = vma->vm_start;
- lock_kernel();
- mem = (unsigned long) shmiqs [minor].shmiq_vaddr = vmalloc_uncached (size);
- if (!mem) {
- unlock_kernel();
+ mem = vmalloc_uncached (size);
+ if (!mem)
return -EINVAL;
- }
+ spin_lock( &shmiqs [minor].shmiq_lock );
+ hmiqs [minor].shmiq_vaddr = mem;
/* Prevent the swapper from considering these pages for swap and touching them */
vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
@@ -342,13 +343,12 @@ shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma)
/* Uncache the pages */
vma->vm_page_prot = PAGE_USERIO;
- error = vmap_page_range (vma->vm_start, size, mem);
shmiqs [minor].tail = 0;
/* Init the shared memory input queue */
+ spin_unlock( &shmiqs [minor].shmiq_lock );
memset (shmiqs [minor].shmiq_vaddr, 0, size);
- unlock_kernel();
-
+ error = vmap_page_range (vma->vm_start, size, mem);
return error;
}
@@ -393,13 +393,16 @@ shmiq_qcntl_open (struct inode *inode, struct file *filp)
minor--;
if (minor > MAX_SHMI_QUEUES)
return -EINVAL;
+ spin_lock( &shmiqs [minor].shmiq_lock );
if (shmiqs [minor].opened)
+ {
+ spin_unlock( &shmiqs [minor].shmiq_lock );
return -EBUSY;
+ }
- lock_kernel ();
shmiqs [minor].opened = 1;
shmiqs [minor].shmiq_vaddr = 0;
- unlock_kernel ();
+ spin_unlock( &shmiqs [minor].shmiq_lock );
return 0;
}
@@ -429,18 +432,21 @@ shmiq_qcntl_close (struct inode *inode, struct file *filp)
if (minor > MAX_SHMI_QUEUES)
return -EINVAL;
- if (shmiqs [minor].opened == 0)
+
+ spin_lock( &shmiqs [minor].shmiq_lock );
+ if (shmiqs [minor].opened == 0) {
+ spin_unlock( &shmiqs [minor].shmiq_lock );
return -EINVAL;
+ }
- lock_kernel ();
shmiq_qcntl_fasync (-1, filp, 0);
- shmiqs [minor].opened = 0;
+ shmiqs [minor].opened = 0;
shmiqs [minor].mapped = 0;
shmiqs [minor].events = 0;
shmiqs [minor].fasync = 0;
vfree (shmiqs [minor].shmiq_vaddr);
shmiqs [minor].shmiq_vaddr = 0;
- unlock_kernel ();
+ spin_unlock( &shmiqs [minor].shmiq_lock );
return 0;
}
diff --git a/drivers/sgi/char/streamable.c b/drivers/sgi/char/streamable.c
index 1d2a65c2a..6e4f0e34f 100644
--- a/drivers/sgi/char/streamable.c
+++ b/drivers/sgi/char/streamable.c
@@ -221,9 +221,7 @@ sgi_mouse_open (struct inode *inode, struct file *file)
static int
sgi_mouse_close (struct inode *inode, struct file *filp)
{
- lock_kernel();
mouse_opened = 0;
- unlock_kernel();
return 0;
}
diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c
index 8e86be1b6..07fdc87c0 100644
--- a/drivers/sound/ad1816.c
+++ b/drivers/sound/ad1816.c
@@ -1258,7 +1258,7 @@ static int __initdata irq = -1;
static int __initdata dma = -1;
static int __initdata dma2 = -1;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
struct pci_dev *ad1816_dev = NULL;
static int activated = 1;
@@ -1280,7 +1280,7 @@ MODULE_PARM(dma2,"i");
MODULE_PARM(ad1816_clockfreq,"i");
MODULE_PARM(options,"i");
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
{
@@ -1407,7 +1407,7 @@ int __init ad1816_probe_isapnp(struct address_info *hw_config)
static int __init init_ad1816(void)
{
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if(isapnp && (ad1816_probe_isapnp(&cfg) < 0) ) {
printk(KERN_NOTICE "ad1816: No ISAPnP cards found, trying standard ones...\n");
isapnp = 0;
@@ -1447,7 +1447,7 @@ static void __exit cleanup_ad1816 (void)
}
nr_ad1816_devs=0;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if(activated)
if(ad1816_dev)
ad1816_dev->deactivate(ad1816_dev);
diff --git a/drivers/sound/awe_wave.c b/drivers/sound/awe_wave.c
index cdc860916..050d40f94 100644
--- a/drivers/sound/awe_wave.c
+++ b/drivers/sound/awe_wave.c
@@ -26,9 +26,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
#include <linux/isapnp.h>
-#endif
#include "sound_config.h"
@@ -205,7 +203,7 @@ static awe_chan_info channels[AWE_MAX_CHANNELS];
int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static int isapnp = -1;
#else
static int isapnp = 0;
@@ -4772,7 +4770,7 @@ awe_detect_base(int addr)
return 1;
}
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static struct {
unsigned short card_vendor, card_device;
unsigned short vendor;
@@ -4841,7 +4839,7 @@ awe_detect(void)
{
int base;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if (isapnp) {
if (awe_probe_isapnp(&io) < 0) {
printk(KERN_ERR "AWE32: No ISAPnP cards found\n");
@@ -6132,7 +6130,7 @@ int __init attach_awe(void)
void __exit unload_awe(void)
{
_unload_awe();
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if (isapnp)
awe_deactivate_isapnp();
#endif /* isapnp */
diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c
index fe9108996..a7af154a2 100644
--- a/drivers/sound/cmpci.c
+++ b/drivers/sound/cmpci.c
@@ -2496,7 +2496,6 @@ static int cm_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2694,7 +2693,6 @@ static int cm_dmfm_open(struct inode *inode, struct file *file)
outb(1, s->iosynth+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
diff --git a/drivers/sound/maestro3.c b/drivers/sound/maestro3.c
index 26fe7a67b..b18da793d 100644
--- a/drivers/sound/maestro3.c
+++ b/drivers/sound/maestro3.c
@@ -2036,7 +2036,6 @@ static int m3_open(struct inode *inode, struct file *file)
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- MOD_INC_USE_COUNT;
up(&s->open_sem);
spin_unlock_irqrestore(&s->lock, flags);
return 0;
@@ -2075,7 +2074,6 @@ static int m3_release(struct inode *inode, struct file *file)
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -2142,14 +2140,12 @@ static int m3_open_mixdev(struct inode *inode, struct file *file)
int minor = MINOR(inode->i_rdev);
struct m3_card *card = devs;
- MOD_INC_USE_COUNT;
for (card = devs; card != NULL; card = card->next) {
if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor))
break;
}
if (!card) {
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
@@ -2160,7 +2156,6 @@ static int m3_open_mixdev(struct inode *inode, struct file *file)
static int m3_release_mixdev(struct inode *inode, struct file *file)
{
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -2173,6 +2168,7 @@ static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
}
static struct file_operations m3_mixer_fops = {
+ owner: THIS_MODULE,
llseek: no_llseek,
ioctl: m3_ioctl_mixdev,
open: m3_open_mixdev,
@@ -2546,6 +2542,7 @@ static void m3_enable_ints(struct m3_card *card)
}
static struct file_operations m3_audio_fops = {
+ owner: THIS_MODULE,
llseek: &no_llseek,
read: &m3_read,
write: &m3_write,
diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c
index 153d270fa..9791d7a7c 100644
--- a/drivers/sound/opl3sa2.c
+++ b/drivers/sound/opl3sa2.c
@@ -99,7 +99,7 @@
#define CHIPSET_OPL3SA2 0
#define CHIPSET_OPL3SA3 1
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
#define OPL3SA2_CARDS_MAX 4
#else
#define OPL3SA2_CARDS_MAX 1
@@ -147,7 +147,7 @@ static int __initdata dma2 = -1;
static int __initdata ymode = -1;
static int __initdata loopback = -1;
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
/* PnP specific parameters */
static int __initdata isapnp = 1;
static int __initdata multiple = 1;
@@ -191,7 +191,7 @@ MODULE_PARM_DESC(ymode, "Set Yamaha 3D enhancement mode (0 = Desktop/Normal, 1 =
MODULE_PARM(loopback, "i");
MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)");
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
MODULE_PARM(isapnp, "i");
MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled");
@@ -807,7 +807,7 @@ static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
}
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
struct isapnp_device_id isapnp_opl3sa2_list[] __initdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
@@ -888,7 +888,7 @@ static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,
return 0;
}
-#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
+#endif /* __ISAPNP__ */
/* End of component functions */
@@ -909,9 +909,9 @@ static int __init init_opl3sa2(void)
max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1;
for(card = 0; card < max; card++, opl3sa2_cards_num++) {
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
/*
- * Please remember that even with CONFIG_ISAPNP defined one
+ * Please remember that even with __ISAPNP__ defined one
* should still be able to disable PNP support for this
* single driver!
*/
@@ -1039,7 +1039,7 @@ static void __exit cleanup_opl3sa2(void)
unload_opl3sa2_mss(&cfg_mss[card]);
unload_opl3sa2(&cfg[card], card);
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if(opl3sa2_activated[card] && opl3sa2_dev[card]) {
opl3sa2_dev[card]->deactivate(opl3sa2_dev[card]);
@@ -1058,7 +1058,7 @@ module_exit(cleanup_opl3sa2);
static int __init setup_opl3sa2(char *str)
{
/* io, irq, dma, dma2,... */
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
int ints[11];
#else
int ints[9];
@@ -1073,7 +1073,7 @@ static int __init setup_opl3sa2(char *str)
mpu_io = ints[6];
ymode = ints[7];
loopback = ints[8];
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
isapnp = ints[9];
multiple = ints[10];
#endif
diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c
index 64e52ddd5..779036ab0 100644
--- a/drivers/sound/sb_card.c
+++ b/drivers/sound/sb_card.c
@@ -69,7 +69,7 @@
#include "sb_mixer.h"
#include "sb.h"
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
#define SB_CARDS_MAX 5
#else
#define SB_CARDS_MAX 1
@@ -196,7 +196,7 @@ struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL},
*opl_dev[SB_CARDS_MAX] = {NULL};
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
static int isapnp = 1;
static int isapnpjump = 0;
static int multiple = 1;
@@ -226,7 +226,7 @@ MODULE_PARM(sm_games, "i");
MODULE_PARM(esstype, "i");
MODULE_PARM(acer, "i");
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
MODULE_PARM(isapnp, "i");
MODULE_PARM(isapnpjump, "i");
MODULE_PARM(multiple, "i");
@@ -251,7 +251,7 @@ MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
MODULE_PARM_DESC(esstype, "ESS chip type");
MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
/* Please add new entries at the end of the table */
static struct {
@@ -914,8 +914,8 @@ static int __init init_sb(void)
printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
for(card = 0; card < max; card++, sb_cards_num++) {
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
- /* Please remember that even with CONFIG_ISAPNP defined one
+#ifdef __ISAPNP__
+ /* Please remember that even with __ISAPNP__ defined one
* should still be able to disable PNP support for this
* single driver! */
if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
@@ -1002,7 +1002,7 @@ static void __exit cleanup_sb(void)
if (sbmpu[i])
unload_sbmpu(&cfg_mpu[i]);
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#ifdef __ISAPNP__
if(!audio_activated[i] && sb_dev[i])
sb_dev[i]->deactivate(sb_dev[i]);
if(!mpu_activated[i] && mpu_dev[i])
diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c
index 984fc2394..de05ee691 100644
--- a/drivers/sound/sound_core.c
+++ b/drivers/sound/sound_core.c
@@ -115,7 +115,6 @@ static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list,
*list=s;
- MOD_INC_USE_COUNT;
return n;
}
@@ -133,7 +132,6 @@ static void __sound_remove_unit(struct sound_unit **list, int unit)
*list=p->next;
devfs_unregister (p->de);
kfree(p);
- MOD_DEC_USE_COUNT;
return;
}
list=&(p->next);
diff --git a/drivers/usb/CDCEther.c b/drivers/usb/CDCEther.c
index f00b3fceb..f8eda80f0 100644
--- a/drivers/usb/CDCEther.c
+++ b/drivers/usb/CDCEther.c
@@ -82,9 +82,9 @@ static void read_bulk_callback( struct urb *urb )
ether_dev->flags |= CDC_ETHER_RX_BUSY;
switch ( urb->status ) {
- case USB_ST_NOERROR:
+ case 0:
break;
- case USB_ST_NORESPONSE:
+ case -ETIMEDOUT:
dbg( "no repsonse in BULK IN" );
ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
break;
@@ -179,9 +179,9 @@ static void write_bulk_callback( struct urb *urb )
// return;
//
// switch ( urb->status ) {
-// case USB_ST_NOERROR:
+// case 0:
// break;
-// case USB_ST_URB_KILLED:
+// case -ENOENT:
// return;
// default:
// info("intr status %d", urb->status);
@@ -337,13 +337,9 @@ static int CDCEther_open(struct net_device *net)
ether_dev_t *ether_dev = (ether_dev_t *)net->priv;
int res;
- // We are finally getting used!
- MOD_INC_USE_COUNT;
-
// Turn on the USB and let the packets flow!!!
if ( (res = enable_net_traffic( ether_dev )) ) {
err( __FUNCTION__ "can't enable_net_traffic() - %d", res );
- MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -391,9 +387,6 @@ static int CDCEther_close( struct net_device *net )
usb_unlink_urb( &ether_dev->tx_urb );
usb_unlink_urb( &ether_dev->intr_urb );
- // We are not being used now.
- MOD_DEC_USE_COUNT;
-
// That's it. I'm done.
return 0;
}
@@ -480,6 +473,7 @@ static void CDCEther_set_multicast( struct net_device *net )
i++, mclist = mclist->next) {
memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
}
+#if 0
usb_control_msg(ether_dev->usb,
usb_sndctrlpipe(ether_dev->usb, 0),
SET_ETHERNET_MULTICAST_FILTER, /* request */
@@ -489,11 +483,13 @@ static void CDCEther_set_multicast( struct net_device *net )
buff,
(6* net->mc_count), /* size */
HZ); /* timeout */
+#endif
kfree(buff);
}
-
+
+#if 0
CDC_SetEthernetPacketFilter(ether_dev);
-
+#endif
// Tell the kernel to start giving frames to us again.
netif_wake_queue(net);
}
@@ -1210,6 +1206,7 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum,
// Now that we have an ethernet device, let's set it up
// (And I don't mean "set [it] up the bomb".)
net->priv = ether_dev;
+ SET_MODULE_OWNER(net);
net->open = CDCEther_open;
net->stop = CDCEther_close;
net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT;
diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in
index c15da6f3c..c1792a622 100644
--- a/drivers/usb/Config.in
+++ b/drivers/usb/Config.in
@@ -9,7 +9,7 @@ if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then
bool ' USB verbose debug messages' CONFIG_USB_DEBUG
comment 'Miscellaneous USB options'
- bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
+ bool ' USB device filesystem' CONFIG_USB_DEVICEFS
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH
else
diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c
index 2f9aa3cfe..593e4671d 100644
--- a/drivers/usb/audio.c
+++ b/drivers/usb/audio.c
@@ -899,7 +899,7 @@ static void usbin_completed(struct urb *urb)
struct usbin *u = &as->usbin;
unsigned long flags;
unsigned int mask;
- int suret = USB_ST_NOERROR;
+ int suret = 0;
#if 0
printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -917,7 +917,7 @@ static void usbin_completed(struct urb *urb)
if (!usbin_retire_desc(u, urb) &&
u->flags & FLG_RUNNING &&
!usbin_prepare_desc(u, urb) &&
- (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+ (suret = usb_submit_urb(urb)) == 0) {
u->flags |= mask;
} else {
u->flags &= ~(mask | FLG_RUNNING);
@@ -964,7 +964,7 @@ static void usbin_sync_completed(struct urb *urb)
struct usbin *u = &as->usbin;
unsigned long flags;
unsigned int mask;
- int suret = USB_ST_NOERROR;
+ int suret = 0;
#if 0
printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -982,7 +982,7 @@ static void usbin_sync_completed(struct urb *urb)
if (!usbin_sync_retire_desc(u, urb) &&
u->flags & FLG_RUNNING &&
!usbin_sync_prepare_desc(u, urb) &&
- (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+ (suret = usb_submit_urb(urb)) == 0) {
u->flags |= mask;
} else {
u->flags &= ~(mask | FLG_RUNNING);
@@ -1257,7 +1257,7 @@ static void usbout_completed(struct urb *urb)
struct usbout *u = &as->usbout;
unsigned long flags;
unsigned int mask;
- int suret = USB_ST_NOERROR;
+ int suret = 0;
#if 0
printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -1275,7 +1275,7 @@ static void usbout_completed(struct urb *urb)
if (!usbout_retire_desc(u, urb) &&
u->flags & FLG_RUNNING &&
!usbout_prepare_desc(u, urb) &&
- (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+ (suret = usb_submit_urb(urb)) == 0) {
u->flags |= mask;
} else {
u->flags &= ~(mask | FLG_RUNNING);
@@ -1329,7 +1329,7 @@ static void usbout_sync_completed(struct urb *urb)
struct usbout *u = &as->usbout;
unsigned long flags;
unsigned int mask;
- int suret = USB_ST_NOERROR;
+ int suret = 0;
#if 0
printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
@@ -1347,7 +1347,7 @@ static void usbout_sync_completed(struct urb *urb)
if (!usbout_sync_retire_desc(u, urb) &&
u->flags & FLG_RUNNING &&
!usbout_sync_prepare_desc(u, urb) &&
- (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) {
+ (suret = usb_submit_urb(urb)) == 0) {
u->flags |= mask;
} else {
u->flags &= ~(mask | FLG_RUNNING);
@@ -3362,28 +3362,48 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr
struct usb_device *dev = state->s->usbdev;
unsigned char data[1];
#endif
+ unsigned char nr_logical_channels, i;
usb_audio_recurseunit(state, ftr[4]);
+
+ if (ftr[5] == 0 ) {
+ printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]);
+ return;
+ }
+
if (state->nrchannels == 0) {
printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]);
return;
}
if (state->nrchannels > 2)
printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
- if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) {
- printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n");
- mchftr = ftr[6];
- chftr = 0;
- } else {
- if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) {
- printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]);
- return;
+
+ nr_logical_channels=(ftr[0]-7)/ftr[5]-1;
+
+ if (nr_logical_channels != state->nrchannels) {
+ printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels);
+
+ if (state->nrchannels == 1 && nr_logical_channels==0) {
+ printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n");
+ } else if (state->nrchannels == 1 && nr_logical_channels==2) {
+ printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n");
+ state->nrchannels=nr_logical_channels;
+ } else {
+ printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n");
}
- mchftr = ftr[6];
+ }
+
+ /* There is always a master channel */
+ mchftr = ftr[6];
+ /* Binary AND over logical channels if they exist */
+ if (nr_logical_channels) {
chftr = ftr[6+ftr[5]];
- if (state->nrchannels > 1)
- chftr &= ftr[6+2*ftr[5]];
+ for (i = 2; i <= nr_logical_channels; i++)
+ chftr &= ftr[6+i*ftr[5]];
+ } else {
+ chftr = 0;
}
+
/* volume control */
if (chftr & 2) {
ch = getmixchannel(state, getvolchannel(state));
diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c
index 1b8e8190a..c4786295e 100644
--- a/drivers/usb/bluetooth.c
+++ b/drivers/usb/bluetooth.c
@@ -1,11 +1,15 @@
/*
- * bluetooth.c Version 0.12
+ * bluetooth.c Version 0.13
*
* Copyright (c) 2000, 2001 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
*
* USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
*
+ * (2001/11/30) Version 0.13 gkh
+ * - added locking patch from Masoodur Rahman <rmasoodu@in.ibm.com>
+ * - removed active variable, as open_count will do.
+ *
* (2001/07/09) Version 0.12 gkh
* - removed in_interrupt() call, as it doesn't make sense to do
* that anymore.
@@ -118,7 +122,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.12"
+#define DRIVER_VERSION "v0.13"
#define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
#define DRIVER_DESC "USB Bluetooth tty driver"
@@ -170,8 +174,8 @@ struct usb_bluetooth {
struct tty_struct * tty; /* the coresponding tty for this port */
unsigned char minor; /* the starting minor number for this device */
- char active; /* someone has this device open */
int throttle; /* throttled by tty layer */
+ int open_count;
__u8 control_out_bInterfaceNum;
struct urb * control_urb_pool[NUM_CONTROL_URBS];
@@ -200,6 +204,7 @@ struct usb_bluetooth {
unsigned char int_buffer[EVENT_BUFFER_SIZE];
unsigned int bulk_packet_pos;
unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */
+ struct semaphore lock;
};
@@ -361,43 +366,46 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp)
return -ENODEV;
}
- if (bluetooth->active) {
- dbg (__FUNCTION__ " - device already open");
- return -EINVAL;
- }
-
- /* set up our structure making the tty driver remember our object, and us it */
- tty->driver_data = bluetooth;
- bluetooth->tty = tty;
+ down (&bluetooth->lock);
+
+ ++bluetooth->open_count;
+ if (bluetooth->open_count == 1) {
+ /* set up our structure making the tty driver remember our object, and us it */
+ tty->driver_data = bluetooth;
+ bluetooth->tty = tty;
- /* force low_latency on so that our tty_push actually forces the data through,
- * otherwise it is scheduled, and with high data rates (like with OHCI) data
- * can get lost. */
- bluetooth->tty->low_latency = 1;
+ /* force low_latency on so that our tty_push actually forces the data through,
+ * otherwise it is scheduled, and with high data rates (like with OHCI) data
+ * can get lost. */
+ bluetooth->tty->low_latency = 1;
- bluetooth->active = 1;
-
- /* Reset the packet position counters */
- bluetooth->int_packet_pos = 0;
- bluetooth->bulk_packet_pos = 0;
+ /* Reset the packet position counters */
+ bluetooth->int_packet_pos = 0;
+ bluetooth->bulk_packet_pos = 0;
#ifndef BTBUGGYHARDWARE
- /* Start reading from the device */
- FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev,
- usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
- bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size,
- bluetooth_read_bulk_callback, bluetooth);
- result = usb_submit_urb(bluetooth->read_urb);
- if (result)
- dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
+ /* Start reading from the device */
+ FILL_BULK_URB (bluetooth->read_urb, bluetooth->dev,
+ usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+ bluetooth->bulk_in_buffer,
+ bluetooth->bulk_in_buffer_size,
+ bluetooth_read_bulk_callback, bluetooth);
+ result = usb_submit_urb(bluetooth->read_urb);
+ if (result)
+ dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
#endif
- FILL_INT_URB(bluetooth->interrupt_in_urb, bluetooth->dev,
- usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
- bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size,
- bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval);
- result = usb_submit_urb(bluetooth->interrupt_in_urb);
- if (result)
- dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
+ FILL_INT_URB (bluetooth->interrupt_in_urb, bluetooth->dev,
+ usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
+ bluetooth->interrupt_in_buffer,
+ bluetooth->interrupt_in_buffer_size,
+ bluetooth_int_callback, bluetooth,
+ bluetooth->interrupt_in_interval);
+ result = usb_submit_urb(bluetooth->interrupt_in_urb);
+ if (result)
+ dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
+ }
+
+ up(&bluetooth->lock);
return 0;
}
@@ -414,18 +422,24 @@ static void bluetooth_close (struct tty_struct *tty, struct file * filp)
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not opened");
return;
}
- /* shutdown any bulk reads and writes that might be going on */
- for (i = 0; i < NUM_BULK_URBS; ++i)
- usb_unlink_urb (bluetooth->write_urb_pool[i]);
- usb_unlink_urb (bluetooth->read_urb);
- usb_unlink_urb (bluetooth->interrupt_in_urb);
+ down (&bluetooth->lock);
+
+ --bluetooth->open_count;
+ if (bluetooth->open_count <= 0) {
+ bluetooth->open_count = 0;
- bluetooth->active = 0;
+ /* shutdown any bulk reads and writes that might be going on */
+ for (i = 0; i < NUM_BULK_URBS; ++i)
+ usb_unlink_urb (bluetooth->write_urb_pool[i]);
+ usb_unlink_urb (bluetooth->read_urb);
+ usb_unlink_urb (bluetooth->interrupt_in_urb);
+ }
+ up(&bluetooth->lock);
}
@@ -447,7 +461,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign
dbg(__FUNCTION__ " - %d byte(s)", count);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not opened");
return -EINVAL;
}
@@ -572,7 +586,7 @@ static int bluetooth_write_room (struct tty_struct *tty)
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return -EINVAL;
}
@@ -598,7 +612,7 @@ static int bluetooth_chars_in_buffer (struct tty_struct *tty)
return -ENODEV;
}
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return -EINVAL;
}
@@ -624,7 +638,7 @@ static void bluetooth_throttle (struct tty_struct * tty)
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return;
}
@@ -645,7 +659,7 @@ static void bluetooth_unthrottle (struct tty_struct * tty)
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return;
}
@@ -664,7 +678,7 @@ static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned
dbg(__FUNCTION__ " - cmd 0x%.4x", cmd);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return -ENODEV;
}
@@ -684,7 +698,7 @@ static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old)
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return;
}
@@ -706,7 +720,7 @@ void btusb_enable_bulk_read(struct tty_struct *tty){
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return;
}
@@ -731,7 +745,7 @@ void btusb_disable_bulk_read(struct tty_struct *tty){
dbg(__FUNCTION__);
- if (!bluetooth->active) {
+ if (!bluetooth->open_count) {
dbg (__FUNCTION__ " - device not open");
return;
}
@@ -961,7 +975,7 @@ static void bluetooth_read_bulk_callback (struct urb *urb)
}
exit:
- if (!bluetooth || !bluetooth->active)
+ if (!bluetooth || !bluetooth->open_count)
return;
FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev,
@@ -1102,6 +1116,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum,
bluetooth->minor = minor;
bluetooth->tqueue.routine = bluetooth_softint;
bluetooth->tqueue.data = bluetooth;
+ init_MUTEX(&bluetooth->lock);
/* record the interface number for the control out */
bluetooth->control_out_bInterfaceNum = control_out_endpoint;
@@ -1217,10 +1232,10 @@ static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr)
int i;
if (bluetooth) {
- if ((bluetooth->active) && (bluetooth->tty))
+ if ((bluetooth->open_count) && (bluetooth->tty))
tty_hangup(bluetooth->tty);
- bluetooth->active = 0;
+ bluetooth->open_count = 0;
if (bluetooth->read_urb) {
usb_unlink_urb (bluetooth->read_urb);
diff --git a/drivers/usb/dabusb.c b/drivers/usb/dabusb.c
index 6607d8f9b..123bbc322 100644
--- a/drivers/usb/dabusb.c
+++ b/drivers/usb/dabusb.c
@@ -622,7 +622,6 @@ static int dabusb_release (struct inode *inode, struct file *file)
dbg("dabusb_release");
- lock_kernel();
down (&s->mutex);
dabusb_stop (s);
dabusb_free_buffers (s);
@@ -636,7 +635,6 @@ static int dabusb_release (struct inode *inode, struct file *file)
wake_up (&s->remove_ok);
s->opened = 0;
- unlock_kernel();
return 0;
}
diff --git a/drivers/usb/dc2xx.c b/drivers/usb/dc2xx.c
index e8549748a..931a274dc 100644
--- a/drivers/usb/dc2xx.c
+++ b/drivers/usb/dc2xx.c
@@ -199,7 +199,7 @@ static ssize_t camera_read (struct file *file,
retval = count;
break;
}
- if (retval != USB_ST_TIMEOUT)
+ if (retval != -ETIMEDOUT)
break;
interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
@@ -267,7 +267,7 @@ static ssize_t camera_write (struct file *file,
} else if (!result)
break;
- if (result == USB_ST_TIMEOUT) { /* NAK - delay a bit */
+ if (result == -ETIMEDOUT) { /* NAK - delay a bit */
if (!maxretry--) {
if (!bytes_written)
bytes_written = -ETIME;
diff --git a/drivers/usb/devio.c b/drivers/usb/devio.c
index 7978a9bd7..f88e46910 100644
--- a/drivers/usb/devio.c
+++ b/drivers/usb/devio.c
@@ -276,7 +276,7 @@ static void destroy_all_async(struct dev_state *ps)
list_del(&as->asynclist);
INIT_LIST_HEAD(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags);
- /* usb_unlink_urb calls the completion handler with status == USB_ST_URB_KILLED */
+ /* usb_unlink_urb calls the completion handler with status == -ENOENT */
usb_unlink_urb(&as->urb);
spin_lock_irqsave(&ps->lock, flags);
}
@@ -299,11 +299,12 @@ static void driver_disconnect(struct usb_device *dev, void *context)
{
struct dev_state *ps = (struct dev_state *)context;
- ps->ifclaimed = 0;
+ if (ps)
+ ps->ifclaimed = 0;
}
struct usb_driver usbdevfs_driver = {
- name: "usbdevfs",
+ name: "usbfs",
probe: driver_probe,
disconnect: driver_disconnect,
};
diff --git a/drivers/usb/hid-core.c b/drivers/usb/hid-core.c
index 0f462d8dd..7c40af27a 100644
--- a/drivers/usb/hid-core.c
+++ b/drivers/usb/hid-core.c
@@ -897,7 +897,7 @@ void hid_read_report(struct hid_device *hid, struct hid_report *report)
u8 data[len];
int read;
- if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
+ if ((read = hid_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read);
return;
}
@@ -1064,7 +1064,7 @@ void hid_init_reports(struct hid_device *hid)
list = report_enum->report_list.next;
while (list != &report_enum->report_list) {
report = (struct hid_report *) list;
- usb_set_idle(hid->dev, hid->ifnum, 0, report->id);
+ hid_set_idle(hid->dev, hid->ifnum, 0, report->id);
hid_read_report(hid, report);
list = list->next;
}
@@ -1089,6 +1089,16 @@ struct hid_blacklist {
{ 0, 0 }
};
+static int get_class_descriptor(struct usb_device *dev, int ifnum,
+ unsigned char type, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
+ (type << 8), ifnum, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
+}
+
+
static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
{
struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
@@ -1102,14 +1112,14 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
(hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL;
- if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
- usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) {
+ if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
+ usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
dbg("class descriptor not present\n");
return NULL;
}
for (n = 0; n < hdesc->bNumDescriptors; n++)
- if (hdesc->desc[n].bDescriptorType == USB_DT_REPORT)
+ if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
@@ -1120,7 +1130,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
{
__u8 rdesc[rsize];
- if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
+ if ((n = get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
dbg("reading report descriptor failed");
return NULL;
}
@@ -1170,7 +1180,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) {
hid->out[n].dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- hid->out[n].dr.request = USB_REQ_SET_REPORT;
+ hid->out[n].dr.request = HID_REQ_SET_REPORT;
hid->out[n].dr.index = cpu_to_le16(hid->ifnum);
}
@@ -1198,7 +1208,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
#if 0
if (interface->bInterfaceSubClass == 1)
- usb_set_protocol(dev, hid->ifnum, 1);
+ hid_set_protocol(dev, hid->ifnum, 1);
#endif
return hid;
diff --git a/drivers/usb/hid.h b/drivers/usb/hid.h
index 529a1112a..7eb085fce 100644
--- a/drivers/usb/hid.h
+++ b/drivers/usb/hid.h
@@ -30,6 +30,88 @@
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
+/*
+ * HID class requests
+ */
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE 0x02
+#define HID_REQ_GET_PROTOCOL 0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE 0x0A
+#define HID_REQ_SET_PROTOCOL 0x0B
+
+/*
+ * HID class descriptor types
+ */
+#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
+#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
+#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
+
+/*
+ * Utilities for class control messaging
+ */
+static inline int
+hid_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (duration << 8) | report_id, ifnum, NULL, 0,
+ HZ * USB_CTRL_SET_TIMEOUT);
+}
+
+static inline int
+hid_get_protocol(struct usb_device *dev, int ifnum)
+{
+ unsigned char type;
+ int ret;
+
+ if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ HID_REQ_GET_PROTOCOL,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, ifnum, &type, 1,
+ HZ * USB_CTRL_GET_TIMEOUT)) < 0)
+ return ret;
+
+ return type;
+}
+
+static inline int
+hid_set_protocol(struct usb_device *dev, int ifnum, int protocol)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ HID_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ protocol, ifnum, NULL, 0,
+ HZ * USB_CTRL_SET_TIMEOUT);
+}
+
+static inline int
+hid_get_report(struct usb_device *dev, int ifnum, unsigned char type,
+ unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ HID_REQ_GET_REPORT,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (type << 8) + id, ifnum, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int
+hid_set_report(struct usb_device *dev, int ifnum, unsigned char type,
+ unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (type << 8) + id, ifnum, buf, size, HZ);
+ // FIXME USB_CTRL_SET_TIMEOUT
+}
+
+
+/*
+ * "Boot Protocol" keyboard/mouse drivers use don't use all of HID;
+ * they're a lot smaller but can't support all the device features.
+ */
+#ifndef _HID_BOOT_PROTOCOL
+
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
@@ -359,9 +441,7 @@ void hidinput_disconnect(struct hid_device *);
#else
#define hid_dump_input(a,b) do { } while (0)
#define hid_dump_device(c) do { } while (0)
-#endif
-
-#endif
+#endif /* DEBUG */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
@@ -372,3 +452,8 @@ int hid_set_field(struct hid_field *, unsigned, __s32);
void hid_write_report(struct hid_device *, struct hid_report *);
void hid_read_report(struct hid_device *, struct hid_report *);
void hid_init_reports(struct hid_device *hid);
+
+#endif /* !_HID_BOOT_PROTOCOL */
+
+#endif /* !__HID_H */
+
diff --git a/drivers/usb/hiddev.c b/drivers/usb/hiddev.c
index 982f366fe..b9b3f1daa 100644
--- a/drivers/usb/hiddev.c
+++ b/drivers/usb/hiddev.c
@@ -193,7 +193,6 @@ static int hiddev_release(struct inode * inode, struct file * file)
struct hiddev_list *list = file->private_data;
struct hiddev_list **listptr;
- lock_kernel();
listptr = &list->hiddev->list;
hiddev_fasync(-1, file, 0);
@@ -209,7 +208,6 @@ static int hiddev_release(struct inode * inode, struct file * file)
}
kfree(list);
- unlock_kernel();
return 0;
}
diff --git a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h
index 877e69891..0daa39708 100644
--- a/drivers/usb/hpusbscsi.h
+++ b/drivers/usb/hpusbscsi.h
@@ -73,7 +73,6 @@ static Scsi_Host_Template hpusbscsi_scsi_host_template = {
present: 0,
unchecked_isa_dma: FALSE,
use_clustering: TRUE,
- use_new_eh_code: TRUE,
emulated: TRUE
};
diff --git a/drivers/usb/inode.c b/drivers/usb/inode.c
index 0c348ed80..cd38ce06a 100644
--- a/drivers/usb/inode.c
+++ b/drivers/usb/inode.c
@@ -654,7 +654,13 @@ struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int s
return NULL;
}
+/*
+ * The usbdevfs name is now depreciated (as of 2.5.1).
+ * It will be removed when the 2.7.x development cycle is started.
+ * You have been warned :)
+ */
static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);
+static DECLARE_FSTYPE(usb_fs_type, "usbfs", usbdevfs_read_super, FS_SINGLE);
/* --------------------------------------------------------------------- */
@@ -747,7 +753,12 @@ int __init usbdevfs_init(void)
}
if ((ret = usb_register(&usbdevfs_driver)))
return ret;
+ if ((ret = register_filesystem(&usb_fs_type))) {
+ usb_deregister(&usbdevfs_driver);
+ return ret;
+ }
if ((ret = register_filesystem(&usbdevice_fs_type))) {
+ unregister_filesystem(&usb_fs_type);
usb_deregister(&usbdevfs_driver);
return ret;
}
@@ -761,6 +772,7 @@ int __init usbdevfs_init(void)
void __exit usbdevfs_cleanup(void)
{
usb_deregister(&usbdevfs_driver);
+ unregister_filesystem(&usb_fs_type);
unregister_filesystem(&usbdevice_fs_type);
#ifdef CONFIG_PROC_FS
if (usbdir)
@@ -768,7 +780,3 @@ void __exit usbdevfs_cleanup(void)
#endif
}
-#if 0
-module_init(usbdevfs_init);
-module_exit(usbdevfs_cleanup);
-#endif
diff --git a/drivers/usb/kaweth.c b/drivers/usb/kaweth.c
index df36984ad..7289dcd38 100644
--- a/drivers/usb/kaweth.c
+++ b/drivers/usb/kaweth.c
@@ -944,6 +944,13 @@ static void kaweth_disconnect(struct usb_device *dev, void *ptr)
}
+// FIXME this completion stuff is a modified clone of
+// an OLD version of some stuff in usb.c ...
+struct usb_api_data {
+ wait_queue_head_t wqh;
+ int done;
+};
+
/*-------------------------------------------------------------------*
* completion handler for compatibility wrappers (sync control/bulk) *
*-------------------------------------------------------------------*/
diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c
index cc458b385..d2a1ebe71 100644
--- a/drivers/usb/mdc800.c
+++ b/drivers/usb/mdc800.c
@@ -30,8 +30,14 @@
*
* The driver supports only one camera.
*
- * (08/04/2001) gb
+ * Fix: mdc800 used sleep_on and slept with io_lock held.
+ * Converted sleep_on to waitqueues with schedule_timeout and made io_lock
+ * a semaphore from a spinlock.
+ * by Oliver Neukum <520047054719-0001@t-online.de>
+ * (02/12/2001)
+ *
* Identify version on module load.
+ * (08/04/2001) gb
*
* version 0.7.5
* Fixed potential SMP races with Spinlocks.
@@ -136,6 +142,7 @@ struct mdc800_data
purb_t irq_urb;
wait_queue_head_t irq_wait;
+ int irq_woken;
char* irq_urb_buffer;
int camera_busy; // is camera busy ?
@@ -145,11 +152,13 @@ struct mdc800_data
purb_t write_urb;
char* write_urb_buffer;
wait_queue_head_t write_wait;
+ int written;
purb_t download_urb;
char* download_urb_buffer;
wait_queue_head_t download_wait;
+ int downloaded;
int download_left; // Bytes left to download ?
@@ -159,7 +168,7 @@ struct mdc800_data
int out_count; // Bytes in the buffer
int open; // Camera device open ?
- spinlock_t io_lock; // IO -lock
+ struct semaphore io_lock; // IO -lock
char in [8]; // Command Input Buffer
int in_count;
@@ -284,6 +293,7 @@ static void mdc800_usb_irq (struct urb *urb)
if (wake_up)
{
mdc800->camera_request_ready=0;
+ mdc800->irq_woken=1;
wake_up_interruptible (&mdc800->irq_wait);
}
}
@@ -300,9 +310,19 @@ static void mdc800_usb_irq (struct urb *urb)
*/
static int mdc800_usb_waitForIRQ (int mode, int msec)
{
+ DECLARE_WAITQUEUE(wait, current);
+
mdc800->camera_request_ready=1+mode;
- interruptible_sleep_on_timeout (&mdc800->irq_wait, msec*HZ/1000);
+ add_wait_queue(&mdc800->irq_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!mdc800->irq_woken)
+ {
+ schedule_timeout (msec*HZ/1000);
+ }
+ remove_wait_queue(&mdc800->irq_wait, &wait);
+ set_current_state(TASK_RUNNING);
+ mdc800->irq_woken = 0;
if (mdc800->camera_request_ready>0)
{
@@ -337,6 +357,7 @@ static void mdc800_usb_write_notify (struct urb *urb)
{
mdc800->state=READY;
}
+ mdc800->written = 1;
wake_up_interruptible (&mdc800->write_wait);
}
@@ -364,6 +385,7 @@ static void mdc800_usb_download_notify (struct urb *urb)
{
err ("request bytes fails (status:%i)", urb->status);
}
+ mdc800->downloaded = 1;
wake_up_interruptible (&mdc800->download_wait);
}
@@ -445,7 +467,7 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
info ("Found Mustek MDC800 on USB.");
- spin_lock (&mdc800->io_lock);
+ down (&mdc800->io_lock);
mdc800->dev=dev;
mdc800->open=0;
@@ -484,7 +506,7 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
mdc800->state=READY;
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return mdc800;
}
@@ -558,7 +580,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file)
int retval=0;
int errn=0;
- spin_lock (&mdc800->io_lock);
+ down (&mdc800->io_lock);
if (mdc800->state == NOT_CONNECTED)
{
@@ -594,7 +616,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file)
dbg ("Mustek MDC800 device opened.");
error_out:
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return errn;
}
@@ -607,10 +629,9 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
int retval=0;
dbg ("Mustek MDC800 device closed.");
- spin_lock (&mdc800->io_lock);
+ down (&mdc800->io_lock);
if (mdc800->open && (mdc800->state != NOT_CONNECTED))
{
- spin_unlock(&mdc800->io_lock);
usb_unlink_urb (mdc800->irq_urb);
usb_unlink_urb (mdc800->write_urb);
usb_unlink_urb (mdc800->download_urb);
@@ -618,11 +639,10 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
}
else
{
- spin_unlock (&mdc800->io_lock);
retval=-EIO;
}
-
+ up(&mdc800->io_lock);
return retval;
}
@@ -634,22 +654,23 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
{
int left=len, sts=len; /* single transfer size */
char* ptr=buf;
+ DECLARE_WAITQUEUE(wait, current);
- spin_lock (&mdc800->io_lock);
+ down (&mdc800->io_lock);
if (mdc800->state == NOT_CONNECTED)
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EBUSY;
}
if (mdc800->state == WORKING)
{
warn ("Illegal State \"working\" reached during read ?!");
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EBUSY;
}
if (!mdc800->open)
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EBUSY;
}
@@ -657,7 +678,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
{
if (signal_pending (current))
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EINTR;
}
@@ -676,21 +697,29 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
if (usb_submit_urb (mdc800->download_urb))
{
err ("Can't submit download urb (status=%i)",mdc800->download_urb->status);
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return len-left;
}
- interruptible_sleep_on_timeout (&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000);
+ add_wait_queue(&mdc800->download_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!mdc800->downloaded)
+ {
+ schedule_timeout (TO_DOWNLOAD_GET_READY*HZ/1000);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&mdc800->download_wait, &wait);
+ mdc800->downloaded = 0;
if (mdc800->download_urb->status != 0)
{
err ("request download-bytes fails (status=%i)",mdc800->download_urb->status);
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return len-left;
}
}
else
{
/* No more bytes -> that's an error*/
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
}
@@ -704,7 +733,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
}
}
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return len-left;
}
@@ -718,16 +747,17 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof
static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
{
int i=0;
+ DECLARE_WAITQUEUE(wait, current);
- spin_lock (&mdc800->io_lock);
+ down (&mdc800->io_lock);
if (mdc800->state != READY)
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EBUSY;
}
if (!mdc800->open )
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EBUSY;
}
@@ -735,7 +765,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
{
if (signal_pending (current))
{
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EINTR;
}
@@ -757,7 +787,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
else
{
err ("Command is to long !\n");
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
@@ -769,7 +799,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
{
err ("Camera didn't get ready.\n");
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
@@ -781,14 +811,22 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
if (usb_submit_urb (mdc800->write_urb))
{
err ("submitting write urb fails (status=%i)", mdc800->write_urb->status);
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
- interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000);
+ add_wait_queue(&mdc800->write_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!mdc800->written)
+ {
+ schedule_timeout (TO_WRITE_GET_READY*HZ/1000);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&mdc800->write_wait, &wait);
+ mdc800->written = 0;
if (mdc800->state == WORKING)
{
usb_unlink_urb (mdc800->write_urb);
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
@@ -800,7 +838,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
{
err ("call 0x07 before 0x05,0x3e");
mdc800->state=READY;
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
mdc800->pic_len=-1;
@@ -819,7 +857,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ))
{
err ("requesting answer from irq fails");
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
@@ -847,7 +885,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND))
{
err ("Command Timeout.");
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return -EIO;
}
}
@@ -857,7 +895,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l
}
i++;
}
- spin_unlock (&mdc800->io_lock);
+ up (&mdc800->io_lock);
return i;
}
@@ -916,12 +954,16 @@ int __init usb_mdc800_init (void)
mdc800->dev=0;
mdc800->open=0;
mdc800->state=NOT_CONNECTED;
- spin_lock_init (&mdc800->io_lock);
+ init_MUTEX (&mdc800->io_lock);
init_waitqueue_head (&mdc800->irq_wait);
init_waitqueue_head (&mdc800->write_wait);
init_waitqueue_head (&mdc800->download_wait);
+ mdc800->irq_woken = 0;
+ mdc800->downloaded = 0;
+ mdc800->written = 0;
+
try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL));
try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL));
try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL));
diff --git a/drivers/usb/microtek.c b/drivers/usb/microtek.c
index 249de20e4..2e5d06a92 100644
--- a/drivers/usb/microtek.c
+++ b/drivers/usb/microtek.c
@@ -760,7 +760,6 @@ static Scsi_Host_Template mts_scsi_host_template = {
present: 0,
unchecked_isa_dma: FALSE,
use_clustering: TRUE,
- use_new_eh_code: TRUE,
emulated: TRUE
};
diff --git a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c
index bb8d84cff..7ae85febb 100644
--- a/drivers/usb/pegasus.c
+++ b/drivers/usb/pegasus.c
@@ -53,7 +53,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.4.21 (2001/08/27)"
+#define DRIVER_VERSION "v0.4.22 (2001/12/07)"
#define DRIVER_AUTHOR "Petko Manolov <pmanolov@lnxw.com>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
@@ -102,7 +102,7 @@ static void ctrl_callback( urb_t *urb )
return;
switch ( urb->status ) {
- case USB_ST_NOERROR:
+ case 0:
if ( pegasus->flags & ETH_REGS_CHANGE ) {
pegasus->flags &= ~ETH_REGS_CHANGE;
pegasus->flags |= ETH_REGS_CHANGED;
@@ -110,9 +110,9 @@ static void ctrl_callback( urb_t *urb )
return;
}
break;
- case USB_ST_URB_PENDING:
+ case -EINPROGRESS:
return;
- case USB_ST_URB_KILLED:
+ case -ENOENT:
break;
default:
warn( __FUNCTION__ " status %d", urb->status);
@@ -526,9 +526,9 @@ static void read_bulk_callback( struct urb *urb )
pegasus->flags |= PEGASUS_RX_BUSY;
switch ( urb->status ) {
- case USB_ST_NOERROR:
+ case 0:
break;
- case USB_ST_NORESPONSE:
+ case -ETIMEDOUT:
dbg( "reset MAC" );
pegasus->flags &= ~PEGASUS_RX_BUSY;
break;
@@ -607,9 +607,9 @@ static void intr_callback( struct urb *urb )
return;
switch ( urb->status ) {
- case USB_ST_NOERROR:
+ case 0:
break;
- case USB_ST_URB_KILLED:
+ case -ENOENT:
return;
default:
info("intr status %d", urb->status);
@@ -713,10 +713,8 @@ static int pegasus_open(struct net_device *net)
pegasus_t *pegasus = (pegasus_t *)net->priv;
int res;
- MOD_INC_USE_COUNT;
if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
err("can't enable_net_traffic() - %d", res);
- MOD_DEC_USE_COUNT;
return -EIO;
}
FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb,
@@ -755,7 +753,6 @@ static int pegasus_close( struct net_device *net )
#ifdef PEGASUS_USE_INTR
usb_unlink_urb( &pegasus->intr_urb );
#endif
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -867,6 +864,7 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
pegasus->usb = dev;
pegasus->net = net;
+ SET_MODULE_OWNER(net);
net->priv = pegasus;
net->open = pegasus_open;
net->stop = pegasus_close;
diff --git a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h
index 9ef3801f3..d76125cfa 100644
--- a/drivers/usb/pegasus.h
+++ b/drivers/usb/pegasus.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
+ * Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -138,6 +138,7 @@ struct usb_eth_dev {
#define VENDOR_DLINK 0x2001
#define VENDOR_ELSA 0x05cc
#define VENDOR_IODATA 0x04bb
+#define VENDOR_KINGSTON 0x0951
#define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411
@@ -210,6 +211,8 @@ PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
+ DEFAULT_GPIO_RESET)
PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
diff --git a/drivers/usb/rio500.c b/drivers/usb/rio500.c
index 244674864..96bb3a811 100644
--- a/drivers/usb/rio500.c
+++ b/drivers/usb/rio500.c
@@ -324,7 +324,7 @@ write_rio(struct file *file, const char *buffer,
dbg("write stats: result:%d thistime:%lu partial:%u",
result, thistime, partial);
- if (result == USB_ST_TIMEOUT) { /* NAK - so hold for a while */
+ if (result == -ETIMEDOUT) { /* NAK - so hold for a while */
if (!maxretry--) {
errn = -ETIME;
goto error;
@@ -403,7 +403,7 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
if (partial) {
count = this_read = partial;
- } else if (result == USB_ST_TIMEOUT || result == 15) { /* FIXME: 15 ??? */
+ } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
if (!maxretry--) {
up(&(rio->lock));
err("read_rio: maxretry timeout");
@@ -412,7 +412,7 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
interruptible_sleep_on_timeout(&rio->wait_q,
NAK_TIMEOUT);
continue;
- } else if (result != USB_ST_DATAUNDERRUN) {
+ } else if (result != -EREMOTEIO) {
up(&(rio->lock));
err("Read Whoops - result:%u partial:%u this_read:%u",
result, partial, this_read);
diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c
index e686f6f42..2e17eabd2 100644
--- a/drivers/usb/scanner.c
+++ b/drivers/usb/scanner.c
@@ -281,7 +281,7 @@
* 0.4.7 11/28/2001
* - Fixed typo in Documentation/scanner.txt. Thanks to
* Karel <karel.vervaeke@pandora.be> for pointing it out.
- * - Added ID's for a Memorex 6136u. Thanks to Álvaro Gaspar de
+ * - Added ID's for a Memorex 6136u. Thanks to =C1lvaro Gaspar de
* Valenzuela" <agaspard@utsi.edu>.
* - Added ID's for Agfa e25. Thanks to Heinrich
* Rust <Heinrich.Rust@gmx.de>. Also reported to work with
@@ -628,7 +628,7 @@ read_scanner(struct file * file, char * buffer,
}
ret = result;
break;
- } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
+ } else if ((result < 0) && (result != -EREMOTEIO)) {
warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result);
ret = -EIO;
break;
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 1191ecb95..126846933 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -1,8 +1,8 @@
/*
* Belkin USB Serial Adapter Driver
*
- * Copyright (C) 2000
- * William Greathouse (wgreathouse@smva.com)
+ * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com)
+ * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com)
*
* This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for
@@ -24,6 +24,9 @@
* -- Add support for flush commands
* -- Add everything that is missing :)
*
+ * 27-Nov-2001 gkh
+ * compressed all the differnent device entries into 1.
+ *
* 30-May-2001 gkh
* switched from using spinlock to a semaphore, which fixes lots of problems.
*
@@ -88,7 +91,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
#define DRIVER_DESC "USB Belkin Serial converter driver"
@@ -112,125 +115,12 @@ static __devinitdata struct usb_device_id id_table_combined [] = {
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id belkin_dockstation_table [] = {
- { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id belkin_sa_table [] = {
- { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id belkin_old_table [] = {
- { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id peracom_table [] = {
- { USB_DEVICE(PERACOM_VID, PERACOM_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id gocom232_table [] = {
- { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
- { } /* Terminating entry */
-};
-
MODULE_DEVICE_TABLE (usb, id_table_combined);
-/* All of the device info needed for the Belkin dockstation serial converter */
-static struct usb_serial_device_type belkin_dockstation_device = {
- name: "Belkin F5U120-PC USB Serial Adapter",
- id_table: belkin_dockstation_table, /* the Belkin F5U103 device */
- needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 1,
- num_bulk_in: 1,
- num_bulk_out: 1,
- num_ports: 1,
- open: belkin_sa_open,
- close: belkin_sa_close,
- read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */
- ioctl: belkin_sa_ioctl,
- set_termios: belkin_sa_set_termios,
- break_ctl: belkin_sa_break_ctl,
- startup: belkin_sa_startup,
- shutdown: belkin_sa_shutdown,
-};
-
-/* All of the device info needed for the Belkin serial converter */
-static struct usb_serial_device_type belkin_sa_device = {
- name: "Belkin F5U103 USB Serial Adapter",
- id_table: belkin_sa_table, /* the Belkin F5U103 device */
- needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 1,
- num_bulk_in: 1,
- num_bulk_out: 1,
- num_ports: 1,
- open: belkin_sa_open,
- close: belkin_sa_close,
- read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */
- ioctl: belkin_sa_ioctl,
- set_termios: belkin_sa_set_termios,
- break_ctl: belkin_sa_break_ctl,
- startup: belkin_sa_startup,
- shutdown: belkin_sa_shutdown,
-};
-
-
-/* This driver also supports the "old" school Belkin single port adaptor */
-static struct usb_serial_device_type belkin_old_device = {
- name: "Belkin USB Serial Adapter",
- id_table: belkin_old_table, /* the old Belkin device */
- needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 1,
- num_bulk_in: 1,
- num_bulk_out: 1,
- num_ports: 1,
- open: belkin_sa_open,
- close: belkin_sa_close,
- read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */
- ioctl: belkin_sa_ioctl,
- set_termios: belkin_sa_set_termios,
- break_ctl: belkin_sa_break_ctl,
- startup: belkin_sa_startup,
- shutdown: belkin_sa_shutdown,
-};
-
-/* this driver also works for the Peracom single port adapter */
-static struct usb_serial_device_type peracom_device = {
- name: "Peracom single port USB Serial Adapter",
- id_table: peracom_table, /* the Peracom device */
- needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 1,
- num_bulk_in: 1,
- num_bulk_out: 1,
- num_ports: 1,
- open: belkin_sa_open,
- close: belkin_sa_close,
- read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */
- ioctl: belkin_sa_ioctl,
- set_termios: belkin_sa_set_termios,
- break_ctl: belkin_sa_break_ctl,
- startup: belkin_sa_startup,
- shutdown: belkin_sa_shutdown,
-};
-
-/* the GoHubs Go-COM232 device is the same as the Peracom single port adapter */
-static struct usb_serial_device_type gocom232_device = {
- name: "GO-COM232 USB Serial Converter",
- id_table: gocom232_table, /* the GO-COM232 device */
- needs_interrupt_in: MUST_HAVE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
+/* All of the device info needed for the serial converters */
+static struct usb_serial_device_type belkin_device = {
+ name: "Belkin / Peracom / GoHubs USB Serial Adapter",
+ id_table: id_table_combined,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -321,9 +211,7 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/*Start reading from the device*/
/* TODO: Look at possibility of submitting mulitple URBs to device to
* enhance buffering. Win trace shows 16 initial read URBs.
@@ -372,7 +260,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
- port->active = 0;
+ port->open_count = 0;
}
up (&port->sem);
@@ -642,11 +530,7 @@ static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, un
static int __init belkin_sa_init (void)
{
- usb_serial_register (&belkin_dockstation_device);
- usb_serial_register (&belkin_sa_device);
- usb_serial_register (&belkin_old_device);
- usb_serial_register (&peracom_device);
- usb_serial_register (&gocom232_device);
+ usb_serial_register (&belkin_device);
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -654,11 +538,7 @@ static int __init belkin_sa_init (void)
static void __exit belkin_sa_exit (void)
{
- usb_serial_deregister (&belkin_dockstation_device);
- usb_serial_deregister (&belkin_sa_device);
- usb_serial_deregister (&belkin_old_device);
- usb_serial_deregister (&peracom_device);
- usb_serial_deregister (&gocom232_device);
+ usb_serial_deregister (&belkin_device);
}
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 7c9d1f2b5..f74b72bb6 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -79,9 +79,6 @@ MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_serial_device_type cyberjack_device = {
name: "Reiner SCT Cyberjack USB card reader",
id_table: id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -159,8 +156,7 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
- if (!port->active) {
- port->active = 1;
+ if (port->open_count == 1) {
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
@@ -204,8 +200,6 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
-
- port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index c974e428e..74316472f 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -14,6 +14,10 @@
* Peter Berger (pberger@brimson.com)
* Al Borchers (borchers@steinerpoint.com)
*
+* (12/03/2001) gkh
+* switched to using port->open_count instead of private version.
+* Removed port->active
+*
* (04/08/2001) gb
* Identify version on module load.
*
@@ -429,7 +433,6 @@ typedef struct digi_port {
int dp_write_urb_in_use;
unsigned int dp_modem_signals;
wait_queue_head_t dp_modem_change_wait;
- int dp_open_count; /* inc on open, dec on close */
int dp_transmit_idle;
wait_queue_head_t dp_transmit_idle_wait;
int dp_throttled;
@@ -500,9 +503,6 @@ MODULE_DEVICE_TABLE (usb, id_table_combined);
static struct usb_serial_device_type digi_acceleport_2_device = {
name: "Digi USB",
id_table: id_table_2,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 0,
num_bulk_in: 4,
num_bulk_out: 4,
@@ -526,9 +526,6 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
static struct usb_serial_device_type digi_acceleport_4_device = {
name: "Digi USB",
id_table: id_table_4,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 0,
num_bulk_in: 5,
num_bulk_out: 5,
@@ -1386,7 +1383,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status );
/* try to send any buffered data on this port, if it is open */
spin_lock( &priv->dp_port_lock );
priv->dp_write_urb_in_use = 0;
- if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS
+ if( port->open_count && port->write_urb->status != -EINPROGRESS
&& priv->dp_out_buf_len > 0 ) {
*((unsigned char *)(port->write_urb->transfer_buffer))
@@ -1480,7 +1477,7 @@ static int digi_open( struct usb_serial_port *port, struct file *filp )
unsigned long flags = 0;
-dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count );
+dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count );
/* be sure the device is started up */
if( digi_startup_device( port->serial ) != 0 )
@@ -1495,7 +1492,7 @@ dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, por
}
/* inc module use count before sleeping to wait for closes */
- ++priv->dp_open_count;
+ ++port->open_count;
MOD_INC_USE_COUNT;
/* wait for a close in progress to finish */
@@ -1504,7 +1501,7 @@ dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, por
&priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
&priv->dp_port_lock, flags );
if( signal_pending(current) ) {
- --priv->dp_open_count;
+ --port->open_count;
MOD_DEC_USE_COUNT;
return( -EINTR );
}
@@ -1513,13 +1510,11 @@ dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, por
/* if port is already open, just return */
/* be sure exactly one open proceeds */
- if( port->active ) {
+ if( port->open_count != 1) {
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return( 0 );
}
- /* first open, mark port as active */
- port->active = 1;
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
/* read modem signals automatically whenever they change */
@@ -1560,17 +1555,17 @@ static void digi_close( struct usb_serial_port *port, struct file *filp )
unsigned long flags = 0;
-dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count );
+dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count );
/* do cleanup only after final close on this port */
spin_lock_irqsave( &priv->dp_port_lock, flags );
- if( priv->dp_open_count > 1 ) {
- --priv->dp_open_count;
+ if( port->open_count > 1 ) {
+ --port->open_count;
MOD_DEC_USE_COUNT;
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return;
- } else if( priv->dp_open_count <= 0 ) {
+ } else if( port->open_count <= 0 ) {
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
return;
}
@@ -1644,10 +1639,9 @@ dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, po
tty->closing = 0;
spin_lock_irqsave( &priv->dp_port_lock, flags );
- port->active = 0;
priv->dp_write_urb_in_use = 0;
priv->dp_in_close = 0;
- --priv->dp_open_count;
+ --port->open_count;
MOD_DEC_USE_COUNT;
wake_up_interruptible( &priv->dp_close_wait );
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
@@ -1716,8 +1710,6 @@ dbg( "digi_startup: TOP" );
/* number of regular ports + 1 for the out-of-band port */
for( i=0; i<serial->type->num_ports+1; i++ ) {
- serial->port[i].active = 0;
-
/* allocate port private structure */
priv = serial->port[i].private =
(digi_port_t *)kmalloc( sizeof(digi_port_t),
@@ -1736,7 +1728,6 @@ dbg( "digi_startup: TOP" );
priv->dp_write_urb_in_use = 0;
priv->dp_modem_signals = 0;
init_waitqueue_head( &priv->dp_modem_change_wait );
- priv->dp_open_count = 0;
priv->dp_transmit_idle = 0;
init_waitqueue_head( &priv->dp_transmit_idle_wait );
priv->dp_throttled = 0;
@@ -1795,9 +1786,9 @@ dbg( "digi_shutdown: TOP, in_interrupt()=%d", in_interrupt() );
for( i=0; i<serial->type->num_ports; i++ ) {
priv = serial->port[i].private;
spin_lock_irqsave( &priv->dp_port_lock, flags );
- while( priv->dp_open_count > 0 ) {
+ while( serial->port[i].open_count > 0 ) {
MOD_DEC_USE_COUNT;
- --priv->dp_open_count;
+ --serial->port[i].open_count;
}
spin_unlock_irqrestore( &priv->dp_port_lock, flags );
}
@@ -1889,7 +1880,7 @@ static int digi_read_inb_callback( struct urb *urb )
/* do not process callbacks on closed ports */
/* but do continue the read chain */
- if( priv->dp_open_count == 0 )
+ if( port->open_count == 0 )
return( 0 );
/* short/multiple packet check */
@@ -2023,7 +2014,7 @@ opcode, line, status, val );
if( val & DIGI_READ_INPUT_SIGNALS_CTS ) {
priv->dp_modem_signals |= TIOCM_CTS;
/* port must be open to use tty struct */
- if( priv->dp_open_count
+ if( port->open_count
&& port->tty->termios->c_cflag & CRTSCTS ) {
port->tty->hw_stopped = 0;
digi_wakeup_write( port );
@@ -2031,7 +2022,7 @@ opcode, line, status, val );
} else {
priv->dp_modem_signals &= ~TIOCM_CTS;
/* port must be open to use tty struct */
- if( priv->dp_open_count
+ if( port->open_count
&& port->tty->termios->c_cflag & CRTSCTS ) {
port->tty->hw_stopped = 1;
}
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index a476bfab0..e935a248d 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -116,9 +116,6 @@ MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_serial_device_type empeg_device = {
name: "Empeg",
id_table: id_table,
- needs_interrupt_in: MUST_HAVE_NOT, /* must not have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* must have a bulk out endpoint */
num_interrupt_in: 0,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -164,12 +161,11 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
+ if (port->open_count == 1) {
/* Force default termio settings */
empeg_set_termios (port, NULL) ;
- port->active = 1;
bytes_in = 0;
bytes_out = 0;
@@ -221,7 +217,6 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
}
- port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 23aabea52..8f634f74f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -176,9 +176,6 @@ static void ftdi_sio_break_ctl (struct usb_serial_port *port, int break_state )
static struct usb_serial_device_type ftdi_sio_device = {
name: "FTDI SIO",
id_table: id_table_sio,
- needs_interrupt_in: MUST_HAVE_NOT,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 0,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -199,9 +196,6 @@ static struct usb_serial_device_type ftdi_sio_device = {
static struct usb_serial_device_type ftdi_8U232AM_device = {
name: "FTDI 8U232AM",
id_table: id_table_8U232AM,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 0,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -327,9 +321,7 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
MOD_INC_USE_COUNT;
++port->open_count;
- if (!port->active){
- port->active = 1;
-
+ if (port->open_count == 1){
/* This will push the characters through immediately rather
than queue a task to deliver them */
port->tty->low_latency = 1;
@@ -410,7 +402,6 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
}
- port->active = 0;
port->open_count = 0;
} else {
/* Send a HUP if necessary */
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 4203f6fde..395ca6262 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -987,9 +987,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/* force low_latency on so that our tty_push actually forces the data through,
otherwise it is scheduled, and with high data rates (like with OHCI) data
can get lost. */
@@ -1000,7 +998,6 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
serial = port->serial;
edge_serial = (struct edgeport_serial *)serial->private;
if (edge_serial == NULL) {
- port->active = 0;
port->open_count = 0;
MOD_DEC_USE_COUNT;
return -ENODEV;
@@ -1064,7 +1061,6 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
if (response < 0) {
err(__FUNCTION__" - error sending open port command");
edge_port->openPending = FALSE;
- port->active = 0;
port->open_count = 0;
MOD_DEC_USE_COUNT;
return -ENODEV;
@@ -1080,7 +1076,6 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
/* open timed out */
dbg(__FUNCTION__" - open timedout");
edge_port->openPending = FALSE;
- port->active = 0;
port->open_count = 0;
MOD_DEC_USE_COUNT;
return -ENODEV;
@@ -1285,7 +1280,6 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
if (edge_port->txfifo.fifo) {
kfree(edge_port->txfifo.fifo);
}
- port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
index 739113905..01f562a5e 100644
--- a/drivers/usb/serial/io_tables.h
+++ b/drivers/usb/serial/io_tables.h
@@ -74,9 +74,6 @@ MODULE_DEVICE_TABLE (usb, id_table_combined);
static struct usb_serial_device_type edgeport_1port_device = {
name: "Edgeport 1 port adapter",
id_table: edgeport_1port_id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -98,9 +95,6 @@ static struct usb_serial_device_type edgeport_1port_device = {
static struct usb_serial_device_type edgeport_2port_device = {
name: "Edgeport 2 port adapter",
id_table: edgeport_2port_id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -122,9 +116,6 @@ static struct usb_serial_device_type edgeport_2port_device = {
static struct usb_serial_device_type edgeport_4port_device = {
name: "Edgeport 4 port adapter",
id_table: edgeport_4port_id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -146,9 +137,6 @@ static struct usb_serial_device_type edgeport_4port_device = {
static struct usb_serial_device_type edgeport_8port_device = {
name: "Edgeport 8 port adapter",
id_table: edgeport_8port_id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 4443e9624..ecec9b983 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -93,9 +93,6 @@ MODULE_DEVICE_TABLE (usb, id_table);
struct usb_serial_device_type ir_device = {
name: "IR Dongle",
id_table: id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -209,9 +206,7 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
if (buffer_size) {
/* override the default buffer sizes */
buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -271,7 +266,6 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
}
- port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index d5dd6ca6c..80df4f451 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -468,7 +468,7 @@ static void usa2x_outdat_callback(struct urb *urb)
p_priv = (struct keyspan_port_private *)(port->private);
dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]);
- if (port->active) {
+ if (port->open_count) {
queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
@@ -880,9 +880,8 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
MOD_INC_USE_COUNT;
down (&port->sem);
+ already_active = port->open_count;
++port->open_count;
- already_active = port->active;
- port->active = 1;
up (&port->sem);
if (already_active)
@@ -948,18 +947,15 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
down (&port->sem);
if (--port->open_count <= 0) {
- if (port->active) {
- if (serial->dev) {
- /* Stop reading/writing urbs */
- stop_urb(p_priv->inack_urb);
- stop_urb(p_priv->outcont_urb);
- for (i = 0; i < 2; i++) {
- stop_urb(p_priv->in_urbs[i]);
- stop_urb(p_priv->out_urbs[i]);
- }
+ if (serial->dev) {
+ /* Stop reading/writing urbs */
+ stop_urb(p_priv->inack_urb);
+ stop_urb(p_priv->outcont_urb);
+ for (i = 0; i < 2; i++) {
+ stop_urb(p_priv->in_urbs[i]);
+ stop_urb(p_priv->out_urbs[i]);
}
}
- port->active = 0;
port->open_count = 0;
port->tty = 0;
}
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index e3e15967e..5998e9edd 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -451,9 +451,6 @@ static __devinitdata struct usb_device_id keyspan_usa49w_ids[] = {
static struct usb_serial_device_type keyspan_usa18x_pre_device = {
name: "Keyspan USA18X - (without firmware)",
id_table: keyspan_usa18x_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -464,9 +461,6 @@ static struct usb_serial_device_type keyspan_usa18x_pre_device = {
static struct usb_serial_device_type keyspan_usa19_pre_device = {
name: "Keyspan USA19 - (without firmware)",
id_table: keyspan_usa19_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -478,9 +472,6 @@ static struct usb_serial_device_type keyspan_usa19_pre_device = {
static struct usb_serial_device_type keyspan_usa19w_pre_device = {
name: "Keyspan USA19W - (without firmware)",
id_table: keyspan_usa19w_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -492,9 +483,6 @@ static struct usb_serial_device_type keyspan_usa19w_pre_device = {
static struct usb_serial_device_type keyspan_usa28_pre_device = {
name: "Keyspan USA28 - (without firmware)",
id_table: keyspan_usa28_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -505,9 +493,6 @@ static struct usb_serial_device_type keyspan_usa28_pre_device = {
static struct usb_serial_device_type keyspan_usa28x_pre_device = {
name: "Keyspan USA28X - (without firmware)",
id_table: keyspan_usa28x_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -518,9 +503,6 @@ static struct usb_serial_device_type keyspan_usa28x_pre_device = {
static struct usb_serial_device_type keyspan_usa28xa_pre_device = {
name: "Keyspan USA28XA - (without firmware)",
id_table: keyspan_usa28xa_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -531,9 +513,6 @@ static struct usb_serial_device_type keyspan_usa28xa_pre_device = {
static struct usb_serial_device_type keyspan_usa28xb_pre_device = {
name: "Keyspan USA28XB - (without firmware)",
id_table: keyspan_usa28xb_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -544,9 +523,6 @@ static struct usb_serial_device_type keyspan_usa28xb_pre_device = {
static struct usb_serial_device_type keyspan_usa49w_pre_device = {
name: "Keyspan USA49W - (without firmware)",
id_table: keyspan_usa49w_pre_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -557,9 +533,6 @@ static struct usb_serial_device_type keyspan_usa49w_pre_device = {
static struct usb_serial_device_type keyspan_usa18x_device = {
name: "Keyspan USA18X",
id_table: keyspan_usa18x_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 3,
num_bulk_out: 4,
@@ -583,9 +556,6 @@ static struct usb_serial_device_type keyspan_usa18x_device = {
static struct usb_serial_device_type keyspan_usa19_device = {
name: "Keyspan USA19",
id_table: keyspan_usa19_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 3,
num_bulk_out: 4,
@@ -610,9 +580,6 @@ static struct usb_serial_device_type keyspan_usa19_device = {
static struct usb_serial_device_type keyspan_usa19w_device = {
name: "Keyspan USA19W",
id_table: keyspan_usa19w_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 3,
num_bulk_out: 4,
@@ -637,9 +604,6 @@ static struct usb_serial_device_type keyspan_usa19w_device = {
static struct usb_serial_device_type keyspan_usa28_device = {
name: "Keyspan USA28",
id_table: keyspan_usa28_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -655,9 +619,6 @@ static struct usb_serial_device_type keyspan_usa28_device = {
static struct usb_serial_device_type keyspan_usa28x_device = {
name: "Keyspan USA28X/XB",
id_table: keyspan_usa28x_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -682,9 +643,6 @@ static struct usb_serial_device_type keyspan_usa28x_device = {
static struct usb_serial_device_type keyspan_usa28xa_device = {
name: "Keyspan USA28XA",
id_table: keyspan_usa28xa_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -709,9 +667,6 @@ static struct usb_serial_device_type keyspan_usa28xa_device = {
static struct usb_serial_device_type keyspan_usa49w_device = {
name: "Keyspan USA49W",
id_table: keyspan_usa49w_ids,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 5,
num_bulk_out: 5,
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index d333c8cc0..c1a9864c9 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -172,10 +172,6 @@ static __devinitdata struct usb_device_id id_table_fake [] = {
#ifdef XIRCOM
static __devinitdata struct usb_device_id id_table_fake_xircom [] = {
{ USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
- { }
-};
-
-static __devinitdata struct usb_device_id id_table_fake_entregra [] = {
{ USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
{ }
};
@@ -679,9 +675,7 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
MOD_INC_USE_COUNT;
++port->open_count;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/* find out how much room is in the Tx ring */
rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
6, /* write_room */
@@ -727,7 +721,6 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
return rc;
error:
--port->open_count;
- port->active = 0;
MOD_DEC_USE_COUNT;
up (&port->sem);
return rc;
@@ -752,7 +745,6 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
- port->active = 0;
port->open_count = 0;
}
@@ -843,9 +835,6 @@ static void keyspan_pda_shutdown (struct usb_serial *serial)
static struct usb_serial_device_type keyspan_pda_fake_device = {
name: "Keyspan PDA - (prerenumeration)",
id_table: id_table_fake,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -856,24 +845,8 @@ static struct usb_serial_device_type keyspan_pda_fake_device = {
#ifdef XIRCOM
static struct usb_serial_device_type xircom_pgs_fake_device = {
- name: "Xircom PGS - (prerenumeration)",
+ name: "Xircom / Entregra PGS - (prerenumeration)",
id_table: id_table_fake_xircom,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
- num_interrupt_in: NUM_DONT_CARE,
- num_bulk_in: NUM_DONT_CARE,
- num_bulk_out: NUM_DONT_CARE,
- num_ports: 1,
- startup: keyspan_pda_fake_startup,
-};
-
-static struct usb_serial_device_type entregra_pgs_fake_device = {
- name: "Entregra PGS - (prerenumeration)",
- id_table: id_table_fake_entregra,
- needs_interrupt_in: DONT_CARE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: DONT_CARE,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -885,9 +858,6 @@ static struct usb_serial_device_type entregra_pgs_fake_device = {
static struct usb_serial_device_type keyspan_pda_device = {
name: "Keyspan PDA",
id_table: id_table_std,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: DONT_CARE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 0,
num_bulk_out: 1,
@@ -917,7 +887,6 @@ static int __init keyspan_pda_init (void)
#endif
#ifdef XIRCOM
usb_serial_register (&xircom_pgs_fake_device);
- usb_serial_register (&entregra_pgs_fake_device);
#endif
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
@@ -931,7 +900,6 @@ static void __exit keyspan_pda_exit (void)
usb_serial_deregister (&keyspan_pda_fake_device);
#endif
#ifdef XIRCOM
- usb_serial_deregister (&entregra_pgs_fake_device);
usb_serial_deregister (&xircom_pgs_fake_device);
#endif
}
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 6caac1bcd..f8b7f39f9 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -27,6 +27,9 @@
* 10-Nov-2001 Wolfgang Grandegger
* - Fixed an endianess problem with the baudrate selection for PowerPC.
*
+ * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
+ * Added support for the Belkin F5U109 DB9 adaptor
+ *
* 30-May-2001 Greg Kroah-Hartman
* switched from using spinlock to a semaphore, which fixes lots of problems.
*
@@ -133,57 +136,16 @@ static __devinitdata struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
+ { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id mct_u232_table [] = {
- { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id mct_u232_sitecom_table [] = {
- { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id mct_u232_du_h3sp_table [] = {
- { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
- { } /* Terminating entry */
-};
-
MODULE_DEVICE_TABLE (usb, id_table_combined);
static struct usb_serial_device_type mct_u232_device = {
name: "Magic Control Technology USB-RS232",
- id_table: mct_u232_table,
- needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */
- needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */
- needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */
- num_interrupt_in: 2,
- num_bulk_in: 0,
- num_bulk_out: 1,
- num_ports: 1,
- open: mct_u232_open,
- close: mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
- write: mct_u232_write,
- write_bulk_callback: mct_u232_write_bulk_callback,
-#endif
- read_int_callback: mct_u232_read_int_callback,
- ioctl: mct_u232_ioctl,
- set_termios: mct_u232_set_termios,
- break_ctl: mct_u232_break_ctl,
- startup: mct_u232_startup,
- shutdown: mct_u232_shutdown,
-};
-
-static struct usb_serial_device_type mct_u232_sitecom_device = {
- name: "MCT/Sitecom USB-RS232",
- id_table: mct_u232_sitecom_table,
- needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */
- needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */
- needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */
+ id_table: id_table_combined,
num_interrupt_in: 2,
num_bulk_in: 0,
num_bulk_out: 1,
@@ -202,32 +164,6 @@ static struct usb_serial_device_type mct_u232_sitecom_device = {
shutdown: mct_u232_shutdown,
};
-static struct usb_serial_device_type mct_u232_du_h3sp_device = {
- name: "MCT/D-Link DU-H3SP USB BAY",
- id_table: mct_u232_du_h3sp_table,
- needs_interrupt_in: MUST_HAVE, /* 2 interrupt-in endpoints */
- needs_bulk_in: MUST_HAVE_NOT, /* no bulk-in endpoint */
- needs_bulk_out: MUST_HAVE, /* 1 bulk-out endpoint */
- num_interrupt_in: 2,
- num_bulk_in: 0,
- num_bulk_out: 1,
- num_ports: 1,
- open: mct_u232_open,
- close: mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
- write: mct_u232_write,
- write_bulk_callback: mct_u232_write_bulk_callback,
-#endif
- read_int_callback: mct_u232_read_int_callback,
- ioctl: mct_u232_ioctl,
- set_termios: mct_u232_set_termios,
- break_ctl: mct_u232_break_ctl,
- startup: mct_u232_startup,
- shutdown: mct_u232_shutdown,
-};
-
-
-
struct mct_u232_private {
unsigned long control_state; /* Modem Line Setting (TIOCM) */
@@ -243,7 +179,8 @@ struct mct_u232_private {
#define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
- if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID) {
+ if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
+ || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
switch (value) {
case 300: return 0x01;
case 600: return 0x02; /* this one not tested */
@@ -408,9 +345,7 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/* Compensate for a hardware bug: although the Sitecom U232-P25
* device reports a maximum output packet size of 32 bytes,
* it seems to be able to accept only 16 bytes (and that's what
@@ -484,7 +419,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
}
- port->active = 0;
+ port->open_count = 0;
}
up (&port->sem);
@@ -880,9 +815,7 @@ static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
static int __init mct_u232_init (void)
{
usb_serial_register (&mct_u232_device);
- usb_serial_register (&mct_u232_sitecom_device);
- usb_serial_register (&mct_u232_du_h3sp_device);
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
@@ -890,8 +823,6 @@ static int __init mct_u232_init (void)
static void __exit mct_u232_exit (void)
{
usb_serial_deregister (&mct_u232_device);
- usb_serial_deregister (&mct_u232_sitecom_device);
- usb_serial_deregister (&mct_u232_du_h3sp_device);
}
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h
index 84e79ddc6..06ca30b80 100644
--- a/drivers/usb/serial/mct_u232.h
+++ b/drivers/usb/serial/mct_u232.h
@@ -30,9 +30,12 @@
#define MCT_U232_SITECOM_PID 0x0230 /* Sitecom Product Id */
/* DU-H3SP USB BAY hub */
-
#define MCT_U232_DU_H3SP_PID 0x0200 /* D-Link DU-H3SP USB BAY */
+/* Belkin badge the MCT U232-P9 as the F5U109 */
+#define MCT_U232_BELKIN_F5U109_VID 0x050d /* Vendor Id */
+#define MCT_U232_BELKIN_F5U109_PID 0x0109 /* Product Id */
+
/*
* Vendor Request Interface
*/
@@ -363,6 +366,25 @@
* bmAttributes = 03 (Interrupt)
* wMaxPacketSize = 0002
* bInterval = 02
+ *
+ *
+ * Hardware details (added by Martin Hamilton, 2001/12/06)
+ * -----------------------------------------------------------------
+ *
+ * This info was gleaned from opening a Belkin F5U109 DB9 USB serial
+ * adaptor, which turns out to simply be a re-badged U232-P9. We
+ * know this because there is a sticky label on the circuit board
+ * which says "U232-P9" ;-)
+ *
+ * The circuit board inside the adaptor contains a Philips PDIUSBD12
+ * USB endpoint chip and a Phillips P87C52UBAA microcontroller with
+ * embedded UART. Exhaustive documentation for these is available at:
+ *
+ * http://www.semiconductors.philips.com/pip/p87c52ubaa
+ * http://www.semiconductors.philips.com/pip/pdiusbd12
+ *
+ * Thanks to Julian Highfield for the pointer to the Philips database.
+ *
*/
#endif /* __LINUX_USB_SERIAL_MCT_U232_H */
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 07ee634b3..ff8e75733 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -90,9 +90,6 @@ MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_serial_device_type zyxel_omninet_device = {
name: "ZyXEL - omni.net lcd plus usb",
id_table: id_table,
- needs_interrupt_in: MUST_HAVE,
- needs_bulk_in: MUST_HAVE,
- needs_bulk_out: MUST_HAVE,
num_interrupt_in: 1,
num_bulk_in: 1,
num_bulk_out: 2,
@@ -164,14 +161,11 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
MOD_INC_USE_COUNT;
++port->open_count;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
if( !od ) {
err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
- --port->open_count;
- port->active = 0;
+ port->open_count = 0;
up (&port->sem);
MOD_DEC_USE_COUNT;
return -ENOMEM;
@@ -222,7 +216,6 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
usb_unlink_urb (port->read_urb);
}
- port->active = 0;
port->open_count = 0;
od = (struct omninet_data *)port->private;
if (od)
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 85ff19b6b..07ff1da9c 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -118,9 +118,6 @@ static void pl2303_shutdown (struct usb_serial *serial);
static struct usb_serial_device_type pl2303_device = {
name: "PL-2303",
id_table: id_table,
- needs_interrupt_in: DONT_CARE, /* this device must have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -374,9 +371,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
#define FISH(a,b,c,d) \
result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
b, a, c, d, buf, 1, 100); \
@@ -481,8 +476,6 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
"(interrupt_in_urb) failed with reason: %d",
result);
}
-
- port->active = 0;
port->open_count = 0;
}
@@ -651,7 +644,7 @@ static void pl2303_read_bulk_callback (struct urb *urb)
if (urb->status) {
dbg (__FUNCTION__ " - urb->status = %d", urb->status);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port is closed, exiting.");
return;
}
@@ -683,7 +676,7 @@ static void pl2303_read_bulk_callback (struct urb *urb)
}
/* Schedule the next read _if_ we are still open */
- if (port->active) {
+ if (port->open_count) {
urb->dev = serial->dev;
result = usb_submit_urb(urb);
if (result)
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index 5d40a8d51..db1f4ff4f 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -11,6 +11,10 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (12/03/2001) gkh
+ * removed active from the port structure.
+ * added documentation to the usb_serial_device_type structure
+ *
* (10/10/2001) gkh
* added vendor and product to serial structure. Needed to determine device
* owner when the device is disconnected.
@@ -65,7 +69,6 @@ struct usb_serial_port {
struct usb_serial *serial; /* pointer back to the owner of this port */
struct tty_struct * tty; /* the coresponding tty for this port */
unsigned char number;
- char active; /* someone has this device open */
unsigned char * interrupt_in_buffer;
struct urb * interrupt_in_urb;
@@ -108,34 +111,43 @@ struct usb_serial {
};
-#define MUST_HAVE_NOT 0x01
-#define MUST_HAVE 0x02
-#define DONT_CARE 0x03
-
-#define HAS 0x02
-#define HAS_NOT 0x01
-
#define NUM_DONT_CARE (-1)
-/* This structure defines the individual serial converter. */
+/**
+ * usb_serial_device_type - a structure that defines a usb serial device
+ * @name: pointer to a string that describes this device. This string used
+ * in the syslog messages when a device is inserted or removed.
+ * @id_table: pointer to a list of usb_device_id structures that define all
+ * of the devices this structure can support.
+ * @num_interrupt_in: the number of interrupt in endpoints this device will
+ * have.
+ * @num_bulk_in: the number of bulk in endpoints this device will have.
+ * @num_bulk_out: the number of bulk out endpoints this device will have.
+ * @num_ports: the number of different ports this device will have.
+ * @startup: pointer to the driver's startup function. This will be called
+ * when the driver is inserted into the system. Return 0 to continue
+ * on with the initialization sequence. Anything else will abort it.
+ * @shutdown: pointer to the driver's shutdown function. This will be
+ * called when the device is removed from the system.
+ *
+ * This structure is defines a USB Serial device. It provides all of
+ * the information that the USB serial core code needs. If the function
+ * pointers are defined, then the USB serial core code will call them when
+ * the corresponding tty port functions are called. If they are not
+ * called, the generic serial function will be used instead.
+ */
struct usb_serial_device_type {
char *name;
const struct usb_device_id *id_table;
- char needs_interrupt_in;
- char needs_bulk_in;
- char needs_bulk_out;
char num_interrupt_in;
char num_bulk_in;
char num_bulk_out;
- char num_ports; /* number of serial ports this device has */
+ char num_ports;
struct list_head driver_list;
- /* function call to make before accepting driver */
- /* return 0 to continue initialization, anything else to abort */
int (*startup) (struct usb_serial *serial);
-
void (*shutdown) (struct usb_serial *serial);
/* serial function calls */
diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
index b492bb672..fdd07e6c7 100644
--- a/drivers/usb/serial/usbserial.c
+++ b/drivers/usb/serial/usbserial.c
@@ -339,9 +339,6 @@ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
static struct usb_serial_device_type generic_device = {
name: "Generic",
id_table: generic_device_ids,
- needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */
- needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */
- needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -548,7 +545,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not opened");
return;
}
@@ -573,7 +570,7 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not opened");
return -EINVAL;
}
@@ -598,7 +595,7 @@ static int serial_write_room (struct tty_struct *tty)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return -EINVAL;
}
@@ -621,7 +618,7 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
return -ENODEV;
}
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return -EINVAL;
}
@@ -646,7 +643,7 @@ static void serial_throttle (struct tty_struct * tty)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return;
}
@@ -671,7 +668,7 @@ static void serial_unthrottle (struct tty_struct * tty)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return;
}
@@ -696,7 +693,7 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return -ENODEV;
}
@@ -721,7 +718,7 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return;
}
@@ -746,7 +743,7 @@ static void serial_break (struct tty_struct *tty, int break_state)
dbg(__FUNCTION__ " - port %d", port->number);
- if (!port->active) {
+ if (!port->open_count) {
dbg (__FUNCTION__ " - port not open");
return;
}
@@ -790,9 +787,7 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/* force low_latency on so that our tty_push actually forces the data through,
otherwise it is scheduled, and with high data rates (like with OHCI) data
can get lost. */
@@ -801,13 +796,14 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
/* if we have a bulk interrupt, start reading from it */
if (serial->num_bulk_in) {
/* Start reading from the device */
- FILL_BULK_URB(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ((serial->type->read_bulk_callback) ?
- serial->type->read_bulk_callback :
- generic_read_bulk_callback),
- port);
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ((serial->type->read_bulk_callback) ?
+ serial->type->read_bulk_callback :
+ generic_read_bulk_callback),
+ port);
result = usb_submit_urb(port->read_urb);
if (result)
err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -838,8 +834,6 @@ static void generic_close (struct usb_serial_port *port, struct file * filp)
if (serial->num_bulk_in)
usb_unlink_urb (port->read_urb);
}
-
- port->active = 0;
port->open_count = 0;
}
@@ -882,13 +876,13 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
/* set up our urb */
- FILL_BULK_URB(port->write_urb, serial->dev,
- usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
- port->write_urb->transfer_buffer, count,
- ((serial->type->write_bulk_callback) ?
- serial->type->write_bulk_callback :
- generic_write_bulk_callback),
- port);
+ usb_fill_bulk_urb (port->write_urb, serial->dev,
+ usb_sndbulkpipe (serial->dev,
+ port->bulk_out_endpointAddress),
+ port->write_urb->transfer_buffer, count,
+ ((serial->type->write_bulk_callback) ?
+ serial->type->write_bulk_callback :
+ generic_write_bulk_callback), port);
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb);
@@ -976,13 +970,14 @@ static void generic_read_bulk_callback (struct urb *urb)
}
/* Continue trying to always read */
- FILL_BULK_URB(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- ((serial->type->read_bulk_callback) ?
- serial->type->read_bulk_callback :
- generic_read_bulk_callback),
- port);
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe (serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ ((serial->type->read_bulk_callback) ?
+ serial->type->read_bulk_callback :
+ generic_read_bulk_callback), port);
result = usb_submit_urb(port->read_urb);
if (result)
err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -1068,9 +1063,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
int minor;
int buffer_size;
int i;
- char interrupt_pipe;
- char bulk_in_pipe;
- char bulk_out_pipe;
int num_interrupt_in = 0;
int num_bulk_in = 0;
int num_bulk_out = 0;
@@ -1097,10 +1089,8 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
dbg("none matched");
return(NULL);
}
-
+
/* descriptor matches, let's find the endpoints needed */
- interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT;
-
/* check out the endpoints */
iface_desc = &interface->altsetting[0];
for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
@@ -1110,7 +1100,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk in endpoint */
dbg("found bulk in");
- bulk_in_pipe = HAS;
bulk_in_endpoint[num_bulk_in] = endpoint;
++num_bulk_in;
}
@@ -1119,7 +1108,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk out endpoint */
dbg("found bulk out");
- bulk_out_pipe = HAS;
bulk_out_endpoint[num_bulk_out] = endpoint;
++num_bulk_out;
}
@@ -1128,7 +1116,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
((endpoint->bmAttributes & 3) == 0x03)) {
/* we found a interrupt in endpoint */
dbg("found interrupt in");
- interrupt_pipe = HAS;
interrupt_in_endpoint[num_interrupt_in] = endpoint;
++num_interrupt_in;
}
@@ -1151,7 +1138,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
((endpoint->bmAttributes & 3) == 0x03)) {
/* we found a interrupt in endpoint */
dbg("found interrupt in for Prolific device on separate interface");
- interrupt_pipe = HAS;
interrupt_in_endpoint[num_interrupt_in] = endpoint;
++num_interrupt_in;
}
@@ -1161,15 +1147,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
/* END HORRIBLE HACK FOR PL2303 */
#endif
- /* verify that we found all of the endpoints that we need */
- if (!((interrupt_pipe & type->needs_interrupt_in) &&
- (bulk_in_pipe & type->needs_bulk_in) &&
- (bulk_out_pipe & type->needs_bulk_out))) {
- /* nope, they don't match what we expected */
- info("descriptors matched, but endpoints did not");
- return NULL;
- }
-
/* found all that we need */
info("%s converter detected", type->name);
@@ -1224,13 +1201,14 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
err("Couldn't allocate bulk_in_buffer");
goto probe_error;
}
- FILL_BULK_URB(port->read_urb, dev,
- usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
- port->bulk_in_buffer, buffer_size,
- ((serial->type->read_bulk_callback) ?
- serial->type->read_bulk_callback :
- generic_read_bulk_callback),
- port);
+ usb_fill_bulk_urb (port->read_urb, dev,
+ usb_rcvbulkpipe (dev,
+ endpoint->bEndpointAddress),
+ port->bulk_in_buffer, buffer_size,
+ ((serial->type->read_bulk_callback) ?
+ serial->type->read_bulk_callback :
+ generic_read_bulk_callback),
+ port);
}
for (i = 0; i < num_bulk_out; ++i) {
@@ -1249,13 +1227,14 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
err("Couldn't allocate bulk_out_buffer");
goto probe_error;
}
- FILL_BULK_URB(port->write_urb, dev,
- usb_sndbulkpipe(dev, endpoint->bEndpointAddress),
- port->bulk_out_buffer, buffer_size,
- ((serial->type->write_bulk_callback) ?
- serial->type->write_bulk_callback :
- generic_write_bulk_callback),
- port);
+ usb_fill_bulk_urb (port->write_urb, dev,
+ usb_sndbulkpipe (dev,
+ endpoint->bEndpointAddress),
+ port->bulk_out_buffer, buffer_size,
+ ((serial->type->write_bulk_callback) ?
+ serial->type->write_bulk_callback :
+ generic_write_bulk_callback),
+ port);
}
for (i = 0; i < num_interrupt_in; ++i) {
@@ -1273,12 +1252,12 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
err("Couldn't allocate interrupt_in_buffer");
goto probe_error;
}
- FILL_INT_URB(port->interrupt_in_urb, dev,
- usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- port->interrupt_in_buffer, buffer_size,
- serial->type->read_int_callback,
- port,
- endpoint->bInterval);
+ usb_fill_int_urb (port->interrupt_in_urb, dev,
+ usb_rcvintpipe (dev,
+ endpoint->bEndpointAddress),
+ port->interrupt_in_buffer, buffer_size,
+ serial->type->read_int_callback, port,
+ endpoint->bInterval);
}
/* initialize some parts of the port structures */
@@ -1356,7 +1335,7 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
serial_shutdown (serial);
for (i = 0; i < serial->num_ports; ++i)
- serial->port[i].active = 0;
+ serial->port[i].open_count = 0;
for (i = 0; i < serial->num_bulk_in; ++i) {
port = &serial->port[i];
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 5147acebc..292101a81 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -127,7 +127,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.5"
+#define DRIVER_VERSION "v1.7"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver"
@@ -147,15 +147,12 @@ static void visor_write_bulk_callback (struct urb *urb);
static void visor_read_bulk_callback (struct urb *urb);
-static __devinitdata struct usb_device_id visor_id_table [] = {
- { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
- { } /* Terminating entry */
-};
-
-static __devinitdata struct usb_device_id palm_4_0_id_table [] = {
+static __devinitdata struct usb_device_id combined_id_table [] = {
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
+ { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ } /* Terminating entry */
};
@@ -164,11 +161,6 @@ static __devinitdata struct usb_device_id clie_id_3_5_table [] = {
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id clie_id_4_0_table [] = {
- { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
- { } /* Terminating entry */
-};
-
static __devinitdata struct usb_device_id id_table [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
@@ -183,13 +175,10 @@ MODULE_DEVICE_TABLE (usb, id_table);
-/* All of the device info needed for the Handspring Visor */
+/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
static struct usb_serial_device_type handspring_device = {
- name: "Handspring Visor",
- id_table: visor_id_table,
- needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
+ name: "Handspring Visor / Palm 4.0 / Clié 4.0",
+ id_table: combined_id_table,
num_interrupt_in: 0,
num_bulk_in: 2,
num_bulk_out: 2,
@@ -209,40 +198,10 @@ static struct usb_serial_device_type handspring_device = {
read_bulk_callback: visor_read_bulk_callback,
};
-/* device info for the Palm 4.0 devices */
-static struct usb_serial_device_type palm_4_0_device = {
- name: "Palm 4.0",
- id_table: palm_4_0_id_table,
- needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 0,
- num_bulk_in: 2,
- num_bulk_out: 2,
- num_ports: 2,
- open: visor_open,
- close: visor_close,
- throttle: visor_throttle,
- unthrottle: visor_unthrottle,
- startup: visor_startup,
- shutdown: visor_shutdown,
- ioctl: visor_ioctl,
- set_termios: visor_set_termios,
- write: visor_write,
- write_room: visor_write_room,
- chars_in_buffer: visor_chars_in_buffer,
- write_bulk_callback: visor_write_bulk_callback,
- read_bulk_callback: visor_read_bulk_callback,
-};
-
-
/* device info for the Sony Clie OS version 3.5 */
static struct usb_serial_device_type clie_3_5_device = {
name: "Sony Clié 3.5",
id_table: clie_id_3_5_table,
- needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
num_interrupt_in: 0,
num_bulk_in: 1,
num_bulk_out: 1,
@@ -260,31 +219,6 @@ static struct usb_serial_device_type clie_3_5_device = {
read_bulk_callback: visor_read_bulk_callback,
};
-/* device info for the Sony Clie OS version 4.0 */
-static struct usb_serial_device_type clie_4_0_device = {
- name: "Sony Clié 4.0",
- id_table: clie_id_4_0_table,
- needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
- needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
- needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
- num_interrupt_in: 0,
- num_bulk_in: 2,
- num_bulk_out: 2,
- num_ports: 2,
- open: visor_open,
- close: visor_close,
- throttle: visor_throttle,
- unthrottle: visor_unthrottle,
- startup: visor_startup,
- shutdown: visor_shutdown,
- ioctl: visor_ioctl,
- set_termios: visor_set_termios,
- write: visor_write,
- write_room: visor_write_room,
- chars_in_buffer: visor_chars_in_buffer,
- write_bulk_callback: visor_write_bulk_callback,
- read_bulk_callback: visor_read_bulk_callback,
-};
#define NUM_URBS 24
#define URB_TRANSFER_BUFFER_SIZE 768
@@ -317,8 +251,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
+ if (port->open_count == 1) {
bytes_in = 0;
bytes_out = 0;
@@ -328,10 +261,12 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
port->tty->low_latency = 1;
/* Start reading from the device */
- FILL_BULK_URB(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- visor_read_bulk_callback, port);
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe (serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ visor_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
@@ -380,7 +315,6 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
/* shutdown our bulk read */
usb_unlink_urb (port->read_urb);
}
- port->active = 0;
port->open_count = 0;
}
up (&port->sem);
@@ -441,8 +375,11 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer);
/* build up our urb */
- FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
- urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port);
+ usb_fill_bulk_urb (urb, serial->dev,
+ usb_sndbulkpipe (serial->dev,
+ port->bulk_out_endpointAddress),
+ urb->transfer_buffer, transfer_size,
+ visor_write_bulk_callback, port);
urb->transfer_flags |= USB_QUEUE_BULK;
/* send it down the pipe */
@@ -572,10 +509,12 @@ static void visor_read_bulk_callback (struct urb *urb)
}
/* Continue trying to always read */
- FILL_BULK_URB(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
- visor_read_bulk_callback, port);
+ usb_fill_bulk_urb (port->read_urb, serial->dev,
+ usb_rcvbulkpipe (serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ visor_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb);
if (result)
err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -713,10 +652,8 @@ static void visor_shutdown (struct usb_serial *serial)
dbg (__FUNCTION__);
/* stop reads and writes on all ports */
- for (i=0; i < serial->num_ports; ++i) {
- serial->port[i].active = 0;
+ for (i=0; i < serial->num_ports; ++i)
serial->port[i].open_count = 0;
- }
}
@@ -800,9 +737,7 @@ static int __init visor_init (void)
int i;
usb_serial_register (&handspring_device);
- usb_serial_register (&palm_4_0_device);
usb_serial_register (&clie_3_5_device);
- usb_serial_register (&clie_4_0_device);
/* create our write urb pool and transfer buffers */
spin_lock_init (&write_urb_pool_lock);
@@ -834,9 +769,7 @@ static void __exit visor_exit (void)
unsigned long flags;
usb_serial_deregister (&handspring_device);
- usb_serial_deregister (&palm_4_0_device);
usb_serial_deregister (&clie_3_5_device);
- usb_serial_deregister (&clie_4_0_device);
spin_lock_irqsave (&write_urb_pool_lock, flags);
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index c8b1a9f9f..e07b797e8 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -88,7 +88,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
@@ -128,28 +128,23 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file,
static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * old);
static void whiteheat_throttle (struct usb_serial_port *port);
static void whiteheat_unthrottle (struct usb_serial_port *port);
-static int whiteheat_startup (struct usb_serial *serial);
-static void whiteheat_shutdown (struct usb_serial *serial);
+static int whiteheat_fake_startup (struct usb_serial *serial);
+static int whiteheat_real_startup (struct usb_serial *serial);
+static void whiteheat_real_shutdown (struct usb_serial *serial);
static struct usb_serial_device_type whiteheat_fake_device = {
name: "Connect Tech - WhiteHEAT - (prerenumeration)",
id_table: id_table_prerenumeration,
- needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */
- needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */
- needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
num_ports: 1,
- startup: whiteheat_startup
+ startup: whiteheat_fake_startup,
};
static struct usb_serial_device_type whiteheat_device = {
name: "Connect Tech - WhiteHEAT",
id_table: id_table_std,
- needs_interrupt_in: DONT_CARE, /* don't have to have an interrupt in endpoint */
- needs_bulk_in: DONT_CARE, /* don't have to have a bulk in endpoint */
- needs_bulk_out: DONT_CARE, /* don't have to have a bulk out endpoint */
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: NUM_DONT_CARE,
num_bulk_out: NUM_DONT_CARE,
@@ -160,7 +155,8 @@ static struct usb_serial_device_type whiteheat_device = {
unthrottle: whiteheat_unthrottle,
ioctl: whiteheat_ioctl,
set_termios: whiteheat_set_termios,
- shutdown: whiteheat_shutdown,
+ startup: whiteheat_real_startup,
+ shutdown: whiteheat_real_shutdown,
};
struct whiteheat_private {
@@ -313,9 +309,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
++port->open_count;
MOD_INC_USE_COUNT;
- if (!port->active) {
- port->active = 1;
-
+ if (port->open_count == 1) {
/* set up some stuff for our command port */
command_port = &port->serial->port[COMMAND_PORT];
if (command_port->private == NULL) {
@@ -395,7 +389,7 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
/* shutdown our bulk reads and writes */
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
- port->active = 0;
+ port->open_count = 0;
}
MOD_DEC_USE_COUNT;
up (&port->sem);
@@ -539,7 +533,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
- device renumerated itself and comes up as new device id with all
firmware download completed.
*/
-static int whiteheat_startup (struct usb_serial *serial)
+static int whiteheat_fake_startup (struct usb_serial *serial)
{
int response;
const struct whiteheat_hex_record *record;
@@ -598,7 +592,66 @@ static int whiteheat_startup (struct usb_serial *serial)
}
-static void whiteheat_shutdown (struct usb_serial *serial)
+static int whiteheat_real_startup (struct usb_serial *serial)
+{
+ struct whiteheat_hw_info *hw_info;
+ int pipe;
+ int ret;
+ int alen;
+ __u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
+ __u8 result[sizeof(*hw_info) + 1];
+
+ pipe = usb_rcvbulkpipe (serial->dev, 7);
+ usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+ /*
+ * We ignore the return code. In the case where rmmod/insmod is
+ * performed with a WhiteHEAT connected, the above times out
+ * because the endpoint is already prepped, meaning the below succeeds
+ * regardless. All other cases the above succeeds.
+ */
+
+ pipe = usb_sndbulkpipe (serial->dev, 7);
+ ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);
+ if (ret) {
+ err("%s: Couldn't send command [%d]", serial->type->name, ret);
+ goto error_out;
+ } else if (alen != sizeof(command)) {
+ err("%s: Send command incomplete [%d]", serial->type->name, alen);
+ goto error_out;
+ }
+
+ pipe = usb_rcvbulkpipe (serial->dev, 7);
+ ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+ if (ret) {
+ err("%s: Couldn't get results [%d]", serial->type->name, ret);
+ goto error_out;
+ } else if (alen != sizeof(result)) {
+ err("%s: Get results incomplete [%d]", serial->type->name, alen);
+ goto error_out;
+ } else if (result[0] != command[0]) {
+ err("%s: Command failed [%d]", serial->type->name, result[0]);
+ goto error_out;
+ }
+
+ hw_info = (struct whiteheat_hw_info *)&result[1];
+
+ info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+ DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+
+ return 0;
+
+error_out:
+ err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+ /*
+ * Return that we've claimed the interface. A failure here may be
+ * due to interception by the command_callback routine or other
+ * causes that don't mean that the firmware isn't running. This may
+ * change in the future. Probably should actually.
+ */
+ return 0;
+}
+
+static void whiteheat_real_shutdown (struct usb_serial *serial)
{
struct usb_serial_port *command_port;
int i;
@@ -660,7 +713,7 @@ static int __init whiteheat_init (void)
{
usb_serial_register (&whiteheat_fake_device);
usb_serial_register (&whiteheat_device);
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
diff --git a/drivers/usb/serial/whiteheat_fw.h b/drivers/usb/serial/whiteheat_fw.h
index e50a9e82f..b64de945e 100644
--- a/drivers/usb/serial/whiteheat_fw.h
+++ b/drivers/usb/serial/whiteheat_fw.h
@@ -47,28 +47,28 @@ struct whiteheat_hex_record {
};
static const struct whiteheat_hex_record whiteheat_firmware[] = {
-{ 0x0000, 3, {0x02, 0x95, 0x09} },
+{ 0x0000, 3, {0x02, 0x95, 0xe7} },
{ 0x0003, 3, {0x02, 0x13, 0x12} },
-{ 0x000b, 3, {0x02, 0x0a, 0x91} },
-{ 0x0033, 3, {0x02, 0x08, 0x1b} },
+{ 0x000b, 3, {0x02, 0x0b, 0xb5} },
+{ 0x0033, 3, {0x02, 0x08, 0x18} },
{ 0x0043, 3, {0x02, 0x0a, 0x00} },
-{ 0x005b, 3, {0x02, 0x1a, 0xd2} },
+{ 0x005b, 3, {0x02, 0x11, 0xdd} },
{ 0x0370, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} },
{ 0x0380, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} },
{ 0x0390, 16, {0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} },
{ 0x03a0, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} },
{ 0x03b0, 16, {0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} },
-{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x81, 0xea, 0x49, 0x60, 0x0d} },
+{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} },
{ 0x03d0, 16, {0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} },
-{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x40, 0xea} },
-{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0x9f, 0x48, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} },
-{ 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4b, 0x40} },
-{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xb5} },
-{ 0x0420, 16, {0xe5, 0x4b, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
+{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} },
+{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0xa0, 0x3f, 0xf5, 0x4c, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4c, 0xd3} },
+{ 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4c, 0x40} },
+{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4c, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xb5} },
+{ 0x0420, 16, {0xe5, 0x4c, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
{ 0x0430, 16, {0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} },
{ 0x0440, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} },
-{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
-{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
+{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x32, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
+{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x32, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
{ 0x0470, 16, {0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} },
{ 0x0480, 16, {0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} },
{ 0x0490, 16, {0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} },
@@ -79,8 +79,8 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x04e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} },
{ 0x04f0, 16, {0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} },
{ 0x0500, 16, {0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4b, 0xef, 0x30, 0xe7, 0x03} },
-{ 0x0520, 16, {0x43, 0x4b, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4b, 0xf0, 0xe5, 0x4b, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
+{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4c, 0xef, 0x30, 0xe7, 0x03} },
+{ 0x0520, 16, {0x43, 0x4c, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4c, 0xf0, 0xe5, 0x4c, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
{ 0x0530, 16, {0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} },
{ 0x0540, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} },
{ 0x0550, 16, {0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} },
@@ -90,229 +90,226 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x0590, 16, {0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} },
{ 0x05a0, 12, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
{ 0x05ac, 1, {0x22} },
-{ 0x05ad, 16, {0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
+{ 0x05ad, 16, {0x75, 0x48, 0xff, 0x75, 0x47, 0xff, 0x75, 0x46, 0x0f, 0x75, 0x45, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
{ 0x05bd, 16, {0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} },
{ 0x05cd, 16, {0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} },
-{ 0x05dd, 16, {0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
+{ 0x05dd, 16, {0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
{ 0x05ed, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} },
-{ 0x05fd, 16, {0x01, 0x7f, 0x00, 0x12, 0x10, 0x2c, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
-{ 0x060d, 16, {0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x061d, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x062d, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
-{ 0x063d, 16, {0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x064d, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
+{ 0x05fd, 16, {0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
+{ 0x060d, 16, {0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
+{ 0x061d, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x062d, 16, {0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
+{ 0x063d, 16, {0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x064d, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
{ 0x065d, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} },
{ 0x066d, 16, {0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} },
{ 0x067d, 16, {0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} },
-{ 0x068d, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} },
-{ 0x069d, 16, {0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x91, 0x7a, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} },
-{ 0x06ad, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} },
-{ 0x06bd, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x06cd, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
-{ 0x06dd, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
-{ 0x06ed, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} },
+{ 0x068d, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x50, 0x10, 0x75, 0x51, 0x02, 0x75} },
+{ 0x069d, 16, {0x52, 0x12, 0x75, 0x53, 0xac, 0x12, 0x92, 0x2a, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0xb2, 0x90, 0x01} },
+{ 0x06ad, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82} },
+{ 0x06bd, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x06cd, 16, {0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
+{ 0x06dd, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
+{ 0x06ed, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xae, 0x4a, 0x70, 0x02, 0x05, 0x4a} },
{ 0x06fd, 16, {0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} },
-{ 0x070d, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa0, 0xfb, 0x7e, 0x01} },
-{ 0x071d, 16, {0x7f, 0x18, 0x12, 0x85, 0x2f, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x072d, 16, {0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} },
-{ 0x073d, 16, {0x91, 0x7a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
+{ 0x070d, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa1, 0xf2, 0x7e, 0x01} },
+{ 0x071d, 16, {0x7f, 0x18, 0x12, 0x85, 0xcf, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x072d, 16, {0xa3, 0xe0, 0xff, 0x75, 0x50, 0x0a, 0x75, 0x51, 0x06, 0x75, 0x52, 0x12, 0x75, 0x53, 0xb8, 0x12} },
+{ 0x073d, 16, {0x92, 0x2a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
{ 0x074d, 16, {0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} },
-{ 0x075d, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xd0, 0x75, 0x43, 0x50} },
-{ 0x076d, 16, {0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
-{ 0x077d, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0xa0, 0xe4, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
-{ 0x078d, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x09, 0xf5, 0x50} },
-{ 0x079d, 16, {0x06, 0x12, 0x0b, 0x00, 0x12, 0x09, 0xfa, 0xc2, 0x06, 0x12, 0x93, 0x98, 0x90, 0x01, 0xbd, 0xe0} },
-{ 0x07ad, 16, {0x60, 0x0c, 0x12, 0x8f, 0x55, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02} },
-{ 0x07bd, 16, {0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x96, 0xe2, 0x12, 0x9d, 0xa2, 0xe4, 0xff, 0x74, 0x01, 0xa8} },
-{ 0x07cd, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14} },
-{ 0x07dd, 16, {0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00} },
-{ 0x07ed, 16, {0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5} },
-{ 0x07fd, 16, {0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f} },
-{ 0x080d, 13, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
-{ 0x081a, 1, {0x22} },
-{ 0x081b, 4, {0x53, 0xd8, 0xef, 0x32} },
-{ 0x081f, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0x74, 0x89} },
-{ 0x082f, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x083f, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff} },
-{ 0x084f, 16, {0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} },
-{ 0x085f, 16, {0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x086f, 16, {0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} },
-{ 0x087f, 16, {0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} },
-{ 0x088f, 7, {0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x22} },
-{ 0x0896, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
-{ 0x08a6, 16, {0x09, 0x29, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29} },
-{ 0x08b6, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x08c6, 16, {0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x08d6, 16, {0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} },
-{ 0x08e6, 12, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x12, 0x0b, 0x00, 0x22} },
-{ 0x08f2, 16, {0x90, 0x95, 0xbe, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
-{ 0x0902, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} },
-{ 0x0912, 16, {0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x1f, 0x75, 0x82, 0xbe} },
-{ 0x0922, 7, {0x75, 0x83, 0x95, 0x74, 0xff, 0xf0, 0x22} },
-{ 0x0929, 16, {0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} },
-{ 0x0939, 7, {0x05, 0x12, 0x0a, 0x58, 0x80, 0xee, 0x22} },
-{ 0x0940, 2, {0x8f, 0x4c} },
-{ 0x0942, 16, {0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} },
-{ 0x0952, 16, {0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} },
-{ 0x0962, 16, {0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9f, 0x48, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0972, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0980, 1, {0x22} },
-{ 0x0981, 16, {0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} },
-{ 0x0991, 16, {0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x09a1, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9f, 0xba, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} },
-{ 0x09b1, 16, {0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x09c1, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x09cf, 1, {0x22} },
-{ 0x09d0, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
-{ 0x09e0, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x09f0, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x09f5, 5, {0x12, 0x08, 0x96, 0xd3, 0x22} },
-{ 0x09fa, 5, {0x12, 0x08, 0x1f, 0xd3, 0x22} },
+{ 0x075d, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xc1, 0x75, 0x44, 0x50} },
+{ 0x076d, 16, {0x75, 0x43, 0x6d, 0x75, 0x42, 0x33, 0x75, 0x41, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
+{ 0x077d, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x41, 0x12, 0xa1, 0xdb, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
+{ 0x078d, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a, 0x12, 0x09, 0xf7, 0x50} },
+{ 0x079d, 16, {0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x94, 0x62, 0x90, 0x01, 0xbd, 0xe0, 0x60, 0x0c, 0x12} },
+{ 0x07ad, 16, {0x90, 0x05, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4} },
+{ 0x07bd, 16, {0x0f, 0x03, 0x12, 0x97, 0xbd, 0x12, 0x9e, 0x99, 0xe4, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80} },
+{ 0x07cd, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f} },
+{ 0x07dd, 16, {0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0x8e, 0x49, 0x80} },
+{ 0x07ed, 16, {0x03, 0x75, 0x49, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x49} },
+{ 0x07fd, 16, {0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02} },
+{ 0x080d, 10, {0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
+{ 0x0817, 1, {0x22} },
+{ 0x0818, 4, {0x53, 0xd8, 0xef, 0x32} },
+{ 0x081c, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} },
+{ 0x082c, 16, {0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0} },
+{ 0x083c, 16, {0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} },
+{ 0x084c, 16, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} },
+{ 0x085c, 16, {0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} },
+{ 0x086c, 16, {0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
+{ 0x087c, 16, {0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96} },
+{ 0x088c, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54} },
+{ 0x089c, 16, {0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} },
+{ 0x08ac, 8, {0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x22} },
+{ 0x08b4, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
+{ 0x08c4, 16, {0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xa8} },
+{ 0x08d4, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} },
+{ 0x08e4, 16, {0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} },
+{ 0x08f4, 16, {0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} },
+{ 0x0904, 16, {0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5} },
+{ 0x0914, 16, {0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} },
+{ 0x0924, 8, {0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} },
+{ 0x092c, 16, {0x90, 0x0a, 0xf0, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
+{ 0x093c, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa} },
+{ 0x094c, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} },
+{ 0x095c, 16, {0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} },
+{ 0x096c, 16, {0xf5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} },
+{ 0x097c, 16, {0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0b} },
+{ 0x098c, 16, {0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} },
+{ 0x099c, 14, {0xf0, 0x12, 0x08, 0x1c, 0x75, 0x82, 0xf0, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} },
+{ 0x09aa, 16, {0x8e, 0x5b, 0x8f, 0x5c, 0xe5, 0x5c, 0x15, 0x5c, 0xae, 0x5b, 0x70, 0x02, 0x15, 0x5b, 0x4e, 0x60} },
+{ 0x09ba, 7, {0x05, 0x12, 0x09, 0xe6, 0x80, 0xee, 0x22} },
+{ 0x09c1, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
+{ 0x09d1, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
+{ 0x09e1, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} },
+{ 0x09e6, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
+{ 0x09f6, 1, {0x22} },
+{ 0x09f7, 5, {0x12, 0x08, 0xb4, 0xd3, 0x22} },
+{ 0x09fc, 1, {0x32} },
+{ 0x09fd, 1, {0x32} },
+{ 0x09fe, 1, {0x32} },
{ 0x09ff, 1, {0x32} },
-{ 0x0a00, 16, {0x02, 0x0b, 0xaa, 0x00, 0x02, 0x0b, 0xdd, 0x00, 0x02, 0x0b, 0xc2, 0x00, 0x02, 0x0c, 0x1c, 0x00} },
-{ 0x0a10, 16, {0x02, 0x0c, 0x06, 0x00, 0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xfe, 0x00, 0x02, 0x0a, 0xff, 0x00} },
-{ 0x0a20, 16, {0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x29, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7d, 0x00} },
-{ 0x0a30, 16, {0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xd1, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x25, 0x00} },
-{ 0x0a40, 16, {0x02, 0x0d, 0x27, 0x00, 0x02, 0x0e, 0x79, 0x00, 0x02, 0x0d, 0x28, 0x00, 0x02, 0x0e, 0x7a, 0x00} },
-{ 0x0a50, 8, {0x02, 0x0e, 0x7b, 0x00, 0x02, 0x0e, 0x91, 0x00} },
-{ 0x0a58, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0a68, 1, {0x22} },
-{ 0x0a69, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
-{ 0x0a79, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
-{ 0x0a89, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
-{ 0x0a90, 1, {0x22} },
-{ 0x0a91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
-{ 0x0aa1, 1, {0x07} },
-{ 0x0aa2, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
-{ 0x0ab2, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
-{ 0x0ac2, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
-{ 0x0ad2, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
-{ 0x0ae2, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
-{ 0x0aef, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0afe, 1, {0x32} },
-{ 0x0aff, 1, {0x32} },
+{ 0x0a00, 16, {0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} },
+{ 0x0a10, 16, {0x02, 0x0c, 0xaa, 0x00, 0x02, 0x09, 0xfc, 0x00, 0x02, 0x09, 0xfd, 0x00, 0x02, 0x09, 0xfe, 0x00} },
+{ 0x0a20, 16, {0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x1f, 0x00} },
+{ 0x0a30, 16, {0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x73, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xc7, 0x00} },
+{ 0x0a40, 16, {0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xef, 0x00} },
+{ 0x0a50, 8, {0x02, 0x0f, 0x1b, 0x00, 0x02, 0x0f, 0x31, 0x00} },
+{ 0x0a58, 2, {0x8f, 0x4d} },
+{ 0x0a5a, 16, {0xe4, 0xf5, 0x4e, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x6a, 0xab, 0x4f, 0xaa, 0x50} },
+{ 0x0a6a, 16, {0xa9, 0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x03, 0x1d, 0xaf, 0x4e, 0x05, 0x4e, 0xef} },
+{ 0x0a7a, 16, {0xb5, 0x4d, 0x01, 0x22, 0x12, 0xa0, 0x3f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
+{ 0x0a8a, 14, {0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0a98, 1, {0x22} },
+{ 0x0a99, 16, {0xe4, 0xfe, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x12, 0xab, 0x4f, 0xaa, 0x50, 0xa9} },
+{ 0x0aa9, 16, {0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
+{ 0x0ab9, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa0, 0xb1, 0x85, 0xf0, 0x4d, 0xf5, 0x4e, 0x62, 0x4d} },
+{ 0x0ac9, 16, {0xe5, 0x4d, 0x62, 0x4e, 0xe5, 0x4e, 0x62, 0x4d, 0x29, 0xfd, 0xe5, 0x4d, 0x3a, 0xa9, 0x05, 0x75} },
+{ 0x0ad9, 14, {0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0ae7, 1, {0x22} },
+{ 0x0ae8, 5, {0x12, 0x08, 0x1c, 0xd3, 0x22} },
+{ 0x0aed, 1, {0x32} },
+{ 0x0aee, 1, {0x32} },
+{ 0x0aef, 1, {0x32} },
+{ 0x0af0, 3, {0x00, 0x04, 0x00} },
{ 0x0b00, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} },
{ 0x0b7d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0b8d, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12, 0x08, 0xf2} },
-{ 0x0b9d, 13, {0x12, 0x0e, 0xad, 0x12, 0x11, 0xe5, 0x12, 0x11, 0xc8, 0x12, 0x0a, 0x69, 0x22} },
-{ 0x0baa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
-{ 0x0bba, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bc2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0bd2, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bdd, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
-{ 0x0bed, 16, {0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
-{ 0x0bfd, 9, {0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c06, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
-{ 0x0c16, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c1c, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c2c, 11, {0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c37, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c47, 16, {0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x30, 0xe0, 0x13, 0xe5, 0x3b, 0x30, 0xe0, 0x07, 0x90, 0x20} },
-{ 0x0c57, 16, {0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0c67, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c73, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c83, 16, {0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x30, 0xe1, 0x13, 0xe5, 0x3b, 0x30, 0xe1, 0x07, 0x90, 0x20} },
-{ 0x0c93, 16, {0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0ca3, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0caf, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cbf, 16, {0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x30, 0xe2, 0x13, 0xe5, 0x3b, 0x30, 0xe2, 0x07, 0x90, 0x20} },
-{ 0x0ccf, 16, {0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0cdf, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ceb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cfb, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x30, 0xe3, 0x13, 0xe5, 0x3b, 0x30, 0xe3, 0x07, 0x90, 0x20} },
-{ 0x0d0b, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d1b, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d27, 1, {0x32} },
-{ 0x0d28, 1, {0x32} },
-{ 0x0d29, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d39, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d49, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
-{ 0x0d59, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0d69, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0d79, 4, {0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d7d, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d8d, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d9d, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
-{ 0x0dad, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0dbd, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0dcd, 4, {0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0dd1, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0de1, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0df1, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
-{ 0x0e01, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e11, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e21, 4, {0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e25, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0e35, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0e45, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
-{ 0x0e55, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e65, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e75, 4, {0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e79, 1, {0x32} },
-{ 0x0e7a, 1, {0x32} },
-{ 0x0e7b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
-{ 0x0e8b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
-{ 0x0ea1, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ead, 16, {0x90, 0x01, 0x20, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
-{ 0x0ebd, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
-{ 0x0ecd, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0edd, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
-{ 0x0eed, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f} },
-{ 0x0efd, 16, {0x1f, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0x17, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
-{ 0x0f0d, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0f1d, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
-{ 0x0f2d, 16, {0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
-{ 0x0f3d, 16, {0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f4d, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x0f5d, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83, 0xb7, 0x90, 0x01, 0x1e} },
-{ 0x0f6d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f7d, 16, {0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x0f8d, 16, {0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x36} },
-{ 0x0f9d, 16, {0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
-{ 0x0fad, 16, {0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0fbd, 16, {0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4b, 0x60, 0x5e} },
-{ 0x0fcd, 4, {0xe4, 0x90, 0x01, 0x1e} },
-{ 0x0fd1, 16, {0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
-{ 0x0fe1, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
-{ 0x0ff1, 16, {0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
-{ 0x1001, 16, {0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
-{ 0x1011, 16, {0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
-{ 0x1021, 11, {0x83, 0x2d, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
-{ 0x102c, 4, {0xad, 0x07, 0xac, 0x06} },
-{ 0x1030, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
-{ 0x1040, 16, {0x4a, 0x70, 0x03, 0x02, 0x11, 0x74, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x11, 0x46, 0x90} },
-{ 0x1050, 16, {0x10, 0x56, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x11, 0x24, 0x02, 0x10, 0xdc, 0x02, 0x10, 0xc5, 0x02} },
-{ 0x1060, 16, {0x10, 0xab, 0x02, 0x10, 0x9a, 0x02, 0x10, 0x85, 0x02, 0x10, 0x6b, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1070, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
-{ 0x1080, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
-{ 0x1090, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x11, 0x46, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x10a0, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x11, 0x46, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10b0, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
-{ 0x10c0, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10d0, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
-{ 0x10e0, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
-{ 0x10f0, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1100, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x1110, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
-{ 0x1120, 16, {0x9f, 0x8e, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
-{ 0x1130, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
-{ 0x1140, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} },
-{ 0x1150, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
-{ 0x1160, 16, {0x10, 0x32, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x10, 0x32, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
-{ 0x1170, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
-{ 0x1176, 1, {0x22} },
-{ 0x1177, 2, {0xae, 0x07} },
-{ 0x1179, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
-{ 0x1189, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
-{ 0x1199, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
-{ 0x11a9, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
-{ 0x11b9, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
-{ 0x11c7, 1, {0x22} },
-{ 0x11c8, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x7f, 0x05} },
-{ 0x11d8, 13, {0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x22} },
-{ 0x11e5, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
-{ 0x11f5, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x0b8d, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
+{ 0x0b9d, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
+{ 0x0bad, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
+{ 0x0bb4, 1, {0x22} },
+{ 0x0bb5, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
+{ 0x0bc5, 1, {0x07} },
+{ 0x0bc6, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
+{ 0x0bd6, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
+{ 0x0be6, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
+{ 0x0bf6, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
+{ 0x0c06, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
+{ 0x0c13, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c22, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x2c, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} },
+{ 0x0c32, 16, {0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} },
+{ 0x0c42, 12, {0x0f, 0x4d, 0x12, 0x92, 0xfb, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} },
+{ 0x0c4e, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
+{ 0x0c5e, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c66, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0c76, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c81, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
+{ 0x0c91, 16, {0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
+{ 0x0ca1, 9, {0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0caa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
+{ 0x0cba, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cc0, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0cd0, 11, {0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cdb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0ceb, 16, {0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x30, 0xe0, 0x13, 0xe5, 0x3c, 0x30, 0xe0, 0x07, 0x90, 0x20} },
+{ 0x0cfb, 16, {0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d0b, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d17, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d27, 16, {0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x30, 0xe1, 0x13, 0xe5, 0x3c, 0x30, 0xe1, 0x07, 0x90, 0x20} },
+{ 0x0d37, 16, {0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d47, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d53, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d63, 16, {0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x30, 0xe2, 0x13, 0xe5, 0x3c, 0x30, 0xe2, 0x07, 0x90, 0x20} },
+{ 0x0d73, 16, {0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d83, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d8f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d9f, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0x30, 0xe3, 0x07, 0x90, 0x20} },
+{ 0x0daf, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0dbf, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0dcb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ddb, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0deb, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
+{ 0x0dfb, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e0b, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e1b, 4, {0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e1f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e2f, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e3f, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
+{ 0x0e4f, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e5f, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e6f, 4, {0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e73, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e83, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e93, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
+{ 0x0ea3, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0eb3, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0ec3, 4, {0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0ec7, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ed7, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0ee7, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
+{ 0x0ef7, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0f07, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0f17, 4, {0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f1b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
+{ 0x0f2b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f31, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
+{ 0x0f41, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f4d, 16, {0x90, 0x01, 0x20, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
+{ 0x0f5d, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
+{ 0x0f6d, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0f7d, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
+{ 0x0f8d, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0} },
+{ 0x0f9d, 16, {0x16, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0xb7, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
+{ 0x0fad, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0fbd, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
+{ 0x0fcd, 16, {0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
+{ 0x0fdd, 16, {0xf5, 0x31, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x0fed, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x0ffd, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x08, 0x90, 0x01, 0x1e} },
+{ 0x100d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3b, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x101d, 16, {0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x102d, 16, {0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x37} },
+{ 0x103d, 16, {0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x33, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
+{ 0x104d, 16, {0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x105d, 16, {0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4c, 0x60, 0x5e} },
+{ 0x106d, 4, {0xe4, 0x90, 0x01, 0x1e} },
+{ 0x1071, 16, {0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
+{ 0x1081, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4c, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
+{ 0x1091, 16, {0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
+{ 0x10a1, 16, {0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
+{ 0x10b1, 16, {0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
+{ 0x10c1, 11, {0x83, 0x7e, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
+{ 0x10cc, 4, {0x8e, 0x57, 0x8f, 0x58} },
+{ 0x10d0, 16, {0x75, 0x59, 0x03, 0xe5, 0x58, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe} },
+{ 0x10e0, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x11, 0xda, 0xe5, 0x59, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
+{ 0x10f0, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x11, 0x7e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
+{ 0x1100, 16, {0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
+{ 0x1110, 16, {0x80, 0x6c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
+{ 0x1120, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x59, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} },
+{ 0x1130, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1140, 16, {0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5} },
+{ 0x1150, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x58, 0x24} },
+{ 0x1160, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa0, 0x85, 0x85} },
+{ 0x1170, 16, {0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x85, 0x90, 0x7f} },
+{ 0x1180, 16, {0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
+{ 0x1190, 16, {0x22, 0xe5, 0x5a, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
+{ 0x11a0, 16, {0xe5, 0x59, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x11b0, 16, {0x80, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
+{ 0x11c0, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
+{ 0x11d0, 12, {0x59, 0x03, 0x02, 0x10, 0xd3, 0x15, 0x59, 0x02, 0x10, 0xd3, 0x7f, 0x08} },
+{ 0x11dc, 1, {0x22} },
+{ 0x11dd, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
+{ 0x11ed, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
{ 0x1200, 16, {0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} },
{ 0x1210, 16, {0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} },
{ 0x1220, 16, {0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} },
@@ -339,14 +336,14 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x1362, 16, {0x75, 0x28, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x29, 0x70, 0x03, 0x75, 0x29, 0x14, 0x02, 0x16, 0x9e} },
{ 0x1372, 16, {0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} },
{ 0x1382, 16, {0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} },
-{ 0x1392, 16, {0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x36, 0x02, 0x13, 0x43} },
+{ 0x1392, 16, {0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13, 0x43} },
{ 0x13a2, 16, {0x43, 0x82, 0x04, 0xe0, 0x43, 0x2c, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} },
-{ 0x13b2, 16, {0xe0, 0x42, 0x32, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
-{ 0x13c2, 16, {0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
+{ 0x13b2, 16, {0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
+{ 0x13c2, 16, {0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
{ 0x13d2, 16, {0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} },
{ 0x13e2, 16, {0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} },
{ 0x13f2, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} },
-{ 0x1402, 16, {0xe5, 0xe5, 0x3c, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1402, 16, {0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
{ 0x1412, 16, {0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} },
{ 0x1422, 16, {0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} },
{ 0x1432, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} },
@@ -364,14 +361,14 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x14f2, 16, {0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} },
{ 0x1502, 16, {0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} },
{ 0x1512, 16, {0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} },
-{ 0x1522, 16, {0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13} },
+{ 0x1522, 16, {0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x38, 0x02, 0x13} },
{ 0x1532, 16, {0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} },
-{ 0x1542, 16, {0x05, 0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
-{ 0x1552, 16, {0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
+{ 0x1542, 16, {0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
+{ 0x1552, 16, {0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
{ 0x1562, 16, {0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} },
{ 0x1572, 16, {0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} },
{ 0x1582, 16, {0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} },
-{ 0x1592, 16, {0x7f, 0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1592, 16, {0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
{ 0x15a2, 16, {0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
{ 0x15b2, 16, {0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} },
{ 0x15c2, 16, {0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} },
@@ -390,13 +387,13 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x1690, 16, {0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} },
{ 0x16a0, 16, {0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} },
{ 0x16b0, 16, {0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} },
-{ 0x16c0, 16, {0x38, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
-{ 0x16d0, 16, {0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
-{ 0x16e0, 16, {0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
+{ 0x16c0, 16, {0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
+{ 0x16d0, 16, {0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
+{ 0x16e0, 16, {0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
{ 0x16f0, 16, {0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} },
{ 0x1700, 16, {0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
{ 0x1710, 16, {0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} },
-{ 0x1720, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1720, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
{ 0x1730, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} },
{ 0x1740, 16, {0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} },
{ 0x1750, 16, {0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} },
@@ -415,13 +412,13 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x1820, 16, {0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} },
{ 0x1830, 16, {0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} },
{ 0x1840, 16, {0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} },
-{ 0x1850, 16, {0xf5, 0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
-{ 0x1860, 16, {0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
-{ 0x1870, 16, {0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
+{ 0x1850, 16, {0xf5, 0x3a, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
+{ 0x1860, 16, {0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
+{ 0x1870, 16, {0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
{ 0x1880, 16, {0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} },
{ 0x1890, 16, {0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} },
{ 0x18a0, 16, {0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} },
-{ 0x18b0, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
+{ 0x18b0, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
{ 0x18c0, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} },
{ 0x18d0, 16, {0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} },
{ 0x18e0, 16, {0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} },
@@ -439,63 +436,61 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x19a0, 16, {0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} },
{ 0x19b0, 16, {0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} },
{ 0x19c0, 1, {0x32} },
-{ 0x19c1, 4, {0x8e, 0x54, 0x8f, 0x55} },
-{ 0x19c5, 16, {0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} },
-{ 0x19d5, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x1a, 0xcf, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
-{ 0x19e5, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x1a, 0x73, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
-{ 0x19f5, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
-{ 0x1a05, 16, {0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
-{ 0x1a15, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x1a25, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1a35, 16, {0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5} },
-{ 0x1a45, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} },
-{ 0x1a55, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9f, 0x8e, 0x85} },
-{ 0x1a65, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0x8e, 0x90, 0x7f} },
-{ 0x1a75, 16, {0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
-{ 0x1a85, 16, {0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
-{ 0x1a95, 16, {0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1aa5, 16, {0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
-{ 0x1ab5, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
-{ 0x1ac5, 12, {0x56, 0x03, 0x02, 0x19, 0xc8, 0x15, 0x56, 0x02, 0x19, 0xc8, 0x7f, 0x08} },
-{ 0x1ad1, 1, {0x22} },
-{ 0x1ad2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
-{ 0x1ae2, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1af1, 4, {0x8e, 0x54, 0x8f, 0x55} },
-{ 0x1af5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x1b05, 16, {0xe5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
-{ 0x1b15, 16, {0x54, 0x03, 0x70, 0x24, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
-{ 0x1b25, 16, {0x56, 0x7d, 0x02, 0x12, 0x83, 0x2d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
-{ 0x1b35, 10, {0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x83, 0x2d, 0x7f, 0x00} },
-{ 0x1b3f, 1, {0x22} },
-{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0xfd, 0x8b, 0x4d, 0x75} },
-{ 0x8010, 16, {0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} },
-{ 0x8020, 16, {0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
+{ 0x19c1, 4, {0xad, 0x07, 0xac, 0x06} },
+{ 0x19c5, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
+{ 0x19d5, 16, {0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} },
+{ 0x19e5, 16, {0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} },
+{ 0x19f5, 16, {0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a05, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
+{ 0x1a15, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
+{ 0x1a25, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x1a35, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a45, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
+{ 0x1a55, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a65, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x57, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
+{ 0x1a75, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
+{ 0x1a85, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1a95, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x1aa5, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
+{ 0x1ab5, 16, {0xa0, 0x85, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
+{ 0x1ac5, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
+{ 0x1ad5, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30} },
+{ 0x1ae5, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
+{ 0x1af5, 16, {0x19, 0xc7, 0xe5, 0x57, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
+{ 0x1b05, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
+{ 0x1b0b, 1, {0x22} },
+{ 0x1b0c, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x02} },
+{ 0x1b1c, 16, {0x7d, 0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x03, 0x7d, 0xff} },
+{ 0x1b2c, 4, {0x12, 0x82, 0xa8, 0x22} },
+{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0xfd, 0x8b, 0x4e, 0x75} },
+{ 0x8010, 16, {0x4f, 0x12, 0x75, 0x50, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4c} },
+{ 0x8020, 16, {0xf5, 0x4d, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
{ 0x8030, 16, {0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} },
{ 0x8040, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} },
-{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} },
-{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
-{ 0x8070, 16, {0x12, 0x9f, 0x61, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61} },
+{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4e, 0xaa, 0x4f, 0xa9, 0x50} },
+{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
+{ 0x8070, 16, {0x12, 0xa0, 0x58, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58} },
{ 0x8080, 16, {0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} },
-{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} },
+{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4d, 0xae, 0x4c, 0x78, 0x02, 0xce} },
{ 0x80a0, 16, {0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
{ 0x80b0, 16, {0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} },
{ 0x80c0, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} },
-{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} },
+{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4d, 0xae, 0x4c, 0x78} },
{ 0x80e0, 16, {0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} },
{ 0x80f0, 16, {0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} },
{ 0x8100, 16, {0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} },
-{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0x25} },
-{ 0x8120, 16, {0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9f, 0x61, 0xfe, 0xe4} },
-{ 0x8130, 16, {0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x81, 0xb8, 0xab, 0x4d, 0xaa, 0x4e} },
-{ 0x8140, 16, {0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9f, 0x61, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
-{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
+{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0x25} },
+{ 0x8120, 16, {0x4d, 0xf5, 0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x90, 0x00, 0x05, 0x12, 0xa0, 0x58, 0xfe, 0xe4} },
+{ 0x8130, 16, {0x25, 0x4d, 0xf5, 0x4d, 0xee, 0x35, 0x4c, 0xf5, 0x4c, 0x02, 0x81, 0xb8, 0xab, 0x4e, 0xaa, 0x4f} },
+{ 0x8140, 16, {0xa9, 0x50, 0x90, 0x00, 0x03, 0x12, 0xa0, 0x58, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
+{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
{ 0x8160, 16, {0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} },
{ 0x8170, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} },
{ 0x8180, 16, {0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} },
{ 0x8190, 16, {0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} },
{ 0x81a0, 16, {0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} },
-{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} },
-{ 0x81c0, 16, {0x4e, 0xf5, 0x4e, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
+{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x50, 0xf5, 0x50, 0xe4, 0x35} },
+{ 0x81c0, 16, {0x4f, 0xf5, 0x4f, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
{ 0x81d0, 8, {0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} },
{ 0x81d8, 1, {0x22} },
{ 0x81d9, 2, {0xac, 0x07} },
@@ -513,549 +508,569 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = {
{ 0x828b, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
{ 0x829b, 12, {0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} },
{ 0x82a7, 1, {0x22} },
-{ 0x82a8, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
-{ 0x82b8, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} },
-{ 0x82c8, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x82d8, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
-{ 0x82e8, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
-{ 0x82f8, 16, {0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x8308, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
-{ 0x8318, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
-{ 0x8328, 4, {0x83, 0xa3, 0xe9, 0xf0} },
-{ 0x832c, 1, {0x22} },
-{ 0x832d, 4, {0x8f, 0x5e, 0x8d, 0x5f} },
-{ 0x8331, 16, {0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
-{ 0x8341, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x8351, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x50} },
-{ 0x8361, 16, {0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
-{ 0x8371, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
-{ 0x8381, 16, {0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} },
-{ 0x8391, 16, {0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} },
-{ 0x83a1, 16, {0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x83b1, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x83b6, 1, {0x22} },
-{ 0x83b7, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x83c7, 16, {0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x83d7, 16, {0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
-{ 0x83e7, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x83f7, 16, {0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6, 0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x8407, 16, {0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d} },
-{ 0x8417, 16, {0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0} },
-{ 0x8427, 16, {0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83} },
-{ 0x8437, 16, {0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54} },
-{ 0x8447, 16, {0x7d, 0x06, 0x12, 0x83, 0x2d, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x8457, 16, {0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
-{ 0x8467, 16, {0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef} },
-{ 0x8477, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01} },
-{ 0x8487, 13, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7f, 0x00} },
-{ 0x8494, 1, {0x22} },
-{ 0x8495, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x84a5, 16, {0xaf, 0x54, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
-{ 0x84b5, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x84c5, 16, {0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
-{ 0x84d5, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0xe5} },
-{ 0x84e5, 16, {0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57} },
-{ 0x84f5, 16, {0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x8505, 16, {0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
-{ 0x8515, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
-{ 0x8525, 9, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
-{ 0x852e, 1, {0x22} },
-{ 0x852f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
-{ 0x853f, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x854f, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
-{ 0x855f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
-{ 0x856f, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
-{ 0x857f, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
-{ 0x858f, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
-{ 0x859f, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x85af, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
-{ 0x85bf, 3, {0x83, 0xf0, 0x22} },
-{ 0x85c2, 4, {0xad, 0x07, 0xac, 0x06} },
-{ 0x85c6, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
-{ 0x85d6, 16, {0x22, 0x8c, 0x54, 0x8d, 0x55, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x85e6, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
-{ 0x85f6, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5, 0x55, 0xaa, 0x54, 0x70, 0x02} },
-{ 0x8606, 16, {0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8616, 1, {0x22} },
-{ 0x8617, 4, {0x8e, 0x54, 0x8f, 0x55} },
-{ 0x861b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x862b, 16, {0xe5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x863b, 16, {0x5c, 0x8f, 0x5d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x864b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa0} },
-{ 0x865b, 16, {0xc0, 0x40, 0x10, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x00} },
-{ 0x866b, 16, {0x08, 0x80, 0x2e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x867b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa0} },
-{ 0x868b, 16, {0xc0, 0x50, 0x0e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x07, 0x08} },
-{ 0x869b, 16, {0x00, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
-{ 0x86ab, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59} },
-{ 0x86bb, 16, {0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0} },
-{ 0x86cb, 16, {0x2e, 0xaf, 0x03, 0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a} },
-{ 0x86db, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56} },
-{ 0x86eb, 16, {0xe5, 0x5a, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58} },
-{ 0x86fb, 16, {0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85} },
-{ 0x870b, 16, {0x5c, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
-{ 0x871b, 16, {0x80, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad} },
-{ 0x872b, 16, {0x57, 0xac, 0x56, 0x78, 0x08, 0x12, 0xa0, 0xd1, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef} },
-{ 0x873b, 16, {0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
-{ 0x874b, 16, {0x5a, 0xe5, 0x55, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
-{ 0x875b, 16, {0x05, 0x43, 0x5a, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x11, 0xef} },
-{ 0x876b, 16, {0xb4, 0x74, 0x05, 0x43, 0x5a, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x877b, 16, {0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
-{ 0x878b, 16, {0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x879b, 16, {0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
-{ 0x87ab, 16, {0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5b, 0x74, 0x01} },
-{ 0x87bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d, 0x24, 0x04, 0xf5} },
-{ 0x87cb, 16, {0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a, 0x80, 0x10, 0xaf} },
-{ 0x87db, 16, {0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3b, 0x85} },
-{ 0x87eb, 16, {0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x87fb, 16, {0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x880b, 16, {0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83} },
-{ 0x881b, 16, {0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
-{ 0x882b, 16, {0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09} },
-{ 0x883b, 16, {0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
-{ 0x884b, 16, {0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} },
-{ 0x885b, 16, {0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x886b, 16, {0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x887b, 16, {0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0x75, 0x5a, 0x08, 0xe5, 0x55} },
-{ 0x888b, 16, {0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5a, 0x10, 0xe5} },
-{ 0x889b, 16, {0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5a, 0xf0} },
-{ 0x88ab, 16, {0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
-{ 0x88bb, 16, {0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x55, 0x24, 0x06, 0xf5} },
-{ 0x88cb, 16, {0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
-{ 0x88db, 16, {0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
-{ 0x88eb, 16, {0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0} },
-{ 0x88fb, 16, {0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
-{ 0x890b, 16, {0x70, 0x14, 0x43, 0x5a, 0x18, 0x80, 0x12, 0x43, 0x5a, 0x08, 0x80, 0x0d, 0x43, 0x5a, 0x38, 0x80} },
-{ 0x891b, 16, {0x08, 0x43, 0x5a, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} },
-{ 0x892b, 16, {0xa3, 0xa3, 0xe5, 0x5a, 0xf0, 0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0xaa, 0x54, 0xa9, 0x55} },
-{ 0x893b, 16, {0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
-{ 0x894b, 15, {0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f, 0x1f, 0x7f, 0x00} },
-{ 0x895a, 1, {0x22} },
-{ 0x895b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x896b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
-{ 0x897b, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
-{ 0x898b, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
-{ 0x899b, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x89ab, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
-{ 0x89bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54, 0x7f, 0x02, 0x12, 0x81, 0xd9} },
-{ 0x89cb, 16, {0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f, 0x90, 0x01, 0x32, 0xf0, 0x7e} },
-{ 0x89db, 10, {0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x89e5, 1, {0x22} },
-{ 0x89e6, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x89f6, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
-{ 0x8a06, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x8a16, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8e} },
-{ 0x8a26, 3, {0xb4, 0x7f, 0x00} },
-{ 0x8a29, 1, {0x22} },
-{ 0x8a2a, 4, {0xad, 0x07, 0xac, 0x06} },
-{ 0x8a2e, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a3e, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a4e, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8a5e, 16, {0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8a6e, 4, {0xfd, 0xf0, 0x7f, 0x00} },
-{ 0x8a72, 1, {0x22} },
-{ 0x8a73, 4, {0xad, 0x07, 0xac, 0x06} },
-{ 0x8a77, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a87, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a97, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8aa7, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8ab7, 4, {0xfe, 0xf0, 0x7f, 0x00} },
-{ 0x8abb, 1, {0x22} },
-{ 0x8abc, 4, {0xad, 0x07, 0xac, 0x06} },
-{ 0x8ac0, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8ad0, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8ae0, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
-{ 0x8af0, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
-{ 0x8b00, 1, {0x22} },
-{ 0x8b01, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
-{ 0x8b11, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00} },
-{ 0x8b21, 1, {0x22} },
-{ 0x8b22, 4, {0x8e, 0x54, 0x8f, 0x55} },
-{ 0x8b26, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x59, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x56, 0xc3} },
-{ 0x8b36, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
-{ 0x8b46, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x57, 0x7e, 0x75, 0x58} },
-{ 0x8b56, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x57, 0x7e, 0x75, 0x58, 0x00, 0x80, 0x16, 0x7e} },
-{ 0x8b66, 16, {0x7d, 0x7f, 0x80, 0x75, 0x57, 0x7d, 0x75, 0x58, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
-{ 0x8b76, 16, {0x57, 0x7d, 0x75, 0x58, 0x00, 0xe5, 0x59, 0x70, 0x1b, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0x74} },
-{ 0x8b86, 16, {0xff, 0xf0, 0xe5, 0x56, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
-{ 0x8b96, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x55, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x59, 0x60} },
-{ 0x8ba6, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
-{ 0x8bb6, 16, {0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
-{ 0x8bc6, 16, {0x15, 0x59, 0x80, 0xd9, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x56, 0x25} },
-{ 0x8bd6, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
-{ 0x8be4, 1, {0x22} },
-{ 0x8be5, 16, {0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
-{ 0x8bf5, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x8c05, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8c15, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0xc6} },
-{ 0x8c25, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0x12, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} },
-{ 0x8c35, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} },
-{ 0x8c45, 16, {0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} },
-{ 0x8c55, 16, {0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8d, 0x15, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x8c65, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
-{ 0x8c75, 16, {0x56, 0xf5, 0x57, 0x02, 0x8d, 0x15, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
-{ 0x8c85, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} },
-{ 0x8c95, 16, {0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} },
-{ 0x8ca5, 16, {0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} },
-{ 0x8cb5, 16, {0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} },
-{ 0x8cc5, 16, {0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
-{ 0x8cd5, 16, {0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} },
-{ 0x8ce5, 16, {0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} },
-{ 0x8cf5, 16, {0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d05, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} },
-{ 0x8d15, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0xd5, 0x24, 0xf9} },
-{ 0x8d25, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0x25, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8e, 0x69} },
-{ 0x8d35, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
-{ 0x8d45, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} },
-{ 0x8d55, 16, {0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xe0} },
-{ 0x8d65, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f} },
-{ 0x8d75, 16, {0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d85, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8e} },
-{ 0x8d95, 16, {0x69, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x76} },
-{ 0x8da5, 16, {0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} },
-{ 0x8db5, 16, {0x8e, 0x69, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8dc5, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
-{ 0x8dd5, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
-{ 0x8de5, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8e, 0x69, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
-{ 0x8df5, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} },
-{ 0x8e05, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8e15, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
-{ 0x8e25, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
-{ 0x8e35, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} },
-{ 0x8e45, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
-{ 0x8e55, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x8e65, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} },
-{ 0x8e75, 11, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x8e80, 1, {0x22} },
-{ 0x8e81, 16, {0x8e, 0x5f, 0x8f, 0x60, 0x8c, 0x61, 0x8d, 0x62, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x60} },
-{ 0x8e91, 16, {0xe5, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x05, 0x5f, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
-{ 0x8ea1, 16, {0x62, 0xe5, 0x62, 0xac, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x8eb1, 3, {0x80, 0xd6, 0x22} },
-{ 0x8eb4, 6, {0x8d, 0x5a, 0xab, 0x07, 0xaa, 0x06} },
-{ 0x8eba, 16, {0x75, 0x5e, 0x40, 0x75, 0x5d, 0x0d, 0x75, 0x5c, 0x03, 0x75, 0x5b, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
-{ 0x8eca, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x5e, 0xae, 0x5d, 0xad, 0x5c, 0xac, 0x5b, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
-{ 0x8eda, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
-{ 0x8eea, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5a, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xc3} },
-{ 0x8efa, 8, {0xe5, 0x5a, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8f02, 1, {0x22} },
-{ 0x8f03, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} },
-{ 0x8f13, 16, {0x90, 0x01, 0x85, 0xf0, 0x90, 0x95, 0xbf, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x95, 0xc0} },
-{ 0x8f23, 16, {0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
-{ 0x8f33, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} },
-{ 0x8f43, 16, {0x01, 0x7f, 0x7c, 0x12, 0x10, 0x2c, 0x7e, 0x01, 0x7f, 0x84, 0x7d, 0x14, 0x12, 0x8e, 0xb4, 0x7f} },
-{ 0x8f53, 1, {0x00} },
-{ 0x8f54, 1, {0x22} },
-{ 0x8f55, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4b, 0x7b, 0x75, 0x4c, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
-{ 0x8f65, 16, {0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5, 0x52} },
-{ 0x8f75, 16, {0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
-{ 0x8f85, 16, {0x5b, 0x90, 0x8f, 0x8d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xb1, 0x02, 0x8f} },
-{ 0x8f95, 16, {0xbb, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xd9, 0x02, 0x8f, 0xb1} },
-{ 0x8fa5, 16, {0x02, 0x8f, 0xcf, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xe1, 0x02, 0x8f, 0xb1, 0xef, 0x64, 0x02, 0x60} },
-{ 0x8fb5, 16, {0x2b, 0x75, 0x4d, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4d, 0xff, 0x80, 0x1c} },
-{ 0x8fc5, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4d, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
-{ 0x8fd5, 16, {0x4d, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x60, 0x15} },
-{ 0x8fe5, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
-{ 0x8ff5, 16, {0x8e, 0xb4, 0xaf, 0x4d, 0x22, 0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14} },
-{ 0x9005, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0x23, 0x90, 0x90, 0x14, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9015, 16, {0x90, 0x41, 0x02, 0x90, 0x4d, 0x02, 0x90, 0x59, 0x02, 0x90, 0xa7, 0x02, 0x90, 0xb2, 0x02, 0x90} },
-{ 0x9025, 16, {0xbd, 0x02, 0x90, 0xc8, 0x02, 0x90, 0xd3, 0x02, 0x90, 0xde, 0x02, 0x90, 0xe9, 0x02, 0x90, 0xf4} },
-{ 0x9035, 16, {0x02, 0x90, 0xfb, 0x02, 0x91, 0x23, 0x02, 0x91, 0x06, 0x02, 0x91, 0x11, 0xaf, 0x53, 0xae, 0x52} },
-{ 0x9045, 16, {0x12, 0x83, 0xb7, 0x8f, 0x4d, 0x02, 0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x95, 0x8f} },
-{ 0x9055, 16, {0x4d, 0x02, 0x91, 0x26, 0x85, 0x52, 0x50, 0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4} },
-{ 0x9065, 16, {0x35, 0x50, 0xfe, 0x12, 0x85, 0x2f, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x85, 0xc2, 0x8f, 0x4d, 0xef} },
-{ 0x9075, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0x26, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x86, 0x17, 0x8f, 0x4d} },
-{ 0x9085, 16, {0xe5, 0x4d, 0x70, 0x03, 0x02, 0x91, 0x26, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0x75, 0xf0} },
-{ 0x9095, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0x17, 0x02} },
-{ 0x90a5, 16, {0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x2a, 0x8f, 0x4d, 0x80, 0x74, 0xaf, 0x53, 0xae} },
-{ 0x90b5, 16, {0x52, 0x12, 0x8a, 0x73, 0x8f, 0x4d, 0x80, 0x69, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0xbc, 0x8f} },
-{ 0x90c5, 16, {0x4d, 0x80, 0x5e, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0xe5, 0x8f, 0x4d, 0x80, 0x53, 0xaf, 0x53} },
-{ 0x90d5, 16, {0xae, 0x52, 0x12, 0x89, 0x5b, 0x8f, 0x4d, 0x80, 0x48, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x1a, 0xf1} },
-{ 0x90e5, 16, {0x8f, 0x4d, 0x80, 0x3d, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xe6, 0x8f, 0x4d, 0x80, 0x32, 0x12} },
-{ 0x90f5, 16, {0x8f, 0x03, 0x8f, 0x4d, 0x80, 0x2b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x01, 0x8f, 0x4d, 0x80} },
-{ 0x9105, 16, {0x20, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x22, 0x8f, 0x4d, 0x80, 0x15, 0xaf, 0x4c, 0xae, 0x4b} },
-{ 0x9115, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8e, 0x81, 0xe4, 0xf5, 0x4d, 0x80, 0x03, 0x75, 0x4d} },
-{ 0x9125, 16, {0xff, 0xe5, 0x4d, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e} },
-{ 0x9135, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8e, 0xb4, 0xaf} },
-{ 0x9145, 16, {0x4d, 0x22, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
-{ 0x9155, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85} },
-{ 0x9165, 16, {0x52, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8e, 0xb4} },
-{ 0x9175, 4, {0x8f, 0x4d, 0xaf, 0x4d} },
-{ 0x9179, 1, {0x22} },
-{ 0x917a, 8, {0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} },
-{ 0x9182, 16, {0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} },
-{ 0x9192, 16, {0x02, 0x92, 0x18, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} },
-{ 0x91a2, 16, {0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0xa0, 0x2e, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} },
-{ 0x91b2, 16, {0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} },
-{ 0x91c2, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
-{ 0x91d2, 16, {0x12, 0xa0, 0x2e, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} },
-{ 0x91e2, 16, {0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} },
-{ 0x91f2, 16, {0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} },
-{ 0x9202, 16, {0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} },
-{ 0x9212, 16, {0x54, 0x05, 0x54, 0x02, 0x91, 0x8b, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} },
-{ 0x9222, 16, {0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} },
-{ 0x9232, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} },
-{ 0x9242, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
-{ 0x924a, 1, {0x22} },
-{ 0x924b, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
-{ 0x925b, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
-{ 0x926b, 16, {0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x927b, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x928b, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x929b, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x92ab, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x92bb, 1, {0x22} },
-{ 0x92bc, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x92cc, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
-{ 0x92dc, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
-{ 0x92ec, 16, {0x9f, 0x1f, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x92fc, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x930c, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x931c, 1, {0x22} },
-{ 0x931d, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} },
-{ 0x932d, 16, {0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} },
-{ 0x933d, 16, {0x53, 0x89, 0x54, 0xfe, 0x12, 0x92, 0xbc, 0xef, 0x60, 0x50, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} },
-{ 0x934d, 16, {0x12, 0x9f, 0x48, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
-{ 0x935d, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
-{ 0x936d, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
-{ 0x937d, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x30, 0x60, 0x0f, 0x85, 0x51, 0x82, 0x85, 0x50} },
-{ 0x938d, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
-{ 0x9397, 1, {0x22} },
-{ 0x9398, 16, {0x12, 0x93, 0x1d, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} },
-{ 0x93a8, 16, {0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} },
-{ 0x93b8, 16, {0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
-{ 0x93c8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x92, 0x4b} },
-{ 0x93d8, 16, {0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} },
-{ 0x93e8, 16, {0xb5, 0x12, 0x93, 0x1d, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x93f8, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} },
-{ 0x9408, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
-{ 0x9418, 16, {0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d} },
-{ 0x9428, 16, {0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
-{ 0x9438, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0x05, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} },
-{ 0x9448, 16, {0xd9, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} },
-{ 0x9458, 16, {0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} },
-{ 0x9468, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} },
-{ 0x9478, 16, {0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05} },
-{ 0x9488, 16, {0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} },
-{ 0x9498, 16, {0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} },
-{ 0x94a8, 16, {0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} },
-{ 0x94b8, 16, {0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0x2c, 0x25} },
-{ 0x94c8, 16, {0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x94d8, 16, {0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70} },
-{ 0x94e8, 16, {0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} },
-{ 0x94f8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x93, 0x1d} },
-{ 0x9508, 1, {0x22} },
-{ 0x9509, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x62, 0x02, 0x95, 0x50} },
-{ 0x9515, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x9525, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x9535, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x9545, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x95, 0x95, 0xe4, 0x7e} },
-{ 0x9555, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x9565, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x9575, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x9585, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x9595, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
-{ 0x95a5, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
-{ 0x95b5, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
-{ 0x95bd, 1, {0x00} },
-{ 0x95be, 3, {0x00, 0x03, 0x1d} },
-{ 0x95c1, 8, {0x8b, 0x54, 0x8a, 0x55, 0x89, 0x56, 0x8d, 0x57} },
-{ 0x95c9, 16, {0xe4, 0xf5, 0x58, 0xf5, 0x59, 0xaf, 0x57, 0x15, 0x57, 0xef, 0x60, 0x36, 0xab, 0x54, 0x05, 0x56} },
-{ 0x95d9, 16, {0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf9, 0x12, 0x9f, 0x48, 0xff, 0xe5, 0x58} },
-{ 0x95e9, 16, {0xe5, 0x59, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0xa2, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
-{ 0x95f9, 16, {0x9b, 0xf5, 0x83, 0xe5, 0x58, 0xff, 0xe4, 0x93, 0xf5, 0x58, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x59} },
-{ 0x9609, 6, {0x80, 0xc3, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x960f, 1, {0x22} },
-{ 0x9610, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
-{ 0x961b, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
-{ 0x962b, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
-{ 0x963b, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
-{ 0x964b, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
-{ 0x9655, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x965e, 2, {0xa9, 0x03} },
-{ 0x9660, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
-{ 0x9670, 16, {0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x9680, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
-{ 0x9690, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} },
-{ 0x96a0, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
-{ 0x96b0, 16, {0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
-{ 0x96c0, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
-{ 0x96d0, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} },
-{ 0x96e0, 1, {0x00} },
-{ 0x96e1, 1, {0x22} },
-{ 0x96e2, 16, {0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} },
-{ 0x96f2, 16, {0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} },
-{ 0x9702, 16, {0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} },
-{ 0x9712, 16, {0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9b, 0x6a, 0x90, 0x97, 0x21, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9722, 16, {0x97, 0x42, 0x02, 0x97, 0xe1, 0x02, 0x98, 0xe6, 0x02, 0x99, 0x06, 0x02, 0x99, 0x06, 0x02, 0x99} },
-{ 0x9732, 16, {0xa1, 0x02, 0x99, 0xdc, 0x02, 0x9a, 0x01, 0x02, 0x9a, 0xbf, 0x02, 0x9a, 0xef, 0x02, 0x9b, 0x1b} },
-{ 0x9742, 16, {0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} },
-{ 0x9752, 16, {0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} },
-{ 0x9762, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} },
-{ 0x9772, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} },
-{ 0x9782, 16, {0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} },
-{ 0x9792, 16, {0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} },
-{ 0x97a2, 16, {0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} },
-{ 0x97b2, 16, {0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x97c2, 16, {0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} },
-{ 0x97d2, 16, {0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x97, 0x45, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x97e2, 16, {0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} },
-{ 0x97f2, 16, {0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} },
-{ 0x9802, 16, {0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x9812, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} },
-{ 0x9822, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} },
-{ 0x9832, 16, {0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} },
-{ 0x9842, 16, {0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} },
-{ 0x9852, 16, {0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9862, 16, {0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} },
-{ 0x9872, 16, {0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} },
-{ 0x9882, 16, {0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} },
-{ 0x9892, 16, {0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} },
-{ 0x98a2, 16, {0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} },
-{ 0x98b2, 16, {0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} },
-{ 0x98c2, 16, {0x03, 0x02, 0x98, 0x0d, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x05, 0x4b} },
-{ 0x98d2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} },
-{ 0x98e2, 16, {0xf0, 0x02, 0x9b, 0x70, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} },
-{ 0x98f2, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} },
-{ 0x9902, 16, {0xf0, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} },
-{ 0x9912, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} },
-{ 0x9922, 16, {0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9932, 16, {0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0} },
-{ 0x9942, 16, {0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} },
-{ 0x9952, 16, {0x02, 0x12, 0x81, 0xd9, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} },
-{ 0x9962, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} },
-{ 0x9972, 16, {0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} },
-{ 0x9982, 16, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90} },
-{ 0x9992, 16, {0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x99a2, 16, {0xff, 0xfd, 0x12, 0x82, 0xa8, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} },
-{ 0x99b2, 16, {0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} },
-{ 0x99c2, 16, {0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} },
-{ 0x99d2, 16, {0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x9b, 0x70, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} },
-{ 0x99e2, 16, {0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} },
-{ 0x99f2, 16, {0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x9a02, 16, {0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0xe5, 0x4b, 0x75, 0xf0, 0x08} },
-{ 0x9a12, 16, {0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} },
-{ 0x9a22, 16, {0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} },
-{ 0x9a32, 16, {0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d} },
-{ 0x9a42, 16, {0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} },
-{ 0x9a52, 16, {0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} },
-{ 0x9a62, 16, {0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} },
-{ 0x9a72, 16, {0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} },
-{ 0x9a82, 16, {0x01, 0x12, 0x82, 0xa8, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} },
-{ 0x9a92, 16, {0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x9aa2, 16, {0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x05, 0x4b} },
-{ 0x9ab2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x9a, 0x06, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9ac2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} },
-{ 0x9ad2, 16, {0x9b, 0xf0, 0xa3, 0x74, 0x92, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08} },
-{ 0x9ae2, 16, {0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9af2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5} },
-{ 0x9b02, 16, {0x52, 0xf0, 0xa3, 0xe5, 0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0x2c, 0xef, 0x64, 0x08} },
-{ 0x9b12, 16, {0x60, 0x5c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x51, 0x24, 0x02, 0xff, 0xe4, 0x35} },
-{ 0x9b22, 16, {0x50, 0xfa, 0xa9, 0x07, 0x7b, 0x01, 0x7d, 0x10, 0x12, 0x95, 0xc1, 0xef, 0x4e, 0x70, 0x32, 0x90} },
-{ 0x9b32, 16, {0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5} },
-{ 0x9b42, 16, {0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35, 0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03} },
-{ 0x9b52, 16, {0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80} },
-{ 0x9b62, 16, {0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} },
-{ 0x9b72, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} },
-{ 0x9b82, 15, {0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x7d, 0x24, 0x12, 0x8e, 0xb4, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
-{ 0x9b91, 1, {0x22} },
-{ 0x9b92, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
-{ 0x9ba2, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
-{ 0x9bb2, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
-{ 0x9bc2, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
-{ 0x9bd2, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
-{ 0x9be2, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
-{ 0x9bf2, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
-{ 0x9c02, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
-{ 0x9c12, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
-{ 0x9c22, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
-{ 0x9c32, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
-{ 0x9c42, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
-{ 0x9c52, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
-{ 0x9c62, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
-{ 0x9c72, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
-{ 0x9c82, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
-{ 0x9c92, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
-{ 0x9ca2, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
-{ 0x9cb2, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
-{ 0x9cc2, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
-{ 0x9cd2, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
-{ 0x9ce2, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
-{ 0x9cf2, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
-{ 0x9d02, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
-{ 0x9d12, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
-{ 0x9d22, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
-{ 0x9d32, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
-{ 0x9d42, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
-{ 0x9d52, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
-{ 0x9d62, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
-{ 0x9d72, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
-{ 0x9d82, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
-{ 0x9d92, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
-{ 0x9da2, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
-{ 0x9db2, 16, {0x9e, 0x45, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9e, 0x45, 0xef, 0x75, 0xf0} },
-{ 0x9dc2, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
-{ 0x9dd2, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
-{ 0x9de2, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
-{ 0x9df2, 16, {0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
-{ 0x9e02, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
-{ 0x9e12, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
-{ 0x9e22, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
-{ 0x9e32, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
-{ 0x9e42, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9d, 0xa4} },
-{ 0x9e4e, 1, {0x22} },
-{ 0x9e4f, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
-{ 0x9e5f, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
-{ 0x9e6f, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
-{ 0x9e7f, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
-{ 0x9e8f, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
-{ 0x9e9f, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
-{ 0x9eaf, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
-{ 0x9ebf, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
-{ 0x9ecf, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
-{ 0x9edf, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
-{ 0x9eef, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
-{ 0x9eff, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
-{ 0x9f0f, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
-{ 0x9f1f, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
-{ 0x9f2f, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
-{ 0x9f3f, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9e, 0x9f, 0x73} },
-{ 0x9f48, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x9f58, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f61, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x9f71, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x9f81, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f8e, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
-{ 0x9f9e, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
-{ 0x9fa4, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
-{ 0x9fb4, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
-{ 0x9fba, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x9fca, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x9fda, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x9fea, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x9ff2, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
-{ 0xa002, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
-{ 0xa012, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
-{ 0xa022, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
-{ 0xa032, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
-{ 0xa042, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
-{ 0xa052, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
-{ 0xa062, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
-{ 0xa072, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
-{ 0xa082, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
-{ 0xa092, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
-{ 0xa0a2, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
-{ 0xa0b2, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
-{ 0xa0c0, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
-{ 0xa0d0, 1, {0x22} },
-{ 0xa0d1, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
-{ 0xa0e1, 3, {0xd8, 0xf1, 0x22} },
-{ 0xa0e4, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
-{ 0xa0f4, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
-{ 0xa0fb, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
-{ 0xa107, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0x12} },
-{ 0xa117, 16, {0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
-{ 0xa127, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
-{ 0xa137, 1, {0x22} },
+{ 0x82a8, 2, {0xae, 0x07} },
+{ 0x82aa, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
+{ 0x82ba, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
+{ 0x82ca, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
+{ 0x82da, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
+{ 0x82ea, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
+{ 0x82f8, 1, {0x22} },
+{ 0x82f9, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
+{ 0x8309, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5f, 0x74, 0xbf} },
+{ 0x8319, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8329, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
+{ 0x8339, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
+{ 0x8349, 16, {0xef, 0x55, 0x3c, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8359, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
+{ 0x8369, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5f, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
+{ 0x8379, 4, {0x83, 0xa3, 0xe9, 0xf0} },
+{ 0x837d, 1, {0x22} },
+{ 0x837e, 4, {0x8f, 0x5f, 0x8d, 0x60} },
+{ 0x8382, 16, {0xe4, 0xf5, 0x61, 0x74, 0x3d, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
+{ 0x8392, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x83a2, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x50} },
+{ 0x83b2, 16, {0x3c, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
+{ 0x83c2, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
+{ 0x83d2, 16, {0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x40, 0x0c, 0x75, 0x61, 0x40, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76} },
+{ 0x83e2, 16, {0x10, 0x80, 0x0a, 0x75, 0x61, 0x80, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76, 0x38, 0xe5, 0x61, 0x45} },
+{ 0x83f2, 16, {0x60, 0x44, 0x01, 0xff, 0xe5, 0x5f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8402, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x8407, 1, {0x22} },
+{ 0x8408, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8418, 16, {0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x8428, 16, {0x56, 0x8f, 0x57, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
+{ 0x8438, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
+{ 0x8448, 16, {0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x55, 0xf8, 0xe4, 0xf6, 0xe5, 0x57, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x8458, 16, {0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e} },
+{ 0x8468, 16, {0xaf, 0x55, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xa3, 0xa3, 0xe0} },
+{ 0x8478, 16, {0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83} },
+{ 0x8488, 16, {0xe0, 0xe5, 0x57, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x55} },
+{ 0x8498, 16, {0x7d, 0x06, 0x12, 0x83, 0x7e, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
+{ 0x84a8, 16, {0xe4, 0xf0, 0xe5, 0x55, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
+{ 0x84b8, 16, {0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xef} },
+{ 0x84c8, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x55, 0x74, 0x01} },
+{ 0x84d8, 13, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7f, 0x00} },
+{ 0x84e5, 1, {0x22} },
+{ 0x84e6, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x84f6, 16, {0xaf, 0x55, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
+{ 0x8506, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8516, 16, {0x20, 0xaf, 0x82, 0xf5, 0x57, 0x8f, 0x58, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
+{ 0x8526, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0xe5} },
+{ 0x8536, 16, {0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x58} },
+{ 0x8546, 16, {0x82, 0x85, 0x57, 0x83, 0xe0, 0xf5, 0x56, 0xaf, 0x55, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x8556, 16, {0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
+{ 0x8566, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
+{ 0x8576, 9, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
+{ 0x857f, 1, {0x22} },
+{ 0x8580, 4, {0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8584, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8594, 16, {0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
+{ 0x85a4, 16, {0x54, 0x03, 0x70, 0x24, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
+{ 0x85b4, 16, {0x57, 0x7d, 0x02, 0x12, 0x83, 0x7e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
+{ 0x85c4, 10, {0x07, 0xaf, 0x57, 0x7d, 0x04, 0x12, 0x83, 0x7e, 0x7f, 0x00} },
+{ 0x85ce, 1, {0x22} },
+{ 0x85cf, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
+{ 0x85df, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x85ef, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
+{ 0x85ff, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
+{ 0x860f, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
+{ 0x861f, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
+{ 0x862f, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
+{ 0x863f, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x864f, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
+{ 0x865f, 3, {0x83, 0xf0, 0x22} },
+{ 0x8662, 4, {0xad, 0x07, 0xac, 0x06} },
+{ 0x8666, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
+{ 0x8676, 16, {0x22, 0x8c, 0x55, 0x8d, 0x56, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8686, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
+{ 0x8696, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02} },
+{ 0x86a6, 16, {0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x86b6, 1, {0x22} },
+{ 0x86b7, 4, {0x8e, 0x55, 0x8f, 0x56} },
+{ 0x86bb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5c, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x86cb, 16, {0xe5, 0x5c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x86db, 16, {0x5d, 0x8f, 0x5e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x86eb, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa1} },
+{ 0x86fb, 16, {0xb7, 0x40, 0x10, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x00} },
+{ 0x870b, 16, {0x08, 0x80, 0x2e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x871b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa1} },
+{ 0x872b, 16, {0xb7, 0x50, 0x0e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x07, 0x08} },
+{ 0x873b, 16, {0x00, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
+{ 0x874b, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a} },
+{ 0x875b, 16, {0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1} },
+{ 0x876b, 16, {0x25, 0xaf, 0x03, 0x8f, 0x5b, 0xaf, 0x5a, 0xae, 0x59, 0xad, 0x58, 0xac, 0x57, 0x7b, 0x0a, 0x7a} },
+{ 0x877b, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a, 0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57} },
+{ 0x878b, 16, {0xe5, 0x5b, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5a, 0x24, 0x01, 0xf5, 0x5a, 0xe4, 0x35, 0x59} },
+{ 0x879b, 16, {0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0x85, 0x5e, 0x82, 0x85} },
+{ 0x87ab, 16, {0x5d, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
+{ 0x87bb, 16, {0x80, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xe5, 0x5a, 0xf0, 0xaf, 0x5a, 0xae, 0x59, 0xad} },
+{ 0x87cb, 16, {0x58, 0xac, 0x57, 0x78, 0x08, 0x12, 0xa1, 0xc8, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xef} },
+{ 0x87db, 16, {0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
+{ 0x87eb, 16, {0x5b, 0xe5, 0x56, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
+{ 0x87fb, 16, {0x05, 0x43, 0x5b, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5b, 0x08, 0x80, 0x11, 0xef} },
+{ 0x880b, 16, {0xb4, 0x74, 0x05, 0x43, 0x5b, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x881b, 16, {0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
+{ 0x882b, 16, {0x43, 0x5b, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5b, 0x40, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x883b, 16, {0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
+{ 0x884b, 16, {0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5c, 0x74, 0x01} },
+{ 0x885b, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3c, 0xe5, 0x5e, 0x24, 0x04, 0xf5} },
+{ 0x886b, 16, {0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5b, 0x80, 0x10, 0xaf} },
+{ 0x887b, 16, {0x5c, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3c, 0x85} },
+{ 0x888b, 16, {0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x889b, 16, {0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5b, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x88ab, 16, {0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83} },
+{ 0x88bb, 16, {0xef, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
+{ 0x88cb, 16, {0x5e, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09} },
+{ 0x88db, 16, {0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
+{ 0x88eb, 16, {0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5} },
+{ 0x88fb, 16, {0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x890b, 16, {0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x891b, 16, {0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5c, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0x75, 0x5b, 0x08, 0xe5, 0x56} },
+{ 0x892b, 16, {0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5b, 0x10, 0xe5} },
+{ 0x893b, 16, {0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5b, 0xf0} },
+{ 0x894b, 16, {0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
+{ 0x895b, 16, {0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0x06, 0xf5} },
+{ 0x896b, 16, {0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
+{ 0x897b, 16, {0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
+{ 0x898b, 16, {0xfb, 0x4f, 0xf5, 0x5b, 0xe5, 0x56, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0} },
+{ 0x899b, 16, {0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
+{ 0x89ab, 16, {0x70, 0x14, 0x43, 0x5b, 0x18, 0x80, 0x12, 0x43, 0x5b, 0x08, 0x80, 0x0d, 0x43, 0x5b, 0x38, 0x80} },
+{ 0x89bb, 16, {0x08, 0x43, 0x5b, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3} },
+{ 0x89cb, 16, {0xa3, 0xa3, 0xe5, 0x5b, 0xf0, 0xaf, 0x5c, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0xaa, 0x55, 0xa9, 0x56} },
+{ 0x89db, 16, {0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5c, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
+{ 0x89eb, 15, {0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0, 0x16, 0x7f, 0x00} },
+{ 0x89fa, 1, {0x22} },
+{ 0x89fb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8a0b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
+{ 0x8a1b, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
+{ 0x8a2b, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
+{ 0x8a3b, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8a4b, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
+{ 0x8a5b, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x55, 0xe5, 0x30, 0xc3, 0x94, 0x01} },
+{ 0x8a6b, 16, {0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x56, 0x00, 0xf5, 0x57, 0x80, 0x09, 0x7f} },
+{ 0x8a7b, 16, {0x02, 0x12, 0x81, 0xd9, 0x8e, 0x56, 0x8f, 0x57, 0xc3, 0xe5, 0x56, 0x64, 0x80, 0x94, 0x80, 0x40} },
+{ 0x8a8b, 16, {0xda, 0xe5, 0x55, 0x55, 0x57, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} },
+{ 0x8a9b, 4, {0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8a9f, 1, {0x22} },
+{ 0x8aa0, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8ab0, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
+{ 0x8ac0, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x8ad0, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8f} },
+{ 0x8ae0, 3, {0x6e, 0x7f, 0x00} },
+{ 0x8ae3, 1, {0x22} },
+{ 0x8ae4, 4, {0xad, 0x07, 0xac, 0x06} },
+{ 0x8ae8, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8af8, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b08, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b18, 16, {0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b28, 4, {0xfd, 0xf0, 0x7f, 0x00} },
+{ 0x8b2c, 1, {0x22} },
+{ 0x8b2d, 4, {0xad, 0x07, 0xac, 0x06} },
+{ 0x8b31, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b41, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b51, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b61, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b71, 4, {0xfe, 0xf0, 0x7f, 0x00} },
+{ 0x8b75, 1, {0x22} },
+{ 0x8b76, 4, {0xad, 0x07, 0xac, 0x06} },
+{ 0x8b7a, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b8a, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b9a, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
+{ 0x8baa, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
+{ 0x8bba, 1, {0x22} },
+{ 0x8bbb, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
+{ 0x8bcb, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0x7f, 0x00} },
+{ 0x8bdb, 1, {0x22} },
+{ 0x8bdc, 4, {0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8be0, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xd3} },
+{ 0x8bf0, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x57, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
+{ 0x8c00, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x58, 0x7e, 0x75, 0x59} },
+{ 0x8c10, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x00, 0x80, 0x16, 0x7e} },
+{ 0x8c20, 16, {0x7d, 0x7f, 0x80, 0x75, 0x58, 0x7d, 0x75, 0x59, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
+{ 0x8c30, 16, {0x58, 0x7d, 0x75, 0x59, 0x00, 0xe5, 0x5a, 0x70, 0x1b, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74} },
+{ 0x8c40, 16, {0xff, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
+{ 0x8c50, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfe, 0xe5, 0x5a, 0x60} },
+{ 0x8c60, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
+{ 0x8c70, 16, {0x59, 0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
+{ 0x8c80, 16, {0x15, 0x5a, 0x80, 0xd9, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x57, 0x25} },
+{ 0x8c90, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
+{ 0x8c9e, 1, {0x22} },
+{ 0x8c9f, 16, {0xef, 0x24, 0x05, 0xf5, 0x56, 0xe4, 0x3e, 0xf5, 0x55, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
+{ 0x8caf, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3} },
+{ 0x8cbf, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x57, 0xf5, 0x58, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8ccf, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x80} },
+{ 0x8cdf, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xcc, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe} },
+{ 0x8cef, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5a, 0x74, 0x01, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a} },
+{ 0x8cff, 16, {0x94, 0x40, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5} },
+{ 0x8d0f, 16, {0x58, 0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x50, 0x03, 0x02, 0x8d, 0xcf, 0xae, 0x59, 0xaf, 0x5a} },
+{ 0x8d1f, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
+{ 0x8d2f, 16, {0x57, 0xf5, 0x58, 0x02, 0x8d, 0xcf, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
+{ 0x8d3f, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a, 0x94} },
+{ 0x8d4f, 16, {0x10, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x10, 0xd3, 0xe5, 0x58} },
+{ 0x8d5f, 16, {0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x40, 0x68, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85} },
+{ 0x8d6f, 16, {0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x80} },
+{ 0x8d7f, 16, {0x4f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
+{ 0x8d8f, 16, {0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0x45, 0x5a, 0x60, 0x0b, 0xd3, 0xe5, 0x5a, 0x94, 0x40, 0xe5} },
+{ 0x8d9f, 16, {0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5, 0x58, 0x95, 0x5a} },
+{ 0x8daf, 16, {0xe5, 0x57, 0x95, 0x59, 0x40, 0x17, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8dbf, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x7f, 0x01, 0x22} },
+{ 0x8dcf, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8e, 0x8f, 0x24, 0xf9} },
+{ 0x8ddf, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0xdf, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x23} },
+{ 0x8def, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
+{ 0x8dff, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58} },
+{ 0x8e0f, 16, {0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xe0} },
+{ 0x8e1f, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0} },
+{ 0x8e2f, 16, {0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8e3f, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8f} },
+{ 0x8e4f, 16, {0x23, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x76} },
+{ 0x8e5f, 16, {0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02} },
+{ 0x8e6f, 16, {0x8f, 0x23, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8e7f, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
+{ 0x8e8f, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
+{ 0x8e9f, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8f, 0x23, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
+{ 0x8eaf, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e} },
+{ 0x8ebf, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8ecf, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
+{ 0x8edf, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
+{ 0x8eef, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x60, 0x24} },
+{ 0x8eff, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
+{ 0x8f0f, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x8f1f, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3} },
+{ 0x8f2f, 11, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8f3a, 1, {0x22} },
+{ 0x8f3b, 16, {0x8e, 0x60, 0x8f, 0x61, 0x8c, 0x62, 0x8d, 0x63, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x61} },
+{ 0x8f4b, 16, {0xe5, 0x61, 0xae, 0x60, 0x70, 0x02, 0x05, 0x60, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
+{ 0x8f5b, 16, {0x63, 0xe5, 0x63, 0xac, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x8f6b, 3, {0x80, 0xd6, 0x22} },
+{ 0x8f6e, 6, {0x8d, 0x5b, 0xab, 0x07, 0xaa, 0x06} },
+{ 0x8f74, 16, {0x75, 0x5f, 0x40, 0x75, 0x5e, 0x0d, 0x75, 0x5d, 0x03, 0x75, 0x5c, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
+{ 0x8f84, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x5f, 0xae, 0x5e, 0xad, 0x5d, 0xac, 0x5c, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
+{ 0x8f94, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
+{ 0x8fa4, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5b, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xc3} },
+{ 0x8fb4, 8, {0xe5, 0x5b, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x8fbc, 1, {0x22} },
+{ 0x8fbd, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0x90, 0x0a, 0xf1, 0xe4, 0x93, 0x90} },
+{ 0x8fcd, 16, {0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf2, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} },
+{ 0x8fdd, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} },
+{ 0x8fed, 16, {0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} },
+{ 0x8ffd, 7, {0x7d, 0x14, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x9004, 1, {0x22} },
+{ 0x9005, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4c, 0x7b, 0x75, 0x4d, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
+{ 0x9015, 16, {0x4c, 0x4f, 0x85, 0x4d, 0x50, 0xe5, 0x50, 0x24, 0x01, 0xf5, 0x54, 0xe4, 0x35, 0x4f, 0xf5, 0x53} },
+{ 0x9025, 16, {0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
+{ 0x9035, 16, {0x5b, 0x90, 0x90, 0x3d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x90, 0x61, 0x02, 0x90, 0x61, 0x02, 0x90} },
+{ 0x9045, 16, {0x6b, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x89, 0x02, 0x90, 0x61} },
+{ 0x9055, 16, {0x02, 0x90, 0x7f, 0x02, 0x90, 0x61, 0x02, 0x90, 0x91, 0x02, 0x90, 0x61, 0xef, 0x64, 0x02, 0x60} },
+{ 0x9065, 16, {0x2b, 0x75, 0x4e, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4e, 0xff, 0x80, 0x1c} },
+{ 0x9075, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4e, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
+{ 0x9085, 16, {0x4e, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x60, 0x15} },
+{ 0x9095, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
+{ 0x90a5, 16, {0x8f, 0x6e, 0xaf, 0x4e, 0x22, 0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0x14} },
+{ 0x90b5, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0xd3, 0x90, 0x90, 0xc4, 0xf8, 0x28, 0x28, 0x73, 0x02} },
+{ 0x90c5, 16, {0x90, 0xf1, 0x02, 0x90, 0xfd, 0x02, 0x91, 0x09, 0x02, 0x91, 0x57, 0x02, 0x91, 0x62, 0x02, 0x91} },
+{ 0x90d5, 16, {0x6d, 0x02, 0x91, 0x78, 0x02, 0x91, 0x83, 0x02, 0x91, 0x8e, 0x02, 0x91, 0x99, 0x02, 0x91, 0xa4} },
+{ 0x90e5, 16, {0x02, 0x91, 0xab, 0x02, 0x91, 0xd3, 0x02, 0x91, 0xb6, 0x02, 0x91, 0xc1, 0xaf, 0x54, 0xae, 0x53} },
+{ 0x90f5, 16, {0x12, 0x84, 0x08, 0x8f, 0x4e, 0x02, 0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x84, 0xe6, 0x8f} },
+{ 0x9105, 16, {0x4e, 0x02, 0x91, 0xd6, 0x85, 0x53, 0x51, 0x85, 0x54, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4} },
+{ 0x9115, 16, {0x35, 0x51, 0xfe, 0x12, 0x85, 0xcf, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0x62, 0x8f, 0x4e, 0xef} },
+{ 0x9125, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0xd6, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0xb7, 0x8f, 0x4e} },
+{ 0x9135, 16, {0xe5, 0x4e, 0x70, 0x03, 0x02, 0x91, 0xd6, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x75, 0xf0} },
+{ 0x9145, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0xb7, 0x02} },
+{ 0x9155, 16, {0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xe4, 0x8f, 0x4e, 0x80, 0x74, 0xaf, 0x54, 0xae} },
+{ 0x9165, 16, {0x53, 0x12, 0x8b, 0x2d, 0x8f, 0x4e, 0x80, 0x69, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0x76, 0x8f} },
+{ 0x9175, 16, {0x4e, 0x80, 0x5e, 0xaf, 0x4d, 0xae, 0x4c, 0x12, 0x8c, 0x9f, 0x8f, 0x4e, 0x80, 0x53, 0xaf, 0x54} },
+{ 0x9185, 16, {0xae, 0x53, 0x12, 0x89, 0xfb, 0x8f, 0x4e, 0x80, 0x48, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x85, 0x80} },
+{ 0x9195, 16, {0x8f, 0x4e, 0x80, 0x3d, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xa0, 0x8f, 0x4e, 0x80, 0x32, 0x12} },
+{ 0x91a5, 16, {0x8f, 0xbd, 0x8f, 0x4e, 0x80, 0x2b, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xbb, 0x8f, 0x4e, 0x80} },
+{ 0x91b5, 16, {0x20, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xdc, 0x8f, 0x4e, 0x80, 0x15, 0xaf, 0x4d, 0xae, 0x4c} },
+{ 0x91c5, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8f, 0x3b, 0xe4, 0xf5, 0x4e, 0x80, 0x03, 0x75, 0x4e} },
+{ 0x91d5, 16, {0xff, 0xe5, 0x4e, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x50, 0x82, 0x85, 0x4f} },
+{ 0x91e5, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8f, 0x6e, 0xaf} },
+{ 0x91f5, 16, {0x4e, 0x22, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
+{ 0x9205, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9215, 16, {0x53, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8f, 0x6e} },
+{ 0x9225, 4, {0x8f, 0x4e, 0xaf, 0x4e} },
+{ 0x9229, 1, {0x22} },
+{ 0x922a, 8, {0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c} },
+{ 0x9232, 16, {0x75, 0x56, 0x01, 0x75, 0x57, 0x9c, 0xe4, 0xf5, 0x55, 0xaf, 0x51, 0x15, 0x51, 0xef, 0x70, 0x03} },
+{ 0x9242, 16, {0x02, 0x92, 0xc8, 0xaf, 0x50, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4f} },
+{ 0x9252, 16, {0xae, 0x4e, 0xad, 0x4d, 0xac, 0x4c, 0x12, 0xa1, 0x25, 0xaf, 0x03, 0x8f, 0x54, 0xaf, 0x4f, 0xae} },
+{ 0x9262, 16, {0x4e, 0xad, 0x4d, 0xac, 0x4c, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x50, 0xe4} },
+{ 0x9272, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
+{ 0x9282, 16, {0x12, 0xa1, 0x25, 0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c, 0xe5, 0x54, 0x24, 0x30, 0xf5} },
+{ 0x9292, 16, {0x54, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x54, 0xf5, 0x54, 0x05, 0x57, 0xe5, 0x57} },
+{ 0x92a2, 16, {0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x57, 0xe5} },
+{ 0x92b2, 16, {0x57, 0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x54, 0xf0, 0x05} },
+{ 0x92c2, 16, {0x55, 0x05, 0x55, 0x02, 0x92, 0x3b, 0xe5, 0x57, 0x15, 0x57, 0x70, 0x02, 0x15, 0x56, 0xaf, 0x55} },
+{ 0x92d2, 16, {0x15, 0x55, 0xef, 0x60, 0x23, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0xf5} },
+{ 0x92e2, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14} },
+{ 0x92f2, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
+{ 0x92fa, 1, {0x22} },
+{ 0x92fb, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
+{ 0x930b, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x9315, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
+{ 0x9325, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
+{ 0x9335, 16, {0xe4, 0xef, 0x55, 0x31, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9345, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x9355, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x9365, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x9375, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x9385, 1, {0x22} },
+{ 0x9386, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9396, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
+{ 0x93a6, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
+{ 0x93b6, 16, {0xa0, 0x16, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x93c6, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x93d6, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x93e6, 1, {0x22} },
+{ 0x93e7, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x51, 0x7b, 0x75, 0x52} },
+{ 0x93f7, 16, {0x80, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x51, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x53, 0xf5} },
+{ 0x9407, 16, {0x54, 0x89, 0x55, 0xfe, 0x12, 0x93, 0x86, 0xef, 0x60, 0x50, 0xab, 0x53, 0xaa, 0x54, 0xa9, 0x55} },
+{ 0x9417, 16, {0x12, 0xa0, 0x3f, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
+{ 0x9427, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
+{ 0x9437, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
+{ 0x9447, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x31, 0x60, 0x0f, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9457, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
+{ 0x9461, 1, {0x22} },
+{ 0x9462, 16, {0x12, 0x93, 0xe7, 0xe4, 0xf5, 0x4c, 0x74, 0x37, 0x25, 0x4c, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4d} },
+{ 0x9472, 16, {0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0xff, 0xc4} },
+{ 0x9482, 16, {0x54, 0x0f, 0xf5, 0x4e, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
+{ 0x9492, 16, {0x83, 0xe5, 0x4d, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0xe5, 0x4d, 0x45, 0x4e, 0xfb, 0x12, 0x93, 0x15} },
+{ 0x94a2, 16, {0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x94b2, 16, {0xb5, 0x12, 0x93, 0xe7, 0xe5, 0x3b, 0x60, 0x48, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x74, 0x01, 0xa8} },
+{ 0x94c2, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x55, 0x3b, 0x60, 0x29, 0xe5, 0x4c} },
+{ 0x94d2, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x94e2, 16, {0x16, 0xaf, 0x4c, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7} },
+{ 0x94f2, 16, {0x80, 0xef, 0xe5, 0x4d, 0xf4, 0x52, 0x3b, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
+{ 0x9502, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0xe3, 0x74, 0x19, 0xf0, 0xe5, 0x30, 0xc3, 0x94} },
+{ 0x9512, 16, {0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00, 0xf5, 0x50, 0x80, 0x09} },
+{ 0x9522, 16, {0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f, 0x64, 0x80, 0x94, 0x80} },
+{ 0x9532, 16, {0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x50, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c} },
+{ 0x9542, 16, {0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xbc} },
+{ 0x9552, 16, {0xe0, 0x55, 0x4d, 0x60, 0x14, 0xaf, 0x4c, 0x7d, 0x08, 0xe5, 0x4d, 0x55, 0x50, 0xfb, 0x12, 0x93} },
+{ 0x9562, 16, {0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04} },
+{ 0x9572, 16, {0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x50, 0xf0, 0xe4, 0xf5, 0x4c, 0xc2, 0xaf, 0x74, 0x33, 0x25} },
+{ 0x9582, 16, {0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4d, 0x1e, 0xe5, 0x4d, 0x60, 0x11} },
+{ 0x9592, 16, {0xaf, 0x4c, 0x7d, 0x02, 0xab, 0x4d, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80} },
+{ 0x95a2, 16, {0xef, 0x74, 0x2c, 0x25, 0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82, 0xe4} },
+{ 0x95b2, 16, {0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0x60, 0x11, 0xaf, 0x4c, 0x7d, 0x04, 0xab, 0x4d, 0x12} },
+{ 0x95c2, 16, {0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82} },
+{ 0x95d2, 16, {0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x95e2, 4, {0x9a, 0x12, 0x93, 0xe7} },
+{ 0x95e6, 1, {0x22} },
+{ 0x95e7, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x63, 0x02, 0x96, 0x2e} },
+{ 0x95f3, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
+{ 0x9603, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
+{ 0x9613, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
+{ 0x9623, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x96, 0x73, 0xe4, 0x7e} },
+{ 0x9633, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
+{ 0x9643, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
+{ 0x9653, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
+{ 0x9663, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
+{ 0x9673, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
+{ 0x9683, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
+{ 0x9693, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
+{ 0x969b, 1, {0x00} },
+{ 0x969c, 8, {0x8b, 0x57, 0x8a, 0x58, 0x89, 0x59, 0x8d, 0x5a} },
+{ 0x96a4, 16, {0xe4, 0xf5, 0x5b, 0xf5, 0x5c, 0xaf, 0x5a, 0x15, 0x5a, 0xef, 0x60, 0x36, 0xab, 0x57, 0x05, 0x59} },
+{ 0x96b4, 16, {0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf9, 0x12, 0xa0, 0x3f, 0xff, 0xe5, 0x5b} },
+{ 0x96c4, 16, {0xe5, 0x5c, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x99, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
+{ 0x96d4, 16, {0x9c, 0xf5, 0x83, 0xe5, 0x5b, 0xff, 0xe4, 0x93, 0xf5, 0x5b, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5c} },
+{ 0x96e4, 6, {0x80, 0xc3, 0xae, 0x5b, 0xaf, 0x5c} },
+{ 0x96ea, 1, {0x22} },
+{ 0x96eb, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
+{ 0x96f6, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
+{ 0x9706, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
+{ 0x9716, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
+{ 0x9726, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
+{ 0x9730, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x9739, 2, {0xa9, 0x03} },
+{ 0x973b, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
+{ 0x974b, 16, {0x5a, 0x45, 0x5b, 0xf5, 0x5c, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x975b, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
+{ 0x976b, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5c, 0xeb} },
+{ 0x977b, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5c, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
+{ 0x978b, 16, {0x05, 0x22, 0xe5, 0x5a, 0x5c, 0xfe, 0xe5, 0x5b, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
+{ 0x979b, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x97ab, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5a, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5b, 0x22, 0x7f} },
+{ 0x97bb, 1, {0x00} },
+{ 0x97bc, 1, {0x22} },
+{ 0x97bd, 16, {0x75, 0x53, 0x02, 0x75, 0x54, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x97cd, 16, {0x53, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0} },
+{ 0x97dd, 16, {0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x55, 0x03, 0x75, 0x56, 0x39} },
+{ 0x97ed, 16, {0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9c, 0x61, 0x90, 0x97, 0xfe, 0xf8, 0x28, 0x28} },
+{ 0x97fd, 16, {0x73, 0x02, 0x98, 0x1f, 0x02, 0x98, 0xbe, 0x02, 0x99, 0xc3, 0x02, 0x99, 0xe2, 0x02, 0x99, 0xe2} },
+{ 0x980d, 16, {0x02, 0x9a, 0x98, 0x02, 0x9a, 0xd3, 0x02, 0x9a, 0xf8, 0x02, 0x9b, 0xb6, 0x02, 0x9b, 0xe6, 0x02} },
+{ 0x981d, 16, {0x9c, 0x12, 0xe4, 0xf5, 0x4c, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} },
+{ 0x982d, 16, {0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} },
+{ 0x983d, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4d, 0x80, 0x0d, 0x74} },
+{ 0x984d, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4d, 0xe5, 0x52, 0x24, 0x07} },
+{ 0x985d, 16, {0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0xe0, 0xf5, 0x4e, 0x65, 0x4d, 0x60} },
+{ 0x986d, 16, {0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55} },
+{ 0x987d, 16, {0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x56, 0xe5, 0x56, 0xac} },
+{ 0x988d, 16, {0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4d, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x989d, 16, {0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} },
+{ 0x98ad, 16, {0x02, 0x70, 0x87, 0x05, 0x4c, 0xe5, 0x4c, 0x64, 0x04, 0x60, 0x03, 0x02, 0x98, 0x22, 0x02, 0x9c} },
+{ 0x98bd, 16, {0x67, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x05, 0x4c, 0xe5, 0x4c, 0xd3} },
+{ 0x98cd, 16, {0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0xeb, 0xf0, 0xe4, 0xf5} },
+{ 0x98dd, 16, {0x4e, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0xf5, 0x4c, 0xaf, 0x4c, 0x74} },
+{ 0x98ed, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xc4, 0xf0} },
+{ 0x98fd, 16, {0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3} },
+{ 0x990d, 16, {0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4d, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} },
+{ 0x991d, 16, {0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5, 0x56} },
+{ 0x992d, 16, {0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x993d, 16, {0x85, 0x55, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4e, 0xff, 0x90, 0x01} },
+{ 0x994d, 16, {0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfe, 0x05, 0x56} },
+{ 0x995d, 16, {0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} },
+{ 0x996d, 16, {0x56, 0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x997d, 16, {0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4d, 0xf0, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x70, 0x16} },
+{ 0x998d, 16, {0x74, 0x08, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35, 0x51, 0xf5, 0x51, 0x05, 0x4c, 0xe5, 0x4c, 0x64} },
+{ 0x999d, 16, {0x04, 0x60, 0x03, 0x02, 0x98, 0xea, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x99ad, 16, {0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} },
+{ 0x99bd, 16, {0x74, 0x12, 0xf0, 0x02, 0x9c, 0x67, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x14, 0xff, 0x74} },
+{ 0x99cd, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} },
+{ 0x99dd, 16, {0xc4, 0xf0, 0x02, 0x9c, 0x67, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} },
+{ 0x99ed, 16, {0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} },
+{ 0x99fd, 16, {0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x56, 0x82, 0x85} },
+{ 0x9a0d, 16, {0x55, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4e, 0xe5, 0x4e, 0x60, 0x03, 0x02, 0x9c, 0x67, 0x90, 0x01} },
+{ 0x9a1d, 16, {0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} },
+{ 0x9a2d, 16, {0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00} },
+{ 0x9a3d, 16, {0xf5, 0x50, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f} },
+{ 0x9a4d, 16, {0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x50, 0x54, 0x0f, 0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0} },
+{ 0x9a5d, 16, {0x55, 0x4e, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4d, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9a6d, 16, {0x53, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x9a7d, 16, {0x00, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x03, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} },
+{ 0x9a8d, 16, {0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0xff, 0xfd, 0x12, 0x82} },
+{ 0x9a9d, 16, {0xf9, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9aad, 16, {0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0x74, 0x01} },
+{ 0x9abd, 16, {0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} },
+{ 0x9acd, 16, {0xf0, 0xd2, 0x04, 0x02, 0x9c, 0x67, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75} },
+{ 0x9add, 16, {0x52, 0x00, 0xe5, 0x52, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x9aed, 16, {0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x02, 0x9c, 0x67, 0xe4, 0xf5, 0x4e, 0xf5, 0x4c} },
+{ 0x9afd, 16, {0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} },
+{ 0x9b0d, 16, {0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} },
+{ 0x9b1d, 16, {0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0x7b} },
+{ 0x9b2d, 16, {0x01, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x11} },
+{ 0x9b3d, 16, {0xaf, 0x4c, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5a, 0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f} },
+{ 0x9b4d, 16, {0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x01, 0xfb, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40} },
+{ 0x9b5d, 16, {0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x02, 0xfb, 0x75, 0x5a} },
+{ 0x9b6d, 16, {0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x9b7d, 16, {0xe5, 0x4e, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5} },
+{ 0x9b8d, 16, {0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56} },
+{ 0x9b9d, 16, {0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94} },
+{ 0x9bad, 16, {0x03, 0x50, 0x03, 0x02, 0x9a, 0xfd, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bbd, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9c, 0xf0, 0xa3, 0x74} },
+{ 0x9bcd, 16, {0x89, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0xcc, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9c} },
+{ 0x9bdd, 16, {0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bed, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x55, 0xf0, 0xa3, 0xe5} },
+{ 0x9bfd, 16, {0x56, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} },
+{ 0x9c0d, 16, {0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x54, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x53, 0xfa, 0xa9, 0x07} },
+{ 0x9c1d, 16, {0x7b, 0x01, 0x7d, 0x10, 0x12, 0x96, 0x9c, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} },
+{ 0x9c2d, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x54, 0x24, 0x02, 0x90} },
+{ 0x9c3d, 16, {0x03, 0x60, 0xf0, 0xe4, 0x35, 0x53, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10} },
+{ 0x9c4d, 16, {0xcc, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} },
+{ 0x9c5d, 16, {0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} },
+{ 0x9c6d, 16, {0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} },
+{ 0x9c7d, 11, {0x35, 0x7d, 0x24, 0x12, 0x8f, 0x6e, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
+{ 0x9c88, 1, {0x22} },
+{ 0x9c89, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
+{ 0x9c99, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
+{ 0x9ca9, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
+{ 0x9cb9, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
+{ 0x9cc9, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
+{ 0x9cd9, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
+{ 0x9ce9, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
+{ 0x9cf9, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
+{ 0x9d09, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
+{ 0x9d19, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
+{ 0x9d29, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
+{ 0x9d39, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
+{ 0x9d49, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
+{ 0x9d59, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
+{ 0x9d69, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
+{ 0x9d79, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
+{ 0x9d89, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
+{ 0x9d99, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
+{ 0x9da9, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
+{ 0x9db9, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
+{ 0x9dc9, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
+{ 0x9dd9, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
+{ 0x9de9, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
+{ 0x9df9, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
+{ 0x9e09, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
+{ 0x9e19, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
+{ 0x9e29, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
+{ 0x9e39, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
+{ 0x9e49, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
+{ 0x9e59, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
+{ 0x9e69, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
+{ 0x9e79, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
+{ 0x9e89, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
+{ 0x9e99, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
+{ 0x9ea9, 16, {0x9f, 0x3c, 0x74, 0x37, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9f, 0x3c, 0xef, 0x75, 0xf0} },
+{ 0x9eb9, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
+{ 0x9ec9, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
+{ 0x9ed9, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
+{ 0x9ee9, 16, {0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
+{ 0x9ef9, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
+{ 0x9f09, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
+{ 0x9f19, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
+{ 0x9f29, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
+{ 0x9f39, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9e, 0x9b} },
+{ 0x9f45, 1, {0x22} },
+{ 0x9f46, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
+{ 0x9f56, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
+{ 0x9f66, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
+{ 0x9f76, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
+{ 0x9f86, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
+{ 0x9f96, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
+{ 0x9fa6, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
+{ 0x9fb6, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
+{ 0x9fc6, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
+{ 0x9fd6, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
+{ 0x9fe6, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
+{ 0x9ff6, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
+{ 0xa006, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
+{ 0xa016, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
+{ 0xa026, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
+{ 0xa036, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9f, 0x96, 0x73} },
+{ 0xa03f, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
+{ 0xa04f, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa058, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
+{ 0xa068, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
+{ 0xa078, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa085, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
+{ 0xa095, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
+{ 0xa09b, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
+{ 0xa0ab, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
+{ 0xa0b1, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
+{ 0xa0c1, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
+{ 0xa0d1, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
+{ 0xa0e1, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
+{ 0xa0e9, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
+{ 0xa0f9, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
+{ 0xa109, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
+{ 0xa119, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
+{ 0xa129, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
+{ 0xa139, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
+{ 0xa149, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
+{ 0xa159, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
+{ 0xa169, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
+{ 0xa179, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
+{ 0xa189, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
+{ 0xa199, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
+{ 0xa1a9, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
+{ 0xa1b7, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
+{ 0xa1c7, 1, {0x22} },
+{ 0xa1c8, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
+{ 0xa1d8, 3, {0xd8, 0xf1, 0x22} },
+{ 0xa1db, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
+{ 0xa1eb, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
+{ 0xa1f2, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0xa1fe, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa2, 0x15, 0x12, 0xa2, 0x15, 0x12} },
+{ 0xa20e, 16, {0xa2, 0x15, 0x12, 0xa2, 0x15, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
+{ 0xa21e, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
+{ 0xa22e, 1, {0x22} },
{ 0xffff, 0, {0x00} }
};
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 88e654ec7..44e6cf0a9 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -388,7 +388,6 @@ Scsi_Host_Template usb_stor_host_template = {
present: 0,
unchecked_isa_dma: FALSE,
use_clustering: TRUE,
- use_new_eh_code: TRUE,
emulated: TRUE
};
diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index a090f1c1c..57e4c68e1 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -485,7 +485,7 @@ static int sohci_return_urb (struct ohci *hc, urb_t * urb)
/* implicitly requeued */
urb->actual_length = 0;
- urb->status = USB_ST_URB_PENDING;
+ urb->status = -EINPROGRESS;
if (urb_priv->state != URB_DEL)
td_submit_urb (urb);
break;
@@ -502,7 +502,7 @@ static int sohci_return_urb (struct ohci *hc, urb_t * urb)
urb->complete (urb);
spin_lock_irqsave (&usb_ed_lock, flags);
urb->actual_length = 0;
- urb->status = USB_ST_URB_PENDING;
+ urb->status = -EINPROGRESS;
urb->start_frame = urb_priv->ed->last_iso + 1;
if (urb_priv->state != URB_DEL) {
for (i = 0; i < urb->number_of_packets; i++) {
@@ -673,7 +673,7 @@ static int sohci_submit_urb (urb_t * urb)
urb->actual_length = 0;
urb->hcpriv = urb_priv;
- urb->status = USB_ST_URB_PENDING;
+ urb->status = -EINPROGRESS;
/* link the ed into a chain if is not already */
if (ed->state != ED_OPER)
@@ -737,7 +737,7 @@ static int sohci_unlink_urb (urb_t * urb)
if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
return rh_unlink_urb (urb);
- if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) {
+ if (urb->hcpriv && (urb->status == -EINPROGRESS)) {
if (!ohci->disabled) {
urb_priv_t * urb_priv;
@@ -777,11 +777,11 @@ static int sohci_unlink_urb (urb_t * urb)
/* wait until all TDs are deleted */
set_current_state(TASK_UNINTERRUPTIBLE);
- while (timeout && (urb->status == USB_ST_URB_PENDING))
+ while (timeout && (urb->status == -EINPROGRESS))
timeout = schedule_timeout (timeout);
set_current_state(TASK_RUNNING);
remove_wait_queue (&unlink_wakeup, &wait);
- if (urb->status == USB_ST_URB_PENDING) {
+ if (urb->status == -EINPROGRESS) {
err ("unlink URB timeout");
return -ETIMEDOUT;
}
diff --git a/drivers/usb/usb-ohci.h b/drivers/usb/usb-ohci.h
index e38fc015a..ba9758e2d 100644
--- a/drivers/usb/usb-ohci.h
+++ b/drivers/usb/usb-ohci.h
@@ -11,22 +11,22 @@
static int cc_to_error[16] = {
/* mapping of the OHCI CC status to error codes */
- /* No Error */ USB_ST_NOERROR,
- /* CRC Error */ USB_ST_CRC,
- /* Bit Stuff */ USB_ST_BITSTUFF,
- /* Data Togg */ USB_ST_CRC,
- /* Stall */ USB_ST_STALL,
- /* DevNotResp */ USB_ST_NORESPONSE,
- /* PIDCheck */ USB_ST_BITSTUFF,
- /* UnExpPID */ USB_ST_BITSTUFF,
- /* DataOver */ USB_ST_DATAOVERRUN,
- /* DataUnder */ USB_ST_DATAUNDERRUN,
- /* reservd */ USB_ST_NORESPONSE,
- /* reservd */ USB_ST_NORESPONSE,
- /* BufferOver */ USB_ST_BUFFEROVERRUN,
- /* BuffUnder */ USB_ST_BUFFERUNDERRUN,
- /* Not Access */ USB_ST_NORESPONSE,
- /* Not Access */ USB_ST_NORESPONSE
+ /* No Error */ 0,
+ /* CRC Error */ -EILSEQ,
+ /* Bit Stuff */ -EPROTO,
+ /* Data Togg */ -EILSEQ,
+ /* Stall */ -EPIPE,
+ /* DevNotResp */ -ETIMEDOUT,
+ /* PIDCheck */ -EPROTO,
+ /* UnExpPID */ -EPROTO,
+ /* DataOver */ -EOVERFLOW,
+ /* DataUnder */ -EREMOTEIO,
+ /* reservd */ -ETIMEDOUT,
+ /* reservd */ -ETIMEDOUT,
+ /* BufferOver */ -ECOMM,
+ /* BuffUnder */ -ENOSR,
+ /* Not Access */ -ETIMEDOUT,
+ /* Not Access */ -ETIMEDOUT
};
#include <linux/config.h>
diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c
index af4bd2c9e..1003eaf52 100644
--- a/drivers/usb/usb.c
+++ b/drivers/usb/usb.c
@@ -7,7 +7,8 @@
* (C) Copyright Gregory P. Smith 1999
* (C) Copyright Deti Fliegl 1999 (new USB architecture)
* (C) Copyright Randy Dunlap 2000
- * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
+ * (C) Copyright David Brownell 2000-2001 (kernel hotplug, usb_device_id,
+ more docs, etc)
* (C) Copyright Yggdrasil Computing, Inc. 2000
* (usb_device_id matching changes by Adam J. Richter)
*
@@ -105,8 +106,8 @@ int usb_register(struct usb_driver *new_driver)
* Goes through all unclaimed USB interfaces, and offers them to all
* registered USB drivers through the 'probe' function.
* This will automatically be called after usb_register is called.
- * It is called by some of the USB subsystems after one of their subdrivers
- * are registered.
+ * It is called by some of the subsystems layered over USB
+ * after one of their subdrivers are registered.
*/
void usb_scan_devices(void)
{
@@ -193,6 +194,22 @@ void usb_deregister(struct usb_driver *driver)
up (&usb_bus_list_lock);
}
+/**
+ * usb_ifnum_to_if - get the interface object with a given interface number
+ * @dev: the device whose current configuration is considered
+ * @ifnum: the desired interface
+ *
+ * This walks the device descriptor for the currently active configuration
+ * and returns a pointer to the interface with that particular interface
+ * number, or null.
+ *
+ * Note that configuration descriptors are not required to assign interface
+ * numbers sequentially, so that it would be incorrect to assume that
+ * the first interface in that descriptor corresponds to interface zero.
+ * This routine helps device drivers avoid such mistakes.
+ * However, you should make sure that you do the right thing with any
+ * alternate settings available for this interfaces.
+ */
struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
{
int i;
@@ -204,6 +221,20 @@ struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
return NULL;
}
+/**
+ * usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
+ * @dev: the device whose current configuration is considered
+ * @epnum: the desired endpoint
+ *
+ * This walks the device descriptor for the currently active configuration,
+ * and returns a pointer to the endpoint with that particular endpoint
+ * number, or null.
+ *
+ * Note that interface descriptors are not required to assign endpont
+ * numbers sequentially, so that it would be incorrect to assume that
+ * the first endpoint in that descriptor corresponds to interface zero.
+ * This routine helps device drivers avoid such mistakes.
+ */
struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
{
int i, j, k;
@@ -261,7 +292,7 @@ static long usb_calc_bus_time (int low_speed, int input_dir, int isoc, int bytec
* bustime is from calc_bus_time(), but converted to microseconds.
*
* returns <bustime in us> if successful,
- * or USB_ST_BANDWIDTH_ERROR if bandwidth request fails.
+ * or -ENOSPC if bandwidth request fails.
*
* FIXME:
* This initial implementation does not use Endpoint.bInterval
@@ -302,7 +333,7 @@ int usb_check_bandwidth (struct usb_device *dev, struct urb *urb)
if (!usb_bandwidth_option) /* don't enforce it */
return (bustime);
- return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : USB_ST_BANDWIDTH_ERROR;
+ return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : -ENOSPC;
}
void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc)
@@ -356,7 +387,7 @@ static void usb_bus_put(struct usb_bus *bus)
}
/**
- * usb_alloc_bus - creates a new USB host controller structure
+ * usb_alloc_bus - creates a new USB host controller structure (usbcore-internal)
* @op: pointer to a struct usb_operations that this bus structure should use
*
* Creates a USB host controller bus structure with the specified
@@ -398,7 +429,7 @@ struct usb_bus *usb_alloc_bus(struct usb_operations *op)
}
/**
- * usb_free_bus - frees the memory used by a bus structure
+ * usb_free_bus - frees the memory used by a bus structure (usbcore-internal)
* @bus: pointer to the bus to free
*
* (For use only by USB Host Controller Drivers.)
@@ -412,10 +443,12 @@ void usb_free_bus(struct usb_bus *bus)
}
/**
- * usb_register_bus - registers the USB host controller with the usb core
+ * usb_register_bus - registers the USB host controller with the usb core (usbcore-internal)
* @bus: pointer to the bus to register
*
* (For use only by USB Host Controller Drivers.)
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
*/
void usb_register_bus(struct usb_bus *bus)
{
@@ -441,10 +474,12 @@ void usb_register_bus(struct usb_bus *bus)
}
/**
- * usb_deregister_bus - deregisters the USB host controller
+ * usb_deregister_bus - deregisters the USB host controller (usbcore-internal)
* @bus: pointer to the bus to deregister
*
* (For use only by USB Host Controller Drivers.)
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
*/
void usb_deregister_bus(struct usb_bus *bus)
{
@@ -493,27 +528,49 @@ static void usb_check_support(struct usb_device *dev)
}
-/*
- * This is intended to be used by usb device drivers that need to
- * claim more than one interface on a device at once when probing
- * (audio and acm are good examples). No device driver should have
- * to mess with the internal usb_interface or usb_device structure
- * members.
+/**
+ * usb_driver_claim_interface - bind a driver to an interface
+ * @driver: the driver to be bound
+ * @iface: the interface to which it will be bound
+ * @priv: driver data associated with that interface
+ *
+ * This is used by usb device drivers that need to claim more than one
+ * interface on a device when probing (audio and acm are current examples).
+ * No device driver should directly modify internal usb_interface or
+ * usb_device structure members.
+ *
+ * Few drivers should need to use this routine, since the most natural
+ * way to bind to an interface is to return the private data from
+ * the driver's probe() method. Any driver that does use this must
+ * first be sure that no other driver has claimed the interface, by
+ * checking with usb_interface_claimed().
*/
void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv)
{
if (!iface || !driver)
return;
- dbg("%s driver claimed interface %p", driver->name, iface);
+ // FIXME change API to report an error in this case
+ if (iface->driver)
+ err ("%s driver booted %s off interface %p",
+ driver->name, iface->driver->name, iface);
+ else
+ dbg("%s driver claimed interface %p", driver->name, iface);
iface->driver = driver;
iface->private_data = priv;
} /* usb_driver_claim_interface() */
-/*
+/**
+ * usb_interface_claimed - returns true iff an interface is claimed
+ * @iface: the interface being checked
+ *
* This should be used by drivers to check other interfaces to see if
- * they are available or not.
+ * they are available or not. If another driver has claimed the interface,
+ * they may not claim it. Otherwise it's OK to claim it using
+ * usb_driver_claim_interface().
+ *
+ * Returns true (nonzero) iff the interface is claimed, else false (zero).
*/
int usb_interface_claimed(struct usb_interface *iface)
{
@@ -523,8 +580,19 @@ int usb_interface_claimed(struct usb_interface *iface)
return (iface->driver != NULL);
} /* usb_interface_claimed() */
-/*
- * This should be used by drivers to release their claimed interfaces
+/**
+ * usb_driver_release_interface - unbind a driver from an interface
+ * @driver: the driver to be unbound
+ * @iface: the interface from which it will be unbound
+ *
+ * This should be used by drivers to release their claimed interfaces.
+ * It is normally called in their disconnect() methods, and only for
+ * drivers that bound to more than one interface in their probe().
+ *
+ * When the USB subsystem disconnect()s a driver from some interface,
+ * it automatically invokes this method for that interface. That
+ * means that even drivers that used usb_driver_claim_interface()
+ * usually won't need to call this.
*/
void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface)
{
@@ -923,9 +991,15 @@ static void usb_find_drivers(struct usb_device *dev)
}
}
-/*
- * Only HC's should call usb_alloc_dev and usb_free_dev directly
- * Anybody may use usb_inc_dev_use or usb_dec_dev_use
+/**
+ * usb_alloc_dev - allocate a usb device structure (usbcore-internal)
+ * @parent: hub to which device is connected
+ * @bus: bus used to access the device
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
*/
struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
{
@@ -952,6 +1026,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
return dev;
}
+// usbcore-internal ...
+// but usb_dec_dev_use() is #defined to this, and that's public!!
void usb_free_dev(struct usb_device *dev)
{
if (atomic_dec_and_test(&dev->refcnt)) {
@@ -964,14 +1040,25 @@ void usb_free_dev(struct usb_device *dev)
}
}
+/**
+ * usb_inc_dev_use - record another reference to a device
+ * @dev: the device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Device drivers should normally record such references in their
+ * open() methods.
+ * Drivers should then release them, using usb_dec_dev_use(), in their
+ * close() methods.
+ */
void usb_inc_dev_use(struct usb_device *dev)
{
atomic_inc(&dev->refcnt);
}
-/* -------------------------------------------------------------------------------------
+/* ----------------------------------------------------------------------
* New USB Core Functions
- * -------------------------------------------------------------------------------------*/
+ * ----------------------------------------------------------------------*/
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
@@ -1017,6 +1104,61 @@ void usb_free_urb(urb_t* urb)
kfree(urb);
}
/*-------------------------------------------------------------------*/
+
+/**
+ * usb_submit_urb - asynchronously issue a transfer request for an endpoint
+ * @urb: pointer to the urb describing the request
+ *
+ * This submits a transfer request, and transfers control of the URB
+ * describing that request to the USB subsystem. Request completion will
+ * indicated later, asynchronously, by calling the completion handler.
+ * This call may be issued in interrupt context.
+ *
+ * The caller must have correctly initialized the URB before submitting
+ * it. Macros such as FILL_BULK_URB() and FILL_CONTROL_URB() are
+ * available to ensure that most fields are correctly initialized, for
+ * the particular kind of transfer, although they will not initialize
+ * any transfer flags.
+ *
+ * Successful submissions return 0; otherwise this routine returns a
+ * negative error number. If the submission is successful, the complete
+ * fuction of the urb will be called when the USB host driver is
+ * finished with the urb (either a successful transmission, or some
+ * error case.)
+ *
+ * Unreserved Bandwidth Transfers:
+ *
+ * Bulk or control requests complete only once. When the completion
+ * function is called, control of the URB is returned to the device
+ * driver which issued the request. The completion handler may then
+ * immediately free or reuse that URB.
+ *
+ * Bulk URBs will be queued if the USB_QUEUE_BULK transfer flag is set
+ * in the URB. This can be used to maximize bandwidth utilization by
+ * letting the USB controller start work on the next URB without any
+ * delay to report completion (scheduling and processing an interrupt)
+ * and then submit that next request.
+ *
+ * For control endpoints, the synchronous usb_control_msg() call is
+ * often used (in non-interrupt context) instead of this call.
+ *
+ * Reserved Bandwidth Transfers:
+ *
+ * Periodic URBs (interrupt or isochronous) are completed repeatedly,
+ * until the original request is aborted. When the completion callback
+ * indicates the URB has been unlinked (with a special status code),
+ * control of that URB returns to the device driver. Otherwise, the
+ * completion handler does not control the URB, and should not change
+ * any of its fields.
+ *
+ * Note that isochronous URBs should be submitted in a "ring" data
+ * structure (using urb->next) to ensure that they are resubmitted
+ * appropriately.
+ *
+ * If the USB subsystem can't reserve sufficient bandwidth to perform
+ * the periodic request, and bandwidth reservation is being done for
+ * this controller, submitting such a periodic request will fail.
+ */
int usb_submit_urb(urb_t *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
@@ -1026,6 +1168,31 @@ int usb_submit_urb(urb_t *urb)
}
/*-------------------------------------------------------------------*/
+
+/**
+ * usb_unlink_urb - abort/cancel a transfer request for an endpoint
+ * @urb: pointer to urb describing a previously submitted request
+ *
+ * This routine cancels an in-progress request. The requests's
+ * completion handler will be called with a status code indicating
+ * that the request has been canceled, and that control of the URB
+ * has been returned to that device driver. This is the only way
+ * to stop an interrupt transfer, so long as the device is connected.
+ *
+ * When the USB_ASYNC_UNLINK transfer flag for the URB is clear, this
+ * request is synchronous. Success is indicated by returning zero,
+ * at which time the urb will have been unlinked,
+ * and the completion function will see status -ENOENT. Failure is
+ * indicated by any other return value. This mode may not be used
+ * when unlinking an urb from an interrupt context, such as a bottom
+ * half or a completion handler,
+ *
+ * When the USB_ASYNC_UNLINK transfer flag for the URB is set, this
+ * request is asynchronous. Success is indicated by returning -EINPROGRESS,
+ * at which time the urb will normally not have been unlinked,
+ * and the completion function will see status -ECONNRESET. Failure is
+ * indicated by any other return value.
+ */
int usb_unlink_urb(urb_t *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
@@ -1034,12 +1201,14 @@ int usb_unlink_urb(urb_t *urb)
return -ENODEV;
}
/*-------------------------------------------------------------------*
- * COMPLETION HANDLERS *
+ * SYNCHRONOUS CALLS *
*-------------------------------------------------------------------*/
-/*-------------------------------------------------------------------*
- * completion handler for compatibility wrappers (sync control/bulk) *
- *-------------------------------------------------------------------*/
+struct usb_api_data {
+ wait_queue_head_t wqh;
+ int done;
+};
+
static void usb_api_blocking_completion(urb_t *urb)
{
struct usb_api_data *awd = (struct usb_api_data *)urb->context;
@@ -1049,10 +1218,6 @@ static void usb_api_blocking_completion(urb_t *urb)
wake_up(&awd->wqh);
}
-/*-------------------------------------------------------------------*
- * COMPATIBILITY STUFF *
- *-------------------------------------------------------------------*/
-
// Starts urb and waits for completion or timeout
static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
{
@@ -1145,7 +1310,7 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
* This function sends a simple control message to a specified endpoint
* and waits for the message to complete, or timeout.
*
- * If successful, it returns 0, othwise a negative error number.
+ * If successful, it returns 0, otherwise a negative error number.
*
* Don't use this function from within an interrupt context, like a
* bottom half handler. If you need a asyncronous message, or need to send
@@ -1188,9 +1353,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
* This function sends a simple bulk message to a specified endpoint
* and waits for the message to complete, or timeout.
*
- * If successful, it returns 0, othwise a negative error number.
- * The number of actual bytes transferred will be plaed in the
- * actual_timeout paramater.
+ * If successful, it returns 0, otherwise a negative error number.
+ * The number of actual bytes transferred will be stored in the
+ * actual_length paramater.
*
* Don't use this function from within an interrupt context, like a
* bottom half handler. If you need a asyncronous message, or need to
@@ -1214,16 +1379,19 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
return usb_start_wait_urb(urb,timeout,actual_length);
}
-/*
- * usb_get_current_frame_number()
+/**
+ * usb_get_current_frame_number - return current bus frame number
+ * @dev: the device whose bus is being queried
*
- * returns the current frame number for the parent USB bus/controller
- * of the given USB device.
+ * Returns the current frame number for the USB host controller
+ * used with the given USB device. This can be used when scheduling
+ * isochronous requests.
*/
-int usb_get_current_frame_number(struct usb_device *usb_dev)
+int usb_get_current_frame_number(struct usb_device *dev)
{
- return usb_dev->bus->op->get_frame_number (usb_dev);
+ return dev->bus->op->get_frame_number (dev);
}
+
/*-------------------------------------------------------------------*/
static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size)
@@ -1556,6 +1724,8 @@ int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)
return size;
}
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally on disconnect/destroy path
void usb_destroy_configuration(struct usb_device *dev)
{
int c, i, j, k;
@@ -1685,8 +1855,16 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type,
return -1;
}
-/*
+/**
+ * usb_disconnect - disconnect a device (usbcore-internal)
+ * @pdev: pointer to device being disconnected
+ *
* Something got disconnected. Get rid of it, and all of its children.
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
*/
void usb_disconnect(struct usb_device **pdev)
{
@@ -1735,11 +1913,17 @@ void usb_disconnect(struct usb_device **pdev)
usb_free_dev(dev);
}
-/*
+/**
+ * usb_connect - connects a new device during enumeration (usbcore-internal)
+ * @dev: partially enumerated device
+ *
* Connect a new USB device. This basically just initializes
* the USB device information and sets up the topology - it's
* up to the low-level driver to reset the port and actually
* do the setup (the upper levels don't know how to do that).
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
*/
void usb_connect(struct usb_device *dev)
{
@@ -1747,6 +1931,9 @@ void usb_connect(struct usb_device *dev)
// FIXME needs locking for SMP!!
/* why? this is called only from the hub thread,
* which hopefully doesn't run on multiple CPU's simultaneously 8-)
+ * ... it's also called from modprobe/rmmod/apmd threads as part
+ * of virtual root hub init/reinit. In the init case, the hub code
+ * won't have seen this, but not so for reinit ...
*/
dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
#ifndef DEVNUM_ROUND_ROBIN
@@ -1770,19 +1957,38 @@ void usb_connect(struct usb_device *dev)
* These are the actual routines to send
* and receive control messages.
*/
-#ifdef CONFIG_USB_LONG_TIMEOUT
-#define GET_TIMEOUT 4
-#else
-#define GET_TIMEOUT 3
-#endif
-#define SET_TIMEOUT 3
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally, for usb_new_device()
int usb_set_address(struct usb_device *dev)
{
return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
- 0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT);
+ // FIXME USB_CTRL_SET_TIMEOUT
+ 0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
}
+/**
+ * usb_get_descriptor - issues a generic GET_DESCRIPTOR request
+ * @dev: the device whose descriptor is being retrieved
+ * @type: the descriptor type (USB_DT_*)
+ * @index: the number of the descriptor
+ * @buf: where to put the descriptor
+ * @size: how big is "buf"?
+ *
+ * Gets a USB descriptor. Convenience functions exist to simplify
+ * getting some types of descriptors. Use
+ * usb_get_device_descriptor() for USB_DT_DEVICE,
+ * and usb_get_string() or usb_string() for USB_DT_STRING.
+ * Configuration descriptors (USB_DT_CONFIG) are part of the device
+ * structure, at least for the current configuration.
+ * In addition to a number of USB-standard descriptors, some
+ * devices also use class-specific or vendor-specific descriptors.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
{
int i = 5;
@@ -1791,30 +1997,64 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
memset(buf,0,size); // Make sure we parse really received data
while (i--) {
+ /* retries if the returned length was 0; flakey device */
if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 ||
- result == -EPIPE)
- break; /* retry if the returned length was 0; flaky device */
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (type << 8) + index, 0, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT)) > 0
+ || result == -EPIPE)
+ break;
}
return result;
}
-int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
- unsigned char type, unsigned char id, void *buf, int size)
-{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
- (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
-}
-
+/**
+ * usb_get_string - gets a string descriptor
+ * @dev: the device whose string descriptor is being retrieved
+ * @langid: code for language chosen (from string descriptor zero)
+ * @index: the number of the descriptor
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ *
+ * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
+ * in little-endian byte order).
+ * The usb_string() function will often be a convenient way to turn
+ * these strings into kernel-printable form.
+ *
+ * Strings may be referenced in device, configuration, interface, or other
+ * descriptors, and could also be used in vendor-specific ways.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT);
+ (USB_DT_STRING << 8) + index, langid, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
}
+/**
+ * usb_get_device_descriptor - (re)reads the device descriptor
+ * @dev: the device whose device descriptor is being updated
+ *
+ * Updates the copy of the device descriptor stored in the device structure,
+ * which dedicates space for this purpose. Note that several fields are
+ * converted to the host CPU's byte order: the USB version (bcdUSB), and
+ * vendors product and version fields (idVendor, idProduct, and bcdDevice).
+ * That lets device drivers compare against non-byteswapped constants.
+ *
+ * There's normally no need to use this call, although some devices
+ * will change their descriptors after events like updating firmware.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_get_device_descriptor(struct usb_device *dev)
{
int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
@@ -1828,39 +2068,37 @@ int usb_get_device_descriptor(struct usb_device *dev)
return ret;
}
+/**
+ * usb_get_status - issues a GET_STATUS call
+ * @dev: the device whose status is being checked
+ * @type: USB_RECIP_*; for device, interface, or endpoint
+ * @target: zero (for device), else interface or endpoint number
+ * @data: pointer to two bytes of bitmap data
+ *
+ * Returns device, interface, or endpoint status. Normally only of
+ * interest to see if the device is self powered, or has enabled the
+ * remote wakeup facility; or whether a bulk or interrupt endpoint
+ * is halted ("stalled").
+ *
+ * Bits in these status bitmaps are set using the SET_FEATURE request,
+ * and cleared using the CLEAR_FEATURE request. The usb_clear_halt()
+ * function should be used to clear halt ("stall") status.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_get_status(struct usb_device *dev, int type, int target, void *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT);
+ USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2,
+ HZ * USB_CTRL_GET_TIMEOUT);
}
-int usb_get_protocol(struct usb_device *dev, int ifnum)
-{
- unsigned char type;
- int ret;
-
- if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0)
- return ret;
-
- return type;
-}
-
-int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT);
-}
-
-int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT);
-}
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally, for config/altsetting reconfig.
void usb_set_maxpacket(struct usb_device *dev)
{
int i, b;
@@ -1890,9 +2128,26 @@ void usb_set_maxpacket(struct usb_device *dev)
}
}
-/*
- * endp: endpoint number in bits 0-3;
- * direction flag in bit 7 (1 = IN, 0 = OUT)
+/**
+ * usb_clear_halt - tells device to clear endpoint halt/stall condition
+ * @dev: device whose endpoint is halted
+ * @pipe: endpoint "pipe" being cleared
+ *
+ * This is used to clear halt conditions for bulk and interrupt endpoints,
+ * as reported by URB completion status. Endpoints that are halted are
+ * sometimes referred to as being "stalled". Such endpoints are unable
+ * to transmit or receive data until the halt status is cleared. Any URBs
+ * queued queued for such an endpoint should normally be unlinked before
+ * clearing the halt condition.
+ *
+ * Note that control and isochronous endpoints don't halt, although control
+ * endpoints report "protocol stall" (for unsupported requests) using the
+ * same status code used to report a true stall.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
*/
int usb_clear_halt(struct usb_device *dev, int pipe)
{
@@ -1907,7 +2162,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
*/
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT);
+ USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
+ HZ * USB_CTRL_SET_TIMEOUT);
/* don't clear if failed */
if (result < 0)
@@ -1921,7 +2177,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
- buffer, sizeof(status), HZ * SET_TIMEOUT);
+ // FIXME USB_CTRL_GET_TIMEOUT, yes? why not usb_get_status() ?
+ buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT);
memcpy(&status, buffer, sizeof(status));
kfree(buffer);
@@ -1941,6 +2198,33 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
return 0;
}
+/**
+ * usb_set_interface - Makes a particular alternate setting be current
+ * @dev: the device whose interface is being updated
+ * @interface: the interface being updated
+ * @alternate: the setting being chosen.
+ *
+ * This is used to enable data transfers on interfaces that may not
+ * be enabled by default. Not all devices support such configurability.
+ *
+ * Within any given configuration, each interface may have several
+ * alternative settings. These are often used to control levels of
+ * bandwidth consumption. For example, the default setting for a high
+ * speed interrupt endpoint may not send more than about 4KBytes per
+ * microframe, and isochronous endpoints may never be part of a an
+ * interface's default setting. To access such bandwidth, alternate
+ * interface setting must be made current.
+ *
+ * Note that in the Linux USB subsystem, bandwidth associated with
+ * an endpoint in a given alternate setting is not reserved until an
+ * is submitted that needs that bandwidth. Some other operating systems
+ * allocate bandwidth early, when a configuration is chosen.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
struct usb_interface *iface;
@@ -1964,6 +2248,35 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
return 0;
}
+/**
+ * usb_set_configuration - Makes a particular device setting be current
+ * @dev: the device whose configuration is being updated
+ * @configuration: the configuration being chosen.
+ *
+ * This is used to enable non-default device modes. Not all devices
+ * support this kind of configurability. By default, configuration
+ * zero is selected after enumeration; many devices only have a single
+ * configuration.
+ *
+ * USB devices may support one or more configurations, which affect
+ * power consumption and the functionality available. For example,
+ * the default configuration is limited to using 100mA of bus power,
+ * so that when certain device functionality requires more power,
+ * and the device is bus powered, that functionality will be in some
+ * non-default device configuration. Other device modes may also be
+ * reflected as configuration options, such as whether two ISDN
+ * channels are presented as independent 64Kb/s interfaces or as one
+ * bonded 128Kb/s interface.
+ *
+ * Note that USB has an additional level of device configurability,
+ * associated with interfaces. That configurability is accessed using
+ * usb_set_interface().
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
int usb_set_configuration(struct usb_device *dev, int configuration)
{
int i, ret;
@@ -1981,7 +2294,8 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
}
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0)
+ USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+ NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
return ret;
dev->actconfig = cp;
@@ -1992,20 +2306,8 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
return 0;
}
-int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
-{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
-}
-
-int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, ifnum, buf, size, HZ);
-}
-
+// hub-only!! ... and only in reset path, or usb_new_device()
+// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
int result;
@@ -2106,9 +2408,28 @@ err:
return result;
}
-/*
- * usb_string:
- * returns string length (> 0) or error (< 0)
+/**
+ * usb_string - returns ISO 8859-1 version of a string descriptor
+ * @dev: the device whose string descriptor is being retrieved
+ * @index: the number of the descriptor
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ *
+ * This converts the UTF-16LE encoded strings returned by devices, from
+ * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones
+ * that are more usable in most kernel contexts. Note that all characters
+ * in the chosen descriptor that can't be encoded using ISO-8859-1
+ * are converted to the question mark ("?") character, and this function
+ * chooses strings in the first language supported by the device.
+ *
+ * The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit
+ * subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode,
+ * and is appropriate for use many uses of English and several other
+ * Western European languages. (But it doesn't include the "Euro" symbol.)
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns length of the string (>= 0) or usb_control_msg status (< 0).
*/
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
@@ -2155,7 +2476,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
if (idx >= size)
break;
if (tbuf[u+1]) /* high byte */
- buf[idx++] = '?'; /* non-ASCII character */
+ buf[idx++] = '?'; /* non ISO-8859-1 character */
else
buf[idx++] = tbuf[u];
}
@@ -2173,6 +2494,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
* get the ball rolling..
*
* Returns 0 for success, != 0 for error.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
*/
int usb_new_device(struct usb_device *dev)
{
@@ -2388,33 +2714,28 @@ EXPORT_SYMBOL(usb_check_bandwidth);
EXPORT_SYMBOL(usb_claim_bandwidth);
EXPORT_SYMBOL(usb_release_bandwidth);
-EXPORT_SYMBOL(usb_set_address);
-EXPORT_SYMBOL(usb_get_descriptor);
-EXPORT_SYMBOL(usb_get_class_descriptor);
EXPORT_SYMBOL(__usb_get_extra_descriptor);
-EXPORT_SYMBOL(usb_get_device_descriptor);
-EXPORT_SYMBOL(usb_get_string);
-EXPORT_SYMBOL(usb_string);
-EXPORT_SYMBOL(usb_get_protocol);
-EXPORT_SYMBOL(usb_set_protocol);
-EXPORT_SYMBOL(usb_get_report);
-EXPORT_SYMBOL(usb_set_report);
-EXPORT_SYMBOL(usb_set_idle);
-EXPORT_SYMBOL(usb_clear_halt);
-EXPORT_SYMBOL(usb_set_interface);
-EXPORT_SYMBOL(usb_get_configuration);
-EXPORT_SYMBOL(usb_set_configuration);
-EXPORT_SYMBOL(usb_get_status);
EXPORT_SYMBOL(usb_get_current_frame_number);
+// asynchronous request completion model
EXPORT_SYMBOL(usb_alloc_urb);
EXPORT_SYMBOL(usb_free_urb);
EXPORT_SYMBOL(usb_submit_urb);
EXPORT_SYMBOL(usb_unlink_urb);
+// synchronous request completion model
EXPORT_SYMBOL(usb_control_msg);
EXPORT_SYMBOL(usb_bulk_msg);
+// synchronous control message convenience routines
+EXPORT_SYMBOL(usb_get_descriptor);
+EXPORT_SYMBOL(usb_get_device_descriptor);
+EXPORT_SYMBOL(usb_get_status);
+EXPORT_SYMBOL(usb_get_string);
+EXPORT_SYMBOL(usb_string);
+EXPORT_SYMBOL(usb_clear_halt);
+EXPORT_SYMBOL(usb_set_configuration);
+EXPORT_SYMBOL(usb_set_interface);
EXPORT_SYMBOL(usb_devfs_handle);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/usbkbd.c b/drivers/usb/usbkbd.c
index c2c742d4b..365adb3bb 100644
--- a/drivers/usb/usbkbd.c
+++ b/drivers/usb/usbkbd.c
@@ -35,6 +35,9 @@
#include <linux/init.h>
#include <linux/usb.h>
+#define _HID_BOOT_PROTOCOL
+#include "hid.h"
+
/*
* Version Information
*/
@@ -192,8 +195,8 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- usb_set_protocol(dev, interface->bInterfaceNumber, 0);
- usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
+ hid_set_protocol(dev, interface->bInterfaceNumber, 0);
+ hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
memset(kbd, 0, sizeof(struct usb_kbd));
@@ -216,7 +219,7 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
usb_kbd_irq, kbd, endpoint->bInterval);
kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- kbd->dr.request = USB_REQ_SET_REPORT;
+ kbd->dr.request = HID_REQ_SET_REPORT;
kbd->dr.value = 0x200;
kbd->dr.index = interface->bInterfaceNumber;
kbd->dr.length = 1;
diff --git a/drivers/usb/usbmouse.c b/drivers/usb/usbmouse.c
index 9eb4fb275..ff4ee6676 100644
--- a/drivers/usb/usbmouse.c
+++ b/drivers/usb/usbmouse.c
@@ -35,6 +35,9 @@
#include <linux/init.h>
#include <linux/usb.h>
+#define _HID_BOOT_PROTOCOL
+#include "hid.h"
+
/*
* Version Information
*/
@@ -118,7 +121,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
+ hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
memset(mouse, 0, sizeof(struct usb_mouse));
diff --git a/drivers/usb/usbnet.c b/drivers/usb/usbnet.c
index 3e90b8b31..3356d7c5c 100644
--- a/drivers/usb/usbnet.c
+++ b/drivers/usb/usbnet.c
@@ -1535,7 +1535,7 @@ static void tx_complete (struct urb *urb)
struct skb_data *entry = (struct skb_data *) skb->cb;
struct usbnet *dev = entry->dev;
- if (urb->status == USB_ST_STALL) {
+ if (urb->status == -EPIPE) {
if (dev->ctrl_task.sync == 0) {
dev->ctrl_task.routine = tx_clear_halt;
dev->ctrl_task.data = dev;
@@ -1875,6 +1875,11 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
driver_info: (unsigned long) &an2720_info,
},
+
+{
+ USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
+ driver_info: (unsigned long) &an2720_info,
+},
#endif
#ifdef CONFIG_USB_BELKIN
diff --git a/drivers/usb/uss720.c b/drivers/usb/uss720.c
index 98067c866..ebf8e985b 100644
--- a/drivers/usb/uss720.c
+++ b/drivers/usb/uss720.c
@@ -193,7 +193,7 @@ static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
struct parport *pp = (struct parport *)dev_id;
struct parport_uss720_private *priv = pp->private_data;
- if (usbstatus != USB_ST_NOERROR || len < 4 || !buffer)
+ if (usbstatus != 0 || len < 4 || !buffer)
return 1;
memcpy(priv->reg, buffer, 4);
/* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index bcdbfb7f4..845e8e494 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -14,9 +14,9 @@
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/fb.h>
-#include <linux/console_struct.h>
#include <linux/sched.h>
+#include <video/fbcon.h>
#undef DEBUG
@@ -257,29 +257,6 @@ static int __init my_atoi(const char *name)
}
}
-static int PROC_CONSOLE(const struct fb_info *info)
-{
- int fgc;
-
- if (info->display_fg != NULL)
- fgc = info->display_fg->vc_num;
- else
- return -1;
-
- if (!current->tty)
- return fgc;
-
- if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
- /* XXX Should report error here? */
- return fgc;
-
- if (MINOR(current->tty->device) < 1)
- return fgc;
-
- return MINOR(current->tty->device) - 1;
-}
-
-
/**
* __fb_try_mode - test a video mode
* @var: frame buffer user defined part of display
diff --git a/fs/Makefile b/fs/Makefile
index 01eaf026b..23cf3614a 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -7,12 +7,12 @@
O_TARGET := fs.o
-export-objs := filesystems.o open.o dcache.o buffer.o
+export-objs := filesystems.o open.o dcache.o buffer.o bio.o
mod-subdirs := nls
obj-y := open.o read_write.o devices.o file_table.o buffer.o \
- super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
- fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
+ bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
+ namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
filesystems.o namespace.o seq_file.o
@@ -24,6 +24,7 @@ endif
subdir-$(CONFIG_PROC_FS) += proc
subdir-y += partitions
+subdir-y += driverfs
# Do not add any filesystems before this line
subdir-$(CONFIG_EXT3_FS) += ext3 # Before ext2 so root fs can be ext3
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 8a168f71f..a54289141 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -38,8 +38,6 @@ static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
-static int affs_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create);
-
static ssize_t affs_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);
static int affs_file_open(struct inode *inode, struct file *filp);
static int affs_file_release(struct inode *inode, struct file *filp);
@@ -332,7 +330,7 @@ err_bread:
}
static int
-affs_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create)
+affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
{
struct super_block *sb = inode->i_sb;
struct buffer_head *ext_bh;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 6bdc3d358..2a1a29b93 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -202,8 +202,6 @@ static void autofs4_dentry_release(struct dentry *de)
{
struct autofs_info *inf;
- lock_kernel();
-
DPRINTK(("autofs4_dentry_release: releasing %p\n", de));
inf = autofs4_dentry_ino(de);
@@ -215,8 +213,6 @@ static void autofs4_dentry_release(struct dentry *de)
autofs4_free_ino(inf);
}
-
- unlock_kernel();
}
/* For dentries of directories in the root dir */
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index d7a284392..bb301b44e 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -54,7 +54,7 @@ static int bfs_move_blocks(kdev_t dev, unsigned long start, unsigned long end,
return 0;
}
-static int bfs_get_block(struct inode * inode, long block,
+static int bfs_get_block(struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create)
{
long phys;
diff --git a/fs/bio.c b/fs/bio.c
new file mode 100644
index 000000000..f2e5fb160
--- /dev/null
+++ b/fs/bio.c
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
+ *
+ */
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/iobuf.h>
+#include <linux/blk.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/prefetch.h>
+#include <linux/compiler.h>
+
+#include <asm/uaccess.h>
+
+kmem_cache_t *bio_cachep;
+static spinlock_t __cacheline_aligned bio_lock = SPIN_LOCK_UNLOCKED;
+static struct bio *bio_pool;
+static DECLARE_WAIT_QUEUE_HEAD(bio_pool_wait);
+static DECLARE_WAIT_QUEUE_HEAD(biovec_pool_wait);
+
+static unsigned int bio_pool_free;
+
+#define BIOVEC_NR_POOLS 6
+
+struct biovec_pool {
+ int bp_size;
+ kmem_cache_t *bp_cachep;
+};
+
+static struct biovec_pool bvec_list[BIOVEC_NR_POOLS];
+
+/*
+ * if you change this list, also change bvec_alloc or things will
+ * break badly!
+ */
+static const int bvec_pool_sizes[BIOVEC_NR_POOLS] = { 1, 4, 16, 64, 128, 256 };
+
+#define BIO_MAX_PAGES (bvec_pool_sizes[BIOVEC_NR_POOLS - 1])
+
+/*
+ * TODO: change this to use slab reservation scheme once that infrastructure
+ * is in place...
+ */
+#define BIO_POOL_SIZE (256)
+
+/*
+ * if need be, add bio_pool_get_irq() to match...
+ */
+static inline struct bio *__bio_pool_get(void)
+{
+ struct bio *bio;
+
+ if ((bio = bio_pool)) {
+ BIO_BUG_ON(bio_pool_free <= 0);
+ bio_pool = bio->bi_next;
+ bio->bi_next = NULL;
+ bio_pool_free--;
+ }
+
+ return bio;
+}
+
+static inline struct bio *bio_pool_get(void)
+{
+ unsigned long flags;
+ struct bio *bio;
+
+ spin_lock_irqsave(&bio_lock, flags);
+ bio = __bio_pool_get();
+ BIO_BUG_ON(!bio && bio_pool_free);
+ spin_unlock_irqrestore(&bio_lock, flags);
+
+ return bio;
+}
+
+static inline void bio_pool_put(struct bio *bio)
+{
+ unsigned long flags;
+ int wake_pool = 0;
+
+ spin_lock_irqsave(&bio_lock, flags);
+
+ /*
+ * if the pool has enough free entries, just slab free the bio
+ */
+ if (bio_pool_free < BIO_POOL_SIZE) {
+ bio->bi_next = bio_pool;
+ bio_pool = bio;
+ bio_pool_free++;
+ wake_pool = waitqueue_active(&bio_pool_wait);
+ spin_unlock_irqrestore(&bio_lock, flags);
+
+ if (wake_pool)
+ wake_up_nr(&bio_pool_wait, 1);
+ } else {
+ spin_unlock_irqrestore(&bio_lock, flags);
+ kmem_cache_free(bio_cachep, bio);
+ }
+}
+
+#define BIO_CAN_WAIT(gfp_mask) ((gfp_mask) & __GFP_WAIT)
+
+static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, int *idx)
+{
+ struct bio_vec *bvl = NULL;
+ struct biovec_pool *bp;
+
+ /*
+ * see comment near bvec_pool_sizes define!
+ */
+ switch (nr) {
+ case 1:
+ *idx = 0;
+ break;
+ case 2 ... 4:
+ *idx = 1;
+ break;
+ case 5 ... 16:
+ *idx = 2;
+ break;
+ case 17 ... 64:
+ *idx = 3;
+ break;
+ case 65 ... 128:
+ *idx = 4;
+ break;
+ case 129 ... 256:
+ *idx = 5;
+ break;
+ default:
+ return NULL;
+ }
+ bp = &bvec_list[*idx];
+
+ /*
+ * ok, so idx now points to the slab we want to allocate from
+ */
+ if ((bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask)))
+ goto out_gotit;
+
+ if (!BIO_CAN_WAIT(gfp_mask))
+ return NULL;
+
+ do {
+ bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask);
+ if (bvl)
+ break;
+
+ run_task_queue(&tq_disk);
+ __set_current_state(TASK_RUNNING);
+ current->policy |= SCHED_YIELD;
+ schedule();
+ } while (1);
+
+out_gotit:
+ memset(bvl, 0, bp->bp_size);
+ return bvl;
+}
+
+/*
+ * default destructor for a bio allocated with bio_alloc()
+ */
+void bio_destructor(struct bio *bio)
+{
+ struct biovec_pool *bp = &bvec_list[bio->bi_max];
+
+ BIO_BUG_ON(bio->bi_max >= BIOVEC_NR_POOLS);
+
+ /*
+ * cloned bio doesn't own the veclist
+ */
+ if (!(bio->bi_flags & (1 << BIO_CLONED)))
+ kmem_cache_free(bp->bp_cachep, bio->bi_io_vec);
+
+ bio_pool_put(bio);
+}
+
+inline void bio_init(struct bio *bio)
+{
+ bio->bi_next = NULL;
+ bio->bi_flags = 0;
+ bio->bi_rw = 0;
+ bio->bi_vcnt = 0;
+ bio->bi_idx = 0;
+ bio->bi_size = 0;
+ bio->bi_end_io = NULL;
+ atomic_set(&bio->bi_cnt, 1);
+}
+
+static inline struct bio *__bio_alloc(int gfp_mask, bio_destructor_t *dest)
+{
+ struct bio *bio;
+
+ /*
+ * first try our reserved pool
+ */
+ if ((bio = bio_pool_get()))
+ goto gotit;
+
+ /*
+ * no such luck, try slab alloc
+ */
+ if ((bio = kmem_cache_alloc(bio_cachep, gfp_mask)))
+ goto gotit;
+
+ /*
+ * hrmpf, not much luck. if we are allowed to wait, wait on
+ * bio_pool to be replenished
+ */
+ if (BIO_CAN_WAIT(gfp_mask)) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue_exclusive(&bio_pool_wait, &wait);
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if ((bio = bio_pool_get()))
+ break;
+
+ run_task_queue(&tq_disk);
+ schedule();
+ }
+ remove_wait_queue(&bio_pool_wait, &wait);
+ __set_current_state(TASK_RUNNING);
+ }
+
+ if (bio) {
+gotit:
+ bio_init(bio);
+ bio->bi_io_vec = NULL;
+ bio->bi_destructor = dest;
+ }
+
+ return bio;
+}
+
+/**
+ * bio_alloc - allocate a bio for I/O
+ * @gfp_mask: the GFP_ mask given to the slab allocator
+ * @nr_iovecs: number of iovecs to pre-allocate
+ *
+ * Description:
+ * bio_alloc will first try it's on internal pool to satisfy the allocation
+ * and if that fails fall back to the bio slab cache. In the latter case,
+ * the @gfp_mask specifies the priority of the allocation. In particular,
+ * if %__GFP_WAIT is set then we will block on the internal pool waiting
+ * for a &struct bio to become free.
+ **/
+struct bio *bio_alloc(int gfp_mask, int nr_iovecs)
+{
+ struct bio *bio = __bio_alloc(gfp_mask, bio_destructor);
+ struct bio_vec *bvl = NULL;
+
+ if (unlikely(!bio))
+ return NULL;
+
+ if (!nr_iovecs || (bvl = bvec_alloc(gfp_mask,nr_iovecs,&bio->bi_max))) {
+ bio->bi_io_vec = bvl;
+ return bio;
+ }
+
+ bio_pool_put(bio);
+ return NULL;
+}
+
+/*
+ * queue lock assumed held!
+ */
+static inline void bio_free(struct bio *bio)
+{
+ bio->bi_next = NULL;
+ bio->bi_destructor(bio);
+}
+
+/**
+ * bio_put - release a reference to a bio
+ * @bio: bio to release reference to
+ *
+ * Description:
+ * Put a reference to a &struct bio, either one you have gotten with
+ * bio_alloc or bio_get. The last put of a bio will free it.
+ **/
+void bio_put(struct bio *bio)
+{
+ BIO_BUG_ON(!atomic_read(&bio->bi_cnt));
+
+ /*
+ * last put frees it
+ */
+ if (atomic_dec_and_test(&bio->bi_cnt))
+ bio_free(bio);
+}
+
+/**
+ * __bio_clone - clone a bio
+ * @bio: destination bio
+ * @bio_src: bio to clone
+ *
+ * Clone a &bio. Caller will own the returned bio, but not
+ * the actual data it points to. Reference count of returned
+ * bio will be one.
+ */
+inline void __bio_clone(struct bio *bio, struct bio *bio_src)
+{
+ bio->bi_io_vec = bio_src->bi_io_vec;
+
+ bio->bi_sector = bio_src->bi_sector;
+ bio->bi_dev = bio_src->bi_dev;
+ bio->bi_flags |= 1 << BIO_CLONED;
+ bio->bi_rw = bio_src->bi_rw;
+
+ /*
+ * notes -- maybe just leave bi_idx alone. bi_max has no used
+ * on a cloned bio
+ */
+ bio->bi_vcnt = bio_src->bi_vcnt;
+ bio->bi_idx = bio_src->bi_idx;
+ bio->bi_size = bio_src->bi_size;
+ bio->bi_max = bio_src->bi_max;
+}
+
+/**
+ * bio_clone - clone a bio
+ * @bio: bio to clone
+ * @gfp_mask: allocation priority
+ *
+ * Like __bio_clone, only also allocates the returned bio
+ */
+struct bio *bio_clone(struct bio *bio, int gfp_mask)
+{
+ struct bio *b = bio_alloc(gfp_mask, 0);
+
+ if (b)
+ __bio_clone(b, bio);
+
+ return b;
+}
+
+/**
+ * bio_copy - create copy of a bio
+ * @bio: bio to copy
+ * @gfp_mask: allocation priority
+ * @copy: copy data to allocated bio
+ *
+ * Create a copy of a &bio. Caller will own the returned bio and
+ * the actual data it points to. Reference count of returned
+ * bio will be one.
+ */
+struct bio *bio_copy(struct bio *bio, int gfp_mask, int copy)
+{
+ struct bio *b = bio_alloc(gfp_mask, bio->bi_vcnt);
+ unsigned long flags = 0; /* gcc silly */
+ int i;
+
+ if (b) {
+ struct bio_vec *bv;
+
+ /*
+ * iterate iovec list and alloc pages + copy data
+ */
+ __bio_for_each_segment(bv, bio, i, 0) {
+ struct bio_vec *bbv = &b->bi_io_vec[i];
+ char *vfrom, *vto;
+
+ bbv->bv_page = alloc_page(gfp_mask);
+ if (bbv->bv_page == NULL)
+ goto oom;
+
+ if (!copy)
+ goto fill_in;
+
+ if (gfp_mask & __GFP_WAIT) {
+ vfrom = kmap(bv->bv_page);
+ vto = kmap(bbv->bv_page);
+ } else {
+ local_irq_save(flags);
+ vfrom = kmap_atomic(bv->bv_page, KM_BIO_IRQ);
+ vto = kmap_atomic(bbv->bv_page, KM_BIO_IRQ);
+ }
+
+ memcpy(vto + bbv->bv_offset, vfrom + bv->bv_offset, bv->bv_len);
+ if (gfp_mask & __GFP_WAIT) {
+ kunmap(bbv->bv_page);
+ kunmap(bv->bv_page);
+ } else {
+ kunmap_atomic(vto, KM_BIO_IRQ);
+ kunmap_atomic(vfrom, KM_BIO_IRQ);
+ local_irq_restore(flags);
+ }
+
+fill_in:
+ bbv->bv_len = bv->bv_len;
+ bbv->bv_offset = bv->bv_offset;
+ }
+
+ b->bi_sector = bio->bi_sector;
+ b->bi_dev = bio->bi_dev;
+ b->bi_rw = bio->bi_rw;
+
+ b->bi_vcnt = bio->bi_vcnt;
+ b->bi_size = bio->bi_size;
+ }
+
+ return b;
+
+oom:
+ while (--i >= 0)
+ __free_page(b->bi_io_vec[i].bv_page);
+
+ bio_pool_put(b);
+ return NULL;
+}
+
+#ifdef BIO_PAGEIO
+static int bio_end_io_page(struct bio *bio)
+{
+ struct page *page = bio_page(bio);
+
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ SetPageError(page);
+ if (!PageError(page))
+ SetPageUptodate(page);
+
+ /*
+ * Run the hooks that have to be done when a page I/O has completed.
+ */
+ if (PageTestandClearDecrAfter(page))
+ atomic_dec(&nr_async_pages);
+
+ UnlockPage(page);
+ bio_put(bio);
+ return 1;
+}
+#endif
+
+static int bio_end_io_kio(struct bio *bio, int nr_sectors)
+{
+ struct kiobuf *kio = (struct kiobuf *) bio->bi_private;
+
+ end_kio_request(kio, test_bit(BIO_UPTODATE, &bio->bi_flags));
+ bio_put(bio);
+ return 0;
+}
+
+/*
+ * obviously doesn't work for stacking drivers, but ll_rw_blk will split
+ * bio for those
+ */
+int get_max_segments(kdev_t dev)
+{
+ int segments = MAX_SEGMENTS;
+ request_queue_t *q;
+
+ if ((q = blk_get_queue(dev)))
+ segments = q->max_segments;
+
+ return segments;
+}
+
+int get_max_sectors(kdev_t dev)
+{
+ int sectors = MAX_SECTORS;
+ request_queue_t *q;
+
+ if ((q = blk_get_queue(dev)))
+ sectors = q->max_sectors;
+
+ return sectors;
+}
+
+/**
+ * ll_rw_kio - submit a &struct kiobuf for I/O
+ * @rw: %READ or %WRITE
+ * @kio: the kiobuf to do I/O on
+ * @dev: target device
+ * @sector: start location on disk
+ *
+ * Description:
+ * ll_rw_kio will map the page list inside the &struct kiobuf to
+ * &struct bio and queue them for I/O. The kiobuf given must describe
+ * a continous range of data, and must be fully prepared for I/O.
+ **/
+void ll_rw_kio(int rw, struct kiobuf *kio, kdev_t dev, sector_t sector)
+{
+ int i, offset, size, err, map_i, total_nr_pages, nr_pages;
+ int max_bytes, max_segments;
+ struct bio_vec *bvec;
+ struct bio *bio;
+
+ err = 0;
+ if ((rw & WRITE) && is_read_only(dev)) {
+ printk("ll_rw_bio: WRITE to ro device %s\n", kdevname(dev));
+ err = -EPERM;
+ goto out;
+ }
+
+ if (!kio->nr_pages) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * rudimentary max sectors/segments checks and setup. once we are
+ * sure that drivers can handle requests that cannot be completed in
+ * one go this will die
+ */
+ max_bytes = get_max_sectors(dev) << 9;
+ max_segments = get_max_segments(dev);
+ if ((max_bytes >> PAGE_SHIFT) < (max_segments + 1))
+ max_segments = (max_bytes >> PAGE_SHIFT);
+
+ if (max_segments > BIO_MAX_PAGES)
+ max_segments = BIO_MAX_PAGES;
+
+ /*
+ * maybe kio is bigger than the max we can easily map into a bio.
+ * if so, split it up in appropriately sized chunks.
+ */
+ total_nr_pages = kio->nr_pages;
+ offset = kio->offset & ~PAGE_MASK;
+ size = kio->length;
+
+ atomic_set(&kio->io_count, 1);
+
+ map_i = 0;
+
+next_chunk:
+ atomic_inc(&kio->io_count);
+ if ((nr_pages = total_nr_pages) > max_segments)
+ nr_pages = max_segments;
+
+ /*
+ * allocate bio and do initial setup
+ */
+ if ((bio = bio_alloc(GFP_NOIO, nr_pages)) == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ bio->bi_sector = sector;
+ bio->bi_dev = dev;
+ bio->bi_idx = 0;
+ bio->bi_end_io = bio_end_io_kio;
+ bio->bi_private = kio;
+
+ bvec = bio->bi_io_vec;
+ for (i = 0; i < nr_pages; i++, bvec++, map_i++) {
+ int nbytes = PAGE_SIZE - offset;
+
+ if (nbytes > size)
+ nbytes = size;
+
+ BUG_ON(kio->maplist[map_i] == NULL);
+
+ if (bio->bi_size + nbytes > max_bytes)
+ goto queue_io;
+
+ bio->bi_vcnt++;
+ bio->bi_size += nbytes;
+
+ bvec->bv_page = kio->maplist[map_i];
+ bvec->bv_len = nbytes;
+ bvec->bv_offset = offset;
+
+ /*
+ * kiobuf only has an offset into the first page
+ */
+ offset = 0;
+
+ sector += nbytes >> 9;
+ size -= nbytes;
+ total_nr_pages--;
+ kio->offset += nbytes;
+ }
+
+queue_io:
+ if (bio->bi_vcnt > 1)
+ bio->bi_flags |= 1 << BIO_PREBUILT;
+
+ submit_bio(rw, bio);
+
+ if (total_nr_pages)
+ goto next_chunk;
+
+ if (size) {
+ printk("ll_rw_kio: size %d left (kio %d)\n", size, kio->length);
+ BUG();
+ }
+
+out:
+ if (err)
+ kio->errno = err;
+
+ /*
+ * final atomic_dec of io_count to match our initial setting of 1.
+ * I/O may or may not have completed at this point, final completion
+ * handler is only run on last decrement.
+ */
+ end_kio_request(kio, !err);
+}
+
+int bio_endio(struct bio *bio, int uptodate, int nr_sectors)
+{
+ if (uptodate)
+ set_bit(BIO_UPTODATE, &bio->bi_flags);
+ else
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
+
+ return bio->bi_end_io(bio, nr_sectors);
+}
+
+static int __init bio_init_pool(void)
+{
+ struct bio *bio;
+ int i;
+
+ for (i = 0; i < BIO_POOL_SIZE; i++) {
+ bio = kmem_cache_alloc(bio_cachep, GFP_ATOMIC);
+ if (!bio)
+ panic("bio: cannot init bio pool\n");
+
+ bio_pool_put(bio);
+ }
+
+ return i;
+}
+
+static void __init biovec_init_pool(void)
+{
+ char name[16];
+ int i, size;
+
+ memset(&bvec_list, 0, sizeof(bvec_list));
+
+ for (i = 0; i < BIOVEC_NR_POOLS; i++) {
+ struct biovec_pool *bp = &bvec_list[i];
+
+ size = bvec_pool_sizes[i] * sizeof(struct bio_vec);
+
+ printk("biovec: init pool %d, %d entries, %d bytes\n", i,
+ bvec_pool_sizes[i], size);
+
+ snprintf(name, sizeof(name) - 1,"biovec-%d",bvec_pool_sizes[i]);
+ bp->bp_cachep = kmem_cache_create(name, size, 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+ if (!bp->bp_cachep)
+ panic("biovec: can't init slab pools\n");
+
+ bp->bp_size = size;
+ }
+}
+
+static int __init init_bio(void)
+{
+ int nr;
+
+ bio_cachep = kmem_cache_create("bio", sizeof(struct bio), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!bio_cachep)
+ panic("bio: can't create bio_cachep slab cache\n");
+
+ nr = bio_init_pool();
+ printk("BIO: pool of %d setup, %ZuKb (%Zd bytes/bio)\n", nr, nr * sizeof(struct bio) >> 10, sizeof(struct bio));
+
+ biovec_init_pool();
+
+ return 0;
+}
+
+module_init(init_bio);
+
+EXPORT_SYMBOL(bio_alloc);
+EXPORT_SYMBOL(bio_put);
+EXPORT_SYMBOL(ll_rw_kio);
+EXPORT_SYMBOL(bio_endio);
+EXPORT_SYMBOL(bio_init);
+EXPORT_SYMBOL(bio_copy);
+EXPORT_SYMBOL(__bio_clone);
+EXPORT_SYMBOL(bio_clone);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 0563a901b..de4cb8afa 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -102,7 +102,7 @@ int set_blocksize(kdev_t dev, int size)
return 0;
}
-static int blkdev_get_block(struct inode * inode, long iblock, struct buffer_head * bh, int create)
+static int blkdev_get_block(struct inode * inode, sector_t iblock, struct buffer_head * bh, int create)
{
if (iblock >= max_block(inode->i_rdev))
return -EIO;
diff --git a/fs/buffer.c b/fs/buffer.c
index e9442ec38..5ede8005e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -47,6 +47,7 @@
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/completion.h>
+#include <linux/compiler.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -548,7 +549,7 @@ static void remove_from_queues(struct buffer_head *bh)
spin_unlock(&lru_list_lock);
}
-struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
+struct buffer_head * get_hash_table(kdev_t dev, sector_t block, int size)
{
struct buffer_head *bh, **p = &hash(dev, block);
@@ -793,9 +794,10 @@ still_busy:
return;
}
-inline void set_buffer_async_io(struct buffer_head *bh) {
- bh->b_end_io = end_buffer_io_async ;
- mark_buffer_async(bh, 1);
+inline void set_buffer_async_io(struct buffer_head *bh)
+{
+ bh->b_end_io = end_buffer_io_async;
+ mark_buffer_async(bh, 1);
}
/*
@@ -1014,7 +1016,7 @@ void invalidate_inode_buffers(struct inode *inode)
* 14.02.92: changed it to sync dirty buffers a bit: better performance
* when the filesystem starts to get full of dirty blocks (I hope).
*/
-struct buffer_head * getblk(kdev_t dev, int block, int size)
+struct buffer_head * getblk(kdev_t dev, sector_t block, int size)
{
for (;;) {
struct buffer_head * bh;
@@ -1035,8 +1037,7 @@ static int balance_dirty_state(void)
{
unsigned long dirty, tot, hard_dirty_limit, soft_dirty_limit;
- dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
- dirty += size_buffers_type[BUF_LOCKED] >> PAGE_SHIFT;
+ dirty = (size_buffers_type[BUF_DIRTY] + size_buffers_type[BUF_LOCKED]) >> PAGE_SHIFT;
tot = nr_free_buffer_pages();
dirty *= 100;
@@ -1989,7 +1990,8 @@ done:
goto done;
}
-int generic_block_bmap(struct address_space *mapping, long block, get_block_t *get_block)
+sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
+ get_block_t *get_block)
{
struct buffer_head tmp;
struct inode *inode = mapping->host;
@@ -2002,7 +2004,7 @@ int generic_block_bmap(struct address_space *mapping, long block, get_block_t *g
int generic_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsigned long blocknr, int blocksize, get_block_t * get_block)
{
int i, nr_blocks, retval;
- unsigned long * blocks = iobuf->blocks;
+ sector_t *blocks = iobuf->blocks;
nr_blocks = iobuf->length / blocksize;
/* build the blocklist */
@@ -2013,7 +2015,7 @@ int generic_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsig
bh.b_dev = inode->i_dev;
bh.b_size = blocksize;
- retval = get_block(inode, blocknr, &bh, rw == READ ? 0 : 1);
+ retval = get_block(inode, blocknr, &bh, rw & 1);
if (retval)
goto out;
@@ -2034,64 +2036,13 @@ int generic_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsig
blocks[i] = bh.b_blocknr;
}
- retval = brw_kiovec(rw, 1, &iobuf, inode->i_dev, iobuf->blocks, blocksize);
+ retval = brw_kiovec(rw, 1, &iobuf, inode->i_dev, blocks, blocksize);
out:
return retval;
}
/*
- * IO completion routine for a buffer_head being used for kiobuf IO: we
- * can't dispatch the kiobuf callback until io_count reaches 0.
- */
-
-static void end_buffer_io_kiobuf(struct buffer_head *bh, int uptodate)
-{
- struct kiobuf *kiobuf;
-
- mark_buffer_uptodate(bh, uptodate);
-
- kiobuf = bh->b_private;
- unlock_buffer(bh);
- end_kio_request(kiobuf, uptodate);
-}
-
-/*
- * For brw_kiovec: submit a set of buffer_head temporary IOs and wait
- * for them to complete. Clean up the buffer_heads afterwards.
- */
-
-static int wait_kio(int rw, int nr, struct buffer_head *bh[], int size)
-{
- int iosize, err;
- int i;
- struct buffer_head *tmp;
-
- iosize = 0;
- err = 0;
-
- for (i = nr; --i >= 0; ) {
- iosize += size;
- tmp = bh[i];
- if (buffer_locked(tmp)) {
- wait_on_buffer(tmp);
- }
-
- if (!buffer_uptodate(tmp)) {
- /* We are traversing bh'es in reverse order so
- clearing iosize on error calculates the
- amount of IO before the first error. */
- iosize = 0;
- err = -EIO;
- }
- }
-
- if (iosize)
- return iosize;
- return err;
-}
-
-/*
* Start I/O on a physical range of kernel memory, defined by a vector
* of kiobuf structs (much like a user-space iovec list).
*
@@ -2102,22 +2053,13 @@ static int wait_kio(int rw, int nr, struct buffer_head *bh[], int size)
* It is up to the caller to make sure that there are enough blocks
* passed in to completely map the iobufs to disk.
*/
-
-int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
- kdev_t dev, unsigned long b[], int size)
+int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], kdev_t dev, sector_t b[],
+ int size)
{
- int err;
- int length;
int transferred;
int i;
- int bufind;
- int pageind;
- int bhind;
- int offset;
- unsigned long blocknr;
- struct kiobuf * iobuf = NULL;
- struct page * map;
- struct buffer_head *tmp, **bhs = NULL;
+ int err;
+ struct kiobuf * iobuf;
if (!nr)
return 0;
@@ -2127,8 +2069,7 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
*/
for (i = 0; i < nr; i++) {
iobuf = iovec[i];
- if ((iobuf->offset & (size-1)) ||
- (iobuf->length & (size-1)))
+ if ((iobuf->offset & (size-1)) || (iobuf->length & (size-1)))
return -EINVAL;
if (!iobuf->nr_pages)
panic("brw_kiovec: iobuf not initialised");
@@ -2137,94 +2078,28 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
/*
* OK to walk down the iovec doing page IO on each page we find.
*/
- bufind = bhind = transferred = err = 0;
for (i = 0; i < nr; i++) {
iobuf = iovec[i];
- offset = iobuf->offset;
- length = iobuf->length;
iobuf->errno = 0;
- if (!bhs)
- bhs = iobuf->bh;
-
- for (pageind = 0; pageind < iobuf->nr_pages; pageind++) {
- map = iobuf->maplist[pageind];
- if (!map) {
- err = -EFAULT;
- goto finished;
- }
-
- while (length > 0) {
- blocknr = b[bufind++];
- if (blocknr == -1UL) {
- if (rw == READ) {
- /* there was an hole in the filesystem */
- memset(kmap(map) + offset, 0, size);
- flush_dcache_page(map);
- kunmap(map);
-
- transferred += size;
- goto skip_block;
- } else
- BUG();
- }
- tmp = bhs[bhind++];
-
- tmp->b_size = size;
- set_bh_page(tmp, map, offset);
- tmp->b_this_page = tmp;
-
- init_buffer(tmp, end_buffer_io_kiobuf, iobuf);
- tmp->b_dev = dev;
- tmp->b_blocknr = blocknr;
- tmp->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | (1 << BH_Req);
-
- if (rw == WRITE) {
- set_bit(BH_Uptodate, &tmp->b_state);
- clear_bit(BH_Dirty, &tmp->b_state);
- } else
- set_bit(BH_Uptodate, &tmp->b_state);
-
- atomic_inc(&iobuf->io_count);
- submit_bh(rw, tmp);
- /*
- * Wait for IO if we have got too much
- */
- if (bhind >= KIO_MAX_SECTORS) {
- kiobuf_wait_for_io(iobuf); /* wake-one */
- err = wait_kio(rw, bhind, bhs, size);
- if (err >= 0)
- transferred += err;
- else
- goto finished;
- bhind = 0;
- }
- skip_block:
- length -= size;
- offset += size;
+ ll_rw_kio(rw, iobuf, dev, b[i] * (size >> 9));
+ }
- if (offset >= PAGE_SIZE) {
- offset = 0;
- break;
- }
- } /* End of block loop */
- } /* End of page loop */
- } /* End of iovec loop */
-
- /* Is there any IO still left to submit? */
- if (bhind) {
- kiobuf_wait_for_io(iobuf); /* wake-one */
- err = wait_kio(rw, bhind, bhs, size);
- if (err >= 0)
- transferred += err;
- else
- goto finished;
+ /*
+ * now they are all submitted, wait for completion
+ */
+ transferred = 0;
+ err = 0;
+ for (i = 0; i < nr; i++) {
+ iobuf = iovec[i];
+ kiobuf_wait_for_io(iobuf);
+ if (iobuf->errno && !err)
+ err = iobuf->errno;
+ if (!err)
+ transferred += iobuf->length;
}
- finished:
- if (transferred)
- return transferred;
- return err;
+ return err ? err : transferred;
}
/*
@@ -2239,7 +2114,7 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
* FIXME: we need a swapper_inode->get_block function to remove
* some of the bmap kludges and interface ugliness here.
*/
-int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size)
+int brw_page(int rw, struct page *page, kdev_t dev, sector_t b[], int size)
{
struct buffer_head *head, *bh;
@@ -2327,7 +2202,7 @@ static struct page * grow_dev_page(struct block_device *bdev, unsigned long inde
struct buffer_head *bh;
page = find_or_create_page(bdev->bd_inode->i_mapping, index, GFP_NOFS);
- if (IS_ERR(page))
+ if (!page)
return NULL;
if (!PageLocked(page))
@@ -2491,6 +2366,9 @@ int try_to_free_buffers(struct page * page, unsigned int gfp_mask)
{
struct buffer_head * tmp, * bh = page->buffers;
+ BUG_ON(!PageLocked(page));
+ BUG_ON(!bh);
+
cleaned_buffers_try_again:
spin_lock(&lru_list_lock);
write_lock(&hash_table_lock);
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 4fe0cc7b3..2eeb1b733 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -427,7 +427,7 @@
Work sponsored by SGI.
v0.92
20000306 Richard Gooch <rgooch@atnf.csiro.au>
- Added DEVFS_ FL_NO_PERSISTENCE flag.
+ Added DEVFS_FL_NO_PERSISTENCE flag.
Removed unnecessary call to <update_devfs_inode_from_entry> in
<devfs_readdir>.
Work sponsored by SGI.
@@ -562,23 +562,6 @@
20011122 Richard Gooch <rgooch@atnf.csiro.au>
Use slab cache rather than fixed buffer for devfsd events.
v1.1
- 20011125 Richard Gooch <rgooch@atnf.csiro.au>
- Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>.
- 20011127 Richard Gooch <rgooch@atnf.csiro.au>
- Fixed locking bug in <devfs_d_revalidate_wait> due to typo.
- Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from
- devfsd or children.
- v1.2
- 20011202 Richard Gooch <rgooch@atnf.csiro.au>
- Fixed bug in <devfsd_read>: was dereferencing freed pointer.
- v1.3
- 20011203 Richard Gooch <rgooch@atnf.csiro.au>
- Fixed bug in <devfsd_close>: was dereferencing freed pointer.
- Added process group check for devfsd privileges.
- v1.4
- 20011204 Richard Gooch <rgooch@atnf.csiro.au>
- Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>.
- v1.5
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -611,7 +594,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "1.5 (20011204)"
+#define DEVFS_VERSION "1.1 (20011122)"
#define DEVFS_NAME "devfs"
@@ -757,7 +740,6 @@ struct fs_info /* This structure is for the mounted devfs */
struct devfsd_buf_entry *devfsd_last_event;
volatile int devfsd_sleeping;
volatile struct task_struct *devfsd_task;
- volatile pid_t devfsd_pgrp;
volatile struct file *devfsd_file;
struct devfsd_notify_struct *devfsd_info;
volatile unsigned long devfsd_event_mask;
@@ -1333,14 +1315,10 @@ static int is_devfsd_or_child (struct fs_info *fs_info)
{
struct task_struct *p;
- if (current == fs_info->devfsd_task) return (TRUE);
- if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,1)
- for (p = current->p_opptr; p != &init_task; p = p->p_opptr)
+ for (p = current; p != &init_task; p = p->p_opptr)
{
if (p == fs_info->devfsd_task) return (TRUE);
}
-#endif
return (FALSE);
} /* End Function is_devfsd_or_child */
@@ -1397,16 +1375,13 @@ static int wait_for_devfsd_finished (struct fs_info *fs_info)
static int devfsd_notify_de (struct devfs_entry *de,
unsigned short type, umode_t mode,
- uid_t uid, gid_t gid, struct fs_info *fs_info,
- int atomic)
+ uid_t uid, gid_t gid, struct fs_info *fs_info)
{
struct devfsd_buf_entry *entry;
struct devfs_entry *curr;
if ( !( fs_info->devfsd_event_mask & (1 << type) ) ) return (FALSE);
- if ( ( entry = kmem_cache_alloc (devfsd_buf_cache,
- atomic ? SLAB_ATOMIC : SLAB_KERNEL) )
- == NULL )
+ if ( ( entry = kmem_cache_alloc (devfsd_buf_cache, 0) ) == NULL )
{
atomic_inc (&fs_info->devfsd_overrun_count);
return (FALSE);
@@ -1439,7 +1414,7 @@ static int devfsd_notify_de (struct devfs_entry *de,
static void devfsd_notify (struct devfs_entry *de,unsigned short type,int wait)
{
if (devfsd_notify_de (de, type, de->mode, current->euid,
- current->egid, &fs_info, 0) && wait)
+ current->egid, &fs_info) && wait)
wait_for_devfsd_finished (&fs_info);
} /* End Function devfsd_notify */
@@ -1789,7 +1764,6 @@ devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name, void *info)
printk ("%s: devfs_mk_dir(%s): de: %p dir: %p \"%s\"\n",
DEVFS_NAME, name, de, dir, dir->name);
#endif
- devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, 0);
devfs_put (dir);
return de;
} /* End Function devfs_mk_dir */
@@ -2295,7 +2269,7 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info,
buf->namelen = namelen;
buf->u.name = name;
if ( !devfsd_notify_de (buf, DEVFSD_NOTIFY_LOOKUP, 0,
- current->euid, current->egid, fs_info, 0) )
+ current->euid, current->egid, fs_info) )
return -ENOENT;
/* Possible success */
return 0;
@@ -2423,10 +2397,9 @@ static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr)
de->inode.atime = inode->i_atime;
de->inode.mtime = inode->i_mtime;
de->inode.ctime = inode->i_ctime;
- if ( ( iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID) ) &&
- !is_devfsd_or_child (fs_info) )
+ if ( iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_notify_change */
@@ -2664,9 +2637,9 @@ static int devfs_open (struct inode *inode, struct file *file)
inode->i_uid = current->euid;
inode->i_gid = current->egid;
}
- if ( df->aopen_notify && !is_devfsd_or_child (fs_info) )
+ if (df->aopen_notify)
devfsd_notify_de (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
- current->euid, current->egid, fs_info, 0);
+ current->euid, current->egid, fs_info);
return 0;
} /* End Function devfs_open */
@@ -2781,7 +2754,7 @@ static int devfs_d_delete (struct dentry *dentry)
de->u.fcb.open = FALSE;
if (de->u.fcb.aopen_notify)
devfsd_notify_de (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
- current->euid, current->egid, fs_info, 1);
+ current->euid, current->egid, fs_info);
if (!de->u.fcb.auto_owner) return 0;
/* Change the ownership/protection back */
inode->i_mode = (de->mode & S_IFMT) | S_IRUGO | S_IWUGO;
@@ -2809,7 +2782,7 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name,
dentry->d_name.len);
- read_unlock (&parent->u.dir.lock);
+ read_lock (&parent->u.dir.lock);
if (de == NULL) return 1;
/* Create an inode, now that the driver information is available */
inode = get_vfs_inode (dir->i_sb, de, dentry);
@@ -2832,13 +2805,14 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
{
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ struct fs_info *fs_info;
struct devfs_entry *parent, *de;
struct inode *inode;
/* Set up the dentry operations before anything else, to ensure cleaning
up on any error */
dentry->d_op = &devfs_dops;
+ fs_info = dir->i_sb->u.generic_sbp;
/* First try to get the devfs entry for this directory */
parent = get_devfs_entry_from_vfs_inode (dir);
#ifdef CONFIG_DEVFS_DEBUG
@@ -2923,7 +2897,6 @@ static int devfs_unlink (struct inode *dir, struct dentry *dentry)
int unhooked;
struct devfs_entry *de;
struct inode *inode = dentry->d_inode;
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_UNLINK)
@@ -2936,9 +2909,8 @@ static int devfs_unlink (struct inode *dir, struct dentry *dentry)
unhooked = _devfs_unhook (de);
write_unlock (&de->parent->u.dir.lock);
if (!unhooked) return -ENOENT;
- if ( !is_devfsd_or_child (fs_info) )
- devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
+ inode->i_uid, inode->i_gid, dir->i_sb->u.generic_sbp);
free_dentry (de);
devfs_put (de);
return 0;
@@ -2948,10 +2920,11 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry,
const char *symname)
{
int err;
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ struct fs_info *fs_info;
struct devfs_entry *parent, *de;
struct inode *inode;
+ fs_info = dir->i_sb->u.generic_sbp;
/* First try to get the devfs entry for this directory */
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
@@ -2977,20 +2950,20 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry,
DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
d_instantiate (dentry, inode);
- if ( !is_devfsd_or_child (fs_info) )
- devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_symlink */
static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
{
int err;
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ struct fs_info *fs_info;
struct devfs_entry *parent, *de;
struct inode *inode;
mode = (mode & ~S_IFMT) | S_IFDIR; /* VFS doesn't pass S_IFMT part */
+ fs_info = dir->i_sb->u.generic_sbp;
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
@@ -3011,9 +2984,8 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
d_instantiate (dentry, inode);
- if ( !is_devfsd_or_child (fs_info) )
- devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_mkdir */
@@ -3021,10 +2993,11 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
{
int err = 0;
struct devfs_entry *de;
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ struct fs_info *fs_info;
struct inode *inode = dentry->d_inode;
if (dir->i_sb->u.generic_sbp != inode->i_sb->u.generic_sbp) return -EINVAL;
+ fs_info = dir->i_sb->u.generic_sbp;
de = get_devfs_entry_from_vfs_inode (inode);
if (de == NULL) return -ENOENT;
if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
@@ -3040,9 +3013,8 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
if ( !_devfs_unhook (de) ) err = -ENOENT;
write_unlock (&de->parent->u.dir.lock);
if (err) return err;
- if ( !is_devfsd_or_child (fs_info) )
- devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
+ inode->i_uid, inode->i_gid, fs_info);
free_dentry (de);
devfs_put (de);
return 0;
@@ -3052,7 +3024,7 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
int rdev)
{
int err;
- struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ struct fs_info *fs_info;
struct devfs_entry *parent, *de;
struct inode *inode;
@@ -3061,6 +3033,7 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
printk ("%s: mknod(%s): mode: 0%o dev: %d\n",
DEVFS_NAME, dentry->d_name.name, mode, rdev);
#endif
+ fs_info = dir->i_sb->u.generic_sbp;
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
@@ -3086,9 +3059,8 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
d_instantiate (dentry, inode);
- if ( !is_devfsd_or_child (fs_info) )
- devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
- inode->i_uid, inode->i_gid, fs_info, 0);
+ devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_mknod */
@@ -3261,17 +3233,11 @@ static ssize_t devfsd_read (struct file *file, char *buf, size_t len,
tlen = rpos - *ppos;
if (done)
{
- devfs_handle_t parent;
-
spin_lock (&fs_info->devfsd_buffer_lock);
fs_info->devfsd_first_event = entry->next;
if (entry->next == NULL) fs_info->devfsd_last_event = NULL;
spin_unlock (&fs_info->devfsd_buffer_lock);
- for (; de != NULL; de = parent)
- {
- parent = de->parent;
- devfs_put (de);
- }
+ for (; de != NULL; de = de->parent) devfs_put (de);
kmem_cache_free (devfsd_buf_cache, entry);
if (ival > 0) atomic_sub (ival, &fs_info->devfsd_overrun_count);
*ppos = 0;
@@ -3308,8 +3274,6 @@ static int devfsd_ioctl (struct inode *inode, struct file *file,
}
fs_info->devfsd_task = current;
spin_unlock (&lock);
- fs_info->devfsd_pgrp = (current->pgrp == current->pid) ?
- current->pgrp : 0;
fs_info->devfsd_file = file;
fs_info->devfsd_info = kmalloc (sizeof *fs_info->devfsd_info,
GFP_KERNEL);
@@ -3340,7 +3304,7 @@ static int devfsd_ioctl (struct inode *inode, struct file *file,
static int devfsd_close (struct inode *inode, struct file *file)
{
- struct devfsd_buf_entry *entry, *next;
+ struct devfsd_buf_entry *entry;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
if (fs_info->devfsd_file != file) return 0;
@@ -3356,14 +3320,10 @@ static int devfsd_close (struct inode *inode, struct file *file)
fs_info->devfsd_info = NULL;
}
spin_unlock (&fs_info->devfsd_buffer_lock);
- fs_info->devfsd_pgrp = 0;
fs_info->devfsd_task = NULL;
wake_up (&fs_info->revalidate_wait_queue);
- for (; entry; entry = next)
- {
- next = entry->next;
+ for (; entry; entry = entry->next)
kmem_cache_free (devfsd_buf_cache, entry);
- }
return 0;
} /* End Function devfsd_close */
@@ -3398,6 +3358,9 @@ static int __init init_devfs_fs (void)
printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
#endif
printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
+ devfsd_buf_cache = kmem_cache_create ("devfsd_event",
+ sizeof (struct devfsd_buf_entry),
+ 0, 0, NULL, NULL);
err = register_filesystem (&devfs_fs_type);
if (!err)
{
@@ -3412,9 +3375,6 @@ void __init mount_devfs_fs (void)
{
int err;
- devfsd_buf_cache = kmem_cache_create ("devfsd_event",
- sizeof (struct devfsd_buf_entry),
- 0, 0, NULL, NULL);
if ( !(boot_options & OPTION_MOUNT) ) return;
err = do_mount ("none", "/dev", "devfs", 0, "");
if (err == 0) printk ("Mounted devfs on /dev\n");
diff --git a/fs/driverfs/Makefile b/fs/driverfs/Makefile
new file mode 100644
index 000000000..1fd66308f
--- /dev/null
+++ b/fs/driverfs/Makefile
@@ -0,0 +1,8 @@
+O_TARGET := driverfs.o
+
+export-objs := inode.o
+
+obj-y := inode.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
new file mode 100644
index 000000000..1a37b2286
--- /dev/null
+++ b/fs/driverfs/inode.c
@@ -0,0 +1,822 @@
+/*
+ * driverfs.c - The device driver file system
+ *
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This is a simple, ram-based filesystem, which allows kernel
+ * callbacks for read/write of files.
+ *
+ * Please see Documentation/filesystems/driverfs.txt for more information.
+ */
+
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/driverfs_fs.h>
+
+#include <asm/uaccess.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+# define DBG(x...) printk(x)
+#else
+# define DBG(x...)
+#endif
+
+/* Random magic number */
+#define DRIVERFS_MAGIC 0x42454552
+
+static struct super_operations driverfs_ops;
+static struct address_space_operations driverfs_aops;
+static struct file_operations driverfs_dir_operations;
+static struct file_operations driverfs_file_operations;
+static struct inode_operations driverfs_dir_inode_operations;
+static struct dentry_operations driverfs_dentry_dir_ops;
+static struct dentry_operations driverfs_dentry_file_ops;
+
+
+static struct vfsmount *driverfs_mount;
+static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
+static int mount_count = 0;
+
+static int driverfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+ buf->f_type = DRIVERFS_MAGIC;
+ buf->f_bsize = PAGE_CACHE_SIZE;
+ buf->f_namelen = 255;
+ return 0;
+}
+
+static struct dentry *driverfs_lookup(struct inode *dir, struct dentry *dentry)
+{
+ d_add(dentry, NULL);
+ return NULL;
+}
+
+struct inode *driverfs_get_inode(struct super_block *sb, int mode, int dev)
+{
+ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_rdev = NODEV;
+ inode->i_mapping->a_ops = &driverfs_aops;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ switch (mode & S_IFMT) {
+ default:
+ init_special_inode(inode, mode, dev);
+ break;
+ case S_IFREG:
+ inode->i_fop = &driverfs_file_operations;
+ break;
+ case S_IFDIR:
+ inode->i_op = &driverfs_dir_inode_operations;
+ inode->i_fop = &driverfs_dir_operations;
+ break;
+ }
+ }
+ return inode;
+}
+
+static int driverfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+ struct inode *inode = driverfs_get_inode(dir->i_sb, mode, dev);
+ int error = -ENOSPC;
+
+ if (inode) {
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ }
+ return error;
+}
+
+static int driverfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ dentry->d_op = &driverfs_dentry_dir_ops;
+ return driverfs_mknod(dir, dentry, mode | S_IFDIR, 0);
+}
+
+static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+ dentry->d_op = &driverfs_dentry_file_ops;
+ return driverfs_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+static int
+driverfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+
+ if(S_ISDIR(inode->i_mode))
+ return -EPERM;
+
+ inode->i_nlink++;
+ atomic_inc(&inode->i_count);
+ dget(dentry);
+ d_instantiate(dentry, inode);
+ return 0;
+}
+
+static inline int driverfs_positive(struct dentry *dentry)
+{
+ return (dentry->d_inode && !d_unhashed(dentry));
+}
+
+static int driverfs_empty(struct dentry *dentry)
+{
+ struct list_head *list;
+
+ spin_lock(&dcache_lock);
+
+ list_for_each(list, &dentry->d_subdirs) {
+ struct dentry *de = list_entry(list, struct dentry, d_child);
+ if (driverfs_positive(de)) {
+ spin_unlock(&dcache_lock);
+ return 0;
+ }
+ }
+
+ spin_unlock(&dcache_lock);
+ return 1;
+}
+
+static int driverfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ int error = -ENOTEMPTY;
+
+ if (driverfs_empty(dentry)) {
+ struct inode *inode = dentry->d_inode;
+
+ inode->i_nlink--;
+ dput(dentry);
+ error = 0;
+ }
+ return error;
+}
+
+static int
+driverfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ int error = -ENOTEMPTY;
+
+ if (driverfs_empty(new_dentry)) {
+ struct inode *inode = new_dentry->d_inode;
+ if (inode) {
+ inode->i_nlink--;
+ dput(new_dentry);
+ }
+ error = 0;
+ }
+ return error;
+}
+
+static int driverfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+ int error;
+
+ error = driverfs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
+ if (!error) {
+ int l = strlen(symname) + 1;
+ struct inode *inode = dentry->d_inode;
+ error = block_symlink(inode,symname,l);
+ }
+ return error;
+}
+
+#define driverfs_rmdir driverfs_unlink
+
+/**
+ * driverfs_read_file - "read" data from a file.
+ * @file: file pointer
+ * @buf: buffer to fill
+ * @count: number of bytes to read
+ * @ppos: starting offset in file
+ *
+ * Userspace wants data from a file. It is up to the creator of the file to
+ * provide that data.
+ * There is a struct driver_file_entry embedded in file->private_data. We
+ * obtain that and check if the read callback is implemented. If so, we call
+ * it, passing the data field of the file entry.
+ * Said callback is responsible for filling the buffer and returning the number
+ * of bytes it put in it. We update @ppos correctly.
+ */
+static ssize_t
+driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct driver_file_entry * entry;
+ unsigned char *page;
+ ssize_t retval = 0;
+
+ entry = (struct driver_file_entry *)file->private_data;
+ if (!entry) {
+ DBG("%s: file entry is NULL\n",__FUNCTION__);
+ return -ENOENT;
+ }
+
+ if (!entry->ops || !entry->ops->read) {
+ DBG("%s: no read callback\n",__FUNCTION__);
+ return -ENOENT;
+ }
+
+ page = (unsigned char*)__get_free_page(GFP_KERNEL);
+ if (!page) {
+ retval = -ENOMEM;
+ goto done;
+ }
+
+ while (count > 0) {
+ ssize_t len;
+
+ len = entry->ops->read(page,count,*ppos,entry->data);
+
+ if (len <= 0) {
+ if (len < 0)
+ retval = len;
+ break;
+ }
+
+ if (copy_to_user(buf,page,len)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ *ppos += len;
+ count -= len;
+ buf += len;
+ retval += len;
+ }
+ free_page((unsigned long)page);
+
+ done:
+ return retval;
+}
+
+/**
+ * driverfs_write_file - "write" to a file
+ * @file: file pointer
+ * @buf: data to write
+ * @count: number of bytes
+ * @ppos: starting offset
+ *
+ * Similarly to driverfs_read_file, we act essentially as a bit pipe.
+ * We check for a "write" callback in file->private_data, and pass
+ * @buffer, @count, @ppos, and the file entry's data to the callback.
+ * The number of bytes written is returned, and we handle updating
+ * @ppos properly.
+ */
+static ssize_t
+driverfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ struct driver_file_entry * entry;
+ ssize_t retval = 0;
+
+ entry = (struct driver_file_entry *)file->private_data;
+ if (!entry) {
+ DBG("%s: file entry is NULL\n",__FUNCTION__);
+ return -ENOENT;
+ }
+
+ if (!entry->ops || !entry->ops->write) {
+ DBG("%s: no write callback\n",__FUNCTION__);
+ retval = -ENOENT;
+ goto done;
+ }
+
+ while (count > 0) {
+ ssize_t len;
+
+ len = entry->ops->write(buf,count,*ppos,entry->data);
+
+ if (len <= 0) {
+ if (len < 0)
+ retval = len;
+ break;
+ }
+ retval += len;
+ count -= len;
+ *ppos += len;
+ buf += len;
+ }
+
+ done:
+ return retval;
+}
+
+static loff_t
+driverfs_file_lseek(struct file *file, loff_t offset, int orig)
+{
+ loff_t retval = -EINVAL;
+
+ switch(orig) {
+ case 0:
+ if (offset > 0) {
+ file->f_pos = offset;
+ retval = file->f_pos;
+ }
+ break;
+ case 1:
+ if ((offset + file->f_pos) > 0) {
+ file->f_pos += offset;
+ retval = file->f_pos;
+ }
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+static int driverfs_open_file(struct inode * inode, struct file * filp)
+{
+ if (filp && inode)
+ filp->private_data = inode->u.generic_ip;
+
+ return 0;
+}
+
+static int driverfs_sync_file (struct file *file, struct dentry *dentry, int datasync)
+{
+ return 0;
+}
+
+/* When the dentry goes away (the refcount hits 0), free the
+ * driver_file_entry for it.
+ */
+static int driverfs_d_delete_file (struct dentry * dentry)
+{
+ struct driver_file_entry * entry;
+
+ entry = (struct driver_file_entry *)dentry->d_fsdata;
+ if (entry)
+ kfree(dentry);
+ return 0;
+}
+
+/* Similar to above - if this dentry goes away, free the
+ * driver_dir_entry associated with it..
+ */
+static int driverfs_d_delete_dir (struct dentry * dentry)
+{
+ struct driver_dir_entry * entry;
+ entry = (struct driver_dir_entry *)dentry->d_fsdata;
+ if (entry)
+ kfree(entry);
+ return 0;
+}
+
+static struct address_space_operations driverfs_aops = {
+
+};
+
+static struct file_operations driverfs_file_operations = {
+ read: driverfs_read_file,
+ write: driverfs_write_file,
+ llseek: driverfs_file_lseek,
+ mmap: generic_file_mmap,
+ open: driverfs_open_file,
+ fsync: driverfs_sync_file,
+};
+
+static struct file_operations driverfs_dir_operations = {
+ read: generic_read_dir,
+ readdir: dcache_readdir,
+ fsync: driverfs_sync_file,
+};
+
+static struct inode_operations driverfs_dir_inode_operations = {
+ create: driverfs_create,
+ lookup: driverfs_lookup,
+ link: driverfs_link,
+ unlink: driverfs_unlink,
+ symlink: driverfs_symlink,
+ mkdir: driverfs_mkdir,
+ rmdir: driverfs_rmdir,
+ mknod: driverfs_mknod,
+ rename: driverfs_rename,
+};
+
+static struct dentry_operations driverfs_dentry_file_ops = {
+ d_delete: driverfs_d_delete_file,
+};
+
+static struct dentry_operations driverfs_dentry_dir_ops = {
+ d_delete: driverfs_d_delete_dir,
+};
+
+static struct super_operations driverfs_ops = {
+ statfs: driverfs_statfs,
+ put_inode: force_delete,
+};
+
+static struct super_block*
+driverfs_read_super(struct super_block *sb, void *data, int silent)
+{
+ struct inode *inode;
+ struct dentry *root;
+
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = DRIVERFS_MAGIC;
+ sb->s_op = &driverfs_ops;
+ inode = driverfs_get_inode(sb, S_IFDIR | 0755, 0);
+
+ if (!inode) {
+ DBG("%s: could not get inode!\n",__FUNCTION__);
+ return NULL;
+ }
+
+ root = d_alloc_root(inode);
+ if (!root) {
+ DBG("%s: could not get root dentry!\n",__FUNCTION__);
+ iput(inode);
+ return NULL;
+ }
+ sb->s_root = root;
+ return sb;
+}
+
+static DECLARE_FSTYPE(driverfs_fs_type, "driverfs", driverfs_read_super, FS_SINGLE | FS_LITTER);
+
+static int get_mount(void)
+{
+ struct vfsmount * mnt;
+
+ spin_lock(&mount_lock);
+ if (driverfs_mount) {
+ mntget(driverfs_mount);
+ ++mount_count;
+ spin_unlock(&mount_lock);
+ goto go_ahead;
+ }
+
+ spin_unlock(&mount_lock);
+ mnt = kern_mount(&driverfs_fs_type);
+
+ if (IS_ERR(mnt)) {
+ printk(KERN_ERR "driverfs: could not mount!\n");
+ return -ENODEV;
+ }
+
+ spin_lock(&mount_lock);
+ if (!driverfs_mount) {
+ driverfs_mount = mnt;
+ ++mount_count;
+ spin_unlock(&mount_lock);
+ goto go_ahead;
+ }
+
+ mntget(driverfs_mount);
+ ++mount_count;
+ spin_unlock(&mount_lock);
+
+ go_ahead:
+ DBG("driverfs: mount_count = %d\n",mount_count);
+ return 0;
+}
+
+static void put_mount(void)
+{
+ struct vfsmount * mnt;
+
+ spin_lock(&mount_lock);
+ mnt = driverfs_mount;
+ --mount_count;
+ if (!mount_count)
+ driverfs_mount = NULL;
+ spin_unlock(&mount_lock);
+ mntput(mnt);
+ DBG("driverfs: mount_count = %d\n",mount_count);
+}
+
+int __init init_driverfs_fs(void)
+{
+ int error;
+
+ DBG("%s: registering filesystem.\n",__FUNCTION__);
+ error = register_filesystem(&driverfs_fs_type);
+
+ if (error)
+ DBG(KERN_ERR "%s: register_filesystem failed with %d\n",
+ __FUNCTION__,error);
+
+ return error;
+}
+
+static void __exit exit_driverfs_fs(void)
+{
+ unregister_filesystem(&driverfs_fs_type);
+}
+#if 0
+module_init(init_driverfs_fs);
+module_exit(exit_driverfs_fs);
+#endif
+
+EXPORT_SYMBOL(driverfs_create_file);
+EXPORT_SYMBOL(driverfs_create_dir);
+EXPORT_SYMBOL(driverfs_remove_file);
+EXPORT_SYMBOL(driverfs_remove_dir);
+
+MODULE_DESCRIPTION("The device driver filesystem");
+MODULE_LICENSE("GPL");
+
+/**
+ * driverfs_create_dir_entry - allocate and initialise directory entry
+ * @name: name of the directory
+ * @mode: permissions of the dir
+ */
+struct driver_dir_entry *
+driverfs_create_dir_entry(const char * name, mode_t mode)
+{
+ struct driver_dir_entry * entry;
+ int size = sizeof(struct driver_dir_entry) + strlen(name) + 1;
+
+
+ entry = kmalloc(size, GFP_KERNEL);
+ if (!entry)
+ return NULL;
+
+ memset(entry, 0, size);
+ strcpy((char *)entry + sizeof(struct driver_dir_entry), name);
+
+ entry->name = (char *)entry + sizeof(struct driver_dir_entry);
+
+ INIT_LIST_HEAD(&entry->files);
+ entry->mode = mode;
+
+ return entry;
+}
+
+/**
+ * driverfs_create_dir - create a directory in the filesystem
+ * @entry: directory entry
+ * @parent: parent directory entry
+ */
+int
+driverfs_create_dir(struct driver_dir_entry * entry,
+ struct driver_dir_entry * parent)
+{
+ struct dentry * dentry = NULL;
+ struct dentry * parent_dentry;
+ struct qstr qstr;
+ int error = 0;
+
+ if (!entry)
+ return -EINVAL;
+
+ get_mount();
+
+ parent_dentry = parent ? parent->dentry : NULL;
+
+ if (!parent_dentry)
+ if (driverfs_mount && driverfs_mount->mnt_sb)
+ parent_dentry = driverfs_mount->mnt_sb->s_root;
+
+ if (!parent_dentry) {
+ put_mount();
+ return -EFAULT;
+ }
+
+ dget(parent_dentry);
+ down(&parent_dentry->d_inode->i_sem);
+
+ qstr.name = entry->name;
+ qstr.len = strlen(entry->name);
+ qstr.hash = full_name_hash(entry->name,qstr.len);
+
+ dentry = lookup_hash(&qstr,parent_dentry);
+ if (IS_ERR(dentry)) {
+ error = PTR_ERR(dentry);
+ up(&parent_dentry->d_inode->i_sem);
+ dput(parent_dentry);
+ } else {
+ dentry->d_fsdata = (void *) entry;
+ entry->dentry = dentry;
+ error = vfs_mkdir(parent_dentry->d_inode,dentry,entry->mode);
+ up(&parent_dentry->d_inode->i_sem);
+ }
+
+ if (error)
+ put_mount();
+ return error;
+}
+
+/**
+ * driverfs_create_file - create a file
+ * @entry: structure describing the file
+ * @parent: directory to create it in
+ */
+int
+driverfs_create_file(struct driver_file_entry * entry,
+ struct driver_dir_entry * parent)
+{
+ struct dentry * dentry;
+ struct dentry * parent_dentry;
+ struct qstr qstr;
+ int error = 0;
+
+ if (!entry || !parent)
+ return -EINVAL;
+
+ /* make sure we're mounted */
+ get_mount();
+
+ if (!parent->dentry) {
+ put_mount();
+ return -EINVAL;
+ }
+
+ /* make sure daddy doesn't run out on us again... */
+ parent_dentry = dget(parent->dentry);
+ down(&parent_dentry->d_inode->i_sem);
+
+ qstr.name = entry->name;
+ qstr.len = strlen(entry->name);
+ qstr.hash = full_name_hash(entry->name,qstr.len);
+
+ dentry = lookup_hash(&qstr,parent_dentry);
+ if (IS_ERR(dentry))
+ error = PTR_ERR(dentry);
+ else
+ error = vfs_create(parent_dentry->d_inode,dentry,entry->mode);
+
+
+ /* Still good? Ok, then fill in the blanks: */
+ if (!error) {
+ dentry->d_fsdata = (void *)entry;
+ dentry->d_inode->u.generic_ip = (void *)entry;
+
+ entry->dentry = dentry;
+
+ list_add_tail(&entry->node,&parent->files);
+ }
+ up(&parent_dentry->d_inode->i_sem);
+
+ if (error) {
+ dput(parent_dentry);
+ put_mount();
+ }
+ return error;
+}
+
+/**
+ * __remove_file - remove a regular file in the filesystem
+ * @dentry: dentry of file to remove
+ *
+ * Call unlink to remove the file, and dput on the dentry to drop
+ * the refcount.
+ */
+static void __remove_file(struct dentry * dentry)
+{
+ dget(dentry);
+ down(&dentry->d_inode->i_sem);
+
+ vfs_unlink(dentry->d_parent->d_inode,dentry);
+
+ unlock_dir(dentry);
+
+ /* remove reference count from when file was created */
+ dput(dentry);
+
+ put_mount();
+}
+
+/**
+ * driverfs_remove_file - exported file removal
+ * @dir: directory the file supposedly resides in
+ * @name: name of the file
+ *
+ * Try and find the file in the dir's list.
+ * If it's there, call __remove_file() (above) for the dentry.
+ */
+void driverfs_remove_file(struct driver_dir_entry * dir, const char * name)
+{
+ struct dentry * dentry;
+ struct list_head * node;
+
+ if (!dir->dentry)
+ return;
+
+ dentry = dget(dir->dentry);
+ down(&dentry->d_inode->i_sem);
+
+ node = dir->files.next;
+ while (node != &dir->files) {
+ struct driver_file_entry * entry = NULL;
+
+ entry = list_entry(node,struct driver_file_entry,node);
+ if (!strcmp(entry->name,name)) {
+ list_del_init(node);
+
+ __remove_file(entry->dentry);
+ break;
+ }
+ node = node->next;
+ }
+ unlock_dir(dentry);
+}
+
+/**
+ * driverfs_remove_dir - exportable directory removal
+ * @dir: directory to remove
+ *
+ * To make sure we don't orphan anyone, first remove
+ * all the children in the list, then do vfs_rmdir() to remove it
+ * and decrement the refcount..
+ */
+void driverfs_remove_dir(struct driver_dir_entry * dir)
+{
+ struct list_head * node;
+ struct dentry * dentry;
+
+ if (!dir->dentry)
+ goto done;
+
+ /* lock the directory while we remove the files */
+ dentry = dget(dir->dentry);
+ down(&dentry->d_inode->i_sem);
+
+ node = dir->files.next;
+ while (node != &dir->files) {
+ struct driver_file_entry * entry;
+ entry = list_entry(node,struct driver_file_entry,node);
+
+ list_del_init(node);
+
+ __remove_file(entry->dentry);
+
+ node = dir->files.next;
+ }
+
+ /* now lock the parent, so we can remove this directory */
+ lock_parent(dentry);
+
+ vfs_rmdir(dentry->d_parent->d_inode,dentry);
+ double_unlock(dentry,dentry->d_parent);
+
+ /* remove reference count from when directory was created */
+ dput(dentry);
+ done:
+ put_mount();
+}
+
+/**
+ * driverfs_create_entry - allocate and initialise a struct driver_file_entry
+ * @name: name of the file
+ * @mode: permissions of the file
+ * @ops: Operations for the file
+ * @data: data that will be passed back to the callback
+ *
+ */
+struct driver_file_entry *
+driverfs_create_entry (const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data)
+{
+ struct driver_file_entry * entry;
+ int size;
+
+ size = sizeof(struct driver_file_entry) + strlen(name) + 1;
+
+ entry = kmalloc(size,GFP_KERNEL);
+ if (!entry)
+ return NULL;
+
+ memset(entry, 0, size);
+ strcpy((char *)entry + sizeof(struct driver_file_entry), name);
+
+ entry->name = (char *)entry + sizeof(struct driver_file_entry);
+
+ INIT_LIST_HEAD(&entry->node);
+
+ entry->mode = mode;
+ entry->ops = ops;
+ entry->data = data;
+
+ return entry;
+}
+
diff --git a/fs/efs/file.c b/fs/efs/file.c
index 67f58987e..faa5b9f2c 100644
--- a/fs/efs/file.c
+++ b/fs/efs/file.c
@@ -8,7 +8,7 @@
#include <linux/efs_fs.h>
-int efs_get_block(struct inode *inode, long iblock,
+int efs_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int error = -EROFS;
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index 39e503d3f..e27e376a5 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -12,7 +12,7 @@
#include <linux/module.h>
-extern int efs_get_block(struct inode *, long, struct buffer_head *, int);
+extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
static int efs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,efs_get_block);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 45eeaa675..3665f5ef6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -505,7 +505,7 @@ changed:
* reachable from inode.
*/
-static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
+static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{
int err = -EIO;
int offsets[4];
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 02ebe46d4..658ccef60 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -720,7 +720,7 @@ err_out:
*/
static int ext3_get_block_handle(handle_t *handle, struct inode *inode,
- long iblock,
+ sector_t iblock,
struct buffer_head *bh_result, int create)
{
int err = -EIO;
@@ -827,7 +827,7 @@ changed:
/*
* The BKL is not held on entry here.
*/
-static int ext3_get_block(struct inode *inode, long iblock,
+static int ext3_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
handle_t *handle = 0;
diff --git a/fs/fat/file.c b/fs/fat/file.c
index ade1a71bf..8071aaf6e 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -48,7 +48,7 @@ ssize_t fat_file_read(
}
-int fat_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
+int fat_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{
struct super_block *sb = inode->i_sb;
unsigned long phys;
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index cefb5b326..bce5d5dac 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -68,7 +68,7 @@ void hpfs_truncate(struct inode *i)
hpfs_write_inode(i);
}
-int hpfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
+int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{
secno s;
s = hpfs_bmap(inode, iblock);
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index e30e6137e..7fa8f7413 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -259,7 +259,7 @@ int hpfs_open(struct inode *, struct file *);
int hpfs_file_fsync(struct file *, struct dentry *, int);
secno hpfs_bmap(struct inode *, unsigned);
void hpfs_truncate(struct inode *);
-int hpfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create);
+int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create);
ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
/* inode.c */
diff --git a/fs/inode.c b/fs/inode.c
index 7132ee583..10bbf20f3 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1176,6 +1176,16 @@ void __init inode_init(unsigned long mempages)
unused_inodes_flush_task.routine = try_to_sync_unused_inodes;
}
+static inline void do_atime_update(struct inode *inode)
+{
+ unsigned long time = CURRENT_TIME;
+ if (inode->i_atime != time) {
+ inode->i_atime = time;
+ mark_inode_dirty_sync(inode);
+ }
+}
+
+
/**
* update_atime - update the access time
* @inode: inode accessed
@@ -1192,8 +1202,7 @@ void update_atime (struct inode *inode)
if ( IS_NOATIME (inode) ) return;
if ( IS_NODIRATIME (inode) && S_ISDIR (inode->i_mode) ) return;
if ( IS_RDONLY (inode) ) return;
- inode->i_atime = CURRENT_TIME;
- mark_inode_dirty_sync (inode);
+ do_atime_update(inode);
} /* End Function update_atime */
diff --git a/fs/intermezzo/psdev.c b/fs/intermezzo/psdev.c
index 88ecfa4cf..885b5270d 100644
--- a/fs/intermezzo/psdev.c
+++ b/fs/intermezzo/psdev.c
@@ -42,6 +42,7 @@
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
+#include <linux/tty.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/list.h>
@@ -50,6 +51,7 @@
#include <asm/system.h>
#include <asm/poll.h>
#include <asm/uaccess.h>
+#include <asm/ioctls.h>
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
diff --git a/fs/iobuf.c b/fs/iobuf.c
index 9cfd01eaf..3f9e5642f 100644
--- a/fs/iobuf.c
+++ b/fs/iobuf.c
@@ -8,70 +8,45 @@
#include <linux/iobuf.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
-void end_kio_request(struct kiobuf *kiobuf, int uptodate)
+int end_kio_request(struct kiobuf *kiobuf, int uptodate)
{
+ int ret = 1;
+
if ((!uptodate) && !kiobuf->errno)
kiobuf->errno = -EIO;
if (atomic_dec_and_test(&kiobuf->io_count)) {
+ ret = 0;
if (kiobuf->end_io)
kiobuf->end_io(kiobuf);
wake_up(&kiobuf->wait_queue);
}
+
+ return ret;
}
static void kiobuf_init(struct kiobuf *iobuf)
{
memset(iobuf, 0, sizeof(*iobuf));
init_waitqueue_head(&iobuf->wait_queue);
+ atomic_set(&iobuf->io_count, 0);
iobuf->array_len = KIO_STATIC_PAGES;
iobuf->maplist = iobuf->map_array;
}
-int alloc_kiobuf_bhs(struct kiobuf * kiobuf)
-{
- int i;
-
- for (i = 0; i < KIO_MAX_SECTORS; i++)
- if (!(kiobuf->bh[i] = kmem_cache_alloc(bh_cachep, SLAB_KERNEL))) {
- while (i--) {
- kmem_cache_free(bh_cachep, kiobuf->bh[i]);
- kiobuf->bh[i] = NULL;
- }
- return -ENOMEM;
- }
- return 0;
-}
-
-void free_kiobuf_bhs(struct kiobuf * kiobuf)
-{
- int i;
-
- for (i = 0; i < KIO_MAX_SECTORS; i++) {
- kmem_cache_free(bh_cachep, kiobuf->bh[i]);
- kiobuf->bh[i] = NULL;
- }
-}
-
int alloc_kiovec(int nr, struct kiobuf **bufp)
{
int i;
struct kiobuf *iobuf;
for (i = 0; i < nr; i++) {
- iobuf = vmalloc(sizeof(struct kiobuf));
+ iobuf = kmalloc(sizeof(struct kiobuf), GFP_KERNEL);
if (!iobuf) {
free_kiovec(i, bufp);
return -ENOMEM;
}
kiobuf_init(iobuf);
- if (alloc_kiobuf_bhs(iobuf)) {
- vfree(iobuf);
- free_kiovec(i, bufp);
- return -ENOMEM;
- }
bufp[i] = iobuf;
}
@@ -89,8 +64,7 @@ void free_kiovec(int nr, struct kiobuf **bufp)
unlock_kiovec(1, &iobuf);
if (iobuf->array_len > KIO_STATIC_PAGES)
kfree (iobuf->maplist);
- free_kiobuf_bhs(iobuf);
- vfree(bufp[i]);
+ kfree(bufp[i]);
}
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 75bad0e58..305bf8fae 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -888,7 +888,7 @@ static int isofs_statfs (struct super_block *sb, struct statfs *buf)
* or getblk() if they are not. Returns the number of blocks inserted
* (0 == error.)
*/
-int isofs_get_blocks(struct inode *inode, long iblock,
+int isofs_get_blocks(struct inode *inode, sector_t iblock,
struct buffer_head **bh_result, unsigned long nblocks)
{
unsigned long b_off;
@@ -976,7 +976,7 @@ abort:
/*
* Used by the standard interfaces.
*/
-static int isofs_get_block(struct inode *inode, long iblock,
+static int isofs_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
if ( create ) {
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 05d7b93c6..fe53b4991 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -292,7 +292,7 @@ static int minix_statfs(struct super_block *sb, struct statfs *buf)
return 0;
}
-static int minix_get_block(struct inode *inode, long block,
+static int minix_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int create)
{
if (INODE_VERSION(inode) == MINIX_V1)
diff --git a/fs/minix/itree_common.c b/fs/minix/itree_common.c
index 061aad0e8..0aee59b47 100644
--- a/fs/minix/itree_common.c
+++ b/fs/minix/itree_common.c
@@ -140,7 +140,7 @@ changed:
return -EAGAIN;
}
-static inline int get_block(struct inode * inode, long block,
+static inline int get_block(struct inode * inode, sector_t block,
struct buffer_head *bh_result, int create)
{
int err = -EIO;
diff --git a/fs/namei.c b/fs/namei.c
index c00e8c22c..590d31c4e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -434,6 +434,8 @@ static inline void follow_dotdot(struct nameidata *nd)
mntput(nd->mnt);
nd->mnt = parent;
}
+ while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
+ ;
}
/*
diff --git a/fs/namespace.c b/fs/namespace.c
index 5c1abb87a..d790be367 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -15,12 +15,10 @@
#include <linux/quotaops.h>
#include <linux/acct.h>
#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
+#include <linux/seq_file.h>
#include <asm/uaccess.h>
-#include <linux/seq_file.h>
-
struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
int do_remount_sb(struct super_block *sb, int flags, void * data);
void kill_super(struct super_block *sb);
@@ -31,9 +29,7 @@ static kmem_cache_t *mnt_cache;
static LIST_HEAD(vfsmntlist);
static DECLARE_MUTEX(mount_sem);
-
-/* Will be static */
-struct vfsmount *root_vfsmnt;
+static struct vfsmount *root_vfsmnt;
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
{
@@ -462,8 +458,7 @@ Enomem:
return NULL;
}
-/* Will become static */
-int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
+static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
{
int err;
if (mnt->mnt_sb->s_flags & MS_NOUSER)
@@ -561,6 +556,67 @@ static int do_remount(struct nameidata *nd,int flags,int mnt_flags,void *data)
return err;
}
+static int do_move_mount(struct nameidata *nd, char *old_name)
+{
+ struct nameidata old_nd, parent_nd;
+ struct vfsmount *p;
+ int err = 0;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!old_name || !*old_name)
+ return -EINVAL;
+ if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+ err = path_walk(old_name, &old_nd);
+ if (err)
+ return err;
+
+ down(&mount_sem);
+ while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+ ;
+ err = -EINVAL;
+ if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+ goto out;
+
+ err = -ENOENT;
+ down(&nd->dentry->d_inode->i_zombie);
+ if (IS_DEADDIR(nd->dentry->d_inode))
+ goto out1;
+
+ spin_lock(&dcache_lock);
+ if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
+ goto out2;
+
+ err = -EINVAL;
+ if (old_nd.dentry != old_nd.mnt->mnt_root)
+ goto out2;
+
+ if (old_nd.mnt == old_nd.mnt->mnt_parent)
+ goto out2;
+
+ if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+ S_ISDIR(old_nd.dentry->d_inode->i_mode))
+ goto out2;
+
+ err = -ELOOP;
+ for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
+ if (p == old_nd.mnt)
+ goto out2;
+ err = 0;
+
+ detach_mnt(old_nd.mnt, &parent_nd);
+ attach_mnt(old_nd.mnt, nd);
+out2:
+ spin_unlock(&dcache_lock);
+out1:
+ up(&nd->dentry->d_inode->i_zombie);
+out:
+ up(&mount_sem);
+ if (!err)
+ path_release(&parent_nd);
+ path_release(&old_nd);
+ return err;
+}
+
static int do_add_mount(struct nameidata *nd, char *type, int flags,
int mnt_flags, char *name, void *data)
{
@@ -677,6 +733,8 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
data_page);
else if (flags & MS_BIND)
retval = do_loopback(&nd, dev_name, flags & MS_REC);
+ else if (flags & MS_MOVE)
+ retval = do_move_mount(&nd, dev_name);
else
retval = do_add_mount(&nd, type_page, flags, mnt_flags,
dev_name, data_page);
@@ -865,6 +923,44 @@ out3:
* In 2.5 we'll use ramfs or tmpfs, but for now it's all we need - just
* something to go with root vfsmount.
*/
+static struct inode_operations rootfs_dir_inode_operations;
+static struct file_operations rootfs_dir_operations;
+static int rootfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct inode * inode = new_inode(dir->i_sb);
+ int error = -ENOSPC;
+ if (inode) {
+ inode->i_mode = S_IFDIR|mode;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_op = &rootfs_dir_inode_operations;
+ inode->i_fop = &rootfs_dir_operations;
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ }
+ return error;
+}
+static int rootfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+ struct inode * inode = new_inode(dir->i_sb);
+ int error = -ENOSPC;
+ if (inode) {
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ init_special_inode(inode, mode, dev);
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ error = 0;
+ }
+ return error;
+}
+static int rootfs_unlink(struct inode * dir, struct dentry *dentry)
+{
+ dentry->d_inode->i_nlink--;
+ dput(dentry);
+ return 0;
+}
static struct dentry *rootfs_lookup(struct inode *dir, struct dentry *dentry)
{
d_add(dentry, NULL);
@@ -876,6 +972,9 @@ static struct file_operations rootfs_dir_operations = {
};
static struct inode_operations rootfs_dir_inode_operations = {
lookup: rootfs_lookup,
+ mkdir: rootfs_mkdir,
+ mknod: rootfs_mknod,
+ unlink: rootfs_unlink,
};
static struct super_block *rootfs_read_super(struct super_block * sb, void * data, int silent)
{
@@ -906,6 +1005,8 @@ static void __init init_mount_tree(void)
root_vfsmnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(root_vfsmnt))
panic("can't allocate root vfsmount");
+ set_fs_pwd(current->fs, root_vfsmnt, root_vfsmnt->mnt_root);
+ set_fs_root(current->fs, root_vfsmnt, root_vfsmnt->mnt_root);
}
void __init mnt_init(unsigned long mempages)
@@ -965,91 +1066,3 @@ void __init mnt_init(unsigned long mempages)
} while (i);
init_mount_tree();
}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init change_root(kdev_t new_root_dev,const char *put_old)
-{
- struct vfsmount *old_rootmnt;
- struct nameidata devfs_nd, nd;
- struct nameidata parent_nd;
- char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
- int error = 0;
-
- if (new_devname)
- strcpy(new_devname, "/dev/root.old");
-
- read_lock(&current->fs->lock);
- old_rootmnt = mntget(current->fs->rootmnt);
- read_unlock(&current->fs->lock);
- /* First unmount devfs if mounted */
- if (path_init("/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
- error = path_walk("/dev", &devfs_nd);
- if (!error) {
- if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
- devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
- do_umount(devfs_nd.mnt, 0);
- }
- path_release(&devfs_nd);
- }
- spin_lock(&dcache_lock);
- detach_mnt(old_rootmnt, &parent_nd);
- spin_unlock(&dcache_lock);
- ROOT_DEV = new_root_dev;
- mount_root();
-#if 1
- shrink_dcache();
- printk("change_root: old root has d_count=%d\n",
- atomic_read(&old_rootmnt->mnt_root->d_count));
-#endif
- mount_devfs_fs ();
- /*
- * Get the new mount directory
- */
- error = 0;
- if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
- error = path_walk(put_old, &nd);
- if (error) {
- int blivet;
- struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
-
- atomic_inc(&ramdisk->bd_count);
- blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
- printk(KERN_NOTICE "Trying to unmount old root ... ");
- if (!blivet) {
- spin_lock(&dcache_lock);
- list_del_init(&old_rootmnt->mnt_list);
- spin_unlock(&dcache_lock);
- mntput(old_rootmnt);
- mntput(old_rootmnt);
- blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
- path_release(&parent_nd);
- blkdev_put(ramdisk, BDEV_FS);
- }
- if (blivet) {
- printk(KERN_ERR "error %d\n", blivet);
- } else {
- printk("okay\n");
- error = 0;
- }
- kfree(new_devname);
- return error;
- }
-
- spin_lock(&dcache_lock);
- attach_mnt(old_rootmnt, &nd);
- if (new_devname) {
- if (old_rootmnt->mnt_devname)
- kfree(old_rootmnt->mnt_devname);
- old_rootmnt->mnt_devname = new_devname;
- }
- spin_unlock(&dcache_lock);
-
- /* put the old stuff */
- path_release(&parent_nd);
- mntput(old_rootmnt);
- path_release(&nd);
- return 0;
-}
-
-#endif
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 0a79189c7..66c4d7aff 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -1,4 +1,6 @@
/*
+ * fs/partitions/check.c
+ *
* Code extracted from drivers/block/genhd.c
* Copyright (C) 1991-1998 Linus Torvalds
* Re-organised Feb 1998 Russell King
@@ -34,8 +36,6 @@
#include "ibm.h"
#include "ultrix.h"
-extern int *blk_size[];
-
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
static int (*check_part[])(struct gendisk *hd, struct block_device *bdev, unsigned long first_sect, int first_minor) = {
@@ -369,38 +369,50 @@ void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors,
{
if (!gdev)
return;
- grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size);
+ grok_partitions(dev, size);
}
-void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size)
+void grok_partitions(kdev_t dev, long size)
{
- int i;
- int first_minor = drive << dev->minor_shift;
- int end_minor = first_minor + dev->max_p;
+ int i, minors, first_minor, end_minor;
+ struct gendisk *g = get_gendisk(dev);
+
+ if (!g)
+ return;
+
+ minors = 1 << g->minor_shift;
+ first_minor = MINOR(dev);
+ if (first_minor & (minors-1)) {
+ printk("grok_partitions: bad device 0x%02x:%02x\n",
+ MAJOR(dev), first_minor);
+ first_minor &= ~(minors-1);
+ }
+ end_minor = first_minor + minors;
+
+ if (!g->sizes)
+ blk_size[g->major] = NULL;
- if(!dev->sizes)
- blk_size[dev->major] = NULL;
+ g->part[first_minor].nr_sects = size;
- dev->part[first_minor].nr_sects = size;
/* No such device or no minors to use for partitions */
if (!size || minors == 1)
return;
- if (dev->sizes) {
- dev->sizes[first_minor] = size >> (BLOCK_SIZE_BITS - 9);
+ if (g->sizes) {
+ g->sizes[first_minor] = size >> (BLOCK_SIZE_BITS - 9);
for (i = first_minor + 1; i < end_minor; i++)
- dev->sizes[i] = 0;
+ g->sizes[i] = 0;
}
- blk_size[dev->major] = dev->sizes;
- check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
+ blk_size[g->major] = g->sizes;
+ check_partition(g, MKDEV(g->major, first_minor), 1 + first_minor);
/*
* We need to set the sizes array before we will be able to access
* any of the partitions on this device.
*/
- if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
+ if (g->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
for (i = first_minor; i < end_minor; i++)
- dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
+ g->sizes[i] = g->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
}
}
@@ -426,3 +438,43 @@ fail:
p->v = NULL;
return NULL;
}
+
+int wipe_partitions(kdev_t dev)
+{
+ struct gendisk *g;
+ kdev_t devp;
+ int p, major, minor, minor0, max_p, res;
+
+ g = get_gendisk(dev);
+ if (g == NULL)
+ return -EINVAL;
+
+ max_p = 1 << g->minor_shift;
+ major = MAJOR(dev);
+ minor = MINOR(dev);
+ minor0 = minor & ~(max_p - 1);
+ if (minor0 != minor) /* for now only whole-disk reread */
+ return -EINVAL; /* %%% later.. */
+
+ /* invalidate stuff */
+ for (p = max_p - 1; p >= 0; p--) {
+ minor = minor0 + p;
+ devp = MKDEV(major,minor);
+#if 0 /* %%% superfluous? */
+ if (g->part[minor].nr_sects == 0)
+ continue;
+#endif
+ res = invalidate_device(devp, 1);
+ if (res)
+ return res;
+ g->part[minor].start_sect = 0;
+ g->part[minor].nr_sects = 0;
+ }
+
+ /* some places do blksize_size[major][minor] = 1024,
+ as preparation for reading partition table - superfluous */
+ /* sd.c used to set blksize_size to 2048 in case
+ rscsi_disks[target].device->sector_size == 2048 */
+
+ return 0;
+}
diff --git a/fs/partitions/check.h b/fs/partitions/check.h
index 32d794046..9d2647a2c 100644
--- a/fs/partitions/check.h
+++ b/fs/partitions/check.h
@@ -1,5 +1,5 @@
/*
- * add_partition adds a partitions details to the devices partition
+ * add_gd_partition adds a partitions details to the devices partition
* description.
*/
void add_gd_partition(struct gendisk *hd, int minor, int start, int size);
diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c
index 8d77aca6e..8a7a27cb0 100644
--- a/fs/partitions/ldm.c
+++ b/fs/partitions/ldm.c
@@ -26,6 +26,7 @@
#include <linux/types.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
+#include <linux/pagemap.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index aeca5ec31..ad6d9714d 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -57,7 +57,6 @@ extern int get_device_list(char *);
extern int get_partition_list(char *, char **, off_t, int);
extern int get_filesystem_list(char *);
extern int get_exec_domain_list(char *);
-extern int get_irq_list(char *);
extern int get_dma_list(char *);
extern int get_locks_status (char *, char **, off_t, int);
extern int get_swaparea_info (char *);
@@ -139,24 +138,14 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
* display in kilobytes.
*/
#define K(x) ((x) << (PAGE_SHIFT - 10))
-#define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
si_meminfo(&i);
si_swapinfo(&i);
pg_size = atomic_read(&page_cache_size) - i.bufferram ;
- len = sprintf(page, " total: used: free: shared: buffers: cached:\n"
- "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
- "Swap: %8Lu %8Lu %8Lu\n",
- B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
- B(i.sharedram), B(i.bufferram),
- B(pg_size), B(i.totalswap),
- B(i.totalswap-i.freeswap), B(i.freeswap));
/*
* Tagged format, for easy grepping and expansion.
- * The above will go away eventually, once the tools
- * have been updated.
*/
- len += sprintf(page+len,
+ len = sprintf(page,
"MemTotal: %8lu kB\n"
"MemFree: %8lu kB\n"
"MemShared: %8lu kB\n"
@@ -187,7 +176,6 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
K(i.freeswap));
return proc_calc_metrics(page, start, off, count, eof, len);
-#undef B
#undef K
}
@@ -328,14 +316,53 @@ static int partitions_read_proc(char *page, char **start, off_t off,
return len;
}
-#if !defined(CONFIG_ARCH_S390)
-static int interrupts_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static void *single_start(struct seq_file *p, loff_t *pos)
{
- int len = get_irq_list(page);
- return proc_calc_metrics(page, start, off, count, eof, len);
+ return NULL + (*pos == 0);
}
-#endif
+static void *single_next(struct seq_file *p, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+static void single_stop(struct seq_file *p, void *v)
+{
+}
+extern int show_interrupts(struct seq_file *p, void *v);
+static struct seq_operations proc_interrupts_op = {
+ start: single_start,
+ next: single_next,
+ stop: single_stop,
+ show: show_interrupts,
+};
+static int interrupts_open(struct inode *inode, struct file *file)
+{
+ unsigned size = PAGE_SIZE;
+ /*
+ * probably should depend on NR_CPUS, but that's only rough estimate;
+ * if we'll need more it will be given,
+ */
+ char *buf = kmalloc(size, GFP_KERNEL);
+ struct seq_file *m;
+ int res;
+
+ if (!buf)
+ return -ENOMEM;
+ res = seq_open(file, &proc_interrupts_op);
+ if (!res) {
+ m = file->private_data;
+ m->buf = buf;
+ m->size = size;
+ } else
+ kfree(buf);
+ return res;
+}
+static struct file_operations proc_interrupts_operations = {
+ open: interrupts_open,
+ read: seq_read,
+ llseek: seq_lseek,
+ release: seq_release,
+};
static int filesystems_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
@@ -512,9 +539,6 @@ void __init proc_misc_init(void)
{"stat", kstat_read_proc},
{"devices", devices_read_proc},
{"partitions", partitions_read_proc},
-#if !defined(CONFIG_ARCH_S390)
- {"interrupts", interrupts_read_proc},
-#endif
{"filesystems", filesystems_read_proc},
{"dma", dma_read_proc},
{"ioports", ioports_read_proc},
@@ -537,6 +561,7 @@ void __init proc_misc_init(void)
entry->proc_fops = &proc_kmsg_operations;
create_seq_entry("mounts", 0, &proc_mounts_operations);
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+ create_seq_entry("interrupts", 0, &proc_interrupts_operations);
#ifdef CONFIG_MODULES
create_seq_entry("ksyms", 0, &proc_ksyms_operations);
#endif
diff --git a/fs/readdir.c b/fs/readdir.c
index e233d5e41..7ec20be60 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -79,6 +79,10 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
while(1) {
struct dentry *de = list_entry(list, struct dentry, d_child);
+ /*
+ * See comment on top of function on why we
+ * can just drop the lock here..
+ */
if (!list_empty(&de->d_hash) && de->d_inode) {
spin_unlock(&dcache_lock);
if (filldir(dirent, de->d_name.name, de->d_name.len, filp->f_pos, de->d_inode->i_ino, DT_UNKNOWN) < 0)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 793db9bd1..421485049 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -17,8 +17,6 @@
#define GET_BLOCK_READ_DIRECT 4 /* read the tail if indirect item not found */
#define GET_BLOCK_NO_ISEM 8 /* i_sem is not held, don't preallocate */
-static int reiserfs_get_block (struct inode * inode, long block,
- struct buffer_head * bh_result, int create);
//
// initially this function was derived from minix or ext2's analog and
// evolved as the prototype did
@@ -42,13 +40,11 @@ void reiserfs_delete_inode (struct inode * inode)
reiserfs_delete_object (&th, inode);
pop_journal_writer(windex) ;
+ reiserfs_release_objectid (&th, inode->i_ino);
journal_end(&th, inode->i_sb, jbegin_count) ;
- up (&inode->i_sem);
-
- /* all items of file are deleted, so we can remove "save" link */
- remove_save_link (inode, 0/* not truncate */);
+ up (&inode->i_sem);
} else {
/* no object items are in the tree */
;
@@ -76,9 +72,9 @@ static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32
void make_cpu_key (struct cpu_key * key, const struct inode * inode, loff_t offset,
int type, int length )
{
- _make_cpu_key (key, get_inode_item_key_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
- le32_to_cpu (INODE_PKEY (inode)->k_objectid),
- offset, type, length);
+ _make_cpu_key (key, inode_items_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
+ le32_to_cpu (INODE_PKEY (inode)->k_objectid),
+ offset, type, length);
}
@@ -219,9 +215,9 @@ static inline void set_block_dev_mapped (struct buffer_head * bh,
// files which were created in the earlier version can not be longer,
// than 2 gb
//
-static int file_capable (struct inode * inode, long block)
+int file_capable (struct inode * inode, long block)
{
- if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
+ if (inode_items_version (inode) != ITEM_VERSION_1 || // it is new file.
block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
return 1;
@@ -394,7 +390,7 @@ finished:
// this is called to create file map. So, _get_block_create_0 will not
// read direct item
-int reiserfs_bmap (struct inode * inode, long block,
+int reiserfs_bmap (struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create)
{
if (!file_capable (inode, block))
@@ -424,7 +420,7 @@ int reiserfs_bmap (struct inode * inode, long block,
** don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block,
** don't use this function.
*/
-static int reiserfs_get_block_create_0 (struct inode * inode, long block,
+static int reiserfs_get_block_create_0 (struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create) {
return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
}
@@ -515,8 +511,8 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th,
// determine which parts are derivative, if any, understanding that
// there are only so many ways to code to a given interface.
//
-static int reiserfs_get_block (struct inode * inode, long block,
- struct buffer_head * bh_result, int create)
+int reiserfs_get_block (struct inode * inode, sector_t block,
+ struct buffer_head * bh_result, int create)
{
int repeat, retval;
unsigned long tag;
@@ -544,7 +540,7 @@ static int reiserfs_get_block (struct inode * inode, long block,
/* bad.... */
lock_kernel() ;
th.t_trans_id = 0 ;
- version = get_inode_item_key_version (inode);
+ version = inode_items_version (inode);
if (block < 0) {
unlock_kernel();
@@ -568,7 +564,7 @@ static int reiserfs_get_block (struct inode * inode, long block,
return ret;
}
- inode->u.reiserfs_i.i_flags |= i_pack_on_close_mask;
+ inode->u.reiserfs_i.i_pack_on_close = 1 ;
windex = push_journal_writer("reiserfs_get_block") ;
@@ -884,8 +880,7 @@ static void init_inode (struct inode * inode, struct path * path)
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
unsigned long blocks;
- set_inode_item_key_version (inode, KEY_FORMAT_3_5);
- set_inode_sd_version (inode, STAT_DATA_V1);
+ inode_items_version (inode) = ITEM_VERSION_1;
inode->i_mode = sd_v1_mode(sd);
inode->i_nlink = sd_v1_nlink(sd);
inode->i_uid = sd_v1_uid(sd);
@@ -934,13 +929,13 @@ static void init_inode (struct inode * inode, struct path * path)
inode->i_generation = sd_v2_generation(sd);
if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
- set_inode_item_key_version (inode, KEY_FORMAT_3_5);
+ inode_items_version (inode) = ITEM_VERSION_1;
else
- set_inode_item_key_version (inode, KEY_FORMAT_3_6);
+ inode_items_version (inode) = ITEM_VERSION_2;
}
/* nopack = 0, by default */
- inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
+ inode->u.reiserfs_i.nopack = 0;
pathrelse (path);
if (S_ISREG (inode->i_mode)) {
@@ -1120,7 +1115,7 @@ void reiserfs_read_inode2 (struct inode * inode, void *p)
/* set version 1, version 2 could be used too, because stat data
key is the same in both versions */
- key.version = KEY_FORMAT_3_5;
+ key.version = ITEM_VERSION_1;
key.on_disk_key.k_dir_id = dirino;
key.on_disk_key.k_objectid = inode->i_ino;
key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
@@ -1143,30 +1138,6 @@ void reiserfs_read_inode2 (struct inode * inode, void *p)
}
init_inode (inode, &path_to_sd);
-
- /* It is possible that knfsd is trying to access inode of a file
- that is being removed from the disk by some other thread. As we
- update sd on unlink all that is required is to check for nlink
- here. This bug was first found by Sizif when debugging
- SquidNG/Butterfly, forgotten, and found again after Philippe
- Gramoulle <philippe.gramoulle@mmania.com> reproduced it.
-
- More logical fix would require changes in fs/inode.c:iput() to
- remove inode from hash-table _after_ fs cleaned disk stuff up and
- in iget() to return NULL if I_FREEING inode is found in
- hash-table. */
- /* Currently there is one place where it's ok to meet inode with
- nlink==0: processing of open-unlinked and half-truncated files
- during mount (fs/reiserfs/super.c:finish_unfinished()). */
- if( ( inode -> i_nlink == 0 ) &&
- ! inode -> i_sb -> u.reiserfs_sb.s_is_unlinked_ok ) {
- reiserfs_warning( "vs-13075: reiserfs_read_inode2: "
- "dead inode read from disk %K. "
- "This is likely to be race with knfsd. Ignore\n",
- &key );
- make_bad_inode( inode );
- }
-
reiserfs_check_path(&path_to_sd) ; /* init inode should be relsing */
}
@@ -1191,7 +1162,7 @@ struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key
}
struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
- int len, int fhtype, int parent) {
+ int len, int fhtype, int parent) {
struct cpu_key key ;
struct inode *inode = NULL ;
struct list_head *lp;
@@ -1332,6 +1303,26 @@ void reiserfs_write_inode (struct inode * inode, int do_sync) {
}
}
+void reiserfs_dirty_inode (struct inode * inode) {
+ struct reiserfs_transaction_handle th ;
+
+ if (inode->i_sb->s_flags & MS_RDONLY) {
+ reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n",
+ inode->i_ino) ;
+ return ;
+ }
+ lock_kernel() ;
+
+ /* this is really only used for atime updates, so they don't have
+ ** to be included in O_SYNC or fsync
+ */
+ journal_begin(&th, inode->i_sb, 1) ;
+ reiserfs_update_sd (&th, inode);
+ journal_end(&th, inode->i_sb, 1) ;
+ unlock_kernel() ;
+}
+
+
/* FIXME: no need any more. right? */
int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode)
{
@@ -1354,20 +1345,20 @@ static int reiserfs_new_directory (struct reiserfs_transaction_handle *th,
struct cpu_key key;
int retval;
- _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
+ _make_cpu_key (&key, ITEM_VERSION_1, le32_to_cpu (ih->ih_key.k_dir_id),
le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
/* compose item head for new item. Directories consist of items of
old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
is done by reiserfs_new_inode */
if (old_format_only (sb)) {
- make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
+ make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
INODE_PKEY (dir)->k_dir_id,
INODE_PKEY (dir)->k_objectid );
} else {
- make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
+ make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
INODE_PKEY (dir)->k_dir_id,
@@ -1403,12 +1394,12 @@ static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th,
struct cpu_key key;
int retval;
- _make_cpu_key (&key, KEY_FORMAT_3_5,
+ _make_cpu_key (&key, ITEM_VERSION_1,
le32_to_cpu (ih->ih_key.k_dir_id),
le32_to_cpu (ih->ih_key.k_objectid),
1, TYPE_DIRECT, 3/*key length*/);
- make_le_item_head (ih, 0, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
+ make_le_item_head (ih, 0, ITEM_VERSION_1, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
/* look for place in the tree for new item */
retval = search_item (sb, &key, path);
@@ -1479,13 +1470,13 @@ struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
inode->i_generation = ++event;
#endif
if (old_format_only (sb))
- make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
+ make_le_item_head (&ih, 0, ITEM_VERSION_1, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
else
- make_le_item_head (&ih, 0, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
+ make_le_item_head (&ih, 0, ITEM_VERSION_2, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
/* key to search for correct place for new stat data */
- _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),
+ _make_cpu_key (&key, ITEM_VERSION_2, le32_to_cpu (ih.ih_key.k_dir_id),
le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);
/* find proper place for inserting of stat data */
@@ -1521,16 +1512,9 @@ struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
- if (old_format_only (sb)) {
- if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
- pathrelse (&path_to_key);
- /* i_uid or i_gid is too big to be stored in stat data v3.5 */
- iput (inode);
- *err = -EINVAL;
- return NULL;
- }
+ if (old_format_only (sb))
inode2sd_v1 (&sd, inode);
- } else
+ else
inode2sd (&sd, inode);
// these do not go to on-disk stat data
@@ -1543,14 +1527,10 @@ struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
// format, other new objects will consist of new items)
memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);
if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))
- set_inode_item_key_version (inode, KEY_FORMAT_3_5);
- else
- set_inode_item_key_version (inode, KEY_FORMAT_3_6);
- if (old_format_only (sb))
- set_inode_sd_version (inode, STAT_DATA_V1);
+ inode_items_version (inode) = ITEM_VERSION_1;
else
- set_inode_sd_version (inode, STAT_DATA_V2);
-
+ inode_items_version (inode) = ITEM_VERSION_2;
+
/* insert the stat data into the tree */
retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));
if (retval) {
@@ -1710,23 +1690,12 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
** because the truncate might pack the item anyway
** (it will unmap bh if it packs).
*/
- /* it is enough to reserve space in transaction for 2 balancings:
- one for "save" link adding and another for the first
- cut_from_item. 1 is for update_sd */
- journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
+ journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
reiserfs_update_inode_transaction(p_s_inode) ;
windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
- if (update_timestamps)
- /* we are doing real truncate: if the system crashes before the last
- transaction of truncating gets committed - on reboot the file
- either appears truncated properly or not truncated at all */
- add_save_link (&th, p_s_inode, 1);
reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
pop_journal_writer(windex) ;
- journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
-
- if (update_timestamps)
- remove_save_link (p_s_inode, 1/* truncate */);
+ journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
if (page) {
length = offset & (blocksize - 1) ;
@@ -1994,7 +1963,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
//
// this is exactly what 2.3.99-pre9's ext2_bmap is
//
-static int reiserfs_aop_bmap(struct address_space *as, long block) {
+static int reiserfs_aop_bmap(struct address_space *as, sector_t block) {
return generic_block_bmap(as, block, reiserfs_bmap) ;
}
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 564553186..2c71fd471 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -92,8 +92,6 @@ static int do_journal_end(struct reiserfs_transaction_handle *,struct super_bloc
static int flush_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
static int can_dirty(struct reiserfs_journal_cnode *cn) ;
-static int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed);
-static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks);
static void init_journal_hash(struct super_block *p_s_sb) {
memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
@@ -1699,7 +1697,7 @@ static int journal_read(struct super_block *p_s_sb) {
/* step three, starting at the oldest transaction, replay */
if (last_flush_start > 0) {
oldest_start = last_flush_start ;
- oldest_trans_id = last_flush_trans_id + 1 ;
+ oldest_trans_id = last_flush_trans_id ;
}
cur_dblock = oldest_start ;
if (oldest_trans_id) {
@@ -1719,8 +1717,6 @@ static int journal_read(struct super_block *p_s_sb) {
}
cur_dblock = reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start ;
replay_count++ ;
- if (cur_dblock == oldest_start)
- break;
}
if (oldest_trans_id == 0) {
@@ -2087,7 +2083,7 @@ relock:
}
-static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
+int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
}
@@ -2242,7 +2238,7 @@ int journal_end(struct reiserfs_transaction_handle *th, struct super_block *p_s_
**
** returns 1 if it cleaned and relsed the buffer. 0 otherwise
*/
-static int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
+int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
struct buffer_head *bh ;
struct reiserfs_journal_cnode *cn ;
int ret = 0;
@@ -2283,7 +2279,7 @@ static int remove_from_transaction(struct super_block *p_s_sb, unsigned long blo
}
/* removes from a specific journal list hash */
-static int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) {
+int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) {
remove_journal_hash(SB_JOURNAL(s)->j_list_hash_table, jl, bh, remove_freed) ;
return 0 ;
}
@@ -2345,6 +2341,20 @@ int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block
int show_reiserfs_locks(void) {
dump_journal_writers() ;
+#if 0 /* debugging code for when we are compiled static don't delete */
+ p_s_sb = sb_entry(super_blocks.next);
+ while (p_s_sb != sb_entry(&super_blocks)) {
+ if (reiserfs_is_super(p_s_sb)) {
+printk("journal lock is %d, join lock is %d, writers %d must wait is %d\n",
+ atomic_read(&(SB_JOURNAL(p_s_sb)->j_wlock)),
+ atomic_read(&(SB_JOURNAL(p_s_sb)->j_jlock)),
+ atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount)),
+ SB_JOURNAL(p_s_sb)->j_must_wait) ;
+ printk("used cnodes %d, free cnodes %d\n", SB_JOURNAL(p_s_sb)->j_cnode_used, SB_JOURNAL(p_s_sb)->j_cnode_free) ;
+ }
+ p_s_sb = sb_entry(p_s_sb->s_list.next);
+ }
+#endif
return 0 ;
}
diff --git a/fs/super.c b/fs/super.c
index a777a4fde..368a1087e 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -21,36 +21,21 @@
*/
#include <linux/config.h>
-#include <linux/string.h>
#include <linux/slab.h>
#include <linux/locks.h>
#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
-#include <linux/fd.h>
-#include <linux/init.h>
#include <linux/major.h>
-#include <linux/quotaops.h>
#include <linux/acct.h>
#include <asm/uaccess.h>
-#include <linux/nfs_fs.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/nfs_mount.h>
-
#include <linux/kmod.h>
#define __NO_VERSION__
#include <linux/module.h>
-extern void wait_for_keypress(void);
-
-extern int root_mountflags;
-
int do_remount_sb(struct super_block *sb, int flags, void * data);
-/* this is initialized in init/main.c */
-kdev_t ROOT_DEV;
-
LIST_HEAD(super_blocks);
spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
@@ -271,22 +256,164 @@ struct file_system_type *get_fs_type(const char *name)
return fs;
}
-struct vfsmount *alloc_vfsmnt(void);
-void free_vfsmnt(struct vfsmount *mnt);
-void set_devname(struct vfsmount *mnt, const char *name);
+/**
+ * alloc_super - create new superblock
+ *
+ * Allocates and initializes a new &struct super_block. alloc_super()
+ * returns a pointer new superblock or %NULL if allocation had failed.
+ */
+static struct super_block *alloc_super(void)
+{
+ struct super_block *s = kmalloc(sizeof(struct super_block), GFP_USER);
+ if (s) {
+ memset(s, 0, sizeof(struct super_block));
+ INIT_LIST_HEAD(&s->s_dirty);
+ INIT_LIST_HEAD(&s->s_locked_inodes);
+ INIT_LIST_HEAD(&s->s_files);
+ INIT_LIST_HEAD(&s->s_instances);
+ init_rwsem(&s->s_umount);
+ sema_init(&s->s_lock, 1);
+ down_write(&s->s_umount);
+ s->s_count = S_BIAS;
+ atomic_set(&s->s_active, 1);
+ sema_init(&s->s_vfs_rename_sem,1);
+ sema_init(&s->s_nfsd_free_path_sem,1);
+ sema_init(&s->s_dquot.dqio_sem, 1);
+ sema_init(&s->s_dquot.dqoff_sem, 1);
+ s->s_maxbytes = MAX_NON_LFS;
+ }
+ return s;
+}
+
+/**
+ * destroy_super - frees a superblock
+ * @s: superblock to free
+ *
+ * Frees a superblock.
+ */
+static inline void destroy_super(struct super_block *s)
+{
+ kfree(s);
+}
-/* Will go away */
-extern struct vfsmount *root_vfsmnt;
-extern int graft_tree(struct vfsmount *mnt, struct nameidata *nd);
+/* Superblock refcounting */
-static inline void __put_super(struct super_block *sb)
+/**
+ * deactivate_super - turn an active reference into temporary
+ * @s: superblock to deactivate
+ *
+ * Turns an active reference into temporary one. Returns 0 if there are
+ * other active references, 1 if we had deactivated the last one.
+ */
+static inline int deactivate_super(struct super_block *s)
+{
+ if (!atomic_dec_and_lock(&s->s_active, &sb_lock))
+ return 0;
+ s->s_count -= S_BIAS-1;
+ spin_unlock(&sb_lock);
+ return 1;
+}
+
+/**
+ * put_super - drop a temporary reference to superblock
+ * @s: superblock in question
+ *
+ * Drops a temporary reference, frees superblock if there's no
+ * references left.
+ */
+static inline void put_super(struct super_block *s)
{
spin_lock(&sb_lock);
- if (!--sb->s_count)
- kfree(sb);
+ if (!--s->s_count)
+ destroy_super(s);
+ spin_unlock(&sb_lock);
+}
+
+/**
+ * grab_super - acquire an active reference
+ * @s - reference we are trying to make active
+ *
+ * Tries to acquire an active reference. grab_super() is used when we
+ * had just found a superblock in super_blocks or fs_type->fs_supers
+ * and want to turn it into a full-blown active reference. grab_super()
+ * is called with sb_lock held and drops it. Returns 1 in case of
+ * success, 0 if we had failed (superblock contents was already dead or
+ * dying when grab_super() had been called).
+ */
+static int grab_super(struct super_block *s)
+{
+ s->s_count++;
+ spin_unlock(&sb_lock);
+ down_write(&s->s_umount);
+ if (s->s_root) {
+ spin_lock(&sb_lock);
+ if (s->s_count > S_BIAS) {
+ atomic_inc(&s->s_active);
+ s->s_count--;
+ spin_unlock(&sb_lock);
+ return 1;
+ }
+ spin_unlock(&sb_lock);
+ }
+ up_write(&s->s_umount);
+ put_super(s);
+ return 0;
+}
+
+/**
+ * insert_super - put superblock on the lists
+ * @s: superblock in question
+ * @type: filesystem type it will belong to
+ *
+ * Associates superblock with fs type and puts it on per-type and global
+ * superblocks' lists. Should be called with sb_lock held; drops it.
+ */
+static void insert_super(struct super_block *s, struct file_system_type *type)
+{
+ s->s_type = type;
+ list_add(&s->s_list, super_blocks.prev);
+ list_add(&s->s_instances, &type->fs_supers);
spin_unlock(&sb_lock);
+ get_filesystem(type);
}
+void put_unnamed_dev(kdev_t dev); /* should become static */
+
+/**
+ * remove_super - makes superblock unreachable
+ * @s: superblock in question
+ *
+ * Removes superblock from the lists, unlocks it, drop the reference
+ * and releases the hosting device. @s should have no active
+ * references by that time and after remove_super() it's essentially
+ * in rundown mode - all remaining references are temporary, no new
+ * reference of any sort are going to appear and all holders of
+ * temporary ones will eventually drop them. At that point superblock
+ * itself will be destroyed; all its contents is already gone.
+ */
+static void remove_super(struct super_block *s)
+{
+ kdev_t dev = s->s_dev;
+ struct block_device *bdev = s->s_bdev;
+ struct file_system_type *fs = s->s_type;
+
+ spin_lock(&sb_lock);
+ list_del(&s->s_list);
+ list_del(&s->s_instances);
+ spin_unlock(&sb_lock);
+ up_write(&s->s_umount);
+ put_super(s);
+ put_filesystem(fs);
+ if (bdev)
+ blkdev_put(bdev, BDEV_FS);
+ else
+ put_unnamed_dev(dev);
+}
+
+struct vfsmount *alloc_vfsmnt(void);
+void free_vfsmnt(struct vfsmount *mnt);
+void set_devname(struct vfsmount *mnt, const char *name);
+
static inline struct super_block * find_super(kdev_t dev)
{
struct list_head *p;
@@ -304,14 +431,7 @@ static inline struct super_block * find_super(kdev_t dev)
void drop_super(struct super_block *sb)
{
up_read(&sb->s_umount);
- __put_super(sb);
-}
-
-static void put_super(struct super_block *sb)
-{
- atomic_dec(&sb->s_active);
- up_write(&sb->s_umount);
- __put_super(sb);
+ put_super(sb);
}
static inline void write_super(struct super_block *sb)
@@ -322,7 +442,7 @@ static inline void write_super(struct super_block *sb)
sb->s_op->write_super(sb);
unlock_super(sb);
}
-
+
/*
* Note: check the dirty flag before waiting, so we don't
* hold up the sync while mounting a device. (The newly
@@ -371,19 +491,19 @@ struct super_block * get_super(kdev_t dev)
if (!dev)
return NULL;
-restart:
- spin_lock(&sb_lock);
- s = find_super(dev);
- if (s) {
+
+ while (1) {
+ spin_lock(&sb_lock);
+ s = find_super(dev);
spin_unlock(&sb_lock);
+ if (!s)
+ break;
down_read(&s->s_umount);
if (s->s_root)
- return s;
+ break;
drop_super(s);
- goto restart;
}
- spin_unlock(&sb_lock);
- return NULL;
+ return s;
}
asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf)
@@ -410,80 +530,6 @@ out:
return err;
}
-/**
- * get_empty_super - find empty superblocks
- *
- * Find a superblock with no device assigned. A free superblock is
- * found and returned. If neccessary new superblocks are allocated.
- * %NULL is returned if there are insufficient resources to complete
- * the request.
- */
-
-static struct super_block *alloc_super(void)
-{
- struct super_block *s = kmalloc(sizeof(struct super_block), GFP_USER);
- if (s) {
- memset(s, 0, sizeof(struct super_block));
- INIT_LIST_HEAD(&s->s_dirty);
- INIT_LIST_HEAD(&s->s_locked_inodes);
- INIT_LIST_HEAD(&s->s_files);
- INIT_LIST_HEAD(&s->s_instances);
- init_rwsem(&s->s_umount);
- sema_init(&s->s_lock, 1);
- s->s_count = 1;
- atomic_set(&s->s_active, 1);
- sema_init(&s->s_vfs_rename_sem,1);
- sema_init(&s->s_nfsd_free_path_sem,1);
- sema_init(&s->s_dquot.dqio_sem, 1);
- sema_init(&s->s_dquot.dqoff_sem, 1);
- s->s_maxbytes = MAX_NON_LFS;
- }
- return s;
-}
-
-static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
- struct file_system_type *type, int flags,
- void *data)
-{
- struct super_block * s;
- s = alloc_super();
- if (!s)
- goto out;
- s->s_dev = dev;
- s->s_bdev = bdev;
- s->s_flags = flags;
- s->s_type = type;
- spin_lock(&sb_lock);
- list_add (&s->s_list, super_blocks.prev);
- list_add (&s->s_instances, &type->fs_supers);
- s->s_count += S_BIAS;
- spin_unlock(&sb_lock);
- down_write(&s->s_umount);
- lock_super(s);
- if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
- goto out_fail;
- s->s_flags |= MS_ACTIVE;
- unlock_super(s);
- /* tell bdcache that we are going to keep this one */
- if (bdev)
- atomic_inc(&bdev->bd_count);
-out:
- return s;
-
-out_fail:
- s->s_dev = 0;
- s->s_bdev = 0;
- s->s_type = NULL;
- unlock_super(s);
- spin_lock(&sb_lock);
- list_del(&s->s_list);
- list_del(&s->s_instances);
- s->s_count -= S_BIAS;
- spin_unlock(&sb_lock);
- put_super(s);
- return NULL;
-}
-
/*
* Unnamed block devices are dummy devices used by virtual
* filesystems which don't use real block-devices. -- jrs
@@ -512,25 +558,6 @@ void put_unnamed_dev(kdev_t dev)
kdevname(dev));
}
-static int grab_super(struct super_block *sb)
-{
- sb->s_count++;
- atomic_inc(&sb->s_active);
- spin_unlock(&sb_lock);
- down_write(&sb->s_umount);
- if (sb->s_root) {
- spin_lock(&sb_lock);
- if (sb->s_count > S_BIAS) {
- sb->s_count--;
- spin_unlock(&sb_lock);
- return 1;
- }
- spin_unlock(&sb_lock);
- }
- put_super(sb);
- return 0;
-}
-
static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
char *dev_name, int flags, void * data)
{
@@ -571,14 +598,17 @@ static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
goto out;
check_disk_change(dev);
error = -EACCES;
- if (!(flags & MS_RDONLY) && is_read_only(dev))
- goto out1;
+ if (!(flags & MS_RDONLY) && is_read_only(dev)) {
+ blkdev_put(bdev, BDEV_FS);
+ goto out;
+ }
error = -ENOMEM;
s = alloc_super();
- if (!s)
- goto out1;
- down_write(&s->s_umount);
+ if (!s) {
+ blkdev_put(bdev, BDEV_FS);
+ goto out;
+ }
error = -EBUSY;
restart:
@@ -591,12 +621,13 @@ restart:
if (old->s_type != fs_type ||
((flags ^ old->s_flags) & MS_RDONLY)) {
spin_unlock(&sb_lock);
- put_super(s);
- goto out1;
+ destroy_super(s);
+ blkdev_put(bdev, BDEV_FS);
+ goto out;
}
if (!grab_super(old))
goto restart;
- put_super(s);
+ destroy_super(s);
blkdev_put(bdev, BDEV_FS);
path_release(&nd);
return old;
@@ -604,12 +635,7 @@ restart:
s->s_dev = dev;
s->s_bdev = bdev;
s->s_flags = flags;
- s->s_type = fs_type;
- list_add (&s->s_list, super_blocks.prev);
- list_add (&s->s_instances, &fs_type->fs_supers);
- s->s_count += S_BIAS;
-
- spin_unlock(&sb_lock);
+ insert_super(s, fs_type);
error = -EINVAL;
lock_super(s);
@@ -617,23 +643,13 @@ restart:
goto out_fail;
s->s_flags |= MS_ACTIVE;
unlock_super(s);
- get_filesystem(fs_type);
path_release(&nd);
return s;
out_fail:
- s->s_dev = 0;
- s->s_bdev = 0;
- s->s_type = NULL;
unlock_super(s);
- spin_lock(&sb_lock);
- list_del(&s->s_list);
- list_del(&s->s_instances);
- s->s_count -= S_BIAS;
- spin_unlock(&sb_lock);
- put_super(s);
-out1:
- blkdev_put(bdev, BDEV_FS);
+ deactivate_super(s);
+ remove_super(s);
out:
path_release(&nd);
return ERR_PTR(error);
@@ -642,20 +658,30 @@ out:
static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
int flags, void * data)
{
- kdev_t dev;
- int error = -EMFILE;
- dev = get_unnamed_dev();
- if (dev) {
- struct super_block * sb;
- error = -EINVAL;
- sb = read_super(dev, NULL, fs_type, flags, data);
- if (sb) {
- get_filesystem(fs_type);
- return sb;
- }
- put_unnamed_dev(dev);
+ struct super_block *s = alloc_super();
+
+ if (!s)
+ return ERR_PTR(-ENOMEM);
+ s->s_dev = get_unnamed_dev();
+ if (!s->s_dev) {
+ destroy_super(s);
+ return ERR_PTR(-EMFILE);
}
- return ERR_PTR(error);
+ s->s_flags = flags;
+ spin_lock(&sb_lock);
+ insert_super(s, fs_type);
+ lock_super(s);
+ if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
+ goto out_fail;
+ s->s_flags |= MS_ACTIVE;
+ unlock_super(s);
+ return s;
+
+out_fail:
+ unlock_super(s);
+ deactivate_super(s);
+ remove_super(s);
+ return ERR_PTR(-EINVAL);
}
static struct super_block *get_sb_single(struct file_system_type *fs_type,
@@ -664,7 +690,6 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type,
struct super_block * s = alloc_super();
if (!s)
return ERR_PTR(-ENOMEM);
- down_write(&s->s_umount);
/*
* Get the superblock of kernel-wide instance, but
* keep the reference to fs_type.
@@ -677,61 +702,42 @@ retry:
s_instances);
if (!grab_super(old))
goto retry;
- put_super(s);
+ destroy_super(s);
do_remount_sb(old, flags, data);
return old;
} else {
- kdev_t dev = get_unnamed_dev();
- if (!dev) {
+ s->s_dev = get_unnamed_dev();
+ if (!s->s_dev) {
spin_unlock(&sb_lock);
- put_super(s);
+ destroy_super(s);
return ERR_PTR(-EMFILE);
}
- s->s_dev = dev;
s->s_flags = flags;
- s->s_type = fs_type;
- list_add (&s->s_list, super_blocks.prev);
- list_add (&s->s_instances, &fs_type->fs_supers);
- s->s_count += S_BIAS;
- spin_unlock(&sb_lock);
+ insert_super(s, fs_type);
lock_super(s);
if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
goto out_fail;
s->s_flags |= MS_ACTIVE;
unlock_super(s);
- get_filesystem(fs_type);
return s;
out_fail:
- s->s_dev = 0;
- s->s_bdev = 0;
- s->s_type = NULL;
unlock_super(s);
- spin_lock(&sb_lock);
- list_del(&s->s_list);
- list_del(&s->s_instances);
- s->s_count -= S_BIAS;
- spin_unlock(&sb_lock);
- put_super(s);
- put_unnamed_dev(dev);
+ deactivate_super(s);
+ remove_super(s);
return ERR_PTR(-EINVAL);
}
}
void kill_super(struct super_block *sb)
{
- struct block_device *bdev;
- kdev_t dev;
struct dentry *root = sb->s_root;
struct file_system_type *fs = sb->s_type;
struct super_operations *sop = sb->s_op;
- if (!atomic_dec_and_lock(&sb->s_active, &sb_lock))
+ if (!deactivate_super(sb))
return;
- sb->s_count -= S_BIAS;
- spin_unlock(&sb_lock);
-
down_write(&sb->s_umount);
lock_kernel();
sb->s_root = NULL;
@@ -757,24 +763,9 @@ void kill_super(struct super_block *sb)
"Self-destruct in 5 seconds. Have a nice day...\n");
}
- dev = sb->s_dev;
- sb->s_dev = 0; /* Free the superblock */
- bdev = sb->s_bdev;
- sb->s_bdev = NULL;
- put_filesystem(fs);
- sb->s_type = NULL;
- unlock_super(sb);
unlock_kernel();
- if (bdev)
- blkdev_put(bdev, BDEV_FS);
- else
- put_unnamed_dev(dev);
- spin_lock(&sb_lock);
- list_del(&sb->s_list);
- list_del(&sb->s_instances);
- spin_unlock(&sb_lock);
- atomic_inc(&sb->s_active);
- put_super(sb);
+ unlock_super(sb);
+ remove_super(sb);
}
/*
@@ -870,211 +861,3 @@ struct vfsmount *kern_mount(struct file_system_type *type)
{
return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
}
-
-static char * __initdata root_mount_data;
-static int __init root_data_setup(char *str)
-{
- root_mount_data = str;
- return 1;
-}
-
-static char * __initdata root_fs_names;
-static int __init fs_names_setup(char *str)
-{
- root_fs_names = str;
- return 1;
-}
-
-__setup("rootflags=", root_data_setup);
-__setup("rootfstype=", fs_names_setup);
-
-static void __init get_fs_names(char *page)
-{
- char *s = page;
-
- if (root_fs_names) {
- strcpy(page, root_fs_names);
- while (*s++) {
- if (s[-1] == ',')
- s[-1] = '\0';
- }
- } else {
- int len = get_filesystem_list(page);
- char *p, *next;
-
- page[len] = '\0';
- for (p = page-1; p; p = next) {
- next = strchr(++p, '\n');
- if (*p++ != '\t')
- continue;
- while ((*s++ = *p++) != '\n')
- ;
- s[-1] = '\0';
- }
- }
- *s = '\0';
-}
-
-void __init mount_root(void)
-{
- struct nameidata root_nd;
- struct super_block * sb;
- struct vfsmount *vfsmnt;
- struct block_device *bdev = NULL;
- mode_t mode;
- int retval;
- void *handle;
- char path[64];
- int path_start = -1;
- char *name = "/dev/root";
- char *fs_names, *p;
-#ifdef CONFIG_ROOT_NFS
- void *data;
-#endif
- root_mountflags |= MS_VERBOSE;
-
-#ifdef CONFIG_ROOT_NFS
- if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
- goto skip_nfs;
- data = nfs_root_data();
- if (!data)
- goto no_nfs;
- vfsmnt = do_kern_mount("nfs", root_mountflags, "/dev/root", data);
- if (!IS_ERR(vfsmnt)) {
- printk ("VFS: Mounted root (%s filesystem).\n", "nfs");
- ROOT_DEV = vfsmnt->mnt_sb->s_dev;
- goto attach_it;
- }
-no_nfs:
- printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
- ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
-skip_nfs:
-#endif
-
-#ifdef CONFIG_BLK_DEV_FD
- if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
-#ifdef CONFIG_BLK_DEV_RAM
- extern int rd_doload;
- extern void rd_load_secondary(void);
-#endif
- floppy_eject();
-#ifndef CONFIG_BLK_DEV_RAM
- printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
-#else
- /* rd_doload is 2 for a dual initrd/ramload setup */
- if(rd_doload==2)
- rd_load_secondary();
- else
-#endif
- {
- printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
- wait_for_keypress();
- }
- }
-#endif
-
- fs_names = __getname();
- get_fs_names(fs_names);
-
- devfs_make_root (root_device_name);
- handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
- MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
- DEVFS_SPECIAL_BLK, 1);
- if (handle) /* Sigh: bd*() functions only paper over the cracks */
- {
- unsigned major, minor;
-
- devfs_get_maj_min (handle, &major, &minor);
- ROOT_DEV = MKDEV (major, minor);
- }
-
- /*
- * Probably pure paranoia, but I'm less than happy about delving into
- * devfs crap and checking it right now. Later.
- */
- if (!ROOT_DEV)
- panic("I have no root and I want to scream");
-
-retry:
- bdev = bdget(kdev_t_to_nr(ROOT_DEV));
- if (!bdev)
- panic(__FUNCTION__ ": unable to allocate root device");
- bdev->bd_op = devfs_get_ops (handle);
- path_start = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
- mode = FMODE_READ;
- if (!(root_mountflags & MS_RDONLY))
- mode |= FMODE_WRITE;
- retval = blkdev_get(bdev, mode, 0, BDEV_FS);
- if (retval == -EROFS) {
- root_mountflags |= MS_RDONLY;
- goto retry;
- }
- if (retval) {
- /*
- * Allow the user to distinguish between failed open
- * and bad superblock on root device.
- */
- printk ("VFS: Cannot open root device \"%s\" or %s\n",
- root_device_name, kdevname (ROOT_DEV));
- printk ("Please append a correct \"root=\" boot option\n");
- panic("VFS: Unable to mount root fs on %s",
- kdevname(ROOT_DEV));
- }
-
- check_disk_change(ROOT_DEV);
- sb = get_super(ROOT_DEV);
- if (sb) {
- /* FIXME */
- p = (char *)sb->s_type->name;
- atomic_inc(&sb->s_active);
- up_read(&sb->s_umount);
- down_write(&sb->s_umount);
- goto mount_it;
- }
-
- for (p = fs_names; *p; p += strlen(p)+1) {
- struct file_system_type * fs_type = get_fs_type(p);
- if (!fs_type)
- continue;
- sb = read_super(ROOT_DEV, bdev, fs_type,
- root_mountflags, root_mount_data);
- if (sb)
- goto mount_it;
- put_filesystem(fs_type);
- }
- panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
-
-mount_it:
- /* FIXME */
- up_write(&sb->s_umount);
- printk ("VFS: Mounted root (%s filesystem)%s.\n", p,
- (sb->s_flags & MS_RDONLY) ? " readonly" : "");
- putname(fs_names);
- if (path_start >= 0) {
- name = path + path_start;
- devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
- name + 5, NULL, NULL);
- memcpy (name, "/dev/", 5);
- }
- vfsmnt = alloc_vfsmnt();
- if (!vfsmnt)
- panic("VFS: alloc_vfsmnt failed for root fs");
-
- set_devname(vfsmnt, name);
- vfsmnt->mnt_sb = sb;
- vfsmnt->mnt_root = dget(sb->s_root);
- bdput(bdev); /* sb holds a reference */
-
-
-#ifdef CONFIG_ROOT_NFS
-attach_it:
-#endif
- root_nd.mnt = root_vfsmnt;
- root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
- graft_tree(vfsmnt, &root_nd);
-
- set_fs_root(current->fs, vfsmnt, vfsmnt->mnt_root);
- set_fs_pwd(current->fs, vfsmnt, vfsmnt->mnt_root);
-
- mntput(vfsmnt);
-}
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index af27d2210..76ff8d83c 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -192,7 +192,7 @@ changed:
return -EAGAIN;
}
-static int get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
+static int get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
{
int err = -EIO;
int offsets[DEPTH];
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 4bcece361..48431cec2 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *,
static void udf_update_extents(struct inode *,
long_ad [EXTENT_MERGE_SIZE], int, int,
lb_addr, Uint32, struct buffer_head **);
-static int udf_get_block(struct inode *, long, struct buffer_head *, int);
+static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
/*
* udf_put_inode
@@ -314,7 +314,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
return dbh;
}
-static int udf_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create)
+static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
{
int err, new;
struct buffer_head *bh;
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 6ad90b306..cff561ab9 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -311,7 +311,7 @@ out:
return result;
}
-static int ufs_getfrag_block (struct inode *inode, long fragment, struct buffer_head *bh_result, int create)
+static int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
{
struct super_block * sb;
struct ufs_sb_private_info * uspi;
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index bd4e5b18f..956c46a60 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -60,6 +60,8 @@ static inline void * phys_to_virt(unsigned long address)
return (void *) (address + IDENT_ADDR);
}
+#define page_to_phys(page) (((page) - (page)->zone->zone_mem_map) << PAGE_SHIFT)
+
/*
* Change addresses as seen by the kernel (virtual) to addresses as
* seen by a device (bus), and vice versa.
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h
index e4e6bd307..f8bc9ac9c 100644
--- a/include/asm-alpha/page.h
+++ b/include/asm-alpha/page.h
@@ -64,6 +64,7 @@ do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
__asm__ __volatile__("call_pal %0 # bugchk" : : "i" (PAL_bugchk)); \
} while (0)
+
#define PAGE_BUG(page) BUG()
/* Pure 2^n version of get_order */
diff --git a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h
index 1270097b2..4ec067c93 100644
--- a/include/asm-arm/mach/irq.h
+++ b/include/asm-arm/mach/irq.h
@@ -35,7 +35,7 @@ extern struct irqdesc irq_desc[];
extern void (*init_arch_irq)(void);
extern int setup_arm_irq(int, struct irqaction *);
-extern int get_fiq_list(char *);
+extern int show_fiq_list(struct seq_file *, void *);
extern void init_FIQ(void);
#endif
diff --git a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
index 0de58abee..6b9761aa8 100644
--- a/include/asm-i386/checksum.h
+++ b/include/asm-i386/checksum.h
@@ -29,9 +29,9 @@ asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, i
/*
* Note: when you get a NULL pointer exception here this means someone
- * passed in an incorrect kernel address to one of these functions.
- *
- * If you use these functions directly please don't forget the
+ * passed in an incorrect kernel address to one of these functions.
+ *
+ * If you use these functions directly please don't forget the
* verify_area().
*/
static __inline__
@@ -66,28 +66,28 @@ unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
* Arnt Gulbrandsen.
*/
static inline unsigned short ip_fast_csum(unsigned char * iph,
- unsigned int ihl) {
+ unsigned int ihl)
+{
unsigned int sum;
- __asm__ __volatile__("
- movl (%1), %0
- subl $4, %2
- jbe 2f
- addl 4(%1), %0
- adcl 8(%1), %0
- adcl 12(%1), %0
-1: adcl 16(%1), %0
- lea 4(%1), %1
- decl %2
- jne 1b
- adcl $0, %0
- movl %0, %2
- shrl $16, %0
- addw %w2, %w0
- adcl $0, %0
- notl %0
-2:
- "
+ __asm__ __volatile__(
+ "movl (%1), %0 ;\n"
+ "subl $4, %2 ;\n"
+ "jbe 2f ;\n"
+ "addl 4(%1), %0 ;\n"
+ "adcl 8(%1), %0 ;\n"
+ "adcl 12(%1), %0 ;\n"
+"1: adcl 16(%1), %0 ;\n"
+ "lea 4(%1), %1 ;\n"
+ "decl %2 ;\n"
+ "jne 1b ;\n"
+ "adcl $0, %0 ;\n"
+ "movl %0, %2 ;\n"
+ "shrl $16, %0 ;\n"
+ "addw %w2, %w0 ;\n"
+ "adcl $0, %0 ;\n"
+ "notl %0 ;\n"
+"2: ;\n"
/* Since the input registers which are loaded with iph and ipl
are modified, we must also specify them as outputs, or gcc
will assume they contain their original values. */
@@ -102,28 +102,26 @@ static inline unsigned short ip_fast_csum(unsigned char * iph,
static inline unsigned int csum_fold(unsigned int sum)
{
- __asm__("
- addl %1, %0
- adcl $0xffff, %0
- "
+ __asm__(
+ "addl %1, %0 ;\n"
+ "adcl $0xffff, %0 ;\n"
: "=r" (sum)
: "r" (sum << 16), "0" (sum & 0xffff0000)
);
return (~sum) >> 16;
}
-
+
static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
- unsigned int sum)
+ unsigned int sum)
{
- __asm__("
- addl %1, %0
- adcl %2, %0
- adcl %3, %0
- adcl $0, %0
- "
+ __asm__(
+ "addl %1, %0 ;\n"
+ "adcl %2, %0 ;\n"
+ "adcl %3, %0 ;\n"
+ "adcl $0, %0 ;\n"
: "=r" (sum)
: "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
return sum;
@@ -137,7 +135,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
- unsigned int sum)
+ unsigned int sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
@@ -147,7 +145,8 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
* in icmp.c
*/
-static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
return csum_fold (csum_partial(buff, len, 0));
}
@@ -156,33 +155,32 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
struct in6_addr *daddr,
__u32 len,
unsigned short proto,
- unsigned int sum)
+ unsigned int sum)
{
- __asm__("
- addl 0(%1), %0
- adcl 4(%1), %0
- adcl 8(%1), %0
- adcl 12(%1), %0
- adcl 0(%2), %0
- adcl 4(%2), %0
- adcl 8(%2), %0
- adcl 12(%2), %0
- adcl %3, %0
- adcl %4, %0
- adcl $0, %0
- "
+ __asm__(
+ "addl 0(%1), %0 ;\n"
+ "adcl 4(%1), %0 ;\n"
+ "adcl 8(%1), %0 ;\n"
+ "adcl 12(%1), %0 ;\n"
+ "adcl 0(%2), %0 ;\n"
+ "adcl 4(%2), %0 ;\n"
+ "adcl 8(%2), %0 ;\n"
+ "adcl 12(%2), %0 ;\n"
+ "adcl %3, %0 ;\n"
+ "adcl %4, %0 ;\n"
+ "adcl $0, %0 ;\n"
: "=&r" (sum)
- : "r" (saddr), "r" (daddr),
+ : "r" (saddr), "r" (daddr),
"r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
return csum_fold(sum);
}
-/*
+/*
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
int len, int sum, int *err_ptr)
{
if (access_ok(VERIFY_WRITE, dst, len))
diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h
index 62f9fd831..0317b2f88 100644
--- a/include/asm-i386/floppy.h
+++ b/include/asm-i386/floppy.h
@@ -75,28 +75,28 @@ static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
#ifndef NO_FLOPPY_ASSEMBLER
__asm__ (
- "testl %1,%1
- je 3f
-1: inb %w4,%b0
- andb $160,%b0
- cmpb $160,%b0
- jne 2f
- incw %w4
- testl %3,%3
- jne 4f
- inb %w4,%b0
- movb %0,(%2)
- jmp 5f
-4: movb (%2),%0
- outb %b0,%w4
-5: decw %w4
- outb %0,$0x80
- decl %1
- incl %2
- testl %1,%1
- jne 1b
-3: inb %w4,%b0
-2: "
+ "testl %1,%1"
+ "je 3f"
+"1: inb %w4,%b0"
+ "andb $160,%b0"
+ "cmpb $160,%b0"
+ "jne 2f"
+ "incw %w4"
+ "testl %3,%3"
+ "jne 4f"
+ "inb %w4,%b0"
+ "movb %0,(%2)"
+ "jmp 5f"
+"4: movb (%2),%0"
+ "outb %b0,%w4"
+"5: decw %w4"
+ "outb %0,$0x80"
+ "decl %1"
+ "incl %2"
+ "testl %1,%1"
+ "jne 1b"
+"3: inb %w4,%b0"
+"2: "
: "=a" ((char) st),
"=c" ((long) virtual_dma_count),
"=S" ((long) virtual_dma_addr)
diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h
index 5107c3db1..af85f6354 100644
--- a/include/asm-i386/kmap_types.h
+++ b/include/asm-i386/kmap_types.h
@@ -7,6 +7,7 @@ enum km_type {
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
+ KM_BIO_IRQ,
KM_TYPE_NR
};
diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h
index 269d90b9d..82badf63f 100644
--- a/include/asm-m68k/machdep.h
+++ b/include/asm-m68k/machdep.h
@@ -1,11 +1,12 @@
#ifndef _M68K_MACHDEP_H
#define _M68K_MACHDEP_H
+#include <linux/seq_file.h>
+
struct pt_regs;
struct kbd_repeat;
struct mktime;
struct hwclk_time;
-struct gendisk;
struct buffer_head;
extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
@@ -22,7 +23,7 @@ extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, s
extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
extern void (*mach_get_model) (char *model);
extern int (*mach_get_hardware_list) (char *buffer);
-extern int (*mach_get_irq_list) (char *buf);
+extern int (*mach_get_irq_list) (struct seq_file *p, void *v);
extern void (*mach_process_int) (int irq, struct pt_regs *fp);
/* machine dependent timer functions */
extern unsigned long (*mach_gettimeoffset)(void);
diff --git a/include/asm-m68k/macintosh.h b/include/asm-m68k/macintosh.h
index e71462a8b..68d1249d3 100644
--- a/include/asm-m68k/macintosh.h
+++ b/include/asm-m68k/macintosh.h
@@ -1,6 +1,8 @@
#ifndef __ASM_MACINTOSH_H
#define __ASM_MACINTOSH_H
+#include <linux/seq_file.h>
+
/*
* Apple Macintoshisms
*/
@@ -15,7 +17,7 @@ extern void mac_free_irq(unsigned int, void *);
extern void mac_enable_irq(unsigned int);
extern void mac_disable_irq(unsigned int);
extern int mac_irq_pending(unsigned int);
-extern int mac_get_irq_list(char *);
+extern int show_mac_interrupts(struct seq_file *, void *);
#if 0
extern void mac_default_handler(int irq);
#endif
diff --git a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h
index ee082b5a2..408f33f9b 100644
--- a/include/asm-m68k/sun3ints.h
+++ b/include/asm-m68k/sun3ints.h
@@ -16,6 +16,7 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
+#include <linux/seq_file.h>
#include <asm/segment.h>
#include <asm/intersil.h>
#include <asm/oplib.h>
@@ -32,7 +33,7 @@ extern void (*sun3_inthandler[]) (int, void *, struct pt_regs *);
extern void sun3_free_irq (unsigned int irq, void *dev_id);
extern void sun3_enable_interrupts (void);
extern void sun3_disable_interrupts (void);
-extern int sun3_get_irq_list(char *buf);
+extern int show_sun3_interrupts(struct seq_file *, void *);
extern void sun3_process_int(int, struct pt_regs *);
extern volatile unsigned char* sun3_intreg;
diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h
index 427b28077..b2e9e78bb 100644
--- a/include/asm-ppc/kmap_types.h
+++ b/include/asm-ppc/kmap_types.h
@@ -11,6 +11,7 @@ enum km_type {
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
+ KM_BIO_IRQ,
KM_TYPE_NR
};
diff --git a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
index 5107c3db1..af85f6354 100644
--- a/include/asm-sparc/kmap_types.h
+++ b/include/asm-sparc/kmap_types.h
@@ -7,6 +7,7 @@ enum km_type {
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
+ KM_BIO_IRQ,
KM_TYPE_NR
};
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
index 466716913..8ffeb330a 100644
--- a/include/asm-sparc64/io.h
+++ b/include/asm-sparc64/io.h
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.41 2001-12-07 18:29:41 kanoj Exp $ */
+/* $Id: io.h,v 1.42 2001-12-11 04:55:54 davem Exp $ */
#ifndef __SPARC64_IO_H
#define __SPARC64_IO_H
@@ -18,6 +18,9 @@ extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr);
extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr);
#define bus_to_virt bus_to_virt_not_defined_use_pci_map
+extern unsigned long phys_base;
+#define page_to_phys(page) ((((page) - mem_map) << PAGE_SHIFT)+phys_base)
+
/* Different PCI controllers we support have their PCI MEM space
* mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area,
* so need to chop off the top 33 or 32 bits.
diff --git a/include/linux/bio.h b/include/linux/bio.h
new file mode 100644
index 000000000..098198393
--- /dev/null
+++ b/include/linux/bio.h
@@ -0,0 +1,179 @@
+/*
+ * 2.5 block I/O model
+ *
+ * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
+ */
+#ifndef __LINUX_BIO_H
+#define __LINUX_BIO_H
+
+#define BIO_DEBUG
+
+#ifdef BIO_DEBUG
+#define BIO_BUG_ON BUG_ON
+#else
+#define BIO_BUG_ON
+#endif
+
+/*
+ * was unsigned short, but we might as well be ready for > 64kB I/O pages
+ */
+struct bio_vec {
+ struct page *bv_page;
+ unsigned int bv_len;
+ unsigned int bv_offset;
+};
+
+/*
+ * weee, c forward decl...
+ */
+struct bio;
+typedef int (bio_end_io_t) (struct bio *, int);
+typedef void (bio_destructor_t) (struct bio *);
+
+/*
+ * main unit of I/O for the block layer and lower layers (ie drivers and
+ * stacking drivers)
+ */
+struct bio {
+ sector_t bi_sector;
+ struct bio *bi_next; /* request queue link */
+ kdev_t bi_dev; /* will be block device */
+ unsigned long bi_flags; /* status, command, etc */
+ unsigned long bi_rw; /* bottom bits READ/WRITE,
+ * top bits priority
+ */
+
+ unsigned int bi_vcnt; /* how many bio_vec's */
+ unsigned int bi_idx; /* current index into bvl_vec */
+ unsigned int bi_size; /* total size in bytes */
+ unsigned int bi_max; /* max bvl_vecs we can hold,
+ used as index into pool */
+
+ struct bio_vec *bi_io_vec; /* the actual vec list */
+
+ bio_end_io_t *bi_end_io;
+ atomic_t bi_cnt; /* pin count */
+
+ void *bi_private;
+
+ bio_destructor_t *bi_destructor; /* destructor */
+};
+
+/*
+ * bio flags
+ */
+#define BIO_UPTODATE 0 /* ok after I/O completion */
+#define BIO_RW_BLOCK 1 /* RW_AHEAD set, and read/write would block */
+#define BIO_EOF 2 /* out-out-bounds error */
+#define BIO_PREBUILT 3 /* not merged big */
+#define BIO_CLONED 4 /* doesn't own data */
+
+/*
+ * bio bi_rw flags
+ *
+ * bit 0 -- read (not set) or write (set)
+ * bit 1 -- rw-ahead when set
+ * bit 2 -- barrier
+ */
+#define BIO_RW 0
+#define BIO_RW_AHEAD 1
+#define BIO_RW_BARRIER 2
+
+/*
+ * various member access, note that bio_data should of course not be used
+ * on highmem page vectors
+ */
+#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)]))
+#define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx)
+#define bio_page(bio) bio_iovec((bio))->bv_page
+#define bio_offset(bio) bio_iovec((bio))->bv_offset
+#define bio_sectors(bio) ((bio)->bi_size >> 9)
+#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
+#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_BARRIER))
+
+/*
+ * will die
+ */
+#define bio_to_phys(bio) (page_to_phys(bio_page((bio))) + bio_offset((bio)))
+#define bvec_to_phys(bv) (page_to_phys((bv)->bv_page) + (bv)->bv_offset)
+
+/*
+ * queues that have highmem support enabled may still need to revert to
+ * PIO transfers occasionally and thus map high pages temporarily. For
+ * permanent PIO fall back, user is probably better off disabling highmem
+ * I/O completely on that queue (see ide-dma for example)
+ */
+#define __bio_kmap(bio, idx) (kmap(bio_iovec_idx((bio), (idx))->bv_page) + bio_iovec_idx((bio), (idx))->bv_offset)
+#define bio_kmap(bio) __bio_kmap((bio), (bio)->bi_idx)
+#define __bio_kunmap(bio, idx) kunmap(bio_iovec_idx((bio), (idx))->bv_page)
+#define bio_kunmap(bio) __bio_kunmap((bio), (bio)->bi_idx)
+
+/*
+ * merge helpers etc
+ */
+#define __BVEC_END(bio) bio_iovec_idx((bio), (bio)->bi_vcnt - 1)
+#define BIO_CONTIG(bio, nxt) \
+ (bvec_to_phys(__BVEC_END((bio))) + (bio)->bi_size == bio_to_phys((nxt)))
+#define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \
+ (((addr1) | (mask)) == (((addr2) - 1) | (mask)))
+#define BIO_SEG_BOUNDARY(q, b1, b2) \
+ __BIO_SEG_BOUNDARY(bvec_to_phys(__BVEC_END((b1))), bio_to_phys((b2)) + (b2)->bi_size, (q)->seg_boundary_mask)
+
+#define bio_io_error(bio) bio_endio((bio), 0, bio_sectors((bio)))
+
+/*
+ * drivers should not use the __ version unless they _really_ want to
+ * run through the entire bio and not just pending pieces
+ */
+#define __bio_for_each_segment(bvl, bio, i, start_idx) \
+ for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \
+ i < (bio)->bi_vcnt; \
+ bvl++, i++)
+
+#define bio_for_each_segment(bvl, bio, i) \
+ __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx)
+
+/*
+ * get a reference to a bio, so it won't disappear. the intended use is
+ * something like:
+ *
+ * bio_get(bio);
+ * submit_bio(rw, bio);
+ * if (bio->bi_flags ...)
+ * do_something
+ * bio_put(bio);
+ *
+ * without the bio_get(), it could potentially complete I/O before submit_bio
+ * returns. and then bio would be freed memory when if (bio->bi_flags ...)
+ * runs
+ */
+#define bio_get(bio) atomic_inc(&(bio)->bi_cnt)
+
+extern struct bio *bio_alloc(int, int);
+extern void bio_put(struct bio *);
+
+extern int bio_endio(struct bio *, int, int);
+
+extern inline void __bio_clone(struct bio *, struct bio *);
+extern struct bio *bio_clone(struct bio *, int);
+extern struct bio *bio_copy(struct bio *, int, int);
+
+extern inline void bio_init(struct bio *);
+
+extern int bio_ioctl(kdev_t, unsigned int, unsigned long);
+
+#endif /* __LINUX_BIO_H */
diff --git a/include/linux/blk.h b/include/linux/blk.h
index b09f5afa9..e3155fcaa 100644
--- a/include/linux/blk.h
+++ b/include/linux/blk.h
@@ -5,65 +5,15 @@
#include <linux/locks.h>
#include <linux/config.h>
#include <linux/spinlock.h>
+#include <linux/compiler.h>
/*
- * Spinlock for protecting the request queue which
- * is mucked around with in interrupts on potentially
- * multiple CPU's..
+ * get rid of this next...
*/
-extern spinlock_t io_request_lock;
-
-/*
- * Initialization functions.
- */
-extern int isp16_init(void);
-extern int cdu31a_init(void);
-extern int acsi_init(void);
-extern int mcd_init(void);
-extern int mcdx_init(void);
-extern int sbpcd_init(void);
-extern int aztcd_init(void);
-extern int sony535_init(void);
-extern int gscd_init(void);
-extern int cm206_init(void);
-extern int optcd_init(void);
-extern int sjcd_init(void);
-extern int cdi_init(void);
-extern int hd_init(void);
extern int ide_init(void);
-extern int xd_init(void);
-extern int mfm_init(void);
-extern int loop_init(void);
-extern int md_init(void);
-extern int ap_init(void);
-extern int ddv_init(void);
-extern int z2_init(void);
-extern int swim3_init(void);
-extern int swimiop_init(void);
-extern int amiga_floppy_init(void);
-extern int atari_floppy_init(void);
-extern int ez_init(void);
-extern int bpcd_init(void);
-extern int ps2esdi_init(void);
-extern int jsfd_init(void);
-extern int viodasd_init(void);
-extern int viocd_init(void);
-
-#if defined(CONFIG_ARCH_S390)
-extern int dasd_init(void);
-extern int xpram_init(void);
-extern int tapeblock_init(void);
-#endif /* CONFIG_ARCH_S390 */
extern void set_device_ro(kdev_t dev,int flag);
-void add_blkdev_randomness(int major);
-
-extern int floppy_init(void);
-extern void rd_load(void);
-extern int rd_init(void);
-extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start; /* starting block # of image */
+extern void add_blkdev_randomness(int major);
#ifdef CONFIG_BLK_DEV_INITRD
@@ -72,11 +22,12 @@ extern int rd_image_start; /* starting block # of image */
extern unsigned long initrd_start,initrd_end;
extern int mount_initrd; /* zero if initrd should not be mounted */
extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < memory_start */
+extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start; /* starting block # of image */
void initrd_init(void);
#endif
-
-
/*
* end_request() and friends. Must be called with the request queue spinlock
* acquired. All functions called within end_request() _must_be_ atomic.
@@ -87,14 +38,60 @@ void initrd_init(void);
* code duplication in drivers.
*/
-static inline void blkdev_dequeue_request(struct request * req)
+extern int end_that_request_first(struct request *, int, int);
+extern void end_that_request_last(struct request *);
+
+static inline void blkdev_dequeue_request(struct request *req)
{
- list_del(&req->queue);
+ list_del(&req->queuelist);
}
-int end_that_request_first(struct request *req, int uptodate, char *name);
-void end_that_request_last(struct request *req);
+#define __elv_next_request(q) (q)->elevator.elevator_next_req_fn((q))
+
+extern inline struct request *elv_next_request(request_queue_t *q)
+{
+ struct request *rq;
+
+ while ((rq = __elv_next_request(q))) {
+ rq->flags |= REQ_STARTED;
+
+ if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
+ break;
+
+ /*
+ * all ok, break and return it
+ */
+ if (!q->prep_rq_fn(q, rq))
+ break;
+
+ /*
+ * prep said no-go, kill it
+ */
+ blkdev_dequeue_request(rq);
+ if (end_that_request_first(rq, 0, rq->nr_sectors))
+ BUG();
+
+ end_that_request_last(rq);
+ }
+ return rq;
+}
+
+#define __elv_add_request_core(q, rq, where, plug) \
+ do { \
+ if ((plug)) \
+ blk_plug_device((q)); \
+ (q)->elevator.elevator_add_req_fn((q), (rq), (where)); \
+ } while (0)
+
+#define __elv_add_request(q, rq, back, p) \
+ if ((back)) \
+ __elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \
+ else \
+ __elv_add_request_core((q), (rq), &(q)->queue_head, 0); \
+
+#define elv_add_request(q, rq, back) __elv_add_request((q), (rq), (back), 1)
+
#if defined(MAJOR_NR) || defined(IDE_DRIVER)
#undef DEVICE_ON
@@ -338,12 +335,16 @@ static void floppy_off(unsigned int nr);
#if !defined(IDE_DRIVER)
#ifndef CURRENT
-#define CURRENT blkdev_entry_next_request(&blk_dev[MAJOR_NR].request_queue.queue_head)
+#define CURRENT elv_next_request(&blk_dev[MAJOR_NR].request_queue)
+#endif
+#ifndef QUEUE
+#define QUEUE (&blk_dev[MAJOR_NR].request_queue)
#endif
#ifndef QUEUE_EMPTY
-#define QUEUE_EMPTY list_empty(&blk_dev[MAJOR_NR].request_queue.queue_head)
+#define QUEUE_EMPTY blk_queue_empty(QUEUE)
#endif
+
#ifndef DEVICE_NAME
#define DEVICE_NAME "unknown"
#endif
@@ -366,17 +367,15 @@ static void (DEVICE_REQUEST)(request_queue_t *);
#define CLEAR_INTR
#endif
-#define INIT_REQUEST \
- if (QUEUE_EMPTY) {\
- CLEAR_INTR; \
- return; \
- } \
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
- panic(DEVICE_NAME ": request list destroyed"); \
- if (CURRENT->bh) { \
- if (!buffer_locked(CURRENT->bh)) \
- panic(DEVICE_NAME ": block not locked"); \
- }
+#define INIT_REQUEST \
+ if (QUEUE_EMPTY) { \
+ CLEAR_INTR; \
+ return; \
+ } \
+ if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
+ panic(DEVICE_NAME ": request list destroyed"); \
+ if (!CURRENT->bio) \
+ panic(DEVICE_NAME ": no bio"); \
#endif /* !defined(IDE_DRIVER) */
@@ -385,10 +384,11 @@ static void (DEVICE_REQUEST)(request_queue_t *);
#if ! SCSI_BLK_MAJOR(MAJOR_NR) && (MAJOR_NR != COMPAQ_SMART2_MAJOR)
-static inline void end_request(int uptodate) {
+static inline void end_request(int uptodate)
+{
struct request *req = CURRENT;
- if (end_that_request_first(req, uptodate, DEVICE_NAME))
+ if (end_that_request_first(req, uptodate, CURRENT->hard_cur_sectors))
return;
#ifndef DEVICE_NO_RANDOM
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 6b78b45eb..e9e0cf210 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -6,71 +6,116 @@
#include <linux/genhd.h>
#include <linux/tqueue.h>
#include <linux/list.h>
+#include <linux/mm.h>
+
+#include <asm/scatterlist.h>
struct request_queue;
typedef struct request_queue request_queue_t;
struct elevator_s;
typedef struct elevator_s elevator_t;
-/*
- * Ok, this is an expanded form so that we can use the same
- * request for paging requests.
- */
+struct request_list {
+ unsigned int count;
+ struct list_head free;
+ wait_queue_head_t wait;
+};
+
struct request {
- struct list_head queue;
+ struct list_head queuelist; /* looking for ->queue? you must _not_
+ * access it directly, use
+ * blkdev_dequeue_request! */
int elevator_sequence;
- volatile int rq_status; /* should split this into a few status bits */
-#define RQ_INACTIVE (-1)
-#define RQ_ACTIVE 1
-#define RQ_SCSI_BUSY 0xffff
-#define RQ_SCSI_DONE 0xfffe
-#define RQ_SCSI_DISCONNECTING 0xffe0
+ unsigned char cmd[16];
+ unsigned long flags; /* see REQ_ bits below */
+
+ int rq_status; /* should split this into a few status bits */
kdev_t rq_dev;
- int cmd; /* READ or WRITE */
int errors;
- unsigned long sector;
+ sector_t sector;
unsigned long nr_sectors;
- unsigned long hard_sector, hard_nr_sectors;
- unsigned int nr_segments;
- unsigned int nr_hw_segments;
- unsigned long current_nr_sectors;
- void * special;
- char * buffer;
- struct completion * waiting;
- struct buffer_head * bh;
- struct buffer_head * bhtail;
+ unsigned long hard_sector; /* the hard_* are block layer
+ * internals, no driver should
+ * touch them
+ */
+ unsigned long hard_nr_sectors;
+ unsigned short nr_segments;
+ unsigned short nr_hw_segments;
+ unsigned int current_nr_sectors;
+ unsigned int hard_cur_sectors;
+ void *special;
+ char *buffer;
+ struct completion *waiting;
+ struct bio *bio, *biotail;
request_queue_t *q;
+ struct request_list *rl;
};
+/*
+ * first three bits match BIO_RW* bits, important
+ */
+enum rq_flag_bits {
+ __REQ_RW, /* not set, read. set, write */
+ __REQ_RW_AHEAD, /* READA */
+ __REQ_BARRIER, /* may not be passed */
+ __REQ_CMD, /* is a regular fs rw request */
+ __REQ_NOMERGE, /* don't touch this for merging */
+ __REQ_STARTED, /* drive already may have started this one */
+ __REQ_DONTPREP, /* don't call prep for this one */
+ /*
+ * for IDE
+ */
+ __REQ_DRIVE_CMD,
+ __REQ_DRIVE_TASK,
+
+ __REQ_PC, /* packet command (special) */
+ __REQ_BLOCK_PC, /* queued down pc from block layer */
+ __REQ_SENSE, /* sense retrival */
+
+ __REQ_SPECIAL, /* driver special command */
+
+ __REQ_NR_BITS, /* stops here */
+};
+
+#define REQ_RW (1 << __REQ_RW)
+#define REQ_RW_AHEAD (1 << __REQ_RW_AHEAD)
+#define REQ_BARRIER (1 << __REQ_BARRIER)
+#define REQ_CMD (1 << __REQ_CMD)
+#define REQ_NOMERGE (1 << __REQ_NOMERGE)
+#define REQ_STARTED (1 << __REQ_STARTED)
+#define REQ_DONTPREP (1 << __REQ_DONTPREP)
+#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)
+#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
+#define REQ_PC (1 << __REQ_PC)
+#define REQ_SENSE (1 << __REQ_SENSE)
+#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
+#define REQ_SPECIAL (1 << __REQ_SPECIAL)
+
#include <linux/elevator.h>
-typedef int (merge_request_fn) (request_queue_t *q,
- struct request *req,
- struct buffer_head *bh,
- int);
-typedef int (merge_requests_fn) (request_queue_t *q,
- struct request *req,
- struct request *req2,
- int);
+typedef int (merge_request_fn) (request_queue_t *, struct request *,
+ struct bio *);
+typedef int (merge_requests_fn) (request_queue_t *, struct request *,
+ struct request *);
typedef void (request_fn_proc) (request_queue_t *q);
typedef request_queue_t * (queue_proc) (kdev_t dev);
-typedef int (make_request_fn) (request_queue_t *q, int rw, struct buffer_head *bh);
-typedef void (plug_device_fn) (request_queue_t *q, kdev_t device);
+typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
+typedef int (prep_rq_fn) (request_queue_t *, struct request *);
typedef void (unplug_device_fn) (void *q);
+enum blk_queue_state {
+ Queue_down,
+ Queue_up,
+};
+
/*
* Default nr free requests per queue, ll_rw_blk will scale it down
* according to available RAM at init time
*/
#define QUEUE_NR_REQUESTS 8192
-struct request_list {
- unsigned int count;
- struct list_head free;
-};
-
struct request_queue
{
/*
@@ -84,46 +129,99 @@ struct request_queue
struct list_head queue_head;
elevator_t elevator;
- request_fn_proc * request_fn;
- merge_request_fn * back_merge_fn;
- merge_request_fn * front_merge_fn;
- merge_requests_fn * merge_requests_fn;
- make_request_fn * make_request_fn;
- plug_device_fn * plug_device_fn;
+ request_fn_proc *request_fn;
+ merge_request_fn *back_merge_fn;
+ merge_request_fn *front_merge_fn;
+ merge_requests_fn *merge_requests_fn;
+ make_request_fn *make_request_fn;
+ prep_rq_fn *prep_rq_fn;
+
/*
* The queue owner gets to use this for whatever they like.
* ll_rw_blk doesn't touch it.
*/
- void * queuedata;
+ void *queuedata;
/*
- * This is used to remove the plug when tq_disk runs.
+ * queue needs bounce pages for pages above this limit
*/
- struct tq_struct plug_tq;
+ unsigned long bounce_pfn;
/*
- * Boolean that indicates whether this queue is plugged or not.
+ * This is used to remove the plug when tq_disk runs.
*/
- char plugged;
+ struct tq_struct plug_tq;
/*
- * Boolean that indicates whether current_request is active or
- * not.
+ * various queue flags, see QUEUE_* below
*/
- char head_active;
+ unsigned long queue_flags;
/*
- * Is meant to protect the queue in the future instead of
- * io_request_lock
+ * protects queue structures from reentrancy
*/
spinlock_t queue_lock;
/*
- * Tasks wait here for free request
+ * queue settings
*/
- wait_queue_head_t wait_for_request;
+ unsigned short max_sectors;
+ unsigned short max_segments;
+ unsigned short hardsect_size;
+ unsigned int max_segment_size;
+
+ unsigned long seg_boundary_mask;
+
+ wait_queue_head_t queue_wait;
};
+#define RQ_INACTIVE (-1)
+#define RQ_ACTIVE 1
+#define RQ_SCSI_BUSY 0xffff
+#define RQ_SCSI_DONE 0xfffe
+#define RQ_SCSI_DISCONNECTING 0xffe0
+
+#define QUEUE_FLAG_PLUGGED 0 /* queue is plugged */
+#define QUEUE_FLAG_NOSPLIT 1 /* can process bio over several goes */
+#define QUEUE_FLAG_CLUSTER 2 /* cluster several segments into 1 */
+
+#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
+#define blk_mark_plugged(q) set_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
+#define blk_queue_empty(q) elv_queue_empty(q)
+#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
+
+#define rq_data_dir(rq) ((rq)->flags & 1)
+
+/*
+ * noop, requests are automagically marked as active/inactive by I/O
+ * scheduler -- see elv_next_request
+ */
+#define blk_queue_headactive(q, head_active)
+
+extern unsigned long blk_max_low_pfn, blk_max_pfn;
+
+#define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT)
+#define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT)
+
+#ifdef CONFIG_HIGHMEM
+
+extern void create_bounce(unsigned long pfn, struct bio **bio_orig);
+
+extern inline void blk_queue_bounce(request_queue_t *q, struct bio **bio)
+{
+ create_bounce(q->bounce_pfn, bio);
+}
+
+#else /* CONFIG_HIGHMEM */
+
+#define blk_queue_bounce(q, bio) do { } while (0)
+
+#endif /* CONFIG_HIGHMEM */
+
+#define rq_for_each_bio(bio, rq) \
+ if ((rq->bio)) \
+ for (bio = (rq)->bio; bio; bio = bio->bi_next)
+
struct blk_dev_struct {
/*
* queue_proc has to be atomic
@@ -148,64 +246,84 @@ struct sec_size {
extern struct sec_size * blk_sec[MAX_BLKDEV];
extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
-extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
+extern void grok_partitions(kdev_t dev, long size);
+extern int wipe_partitions(kdev_t dev);
extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
-extern void generic_make_request(int rw, struct buffer_head * bh);
+extern void generic_make_request(struct bio *bio);
extern inline request_queue_t *blk_get_queue(kdev_t dev);
extern void blkdev_release_request(struct request *);
+extern void blk_attempt_remerge(request_queue_t *, struct request *);
+extern struct request *blk_get_request(request_queue_t *, int, int);
+extern void blk_put_request(struct request *);
+extern void blk_plug_device(request_queue_t *);
+
+extern int block_ioctl(kdev_t, unsigned int, unsigned long);
/*
* Access functions for manipulating queue properties
*/
-extern void blk_init_queue(request_queue_t *, request_fn_proc *);
+extern int blk_init_queue(request_queue_t *, request_fn_proc *);
extern void blk_cleanup_queue(request_queue_t *);
-extern void blk_queue_headactive(request_queue_t *, int);
extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
+extern void blk_queue_bounce_limit(request_queue_t *, u64);
+extern void blk_queue_max_sectors(request_queue_t *q, unsigned short);
+extern void blk_queue_max_segments(request_queue_t *q, unsigned short);
+extern void blk_queue_max_segment_size(request_queue_t *q, unsigned int);
+extern void blk_queue_hardsect_size(request_queue_t *q, unsigned short);
+extern void blk_queue_segment_boundary(request_queue_t *q, unsigned long);
+extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
+extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(void *);
extern int * blk_size[MAX_BLKDEV];
extern int * blksize_size[MAX_BLKDEV];
-extern int * hardsect_size[MAX_BLKDEV];
-
extern int * max_readahead[MAX_BLKDEV];
-extern int * max_sectors[MAX_BLKDEV];
-
-extern int * max_segments[MAX_BLKDEV];
-
#define MAX_SEGMENTS 128
#define MAX_SECTORS 255
-#define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
+#define MAX_SEGMENT_SIZE 65536
-#define blkdev_entry_to_request(entry) list_entry((entry), struct request, queue)
+/* read-ahead in pages.. */
+#define MAX_READAHEAD 31
+#define MIN_READAHEAD 3
+
+#define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
#define blkdev_entry_next_request(entry) blkdev_entry_to_request((entry)->next)
#define blkdev_entry_prev_request(entry) blkdev_entry_to_request((entry)->prev)
-#define blkdev_next_request(req) blkdev_entry_to_request((req)->queue.next)
-#define blkdev_prev_request(req) blkdev_entry_to_request((req)->queue.prev)
+#define blkdev_next_request(req) blkdev_entry_to_request((req)->queuelist.next)
+#define blkdev_prev_request(req) blkdev_entry_to_request((req)->queuelist.prev)
+
+extern void drive_stat_acct(struct request *, int, int);
-extern void drive_stat_acct (kdev_t dev, int rw,
- unsigned long nr_sectors, int new_io);
+extern inline void blk_clear(int major)
+{
+ blk_size[major] = NULL;
+#if 0
+ blk_size_in_bytes[major] = NULL;
+#endif
+ blksize_size[major] = NULL;
+ max_readahead[major] = NULL;
+ read_ahead[major] = 0;
+}
-static inline int get_hardsect_size(kdev_t dev)
+extern inline int get_hardsect_size(kdev_t dev)
{
+ request_queue_t *q = blk_get_queue(dev);
int retval = 512;
- int major = MAJOR(dev);
- if (hardsect_size[major]) {
- int minor = MINOR(dev);
- if (hardsect_size[major][minor])
- retval = hardsect_size[major][minor];
- }
+ if (q && q->hardsect_size)
+ retval = q->hardsect_size;
+
return retval;
}
#define blk_finished_io(nsects) do { } while (0)
#define blk_started_io(nsects) do { } while (0)
-static inline unsigned int blksize_bits(unsigned int size)
+extern inline unsigned int blksize_bits(unsigned int size)
{
unsigned int bits = 8;
do {
@@ -215,7 +333,7 @@ static inline unsigned int blksize_bits(unsigned int size)
return bits;
}
-static inline unsigned int block_size(kdev_t dev)
+extern inline unsigned int block_size(kdev_t dev)
{
int retval = BLOCK_SIZE;
int major = MAJOR(dev);
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 6560f2901..3bd68c042 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -18,6 +18,11 @@ extern unsigned long max_low_pfn;
extern unsigned long min_low_pfn;
/*
+ * highest page
+ */
+extern unsigned long max_pfn;
+
+/*
* node_bootmem_map is a map pointer - the bits represent all physical
* memory pages (including holes) on the node.
*/
diff --git a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
index 545e2ef5f..df5aee5e7 100644
--- a/include/linux/devfs_fs_kernel.h
+++ b/include/linux/devfs_fs_kernel.h
@@ -3,7 +3,7 @@
#include <linux/fs.h>
#include <linux/config.h>
-#include <linux/locks.h>
+#include <linux/spinlock.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
diff --git a/include/linux/device.h b/include/linux/device.h
new file mode 100644
index 000000000..32a2fed4d
--- /dev/null
+++ b/include/linux/device.h
@@ -0,0 +1,253 @@
+/*
+ * device.h - generic, centralized driver model
+ *
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ *
+ * This is a relatively simple centralized driver model.
+ * The data structures were mainly lifted directly from the PCI
+ * driver model. These are thought to be the common fields that
+ * are relevant to all device buses.
+ *
+ * All the devices are arranged in a tree. All devices should
+ * have some sort of parent bus of whom they are children of.
+ * Devices should not be direct children of the system root.
+ *
+ * Device drivers should not directly call the device_* routines
+ * or access the contents of struct device directly. Instead,
+ * abstract that from the drivers and write bus-specific wrappers
+ * that do it for you.
+ *
+ * See Documentation/driver-model.txt for more information.
+ */
+
+#ifndef _DEVICE_H_
+#define _DEVICE_H_
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/driverfs_fs.h>
+
+#define DEVICE_NAME_SIZE 80
+#define DEVICE_ID_SIZE 32
+#define BUS_ID_SIZE 16
+
+
+enum {
+ SUSPEND_NOTIFY,
+ SUSPEND_SAVE_STATE,
+ SUSPEND_DISABLE,
+ SUSPEND_POWER_DOWN,
+};
+
+enum {
+ RESUME_POWER_ON,
+ RESUME_RESTORE_STATE,
+ RESUME_ENABLE,
+};
+
+enum {
+ REMOVE_NOTIFY,
+ REMOVE_FREE_RESOURCES,
+};
+
+struct device;
+struct iobus;
+
+struct device_driver {
+ int (*probe) (struct device * dev);
+ int (*remove) (struct device * dev, u32 flags);
+
+ int (*suspend) (struct device * dev, u32 state, u32 stage);
+ int (*resume) (struct device * dev, u32 stage);
+};
+
+struct device {
+ struct list_head node; /* node in sibling list */
+ struct iobus *parent; /* parent bus */
+
+ struct iobus *subordinate; /* only valid if this device is a
+ bridge device */
+
+ char name[DEVICE_NAME_SIZE]; /* descriptive ascii string */
+ char bus_id[BUS_ID_SIZE]; /* position on parent bus */
+
+ spinlock_t lock; /* lock for the device to ensure two
+ different layers don't access it at
+ the same time. */
+ atomic_t refcount; /* refcount to make sure the device
+ * persists for the right amount of time */
+
+ struct driver_dir_entry * dir;
+
+ struct device_driver *driver; /* which driver has allocated this
+ device */
+ void *driver_data; /* data private to the driver */
+ void *platform_data; /* Platform specific data (e.g. ACPI,
+ BIOS data relevant to device */
+
+ u32 current_state; /* Current operating state. In
+ ACPI-speak, this is D0-D3, D0
+ being fully functional, and D3
+ being off. */
+
+ unsigned char *saved_state; /* saved device state */
+};
+
+/*
+ * struct bus_type - descriptor for a type of bus
+ * There are some instances when you need to know what type of bus a
+ * device is on. Instead of having some sort of enumerated integer type,
+ * each struct iobus will have a pointer to a struct bus_type that gives
+ * actually meaningful data.
+ * There should be one struct bus_type for each type of bus (one for PCI,
+ * one for USB, etc).
+ */
+struct iobus_driver {
+ char name[16]; /* ascii descriptor of type of bus */
+ struct list_head node; /* node in global list of bus drivers */
+
+ int (*scan) (struct iobus*);
+ int (*add_device) (struct iobus*, char*);
+};
+
+struct iobus {
+ spinlock_t lock; /* lock for bus */
+ atomic_t refcount;
+
+ struct list_head node; /* node in sibling list */
+ struct iobus *parent; /* parent bus */
+ struct list_head children; /* children buses */
+ struct list_head devices; /* children devices */
+
+ struct device *self; /* pointer to controlling device */
+ struct driver_dir_entry * dir; /* driverfs directory */
+
+ char name[DEVICE_NAME_SIZE];
+ char bus_id[BUS_ID_SIZE];
+
+ struct iobus_driver *driver; /* bus operations */
+};
+
+static inline struct device *
+list_to_dev(struct list_head *node)
+{
+ return list_entry(node, struct device, node);
+}
+
+static inline struct iobus *
+list_to_iobus(const struct list_head *node)
+{
+ return list_entry(node, struct iobus, node);
+}
+
+/*
+ * High level routines for use by the bus drivers
+ */
+extern int device_register(struct device * dev);
+extern struct device * device_alloc(void);
+extern void device_init_dev(struct device * dev);
+
+extern int iobus_register(struct iobus * iobus);
+extern struct iobus * iobus_alloc(void);
+extern void iobus_init(struct iobus * iobus);
+
+extern int device_create_file(struct device *device, const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data);
+extern void device_remove_file(struct device * dev, const char * name);
+
+extern int iobus_create_file(struct iobus *bus, const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data);
+extern void iobus_remove_file(struct iobus * iobus, const char * name);
+
+
+/*
+ * Platform "fixup" functions - allow the platform to have their say
+ * about devices and actions that the general device layer doesn't
+ * know about.
+ */
+/* Notify platform of device discovery */
+extern int (*platform_notify)(struct device * dev);
+
+extern int (*platform_notify_remove)(struct device * dev);
+
+extern int device_driver_init(void);
+
+
+/* device and bus locking helpers.
+ *
+ * FIXME: Is there anything else we need to do?
+ */
+static inline void lock_device(struct device * dev)
+{
+ spin_lock(&dev->lock);
+}
+
+static inline void unlock_device(struct device * dev)
+{
+ spin_unlock(&dev->lock);
+}
+
+/**
+ * get_device - atomically increment the reference count for the device.
+ *
+ */
+static inline void get_device(struct device * dev)
+{
+ atomic_inc(&dev->refcount);
+}
+
+extern void put_device(struct device * dev);
+
+
+/**
+ * valid_device - check if device is valid
+ * @dev: device in question
+ *
+ * Check whether or not a device can be operated on.
+ * If so, increment the reference count and carry on.
+ */
+static inline int valid_device(struct device * dev)
+{
+ int val;
+
+ lock_device(dev);
+ val = atomic_read(&dev->refcount);
+ if (val)
+ get_device(dev);
+ unlock_device(dev);
+ return (val > 0);
+}
+
+
+static inline void lock_iobus(struct iobus * iobus)
+{
+ spin_lock(&iobus->lock);
+}
+
+static inline void unlock_iobus(struct iobus * iobus)
+{
+ spin_unlock(&iobus->lock);
+}
+
+static inline void get_iobus(struct iobus * iobus)
+{
+ atomic_inc(&iobus->refcount);
+}
+
+static inline int valid_iobus(struct iobus * iobus)
+{
+ int val;
+ lock_iobus(iobus);
+ val = atomic_read(&iobus->refcount);
+ if (val)
+ get_iobus(iobus);
+ unlock_iobus(iobus);
+ return (val > 0);
+}
+
+extern void put_iobus(struct iobus * iobus);
+
+#endif /* _DEVICE_H_ */
diff --git a/include/linux/driverfs_fs.h b/include/linux/driverfs_fs.h
new file mode 100644
index 000000000..90a603430
--- /dev/null
+++ b/include/linux/driverfs_fs.h
@@ -0,0 +1,73 @@
+/*
+ * driverfs_fs.h - definitions for the device driver filesystem
+ *
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This is a simple, ram-based filesystem, which allows kernel
+ * callbacks for read/write of files.
+ *
+ * Please see Documentation/filesystems/driverfs.txt for more information.
+ */
+
+#ifndef _DRIVER_FS_H_
+#define _DRIVER_FS_H_
+
+struct driverfs_operations {
+ ssize_t (*read) (char *, size_t, loff_t, void *);
+ ssize_t (*write)(const char *, size_t, loff_t, void*);
+};
+
+struct driver_dir_entry {
+ char * name;
+ struct dentry * dentry;
+ mode_t mode;
+ struct list_head files;
+};
+
+struct driver_file_entry {
+ struct driver_dir_entry * parent;
+ struct list_head node;
+ char * name;
+ mode_t mode;
+ struct dentry * dentry;
+ void * data;
+ struct driverfs_operations * ops;
+};
+
+extern struct driver_dir_entry *
+driverfs_create_dir_entry(const char * name, mode_t mode);
+
+extern int
+driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *);
+
+extern void
+driverfs_remove_dir(struct driver_dir_entry * entry);
+
+extern struct driver_file_entry *
+driverfs_create_entry (const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data);
+
+extern int
+driverfs_create_file(struct driver_file_entry * entry,
+ struct driver_dir_entry * parent);
+
+extern void
+driverfs_remove_file(struct driver_dir_entry *, const char * name);
+
+extern int init_driverfs_fs(void);
+
+#endif /* _DDFS_H_ */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 1a8bb5c39..df4c50a95 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -5,13 +5,20 @@ typedef void (elevator_fn) (struct request *, elevator_t *,
struct list_head *,
struct list_head *, int);
-typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct list_head *,
- struct buffer_head *, int, int);
+typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
+ struct list_head *, struct bio *);
typedef void (elevator_merge_cleanup_fn) (request_queue_t *, struct request *, int);
typedef void (elevator_merge_req_fn) (struct request *, 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 int (elevator_init_fn) (request_queue_t *, elevator_t *);
+typedef void (elevator_exit_fn) (request_queue_t *, elevator_t *);
+
struct elevator_s
{
int read_latency;
@@ -21,31 +28,39 @@ struct elevator_s
elevator_merge_cleanup_fn *elevator_merge_cleanup_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
- unsigned int queue_ID;
+ elevator_next_req_fn *elevator_next_req_fn;
+ elevator_add_req_fn *elevator_add_req_fn;
+
+ elevator_init_fn *elevator_init_fn;
+ elevator_exit_fn *elevator_exit_fn;
};
-int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
+int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct bio *);
void elevator_noop_merge_cleanup(request_queue_t *, struct request *, int);
void elevator_noop_merge_req(struct request *, struct request *);
-int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
+int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct bio *);
void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int);
void elevator_linus_merge_req(struct request *, struct request *);
+int elv_linus_init(request_queue_t *, elevator_t *);
+void elv_linus_exit(request_queue_t *, elevator_t *);
+struct request *elv_next_request_fn(request_queue_t *);
+void elv_add_request_fn(request_queue_t *, struct request *,struct list_head *);
+/*
+ * use the /proc/iosched interface, all the below is history ->
+ */
typedef struct blkelv_ioctl_arg_s {
int queue_ID;
int read_latency;
int write_latency;
int max_bomb_segments;
} blkelv_ioctl_arg_t;
-
#define BLKELVGET _IOR(0x12,106,sizeof(blkelv_ioctl_arg_t))
#define BLKELVSET _IOW(0x12,107,sizeof(blkelv_ioctl_arg_t))
-extern int blkelvget_ioctl(elevator_t *, blkelv_ioctl_arg_t *);
-extern int blkelvset_ioctl(elevator_t *, const blkelv_ioctl_arg_t *);
-
-extern void elevator_init(elevator_t *, elevator_t);
+extern int elevator_init(request_queue_t *, elevator_t *, elevator_t);
+extern void elevator_exit(request_queue_t *, elevator_t *);
/*
* Return values from elevator merger
@@ -81,6 +96,24 @@ static inline int elevator_request_latency(elevator_t * elevator, int rw)
return latency;
}
+/*
+ * will change once we move to a more complex data structure than a simple
+ * list for pending requests
+ */
+#define elv_queue_empty(q) list_empty(&(q)->queue_head)
+
+/*
+ * elevator private data
+ */
+struct elv_linus_data {
+ unsigned long flags;
+};
+
+#define ELV_DAT(e) ((struct elv_linus_data *)(e)->elevator_data)
+
+#define ELV_LINUS_BACK_MERGE 1
+#define ELV_LINUS_FRONT_MERGE 2
+
#define ELEVATOR_NOOP \
((elevator_t) { \
0, /* read_latency */ \
@@ -89,6 +122,10 @@ static inline int elevator_request_latency(elevator_t * elevator, int rw)
elevator_noop_merge, /* elevator_merge_fn */ \
elevator_noop_merge_cleanup, /* elevator_merge_cleanup_fn */ \
elevator_noop_merge_req, /* elevator_merge_req_fn */ \
+ elv_next_request_fn, \
+ elv_add_request_fn, \
+ elv_linus_init, \
+ elv_linus_exit, \
})
#define ELEVATOR_LINUS \
@@ -99,6 +136,10 @@ static inline int elevator_request_latency(elevator_t * elevator, int rw)
elevator_linus_merge, /* elevator_merge_fn */ \
elevator_linus_merge_cleanup, /* elevator_merge_cleanup_fn */ \
elevator_linus_merge_req, /* elevator_merge_req_fn */ \
+ elv_next_request_fn, \
+ elv_add_request_fn, \
+ elv_linus_init, \
+ elv_linus_exit, \
})
#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dbd67914f..7f52b46d6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -21,6 +21,7 @@
#include <linux/cache.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/bio.h>
#include <asm/atomic.h>
#include <asm/bitops.h>
@@ -74,6 +75,8 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define FMODE_READ 1
#define FMODE_WRITE 2
+#define RW_MASK 1
+#define RWA_MASK 2
#define READ 0
#define WRITE 1
#define READA 2 /* read-ahead - don't block if no resources */
@@ -108,6 +111,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define MS_NOATIME 1024 /* Do not update access times. */
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
+#define MS_MOVE 8192
#define MS_REC 16384
#define MS_VERBOSE 32768
#define MS_ACTIVE (1<<30)
@@ -238,28 +242,24 @@ enum bh_state_bits {
struct buffer_head {
/* First cache line: */
struct buffer_head *b_next; /* Hash queue list */
- unsigned long b_blocknr; /* block number */
+ sector_t b_blocknr; /* block number */
unsigned short b_size; /* block size */
unsigned short b_list; /* List that this buffer appears */
kdev_t b_dev; /* device (B_FREE = free) */
atomic_t b_count; /* users using this block */
- kdev_t b_rdev; /* Real device */
unsigned long b_state; /* buffer state bitmap (see above) */
unsigned long b_flushtime; /* Time when (dirty) buffer should be written */
struct buffer_head *b_next_free;/* lru/free list linkage */
struct buffer_head *b_prev_free;/* doubly linked list of buffers */
struct buffer_head *b_this_page;/* circular list of buffers in one page */
- struct buffer_head *b_reqnext; /* request queue */
-
struct buffer_head **b_pprev; /* doubly linked list of hash-queue */
char * b_data; /* pointer to data block */
struct page *b_page; /* the page this bh is mapped to */
void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */
void *b_private; /* reserved for b_end_io */
- unsigned long b_rsector; /* Real buffer location on disk */
wait_queue_head_t b_wait;
struct inode * b_inode;
@@ -1173,12 +1173,25 @@ static inline void mark_buffer_async(struct buffer_head * bh, int on)
static inline void buffer_IO_error(struct buffer_head * bh)
{
mark_buffer_clean(bh);
+
/*
- * b_end_io has to clear the BH_Uptodate bitflag in the error case!
+ * b_end_io has to clear the BH_Uptodate bitflag in the read error
+ * case, however buffer contents are not necessarily bad if a
+ * write fails
*/
- bh->b_end_io(bh, 0);
+ bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
}
+/*
+ * return READ, READA, or WRITE
+ */
+#define bio_rw(bio) ((bio)->bi_rw & (RW_MASK | RWA_MASK))
+
+/*
+ * return data direction, READ or WRITE
+ */
+#define bio_data_dir(bio) ((bio)->bi_rw & 1)
+
extern void buffer_insert_inode_queue(struct buffer_head *, struct inode *);
static inline void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
{
@@ -1346,10 +1359,11 @@ extern void insert_inode_hash(struct inode *);
extern void remove_inode_hash(struct inode *);
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
-extern struct buffer_head * get_hash_table(kdev_t, int, int);
-extern struct buffer_head * getblk(kdev_t, int, int);
+extern struct buffer_head * get_hash_table(kdev_t, sector_t, int);
+extern struct buffer_head * getblk(kdev_t, sector_t, int);
extern void ll_rw_block(int, int, struct buffer_head * bh[]);
-extern void submit_bh(int, struct buffer_head *);
+extern int submit_bh(int, struct buffer_head *);
+extern int submit_bio(int, struct bio *);
extern int is_read_only(kdev_t);
extern void __brelse(struct buffer_head *);
static inline void brelse(struct buffer_head *buf)
@@ -1369,9 +1383,9 @@ extern void wakeup_bdflush(void);
extern void put_unused_buffer_head(struct buffer_head * bh);
extern struct buffer_head * get_unused_buffer_head(int async);
-extern int brw_page(int, struct page *, kdev_t, int [], int);
+extern int brw_page(int, struct page *, kdev_t, sector_t [], int);
-typedef int (get_block_t)(struct inode*,long,struct buffer_head*,int);
+typedef int (get_block_t)(struct inode*,sector_t,struct buffer_head*,int);
/* Generic buffer handling for block filesystems.. */
extern int try_to_release_page(struct page * page, int gfp_mask);
@@ -1387,7 +1401,7 @@ extern int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
extern int block_commit_write(struct page *page, unsigned from, unsigned to);
extern int block_sync_page(struct page *);
-int generic_block_bmap(struct address_space *, long, get_block_t *);
+sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
extern int generic_direct_IO(int, struct inode *, struct kiobuf *, unsigned long, int, get_block_t *);
@@ -1433,11 +1447,9 @@ extern char root_device_name[];
extern void show_buffers(void);
-extern void mount_root(void);
#ifdef CONFIG_BLK_DEV_INITRD
extern unsigned int real_root_dev;
-extern int change_root(kdev_t, const char *);
#endif
extern ssize_t char_read(struct file *, char *, size_t, loff_t *);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 323a2a2f0..18f8d66eb 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -86,11 +86,11 @@ struct gendisk {
};
/* drivers/block/genhd.c */
-extern struct gendisk *gendisk_head;
-
extern void add_gendisk(struct gendisk *gp);
extern void del_gendisk(struct gendisk *gp);
extern struct gendisk *get_gendisk(kdev_t dev);
+extern unsigned long get_start_sect(kdev_t dev);
+extern unsigned long get_nr_sects(kdev_t dev);
#endif /* __KERNEL__ */
@@ -244,35 +244,10 @@ char *disk_name (struct gendisk *hd, int minor, char *buf);
extern void devfs_register_partitions (struct gendisk *dev, int minor,
int unregister);
-
-
-/*
- * FIXME: this should use genhd->minor_shift, but that is slow to look up.
- */
static inline unsigned int disk_index (kdev_t dev)
{
- int major = MAJOR(dev);
- int minor = MINOR(dev);
- unsigned int index;
-
- switch (major) {
- case DAC960_MAJOR+0:
- index = (minor & 0x00f8) >> 3;
- break;
- case SCSI_DISK0_MAJOR:
- index = (minor & 0x00f0) >> 4;
- break;
- case IDE0_MAJOR: /* same as HD_MAJOR */
- case XT_DISK_MAJOR:
- index = (minor & 0x0040) >> 6;
- break;
- case IDE1_MAJOR:
- index = ((minor & 0x0040) >> 6) + 2;
- break;
- default:
- return 0;
- }
- return index;
+ struct gendisk *g = get_gendisk(dev);
+ return g ? (MINOR(dev) >> g->minor_shift) : 0;
}
#endif
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index b850d9b00..bc89d618b 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -13,8 +13,7 @@ extern struct page *highmem_start_page;
/* declarations for linux/mm/highmem.c */
unsigned int nr_free_highpages(void);
-extern struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig);
-
+extern void create_bounce(unsigned long pfn, struct bio **bio_orig);
static inline char *bh_kmap(struct buffer_head *bh)
{
@@ -26,6 +25,42 @@ static inline void bh_kunmap(struct buffer_head *bh)
kunmap(bh->b_page);
}
+/*
+ * remember to add offset! and never ever reenable interrupts between a
+ * bio_kmap_irq and bio_kunmap_irq!!
+ */
+static inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags)
+{
+ unsigned long addr;
+
+ __save_flags(*flags);
+
+ /*
+ * could be low
+ */
+ if (!PageHighMem(bio_page(bio)))
+ return bio_data(bio);
+
+ /*
+ * it's a highmem page
+ */
+ __cli();
+ addr = (unsigned long) kmap_atomic(bio_page(bio), KM_BIO_IRQ);
+
+ if (addr & ~PAGE_MASK)
+ BUG();
+
+ return (char *) addr + bio_offset(bio);
+}
+
+static inline void bio_kunmap_irq(char *buffer, unsigned long *flags)
+{
+ unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
+
+ kunmap_atomic((void *) ptr, KM_BIO_IRQ);
+ __restore_flags(*flags);
+}
+
#else /* CONFIG_HIGHMEM */
static inline unsigned int nr_free_highpages(void) { return 0; }
@@ -40,6 +75,9 @@ static inline void *kmap(struct page *page) { return page_address(page); }
#define bh_kmap(bh) ((bh)->b_data)
#define bh_kunmap(bh) do { } while (0)
+#define bio_kmap_irq(bio, flags) (bio_data(bio))
+#define bio_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
+
#endif /* CONFIG_HIGHMEM */
/* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 97e3831a4..38a17222c 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -149,6 +149,21 @@ typedef unsigned char byte; /* used everywhere */
#define DATA_READY (DRQ_STAT)
/*
+ * Our Physical Region Descriptor (PRD) table should be large enough
+ * to handle the biggest I/O request we are likely to see. Since requests
+ * can have no more than 256 sectors, and since the typical blocksize is
+ * two or more sectors, we could get by with a limit of 128 entries here for
+ * the usual worst case. Most requests seem to include some contiguous blocks,
+ * further reducing the number of table entries required.
+ *
+ * As it turns out though, we must allocate a full 4KB page for this,
+ * so the two PRD tables (ide0 & ide1) will each get half of that,
+ * allowing each to have about 256 entries (8 bytes each) from this.
+ */
+#define PRD_BYTES 8
+#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
+
+/*
* Some more useful definitions
*/
#define IDE_MAJOR_NAME "hd" /* the same for all i/f; see also genhd.c */
@@ -223,6 +238,23 @@ typedef int (ide_ack_intr_t)(struct hwif_s *);
#endif
/*
+ * hwif_chipset_t is used to keep track of the specific hardware
+ * chipset used by each IDE interface, if known.
+ */
+typedef enum { ide_unknown, ide_generic, ide_pci,
+ ide_cmd640, ide_dtc2278, ide_ali14xx,
+ ide_qd65xx, ide_umc8672, ide_ht6560b,
+ ide_pdc4030, ide_rz1000, ide_trm290,
+ ide_cmd646, ide_cy82c693, ide_4drives,
+ ide_pmac, ide_etrax100
+} hwif_chipset_t;
+
+#define IDE_CHIPSET_PCI_MASK \
+ ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
+#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
+
+
+/*
* Structure to hold all information about the location of this port
*/
typedef struct hw_regs_s {
@@ -231,6 +263,7 @@ typedef struct hw_regs_s {
int dma; /* our dma entry */
ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
void *priv; /* interface specific data */
+ hwif_chipset_t chipset;
} hw_regs_t;
/*
@@ -440,22 +473,6 @@ typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t);
*/
typedef int (ide_busproc_t) (struct hwif_s *, int);
-/*
- * hwif_chipset_t is used to keep track of the specific hardware
- * chipset used by each IDE interface, if known.
- */
-typedef enum { ide_unknown, ide_generic, ide_pci,
- ide_cmd640, ide_dtc2278, ide_ali14xx,
- ide_qd65xx, ide_umc8672, ide_ht6560b,
- ide_pdc4030, ide_rz1000, ide_trm290,
- ide_cmd646, ide_cy82c693, ide_4drives,
- ide_pmac, ide_etrax100
-} hwif_chipset_t;
-
-#define IDE_CHIPSET_PCI_MASK \
- ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
-#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
-
#ifdef CONFIG_BLK_DEV_IDEPCI
typedef struct ide_pci_devid_s {
unsigned short vid;
@@ -488,7 +505,6 @@ typedef struct hwif_s {
struct scatterlist *sg_table; /* Scatter-gather list used to build the above */
int sg_nents; /* Current number of entries in it */
int sg_dma_direction; /* dma transfer direction */
- int sg_dma_active; /* is it in use */
struct hwif_s *mate; /* other hwif from same PCI chip */
unsigned long dma_base; /* base addr for dma ports */
unsigned dma_extra; /* extra addr for dma ports */
@@ -507,6 +523,7 @@ typedef struct hwif_s {
unsigned reset : 1; /* reset after probe */
unsigned autodma : 1; /* automatically try to enable DMA at boot */
unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
+ unsigned highmem : 1; /* can do full 32-bit dma */
byte channel; /* for dual-port chips: 0=primary, 1=secondary */
#ifdef CONFIG_BLK_DEV_IDEPCI
struct pci_dev *pci_dev; /* for pci chipsets */
@@ -541,10 +558,12 @@ typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
*/
typedef int (ide_expiry_t)(ide_drive_t *);
+#define IDE_BUSY 0
+#define IDE_SLEEP 1
+
typedef struct hwgroup_s {
ide_handler_t *handler;/* irq handler, if active */
- volatile int busy; /* BOOL: protects all fields below */
- int sleeping; /* BOOL: wake us up on timer expiry */
+ unsigned long flags; /* BUSY, SLEEPING */
ide_drive_t *drive; /* current drive */
ide_hwif_t *hwif; /* ptr to current hwif in linked-list */
struct request *rq; /* current request */
@@ -711,7 +730,8 @@ extern int noautodma;
#define LOCAL_END_REQUEST /* Don't generate end_request in blk.h */
#include <linux/blk.h>
-void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);
+inline int __ide_end_request(ide_hwgroup_t *, int, int);
+int ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);
/*
* This is used for (nearly) all data transfers from/to the IDE interface
@@ -787,6 +807,11 @@ ide_drive_t *get_info_ptr (kdev_t i_rdev);
unsigned long current_capacity (ide_drive_t *drive);
/*
+ * Revalidate (read partition tables)
+ */
+void ide_revalidate_drive (ide_drive_t *drive);
+
+/*
* Start a reset operation for an IDE interface.
* The caller should return immediately after invoking this.
*/
@@ -814,6 +839,21 @@ typedef enum {
} ide_action_t;
/*
+ * temporarily mapping a (possible) highmem bio for PIO transfer
+ */
+#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
+
+extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
+{
+ return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
+}
+
+extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags)
+{
+ bio_kunmap_irq(buffer, flags);
+}
+
+/*
* This function issues a special IDE device request
* onto the request queue.
*
@@ -961,4 +1001,7 @@ unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *
void hwif_unregister (ide_hwif_t *hwif);
+#define DRIVE_LOCK(drive) (&(drive)->queue.queue_lock)
+extern spinlock_t ide_lock;
+
#endif /* _IDE_H */
diff --git a/include/linux/iobuf.h b/include/linux/iobuf.h
index 619187efe..869b05dc6 100644
--- a/include/linux/iobuf.h
+++ b/include/linux/iobuf.h
@@ -28,7 +28,7 @@
#define KIO_STATIC_PAGES (KIO_MAX_ATOMIC_IO / (PAGE_SIZE >> 10) + 1)
#define KIO_MAX_SECTORS (KIO_MAX_ATOMIC_IO * 2)
-/* The main kiobuf struct used for all our IO! */
+/* The main kiobuf struct */
struct kiobuf
{
@@ -48,8 +48,7 @@ struct kiobuf
/* Always embed enough struct pages for atomic IO */
struct page * map_array[KIO_STATIC_PAGES];
- struct buffer_head * bh[KIO_MAX_SECTORS];
- unsigned long blocks[KIO_MAX_SECTORS];
+ sector_t blocks[KIO_MAX_SECTORS];
/* Dynamic state for IO completion: */
atomic_t io_count; /* IOs still in progress */
@@ -69,7 +68,7 @@ void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes);
/* fs/iobuf.c */
-void end_kio_request(struct kiobuf *, int);
+int end_kio_request(struct kiobuf *, int);
void simple_wakeup_kiobuf(struct kiobuf *);
int alloc_kiovec(int nr, struct kiobuf **);
void free_kiovec(int nr, struct kiobuf **);
@@ -81,6 +80,9 @@ extern void free_kiobuf_bhs(struct kiobuf *);
/* fs/buffer.c */
int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
- kdev_t dev, unsigned long b[], int size);
+ kdev_t dev, sector_t [], int size);
+
+/* fs/bio.c */
+void ll_rw_kio(int rw, struct kiobuf *kio, kdev_t dev, sector_t block);
#endif /* __LINUX_IOBUF_H */
diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h
index 55be4e590..82dde8081 100644
--- a/include/linux/iso_fs.h
+++ b/include/linux/iso_fs.h
@@ -220,7 +220,7 @@ int get_acorn_filename(struct iso_directory_record *, char *, struct inode *);
extern struct dentry *isofs_lookup(struct inode *, struct dentry *);
extern struct buffer_head *isofs_bread(struct inode *, unsigned int, unsigned int);
-extern int isofs_get_blocks(struct inode *, long, struct buffer_head **, unsigned long);
+extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
extern struct inode_operations isofs_dir_inode_operations;
extern struct file_operations isofs_dir_operations;
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 7d0395582..a2ae37d44 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -1,6 +1,7 @@
#ifndef _KBD_KERN_H
#define _KBD_KERN_H
+#include <linux/tty.h>
#include <linux/interrupt.h>
#include <linux/keyboard.h>
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ce4aef9e5..523e38822 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -11,6 +11,7 @@
#include <linux/linkage.h>
#include <linux/stddef.h>
#include <linux/types.h>
+#include <linux/compiler.h>
/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
@@ -176,4 +177,5 @@ struct sysinfo {
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
#endif
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 11622345f..4e86b0dce 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -49,8 +49,8 @@ struct loop_device {
int old_gfp_mask;
spinlock_t lo_lock;
- struct buffer_head *lo_bh;
- struct buffer_head *lo_bhtail;
+ struct bio *lo_bio;
+ struct bio *lo_biotail;
int lo_state;
struct semaphore lo_sem;
struct semaphore lo_ctl_mutex;
diff --git a/include/linux/lvm.h b/include/linux/lvm.h
index b3e68a6db..226e267fd 100644
--- a/include/linux/lvm.h
+++ b/include/linux/lvm.h
@@ -468,6 +468,12 @@ typedef struct lv_bmap {
} lv_bmap_t;
/*
+ * fixme...
+ */
+#define LVM_MAX_ATOMIC_IO 512
+#define LVM_MAX_SECTORS (LVM_MAX_ATOMIC_IO * 2)
+
+/*
* Structure Logical Volume (LV) Version 3
*/
@@ -505,6 +511,7 @@ typedef struct lv_v5 {
uint lv_snapshot_minor;
#ifdef __KERNEL__
struct kiobuf *lv_iobuf;
+ sector_t blocks[LVM_MAX_SECTORS];
struct kiobuf *lv_COW_table_iobuf;
struct rw_semaphore lv_lock;
struct list_head *lv_snapshot_hash_table;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 1baa0a77a..132b545d2 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -273,7 +273,7 @@ extern struct file_operations fat_file_operations;
extern struct inode_operations fat_file_inode_operations;
extern ssize_t fat_file_read(struct file *filp, char *buf, size_t count,
loff_t *ppos);
-extern int fat_get_block(struct inode *inode, long iblock,
+extern int fat_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);
extern ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
loff_t *ppos);
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index b34d4d18d..0dbf87851 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -37,24 +37,25 @@ extern int requests_out;
static void
nbd_end_request(struct request *req)
{
- struct buffer_head *bh;
+ struct bio *bio;
unsigned nsect;
unsigned long flags;
int uptodate = (req->errors == 0) ? 1 : 0;
+ request_queue_t *q = req->q;
#ifdef PARANOIA
requests_out++;
#endif
- spin_lock_irqsave(&io_request_lock, flags);
- while((bh = req->bh) != NULL) {
- nsect = bh->b_size >> 9;
+ spin_lock_irqsave(&q->queue_lock, flags);
+ while((bio = req->bio) != NULL) {
+ nsect = bio_sectors(bio);
blk_finished_io(nsect);
- req->bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- bh->b_end_io(bh, uptodate);
+ req->bio = bio->bi_next;
+ bio->bi_next = NULL;
+ bio_endio(bio, uptodate, nsect);
}
blkdev_release_request(req);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_unlock_irqrestore(&q->queue_lock, flags);
}
#define MAX_NBD 128
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a8753bec7..d73d486ab 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -912,7 +912,7 @@
#define PCI_DEVICE_ID_TTI_HPT366 0x0004
#define PCI_VENDOR_ID_VIA 0x1106
-#define PCI_DEVICE_ID_VIA_8363_0 0x0305
+#define PCI_DEVICE_ID_VIA_8363_0 0x0305
#define PCI_DEVICE_ID_VIA_8371_0 0x0391
#define PCI_DEVICE_ID_VIA_8501_0 0x0501
#define PCI_DEVICE_ID_VIA_82C505 0x0505
@@ -946,9 +946,11 @@
#define PCI_DEVICE_ID_VIA_8233_7 0x3065
#define PCI_DEVICE_ID_VIA_82C686_6 0x3068
#define PCI_DEVICE_ID_VIA_8233_0 0x3074
+#define PCI_DEVICE_ID_VIA_8622 0x3102
#define PCI_DEVICE_ID_VIA_8233C_0 0x3109
+#define PCI_DEVICE_ID_VIA_8361 0x3112
#define PCI_DEVICE_ID_VIA_8633_0 0x3091
-#define PCI_DEVICE_ID_VIA_8367_0 0x3099
+#define PCI_DEVICE_ID_VIA_8367_0 0x3099
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_8231 0x8231
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index d0f16c8f3..360402d76 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -220,7 +220,7 @@ struct mddev_s
struct mdk_personality_s
{
char *name;
- int (*make_request)(mddev_t *mddev, int rw, struct buffer_head * bh);
+ int (*make_request)(mddev_t *mddev, int rw, struct bio *bio);
int (*run)(mddev_t *mddev);
int (*stop)(mddev_t *mddev);
int (*status)(char *page, mddev_t *mddev);
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index eda113f2b..cc6b767a6 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -52,17 +52,48 @@
*/
+ /* Vladimir, what is the story with
+ new_get_new_buffer nowadays? I
+ want a complete explanation written
+ here. */
+
+/* NEW_GET_NEW_BUFFER will try to allocate new blocks better */
+/*#define NEW_GET_NEW_BUFFER*/
+#define OLD_GET_NEW_BUFFER
+
+ /* Vladimir, what about this one too? */
+/* if this is undefined, all inode changes get into stat data immediately, if it can be found in RAM */
+#define DIRTY_LATER
+
+/* enable journalling */
+#define ENABLE_JOURNAL
+
#define USE_INODE_GENERATION_COUNTER
+
+#ifdef __KERNEL__
+
+/* #define REISERFS_CHECK */
+
#define REISERFS_PREALLOCATE
+#endif
#define PREALLOCATION_SIZE 8
+/* if this is undefined, all inode changes get into stat data
+ immediately, if it can be found in RAM */
+#define DIRTY_LATER
+
+
+/*#define READ_LOCK_REISERFS*/
+
+
/* n must be power of 2 */
#define _ROUND_UP(x,n) (((x)+(n)-1u) & ~((n)-1u))
// to be ok for alpha and others we have to align structures to 8 byte
// boundary.
// FIXME: do not change 4 by anything else: there is code which relies on that
+ /* what 4? -Hans */
#define ROUND_UP(x) _ROUND_UP(x,8LL)
/* debug levels. Right now, CONFIG_REISERFS_CHECK means print all debug
@@ -117,17 +148,22 @@ static inline int is_reiserfs_magic_string (const struct reiserfs_super_block *
strlen ( reiser2fs_super_magic_string)));
}
-/* ReiserFS leaves the first 64k unused, so that partition labels have
- enough space. If someone wants to write a fancy bootloader that
- needs more than 64k, let us know, and this will be increased in size.
- This number must be larger than than the largest block size on any
- platform, or code will break. -Hans */
+ /* ReiserFS leaves the first 64k unused,
+ so that partition labels have enough
+ space. If someone wants to write a
+ fancy bootloader that needs more than
+ 64k, let us know, and this will be
+ increased in size. This number must
+ be larger than than the largest block
+ size on any platform, or code will
+ break. -Hans */
#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
#define REISERFS_FIRST_BLOCK unused_define
/* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */
#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
+
// reiserfs internal error code (used by search_by_key adn fix_nodes))
#define CARRY_ON 0
#define REPEAT_SEARCH -1
@@ -136,54 +172,53 @@ static inline int is_reiserfs_magic_string (const struct reiserfs_super_block *
#define NO_BALANCING_NEEDED (-4)
#define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5)
+//#define SCHEDULE_OCCURRED 1
+//#define PATH_INCORRECT 2
+
+//#define NO_DISK_SPACE (-1)
+
+
+
typedef unsigned long b_blocknr_t;
typedef __u32 unp_t;
+ /* who is responsible for this
+ completely uncommented struct? */
struct unfm_nodeinfo {
+ /* This is what? */
unp_t unfm_nodenum;
+ /* now this I know what it is, and
+ most of the people on our project
+ know what it is, but I bet nobody
+ new I hire will have a clue. */
unsigned short unfm_freespace;
};
-/* there are two formats of keys: 3.5 and 3.6
- */
-#define KEY_FORMAT_3_5 0
-#define KEY_FORMAT_3_6 1
-
-/* there are two stat datas */
-#define STAT_DATA_V1 0
-#define STAT_DATA_V2 1
-
-/** this says about version of key of all items (but stat data) the
- object consists of */
-#define get_inode_item_key_version( inode ) \
- (((inode)->u.reiserfs_i.i_flags & i_item_key_version_mask) ? KEY_FORMAT_3_6 : KEY_FORMAT_3_5)
-
-#define set_inode_item_key_version( inode, version ) \
- ({ if((version)==KEY_FORMAT_3_6) \
- (inode)->u.reiserfs_i.i_flags |= i_item_key_version_mask; \
- else \
- (inode)->u.reiserfs_i.i_flags &= ~i_item_key_version_mask; })
-
-#define get_inode_sd_version(inode) \
- (((inode)->u.reiserfs_i.i_flags & i_stat_data_version_mask) ? STAT_DATA_V2 : STAT_DATA_V1)
-
-#define set_inode_sd_version(inode, version) \
- ({ if((version)==STAT_DATA_V2) \
- (inode)->u.reiserfs_i.i_flags |= i_stat_data_version_mask; \
- else \
- (inode)->u.reiserfs_i.i_flags &= ~i_stat_data_version_mask; })
-
-/* This is an aggressive tail suppression policy, I am hoping it
- improves our benchmarks. The principle behind it is that percentage
- space saving is what matters, not absolute space saving. This is
- non-intuitive, but it helps to understand it if you consider that the
- cost to access 4 blocks is not much more than the cost to access 1
- block, if you have to do a seek and rotate. A tail risks a
- non-linear disk access that is significant as a percentage of total
- time cost for a 4 block file and saves an amount of space that is
- less significant as a percentage of space, or so goes the hypothesis.
- -Hans */
+/* when reiserfs_file_write is called with a byte count >= MIN_PACK_ON_CLOSE,
+** it sets the inode to pack on close, and when extending the file, will only
+** use unformatted nodes.
+**
+** This is a big speed up for the journal, which is badly hurt by direct->indirect
+** conversions (they must be logged).
+*/
+#define MIN_PACK_ON_CLOSE 512
+
+// this says about version of all items (but stat data) the object
+// consists of
+#define inode_items_version(inode) ((inode)->u.reiserfs_i.i_version)
+
+
+ /* This is an aggressive tail suppression policy, I am hoping it
+ improves our benchmarks. The principle behind it is that
+ percentage space saving is what matters, not absolute space
+ saving. This is non-intuitive, but it helps to understand it if
+ you consider that the cost to access 4 blocks is not much more
+ than the cost to access 1 block, if you have to do a seek and
+ rotate. A tail risks a non-linear disk access that is
+ significant as a percentage of total time cost for a 4 block file
+ and saves an amount of space that is less significant as a
+ percentage of space, or so goes the hypothesis. -Hans */
#define STORE_TAIL_IN_UNFM(n_file_size,n_tail_size,n_block_size) \
(\
(!(n_tail_size)) || \
@@ -211,6 +246,21 @@ struct unfm_nodeinfo {
/***************************************************************************/
//
+// we do support for old format of reiserfs: the problem is to
+// distinuquish keys with 32 bit offset and keys with 60 bit ones. On
+// leaf level we use ih_version of struct item_head (was
+// ih_reserved). For all old items it is set to 0
+// (ITEM_VERSION_1). For new items it is ITEM_VERSION_2. On internal
+// levels we have to know version of item key belongs to.
+//
+#define ITEM_VERSION_1 0
+#define ITEM_VERSION_2 1
+
+
+/* loff_t - long long */
+
+
+//
// directories use this key as well as old files
//
struct offset_v1 {
@@ -291,11 +341,18 @@ struct cpu_key {
indirect2direct conversion */
};
-/* Our function for comparing keys can compare keys of different
- lengths. It takes as a parameter the length of the keys it is to
- compare. These defines are used in determining what is to be passed
- to it as that parameter. */
+
+
+
+
+
+
+ /* Our function for comparing keys can compare keys of different
+ lengths. It takes as a parameter the length of the keys it is to
+ compare. These defines are used in determining what is to be
+ passed to it as that parameter. */
#define REISERFS_FULL_KEY_LEN 4
+
#define REISERFS_SHORT_KEY_LEN 2
/* The result of the key compare */
@@ -305,6 +362,7 @@ struct cpu_key {
#define KEY_FOUND 1
#define KEY_NOT_FOUND 0
+
#define KEY_SIZE (sizeof(struct key))
#define SHORT_KEY_SIZE (sizeof (__u32) + sizeof (__u32))
@@ -329,6 +387,8 @@ struct cpu_key {
#define GOTO_PREVIOUS_ITEM 2
#define NAME_FOUND_INVISIBLE 3
+
+
/* Everything in the filesystem is stored as a set of items. The
item head contains the key of the item, its free space (for
indirect items) and specifies the location of the item itself
@@ -336,28 +396,37 @@ struct cpu_key {
struct item_head
{
- /* Everything in the tree is found by searching for it based on
- * its key.*/
- struct key ih_key;
- union {
- /* The free space in the last unformatted node of an
- indirect item if this is an indirect item. This
- equals 0xFFFF iff this is a direct item or stat data
- item. Note that the key, not this field, is used to
- determine the item type, and thus which field this
- union contains. */
- __u16 ih_free_space_reserved;
- /* Iff this is a directory item, this field equals the
- number of directory entries in the directory item. */
- __u16 ih_entry_count;
- } __attribute__ ((__packed__)) u;
- __u16 ih_item_len; /* total size of the item body */
- __u16 ih_item_location; /* an offset to the item body
- * within the block */
- __u16 ih_version; /* 0 for all old items, 2 for new
- ones. Highest bit is set by fsck
- temporary, cleaned after all
- done */
+ struct key ih_key; /* Everything in the tree is found by searching for it based on its key.*/
+
+ /* This is bloat, this should be part
+ of the item not the item
+ header. -Hans */
+ union {
+ __u16 ih_free_space_reserved; /* The free space in the last unformatted node of an indirect item if this
+ is an indirect item. This equals 0xFFFF iff this is a direct item or
+ stat data item. Note that the key, not this field, is used to determine
+ the item type, and thus which field this union contains. */
+ __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory
+ entries in the directory item. */
+ } __attribute__ ((__packed__)) u;
+ __u16 ih_item_len; /* total size of the item body */
+ __u16 ih_item_location; /* an offset to the item body within the block */
+ /* I thought we were going to use this
+ for having lots of item types? Why
+ don't you use this for item type
+ not item version. That is how you
+ talked me into this field a year
+ ago, remember? I am still not
+ convinced it needs to be 16 bits
+ (for at least many years), but at
+ least I can sympathize with that
+ hope. Change the name from version
+ to type, and tell people not to use
+ FFFF in case 16 bits is someday too
+ small and needs to be extended:-). */
+ __u16 ih_version; /* 0 for all old items, 2 for new
+ ones. Highest bit is set by fsck
+ temporary, cleaned after all done */
} __attribute__ ((__packed__));
/* size of item header */
#define IH_SIZE (sizeof(struct item_head))
@@ -377,8 +446,8 @@ struct item_head
#define unreachable_item(ih) (ih_version(ih) & (1 << 15))
-#define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih))
-#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == KEY_FORMAT_3_6) ? 0 : (val)))
+#define get_ih_free_space(ih) (ih_version (ih) == ITEM_VERSION_2 ? 0 : ih_free_space (ih))
+#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == ITEM_VERSION_2) ? 0 : (val)))
/* these operate on indirect items, where you've got an array of ints
** at a possibly unaligned location. These are a noop on ia32
@@ -407,9 +476,6 @@ struct item_head
#define V1_DIRENTRY_UNIQUENESS 500
#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
-extern void reiserfs_warning (const char * fmt, ...);
-/* __attribute__( ( format ( printf, 1, 2 ) ) ); */
-
//
// here are conversion routines
//
@@ -421,11 +487,14 @@ static inline int uniqueness2type (__u32 uniqueness)
case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
- default:
- reiserfs_warning( "vs-500: unknown uniqueness %d\n", uniqueness);
- case V1_ANY_UNIQUENESS:
- return TYPE_ANY;
}
+/*
+ if (uniqueness != V1_ANY_UNIQUENESS) {
+ printk ("uniqueness %d\n", uniqueness);
+ BUG ();
+ }
+*/
+ return TYPE_ANY;
}
static inline __u32 type2uniqueness (int type) CONSTF;
@@ -436,13 +505,15 @@ static inline __u32 type2uniqueness (int type)
case TYPE_INDIRECT: return V1_INDIRECT_UNIQUENESS;
case TYPE_DIRECT: return V1_DIRECT_UNIQUENESS;
case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS;
- default:
- reiserfs_warning( "vs-501: unknown type %d\n", type);
- case TYPE_ANY:
- return V1_ANY_UNIQUENESS;
}
+ /*
+ if (type != TYPE_ANY)
+ BUG ();
+ */
+ return V1_ANY_UNIQUENESS;
}
+
//
// key is pointer to on disk key which is stored in le, result is cpu,
// there is no way to get version of object from key, so, provide
@@ -450,7 +521,7 @@ static inline __u32 type2uniqueness (int type)
//
static inline loff_t le_key_k_offset (int version, const struct key * key)
{
- return (version == KEY_FORMAT_3_5) ?
+ return (version == ITEM_VERSION_1) ?
le32_to_cpu( key->u.k_offset_v1.k_offset ) :
offset_v2_k_offset( &(key->u.k_offset_v2) );
}
@@ -462,7 +533,7 @@ static inline loff_t le_ih_k_offset (const struct item_head * ih)
static inline loff_t le_key_k_type (int version, const struct key * key)
{
- return (version == KEY_FORMAT_3_5) ?
+ return (version == ITEM_VERSION_1) ?
uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
offset_v2_k_type( &(key->u.k_offset_v2) );
}
@@ -475,21 +546,20 @@ static inline loff_t le_ih_k_type (const struct item_head * ih)
static inline void set_le_key_k_offset (int version, struct key * key, loff_t offset)
{
- (version == KEY_FORMAT_3_5) ?
+ (version == ITEM_VERSION_1) ?
(key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
(set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
}
-
-
static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
{
set_le_key_k_offset (ih_version (ih), &(ih->ih_key), offset);
}
+
static inline void set_le_key_k_type (int version, struct key * key, int type)
{
- (version == KEY_FORMAT_3_5) ?
+ (version == ITEM_VERSION_1) ?
(key->u.k_offset_v1.k_uniqueness = cpu_to_le32(type2uniqueness(type))):
(set_offset_v2_k_type( &(key->u.k_offset_v2), type ));
}
@@ -519,21 +589,21 @@ static inline void set_le_ih_k_type (struct item_head * ih, int type)
//
static inline loff_t cpu_key_k_offset (const struct cpu_key * key)
{
- return (key->version == KEY_FORMAT_3_5) ?
+ return (key->version == ITEM_VERSION_1) ?
key->on_disk_key.u.k_offset_v1.k_offset :
key->on_disk_key.u.k_offset_v2.k_offset;
}
static inline loff_t cpu_key_k_type (const struct cpu_key * key)
{
- return (key->version == KEY_FORMAT_3_5) ?
+ return (key->version == ITEM_VERSION_1) ?
uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) :
key->on_disk_key.u.k_offset_v2.k_type;
}
static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
{
- (key->version == KEY_FORMAT_3_5) ?
+ (key->version == ITEM_VERSION_1) ?
(key->on_disk_key.u.k_offset_v1.k_offset = offset) :
(key->on_disk_key.u.k_offset_v2.k_offset = offset);
}
@@ -541,15 +611,14 @@ static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
static inline void set_cpu_key_k_type (struct cpu_key * key, int type)
{
- (key->version == KEY_FORMAT_3_5) ?
+ (key->version == ITEM_VERSION_1) ?
(key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)):
(key->on_disk_key.u.k_offset_v2.k_type = type);
}
-
static inline void cpu_key_k_offset_dec (struct cpu_key * key)
{
- if (key->version == KEY_FORMAT_3_5)
+ if (key->version == ITEM_VERSION_1)
key->on_disk_key.u.k_offset_v1.k_offset --;
else
key->on_disk_key.u.k_offset_v2.k_offset --;
@@ -692,7 +761,7 @@ struct stat_data_v1
} __attribute__ ((__packed__));
#define SD_V1_SIZE (sizeof(struct stat_data_v1))
-#define stat_data_v1(ih) (ih_version (ih) == KEY_FORMAT_3_5)
+#define stat_data_v1(ih) (ih_version (ih) == ITEM_VERSION_1)
#define sd_v1_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
#define set_sd_v1_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
#define sd_v1_nlink(sdp) (le16_to_cpu((sdp)->sd_nlink))
@@ -746,11 +815,11 @@ struct stat_data {
} __attribute__ ((__packed__)) u;
} __attribute__ ((__packed__));
//
-// this is 44 bytes long
+// this is 40 bytes long
//
#define SD_SIZE (sizeof(struct stat_data))
#define SD_V2_SIZE SD_SIZE
-#define stat_data_v2(ih) (ih_version (ih) == KEY_FORMAT_3_6)
+#define stat_data_v2(ih) (ih_version (ih) == ITEM_VERSION_2)
#define sd_v2_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
#define set_sd_v2_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
/* sd_reserved */
@@ -880,10 +949,76 @@ struct reiserfs_de_head
#define de_visible(deh) test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
#define de_hidden(deh) !test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
-extern void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid,
- __u32 par_dirid, __u32 par_objid);
-extern void make_empty_dir_item (char * body, __u32 dirid, __u32 objid,
- __u32 par_dirid, __u32 par_objid);
+/* compose directory item containing "." and ".." entries (entries are
+ not aligned to 4 byte boundary) */
+/* the last four params are LE */
+static inline void make_empty_dir_item_v1 (char * body,
+ __u32 dirid, __u32 objid,
+ __u32 par_dirid, __u32 par_objid)
+{
+ struct reiserfs_de_head * deh;
+
+ memset (body, 0, EMPTY_DIR_SIZE_V1);
+ deh = (struct reiserfs_de_head *)body;
+
+ /* direntry header of "." */
+ put_deh_offset( &(deh[0]), DOT_OFFSET );
+ /* these two are from make_le_item_head, and are are LE */
+ deh[0].deh_dir_id = dirid;
+ deh[0].deh_objectid = objid;
+ deh[0].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." ));
+ mark_de_visible(&(deh[0]));
+
+ /* direntry header of ".." */
+ put_deh_offset( &(deh[1]), DOT_DOT_OFFSET);
+ /* key of ".." for the root directory */
+ /* these two are from the inode, and are are LE */
+ deh[1].deh_dir_id = par_dirid;
+ deh[1].deh_objectid = par_objid;
+ deh[1].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) );
+ mark_de_visible(&(deh[1]));
+
+ /* copy ".." and "." */
+ memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+ memcpy (body + deh_location( &(deh[1]) ), "..", 2);
+}
+
+/* compose directory item containing "." and ".." entries */
+static inline void make_empty_dir_item (char * body,
+ __u32 dirid, __u32 objid,
+ __u32 par_dirid, __u32 par_objid)
+{
+ struct reiserfs_de_head * deh;
+
+ memset (body, 0, EMPTY_DIR_SIZE);
+ deh = (struct reiserfs_de_head *)body;
+
+ /* direntry header of "." */
+ put_deh_offset( &(deh[0]), DOT_OFFSET );
+ /* these two are from make_le_item_head, and are are LE */
+ deh[0].deh_dir_id = dirid;
+ deh[0].deh_objectid = objid;
+ deh[0].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) );
+ mark_de_visible(&(deh[0]));
+
+ /* direntry header of ".." */
+ put_deh_offset( &(deh[1]), DOT_DOT_OFFSET );
+ /* key of ".." for the root directory */
+ /* these two are from the inode, and are are LE */
+ deh[1].deh_dir_id = par_dirid;
+ deh[1].deh_objectid = par_objid;
+ deh[1].deh_state = 0; /* Endian safe if 0 */
+ put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) );
+ mark_de_visible(&(deh[1]));
+
+ /* copy ".." and "." */
+ memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+ memcpy (body + deh_location( &(deh[1]) ), "..", 2);
+}
+
/* array of the entry headers */
/* get item body */
@@ -924,9 +1059,13 @@ static inline int entry_length (const struct buffer_head * bh,
// two entries per block (at least)
//#define REISERFS_MAX_NAME_LEN(block_size)
//((block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE * 2) / 2)
+
+// two entries per block (at least)
#define REISERFS_MAX_NAME_LEN(block_size) 255
+
+
/* this structure is used for operations on directory entries. It is
not a disk structure. */
/* When reiserfs_find_entry or search_by_entry_key find directory
@@ -1119,17 +1258,23 @@ struct path var = {ILLEGAL_PATH_ELEMENT_OFFSET, }
// in in-core inode key is stored on le form
#define INODE_PKEY(inode) ((struct key *)((inode)->u.reiserfs_i.i_key))
+//#define mark_tail_converted(inode) (atomic_set(&((inode)->u.reiserfs_i.i_converted),1))
+//#define unmark_tail_converted(inode) (atomic_set(&((inode)->u.reiserfs_i.i_converted), 0))
+//#define is_tail_converted(inode) (atomic_read(&((inode)->u.reiserfs_i.i_converted)))
+
+
#define MAX_UL_INT 0xffffffff
#define MAX_INT 0x7ffffff
#define MAX_US_INT 0xffff
+///#define TOO_LONG_LENGTH (~0ULL)
+
// reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset
#define U32_MAX (~(__u32)0)
-
static inline loff_t max_reiserfs_offset (const struct inode * inode)
{
- if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5)
+ if (inode_items_version (inode) == ITEM_VERSION_1)
return (loff_t)U32_MAX;
return (loff_t)((~(__u64)0) >> 4);
@@ -1162,6 +1307,13 @@ static inline loff_t max_reiserfs_offset (const struct inode * inode)
/* FIXATE NODES */
/***************************************************************************/
+//#define VI_TYPE_STAT_DATA 1
+//#define VI_TYPE_DIRECT 2
+//#define VI_TYPE_INDIRECT 4
+//#define VI_TYPE_DIRECTORY 8
+//#define VI_TYPE_FIRST_DIRECTORY_ITEM 16
+//#define VI_TYPE_INSERTED_DIRECTORY_ITEM 32
+
#define VI_TYPE_LEFT_MERGEABLE 1
#define VI_TYPE_RIGHT_MERGEABLE 2
@@ -1384,7 +1536,11 @@ extern struct item_operations * item_ops [4];
#define COMP_KEYS comp_keys
#define COMP_SHORT_KEYS comp_short_keys
-/*#define keys_of_same_object comp_short_keys*/
+#define keys_of_same_object comp_short_keys
+
+/*#define COMP_KEYS(p_s_key1, p_s_key2) comp_keys((unsigned long *)(p_s_key1), (unsigned long *)(p_s_key2))
+#define COMP_SHORT_KEYS(p_s_key1, p_s_key2) comp_short_keys((unsigned long *)(p_s_key1), (unsigned long *)(p_s_key2))*/
+
/* number of blocks pointed to by the indirect item */
#define I_UNFM_NUM(p_s_ih) ( ih_item_len(p_s_ih) / UNFM_P_SIZE )
@@ -1519,12 +1675,18 @@ int journal_mark_dirty_nolog(struct reiserfs_transaction_handle *, struct super_
int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block *, unsigned long blocknr) ;
int push_journal_writer(char *w) ;
int pop_journal_writer(int windex) ;
+int journal_lock_dobalance(struct super_block *p_s_sb) ;
+int journal_unlock_dobalance(struct super_block *p_s_sb) ;
int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
int reiserfs_in_journal(struct super_block *p_s_sb, kdev_t dev, unsigned long bl, int size, int searchall, unsigned long *next) ;
int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
+int journal_join(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
struct super_block *reiserfs_get_super(kdev_t dev) ;
void flush_async_commits(struct super_block *p_s_sb) ;
+int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) ;
+int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) ;
+
int buffer_journaled(const struct buffer_head *bh) ;
int mark_buffer_journal_new(struct buffer_head *bh) ;
int reiserfs_sync_all_buffers(kdev_t dev, int wait) ;
@@ -1563,10 +1725,6 @@ static inline int mark_buffer_notjournal_new(struct buffer_head *bh) {
return 0 ;
}
-void add_save_link (struct reiserfs_transaction_handle * th,
- struct inode * inode, int truncate);
-void remove_save_link (struct inode * inode, int truncate);
-
/* objectid.c */
__u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, __u32 objectid_to_release);
@@ -1604,16 +1762,16 @@ static inline int le_key_version (const struct key * key)
type = offset_v2_k_type( &(key->u.k_offset_v2));
if (type != TYPE_DIRECT && type != TYPE_INDIRECT && type != TYPE_DIRENTRY)
- return KEY_FORMAT_3_5;
+ return ITEM_VERSION_1;
- return KEY_FORMAT_3_6;
+ return ITEM_VERSION_2;
}
static inline void copy_key (struct key *to, const struct key *from)
{
- memcpy (to, from, KEY_SIZE);
+ memcpy (to, from, KEY_SIZE);
}
@@ -1657,12 +1815,17 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
struct inode * inode,
struct buffer_head * p_s_un_bh);
-void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
- struct key * key);
+
void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
struct inode * p_s_inode, struct page *,
int update_timestamps);
+//
+//void lock_inode_to_convert (struct inode * p_s_inode);
+//void unlock_inode_after_convert (struct inode * p_s_inode);
+//void increment_i_read_sync_counter (struct inode * p_s_inode);
+//void decrement_i_read_sync_counter (struct inode * p_s_inode);
+
#define block_size(inode) ((inode)->i_sb->s_blocksize)
#define file_size(inode) ((inode)->i_size)
@@ -1671,17 +1834,18 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
#define tail_has_to_be_packed(inode) (!dont_have_tails ((inode)->i_sb) &&\
!STORE_TAIL_IN_UNFM(file_size (inode), tail_size(inode), block_size (inode)))
+/*
+int get_buffer_by_range (struct super_block * p_s_sb, struct key * p_s_range_begin, struct key * p_s_range_end,
+ struct buffer_head ** pp_s_buf, unsigned long * p_n_objectid);
+int get_buffers_from_range (struct super_block * p_s_sb, struct key * p_s_range_start, struct key * p_s_range_end,
+ struct buffer_head ** p_s_range_buffers,
+ int n_max_nr_buffers_to_return);
+*/
+
void padd_item (char * item, int total_length, int length);
-/* inode.c */
-void reiserfs_read_inode (struct inode * inode) ;
-void reiserfs_read_inode2(struct inode * inode, void *p) ;
-void reiserfs_delete_inode (struct inode * inode);
-void reiserfs_write_inode (struct inode * inode, int) ;
-struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
- int len, int fhtype, int parent);
-int reiserfs_dentry_to_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent);
+/* inode.c */
int reiserfs_prepare_write(struct file *, struct page *, unsigned, unsigned) ;
void reiserfs_truncate_file(struct inode *, int update_timestamps) ;
@@ -1690,9 +1854,24 @@ void make_cpu_key (struct cpu_key * cpu_key, const struct inode * inode, loff_t
void make_le_item_head (struct item_head * ih, const struct cpu_key * key,
int version,
loff_t offset, int type, int length, int entry_count);
+/*void store_key (struct key * key);
+void forget_key (struct key * key);*/
+int reiserfs_get_block (struct inode * inode, sector_t block,
+ struct buffer_head * bh_result, int create);
struct inode * reiserfs_iget (struct super_block * s,
const struct cpu_key * key);
+void reiserfs_read_inode (struct inode * inode) ;
+void reiserfs_read_inode2(struct inode * inode, void *p) ;
+void reiserfs_delete_inode (struct inode * inode);
+extern int reiserfs_notify_change(struct dentry * dentry, struct iattr * attr);
+void reiserfs_write_inode (struct inode * inode, int) ;
+/* nfsd support functions */
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
+int reiserfs_dentry_to_fh(struct dentry *, __u32 *fh, int *lenp, int need_parent);
+
+/* we don't mark inodes dirty, we just log them */
+void reiserfs_dirty_inode (struct inode * inode) ;
struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
const struct inode * dir, int mode,
@@ -1700,12 +1879,36 @@ struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
struct dentry *dentry, struct inode *inode, int * err);
int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode);
+int reiserfs_inode_setattr(struct dentry *, struct iattr * attr);
/* namei.c */
inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
int search_by_entry_key (struct super_block * sb, const struct cpu_key * key,
struct path * path,
struct reiserfs_dir_entry * de);
+struct dentry * reiserfs_lookup (struct inode * dir, struct dentry *dentry);
+int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode);
+int reiserfs_mknod (struct inode * dir_inode, struct dentry *dentry, int mode, int rdev);
+int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode);
+int reiserfs_rmdir (struct inode * dir, struct dentry *dentry);
+int reiserfs_unlink (struct inode * dir, struct dentry *dentry);
+int reiserfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname);
+int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry *dentry);
+int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir, struct dentry *new_dentry);
+
+/* super.c */
+inline void reiserfs_mark_buffer_dirty (struct buffer_head * bh, int flag);
+inline void reiserfs_mark_buffer_clean (struct buffer_head * bh);
+void reiserfs_write_super (struct super_block * s);
+void reiserfs_put_super (struct super_block * s);
+int reiserfs_remount (struct super_block * s, int * flags, char * data);
+/*int read_super_block (struct super_block * s, int size);
+int read_bitmaps (struct super_block * s);
+int read_old_bitmaps (struct super_block * s);
+int read_old_super_block (struct super_block * s, int size);*/
+struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent);
+int reiserfs_statfs (struct super_block * s, struct statfs * buf);
+
/* procfs.c */
#if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
@@ -1803,6 +2006,8 @@ void free_buffers_in_tb (struct tree_balance * p_s_tb);
/* prints.c */
void reiserfs_panic (struct super_block * s, const char * fmt, ...)
__attribute__ ( ( noreturn ) );/* __attribute__( ( format ( printf, 2, 3 ) ) ) */
+void reiserfs_warning (const char * fmt, ...);
+/* __attribute__( ( format ( printf, 1, 2 ) ) ); */
void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...);
/* __attribute__( ( format ( printf, 3, 4 ) ) ); */
void print_virtual_node (struct virtual_node * vn);
@@ -1895,6 +2100,83 @@ const char *reiserfs_get_version_string(void) CONSTF;
#define reiserfs_test_le_bit ext2_test_bit
#define reiserfs_find_next_zero_le_bit ext2_find_next_zero_bit
+
+//
+// this was totally copied from from linux's
+// find_first_zero_bit and changed a bit
+//
+
+#ifdef __i386__
+
+static __inline__ int
+find_first_nonzero_bit(const void * addr, unsigned size) {
+ int res;
+ int __d0;
+ void *__d1;
+
+
+ if (!size) {
+ return (0);
+ }
+ __asm__ __volatile__ (
+ "cld\n\t"
+ "xorl %%eax,%%eax\n\t"
+ "repe; scasl\n\t"
+ "je 1f\n\t"
+ "movl -4(%%edi),%%eax\n\t"
+ "subl $4, %%edi\n\t"
+ "bsfl %%eax,%%eax\n\t"
+ "1:\tsubl %%edx,%%edi\n\t"
+ "shll $3,%%edi\n\t"
+ "addl %%edi,%%eax"
+ :"=a" (res),
+ "=c"(__d0), "=D"(__d1)
+ :"1" ((size + 31) >> 5), "d" (addr), "2" (addr));
+ return (res);
+}
+
+#else /* __i386__ */
+
+static __inline__ int find_next_nonzero_bit(const void * addr, unsigned size,
+ unsigned offset)
+{
+ unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
+ unsigned int result = offset & ~31UL;
+ unsigned int tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if (offset) {
+ tmp = *p++;
+ /* set to zero first offset bits */
+ tmp &= ~(~0UL >> (32-offset));
+ if (size < 32)
+ goto found_first;
+ if (tmp != 0U)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while (size >= 32) {
+ if ((tmp = *p++) != 0U)
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+found_first:
+found_middle:
+ return result + ffs(tmp);
+}
+
+#define find_first_nonzero_bit(addr,size) find_next_nonzero_bit((addr), (size), 0)
+
+#endif /* 0 */
+
/* sometimes reiserfs_truncate may require to allocate few new blocks
to perform indirect2direct conversion. People probably used to
think, that truncate should work without problems on a filesystem
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 97c574fe8..3a16560f1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -21,7 +21,6 @@ extern unsigned long event;
#include <asm/mmu.h>
#include <linux/smp.h>
-#include <linux/tty.h>
#include <linux/sem.h>
#include <linux/signal.h>
#include <linux/securebits.h>
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 1cf66cd69..b16ee73b3 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -2,7 +2,11 @@
#define _LINUX_SEQ_FILE_H
#ifdef __KERNEL__
+#include <linux/types.h>
+
struct seq_operations;
+struct file;
+struct inode;
struct seq_file {
char *buf;
@@ -12,6 +16,7 @@ struct seq_file {
loff_t index;
struct semaphore sem;
struct seq_operations *op;
+ void *private;
};
struct seq_operations {
diff --git a/include/linux/types.h b/include/linux/types.h
index df4808fcd..211461bc9 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -113,6 +113,17 @@ typedef __u64 u_int64_t;
typedef __s64 int64_t;
#endif
+/*
+ * transition to 64-bit sector_t, possibly making it an option...
+ */
+#undef BLK_64BIT_SECTOR
+
+#ifdef BLK_64BIT_SECTOR
+typedef u64 sector_t;
+#else
+typedef unsigned long sector_t;
+#endif
+
#endif /* __KERNEL_STRICT_NAMES */
/*
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 28f683623..7af47915e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -46,31 +46,6 @@
#define USB_DIR_IN 0x80
/*
- * Descriptor types
- */
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-#define USB_DT_HID (USB_TYPE_CLASS | 0x01)
-#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
-#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
-#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
-
-/*
- * Descriptor sizes per descriptor type
- */
-#define USB_DT_DEVICE_SIZE 18
-#define USB_DT_CONFIG_SIZE 9
-#define USB_DT_INTERFACE_SIZE 9
-#define USB_DT_ENDPOINT_SIZE 7
-#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
-#define USB_DT_HUB_NONVAR_SIZE 7
-#define USB_DT_HID_SIZE 9
-
-/*
* Endpoints
*/
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
@@ -118,16 +93,6 @@
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
-/*
- * HID requests
- */
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_GET_IDLE 0x02
-#define USB_REQ_GET_PROTOCOL 0x03
-#define USB_REQ_SET_REPORT 0x09
-#define USB_REQ_SET_IDLE 0x0A
-#define USB_REQ_SET_PROTOCOL 0x0B
-
#ifdef __KERNEL__
@@ -161,32 +126,6 @@ typedef struct {
} devrequest __attribute__ ((packed));
/*
- * USB-status codes:
- * USB_ST* maps to -E* and should go away in the future
- */
-
-#define USB_ST_NOERROR 0
-#define USB_ST_CRC (-EILSEQ)
-#define USB_ST_BITSTUFF (-EPROTO)
-#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */
-#define USB_ST_DATAOVERRUN (-EOVERFLOW)
-#define USB_ST_DATAUNDERRUN (-EREMOTEIO)
-#define USB_ST_BUFFEROVERRUN (-ECOMM)
-#define USB_ST_BUFFERUNDERRUN (-ENOSR)
-#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */
-#define USB_ST_SHORT_PACKET (-EREMOTEIO)
-#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */
-#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */
-#define USB_ST_URB_PENDING (-EINPROGRESS)
-#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */
-#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/
-#define USB_ST_NOTSUPPORTED (-ENOSYS)
-#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */
-#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */
-#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */
-#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/
-
-/*
* USB device number allocation bitmap. There's one bitmap
* per USB tree.
*/
@@ -200,18 +139,46 @@ struct usb_busmap {
unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))];
};
+struct usb_device;
+
+/*-------------------------------------------------------------------------*/
+
/*
- * This is a USB device descriptor.
- *
- * USB device information
+ * Standard USB Descriptor support.
+ * Devices may also have class-specific or vendor-specific descriptors.
+ */
+
+/*
+ * Descriptor types ... USB 2.0 spec table 9.5
+ */
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+
+// FIXME should be internal to hub driver
+#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
+#define USB_DT_HUB_NONVAR_SIZE 7
+
+/*
+ * Descriptor sizes per descriptor type
*/
+#define USB_DT_DEVICE_SIZE 18
+#define USB_DT_CONFIG_SIZE 9
+#define USB_DT_INTERFACE_SIZE 9
+#define USB_DT_ENDPOINT_SIZE 7
+#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
-/* Everything but the endpoint maximums are aribtrary */
+/* most of these maximums are arbitrary */
#define USB_MAXCONFIG 8
#define USB_ALTSETTINGALLOC 4
#define USB_MAXALTSETTING 128 /* Hard limit */
#define USB_MAXINTERFACES 32
-#define USB_MAXENDPOINTS 32
+#define USB_MAXENDPOINTS 32 /* Hard limit */
/* All standard descriptors have these 2 fields in common */
struct usb_descriptor_header {
@@ -219,7 +186,7 @@ struct usb_descriptor_header {
__u8 bDescriptorType;
} __attribute__ ((packed));
-/* Device descriptor */
+/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
@@ -237,7 +204,7 @@ struct usb_device_descriptor {
__u8 bNumConfigurations;
} __attribute__ ((packed));
-/* Endpoint descriptor */
+/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength __attribute__ ((packed));
__u8 bDescriptorType __attribute__ ((packed));
@@ -248,11 +215,12 @@ struct usb_endpoint_descriptor {
__u8 bRefresh __attribute__ ((packed));
__u8 bSynchAddress __attribute__ ((packed));
+ /* the rest is internal to the Linux implementation */
unsigned char *extra; /* Extra descriptors */
int extralen;
};
-/* Interface descriptor */
+/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength __attribute__ ((packed));
__u8 bDescriptorType __attribute__ ((packed));
@@ -264,6 +232,7 @@ struct usb_interface_descriptor {
__u8 bInterfaceProtocol __attribute__ ((packed));
__u8 iInterface __attribute__ ((packed));
+ /* the rest is internal to the Linux implementation */
struct usb_endpoint_descriptor *endpoint;
unsigned char *extra; /* Extra descriptors */
@@ -281,7 +250,13 @@ struct usb_interface {
void *private_data;
};
-/* Configuration descriptor information.. */
+/* USB_DT_CONFIG: Configuration descriptor information.
+ *
+ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
+ * descriptor type is different. Highspeed-capable devices can look
+ * different depending on what speed they're currently running. Only
+ * devices with a USB_DT_DEVICE_QUALIFIER have an OTHER_SPEED_CONFIG.
+ */
struct usb_config_descriptor {
__u8 bLength __attribute__ ((packed));
__u8 bDescriptorType __attribute__ ((packed));
@@ -292,33 +267,129 @@ struct usb_config_descriptor {
__u8 bmAttributes __attribute__ ((packed));
__u8 MaxPower __attribute__ ((packed));
+ /* the rest is internal to the Linux implementation */
struct usb_interface *interface;
unsigned char *extra; /* Extra descriptors */
int extralen;
};
-/* String descriptor */
+/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength;
__u8 bDescriptorType;
- __u16 wData[1];
+ __u16 wData[1]; /* UTF-16LE encoded */
} __attribute__ ((packed));
-struct usb_device;
+/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
+struct usb_qualifier_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u16 bcdUSB;
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+ __u8 bMaxPacketSize0;
+ __u8 bNumConfigurations;
+ __u8 bRESERVED;
+} __attribute__ ((packed));
+
+/* helpers for driver access to descriptors */
+extern struct usb_interface *
+ usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
+extern struct usb_endpoint_descriptor *
+ usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
+
+int __usb_get_extra_descriptor(char *buffer, unsigned size,
+ unsigned char type, void **ptr);
+#define usb_get_extra_descriptor(ifpoint,type,ptr)\
+ __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
+ type,(void**)ptr)
+
+/*-------------------------------------------------------------------------*/
/*
* Device table entry for "new style" table-driven USB drivers.
* User mode code can read these tables to choose which modules to load.
- * Declare the table as __devinitdata, and as a MODULE_DEVICE_TABLE.
+ * Declare the table as a MODULE_DEVICE_TABLE.
*
- * With a device table provide bind() instead of probe(). Then the
- * third bind() parameter will point to a matching entry from this
- * table. (Null value reserved.)
+ * The third probe() parameter will point to a matching entry from this
+ * table. (Null value reserved.) Use the driver_data field for each
+ * match to hold information tied to that match: device quirks, etc.
*
* Terminate the driver's table with an all-zeroes entry.
- * Init the fields you care about; zeroes are not used in comparisons.
+ * Use the flag values to control which fields are compared.
*/
+
+/**
+ * struct usb_device_id - identifies USB devices for probing and hotplugging
+ * @match_flags: Bit mask controlling of the other fields are used to match
+ * against new devices. Any field except for driver_info may be used,
+ * although some only make sense in conjunction with other fields.
+ * This is usually set by a USB_DEVICE_*() macro, which sets all
+ * other fields in this structure except for driver_info.
+ * @idVendor: USB vendor ID for a device; numbers are assigned
+ * by the USB forum to its members.
+ * @idProduct: Vendor-assigned product ID.
+ * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
+ * This is also used to identify individual product versions, for
+ * a range consisting of a single device.
+ * @bcdDevice_hi: High end of version number range. The range of product
+ * versions is inclusive.
+ * @bDeviceClass: Class of device; numbers are assigned
+ * by the USB forum. Products may choose to implement classes,
+ * or be vendor-specific. Device classes specify behavior of all
+ * the interfaces on a devices.
+ * @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
+ * @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
+ * @bInterfaceClass: Class of interface; numbers are assigned
+ * by the USB forum. Products may choose to implement classes,
+ * or be vendor-specific. Interface classes specify behavior only
+ * of a given interface; other interfaces may support other classes.
+ * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
+ * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @driver_info: Holds information used by the driver. Usually it holds
+ * a pointer to a descriptor understood by the driver, or perhaps
+ * device flags.
+ *
+ * In most cases, drivers will create a table of device IDs by using
+ * USB_DEVICE(), or similar macros designed for that purpose.
+ * They will then export it to userspace using MODULE_DEVICE_TABLE(),
+ * and provide it to the USB core through their usb_driver structure.
+ *
+ * See the usb_match_id() function for information about how matches are
+ * performed. Briefly, you will normally use one of several macros to help
+ * construct these entries. Each entry you provide will either identify
+ * one or more specific products, or will identify a class of products
+ * which have agreed to behave the same. You should put the more specific
+ * matches towards the beginning of your table, so that driver_info can
+ * record quirks of specific products.
+ */
+struct usb_device_id {
+ /* which fields to match against? */
+ __u16 match_flags;
+
+ /* Used for product specific matches; range is inclusive */
+ __u16 idVendor;
+ __u16 idProduct;
+ __u16 bcdDevice_lo;
+ __u16 bcdDevice_hi;
+
+ /* Used for device class matches */
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+
+ /* Used for interface class matches */
+ __u8 bInterfaceClass;
+ __u8 bInterfaceSubClass;
+ __u8 bInterfaceProtocol;
+
+ /* not matched against */
+ unsigned long driver_info;
+};
+
+/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
@@ -338,53 +409,98 @@ struct usb_device;
#define USB_DEVICE_ID_MATCH_INT_INFO \
(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
-/* Some useful macros */
+/**
+ * USB_DEVICE - macro used to describe a specific usb device
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device.
+ */
#define USB_DEVICE(vend,prod) \
match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod)
+/**
+ * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @lo: the bcdDevice_lo value
+ * @hi: the bcdDevice_hi value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device, with a version range.
+ */
#define USB_DEVICE_VER(vend,prod,lo,hi) \
match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi)
+
+/**
+ * USB_DEVICE_INFO - macro used to describe a class of usb devices
+ * @cl: bDeviceClass value
+ * @sc: bDeviceSubClass value
+ * @pr: bDeviceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific class of devices.
+ */
#define USB_DEVICE_INFO(cl,sc,pr) \
match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr)
+
+/**
+ * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
+ * @cl: bInterfaceClass value
+ * @sc: bInterfaceSubClass value
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific class of interfaces.
+ */
#define USB_INTERFACE_INFO(cl,sc,pr) \
match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr)
-struct usb_device_id {
- /* This bitmask is used to determine which of the following fields
- * are to be used for matching.
- */
- __u16 match_flags;
-
- /*
- * vendor/product codes are checked, if vendor is nonzero
- * Range is for device revision (bcdDevice), inclusive;
- * zero values here mean range isn't considered
- */
- __u16 idVendor;
- __u16 idProduct;
- __u16 bcdDevice_lo, bcdDevice_hi;
-
- /*
- * if device class != 0, these can be match criteria;
- * but only if this bDeviceClass value is nonzero
- */
- __u8 bDeviceClass;
- __u8 bDeviceSubClass;
- __u8 bDeviceProtocol;
-
- /*
- * if interface class != 0, these can be match criteria;
- * but only if this bInterfaceClass value is nonzero
- */
- __u8 bInterfaceClass;
- __u8 bInterfaceSubClass;
- __u8 bInterfaceProtocol;
-
- /*
- * for driver's use; not involved in driver matching.
- */
- unsigned long driver_info;
-};
+/* -------------------------------------------------------------------------- */
+/**
+ * struct usb_driver - identifies USB driver to usbcore
+ * @name: The driver name should be unique among USB drivers
+ * @probe: Called to see if the driver is willing to manage a particular
+ * interface on a device. The probe routine returns a handle that
+ * will later be provided to disconnect(), or a null pointer to
+ * indicate that the driver will not handle the interface.
+ * The handle is normally a pointer to driver-specific data.
+ * If the probe() routine needs to access the interface
+ * structure itself, use usb_ifnum_to_if() to make sure it's using
+ * the right one.
+ * @disconnect: Called when the interface is no longer accessible, usually
+ * because its device has been (or is being) disconnected. The
+ * handle passed is what was returned by probe(), or was provided
+ * to usb_driver_claim_interface().
+ * @fops: USB drivers can reuse some character device framework in
+ * the USB subsystem by providing a file operations vector and
+ * a minor number.
+ * @minor: Used with fops to simplify creating USB character devices.
+ * Such drivers have sixteen character devices, using the USB
+ * major number and starting with this minor number.
+ * @ioctl: Used for drivers that want to talk to userspace through
+ * the "usbfs" filesystem. This lets devices provide ways to
+ * expose information to user space regardless of where they
+ * do (or don't) show up otherwise in the filesystem.
+ * @id_table: USB drivers use ID table to support hotplugging.
+ * Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to
+ * say that probe() should be called for any unclaimed interfce.
+ *
+ * USB drivers should provide a name, probe() and disconnect() methods,
+ * and an id_table. Other driver fields are optional.
+ *
+ * The id_table is used in hotplugging. It holds a set of descriptors,
+ * and specialized data may be associated with each entry. That table
+ * is used by both user and kernel mode hotplugging support.
+ *
+ * The probe() and disconnect() methods are called in a context where
+ * they can sleep, but they should avoid abusing the privilage. Most
+ * work to connect to a device should be done when the device is opened,
+ * and undone at the last close. The disconnect code needs to address
+ * concurrency issues with respect to open() and close() methods, as
+ * well as cancel any I/O requests that are still pending.
+ */
struct usb_driver {
const char *name;
@@ -393,7 +509,10 @@ struct usb_driver {
unsigned intf, /* what interface */
const struct usb_device_id *id /* from id_table */
);
- void (*disconnect)(struct usb_device *, void *);
+ void (*disconnect)(
+ struct usb_device *dev, /* the device */
+ void *handle /* as returned by probe() */
+ );
struct list_head driver_list;
@@ -405,152 +524,437 @@ struct usb_driver {
/* ioctl -- userspace apps can talk to drivers through usbdevfs */
int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf);
- /* support for "new-style" USB hotplugging
- * binding policy can be driven from user mode too
- */
+ /* support for "new-style" USB hotplugging */
const struct usb_device_id *id_table;
/* suspend before the bus suspends;
* disconnect or resume when the bus resumes */
- // void (*suspend)(struct usb_device *dev);
- // void (*resume)(struct usb_device *dev);
+ /* void (*suspend)(struct usb_device *dev); */
+ /* void (*resume)(struct usb_device *dev); */
};
-
-/*----------------------------------------------------------------------------*
- * New USB Structures *
- *----------------------------------------------------------------------------*/
+
+/*
+ * use these in module_init()/module_exit()
+ * and don't forget MODULE_DEVICE_TABLE(usb, ...)
+ */
+extern int usb_register(struct usb_driver *);
+extern void usb_deregister(struct usb_driver *);
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * URB support, for asynchronous request completions
+ */
/*
* urb->transfer_flags:
+ *
+ * FIXME should be URB_* flags
*/
#define USB_DISABLE_SPD 0x0001
#define USB_ISO_ASAP 0x0002
#define USB_ASYNC_UNLINK 0x0008
#define USB_QUEUE_BULK 0x0010
#define USB_NO_FSBR 0x0020
-#define USB_ZERO_PACKET 0x0040 // Finish bulk OUTs always with zero length packet
-#define USB_TIMEOUT_KILLED 0x1000 // only set by HCD!
+#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
+#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
+ /* ... less overhead for QUEUE_BULK */
+#define USB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */
typedef struct
{
unsigned int offset;
- unsigned int length; // expected length
+ unsigned int length; /* expected length */
unsigned int actual_length;
unsigned int status;
} iso_packet_descriptor_t, *piso_packet_descriptor_t;
struct urb;
+
typedef void (*usb_complete_t)(struct urb *);
-typedef struct urb
+/**
+ * struct urb - USB Request Block
+ * @urb_list: For use by current owner of the URB.
+ * @next: Used primarily to link ISO requests into rings.
+ * @pipe: Holds endpoint number, direction, type, and max packet size.
+ * Create these values with the eight macros available;
+ * usb_{snd,rcv}TYPEpipe(dev,endpoint), where the type is "ctrl"
+ * (control), "bulk", "int" (interrupt), or "iso" (isochronous).
+ * For example usb_sndbulkpipe() or usb_rcvintpipe(). Endpoint
+ * numbers range from zero to fifteen. Note that "in" endpoint two
+ * is a different endpoint (and pipe) from "out" endpoint two.
+ * The current configuration controls the existence, type, and
+ * maximum packet size of any given endpoint.
+ * @dev: Identifies the USB device to perform the request.
+ * @status: This is read in non-iso completion functions to get the
+ * status of the particular request. ISO requests only use it
+ * to tell whether the URB was unlinked; detailed status for
+ * each frame is in the fields of the iso_frame-desc.
+ * @transfer_flags: A variety of flags may be used to affect how URB
+ * submission, unlinking, or operation are handled. Different
+ * kinds of URB can use different flags.
+ * @transfer_buffer: For non-iso transfers, this identifies the buffer
+ * to (or from) which the I/O request will be performed. This
+ * buffer must be suitable for DMA; allocate it with kmalloc()
+ * or equivalent. For transfers to "in" endpoints, contents of
+ * this buffer will be modified.
+ * @transfer_buffer_length: How big is transfer_buffer. The transfer may
+ * be broken up into chunks according to the current maximum packet
+ * size for the endpoint, which is a function of the configuration
+ * and is encoded in the pipe.
+ * @actual_length: This is read in non-iso completion functions, and
+ * it tells how many bytes (out of transfer_buffer_length) were
+ * transferred. It will normally be the same as requested, unless
+ * either an error was reported or a short read was performed and
+ * the USB_DISABLE_SPD transfer flag was used to say that such
+ * short reads are not errors.
+ * @setup_packet: Only used for control transfers, this points to eight bytes
+ * of setup data. Control transfers always start by sending this data
+ * to the device. Then transfer_buffer is read or written, if needed.
+ * @start_frame: Returns the initial frame for interrupt or isochronous
+ * transfers.
+ * @number_of_packets: Lists the number of ISO transfer buffers.
+ * @interval: Specifies the polling interval for interrupt transfers, in
+ * milliseconds.
+ * @error_count: Returns the number of ISO transfers that reported errors.
+ * @context: For use in completion functions. This normally points to
+ * request-specific driver context.
+ * @complete: Completion handler. This URB is passed as the parameter to the
+ * completion function. Except for interrupt or isochronous transfers
+ * that aren't being unlinked, the completion function may then do what
+ * it likes with the URB, including resubmitting or freeing it.
+ * @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to
+ * collect the transfer status for each buffer.
+ *
+ * This structure identifies USB transfer requests. URBs may be allocated
+ * in any way, although usb_alloc_urb() is often convenient. Initialization
+ * may be done using various FILL_*_URB() macros. URBs are submitted
+ * using usb_submit_urb(), and pending requests may be canceled using
+ * usb_unlink_urb().
+ *
+ * Initialization:
+ *
+ * All URBs submitted must initialize dev, pipe, next (may be null),
+ * transfer_flags (may be zero), complete, timeout (may be zero).
+ * The USB_ASYNC_UNLINK transfer flag affects later invocations of
+ * the usb_unlink_urb() routine.
+ *
+ * All non-isochronous URBs must also initialize
+ * transfer_buffer and transfer_buffer_length. They may provide the
+ * USB_DISABLE_SPD transfer flag, indicating that short reads are
+ * not to be treated as errors.
+ *
+ * Bulk URBs may pass the USB_QUEUE_BULK transfer flag, telling the host
+ * controller driver never to report an error if several bulk requests get
+ * queued to the same endpoint. Such queueing supports more efficient use
+ * of bus bandwidth, minimizing delays due to interrupts and scheduling,
+ * if the host controller hardware is smart enough. Bulk URBs can also
+ * use the USB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers
+ * should always terminate with a short packet, even if it means adding an
+ * extra zero length packet.
+ *
+ * Control URBs must provide a setup_packet.
+ *
+ * Interupt UBS must provide an interval, saying how often (in milliseconds)
+ * to poll for transfers. After the URB has been submitted, the interval
+ * and start_frame fields reflect how the transfer was actually scheduled.
+ * The polling interval may be more frequent than requested.
+ * For example, some controllers have a maximum interval of 32 microseconds,
+ * while others support intervals of up to 1024 microseconds.
+ *
+ * Isochronous URBs normally use the USB_ISO_ASAP transfer flag, telling
+ * the host controller to schedule the transfer as soon as bandwidth
+ * utilization allows, and then set start_frame to reflect the actual frame
+ * selected during submission. Otherwise drivers must specify the start_frame
+ * and handle the case where the transfer can't begin then. However, drivers
+ * won't know how bandwidth is currently allocated, and while they can
+ * find the current frame using usb_get_current_frame_number () they can't
+ * know the range for that frame number. (Common ranges for the frame
+ * counter include 256, 512, and 1024 frames.)
+ *
+ * Isochronous URBs have a different data transfer model, in part because
+ * the quality of service is only "best effort". Callers provide specially
+ * allocated URBs, with number_of_packets worth of iso_frame_desc structures
+ * at the end. Each such packet is an individual ISO transfer. Isochronous
+ * URBs are normally submitted with urb->next fields set up as a ring, so
+ * that data (such as audio or video) streams at as constant a rate as the
+ * host controller scheduler can support.
+ *
+ * Completion Callbacks:
+ *
+ * The completion callback is made in_interrupt(), and one of the first
+ * things that a completion handler should do is check the status field.
+ * The status field is provided for all URBs. It is used to report
+ * unlinked URBs, and status for all non-ISO transfers. It should not
+ * be examined outside of the completion handler.
+ *
+ * The context field is normally used to link URBs back to the relevant
+ * driver or request state.
+ *
+ * When completion callback is invoked for non-isochronous URBs, the
+ * actual_length field tells how many bytes were transferred.
+ *
+ * For interrupt and isochronous URBs, the URB provided to the callback
+ * function is still "owned" by the USB core subsystem unless the status
+ * indicates that the URB has been unlinked. Completion handlers should
+ * not modify such URBs until they have been unlinked.
+ *
+ * ISO transfer status is reported in the status and actual_length fields
+ * of the iso_frame_desc array, and the number of errors is reported in
+ * error_count.
+ */
+struct urb
{
- spinlock_t lock; // lock for the URB
- void *hcpriv; // private data for host controller
- struct list_head urb_list; // list pointer to all active urbs
- struct urb *next; // pointer to next URB
- struct usb_device *dev; // pointer to associated USB device
- unsigned int pipe; // pipe information
- int status; // returned status
- unsigned int transfer_flags; // USB_DISABLE_SPD | USB_ISO_ASAP | etc.
- void *transfer_buffer; // associated data buffer
- int transfer_buffer_length; // data buffer length
- int actual_length; // actual data buffer length
- int bandwidth; // bandwidth for this transfer request (INT or ISO)
- unsigned char *setup_packet; // setup packet (control only)
- //
- int start_frame; // start frame (iso/irq only)
- int number_of_packets; // number of packets in this request (iso)
- int interval; // polling interval (irq only)
- int error_count; // number of errors in this transfer (iso only)
- int timeout; // timeout (in jiffies)
- //
- void *context; // context for completion routine
- usb_complete_t complete; // pointer to completion routine
- //
- iso_packet_descriptor_t iso_frame_desc[0];
-} urb_t, *purb_t;
-
-#define FILL_CONTROL_URB(a,aa,b,c,d,e,f,g) \
+ spinlock_t lock; /* lock for the URB */
+ void *hcpriv; /* private data for host controller */
+ struct list_head urb_list; /* list pointer to all active urbs */
+ struct urb *next; /* (in) pointer to next URB */
+ struct usb_device *dev; /* (in) pointer to associated device */
+ unsigned int pipe; /* (in) pipe information */
+ int status; /* (return) non-ISO status */
+ unsigned int transfer_flags; /* (in) USB_DISABLE_SPD | ...*/
+ void *transfer_buffer; /* (in) associated data buffer */
+ int transfer_buffer_length; /* (in) data buffer length */
+ int actual_length; /* (return) actual transfer length */
+ int bandwidth; /* bandwidth for INT/ISO request */
+ unsigned char *setup_packet; /* (in) setup packet (control only) */
+ int start_frame; /* (modify) start frame (INT/ISO) */
+ int number_of_packets; /* (in) number of ISO packets */
+ int interval; /* (in) polling interval (INT only) */
+ int error_count; /* (return) number of ISO errors */
+ int timeout; /* (in) timeout, in jiffies */
+ void *context; /* (in) context for completion */
+ usb_complete_t complete; /* (in) completion routine */
+ iso_packet_descriptor_t iso_frame_desc[0]; /* (in) ISO ONLY */
+};
+
+typedef struct urb urb_t, *purb_t;
+
+/**
+ * FILL_CONTROL_URB - macro to help initialize a control urb
+ * @URB: pointer to the urb to initialize.
+ * @DEV: pointer to the struct usb_device for this urb.
+ * @PIPE: the endpoint pipe
+ * @SETUP_PACKET: pointer to the setup_packet buffer
+ * @TRANSFER_BUFFER: pointer to the transfer buffer
+ * @BUFFER_LENGTH: length of the transfer buffer
+ * @COMPLETE: pointer to the usb_complete_t function
+ * @CONTEXT: what to set the urb context to.
+ *
+ * Initializes a control urb with the proper information needed to submit
+ * it to a device. This macro is depreciated, the usb_fill_control_urb()
+ * function should be used instead.
+ */
+#define FILL_CONTROL_URB(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \
do {\
- spin_lock_init(&(a)->lock);\
- (a)->dev=aa;\
- (a)->pipe=b;\
- (a)->setup_packet=c;\
- (a)->transfer_buffer=d;\
- (a)->transfer_buffer_length=e;\
- (a)->complete=f;\
- (a)->context=g;\
+ spin_lock_init(&(URB)->lock);\
+ (URB)->dev=DEV;\
+ (URB)->pipe=PIPE;\
+ (URB)->setup_packet=SETUP_PACKET;\
+ (URB)->transfer_buffer=TRANSFER_BUFFER;\
+ (URB)->transfer_buffer_length=BUFFER_LENGTH;\
+ (URB)->complete=COMPLETE;\
+ (URB)->context=CONTEXT;\
} while (0)
-#define FILL_BULK_URB(a,aa,b,c,d,e,f) \
+/**
+ * FILL_BULK_URB - macro to help initialize a bulk urb
+ * @URB: pointer to the urb to initialize.
+ * @DEV: pointer to the struct usb_device for this urb.
+ * @PIPE: the endpoint pipe
+ * @TRANSFER_BUFFER: pointer to the transfer buffer
+ * @BUFFER_LENGTH: length of the transfer buffer
+ * @COMPLETE: pointer to the usb_complete_t function
+ * @CONTEXT: what to set the urb context to.
+ *
+ * Initializes a bulk urb with the proper information needed to submit it
+ * to a device. This macro is depreciated, the usb_fill_bulk_urb()
+ * function should be used instead.
+ */
+#define FILL_BULK_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \
do {\
- spin_lock_init(&(a)->lock);\
- (a)->dev=aa;\
- (a)->pipe=b;\
- (a)->transfer_buffer=c;\
- (a)->transfer_buffer_length=d;\
- (a)->complete=e;\
- (a)->context=f;\
+ spin_lock_init(&(URB)->lock);\
+ (URB)->dev=DEV;\
+ (URB)->pipe=PIPE;\
+ (URB)->transfer_buffer=TRANSFER_BUFFER;\
+ (URB)->transfer_buffer_length=BUFFER_LENGTH;\
+ (URB)->complete=COMPLETE;\
+ (URB)->context=CONTEXT;\
} while (0)
-#define FILL_INT_URB(a,aa,b,c,d,e,f,g) \
+/**
+ * FILL_INT_URB - macro to help initialize a interrupt urb
+ * @URB: pointer to the urb to initialize.
+ * @DEV: pointer to the struct usb_device for this urb.
+ * @PIPE: the endpoint pipe
+ * @TRANSFER_BUFFER: pointer to the transfer buffer
+ * @BUFFER_LENGTH: length of the transfer buffer
+ * @COMPLETE: pointer to the usb_complete_t function
+ * @CONTEXT: what to set the urb context to.
+ * @INTERVAL: what to set the urb interval to.
+ *
+ * Initializes a interrupt urb with the proper information needed to submit
+ * it to a device. This macro is depreciated, the usb_fill_int_urb()
+ * function should be used instead.
+ */
+#define FILL_INT_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) \
do {\
- spin_lock_init(&(a)->lock);\
- (a)->dev=aa;\
- (a)->pipe=b;\
- (a)->transfer_buffer=c;\
- (a)->transfer_buffer_length=d;\
- (a)->complete=e;\
- (a)->context=f;\
- (a)->interval=g;\
- (a)->start_frame=-1;\
+ spin_lock_init(&(URB)->lock);\
+ (URB)->dev=DEV;\
+ (URB)->pipe=PIPE;\
+ (URB)->transfer_buffer=TRANSFER_BUFFER;\
+ (URB)->transfer_buffer_length=BUFFER_LENGTH;\
+ (URB)->complete=COMPLETE;\
+ (URB)->context=CONTEXT;\
+ (URB)->interval=INTERVAL;\
+ (URB)->start_frame=-1;\
} while (0)
-#define FILL_CONTROL_URB_TO(a,aa,b,c,d,e,f,g,h) \
- do {\
- spin_lock_init(&(a)->lock);\
- (a)->dev=aa;\
- (a)->pipe=b;\
- (a)->setup_packet=c;\
- (a)->transfer_buffer=d;\
- (a)->transfer_buffer_length=e;\
- (a)->complete=f;\
- (a)->context=g;\
- (a)->timeout=h;\
- } while (0)
+/**
+ * usb_fill_control_urb - initializes a control urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @setup_packet: pointer to the setup_packet buffer
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a control urb with the proper information needed to submit
+ * it to a device.
+ */
+static inline void usb_fill_control_urb (struct urb *urb,
+ struct usb_device *dev,
+ unsigned int pipe,
+ unsigned char *setup_packet,
+ void *transfer_buffer,
+ int buffer_length,
+ usb_complete_t complete,
+ void *context)
+{
+ spin_lock_init(&urb->lock);
+ urb->dev = dev;
+ urb->pipe = pipe;
+ urb->setup_packet = setup_packet;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = buffer_length;
+ urb->complete = complete;
+ urb->context = context;
+}
-#define FILL_BULK_URB_TO(a,aa,b,c,d,e,f,g) \
- do {\
- spin_lock_init(&(a)->lock);\
- (a)->dev=aa;\
- (a)->pipe=b;\
- (a)->transfer_buffer=c;\
- (a)->transfer_buffer_length=d;\
- (a)->complete=e;\
- (a)->context=f;\
- (a)->timeout=g;\
- } while (0)
+/**
+ * usb_fill_bulk_urb - macro to help initialize a bulk urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a bulk urb with the proper information needed to submit it
+ * to a device.
+ */
+static inline void usb_fill_bulk_urb (struct urb *urb,
+ struct usb_device *dev,
+ unsigned int pipe,
+ void *transfer_buffer,
+ int buffer_length,
+ usb_complete_t complete,
+ void *context)
+
+{
+ spin_lock_init(&urb->lock);
+ urb->dev = dev;
+ urb->pipe = pipe;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = buffer_length;
+ urb->complete = complete;
+ urb->context = context;
+}
+
+/**
+ * usb_fill_int_urb - macro to help initialize a interrupt urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @transfer_buffer: pointer to the transfer buffer
+ * @buffer_length: length of the transfer buffer
+ * @complete: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ * @interval: what to set the urb interval to.
+ *
+ * Initializes a interrupt urb with the proper information needed to submit
+ * it to a device.
+ */
+static inline void usb_fill_int_urb (struct urb *urb,
+ struct usb_device *dev,
+ unsigned int pipe,
+ void *transfer_buffer,
+ int buffer_length,
+ usb_complete_t complete,
+ void *context,
+ int interval)
+{
+ spin_lock_init(&urb->lock);
+ urb->dev = dev;
+ urb->pipe = pipe;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = buffer_length;
+ urb->complete = complete;
+ urb->context = context;
+ urb->interval = interval;
+ urb->start_frame = -1;
+}
-purb_t usb_alloc_urb(int iso_packets);
-void usb_free_urb (purb_t purb);
-int usb_submit_urb(purb_t purb);
-int usb_unlink_urb(purb_t purb);
-int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout);
-int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout);
+extern struct urb *usb_alloc_urb(int iso_packets);
+extern void usb_free_urb(struct urb *purb);
+extern int usb_submit_urb(struct urb *purb);
+extern int usb_unlink_urb(struct urb *purb);
/*-------------------------------------------------------------------*
* SYNCHRONOUS CALL SUPPORT *
*-------------------------------------------------------------------*/
-struct usb_api_data
-{
- wait_queue_head_t wqh;
- int done;
- /* void* stuff; */ /* Possible extension later. */
-};
+extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+ __u8 request, __u8 requesttype, __u16 value, __u16 index,
+ void *data, __u16 size, int timeout);
+extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
+ void *data, int len, int *actual_length,
+ int timeout);
+
+/* wrappers around usb_control_msg() for the most common standard requests */
+extern int usb_clear_halt(struct usb_device *dev, int pipe);
+extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
+ unsigned char descindex, void *buf, int size);
+extern int usb_get_device_descriptor(struct usb_device *dev);
+extern int usb_get_status(struct usb_device *dev,
+ int type, int target, void *data);
+extern int usb_get_string(struct usb_device *dev,
+ unsigned short langid, unsigned char index, void *buf, int size);
+extern int usb_string(struct usb_device *dev, int index,
+ char *buf, size_t size);
+extern int usb_set_configuration(struct usb_device *dev, int configuration);
+extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
+
+/*
+ * timeouts, in seconds, used for sending/receiving control messages
+ * they typically complete within a few frames (msec) after they're issued
+ */
+#ifdef CONFIG_USB_LONG_TIMEOUT
+#define USB_CTRL_GET_TIMEOUT 4
+#else
+#define USB_CTRL_GET_TIMEOUT 3
+#endif
+
+#define USB_CTRL_SET_TIMEOUT 3
/* -------------------------------------------------------------------------- */
+/* Host Controller Driver (HCD) support */
+
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
@@ -591,6 +995,60 @@ struct usb_bus {
atomic_t refcnt;
};
+extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
+extern void usb_free_bus(struct usb_bus *);
+extern void usb_register_bus(struct usb_bus *);
+extern void usb_deregister_bus(struct usb_bus *);
+
+extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
+extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
+ int bustime, int isoc);
+extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb,
+ int isoc);
+extern int usb_root_hub_string(int id, int serial,
+ char *type, __u8 *data, int len);
+
+/*
+ * Some USB 1.1 bandwidth allocation constants.
+ */
+#define BW_HOST_DELAY 1000L /* nanoseconds */
+#define BW_HUB_LS_SETUP 333L /* nanoseconds */
+ /* 4 full-speed bit times (est.) */
+
+#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
+#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
+#define FRAME_TIME_USECS 1000L
+#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
+
+#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
+ /* Trying not to use worst-case bit-stuffing
+ of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+ /* bytecount = data payload byte count */
+
+#define NS_TO_US(ns) ((ns + 500L) / 1000L)
+ /* convert & round nanoseconds to microseconds */
+
+
+/* -------------------------------------------------------------------------- */
+
+/* Enumeration is only for the hub driver, or HCD virtual root hubs */
+extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
+ struct usb_bus *);
+extern void usb_free_dev(struct usb_device *);
+extern int usb_new_device(struct usb_device *dev);
+extern void usb_connect(struct usb_device *dev);
+extern void usb_disconnect(struct usb_device **);
+
+#ifndef _LINUX_HUB_H
+/* exported to hub driver ONLY to support usb_reset_device () */
+extern int usb_get_configuration(struct usb_device *dev);
+extern void usb_set_maxpacket(struct usb_device *dev);
+extern void usb_destroy_configuration(struct usb_device *dev);
+extern int usb_set_address(struct usb_device *dev);
+#endif /* _LINUX_HUB_H */
+
+/* -------------------------------------------------------------------------- */
+
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
* have up to 255 ports. The most yet reported is 10.
@@ -648,44 +1106,30 @@ struct usb_device {
struct usb_device *children[USB_MAXCHILDREN];
};
-extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
-extern struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
-
-extern int usb_register(struct usb_driver *);
-extern void usb_deregister(struct usb_driver *);
+/* for when layers above USB add new non-USB drivers */
extern void usb_scan_devices(void);
-/* used these for multi-interface device registration */
-extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv);
-extern int usb_interface_claimed(struct usb_interface *iface);
-extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface);
-const struct usb_device_id *usb_match_id(struct usb_device *dev,
- struct usb_interface *interface,
- const struct usb_device_id *id);
+/* mostly for devices emulating SCSI over USB */
+extern int usb_reset_device(struct usb_device *dev);
-extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
-extern void usb_free_bus(struct usb_bus *);
-extern void usb_register_bus(struct usb_bus *);
-extern void usb_deregister_bus(struct usb_bus *);
+/* for drivers using iso endpoints */
+extern int usb_get_current_frame_number (struct usb_device *usb_dev);
-extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *);
-extern void usb_free_dev(struct usb_device *);
+/* drivers must track when they bind to a device's interfaces */
extern void usb_inc_dev_use(struct usb_device *);
#define usb_dec_dev_use usb_free_dev
-extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
-extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc);
-extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc);
-
-extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
-
-extern int usb_root_hub_string(int id, int serial, char *type, __u8 *data, int len);
-extern void usb_connect(struct usb_device *dev);
-extern void usb_disconnect(struct usb_device **);
-
-extern void usb_destroy_configuration(struct usb_device *dev);
+/* used these for multi-interface device registration */
+extern void usb_driver_claim_interface(struct usb_driver *driver,
+ struct usb_interface *iface, void* priv);
+extern int usb_interface_claimed(struct usb_interface *iface);
+extern void usb_driver_release_interface(struct usb_driver *driver,
+ struct usb_interface *iface);
+const struct usb_device_id *usb_match_id(struct usb_device *dev,
+ struct usb_interface *interface,
+ const struct usb_device_id *id);
-int usb_get_current_frame_number (struct usb_device *usb_dev);
+/* -------------------------------------------------------------------------- */
/*
* Calling this entity a "pipe" is glorifying it. A USB pipe
@@ -693,7 +1137,7 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
* of the following information:
* - device number (7 bits)
* - endpoint number (4 bits)
- * - current Data0/1 state (1 bit)
+ * - current Data0/1 state (1 bit) [Historical; now gone]
* - direction (1 bit)
* - speed (1 bit)
* - max packet size (2 bits: 8, 16, 32 or 64) [Historical; now gone.]
@@ -710,7 +1154,7 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
* - direction: bit 7 (0 = Host-to-Device [Out], 1 = Device-to-Host [In])
* - device: bits 8-14
* - endpoint: bits 15-18
- * - Data0/1: bit 19
+ * - Data0/1: bit 19 [Historical; now gone. ]
* - speed: bit 26 (0 = Full, 1 = Low Speed)
* - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
*
@@ -723,6 +1167,8 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
* like full speed devices.
*/
+// FIXME 2.5 get rid of usb_pipeslow(), just use dev->speed
+
#define PIPE_ISOCHRONOUS 0
#define PIPE_INTERRUPT 1
#define PIPE_CONTROL 2
@@ -738,7 +1184,6 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f)
#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
-#define usb_pipedata(pipe) (((pipe) >> 19) & 1)
#define usb_pipeslow(pipe) (((pipe) >> 26) & 1)
#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
@@ -782,58 +1227,10 @@ static inline unsigned int __default_pipe(struct usb_device *dev)
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev))
#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev) | USB_DIR_IN)
-/*
- * Send and receive control messages..
- */
-int usb_new_device(struct usb_device *dev);
-int usb_reset_device(struct usb_device *dev);
-int usb_set_address(struct usb_device *dev);
-int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
- unsigned char descindex, void *buf, int size);
-int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char desctype,
- unsigned char descindex, void *buf, int size);
-int usb_get_device_descriptor(struct usb_device *dev);
-int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr);
-int usb_get_status(struct usb_device *dev, int type, int target, void *data);
-int usb_get_configuration(struct usb_device *dev);
-int usb_get_protocol(struct usb_device *dev, int ifnum);
-int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
-int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
-int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id);
-int usb_set_configuration(struct usb_device *dev, int configuration);
-int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
- unsigned char id, void *buf, int size);
-int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type,
- unsigned char id, void *buf, int size);
-int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
-int usb_clear_halt(struct usb_device *dev, int pipe);
-void usb_set_maxpacket(struct usb_device *dev);
-
-#define usb_get_extra_descriptor(ifpoint,type,ptr)\
- __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr)
-
-/*
- * Some USB bandwidth allocation constants.
- */
-#define BW_HOST_DELAY 1000L /* nanoseconds */
-#define BW_HUB_LS_SETUP 333L /* nanoseconds */
- /* 4 full-speed bit times (est.) */
-
-#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
-#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
-#define FRAME_TIME_USECS 1000L
-#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
-
-#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
- /* Trying not to use worst-case bit-stuffing
- of (7/6 * 8 * bytecount) = 9.33 * bytecount */
- /* bytecount = data payload byte count */
-
-#define NS_TO_US(ns) ((ns + 500L) / 1000L)
- /* convert & round nanoseconds to microseconds */
+/* -------------------------------------------------------------------------- */
/*
- * Debugging helpers..
+ * Debugging and troubleshooting/diagnostic helpers.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *);
void usb_show_config_descriptor(struct usb_config_descriptor *);
@@ -847,13 +1244,17 @@ void usb_show_string(struct usb_device *dev, char *id, int index);
#else
#define dbg(format, arg...) do {} while (0)
#endif
+
#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg)
#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg)
+/* -------------------------------------------------------------------------- */
+
/*
* bus and driver list
+ * exported only for usbdevfs (not visible outside usbcore)
*/
extern struct list_head usb_driver_list;
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 0241b41fd..ef9481836 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -7,6 +7,7 @@
*/
#include <linux/config.h>
+#include <linux/tty.h>
#include <linux/vt.h>
#include <linux/kd.h>
diff --git a/init/do_mounts.c b/init/do_mounts.c
new file mode 100644
index 000000000..01439aadb
--- /dev/null
+++ b/init/do_mounts.c
@@ -0,0 +1,559 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/unistd.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/blk.h>
+#include <linux/tty.h>
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/nfs_mount.h>
+
+#include <asm/uaccess.h>
+
+/* syscalls missing from unistd.h */
+
+static inline _syscall2(int,mkdir,char *,name,int,mode);
+static inline _syscall1(int,chdir,char *,name);
+static inline _syscall1(int,chroot,char *,name);
+static inline _syscall1(int,unlink,char *,name);
+static inline _syscall3(int,mknod,char *,name,int,mode,dev_t,dev);
+static inline _syscall5(int,mount,char *,dev,char *,dir,char *,type,
+ unsigned long,flags,void *,data);
+static inline _syscall2(int,umount,char *,name,int,flags);
+
+extern void rd_load(void);
+extern void initrd_load(void);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
+#endif
+int root_mountflags = MS_RDONLY;
+char root_device_name[64];
+
+/* this is initialized in init/main.c */
+kdev_t ROOT_DEV;
+
+static int __init readonly(char *str)
+{
+ if (*str)
+ return 0;
+ root_mountflags |= MS_RDONLY;
+ return 1;
+}
+
+static int __init readwrite(char *str)
+{
+ if (*str)
+ return 0;
+ root_mountflags &= ~MS_RDONLY;
+ return 1;
+}
+
+__setup("ro", readonly);
+__setup("rw", readwrite);
+
+static struct dev_name_struct {
+ const char *name;
+ const int num;
+} root_dev_names[] __initdata = {
+ { "nfs", 0x00ff },
+ { "hda", 0x0300 },
+ { "hdb", 0x0340 },
+ { "loop", 0x0700 },
+ { "hdc", 0x1600 },
+ { "hdd", 0x1640 },
+ { "hde", 0x2100 },
+ { "hdf", 0x2140 },
+ { "hdg", 0x2200 },
+ { "hdh", 0x2240 },
+ { "hdi", 0x3800 },
+ { "hdj", 0x3840 },
+ { "hdk", 0x3900 },
+ { "hdl", 0x3940 },
+ { "hdm", 0x5800 },
+ { "hdn", 0x5840 },
+ { "hdo", 0x5900 },
+ { "hdp", 0x5940 },
+ { "hdq", 0x5A00 },
+ { "hdr", 0x5A40 },
+ { "hds", 0x5B00 },
+ { "hdt", 0x5B40 },
+ { "sda", 0x0800 },
+ { "sdb", 0x0810 },
+ { "sdc", 0x0820 },
+ { "sdd", 0x0830 },
+ { "sde", 0x0840 },
+ { "sdf", 0x0850 },
+ { "sdg", 0x0860 },
+ { "sdh", 0x0870 },
+ { "sdi", 0x0880 },
+ { "sdj", 0x0890 },
+ { "sdk", 0x08a0 },
+ { "sdl", 0x08b0 },
+ { "sdm", 0x08c0 },
+ { "sdn", 0x08d0 },
+ { "sdo", 0x08e0 },
+ { "sdp", 0x08f0 },
+ { "ada", 0x1c00 },
+ { "adb", 0x1c10 },
+ { "adc", 0x1c20 },
+ { "add", 0x1c30 },
+ { "ade", 0x1c40 },
+ { "fd", 0x0200 },
+ { "md", 0x0900 },
+ { "xda", 0x0d00 },
+ { "xdb", 0x0d40 },
+ { "ram", 0x0100 },
+ { "scd", 0x0b00 },
+ { "mcd", 0x1700 },
+ { "cdu535", 0x1800 },
+ { "sonycd", 0x1800 },
+ { "aztcd", 0x1d00 },
+ { "cm206cd", 0x2000 },
+ { "gscd", 0x1000 },
+ { "sbpcd", 0x1900 },
+ { "eda", 0x2400 },
+ { "edb", 0x2440 },
+ { "pda", 0x2d00 },
+ { "pdb", 0x2d10 },
+ { "pdc", 0x2d20 },
+ { "pdd", 0x2d30 },
+ { "pcd", 0x2e00 },
+ { "pf", 0x2f00 },
+ { "apblock", APBLOCK_MAJOR << 8},
+ { "ddv", DDV_MAJOR << 8},
+ { "jsfd", JSFD_MAJOR << 8},
+#if defined(CONFIG_ARCH_S390)
+ { "dasda", (DASD_MAJOR << MINORBITS) },
+ { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
+ { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
+ { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
+ { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
+ { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
+ { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
+ { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
+#endif
+#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
+ { "ida/c0d0p",0x4800 },
+ { "ida/c0d1p",0x4810 },
+ { "ida/c0d2p",0x4820 },
+ { "ida/c0d3p",0x4830 },
+ { "ida/c0d4p",0x4840 },
+ { "ida/c0d5p",0x4850 },
+ { "ida/c0d6p",0x4860 },
+ { "ida/c0d7p",0x4870 },
+ { "ida/c0d8p",0x4880 },
+ { "ida/c0d9p",0x4890 },
+ { "ida/c0d10p",0x48A0 },
+ { "ida/c0d11p",0x48B0 },
+ { "ida/c0d12p",0x48C0 },
+ { "ida/c0d13p",0x48D0 },
+ { "ida/c0d14p",0x48E0 },
+ { "ida/c0d15p",0x48F0 },
+#endif
+#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
+ { "cciss/c0d0p",0x6800 },
+ { "cciss/c0d1p",0x6810 },
+ { "cciss/c0d2p",0x6820 },
+ { "cciss/c0d3p",0x6830 },
+ { "cciss/c0d4p",0x6840 },
+ { "cciss/c0d5p",0x6850 },
+ { "cciss/c0d6p",0x6860 },
+ { "cciss/c0d7p",0x6870 },
+ { "cciss/c0d8p",0x6880 },
+ { "cciss/c0d9p",0x6890 },
+ { "cciss/c0d10p",0x68A0 },
+ { "cciss/c0d11p",0x68B0 },
+ { "cciss/c0d12p",0x68C0 },
+ { "cciss/c0d13p",0x68D0 },
+ { "cciss/c0d14p",0x68E0 },
+ { "cciss/c0d15p",0x68F0 },
+#endif
+ { "nftla", 0x5d00 },
+ { "nftlb", 0x5d10 },
+ { "nftlc", 0x5d20 },
+ { "nftld", 0x5d30 },
+ { "ftla", 0x2c00 },
+ { "ftlb", 0x2c08 },
+ { "ftlc", 0x2c10 },
+ { "ftld", 0x2c18 },
+ { "mtdblock", 0x1f00 },
+ { NULL, 0 }
+};
+
+kdev_t __init name_to_kdev_t(char *line)
+{
+ int base = 0;
+
+ if (strncmp(line,"/dev/",5) == 0) {
+ struct dev_name_struct *dev = root_dev_names;
+ line += 5;
+ do {
+ int len = strlen(dev->name);
+ if (strncmp(line,dev->name,len) == 0) {
+ line += len;
+ base = dev->num;
+ break;
+ }
+ dev++;
+ } while (dev->name);
+ }
+ return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+}
+
+static int __init root_dev_setup(char *line)
+{
+ int i;
+ char ch;
+
+ ROOT_DEV = name_to_kdev_t(line);
+ memset (root_device_name, 0, sizeof root_device_name);
+ if (strncmp (line, "/dev/", 5) == 0) line += 5;
+ for (i = 0; i < sizeof root_device_name - 1; ++i)
+ {
+ ch = line[i];
+ if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
+ root_device_name[i] = ch;
+ }
+ return 1;
+}
+
+__setup("root=", root_dev_setup);
+
+static char * __initdata root_mount_data;
+static int __init root_data_setup(char *str)
+{
+ root_mount_data = str;
+ return 1;
+}
+
+static char * __initdata root_fs_names;
+static int __init fs_names_setup(char *str)
+{
+ root_fs_names = str;
+ return 1;
+}
+
+__setup("rootflags=", root_data_setup);
+__setup("rootfstype=", fs_names_setup);
+
+static void __init get_fs_names(char *page)
+{
+ char *s = page;
+
+ if (root_fs_names) {
+ strcpy(page, root_fs_names);
+ while (*s++) {
+ if (s[-1] == ',')
+ s[-1] = '\0';
+ }
+ } else {
+ int len = get_filesystem_list(page);
+ char *p, *next;
+
+ page[len] = '\0';
+ for (p = page-1; p; p = next) {
+ next = strchr(++p, '\n');
+ if (*p++ != '\t')
+ continue;
+ while ((*s++ = *p++) != '\n')
+ ;
+ s[-1] = '\0';
+ }
+ }
+ *s = '\0';
+}
+
+static void __init mount_root(void)
+{
+ void *handle;
+ char path[64];
+ char *name = "/dev/root";
+ char *fs_names, *p;
+ int err;
+ int do_devfs = 0;
+#ifdef CONFIG_ROOT_NFS
+ void *data;
+#endif
+ root_mountflags |= MS_VERBOSE;
+
+ fs_names = __getname();
+ get_fs_names(fs_names);
+
+#ifdef CONFIG_ROOT_NFS
+ if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
+ goto skip_nfs;
+ data = nfs_root_data();
+ if (!data)
+ goto no_nfs;
+ err = mount("/dev/root", "/root", "nfs", root_mountflags, data);
+ if (!err)
+ goto done;
+no_nfs:
+ printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
+ ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
+skip_nfs:
+#endif
+
+#ifdef CONFIG_BLK_DEV_FD
+ if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
+#ifdef CONFIG_BLK_DEV_RAM
+ extern int rd_doload;
+ extern void rd_load_secondary(void);
+#endif
+ floppy_eject();
+#ifndef CONFIG_BLK_DEV_RAM
+ printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
+#else
+ /* rd_doload is 2 for a dual initrd/ramload setup */
+ if(rd_doload==2)
+ rd_load_secondary();
+ else
+#endif
+ {
+ printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
+ wait_for_keypress();
+ }
+ }
+#endif
+
+ devfs_make_root (root_device_name);
+ handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
+ MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
+ DEVFS_SPECIAL_BLK, 1);
+ if (handle) {
+ int n;
+ unsigned major, minor;
+
+ devfs_get_maj_min (handle, &major, &minor);
+ ROOT_DEV = MKDEV (major, minor);
+ if (!ROOT_DEV)
+ panic("I have no root and I want to scream");
+ n = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
+ if (n >= 0) {
+ name = path + n;
+ devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
+ name + 5, NULL, NULL);
+ memcpy (name, "/dev/", 5);
+ do_devfs = 1;
+ }
+ }
+ chdir("/dev");
+ unlink("root");
+ mknod("root", S_IFBLK|0600, kdev_t_to_nr(ROOT_DEV));
+ if (do_devfs)
+ mount("devfs", ".", "devfs", 0, NULL);
+retry:
+ for (p = fs_names; *p; p += strlen(p)+1) {
+ int err;
+ err = sys_mount(name,"/root",p,root_mountflags,root_mount_data);
+ switch (err) {
+ case 0:
+ goto done;
+ case -EACCES:
+ root_mountflags |= MS_RDONLY;
+ goto retry;
+ case -EINVAL:
+ continue;
+ }
+ /*
+ * Allow the user to distinguish between failed open
+ * and bad superblock on root device.
+ */
+ printk ("VFS: Cannot open root device \"%s\" or %s\n",
+ root_device_name, kdevname (ROOT_DEV));
+ printk ("Please append a correct \"root=\" boot option\n");
+ panic("VFS: Unable to mount root fs on %s",
+ kdevname(ROOT_DEV));
+ }
+ panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+
+done:
+ putname(fs_names);
+ if (do_devfs)
+ umount(".", 0);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int __init change_root(kdev_t new_root_dev,const char *put_old)
+{
+ struct vfsmount *old_rootmnt;
+ struct nameidata devfs_nd;
+ char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
+ int error = 0;
+
+ if (new_devname)
+ strcpy(new_devname, "/dev/root.old");
+
+ /* .. here is directory mounted over root */
+ mount("..", ".", NULL, MS_MOVE, NULL);
+ chdir("/old");
+
+ read_lock(&current->fs->lock);
+ old_rootmnt = mntget(current->fs->pwdmnt);
+ read_unlock(&current->fs->lock);
+
+ /* First unmount devfs if mounted */
+ if (path_init("/old/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
+ error = path_walk("/old/dev", &devfs_nd);
+ if (!error) {
+ if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
+ devfs_nd.dentry == devfs_nd.mnt->mnt_root)
+ umount("/old/dev", 0);
+ path_release(&devfs_nd);
+ }
+
+ ROOT_DEV = new_root_dev;
+ mount_root();
+
+ chdir("/root");
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+ printk("VFS: Mounted root (%s filesystem)%s.\n",
+ current->fs->pwdmnt->mnt_sb->s_type->name,
+ (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+
+#if 1
+ shrink_dcache();
+ printk("change_root: old root has d_count=%d\n",
+ atomic_read(&old_rootmnt->mnt_root->d_count));
+#endif
+
+ error = mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+ if (error) {
+ int blivet;
+ struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
+
+ atomic_inc(&ramdisk->bd_count);
+ blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
+ printk(KERN_NOTICE "Trying to unmount old root ... ");
+ umount("/old", MNT_DETACH);
+ if (!blivet) {
+ blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
+ blkdev_put(ramdisk, BDEV_FS);
+ }
+ if (blivet) {
+ printk(KERN_ERR "error %d\n", blivet);
+ } else {
+ printk("okay\n");
+ error = 0;
+ }
+ } else {
+ spin_lock(&dcache_lock);
+ if (new_devname) {
+ void *p = old_rootmnt->mnt_devname;
+ old_rootmnt->mnt_devname = new_devname;
+ new_devname = p;
+ }
+ spin_unlock(&dcache_lock);
+ }
+
+ /* put the old stuff */
+ mntput(old_rootmnt);
+ kfree(new_devname);
+ return error;
+}
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int do_linuxrc(void * shell)
+{
+ static char *argv[] = { "linuxrc", NULL, };
+ extern char * envp_init[];
+
+ chdir("/root");
+ mount(".", "/", NULL, MS_MOVE, NULL);
+ chroot(".");
+
+ mount_devfs_fs ();
+
+ close(0);close(1);close(2);
+ setsid();
+ (void) open("/dev/console",O_RDWR,0);
+ (void) dup(0);
+ (void) dup(0);
+ return execve(shell, argv, envp_init);
+}
+
+#endif
+
+/*
+ * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
+ */
+void prepare_namespace(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ int real_root_mountflags = root_mountflags;
+ if (!initrd_start)
+ mount_initrd = 0;
+ if (mount_initrd)
+ root_mountflags &= ~MS_RDONLY;
+ real_root_dev = ROOT_DEV;
+#endif
+ mkdir("/dev", 0700);
+ mkdir("/root", 0700);
+
+#ifdef CONFIG_BLK_DEV_RAM
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (mount_initrd)
+ initrd_load();
+ else
+#endif
+ rd_load();
+#endif
+
+ /* Mount the root filesystem.. */
+ mount_root();
+ chdir("/root");
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+ printk("VFS: Mounted root (%s filesystem)%s.\n",
+ current->fs->pwdmnt->mnt_sb->s_type->name,
+ (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ root_mountflags = real_root_mountflags;
+ if (mount_initrd && ROOT_DEV != real_root_dev
+ && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
+ int error;
+ int i, pid;
+ mkdir("/old", 0700);
+ chdir("/old");
+
+ pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+ if (pid > 0) {
+ while (pid != wait(&i)) {
+ current->policy |= SCHED_YIELD;
+ schedule();
+ }
+ }
+ if (MAJOR(real_root_dev) != RAMDISK_MAJOR
+ || MINOR(real_root_dev) != 0) {
+ error = change_root(real_root_dev,"/initrd");
+ if (error)
+ printk(KERN_ERR "Change root to /initrd: "
+ "error %d\n",error);
+
+ chdir("/root");
+ mount(".", "/", NULL, MS_MOVE, NULL);
+ chroot(".");
+
+ mount_devfs_fs ();
+ return;
+ }
+ chroot("..");
+ chdir("/");
+ return;
+ }
+#endif
+ mount(".", "/", NULL, MS_MOVE, NULL);
+ chroot(".");
+
+ mount_devfs_fs ();
+}
diff --git a/init/main.c b/init/main.c
index 8a1e43209..c7e9d0faa 100644
--- a/init/main.c
+++ b/init/main.c
@@ -31,6 +31,8 @@
#include <asm/io.h>
#include <asm/bugs.h>
+#include <linux/device.h>
+
#if defined(CONFIG_ARCH_S390)
#include <asm/s390mach.h>
#include <asm/ccwcache.h>
@@ -118,17 +120,10 @@ extern void softirq_init(void);
int rows, cols;
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
-#endif
-
-int root_mountflags = MS_RDONLY;
char *execute_command;
-char root_device_name[64];
-
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static int __init profile_setup(char *str)
{
@@ -139,175 +134,6 @@ static int __init profile_setup(char *str)
__setup("profile=", profile_setup);
-
-static struct dev_name_struct {
- const char *name;
- const int num;
-} root_dev_names[] __initdata = {
- { "nfs", 0x00ff },
- { "hda", 0x0300 },
- { "hdb", 0x0340 },
- { "loop", 0x0700 },
- { "hdc", 0x1600 },
- { "hdd", 0x1640 },
- { "hde", 0x2100 },
- { "hdf", 0x2140 },
- { "hdg", 0x2200 },
- { "hdh", 0x2240 },
- { "hdi", 0x3800 },
- { "hdj", 0x3840 },
- { "hdk", 0x3900 },
- { "hdl", 0x3940 },
- { "hdm", 0x5800 },
- { "hdn", 0x5840 },
- { "hdo", 0x5900 },
- { "hdp", 0x5940 },
- { "hdq", 0x5A00 },
- { "hdr", 0x5A40 },
- { "hds", 0x5B00 },
- { "hdt", 0x5B40 },
- { "sda", 0x0800 },
- { "sdb", 0x0810 },
- { "sdc", 0x0820 },
- { "sdd", 0x0830 },
- { "sde", 0x0840 },
- { "sdf", 0x0850 },
- { "sdg", 0x0860 },
- { "sdh", 0x0870 },
- { "sdi", 0x0880 },
- { "sdj", 0x0890 },
- { "sdk", 0x08a0 },
- { "sdl", 0x08b0 },
- { "sdm", 0x08c0 },
- { "sdn", 0x08d0 },
- { "sdo", 0x08e0 },
- { "sdp", 0x08f0 },
- { "ada", 0x1c00 },
- { "adb", 0x1c10 },
- { "adc", 0x1c20 },
- { "add", 0x1c30 },
- { "ade", 0x1c40 },
- { "fd", 0x0200 },
- { "md", 0x0900 },
- { "xda", 0x0d00 },
- { "xdb", 0x0d40 },
- { "ram", 0x0100 },
- { "scd", 0x0b00 },
- { "mcd", 0x1700 },
- { "cdu535", 0x1800 },
- { "sonycd", 0x1800 },
- { "aztcd", 0x1d00 },
- { "cm206cd", 0x2000 },
- { "gscd", 0x1000 },
- { "sbpcd", 0x1900 },
- { "eda", 0x2400 },
- { "edb", 0x2440 },
- { "pda", 0x2d00 },
- { "pdb", 0x2d10 },
- { "pdc", 0x2d20 },
- { "pdd", 0x2d30 },
- { "pcd", 0x2e00 },
- { "pf", 0x2f00 },
- { "apblock", APBLOCK_MAJOR << 8},
- { "ddv", DDV_MAJOR << 8},
- { "jsfd", JSFD_MAJOR << 8},
-#if defined(CONFIG_ARCH_S390)
- { "dasda", (DASD_MAJOR << MINORBITS) },
- { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
- { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
- { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
- { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
- { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
- { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
- { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
-#endif
-#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
- { "ida/c0d0p",0x4800 },
- { "ida/c0d1p",0x4810 },
- { "ida/c0d2p",0x4820 },
- { "ida/c0d3p",0x4830 },
- { "ida/c0d4p",0x4840 },
- { "ida/c0d5p",0x4850 },
- { "ida/c0d6p",0x4860 },
- { "ida/c0d7p",0x4870 },
- { "ida/c0d8p",0x4880 },
- { "ida/c0d9p",0x4890 },
- { "ida/c0d10p",0x48A0 },
- { "ida/c0d11p",0x48B0 },
- { "ida/c0d12p",0x48C0 },
- { "ida/c0d13p",0x48D0 },
- { "ida/c0d14p",0x48E0 },
- { "ida/c0d15p",0x48F0 },
-#endif
-#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
- { "cciss/c0d0p",0x6800 },
- { "cciss/c0d1p",0x6810 },
- { "cciss/c0d2p",0x6820 },
- { "cciss/c0d3p",0x6830 },
- { "cciss/c0d4p",0x6840 },
- { "cciss/c0d5p",0x6850 },
- { "cciss/c0d6p",0x6860 },
- { "cciss/c0d7p",0x6870 },
- { "cciss/c0d8p",0x6880 },
- { "cciss/c0d9p",0x6890 },
- { "cciss/c0d10p",0x68A0 },
- { "cciss/c0d11p",0x68B0 },
- { "cciss/c0d12p",0x68C0 },
- { "cciss/c0d13p",0x68D0 },
- { "cciss/c0d14p",0x68E0 },
- { "cciss/c0d15p",0x68F0 },
-#endif
- { "nftla", 0x5d00 },
- { "nftlb", 0x5d10 },
- { "nftlc", 0x5d20 },
- { "nftld", 0x5d30 },
- { "ftla", 0x2c00 },
- { "ftlb", 0x2c08 },
- { "ftlc", 0x2c10 },
- { "ftld", 0x2c18 },
- { "mtdblock", 0x1f00 },
- { NULL, 0 }
-};
-
-kdev_t __init name_to_kdev_t(char *line)
-{
- int base = 0;
-
- if (strncmp(line,"/dev/",5) == 0) {
- struct dev_name_struct *dev = root_dev_names;
- line += 5;
- do {
- int len = strlen(dev->name);
- if (strncmp(line,dev->name,len) == 0) {
- line += len;
- base = dev->num;
- break;
- }
- dev++;
- } while (dev->name);
- }
- return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
-}
-
-static int __init root_dev_setup(char *line)
-{
- int i;
- char ch;
-
- ROOT_DEV = name_to_kdev_t(line);
- memset (root_device_name, 0, sizeof root_device_name);
- if (strncmp (line, "/dev/", 5) == 0) line += 5;
- for (i = 0; i < sizeof root_device_name - 1; ++i)
- {
- ch = line[i];
- if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
- root_device_name[i] = ch;
- }
- return 1;
-}
-
-__setup("root=", root_dev_setup);
-
static int __init checksetup(char *line)
{
struct kernel_param *p;
@@ -374,22 +200,6 @@ void __init calibrate_delay(void)
(loops_per_jiffy/(5000/HZ)) % 100);
}
-static int __init readonly(char *str)
-{
- if (*str)
- return 0;
- root_mountflags |= MS_RDONLY;
- return 1;
-}
-
-static int __init readwrite(char *str)
-{
- if (*str)
- return 0;
- root_mountflags &= ~MS_RDONLY;
- return 1;
-}
-
static int __init debug_kernel(char *str)
{
if (*str)
@@ -406,8 +216,6 @@ static int __init quiet_kernel(char *str)
return 1;
}
-__setup("ro", readonly);
-__setup("rw", readwrite);
__setup("debug", debug_kernel);
__setup("quiet", quiet_kernel);
@@ -622,21 +430,6 @@ asmlinkage void __init start_kernel(void)
rest_init();
}
-#ifdef CONFIG_BLK_DEV_INITRD
-static int do_linuxrc(void * shell)
-{
- static char *argv[] = { "linuxrc", NULL, };
-
- close(0);close(1);close(2);
- setsid();
- (void) open("/dev/console",O_RDWR,0);
- (void) dup(0);
- (void) dup(0);
- return execve(shell, argv, envp_init);
-}
-
-#endif
-
struct task_struct *child_reaper = &init_task;
static void __init do_initcalls(void)
@@ -694,6 +487,9 @@ static void __init do_basic_setup(void)
s390_init_machine_check();
#endif
+ /* bring up the device tree */
+ device_driver_init();
+
#ifdef CONFIG_PCI
pci_init();
#endif
@@ -740,61 +536,7 @@ static void __init do_basic_setup(void)
#endif
}
-extern void rd_load(void);
-extern void initrd_load(void);
-
-/*
- * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
- */
-static void prepare_namespace(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- int real_root_mountflags = root_mountflags;
- if (!initrd_start)
- mount_initrd = 0;
- if (mount_initrd)
- root_mountflags &= ~MS_RDONLY;
- real_root_dev = ROOT_DEV;
-#endif
-
-#ifdef CONFIG_BLK_DEV_RAM
-#ifdef CONFIG_BLK_DEV_INITRD
- if (mount_initrd)
- initrd_load();
- else
-#endif
- rd_load();
-#endif
-
- /* Mount the root filesystem.. */
- mount_root();
-
- mount_devfs_fs ();
-
-#ifdef CONFIG_BLK_DEV_INITRD
- root_mountflags = real_root_mountflags;
- if (mount_initrd && ROOT_DEV != real_root_dev
- && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
- int error;
- int i, pid;
-
- pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
- if (pid > 0) {
- while (pid != wait(&i)) {
- current->policy |= SCHED_YIELD;
- schedule();
- }
- }
- if (MAJOR(real_root_dev) != RAMDISK_MAJOR
- || MINOR(real_root_dev) != 0) {
- error = change_root(real_root_dev,"/initrd");
- if (error)
- printk(KERN_ERR "Change root to /initrd: "
- "error %d\n",error);
- }
- }
-#endif
-}
+extern void prepare_namespace(void);
static int init(void * unused)
{
diff --git a/ipc/shm.c b/ipc/shm.c
index fb2ba9d0b..25b3ae86e 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -569,6 +569,7 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
{
struct shmid_kernel *shp;
unsigned long addr;
+ unsigned long size;
struct file * file;
int err;
unsigned long flags;
@@ -588,8 +589,12 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
return -EINVAL;
}
flags = MAP_SHARED | MAP_FIXED;
- } else
+ } else {
+ if ((shmflg & SHM_REMAP))
+ return -EINVAL;
+
flags = MAP_SHARED;
+ }
if (shmflg & SHM_RDONLY) {
prot = PROT_READ;
@@ -603,7 +608,7 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
/*
* We cannot rely on the fs check since SYSV IPC does have an
- * aditional creator id...
+ * additional creator id...
*/
shp = shm_lock(shmid);
if(shp == NULL)
@@ -618,11 +623,27 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
return -EACCES;
}
file = shp->shm_file;
+ size = file->f_dentry->d_inode->i_size;
shp->shm_nattch++;
shm_unlock(shmid);
down_write(&current->mm->mmap_sem);
- user_addr = (void *) do_mmap (file, addr, file->f_dentry->d_inode->i_size, prot, flags, 0);
+ if (addr && !(shmflg & SHM_REMAP)) {
+ user_addr = ERR_PTR(-EINVAL);
+ if (find_vma_intersection(current->mm, addr, addr + size))
+ goto invalid;
+ /*
+ * If shm segment goes below stack, make sure there is some
+ * space left for the stack to grow (at least 4 pages).
+ */
+ if (addr < current->mm->start_stack &&
+ addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+ goto invalid;
+ }
+
+ user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+
+invalid:
up_write(&current->mm->mmap_sem);
down (&shm_ids.sem);
diff --git a/kernel/Makefile b/kernel/Makefile
index 02c4d3a5c..c118fff17 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,12 +9,13 @@
O_TARGET := kernel.o
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
+ printk.o device.o
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
sysctl.o acct.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o context.o
+ signal.o sys.o kmod.o context.o device.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/kernel/device.c b/kernel/device.c
new file mode 100644
index 000000000..16fe11cf5
--- /dev/null
+++ b/kernel/device.c
@@ -0,0 +1,950 @@
+/*
+ * device.c
+ *
+ * Copyright (c) Patrick Mochel <mochel@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Please see Documentation/driver-model.txt for more explanation.
+ */
+
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/driverfs_fs.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+# define DBG(x...) printk(x)
+#else
+# define DBG(x...)
+#endif
+
+static struct iobus device_root = {
+ bus_id: "root",
+ name: "Logical System Root",
+};
+
+int (*platform_notify)(struct device * dev) = NULL;
+int (*platform_notify_remove)(struct device * dev) = NULL;
+
+static spinlock_t device_lock;
+
+static ssize_t device_read_status(char *, size_t, loff_t, void *);
+static ssize_t device_write_status(const char *, size_t, loff_t, void *);
+
+static struct driverfs_operations device_status_ops = {
+ read: device_read_status,
+ write: device_write_status,
+};
+
+static ssize_t device_read_power(char *, size_t, loff_t, void *);
+static ssize_t device_write_power(const char *, size_t, loff_t, void *);
+
+static struct driverfs_operations device_power_ops = {
+ read: device_read_power,
+ write: device_write_power,
+};
+
+static ssize_t iobus_read_status(char *, size_t, loff_t, void *);
+static ssize_t iobus_write_status(const char *, size_t, loff_t, void *);
+
+static struct driverfs_operations iobus_status_ops = {
+ read: iobus_read_status,
+ write: iobus_write_status,
+};
+
+
+/**
+ * device_create_file - create a driverfs file for a device
+ * @dev: device requesting file
+ * @name: name of file
+ * @mode: permissions of file
+ * @ops: operations for the file
+ * @data: private data for the file
+ *
+ * Create a driverfs entry, then create the actual file the entry describes.
+ */
+int device_create_file(struct device * dev, const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data)
+{
+ int error = -EFAULT;
+ struct driver_file_entry * entry;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (!valid_device(dev))
+ return -EFAULT;
+
+ entry = driverfs_create_entry(name,mode,ops,data);
+ if (entry)
+ error = driverfs_create_file(entry,dev->dir);
+
+ put_device(dev);
+ return error;
+}
+
+/**
+ * device_remove_file - remove a device's file by name
+ * @dev: device requesting removal
+ * @name: name of the file
+ *
+ */
+void device_remove_file(struct device * dev, const char * name)
+{
+ if (!dev)
+ return;
+
+ if (!valid_device(dev))
+ return;
+
+ driverfs_remove_file(dev->dir,name);
+
+ put_device(dev);
+}
+
+/**
+ * device_remove_dir - remove a device's directory
+ * @dev: device in question
+ */
+void device_remove_dir(struct device * dev)
+{
+ struct driver_dir_entry * dir;
+
+ if (!dev)
+ return;
+
+ lock_device(dev);
+ dir = dev->dir;
+ dev->dir = NULL;
+ unlock_device(dev);
+
+ if (dir)
+ driverfs_remove_dir(dir);
+}
+
+/**
+ * device_make_dir - create a driverfs directory
+ * @name: name of directory
+ * @parent: dentry for the parent directory
+ *
+ * Do the initial creation of the device's driverfs directory
+ * and populate it with the one default file.
+ *
+ * This is just a helper for device_register(), as we
+ * don't export this function. (Yes, that means we don't allow
+ * devices to create subdirectories).
+ */
+static int device_make_dir(struct device * dev)
+{
+ struct driver_dir_entry * entry;
+ int error;
+
+ entry = driverfs_create_dir_entry(dev->bus_id,(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO));
+ if (!entry)
+ return -EFAULT;
+
+ error = driverfs_create_dir(entry,dev->parent->dir);
+
+ if (error) {
+ kfree(entry);
+ return error;
+ }
+
+ lock_device(dev);
+ dev->dir = entry;
+ unlock_device(dev);
+
+ /* first the status file */
+ error = device_create_file(dev, "status", S_IRUGO | S_IWUSR,
+ &device_status_ops, (void *) dev);
+ if (error) {
+ device_remove_dir(dev);
+ goto done;
+ }
+
+ /* now the power file */
+ error = device_create_file(dev,"power",S_IRUGO | S_IWUSR,
+ &device_power_ops, (void *) dev);
+ if (error)
+ device_remove_dir(dev);
+
+ done:
+ return error;
+}
+
+/* iobus interface.
+ * For practical purposes, it's exactly the same as the device interface above.
+ * Even below, the two are almost identical, only taking different pointer
+ * types.
+ * I have fantasized about removing struct iobus completely. It would reduce
+ * this file by about 30%, and make life much easier. However, it will take some
+ * time to really work everything out..
+ */
+
+int iobus_create_file(struct iobus * iobus, const char * name, mode_t mode,
+ struct driverfs_operations * ops, void * data)
+{
+ int error = -EFAULT;
+ struct driver_file_entry * entry;
+
+ if (!iobus)
+ return -EINVAL;
+
+ if (!valid_iobus(iobus))
+ return -EFAULT;
+
+ entry = driverfs_create_entry(name,mode,ops,data);
+ if (entry)
+ error = driverfs_create_file(entry,iobus->dir);
+
+ put_iobus(iobus);
+ return error;
+}
+
+void iobus_remove_file(struct iobus * iobus, const char * name)
+{
+ if (!iobus)
+ return;
+
+ if (!valid_iobus(iobus))
+ return;
+
+ driverfs_remove_file(iobus->dir,name);
+
+ put_iobus(iobus);
+}
+
+void iobus_remove_dir(struct iobus * iobus)
+{
+ struct driver_dir_entry * dir;
+
+ if (!iobus)
+ return;
+
+ lock_iobus(iobus);
+ dir = iobus->dir;
+ iobus->dir = NULL;
+ unlock_iobus(iobus);
+
+ if (dir)
+ driverfs_remove_dir(dir);
+}
+
+static int iobus_make_dir(struct iobus * iobus)
+{
+ struct driver_dir_entry * entry;
+ struct driver_dir_entry * parent = NULL;
+ int error;
+
+ entry = driverfs_create_dir_entry(iobus->bus_id,(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO));
+ if (!entry)
+ return -EFAULT;
+
+ if (iobus->parent)
+ parent = iobus->parent->dir;
+
+ error = driverfs_create_dir(entry,parent);
+ if (error) {
+ kfree(entry);
+ return error;
+ }
+
+ lock_iobus(iobus);
+ iobus->dir = entry;
+ unlock_iobus(iobus);
+
+ error = iobus_create_file(iobus, "status", S_IRUGO | S_IWUSR,
+ &iobus_status_ops, (void *)iobus);
+ if (error)
+ iobus_remove_dir(iobus);
+
+ return error;
+}
+
+/**
+ * device_register - register a device
+ * @dev: pointer to the device structure
+ *
+ * First, make sure that the device has a parent, create
+ * a directory for it, then add it to the parent's list of
+ * children.
+ */
+int device_register(struct device *dev)
+{
+ struct iobus * parent;
+ int error = -EFAULT;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (!dev->parent)
+ dev->parent = &device_root;
+ parent = dev->parent;
+
+ if (valid_iobus(parent)) {
+ if (!valid_device(dev)) {
+ put_iobus(parent);
+ goto register_done;
+ }
+ } else
+ return -EFAULT;
+
+ if (!strlen(dev->name)) {
+ error = -EINVAL;
+ goto register_done;
+ }
+
+ error = device_make_dir(dev);
+ if (error)
+ goto register_done;
+
+
+ /* finally add it to its parent's list */
+ lock_iobus(parent);
+ list_add_tail(&dev->node, &parent->devices);
+ unlock_iobus(parent);
+
+ DBG("DEV: registering device: ID = '%s', name = %s, parent = %s\n",
+ dev->bus_id, dev->name, parent->bus_id);
+
+ /* notify platform of device entry */
+ if (platform_notify)
+ platform_notify(dev);
+
+ return 0;
+
+ register_done:
+ put_device(dev);
+ put_iobus(parent);
+
+ return error;
+}
+
+/**
+ * put_device - clean up device
+ * @dev: device in question
+ *
+ * Decrement reference count for device.
+ * If it hits 0, we need to clean it up.
+ * However, we may be here in interrupt context, and it may
+ * take some time to do proper clean up (removing files, calling
+ * back down to device to clean up everything it has).
+ * So, we remove it from its parent's list and add it to the list of
+ * devices to be cleaned up.
+ */
+void put_device(struct device * dev)
+{
+ struct iobus * parent;
+
+ if (!atomic_dec_and_lock(&dev->refcount,&dev->lock))
+ return;
+
+ parent = dev->parent;
+ dev->parent = NULL;
+ unlock_device(dev);
+
+ DBG("DEV: Unregistering device. ID = '%s', name = '%s'\n",
+ dev->bus_id,dev->name);
+
+ /* disavow parent's knowledge */
+ lock_iobus(parent);
+ list_del_init(&dev->node);
+ unlock_iobus(parent);
+
+ /* remove the driverfs directory */
+ device_remove_dir(dev);
+
+ if (dev->subordinate)
+ iobus_remove_dir(dev->subordinate);
+
+ /* Notify the platform of the removal, in case they
+ * need to do anything...
+ */
+ if (platform_notify_remove)
+ platform_notify_remove(dev);
+
+ /* Tell the driver to clean up after itself.
+ * Note that we likely didn't allocate the device,
+ * so this is the driver's chance to free that up...
+ */
+ if (dev->driver && dev->driver->remove)
+ dev->driver->remove(dev,REMOVE_FREE_RESOURCES);
+
+ put_iobus(parent);
+}
+
+int iobus_register(struct iobus *bus)
+{
+ struct iobus * parent;
+ int error = -EINVAL;
+
+ if (!bus)
+ return -EINVAL;
+
+ if (!bus->parent)
+ bus->parent = &device_root;
+ parent = bus->parent;
+
+ DBG("DEV: registering bus. ID = '%s' name = '%s' parent = %p\n",
+ bus->bus_id,bus->name,bus->parent);
+
+ if (valid_iobus(parent)) {
+ if (!valid_iobus(bus)) {
+ put_iobus(parent);
+ goto register_done;
+ }
+ } else
+ goto register_done;
+
+ if (!strlen(bus->bus_id))
+ goto register_done_put;
+
+ error = iobus_make_dir(bus);
+ if (error)
+ goto register_done_put;
+
+ lock_iobus(parent);
+ list_add_tail(&bus->node,&parent->children);
+ unlock_iobus(parent);
+
+ return 0;
+
+ register_done_put:
+ put_iobus(bus);
+ put_iobus(parent);
+ register_done:
+ return error;
+}
+
+/**
+ * iobus_unregister - remove bus and children from device tree
+ * @bus: pointer to bus structure
+ *
+ * Remove device from parent's list of children and decrement
+ * reference count on controlling device. That should take care of
+ * the rest of the cleanup.
+ */
+void put_iobus(struct iobus * iobus)
+{
+ struct iobus * parent;
+
+ if (!atomic_dec_and_lock(&iobus->refcount,&iobus->lock))
+ return;
+
+ parent = iobus->parent;
+ iobus->parent = NULL;
+ unlock_iobus(iobus);
+
+ if (!list_empty(&iobus->devices) ||
+ !list_empty(&iobus->children))
+ BUG();
+
+ /* disavow parent's knowledge */
+ if (parent) {
+ lock_iobus(parent);
+ list_del(&iobus->node);
+ unlock_iobus(parent);
+
+ put_iobus(parent);
+ }
+
+ /* unregister itself */
+ put_device(iobus->self);
+
+ return;
+}
+
+/**
+ * device_init_dev - initialise a struct device
+ * @dev: pointer to device struct
+ */
+void device_init_dev(struct device * dev)
+{
+ INIT_LIST_HEAD(&dev->node);
+ spin_lock_init(&dev->lock);
+ atomic_set(&dev->refcount,1);
+}
+
+/**
+ * device_alloc_dev - allocate and initialise a device structure
+ *
+ */
+struct device * device_alloc(void)
+{
+ struct device * dev;
+
+ dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+
+ if (!dev)
+ return NULL;
+
+ memset(dev,0,sizeof(struct device));
+ device_init_dev(dev);
+
+ return dev;
+}
+
+void iobus_init(struct iobus *bus)
+{
+ spin_lock_init(&bus->lock);
+ atomic_set(&bus->refcount,1);
+
+ INIT_LIST_HEAD(&bus->node);
+ INIT_LIST_HEAD(&bus->children);
+ INIT_LIST_HEAD(&bus->devices);
+}
+
+struct iobus *iobus_alloc(void)
+{
+ struct iobus *bus;
+
+ bus = kmalloc(sizeof(struct iobus), GFP_KERNEL);
+
+ if (!bus)
+ return NULL;
+
+ memset(bus,0,sizeof(struct iobus));
+
+ iobus_init(bus);
+
+ return bus;
+}
+
+static int do_device_suspend(struct device * dev, u32 state)
+{
+ int error = 0;
+
+ if (!dev->driver->suspend)
+ return error;
+
+ error = dev->driver->suspend(dev,state,SUSPEND_NOTIFY);
+
+ if (error)
+ return error;
+
+ error = dev->driver->suspend(dev,state,SUSPEND_SAVE_STATE);
+ if (error) {
+ if (dev->driver->resume)
+ dev->driver->resume(dev,RESUME_RESTORE_STATE);
+ return error;
+ }
+ error = dev->driver->suspend(dev,state,SUSPEND_POWER_DOWN);
+ if (error) {
+ if (dev->driver->resume)
+ dev->driver->resume(dev,RESUME_RESTORE_STATE);
+ }
+ return error;
+}
+
+static int do_device_resume(struct device * dev)
+{
+ int error = 0;
+
+ if (!dev->driver->resume)
+ return 0;
+ error = dev->driver->resume(dev,RESUME_POWER_ON);
+ if (error)
+ return error;
+ error = dev->driver->resume(dev,RESUME_RESTORE_STATE);
+ return error;
+}
+
+/**
+ * device_read_status - report some device information
+ * @page: page-sized buffer to write into
+ * @count: number of bytes requested
+ * @off: offset into buffer
+ * @data: device-specific data
+ *
+ * Report some human-readable information about the device.
+ * This includes the name, the bus id, and the current power state.
+ */
+static ssize_t device_read_status(char * page, size_t count,
+ loff_t off, void * data)
+{
+ char *str = page;
+ struct device *dev = (struct device*)data;
+ ssize_t len = 0;
+
+ if (!dev)
+ return -EINVAL;
+
+ if (!valid_device(dev))
+ return -EFAULT;
+
+ if (off)
+ goto done;
+
+ str += sprintf(str,"Name: %s\n",dev->name);
+ str += sprintf(str,"Bus ID: %s\n",dev->bus_id);
+
+ len = str - page;
+
+ if (len > count)
+ len = count;
+
+ if (len < 0)
+ len = 0;
+
+ done:
+ put_device(dev);
+
+ return len;
+}
+
+/**
+ * device_write_status - forward a command to a driver
+ * @buf: encoded command
+ * @count: number of bytes in buffer
+ * @off: offset into buffer to start with
+ * @data: device-specific data
+ *
+ * Send a comamnd to a device driver.
+ * The following actions are supported:
+ * probe - scan slot for device
+ * remove - detach driver from slot
+ * suspend <state> <stage> - perform <stage> for entering <state>
+ * resume <stage> - perform <stage> for waking device up.
+ * (See Documentation/driver-model.txt for the theory of an n-stage
+ * suspend sequence).
+ */
+static ssize_t device_write_status(const char* buf, size_t count, loff_t off, void *data)
+{
+ char command[20];
+ struct device *dev = (struct device *)data;
+ int num;
+ int arg = 0;
+ int error = 0;
+
+ if (!dev)
+ return 0;
+
+ if (!valid_device(dev))
+ return -EFAULT;
+
+ if (off)
+ goto done_put;
+
+ /* everything involves dealing with the driver. */
+ if (!dev->driver)
+ goto done_put;
+
+ num = sscanf(buf,"%10s %d",command,&arg);
+
+ if (!num)
+ goto done_put;
+
+ if (!strcmp(command,"probe")) {
+ if (dev->driver->probe)
+ error = dev->driver->probe(dev);
+
+ } else if (!strcmp(command,"remove")) {
+ if (dev->driver->remove)
+ error = dev->driver->remove(dev,REMOVE_NOTIFY);
+ } else
+ error = -EFAULT;
+
+ done_put:
+ put_device(dev);
+ return error < 0 ? error : count;
+}
+
+static ssize_t
+device_read_power(char * page, size_t count, loff_t off, void * data)
+{
+ char * str = page;
+ struct device * dev = (struct device *)data;
+ ssize_t len = 0;
+
+ if (!dev)
+ return 0;
+
+ if (!valid_device(dev))
+ return 0;
+
+ str += sprintf(str,"State: %d\n",dev->current_state);
+
+ len = str - page;
+
+ if (off) {
+ if (len < off) {
+ len = 0;
+ goto done;
+ }
+ str += off;
+ len -= off;
+ }
+
+ if (len > count)
+ len = count;
+
+ done:
+ put_device(dev);
+ return len;
+}
+
+static ssize_t
+device_write_power(const char * buf, size_t count, loff_t off, void * data)
+{
+ struct device * dev = (struct device *)data;
+ char str_command[20];
+ char str_stage[20];
+ int num_args;
+ u32 state;
+ u32 int_stage;
+ int error = 0;
+
+ if (!dev)
+ return 0;
+
+ if (!valid_device(dev))
+ return -EFAULT;
+
+ if (off)
+ goto done;
+ if (!dev->driver)
+ goto done;
+
+ num_args = sscanf(buf,"%s %s %u",str_command,str_stage,&state);
+
+ error = -EINVAL;
+
+ if (!num_args) {
+ printk("have no arguments\n");
+ goto done;
+ }
+
+ if (!strnicmp(str_command,"suspend",7)) {
+
+ printk("%s: we know it's a suspend action\n",__FUNCTION__);
+
+ if (num_args != 3)
+ goto done;
+ if (!strnicmp(str_stage,"notify",6))
+ int_stage = SUSPEND_NOTIFY;
+ else if (!strnicmp(str_stage,"save",4))
+ int_stage = SUSPEND_SAVE_STATE;
+ else if (!strnicmp(str_stage,"disable",7))
+ int_stage = SUSPEND_DISABLE;
+ else if (!strnicmp(str_stage,"powerdown",8))
+ int_stage = SUSPEND_POWER_DOWN;
+ else
+ goto done;
+
+ if (dev->driver->suspend)
+ error = dev->driver->suspend(dev,state,int_stage);
+ else
+ error = 0;
+ } else if (!strnicmp(str_command,"resume",6)) {
+ if (num_args != 2)
+ goto done;
+
+ if (!strnicmp(str_stage,"poweron",7))
+ int_stage = RESUME_POWER_ON;
+ else if (!strnicmp(str_stage,"restore",7))
+ int_stage = RESUME_RESTORE_STATE;
+ else if (!strnicmp(str_stage,"enable",6))
+ int_stage = RESUME_ENABLE;
+ else
+ goto done;
+
+ if (dev->driver->resume)
+ error = dev->driver->resume(dev,int_stage);
+ else
+ error = 0;
+ } else
+ printk("%s: couldn't find any thing to do\n",__FUNCTION__);
+ done:
+ put_device(dev);
+
+ DBG("%s: returning %d\n",__FUNCTION__,error);
+
+ return error < 0 ? error : count;
+}
+
+/**
+ * bus_read_status - report human readable information
+ * @page: page-sized buffer to write into
+ * @count: number of bytes requested
+ * @off: offset into buffer to start at
+ * @data: bus-specific data
+ */
+static ssize_t iobus_read_status(char *page, size_t count,
+ loff_t off, void *data)
+{
+ char *str = page;
+ struct iobus *bus = (struct iobus*)data;
+ ssize_t len = 0;
+
+ if (!bus)
+ return -EINVAL;
+
+ if (!valid_iobus(bus))
+ return -EFAULT;
+
+ if (off)
+ goto done;
+
+ str += sprintf(str,"Name: %s\n",bus->name);
+ str += sprintf(str,"Bus ID: %s\n",bus->bus_id);
+
+ if (bus->driver)
+ str += sprintf(str,"Type: %s\n",bus->driver->name);
+
+ len = str - page;
+ if (len < off)
+ len = 0;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+
+ done:
+ put_iobus(bus);
+ return len;
+}
+
+/**
+ * bus_write_status - forward a command to a bus
+ * @buf: string encoded command
+ * @count: number of bytes requested
+ * @off: offset into buffer to start at
+ * @data: bus-specific data
+ *
+ * Like device_write_status, this sends a command to a bus driver.
+ * Supported actions are:
+ * scan - scan a bus for devices
+ * add_device <id> - add a child device
+ */
+static ssize_t iobus_write_status(const char *buf, size_t count, loff_t off, void *data)
+{
+ char command[10];
+ char which[15];
+ char id[10];
+ struct iobus *bus = (struct iobus*)data;
+ int num;
+ int error = -EINVAL;
+
+ if (!bus)
+ return -EINVAL;
+
+ if (!valid_iobus(bus))
+ return -EFAULT;
+
+ if (!bus->driver)
+ goto done;
+
+ num = sscanf(buf,"%10s %15s %10s",command,which,id);
+
+ if (!num)
+ goto done;
+
+ if (!strnicmp(command,"scan",4)) {
+ if (bus->driver->scan)
+ error = bus->driver->scan(bus);
+ } else if (!strnicmp(command,"add",3) && num == 2) {
+ error = bus->driver->add_device(bus,id);
+ } else if (!strnicmp(command, "suspend",7)) {
+ u32 state = simple_strtoul(which,NULL,0);
+ if (state > 0)
+ error = do_device_suspend(bus->self,state);
+
+ } else if (!strnicmp(command,"resume",6)) {
+ error = do_device_resume(bus->self);
+
+ }
+
+ done:
+ put_iobus(bus);
+ return error < 0 ? error : count;
+}
+
+static int __init device_init_root(void)
+{
+ /* initialize parent bus lists */
+ iobus_init(&device_root);
+
+ /* don't call iobus_register, as the only thing it really
+ * needs to do is create the root directory. Easier
+ * to just do it here than special case it elsewhere..
+ */
+ iobus_make_dir(&device_root);
+
+ return (device_root.dir ? 0 : -EFAULT);
+}
+
+int __init device_driver_init(void)
+{
+ int error = 0;
+
+ DBG("DEV: Initialising Device Tree\n");
+
+ spin_lock_init(&device_lock);
+
+ error = init_driverfs_fs();
+
+ if (error) {
+ panic("DEV: could not initialise driverfs\n");
+ return error;
+ }
+
+ error = device_init_root();
+ if (error) {
+ printk(KERN_ERR "%s: device root init failed!\n", __FUNCTION__);
+ return error;
+ }
+
+ DBG("DEV: Done Initialising\n");
+ return error;
+}
+
+void __exit device_driver_exit(void)
+{
+
+}
+
+static int __init device_setup(char *str)
+{
+ return 0;
+}
+
+__setup("device=",device_setup);
+
+EXPORT_SYMBOL(device_register);
+EXPORT_SYMBOL(device_alloc);
+EXPORT_SYMBOL(device_init_dev);
+
+EXPORT_SYMBOL(device_create_file);
+EXPORT_SYMBOL(device_remove_file);
+
+EXPORT_SYMBOL(iobus_register);
+EXPORT_SYMBOL(iobus_alloc);
+EXPORT_SYMBOL(iobus_init);
+
+EXPORT_SYMBOL(iobus_create_file);
+EXPORT_SYMBOL(iobus_remove_file);
+
+EXPORT_SYMBOL(device_driver_init);
diff --git a/kernel/exit.c b/kernel/exit.c
index 2650ac328..c2c97c1eb 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -150,21 +150,34 @@ static inline int has_stopped_jobs(int pgrp)
}
/*
- * When we die, we re-parent all our children to
+ * When we die, we re-parent all our children.
+ * Try to give them to another thread in our process
+ * group, and if no such member exists, give it to
* the global child reaper process (ie "init")
*/
static inline void forget_original_parent(struct task_struct * father)
{
- struct task_struct * p;
+ struct task_struct * p, *reaper;
read_lock(&tasklist_lock);
+ /* Next in our thread group */
+ reaper = next_thread(father);
+ if (reaper == father)
+ reaper = child_reaper;
+
for_each_task(p) {
if (p->p_opptr == father) {
/* We dont want people slaying init */
p->exit_signal = SIGCHLD;
p->self_exec_id++;
- p->p_opptr = child_reaper;
+
+ /* Make sure we're not reparenting to ourselves */
+ if (p == reaper)
+ p->p_opptr = child_reaper;
+ else
+ p->p_opptr = reaper;
+
if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
}
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 3c28fc2a9..8a39c6adb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -206,7 +206,7 @@ fail_nomem:
return retval;
}
-spinlock_t mmlist_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+spinlock_t mmlist_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
int mmlist_nr;
#define allocate_mm() (kmem_cache_alloc(mm_cachep, SLAB_KERNEL))
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 8a11de89c..7ed05fafe 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -122,6 +122,8 @@ EXPORT_SYMBOL(kmap_high);
EXPORT_SYMBOL(kunmap_high);
EXPORT_SYMBOL(highmem_start_page);
EXPORT_SYMBOL(create_bounce);
+EXPORT_SYMBOL(kmap_prot);
+EXPORT_SYMBOL(kmap_pte);
#endif
/* filesystem internal functions */
@@ -291,7 +293,6 @@ EXPORT_SYMBOL(tty_std_termios);
/* block device driver support */
EXPORT_SYMBOL(blksize_size);
-EXPORT_SYMBOL(hardsect_size);
EXPORT_SYMBOL(blk_size);
EXPORT_SYMBOL(blk_dev);
EXPORT_SYMBOL(is_read_only);
@@ -308,8 +309,8 @@ EXPORT_SYMBOL(register_disk);
EXPORT_SYMBOL(tq_disk);
EXPORT_SYMBOL(init_buffer);
EXPORT_SYMBOL(refile_buffer);
-EXPORT_SYMBOL(max_sectors);
EXPORT_SYMBOL(max_readahead);
+EXPORT_SYMBOL(wipe_partitions);
/* tty routines */
EXPORT_SYMBOL(tty_hangup);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index dd5fa5daa..97b8eb8cc 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -42,7 +42,7 @@
irq_cpustat_t irq_stat[NR_CPUS];
-static struct softirq_action softirq_vec[32] __cacheline_aligned;
+static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;
/*
* we cannot loop indefinitely here to avoid userspace starvation,
@@ -146,8 +146,8 @@ void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
/* Tasklets */
-struct tasklet_head tasklet_vec[NR_CPUS] __cacheline_aligned;
-struct tasklet_head tasklet_hi_vec[NR_CPUS] __cacheline_aligned;
+struct tasklet_head tasklet_vec[NR_CPUS] __cacheline_aligned_in_smp;
+struct tasklet_head tasklet_hi_vec[NR_CPUS] __cacheline_aligned_in_smp;
void __tasklet_schedule(struct tasklet_struct *t)
{
diff --git a/mm/bootmem.c b/mm/bootmem.c
index be6b682ca..3b0420d65 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -25,6 +25,7 @@
*/
unsigned long max_low_pfn;
unsigned long min_low_pfn;
+unsigned long max_pfn;
/* return the number of _pages_ that will be allocated for the boot bitmap */
unsigned long __init bootmem_bootmap_pages (unsigned long pages)
diff --git a/mm/filemap.c b/mm/filemap.c
index 129849b4b..3d4c6bb00 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -941,7 +941,6 @@ struct page * find_or_create_page(struct address_space *mapping, unsigned long i
spin_unlock(&pagecache_lock);
if (!page) {
struct page *newpage = alloc_page(gfp_mask);
- page = ERR_PTR(-ENOMEM);
if (newpage) {
spin_lock(&pagecache_lock);
page = __find_lock_page_helper(mapping, index, *hash);
diff --git a/mm/highmem.c b/mm/highmem.c
index a4a3fbb71..d74893da6 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -21,6 +21,9 @@
#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/slab.h>
+#include <linux/compiler.h>
+
+#include <linux/kernel_stat.h>
/*
* Virtual_count is not a pure "count".
@@ -186,7 +189,7 @@ void kunmap_high(struct page *page)
wake_up(&pkmap_map_wait);
}
-#define POOL_SIZE 32
+#define POOL_SIZE 64
/*
* This lock gets no contention at all, normally.
@@ -200,75 +203,34 @@ int nr_emergency_bhs;
static LIST_HEAD(emergency_bhs);
/*
- * Simple bounce buffer support for highmem pages.
- * This will be moved to the block layer in 2.5.
+ * Simple bounce buffer support for highmem pages. Depending on the
+ * queue gfp mask set, *to may or may not be a highmem page. kmap it
+ * always, it will do the Right Thing
*/
-
-static inline void copy_from_high_bh (struct buffer_head *to,
- struct buffer_head *from)
-{
- struct page *p_from;
- char *vfrom;
-
- p_from = from->b_page;
-
- vfrom = kmap_atomic(p_from, KM_USER0);
- memcpy(to->b_data, vfrom + bh_offset(from), to->b_size);
- kunmap_atomic(vfrom, KM_USER0);
-}
-
-static inline void copy_to_high_bh_irq (struct buffer_head *to,
- struct buffer_head *from)
-{
- struct page *p_to;
- char *vto;
- unsigned long flags;
-
- p_to = to->b_page;
- __save_flags(flags);
- __cli();
- vto = kmap_atomic(p_to, KM_BOUNCE_READ);
- memcpy(vto + bh_offset(to), from->b_data, to->b_size);
- kunmap_atomic(vto, KM_BOUNCE_READ);
- __restore_flags(flags);
-}
-
-static inline void bounce_end_io (struct buffer_head *bh, int uptodate)
+static inline void copy_to_high_bio_irq(struct bio *to, struct bio *from)
{
- struct page *page;
- struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
+ unsigned char *vto, *vfrom;
unsigned long flags;
+ struct bio_vec *tovec, *fromvec;
+ int i;
- bh_orig->b_end_io(bh_orig, uptodate);
-
- page = bh->b_page;
+ __bio_for_each_segment(tovec, to, i, 0) {
+ fromvec = &from->bi_io_vec[i];
- spin_lock_irqsave(&emergency_lock, flags);
- if (nr_emergency_pages >= POOL_SIZE)
- __free_page(page);
- else {
- /*
- * We are abusing page->list to manage
- * the highmem emergency pool:
- */
- list_add(&page->list, &emergency_pages);
- nr_emergency_pages++;
- }
-
- if (nr_emergency_bhs >= POOL_SIZE) {
-#ifdef HIGHMEM_DEBUG
- /* Don't clobber the constructed slab cache */
- init_waitqueue_head(&bh->b_wait);
-#endif
- kmem_cache_free(bh_cachep, bh);
- } else {
/*
- * Ditto in the bh case, here we abuse b_inode_buffers:
+ * not bounced
*/
- list_add(&bh->b_inode_buffers, &emergency_bhs);
- nr_emergency_bhs++;
+ if (tovec->bv_page == fromvec->bv_page)
+ continue;
+
+ vfrom = page_address(fromvec->bv_page) + fromvec->bv_offset;
+
+ local_irq_save(flags);
+ vto = kmap_atomic(tovec->bv_page, KM_BOUNCE_READ);
+ memcpy(vto + tovec->bv_offset, vfrom, tovec->bv_len);
+ kunmap_atomic(vto, KM_BOUNCE_READ);
+ local_irq_restore(flags);
}
- spin_unlock_irqrestore(&emergency_lock, flags);
}
static __init int init_emergency_pool(void)
@@ -290,44 +252,75 @@ static __init int init_emergency_pool(void)
list_add(&page->list, &emergency_pages);
nr_emergency_pages++;
}
- while (nr_emergency_bhs < POOL_SIZE) {
- struct buffer_head * bh = kmem_cache_alloc(bh_cachep, SLAB_ATOMIC);
- if (!bh) {
- printk("couldn't refill highmem emergency bhs");
- break;
- }
- list_add(&bh->b_inode_buffers, &emergency_bhs);
- nr_emergency_bhs++;
- }
spin_unlock_irq(&emergency_lock);
- printk("allocated %d pages and %d bhs reserved for the highmem bounces\n",
- nr_emergency_pages, nr_emergency_bhs);
-
+ printk("allocated %d pages reserved for the highmem bounces\n", nr_emergency_pages);
return 0;
}
__initcall(init_emergency_pool);
-static void bounce_end_io_write (struct buffer_head *bh, int uptodate)
+static inline int bounce_end_io (struct bio *bio, int nr_sectors)
+{
+ struct bio *bio_orig = bio->bi_private;
+ struct bio_vec *bvec, *org_vec;
+ unsigned long flags;
+ int ret, i;
+
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ goto out_eio;
+
+ set_bit(BIO_UPTODATE, &bio_orig->bi_flags);
+
+ /*
+ * free up bounce indirect pages used
+ */
+ spin_lock_irqsave(&emergency_lock, flags);
+ __bio_for_each_segment(bvec, bio, i, 0) {
+ org_vec = &bio_orig->bi_io_vec[i];
+ if (bvec->bv_page == org_vec->bv_page)
+ continue;
+
+ if (nr_emergency_pages >= POOL_SIZE)
+ __free_page(bvec->bv_page);
+ else {
+ /*
+ * We are abusing page->list to manage
+ * the highmem emergency pool:
+ */
+ list_add(&bvec->bv_page->list, &emergency_pages);
+ nr_emergency_pages++;
+ }
+ }
+ spin_unlock_irqrestore(&emergency_lock, flags);
+
+out_eio:
+ ret = bio_orig->bi_end_io(bio_orig, nr_sectors);
+
+ bio_put(bio);
+ return ret;
+}
+
+static int bounce_end_io_write(struct bio *bio, int nr_sectors)
{
- bounce_end_io(bh, uptodate);
+ return bounce_end_io(bio, nr_sectors);
}
-static void bounce_end_io_read (struct buffer_head *bh, int uptodate)
+static int bounce_end_io_read (struct bio *bio, int nr_sectors)
{
- struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
+ struct bio *bio_orig = bio->bi_private;
- if (uptodate)
- copy_to_high_bh_irq(bh_orig, bh);
- bounce_end_io(bh, uptodate);
+ if (test_bit(BIO_UPTODATE, &bio->bi_flags))
+ copy_to_high_bio_irq(bio_orig, bio);
+
+ return bounce_end_io(bio, nr_sectors);
}
-struct page *alloc_bounce_page (void)
+struct page *alloc_bounce_page(int gfp_mask)
{
struct list_head *tmp;
struct page *page;
- page = alloc_page(GFP_NOHIGHIO);
+ page = alloc_page(gfp_mask);
if (page)
return page;
/*
@@ -360,91 +353,78 @@ repeat_alloc:
goto repeat_alloc;
}
-struct buffer_head *alloc_bounce_bh (void)
+void create_bounce(unsigned long pfn, struct bio **bio_orig)
{
- struct list_head *tmp;
- struct buffer_head *bh;
+ struct page *page;
+ struct bio *bio = NULL;
+ int i, rw = bio_data_dir(*bio_orig);
+ struct bio_vec *to, *from;
+
+ BUG_ON((*bio_orig)->bi_idx);
+
+ bio_for_each_segment(from, *bio_orig, i) {
+ page = from->bv_page;
+
+ /*
+ * is destination page below bounce pfn?
+ */
+ if ((page - page->zone->zone_mem_map) + (page->zone->zone_start_paddr >> PAGE_SHIFT) < pfn)
+ continue;
+
+ /*
+ * irk, bounce it
+ */
+ if (!bio)
+ bio = bio_alloc(GFP_NOHIGHIO, (*bio_orig)->bi_vcnt);
+
+ to = &bio->bi_io_vec[i];
+
+ to->bv_page = alloc_bounce_page(GFP_NOHIGHIO);
+ to->bv_len = from->bv_len;
+ to->bv_offset = from->bv_offset;
+
+ if (rw & WRITE) {
+ char *vto, *vfrom;
+
+ vto = page_address(to->bv_page) + to->bv_offset;
+ vfrom = kmap(from->bv_page) + from->bv_offset;
+ memcpy(vto, vfrom, to->bv_len);
+ kunmap(from->bv_page);
+ }
+ }
- bh = kmem_cache_alloc(bh_cachep, SLAB_NOHIGHIO);
- if (bh)
- return bh;
/*
- * No luck. First, kick the VM so it doesnt idle around while
- * we are using up our emergency rations.
+ * no pages bounced
*/
- wakeup_bdflush();
+ if (!bio)
+ return;
-repeat_alloc:
/*
- * Try to allocate from the emergency pool.
+ * at least one page was bounced, fill in possible non-highmem
+ * pages
*/
- tmp = &emergency_bhs;
- spin_lock_irq(&emergency_lock);
- if (!list_empty(tmp)) {
- bh = list_entry(tmp->next, struct buffer_head, b_inode_buffers);
- list_del(tmp->next);
- nr_emergency_bhs--;
+ bio_for_each_segment(from, *bio_orig, i) {
+ to = &bio->bi_io_vec[i];
+ if (!to->bv_page) {
+ to->bv_page = from->bv_page;
+ to->bv_len = from->bv_len;
+ to->bv_offset = to->bv_offset;
+ }
}
- spin_unlock_irq(&emergency_lock);
- if (bh)
- return bh;
-
- /* we need to wait I/O completion */
- run_task_queue(&tq_disk);
- current->policy |= SCHED_YIELD;
- __set_current_state(TASK_RUNNING);
- schedule();
- goto repeat_alloc;
-}
+ bio->bi_dev = (*bio_orig)->bi_dev;
+ bio->bi_sector = (*bio_orig)->bi_sector;
+ bio->bi_rw = (*bio_orig)->bi_rw;
-struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig)
-{
- struct page *page;
- struct buffer_head *bh;
+ bio->bi_vcnt = (*bio_orig)->bi_vcnt;
+ bio->bi_idx = 0;
+ bio->bi_size = (*bio_orig)->bi_size;
- if (!PageHighMem(bh_orig->b_page))
- return bh_orig;
+ if (rw & WRITE)
+ bio->bi_end_io = bounce_end_io_write;
+ else
+ bio->bi_end_io = bounce_end_io_read;
- bh = alloc_bounce_bh();
- /*
- * This is wasteful for 1k buffers, but this is a stopgap measure
- * and we are being ineffective anyway. This approach simplifies
- * things immensly. On boxes with more than 4GB RAM this should
- * not be an issue anyway.
- */
- page = alloc_bounce_page();
-
- set_bh_page(bh, page, 0);
-
- bh->b_next = NULL;
- bh->b_blocknr = bh_orig->b_blocknr;
- bh->b_size = bh_orig->b_size;
- bh->b_list = -1;
- bh->b_dev = bh_orig->b_dev;
- bh->b_count = bh_orig->b_count;
- bh->b_rdev = bh_orig->b_rdev;
- bh->b_state = bh_orig->b_state;
-#ifdef HIGHMEM_DEBUG
- bh->b_flushtime = jiffies;
- bh->b_next_free = NULL;
- bh->b_prev_free = NULL;
- /* bh->b_this_page */
- bh->b_reqnext = NULL;
- bh->b_pprev = NULL;
-#endif
- /* bh->b_page */
- if (rw == WRITE) {
- bh->b_end_io = bounce_end_io_write;
- copy_from_high_bh(bh, bh_orig);
- } else
- bh->b_end_io = bounce_end_io_read;
- bh->b_private = (void *)bh_orig;
- bh->b_rsector = bh_orig->b_rsector;
-#ifdef HIGHMEM_DEBUG
- memset(&bh->b_wait, -1, sizeof(bh->b_wait));
-#endif
-
- return bh;
+ bio->bi_private = *bio_orig;
+ *bio_orig = bio;
}
-
diff --git a/mm/page_io.c b/mm/page_io.c
index 237bc0104..feb74055d 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -36,7 +36,7 @@
static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page)
{
unsigned long offset;
- int zones[PAGE_SIZE/512];
+ sector_t zones[PAGE_SIZE/512];
int zones_used;
kdev_t dev = 0;
int block_size;
diff --git a/mm/slab.c b/mm/slab.c
index 7819a1984..b91f65323 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1282,9 +1282,10 @@ static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep,
})
#ifdef CONFIG_SMP
-void* kmem_cache_alloc_batch(kmem_cache_t* cachep, cpucache_t* cc, int flags)
+void* kmem_cache_alloc_batch(kmem_cache_t* cachep, int flags)
{
int batchcount = cachep->batchcount;
+ cpucache_t* cc = cc_data(cachep);
spin_lock(&cachep->spinlock);
while (batchcount--) {
@@ -1333,7 +1334,7 @@ try_again:
objp = cc_entry(cc)[--cc->avail];
} else {
STATS_INC_ALLOCMISS(cachep);
- objp = kmem_cache_alloc_batch(cachep,cc,flags);
+ objp = kmem_cache_alloc_batch(cachep,flags);
if (!objp)
goto alloc_new_slab_nolock;
}
@@ -1921,13 +1922,12 @@ static int proc_getdata (char*page, char**start, off_t off, int count)
#endif
#ifdef CONFIG_SMP
{
- cpucache_t *cc = cc_data(cachep);
unsigned int batchcount = cachep->batchcount;
unsigned int limit;
- if (cc)
- limit = cc->limit;
- else
+ if (cc_data(cachep))
+ limit = cc_data(cachep)->limit;
+ else
limit = 0;
len += sprintf(page+len, " : %4u %4u",
limit, batchcount);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index facad1596..5d8c5d52a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -804,25 +804,17 @@ int get_swaparea_info(char *buf)
{
char * page = (char *) __get_free_page(GFP_KERNEL);
struct swap_info_struct *ptr = swap_info;
- int i, j, len = 0, usedswap;
+ int i, len;
if (!page)
return -ENOMEM;
- len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+ len = sprintf(buf, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
if ((ptr->flags & SWP_USED) && ptr->swap_map) {
char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt,
page, PAGE_SIZE);
-
- len += sprintf(buf + len, "%-31s ", path);
-
- if (!ptr->swap_device)
- len += sprintf(buf + len, "file\t\t");
- else
- len += sprintf(buf + len, "partition\t");
-
- usedswap = 0;
+ int j, usedswap = 0;
for (j = 0; j < ptr->max; ++j)
switch (ptr->swap_map[j]) {
case SWAP_MAP_BAD:
@@ -831,8 +823,12 @@ int get_swaparea_info(char *buf)
default:
usedswap++;
}
- len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10),
- usedswap << (PAGE_SHIFT - 10), ptr->prio);
+ len += sprintf(buf + len, "%-39s %s\t%d\t%d\t%d\n",
+ path,
+ ptr->swap_device ? "partition" : "file\t",
+ ptr->pages << (PAGE_SHIFT - 10),
+ usedswap << (PAGE_SHIFT - 10),
+ ptr->prio);
}
}
free_page((unsigned long) page);
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 748647d36..6de1d6103 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1,5 +1,5 @@
/*
- * $Id: ipconfig.c,v 1.43 2001-11-21 20:27:34 davem Exp $
+ * $Id: ipconfig.c,v 1.44 2001-12-11 04:55:54 davem Exp $
*
* Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
* user-supplied information to configure own IP address and routes.
@@ -47,6 +47,7 @@
#include <linux/route.h>
#include <linux/udp.h>
#include <linux/proc_fs.h>
+#include <linux/major.h>
#include <net/arp.h>
#include <net/ip.h>
#include <net/ipconfig.h>