summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/acpi/osl.c25
-rw-r--r--drivers/ata/Kconfig35
-rw-r--r--drivers/ata/Makefile4
-rw-r--r--drivers/ata/ahci.c229
-rw-r--r--drivers/ata/ata_generic.c11
-rw-r--r--drivers/ata/ata_piix.c194
-rw-r--r--drivers/ata/libata-core.c561
-rw-r--r--drivers/ata/libata-eh.c110
-rw-r--r--drivers/ata/libata-scsi.c342
-rw-r--r--drivers/ata/libata-sff.c43
-rw-r--r--drivers/ata/libata.h28
-rw-r--r--drivers/ata/pata_ali.c140
-rw-r--r--drivers/ata/pata_amd.c26
-rw-r--r--drivers/ata/pata_artop.c1
-rw-r--r--drivers/ata/pata_atiixp.c9
-rw-r--r--drivers/ata/pata_cmd64x.c23
-rw-r--r--drivers/ata/pata_cs5520.c25
-rw-r--r--drivers/ata/pata_cs5530.c100
-rw-r--r--drivers/ata/pata_cs5535.c9
-rw-r--r--drivers/ata/pata_cypress.c9
-rw-r--r--drivers/ata/pata_efar.c7
-rw-r--r--drivers/ata/pata_hpt366.c58
-rw-r--r--drivers/ata/pata_hpt37x.c1
-rw-r--r--drivers/ata/pata_hpt3x2n.c1
-rw-r--r--drivers/ata/pata_hpt3x3.c47
-rw-r--r--drivers/ata/pata_isapnp.c1
-rw-r--r--drivers/ata/pata_it821x.c19
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c271
-rw-r--r--drivers/ata/pata_jmicron.c36
-rw-r--r--drivers/ata/pata_legacy.c1
-rw-r--r--drivers/ata/pata_marvell.c224
-rw-r--r--drivers/ata/pata_mpiix.c9
-rw-r--r--drivers/ata/pata_netcell.c8
-rw-r--r--drivers/ata/pata_ns87410.c9
-rw-r--r--drivers/ata/pata_oldpiix.c5
-rw-r--r--drivers/ata/pata_opti.c34
-rw-r--r--drivers/ata/pata_optidma.c9
-rw-r--r--drivers/ata/pata_pcmcia.c16
-rw-r--r--drivers/ata/pata_pdc2027x.c3
-rw-r--r--drivers/ata/pata_pdc202xx_old.c65
-rw-r--r--drivers/ata/pata_platform.c295
-rw-r--r--drivers/ata/pata_qdi.c1
-rw-r--r--drivers/ata/pata_radisys.c5
-rw-r--r--drivers/ata/pata_rz1000.c49
-rw-r--r--drivers/ata/pata_sc1200.c9
-rw-r--r--drivers/ata/pata_serverworks.c33
-rw-r--r--drivers/ata/pata_sil680.c83
-rw-r--r--drivers/ata/pata_sis.c7
-rw-r--r--drivers/ata/pata_sl82c105.c1
-rw-r--r--drivers/ata/pata_triflex.c9
-rw-r--r--drivers/ata/pata_via.c109
-rw-r--r--drivers/ata/pata_winbond.c306
-rw-r--r--drivers/ata/sata_nv.c1044
-rw-r--r--drivers/ata/sata_promise.c46
-rw-r--r--drivers/ata/sata_sil.c16
-rw-r--r--drivers/ata/sata_sil24.c18
-rw-r--r--drivers/ata/sata_sis.c17
-rw-r--r--drivers/atm/ambassador.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/idt77252.c9
-rw-r--r--drivers/base/cpu.c1
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoecmd.c4
-rw-r--r--drivers/block/aoe/aoedev.c2
-rw-r--r--drivers/block/floppy.c10
-rw-r--r--drivers/block/paride/pd.c8
-rw-r--r--drivers/block/paride/pseudo.h10
-rw-r--r--drivers/block/sx8.c7
-rw-r--r--drivers/block/ub.c8
-rw-r--r--drivers/block/viodasd.c49
-rw-r--r--drivers/bluetooth/bcm203x.c7
-rw-r--r--drivers/bluetooth/bluecard_cs.c38
-rw-r--r--drivers/bluetooth/bt3c_cs.c20
-rw-r--r--drivers/bluetooth/btuart_cs.c20
-rw-r--r--drivers/bluetooth/dtl1_cs.c20
-rw-r--r--drivers/char/Kconfig33
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/cyclades.c9
-rw-r--r--drivers/char/drm/via_dmablit.c6
-rw-r--r--drivers/char/epca.c8
-rw-r--r--drivers/char/esp.c14
-rw-r--r--drivers/char/ftape/Kconfig330
-rw-r--r--drivers/char/ftape/Makefile28
-rw-r--r--drivers/char/ftape/README.PCI81
-rw-r--r--drivers/char/ftape/RELEASE-NOTES966
-rw-r--r--drivers/char/ftape/compressor/Makefile31
-rw-r--r--drivers/char/ftape/compressor/lzrw3.c743
-rw-r--r--drivers/char/ftape/compressor/lzrw3.h253
-rw-r--r--drivers/char/ftape/compressor/zftape-compress.c1203
-rw-r--r--drivers/char/ftape/compressor/zftape-compress.h83
-rw-r--r--drivers/char/ftape/lowlevel/Makefile43
-rw-r--r--drivers/char/ftape/lowlevel/fc-10.c175
-rw-r--r--drivers/char/ftape/lowlevel/fc-10.h39
-rw-r--r--drivers/char/ftape/lowlevel/fdc-io.c1349
-rw-r--r--drivers/char/ftape/lowlevel/fdc-io.h252
-rw-r--r--drivers/char/ftape/lowlevel/fdc-isr.c1170
-rw-r--r--drivers/char/ftape/lowlevel/fdc-isr.h55
-rw-r--r--drivers/char/ftape/lowlevel/ftape-bsm.c491
-rw-r--r--drivers/char/ftape/lowlevel/ftape-bsm.h66
-rw-r--r--drivers/char/ftape/lowlevel/ftape-buffer.c130
-rw-r--r--drivers/char/ftape/lowlevel/ftape-buffer.h32
-rw-r--r--drivers/char/ftape/lowlevel/ftape-calibr.c275
-rw-r--r--drivers/char/ftape/lowlevel/ftape-calibr.h37
-rw-r--r--drivers/char/ftape/lowlevel/ftape-ctl.c896
-rw-r--r--drivers/char/ftape/lowlevel/ftape-ctl.h162
-rw-r--r--drivers/char/ftape/lowlevel/ftape-ecc.c853
-rw-r--r--drivers/char/ftape/lowlevel/ftape-ecc.h84
-rw-r--r--drivers/char/ftape/lowlevel/ftape-format.c344
-rw-r--r--drivers/char/ftape/lowlevel/ftape-format.h37
-rw-r--r--drivers/char/ftape/lowlevel/ftape-init.c160
-rw-r--r--drivers/char/ftape/lowlevel/ftape-init.h43
-rw-r--r--drivers/char/ftape/lowlevel/ftape-io.c992
-rw-r--r--drivers/char/ftape/lowlevel/ftape-io.h90
-rw-r--r--drivers/char/ftape/lowlevel/ftape-proc.c214
-rw-r--r--drivers/char/ftape/lowlevel/ftape-proc.h35
-rw-r--r--drivers/char/ftape/lowlevel/ftape-read.c621
-rw-r--r--drivers/char/ftape/lowlevel/ftape-read.h51
-rw-r--r--drivers/char/ftape/lowlevel/ftape-rw.c1092
-rw-r--r--drivers/char/ftape/lowlevel/ftape-rw.h111
-rw-r--r--drivers/char/ftape/lowlevel/ftape-setup.c104
-rw-r--r--drivers/char/ftape/lowlevel/ftape-tracing.c118
-rw-r--r--drivers/char/ftape/lowlevel/ftape-tracing.h179
-rw-r--r--drivers/char/ftape/lowlevel/ftape-write.c336
-rw-r--r--drivers/char/ftape/lowlevel/ftape-write.h53
-rw-r--r--drivers/char/ftape/lowlevel/ftape_syms.c87
-rw-r--r--drivers/char/ftape/zftape/Makefile36
-rw-r--r--drivers/char/ftape/zftape/zftape-buffers.c149
-rw-r--r--drivers/char/ftape/zftape/zftape-buffers.h55
-rw-r--r--drivers/char/ftape/zftape/zftape-ctl.c1417
-rw-r--r--drivers/char/ftape/zftape/zftape-ctl.h58
-rw-r--r--drivers/char/ftape/zftape/zftape-eof.c199
-rw-r--r--drivers/char/ftape/zftape/zftape-eof.h52
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c377
-rw-r--r--drivers/char/ftape/zftape/zftape-init.h77
-rw-r--r--drivers/char/ftape/zftape/zftape-read.c377
-rw-r--r--drivers/char/ftape/zftape/zftape-read.h53
-rw-r--r--drivers/char/ftape/zftape/zftape-rw.c375
-rw-r--r--drivers/char/ftape/zftape/zftape-rw.h101
-rw-r--r--drivers/char/ftape/zftape/zftape-vtbl.c757
-rw-r--r--drivers/char/ftape/zftape/zftape-vtbl.h227
-rw-r--r--drivers/char/ftape/zftape/zftape-write.c483
-rw-r--r--drivers/char/ftape/zftape/zftape-write.h38
-rw-r--r--drivers/char/ftape/zftape/zftape_syms.c43
-rw-r--r--drivers/char/genrtc.c4
-rw-r--r--drivers/char/hpet.c1
-rw-r--r--drivers/char/hvsi.c16
-rw-r--r--drivers/char/hw_random/core.c1
-rw-r--r--drivers/char/ip2/i2lib.c12
-rw-r--r--drivers/char/ip2/ip2main.c23
-rw-r--r--drivers/char/isicom.c12
-rw-r--r--drivers/char/istallion.c8
-rw-r--r--drivers/char/moxa.c8
-rw-r--r--drivers/char/mxser.c9
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c26
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c26
-rw-r--r--drivers/char/pcmcia/synclink_cs.c15
-rw-r--r--drivers/char/random.c54
-rw-r--r--drivers/char/riscom8.c12
-rw-r--r--drivers/char/serial167.c6
-rw-r--r--drivers/char/sonypi.c4
-rw-r--r--drivers/char/specialix.c14
-rw-r--r--drivers/char/stallion.c10
-rw-r--r--drivers/char/synclink.c9
-rw-r--r--drivers/char/synclink_gt.c10
-rw-r--r--drivers/char/synclinkmp.c8
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm.c6
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tty_io.c31
-rw-r--r--drivers/char/vt.c6
-rw-r--r--drivers/connector/cn_queue.c8
-rw-r--r--drivers/connector/connector.c31
-rw-r--r--drivers/cpufreq/cpufreq.c10
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c7
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c28
-rw-r--r--drivers/hwmon/abituguru.c1
-rw-r--r--drivers/hwmon/hdaps.c1
-rw-r--r--drivers/i2c/chips/ds1374.c12
-rw-r--r--drivers/i2c/chips/m41t00.c9
-rw-r--r--drivers/ide/legacy/ide-cs.c20
-rw-r--r--drivers/ide/pci/via82cxxx.c4
-rw-r--r--drivers/ieee1394/hosts.c9
-rw-r--r--drivers/ieee1394/hosts.h2
-rw-r--r--drivers/ieee1394/sbp2.c28
-rw-r--r--drivers/ieee1394/sbp2.h2
-rw-r--r--drivers/infiniband/core/addr.c6
-rw-r--r--drivers/infiniband/core/cache.c7
-rw-r--r--drivers/infiniband/core/cm.c19
-rw-r--r--drivers/infiniband/core/cma.c10
-rw-r--r--drivers/infiniband/core/iwcm.c6
-rw-r--r--drivers/infiniband/core/mad.c25
-rw-r--r--drivers/infiniband/core/mad_priv.h2
-rw-r--r--drivers/infiniband/core/mad_rmpp.c18
-rw-r--r--drivers/infiniband/core/sa_query.c10
-rw-r--r--drivers/infiniband/core/uverbs_mem.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c7
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h16
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c25
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c22
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c1
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c10
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c7
-rw-r--r--drivers/input/keyboard/atkbd.c6
-rw-r--r--drivers/input/keyboard/lkkbd.c6
-rw-r--r--drivers/input/keyboard/sunkbd.c6
-rw-r--r--drivers/input/mouse/psmouse-base.c7
-rw-r--r--drivers/input/serio/libps2.c6
-rw-r--r--drivers/isdn/act2000/capi.c4
-rw-r--r--drivers/isdn/act2000/capi.h2
-rw-r--r--drivers/isdn/act2000/module.c18
-rw-r--r--drivers/isdn/capi/kcapi.c14
-rw-r--r--drivers/isdn/divert/isdn_divert.c2
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c36
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c7
-rw-r--r--drivers/isdn/hisax/avma1_cs.c36
-rw-r--r--drivers/isdn/hisax/config.c9
-rw-r--r--drivers/isdn/hisax/elsa_cs.c17
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c5
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c9
-rw-r--r--drivers/isdn/hisax/hfc_pci.c6
-rw-r--r--drivers/isdn/hisax/hfc_sx.c6
-rw-r--r--drivers/isdn/hisax/icc.c6
-rw-r--r--drivers/isdn/hisax/isac.c6
-rw-r--r--drivers/isdn/hisax/isar.c6
-rw-r--r--drivers/isdn/hisax/isdnl1.c6
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c10
-rw-r--r--drivers/isdn/hisax/teles_cs.c17
-rw-r--r--drivers/isdn/hisax/w6692.c6
-rw-r--r--drivers/isdn/hysdn/boardergo.c5
-rw-r--r--drivers/isdn/i4l/isdn_net.c6
-rw-r--r--drivers/isdn/pcbit/drv.c4
-rw-r--r--drivers/isdn/pcbit/layer2.c6
-rw-r--r--drivers/isdn/pcbit/pcbit.h2
-rw-r--r--drivers/leds/ledtrig-ide-disk.c1
-rw-r--r--drivers/leds/ledtrig-timer.c1
-rw-r--r--drivers/macintosh/Kconfig7
-rw-r--r--drivers/macintosh/Makefile1
-rw-r--r--drivers/macintosh/adb.c4
-rw-r--r--drivers/macintosh/rack-meter.c616
-rw-r--r--drivers/macintosh/smu.c7
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/macintosh/therm_pm72.c5
-rw-r--r--drivers/macintosh/therm_windtunnel.c7
-rw-r--r--drivers/md/dm-crypt.c8
-rw-r--r--drivers/md/dm-mpath.c18
-rw-r--r--drivers/md/dm-raid1.c4
-rw-r--r--drivers/md/dm-snap.c9
-rw-r--r--drivers/md/kcopyd.c4
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c9
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c19
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c19
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/video/cpia_pp.c20
-rw-r--r--drivers/media/video/cx88/cx88-input.c6
-rw-r--r--drivers/media/video/ir-kbd-i2c.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c13
-rw-r--r--drivers/media/video/saa6588.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c9
-rw-r--r--drivers/message/fusion/mptfc.c14
-rw-r--r--drivers/message/fusion/mptlan.c29
-rw-r--r--drivers/message/fusion/mptsas.c25
-rw-r--r--drivers/message/fusion/mptspi.c14
-rw-r--r--drivers/message/i2o/driver.c2
-rw-r--r--drivers/message/i2o/exec-osm.c13
-rw-r--r--drivers/message/i2o/i2o_block.c15
-rw-r--r--drivers/message/i2o/i2o_block.h2
-rw-r--r--drivers/misc/tifm_7xx1.c18
-rw-r--r--drivers/mmc/Kconfig2
-rw-r--r--drivers/mmc/at91_mci.c2
-rw-r--r--drivers/mmc/au1xmmc.c2
-rw-r--r--drivers/mmc/imxmmc.c2
-rw-r--r--drivers/mmc/mmc.c308
-rw-r--r--drivers/mmc/mmc.h2
-rw-r--r--drivers/mmc/mmc_block.c15
-rw-r--r--drivers/mmc/mmc_queue.c63
-rw-r--r--drivers/mmc/mmc_queue.h3
-rw-r--r--drivers/mmc/mmc_sysfs.c10
-rw-r--r--drivers/mmc/mmci.c2
-rw-r--r--drivers/mmc/omap.c272
-rw-r--r--drivers/mmc/omap.h55
-rw-r--r--drivers/mmc/pxamci.c2
-rw-r--r--drivers/mmc/sdhci.c17
-rw-r--r--drivers/mmc/sdhci.h2
-rw-r--r--drivers/mmc/tifm_sd.c28
-rw-r--r--drivers/mmc/wbsd.c2
-rw-r--r--drivers/net/3c501.c2
-rw-r--r--drivers/net/3c503.c2
-rw-r--r--drivers/net/3c505.c2
-rw-r--r--drivers/net/3c507.c2
-rw-r--r--drivers/net/3c523.c2
-rw-r--r--drivers/net/3c527.c2
-rw-r--r--drivers/net/8139too.c26
-rw-r--r--drivers/net/Space.c1
-rw-r--r--drivers/net/ac3200.c2
-rw-r--r--drivers/net/apne.c4
-rw-r--r--drivers/net/appletalk/cops.c2
-rw-r--r--drivers/net/arm/at91_ether.c88
-rw-r--r--drivers/net/arm/at91_ether.h1
-rw-r--r--drivers/net/arm/ether1.c6
-rw-r--r--drivers/net/arm/ether3.c8
-rw-r--r--drivers/net/at1700.c2
-rw-r--r--drivers/net/atarilance.c4
-rw-r--r--drivers/net/bnx2.c695
-rw-r--r--drivers/net/bnx2.h2940
-rw-r--r--drivers/net/bnx2_fw.h1234
-rw-r--r--drivers/net/bnx2_fw2.h4086
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/cassini.c8
-rw-r--r--drivers/net/chelsio/common.h2
-rw-r--r--drivers/net/chelsio/cphy.h2
-rw-r--r--drivers/net/chelsio/cxgb2.c16
-rw-r--r--drivers/net/chelsio/my3126.c8
-rw-r--r--drivers/net/cs89x0.c2
-rw-r--r--drivers/net/declance.c404
-rw-r--r--drivers/net/e100.c8
-rw-r--r--drivers/net/e1000/e1000_main.c12
-rw-r--r--drivers/net/e2100.c2
-rw-r--r--drivers/net/eepro.c2
-rw-r--r--drivers/net/eexpress.c2
-rw-r--r--drivers/net/ehea/ehea_main.c9
-rw-r--r--drivers/net/ehea/ehea_qmr.c1
-rw-r--r--drivers/net/es3210.c2
-rw-r--r--drivers/net/eth16i.c2
-rw-r--r--drivers/net/hamradio/baycom_epp.c14
-rw-r--r--drivers/net/hamradio/dmascc.c8
-rw-r--r--drivers/net/hp-plus.c2
-rw-r--r--drivers/net/hp.c2
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h6
-rw-r--r--drivers/net/ibmveth.c4
-rw-r--r--drivers/net/ibmveth.h1
-rw-r--r--drivers/net/ioc3-eth.c1
-rw-r--r--drivers/net/irda/mcs7780.c6
-rw-r--r--drivers/net/irda/sir-dev.h2
-rw-r--r--drivers/net/irda/sir_dev.c8
-rw-r--r--drivers/net/iseries_veth.c12
-rw-r--r--drivers/net/ixgb/ixgb_main.c12
-rw-r--r--drivers/net/lance.c3
-rw-r--r--drivers/net/lne390.c2
-rw-r--r--drivers/net/meth.c1
-rw-r--r--drivers/net/mv643xx_eth.c13
-rw-r--r--drivers/net/mvme147.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c104
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp.h56
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp_gen_header.h2
-rw-r--r--drivers/net/myri_sbus.c1
-rw-r--r--drivers/net/ne.c2
-rw-r--r--drivers/net/ne2.c2
-rw-r--r--drivers/net/ne3210.c1
-rw-r--r--drivers/net/netconsole.c8
-rw-r--r--drivers/net/netxen/netxen_nic.h334
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c65
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h6
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c483
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h10
-rw-r--r--drivers/net/netxen/netxen_nic_init.c367
-rw-r--r--drivers/net/netxen/netxen_nic_ioctl.h8
-rw-r--r--drivers/net/netxen/netxen_nic_isr.c51
-rw-r--r--drivers/net/netxen/netxen_nic_main.c325
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c32
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h228
-rw-r--r--drivers/net/ni52.c2
-rw-r--r--drivers/net/ni65.c2
-rw-r--r--drivers/net/ns83820.c35
-rw-r--r--drivers/net/pcmcia/3c574_cs.c25
-rw-r--r--drivers/net/pcmcia/3c589_cs.c19
-rw-r--r--drivers/net/pcmcia/axnet_cs.c6
-rw-r--r--drivers/net/pcmcia/com20020_cs.c13
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c40
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c12
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c12
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c30
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c59
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c40
-rw-r--r--drivers/net/phy/fixed.c2
-rw-r--r--drivers/net/phy/phy.c9
-rw-r--r--drivers/net/plip.c38
-rw-r--r--drivers/net/pppoe.c2
-rw-r--r--drivers/net/qla3xxx.c20
-rw-r--r--drivers/net/qla3xxx.h4
-rw-r--r--drivers/net/r8169.c23
-rw-r--r--drivers/net/s2io.c16
-rw-r--r--drivers/net/s2io.h2
-rw-r--r--drivers/net/seeq8005.c2
-rw-r--r--drivers/net/sis190.c13
-rw-r--r--drivers/net/sk98lin/skge.c5
-rw-r--r--drivers/net/sk98lin/skgesirq.c2
-rw-r--r--drivers/net/skge.c17
-rw-r--r--drivers/net/skge.h152
-rw-r--r--drivers/net/sky2.c119
-rw-r--r--drivers/net/sky2.h54
-rw-r--r--drivers/net/smc-ultra.c2
-rw-r--r--drivers/net/smc-ultra32.c2
-rw-r--r--drivers/net/smc9194.c2
-rw-r--r--drivers/net/smc91x.c15
-rw-r--r--drivers/net/smc91x.h24
-rw-r--r--drivers/net/spider_net.c27
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/sun3lance.c5
-rw-r--r--drivers/net/sungem.c9
-rw-r--r--drivers/net/sunhme.c8
-rw-r--r--drivers/net/tg3.c6
-rw-r--r--drivers/net/tlan.c23
-rw-r--r--drivers/net/tlan.h1
-rw-r--r--drivers/net/tokenring/ibmtr.c2
-rw-r--r--drivers/net/tokenring/smctr.c2
-rw-r--r--drivers/net/tulip/21142.c7
-rw-r--r--drivers/net/tulip/de4x5.c8
-rw-r--r--drivers/net/tulip/timer.c7
-rw-r--r--drivers/net/tulip/tulip.h7
-rw-r--r--drivers/net/tulip/tulip_core.c3
-rw-r--r--drivers/net/typhoon.c2
-rw-r--r--drivers/net/wan/pc300_tty.c23
-rw-r--r--drivers/net/wd.c2
-rw-r--r--drivers/net/wireless/airo_cs.c19
-rw-r--r--drivers/net/wireless/atmel_cs.c11
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c20
-rw-r--r--drivers/net/wireless/hostap/hostap.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c23
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c33
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c9
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c12
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c3
-rw-r--r--drivers/net/wireless/ipw2100.c49
-rw-r--r--drivers/net/wireless/ipw2100.h10
-rw-r--r--drivers/net/wireless/ipw2200.c251
-rw-r--r--drivers/net/wireless/ipw2200.h16
-rw-r--r--drivers/net/wireless/netwave_cs.c18
-rw-r--r--drivers/net/wireless/orinoco.c28
-rw-r--r--drivers/net/wireless/orinoco_cs.c19
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c17
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h4
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c5
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c4
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h2
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c2
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c4
-rw-r--r--drivers/net/wireless/ray_cs.c30
-rw-r--r--drivers/net/wireless/spectrum_cs.c19
-rw-r--r--drivers/net/wireless/wavelan_cs.c33
-rw-r--r--drivers/net/wireless/wl3501_cs.c15
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h43
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c83
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h9
-rw-r--r--drivers/net/wireless/zd1211rw/zd_netdev.c2
-rw-r--r--drivers/oprofile/cpu_buffer.c9
-rw-r--r--drivers/oprofile/cpu_buffer.h2
-rw-r--r--drivers/parport/parport_cs.c9
-rw-r--r--drivers/pci/access.c1
-rw-r--r--drivers/pci/hotplug/shpchp.h4
-rw-r--r--drivers/pci/hotplug/shpchp_core.c2
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c19
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c8
-rw-r--r--drivers/pcmcia/at91_cf.c69
-rw-r--r--drivers/pcmcia/cs_internal.h2
-rw-r--r--drivers/pcmcia/ds.c274
-rw-r--r--drivers/pcmcia/m32r_cfc.c2
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c7
-rw-r--r--drivers/pcmcia/pd6729.c8
-rw-r--r--drivers/pcmcia/socket_sysfs.c4
-rw-r--r--drivers/ps3/Makefile1
-rw-r--r--drivers/ps3/system-bus.c362
-rw-r--r--drivers/rtc/rtc-dev.c7
-rw-r--r--drivers/s390/block/dasd.c26
-rw-r--r--drivers/s390/block/dasd_devmap.c36
-rw-r--r--drivers/s390/char/con3215.c50
-rw-r--r--drivers/s390/char/sclp_quiesce.c37
-rw-r--r--drivers/s390/cio/chsc.c82
-rw-r--r--drivers/s390/cio/cio.c128
-rw-r--r--drivers/s390/cio/css.c9
-rw-r--r--drivers/s390/cio/css.h3
-rw-r--r--drivers/s390/cio/device.c17
-rw-r--r--drivers/s390/cio/device_fsm.c27
-rw-r--r--drivers/s390/cio/device_id.c10
-rw-r--r--drivers/s390/cio/device_pgid.c30
-rw-r--r--drivers/s390/cio/device_status.c3
-rw-r--r--drivers/s390/cio/qdio.c8
-rw-r--r--drivers/s390/cio/qdio.h4
-rw-r--r--drivers/s390/crypto/ap_bus.c16
-rw-r--r--drivers/s390/net/lcs.c88
-rw-r--r--drivers/s390/net/lcs.h29
-rw-r--r--drivers/s390/net/qeth.h2
-rw-r--r--drivers/s390/net/qeth_eddp.c40
-rw-r--r--drivers/s390/net/qeth_eddp.h2
-rw-r--r--drivers/s390/net/qeth_main.c12
-rw-r--r--drivers/scsi/53c700.c7
-rw-r--r--drivers/scsi/BusLogic.c12
-rw-r--r--drivers/scsi/Kconfig59
-rw-r--r--drivers/scsi/Makefile7
-rw-r--r--drivers/scsi/NCR5380.c11
-rw-r--r--drivers/scsi/NCR5380.h4
-rw-r--r--drivers/scsi/NCR53c406a.c5
-rw-r--r--drivers/scsi/aacraid/aacraid.h4
-rw-r--r--drivers/scsi/aacraid/commsup.c23
-rw-r--r--drivers/scsi/aha152x.c4
-rw-r--r--drivers/scsi/aha1740.c10
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.h1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c9
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c121
-rw-r--r--drivers/scsi/fd_mcs.c2
-rw-r--r--drivers/scsi/hosts.c8
-rw-r--r--drivers/scsi/ibmvscsi/Makefile2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c960
-rw-r--r--drivers/scsi/imm.c12
-rw-r--r--drivers/scsi/initio.c2
-rw-r--r--drivers/scsi/ipr.c322
-rw-r--r--drivers/scsi/ipr.h83
-rw-r--r--drivers/scsi/ips.c28
-rw-r--r--drivers/scsi/ips.h9
-rw-r--r--drivers/scsi/libiscsi.c7
-rw-r--r--drivers/scsi/libsas/sas_discover.c22
-rw-r--r--drivers/scsi/libsas/sas_event.c14
-rw-r--r--drivers/scsi/libsas/sas_expander.c36
-rw-r--r--drivers/scsi/libsas/sas_init.c10
-rw-r--r--drivers/scsi/libsas/sas_internal.h12
-rw-r--r--drivers/scsi/libsas/sas_phy.c45
-rw-r--r--drivers/scsi/libsas/sas_port.c30
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c92
-rw-r--r--drivers/scsi/libsrp.c441
-rw-r--r--drivers/scsi/lpfc/lpfc.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c118
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c24
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c34
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c229
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h35
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c136
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c56
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c42
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/megaraid.c13
-rw-r--r--drivers/scsi/megaraid.h3
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c4
-rw-r--r--drivers/scsi/ncr53c8xx.c19
-rw-r--r--drivers/scsi/oktagon_esp.c6
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c7
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c5
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c6
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c11
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c12
-rw-r--r--drivers/scsi/ppa.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c94
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c66
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c8
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.c4
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h105
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h7
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h3
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c47
-rw-r--r--drivers/scsi/qla4xxx/ql4_inline.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c6
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c1
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.c70
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c124
-rw-r--r--drivers/scsi/qla4xxx/ql4_version.h7
-rw-r--r--drivers/scsi/scsi.c45
-rw-r--r--drivers/scsi/scsi_error.c33
-rw-r--r--drivers/scsi/scsi_lib.c346
-rw-r--r--drivers/scsi/scsi_priv.h3
-rw-r--r--drivers/scsi/scsi_scan.c232
-rw-r--r--drivers/scsi/scsi_sysfs.c10
-rw-r--r--drivers/scsi/scsi_tgt_if.c352
-rw-r--r--drivers/scsi/scsi_tgt_lib.c745
-rw-r--r--drivers/scsi/scsi_tgt_priv.h25
-rw-r--r--drivers/scsi/scsi_transport_fc.c60
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c8
-rw-r--r--drivers/scsi/scsi_transport_sas.c1
-rw-r--r--drivers/scsi/scsi_transport_spi.c7
-rw-r--r--drivers/scsi/scsi_wait_scan.c31
-rw-r--r--drivers/scsi/sd.c29
-rw-r--r--drivers/scsi/st.c16
-rw-r--r--drivers/scsi/stex.c130
-rw-r--r--drivers/scsi/t128.h39
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/mcfserial.c54
-rw-r--r--drivers/serial/mpc52xx_uart.c469
-rw-r--r--drivers/serial/serial_cs.c67
-rw-r--r--drivers/serial/sh-sci.c6
-rw-r--r--drivers/serial/sh-sci.h37
-rw-r--r--drivers/spi/pxa2xx_spi.c9
-rw-r--r--drivers/spi/spi_bitbang.c7
-rw-r--r--drivers/spi/spi_butterfly.c1
-rw-r--r--drivers/telephony/ixj_pcmcia.c37
-rw-r--r--drivers/usb/atm/cxacru.c12
-rw-r--r--drivers/usb/atm/speedtch.c15
-rw-r--r--drivers/usb/atm/ueagle-atm.c6
-rw-r--r--drivers/usb/class/cdc-acm.c6
-rw-r--r--drivers/usb/core/hub.c20
-rw-r--r--drivers/usb/core/message.c7
-rw-r--r--drivers/usb/core/usb.c9
-rw-r--r--drivers/usb/gadget/ether.c6
-rw-r--r--drivers/usb/host/sl811_cs.c15
-rw-r--r--drivers/usb/host/u132-hcd.c62
-rw-r--r--drivers/usb/input/hid-core.c7
-rw-r--r--drivers/usb/misc/appledisplay.c11
-rw-r--r--drivers/usb/misc/ftdi-elan.c86
-rw-r--r--drivers/usb/misc/phidgetkit.c21
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c11
-rw-r--r--drivers/usb/net/kaweth.c9
-rw-r--r--drivers/usb/net/pegasus.c6
-rw-r--r--drivers/usb/net/pegasus.h2
-rw-r--r--drivers/usb/net/usbnet.c7
-rw-r--r--drivers/usb/serial/aircable.c13
-rw-r--r--drivers/usb/serial/digi_acceleport.c14
-rw-r--r--drivers/usb/serial/ftdi_sio.c19
-rw-r--r--drivers/usb/serial/keyspan_pda.c22
-rw-r--r--drivers/usb/serial/usb-serial.c7
-rw-r--r--drivers/usb/serial/whiteheat.c15
-rw-r--r--drivers/video/console/fbcon.c6
-rw-r--r--drivers/video/platinumfb.c5
-rw-r--r--drivers/video/pxafb.c7
-rw-r--r--drivers/w1/slaves/w1_therm.c1
630 files changed, 22833 insertions, 26390 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index 4ac14dab3079..67711770b1d9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
obj-$(CONFIG_GENERIC_TIME) += clocksource/
obj-$(CONFIG_DMA_ENGINE) += dma/
+obj-$(CONFIG_PPC_PS3) += ps3/
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 578b99b71d9c..bf5b79ed3613 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/notifier.h>
+#include <linux/jiffies.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 068fe4f100b0..02b30ae6a68e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -50,6 +50,7 @@ ACPI_MODULE_NAME("osl")
struct acpi_os_dpc {
acpi_osd_exec_callback function;
void *context;
+ struct work_struct work;
};
#ifdef CONFIG_ACPI_CUSTOM_DSDT
@@ -564,12 +565,9 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
}
-static void acpi_os_execute_deferred(void *context)
+static void acpi_os_execute_deferred(struct work_struct *work)
{
- struct acpi_os_dpc *dpc = NULL;
-
-
- dpc = (struct acpi_os_dpc *)context;
+ struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
if (!dpc) {
printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
return;
@@ -602,7 +600,6 @@ acpi_status acpi_os_execute(acpi_execute_type type,
{
acpi_status status = AE_OK;
struct acpi_os_dpc *dpc;
- struct work_struct *task;
ACPI_FUNCTION_TRACE("os_queue_for_execution");
@@ -615,28 +612,22 @@ acpi_status acpi_os_execute(acpi_execute_type type,
/*
* Allocate/initialize DPC structure. Note that this memory will be
- * freed by the callee. The kernel handles the tq_struct list in a
+ * freed by the callee. The kernel handles the work_struct list in a
* way that allows us to also free its memory inside the callee.
* Because we may want to schedule several tasks with different
* parameters we can't use the approach some kernel code uses of
- * having a static tq_struct.
- * We can save time and code by allocating the DPC and tq_structs
- * from the same memory.
+ * having a static work_struct.
*/
- dpc =
- kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct),
- GFP_ATOMIC);
+ dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
if (!dpc)
return_ACPI_STATUS(AE_NO_MEMORY);
dpc->function = function;
dpc->context = context;
- task = (void *)(dpc + 1);
- INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
-
- if (!queue_work(kacpid_wq, task)) {
+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+ if (!queue_work(kacpid_wq, &dpc->work)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Call to queue_work() failed.\n"));
kfree(dpc);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 03f6338acc8f..984ab284382a 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -328,6 +328,15 @@ config PATA_TRIFLEX
If unsure, say N.
+config PATA_MARVELL
+ tristate "Marvell PATA support via legacy mode"
+ depends on PCI
+ help
+ This option enables limited support for the Marvell 88SE6145 ATA
+ controller.
+
+ If unsure, say N.
+
config PATA_MPIIX
tristate "Intel PATA MPIIX support"
depends on PCI
@@ -483,6 +492,32 @@ config PATA_WINBOND
If unsure, say N.
+config PATA_WINBOND_VLB
+ tristate "Winbond W83759A VLB PATA support (Experimental)"
+ depends on ISA && EXPERIMENTAL
+ help
+ Support for the Winbond W83759A controller on Vesa Local Bus
+ systems.
+
+config PATA_PLATFORM
+ tristate "Generic platform device PATA support"
+ depends on EMBEDDED
+ help
+ This option enables support for generic directly connected ATA
+ devices commonly found on embedded systems.
+
+ If unsure, say N.
+
+config PATA_IXP4XX_CF
+ tristate "IXP4XX Compact Flash support"
+ depends on ARCH_IXP4XX
+ help
+ This option enables support for a Compact Flash connected on
+ the ixp4xx expansion bus. This driver had been written for
+ Loft/Avila boards in mind but can work with others.
+
+ If unsure, say N.
+
endif
endmenu
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 72243a677f9b..bc3d81ae757e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
+obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
@@ -51,8 +52,11 @@ obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
obj-$(CONFIG_PATA_VIA) += pata_via.o
obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
+obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
obj-$(CONFIG_PATA_SIS) += pata_sis.o
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
+obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
+obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index bddb14e91d3c..f36da488a2c1 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -53,6 +53,7 @@
enum {
AHCI_PCI_BAR = 5,
+ AHCI_MAX_PORTS = 32,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_USE_CLUSTERING = 0,
@@ -77,8 +78,9 @@ enum {
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
board_ahci = 0,
- board_ahci_vt8251 = 1,
- board_ahci_ign_iferr = 2,
+ board_ahci_pi = 1,
+ board_ahci_vt8251 = 2,
+ board_ahci_ign_iferr = 3,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -167,9 +169,9 @@ enum {
AHCI_FLAG_MSI = (1 << 0),
/* ap->flags bits */
- AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24),
- AHCI_FLAG_NO_NCQ = (1 << 25),
- AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */
+ AHCI_FLAG_NO_NCQ = (1 << 24),
+ AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
+ AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
};
struct ahci_cmd_hdr {
@@ -216,6 +218,7 @@ static u8 ahci_check_status(struct ata_port *ap);
static void ahci_freeze(struct ata_port *ap);
static void ahci_thaw(struct ata_port *ap);
static void ahci_error_handler(struct ata_port *ap);
+static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
static int ahci_port_resume(struct ata_port *ap);
@@ -275,6 +278,37 @@ static const struct ata_port_operations ahci_ops = {
.port_stop = ahci_port_stop,
};
+static const struct ata_port_operations ahci_vt8251_ops = {
+ .port_disable = ata_port_disable,
+
+ .check_status = ahci_check_status,
+ .check_altstatus = ahci_check_status,
+ .dev_select = ata_noop_dev_select,
+
+ .tf_read = ahci_tf_read,
+
+ .qc_prep = ahci_qc_prep,
+ .qc_issue = ahci_qc_issue,
+
+ .irq_handler = ahci_interrupt,
+ .irq_clear = ahci_irq_clear,
+
+ .scr_read = ahci_scr_read,
+ .scr_write = ahci_scr_write,
+
+ .freeze = ahci_freeze,
+ .thaw = ahci_thaw,
+
+ .error_handler = ahci_vt8251_error_handler,
+ .post_internal_cmd = ahci_post_internal_cmd,
+
+ .port_suspend = ahci_port_suspend,
+ .port_resume = ahci_port_resume,
+
+ .port_start = ahci_port_start,
+ .port_stop = ahci_port_stop,
+};
+
static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
{
@@ -286,16 +320,26 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
+ /* board_ahci_pi */
+ {
+ .sht = &ahci_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &ahci_ops,
+ },
/* board_ahci_vt8251 */
{
.sht = &ahci_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_SKIP_D2H_BSY |
- AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ,
+ ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &ahci_ops,
+ .port_ops = &ahci_vt8251_ops,
},
/* board_ahci_ign_iferr */
{
@@ -322,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
- { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
- { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
- { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
- { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
- { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
- { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
+ { PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
+ { PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
+ { PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
+ { PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
+ { PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
/* JMicron */
{ PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
@@ -372,6 +416,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
+ /* Generic, PCI class code for AHCI */
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ 0x010601, 0xffffff, board_ahci },
+
{ } /* terminate list */
};
@@ -386,6 +434,11 @@ static struct pci_driver ahci_pci_driver = {
};
+static inline int ahci_nr_ports(u32 cap)
+{
+ return (cap & 0x1f) + 1;
+}
+
static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
{
return base + 0x100 + (port * 0x80);
@@ -559,9 +612,6 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
{
- /* power up */
- ahci_power_up(port_mmio, cap);
-
/* enable FIS reception */
ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
@@ -587,19 +637,17 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
return rc;
}
- /* put device into slumber mode */
- ahci_power_down(port_mmio, cap);
-
return 0;
}
static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
{
- u32 cap_save, tmp;
+ u32 cap_save, impl_save, tmp;
cap_save = readl(mmio + HOST_CAP);
cap_save &= ( (1<<28) | (1<<17) );
cap_save |= (1 << 27);
+ impl_save = readl(mmio + HOST_PORTS_IMPL);
/* global controller reset */
tmp = readl(mmio + HOST_CTL);
@@ -620,10 +668,21 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
return -EIO;
}
+ /* turn on AHCI mode */
writel(HOST_AHCI_EN, mmio + HOST_CTL);
(void) readl(mmio + HOST_CTL); /* flush */
+
+ /* These write-once registers are normally cleared on reset.
+ * Restore BIOS values... which we HOPE were present before
+ * reset.
+ */
+ if (!impl_save) {
+ impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
+ }
writel(cap_save, mmio + HOST_CAP);
- writel(0xf, mmio + HOST_PORTS_IMPL);
+ writel(impl_save, mmio + HOST_PORTS_IMPL);
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
@@ -639,7 +698,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
}
static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
- int n_ports, u32 cap)
+ int n_ports, unsigned int port_flags,
+ struct ahci_host_priv *hpriv)
{
int i, rc;
u32 tmp;
@@ -648,13 +708,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
void __iomem *port_mmio = ahci_port_base(mmio, i);
const char *emsg = NULL;
-#if 0 /* BIOSen initialize this incorrectly */
- if (!(hpriv->port_map & (1 << i)))
+ if ((port_flags & AHCI_FLAG_HONOR_PI) &&
+ !(hpriv->port_map & (1 << i)))
continue;
-#endif
/* make sure port is not active */
- rc = ahci_deinit_port(port_mmio, cap, &emsg);
+ rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
if (rc)
dev_printk(KERN_WARNING, &pdev->dev,
"%s (%d)\n", emsg, rc);
@@ -729,17 +788,6 @@ static int ahci_clo(struct ata_port *ap)
return 0;
}
-static int ahci_prereset(struct ata_port *ap)
-{
- if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) &&
- (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) {
- /* ATA_BUSY hasn't cleared, so send a CLO */
- ahci_clo(ap);
- }
-
- return ata_std_prereset(ap);
-}
-
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_port_priv *pp = ap->private_data;
@@ -877,6 +925,31 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
return rc;
}
+static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
+{
+ void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ int rc;
+
+ DPRINTK("ENTER\n");
+
+ ahci_stop_engine(port_mmio);
+
+ rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
+
+ /* vt8251 needs SError cleared for the port to operate */
+ ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
+
+ ahci_start_engine(port_mmio);
+
+ DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+
+ /* vt8251 doesn't clear BSY on signature FIS reception,
+ * request follow-up softreset.
+ */
+ return rc ?: -EAGAIN;
+}
+
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
{
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -1196,7 +1269,23 @@ static void ahci_error_handler(struct ata_port *ap)
}
/* perform recovery */
- ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset,
+ ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset,
+ ahci_postreset);
+}
+
+static void ahci_vt8251_error_handler(struct ata_port *ap)
+{
+ void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+
+ if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
+ /* restart engine */
+ ahci_stop_engine(port_mmio);
+ ahci_start_engine(port_mmio);
+ }
+
+ /* perform recovery */
+ ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset,
ahci_postreset);
}
@@ -1226,7 +1315,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
int rc;
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
- if (rc) {
+ if (rc == 0)
+ ahci_power_down(port_mmio, hpriv->cap);
+ else {
ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
ahci_init_port(port_mmio, hpriv->cap,
pp->cmd_slot_dma, pp->rx_fis_dma);
@@ -1242,6 +1333,7 @@ static int ahci_port_resume(struct ata_port *ap)
void __iomem *mmio = ap->host->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ ahci_power_up(port_mmio, hpriv->cap);
ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
return 0;
@@ -1281,7 +1373,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
if (rc)
return rc;
- ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap);
+ ahci_init_controller(mmio, pdev, host->n_ports,
+ host->ports[0]->flags, hpriv);
}
ata_host_resume(host);
@@ -1347,6 +1440,9 @@ static int ahci_port_start(struct ata_port *ap)
ap->private_data = pp;
+ /* power up port */
+ ahci_power_up(port_mmio, hpriv->cap);
+
/* initialize port */
ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
@@ -1393,7 +1489,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
void __iomem *mmio = probe_ent->mmio_base;
- unsigned int i, using_dac;
+ unsigned int i, cap_n_ports, using_dac;
int rc;
rc = ahci_reset_controller(mmio, pdev);
@@ -1402,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
hpriv->cap = readl(mmio + HOST_CAP);
hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
- probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
+ cap_n_ports = ahci_nr_ports(hpriv->cap);
VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
- hpriv->cap, hpriv->port_map, probe_ent->n_ports);
+ hpriv->cap, hpriv->port_map, cap_n_ports);
+
+ if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
+ unsigned int n_ports = cap_n_ports;
+ u32 port_map = hpriv->port_map;
+ int max_port = 0;
+
+ for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
+ if (port_map & (1 << i)) {
+ n_ports--;
+ port_map &= ~(1 << i);
+ max_port = i;
+ } else
+ probe_ent->dummy_port_mask |= 1 << i;
+ }
+
+ if (n_ports || port_map)
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "nr_ports (%u) and implemented port map "
+ "(0x%x) don't match\n",
+ cap_n_ports, hpriv->port_map);
+
+ probe_ent->n_ports = max_port + 1;
+ } else
+ probe_ent->n_ports = cap_n_ports;
using_dac = hpriv->cap & HOST_CAP_64;
if (using_dac &&
@@ -1437,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
for (i = 0; i < probe_ent->n_ports; i++)
ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
- ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap);
+ ahci_init_controller(mmio, pdev, probe_ent->n_ports,
+ probe_ent->port_flags, hpriv);
pci_set_master(pdev);
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 4a80ff9312b8..908751d27e76 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -26,7 +26,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_generic"
-#define DRV_VERSION "0.2.6"
+#define DRV_VERSION "0.2.10"
/*
* A generic parallel ATA driver using libata
@@ -109,7 +109,6 @@ static struct scsi_host_template generic_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -118,6 +117,8 @@ static struct scsi_host_template generic_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations generic_port_ops = {
@@ -226,12 +227,14 @@ static struct pci_driver ata_generic_pci_driver = {
.name = DRV_NAME,
.id_table = ata_generic,
.probe = ata_generic_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init ata_generic_init(void)
{
- return pci_module_init(&ata_generic_pci_driver);
+ return pci_register_driver(&ata_generic_pci_driver);
}
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 720174d628fa..c7de0bb1591f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -40,7 +40,7 @@
* Documentation
* Publically available from Intel web site. Errata documentation
* is also publically available. As an aide to anyone hacking on this
- * driver the list of errata that are relevant is below.going back to
+ * driver the list of errata that are relevant is below, going back to
* PIIX4. Older device documentation is now a bit tricky to find.
*
* The chipsets all follow very much the same design. The orginal Triton
@@ -93,7 +93,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "2.00ac6"
+#define DRV_VERSION "2.00ac7"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -101,11 +101,13 @@ enum {
ICH5_PCS = 0x92, /* port control and status */
PIIX_SCC = 0x0A, /* sub-class code register */
- PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */
PIIX_FLAG_SCR = (1 << 26), /* SCR available */
PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
+ PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
+ PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
+
/* combined mode. if set, PATA is channel 0.
* if clear, PATA is channel 1.
*/
@@ -122,11 +124,10 @@ enum {
ich_pata_100 = 3, /* ICH up to UDMA 100 */
ich_pata_133 = 4, /* ICH up to UDMA 133 */
ich5_sata = 5,
- esb_sata = 6,
- ich6_sata = 7,
- ich6_sata_ahci = 8,
- ich6m_sata_ahci = 9,
- ich8_sata_ahci = 10,
+ ich6_sata = 6,
+ ich6_sata_ahci = 7,
+ ich6m_sata_ahci = 8,
+ ich8_sata_ahci = 9,
/* constants for mapping table */
P0 = 0, /* port 0 */
@@ -143,13 +144,11 @@ enum {
struct piix_map_db {
const u32 mask;
const u16 port_enable;
- const int present_shift;
const int map[][4];
};
struct piix_host_priv {
const int *map;
- const struct piix_map_db *map_db;
};
static int piix_init_one (struct pci_dev *pdev,
@@ -214,9 +213,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* 82801EB (ICH5) */
{ 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
/* 6300ESB (ICH5 variant with broken PCS present bits) */
- { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+ { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
/* 6300ESB pretending RAID */
- { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+ { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
/* 82801FB/FW (ICH6/ICH6W) */
{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
/* 82801FR/FRW (ICH6R/ICH6RW) */
@@ -367,7 +366,6 @@ static const struct ata_port_operations piix_sata_ops = {
static const struct piix_map_db ich5_map_db = {
.mask = 0x7,
.port_enable = 0x3,
- .present_shift = 4,
.map = {
/* PM PS SM SS MAP */
{ P0, NA, P1, NA }, /* 000b */
@@ -384,7 +382,6 @@ static const struct piix_map_db ich5_map_db = {
static const struct piix_map_db ich6_map_db = {
.mask = 0x3,
.port_enable = 0xf,
- .present_shift = 4,
.map = {
/* PM PS SM SS MAP */
{ P0, P2, P1, P3 }, /* 00b */
@@ -397,7 +394,6 @@ static const struct piix_map_db ich6_map_db = {
static const struct piix_map_db ich6m_map_db = {
.mask = 0x3,
.port_enable = 0x5,
- .present_shift = 4,
/* Map 01b isn't specified in the doc but some notebooks use
* it anyway. MAP 01b have been spotted on both ICH6M and
@@ -415,7 +411,6 @@ static const struct piix_map_db ich6m_map_db = {
static const struct piix_map_db ich8_map_db = {
.mask = 0x3,
.port_enable = 0x3,
- .present_shift = 8,
.map = {
/* PM PS SM SS MAP */
{ P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
@@ -427,7 +422,6 @@ static const struct piix_map_db ich8_map_db = {
static const struct piix_map_db *piix_map_db_table[] = {
[ich5_sata] = &ich5_map_db,
- [esb_sata] = &ich5_map_db,
[ich6_sata] = &ich6_map_db,
[ich6_sata_ahci] = &ich6_map_db,
[ich6m_sata_ahci] = &ich6m_map_db,
@@ -438,7 +432,7 @@ static struct ata_port_info piix_port_info[] = {
/* piix_pata_33: 0: PIIX3 or 4 at 33MHz */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = PIIX_PATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
.udma_mask = ATA_UDMA_MASK_40C,
@@ -448,7 +442,7 @@ static struct ata_port_info piix_port_info[] = {
/* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS,
+ .flags = PIIX_PATA_FLAGS,
.pio_mask = 0x1f, /* pio 0-4 */
.mwdma_mask = 0x06, /* Check: maybe 0x07 */
.udma_mask = ATA_UDMA2, /* UDMA33 */
@@ -457,7 +451,7 @@ static struct ata_port_info piix_port_info[] = {
/* ich_pata_66: 2 ICH controllers up to 66MHz */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS,
+ .flags = PIIX_PATA_FLAGS,
.pio_mask = 0x1f, /* pio 0-4 */
.mwdma_mask = 0x06, /* MWDMA0 is broken on chip */
.udma_mask = ATA_UDMA4,
@@ -467,7 +461,7 @@ static struct ata_port_info piix_port_info[] = {
/* ich_pata_100: 3 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
+ .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x06, /* mwdma1-2 */
.udma_mask = ATA_UDMA5, /* udma0-5 */
@@ -477,7 +471,7 @@ static struct ata_port_info piix_port_info[] = {
/* ich_pata_133: 4 ICH with full UDMA6 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
+ .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
.pio_mask = 0x1f, /* pio 0-4 */
.mwdma_mask = 0x06, /* Check: maybe 0x07 */
.udma_mask = ATA_UDMA6, /* UDMA133 */
@@ -487,41 +481,27 @@ static struct ata_port_info piix_port_info[] = {
/* ich5_sata: 5 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR |
- PIIX_FLAG_IGNORE_PCS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
- .port_ops = &piix_sata_ops,
- },
-
- /* i6300esb_sata: 6 */
- {
- .sht = &piix_sht,
- .flags = ATA_FLAG_SATA |
- PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
+ .flags = PIIX_SATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
},
- /* ich6_sata: 7 */
+ /* ich6_sata: 6 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SATA |
- PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
},
- /* ich6_sata_ahci: 8 */
+ /* ich6_sata_ahci: 7 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SATA |
- PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -529,11 +509,10 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
- /* ich6m_sata_ahci: 9 */
+ /* ich6m_sata_ahci: 8 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SATA |
- PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -541,11 +520,10 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
- /* ich8_sata_ahci: 10 */
+ /* ich8_sata_ahci: 9 */
{
.sht = &piix_sht,
- .flags = ATA_FLAG_SATA |
- PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -566,10 +544,22 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static int force_pcs = 0;
-module_param(force_pcs, int, 0444);
-MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
- "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");
+struct ich_laptop {
+ u16 device;
+ u16 subvendor;
+ u16 subdevice;
+};
+
+/*
+ * List of laptops that use short cables rather than 80 wire
+ */
+
+static const struct ich_laptop ich_laptop[] = {
+ /* devid, subvendor, subdev */
+ { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
+ /* end marker */
+ { 0, }
+};
/**
* piix_pata_cbl_detect - Probe host controller cable detect info
@@ -585,12 +575,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
static void ich_pata_cbl_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ const struct ich_laptop *lap = &ich_laptop[0];
u8 tmp, mask;
/* no 80c support in host controller? */
if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
goto cbl40;
+ /* Check for specials - Acer Aspire 5602WLMi */
+ while (lap->device) {
+ if (lap->device == pdev->device &&
+ lap->subvendor == pdev->subsystem_vendor &&
+ lap->subdevice == pdev->subsystem_device) {
+ ap->cbl = ATA_CBL_PATA40_SHORT;
+ return;
+ }
+ lap++;
+ }
+
/* check BIOS cable detect results */
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
@@ -659,84 +661,9 @@ static void ich_pata_error_handler(struct ata_port *ap)
ata_std_postreset);
}
-/**
- * piix_sata_present_mask - determine present mask for SATA host controller
- * @ap: Target port
- *
- * Reads SATA PCI device's PCI config register Port Configuration
- * and Status (PCS) to determine port and device availability.
- *
- * LOCKING:
- * None (inherited from caller).
- *
- * RETURNS:
- * determined present_mask
- */
-static unsigned int piix_sata_present_mask(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- struct piix_host_priv *hpriv = ap->host->private_data;
- const unsigned int *map = hpriv->map;
- int base = 2 * ap->port_no;
- unsigned int present_mask = 0;
- int port, i;
- u16 pcs;
-
- pci_read_config_word(pdev, ICH5_PCS, &pcs);
- DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
-
- for (i = 0; i < 2; i++) {
- port = map[base + i];
- if (port < 0)
- continue;
- if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
- (pcs & 1 << (hpriv->map_db->present_shift + port)))
- present_mask |= 1 << i;
- }
-
- DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
- ap->id, pcs, present_mask);
-
- return present_mask;
-}
-
-/**
- * piix_sata_softreset - reset SATA host port via ATA SRST
- * @ap: port to reset
- * @classes: resulting classes of attached devices
- *
- * Reset SATA host port via ATA SRST. On controllers with
- * reliable PCS present bits, the bits are used to determine
- * device presence.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
-{
- unsigned int present_mask;
- int i, rc;
-
- present_mask = piix_sata_present_mask(ap);
-
- rc = ata_std_softreset(ap, classes);
- if (rc)
- return rc;
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- if (!(present_mask & (1 << i)))
- classes[i] = ATA_DEV_NONE;
- }
-
- return 0;
-}
-
static void piix_sata_error_handler(struct ata_port *ap)
{
- ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL,
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
ata_std_postreset);
}
@@ -1051,18 +978,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev,
pci_write_config_word(pdev, ICH5_PCS, new_pcs);
msleep(150);
}
-
- if (force_pcs == 1) {
- dev_printk(KERN_INFO, &pdev->dev,
- "force ignoring PCS (0x%x)\n", new_pcs);
- pinfo[0].flags |= PIIX_FLAG_IGNORE_PCS;
- pinfo[1].flags |= PIIX_FLAG_IGNORE_PCS;
- } else if (force_pcs == 2) {
- dev_printk(KERN_INFO, &pdev->dev,
- "force honoring PCS (0x%x)\n", new_pcs);
- pinfo[0].flags &= ~PIIX_FLAG_IGNORE_PCS;
- pinfo[1].flags &= ~PIIX_FLAG_IGNORE_PCS;
- }
}
static void __devinit piix_init_sata_map(struct pci_dev *pdev,
@@ -1112,7 +1027,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
"invalid MAP value %u\n", map_value);
hpriv->map = map;
- hpriv->map_db = map_db;
}
/**
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 915a55a6cc14..8816e30fb7a4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -199,7 +199,8 @@ static const u8 ata_rw_cmds[] = {
/**
* ata_rwcmd_protocol - set taskfile r/w commands and protocol
- * @qc: command to examine and configure
+ * @tf: command to examine and configure
+ * @dev: device tf belongs to
*
* Examine the device configuration and tf->flags to calculate
* the proper read/write commands and protocol to use.
@@ -207,10 +208,8 @@ static const u8 ata_rw_cmds[] = {
* LOCKING:
* caller.
*/
-int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
+static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev)
{
- struct ata_taskfile *tf = &qc->tf;
- struct ata_device *dev = qc->dev;
u8 cmd;
int index, fua, lba48, write;
@@ -222,7 +221,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
if (dev->flags & ATA_DFLAG_PIO) {
tf->protocol = ATA_PROT_PIO;
index = dev->multi_count ? 0 : 8;
- } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
+ } else if (lba48 && (dev->ap->flags & ATA_FLAG_PIO_LBA48)) {
/* Unable to use DMA due to host limitation */
tf->protocol = ATA_PROT_PIO;
index = dev->multi_count ? 0 : 8;
@@ -240,6 +239,174 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
}
/**
+ * ata_tf_read_block - Read block address from ATA taskfile
+ * @tf: ATA taskfile of interest
+ * @dev: ATA device @tf belongs to
+ *
+ * LOCKING:
+ * None.
+ *
+ * Read block address from @tf. This function can handle all
+ * three address formats - LBA, LBA48 and CHS. tf->protocol and
+ * flags select the address format to use.
+ *
+ * RETURNS:
+ * Block address read from @tf.
+ */
+u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+{
+ u64 block = 0;
+
+ if (tf->flags & ATA_TFLAG_LBA) {
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ block |= (u64)tf->hob_lbah << 40;
+ block |= (u64)tf->hob_lbam << 32;
+ block |= tf->hob_lbal << 24;
+ } else
+ block |= (tf->device & 0xf) << 24;
+
+ block |= tf->lbah << 16;
+ block |= tf->lbam << 8;
+ block |= tf->lbal;
+ } else {
+ u32 cyl, head, sect;
+
+ cyl = tf->lbam | (tf->lbah << 8);
+ head = tf->device & 0xf;
+ sect = tf->lbal;
+
+ block = (cyl * dev->heads + head) * dev->sectors + sect;
+ }
+
+ return block;
+}
+
+/**
+ * ata_build_rw_tf - Build ATA taskfile for given read/write request
+ * @tf: Target ATA taskfile
+ * @dev: ATA device @tf belongs to
+ * @block: Block address
+ * @n_block: Number of blocks
+ * @tf_flags: RW/FUA etc...
+ * @tag: tag
+ *
+ * LOCKING:
+ * None.
+ *
+ * Build ATA taskfile @tf for read/write request described by
+ * @block, @n_block, @tf_flags and @tag on @dev.
+ *
+ * RETURNS:
+ *
+ * 0 on success, -ERANGE if the request is too large for @dev,
+ * -EINVAL if the request is invalid.
+ */
+int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
+ u64 block, u32 n_block, unsigned int tf_flags,
+ unsigned int tag)
+{
+ tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf->flags |= tf_flags;
+
+ if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
+ ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ &&
+ likely(tag != ATA_TAG_INTERNAL)) {
+ /* yay, NCQ */
+ if (!lba_48_ok(block, n_block))
+ return -ERANGE;
+
+ tf->protocol = ATA_PROT_NCQ;
+ tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
+
+ if (tf->flags & ATA_TFLAG_WRITE)
+ tf->command = ATA_CMD_FPDMA_WRITE;
+ else
+ tf->command = ATA_CMD_FPDMA_READ;
+
+ tf->nsect = tag << 3;
+ tf->hob_feature = (n_block >> 8) & 0xff;
+ tf->feature = n_block & 0xff;
+
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
+
+ tf->device = 1 << 6;
+ if (tf->flags & ATA_TFLAG_FUA)
+ tf->device |= 1 << 7;
+ } else if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
+
+ if (lba_28_ok(block, n_block)) {
+ /* use LBA28 */
+ tf->device |= (block >> 24) & 0xf;
+ } else if (lba_48_ok(block, n_block)) {
+ if (!(dev->flags & ATA_DFLAG_LBA48))
+ return -ERANGE;
+
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
+
+ tf->hob_nsect = (n_block >> 8) & 0xff;
+
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ } else
+ /* request too large even for LBA48 */
+ return -ERANGE;
+
+ if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
+ return -EINVAL;
+
+ tf->nsect = n_block & 0xff;
+
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
+
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ u32 sect, head, cyl, track;
+
+ /* The request -may- be too large for CHS addressing. */
+ if (!lba_28_ok(block, n_block))
+ return -ERANGE;
+
+ if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
+ return -EINVAL;
+
+ /* Convert LBA to CHS */
+ track = (u32)block / dev->sectors;
+ cyl = track / dev->heads;
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+ DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+ (u32)block, track, cyl, head, sect);
+
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+ Sector: 1-255*/
+ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
+ return -ERANGE;
+
+ tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+ tf->lbal = sect;
+ tf->lbam = cyl;
+ tf->lbah = cyl >> 8;
+ tf->device |= head;
+ }
+
+ return 0;
+}
+
+/**
* ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
* @pio_mask: pio_mask
* @mwdma_mask: mwdma_mask
@@ -914,7 +1081,7 @@ static unsigned int ata_id_xfermask(const u16 *id)
* ata_port_queue_task - Queue port_task
* @ap: The ata_port to queue port_task for
* @fn: workqueue function to be scheduled
- * @data: data value to pass to workqueue function
+ * @data: data for @fn to use
* @delay: delay time for workqueue function
*
* Schedule @fn(@data) for execution after @delay jiffies using
@@ -929,7 +1096,7 @@ static unsigned int ata_id_xfermask(const u16 *id)
* LOCKING:
* Inherited from caller.
*/
-void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data,
+void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
unsigned long delay)
{
int rc;
@@ -937,12 +1104,10 @@ void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data,
if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK)
return;
- PREPARE_WORK(&ap->port_task, fn, data);
+ PREPARE_DELAYED_WORK(&ap->port_task, fn);
+ ap->port_task_data = data;
- if (!delay)
- rc = queue_work(ata_wq, &ap->port_task);
- else
- rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
+ rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
/* rc == 0 means that another user is using port task */
WARN_ON(rc == 0);
@@ -999,13 +1164,13 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
}
/**
- * ata_exec_internal - execute libata internal command
+ * ata_exec_internal_sg - execute libata internal command
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
* @dma_dir: Data tranfer direction of the command
- * @buf: Data buffer of the command
- * @buflen: Length of data buffer
+ * @sg: sg list for the data buffer of the command
+ * @n_elem: Number of sg entries
*
* Executes libata internal command with timeout. @tf contains
* command on entry and result on return. Timeout and error
@@ -1019,9 +1184,10 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* RETURNS:
* Zero on success, AC_ERR_* mask on failure
*/
-unsigned ata_exec_internal(struct ata_device *dev,
- struct ata_taskfile *tf, const u8 *cdb,
- int dma_dir, void *buf, unsigned int buflen)
+unsigned ata_exec_internal_sg(struct ata_device *dev,
+ struct ata_taskfile *tf, const u8 *cdb,
+ int dma_dir, struct scatterlist *sg,
+ unsigned int n_elem)
{
struct ata_port *ap = dev->ap;
u8 command = tf->command;
@@ -1077,7 +1243,12 @@ unsigned ata_exec_internal(struct ata_device *dev,
qc->flags |= ATA_QCFLAG_RESULT_TF;
qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) {
- ata_sg_init_one(qc, buf, buflen);
+ unsigned int i, buflen = 0;
+
+ for (i = 0; i < n_elem; i++)
+ buflen += sg[i].length;
+
+ ata_sg_init(qc, sg, n_elem);
qc->nsect = buflen / ATA_SECT_SIZE;
}
@@ -1161,6 +1332,35 @@ unsigned ata_exec_internal(struct ata_device *dev,
}
/**
+ * ata_exec_internal_sg - execute libata internal command
+ * @dev: Device to which the command is sent
+ * @tf: Taskfile registers for the command and the result
+ * @cdb: CDB for packet command
+ * @dma_dir: Data tranfer direction of the command
+ * @buf: Data buffer of the command
+ * @buflen: Length of data buffer
+ *
+ * Wrapper around ata_exec_internal_sg() which takes simple
+ * buffer instead of sg list.
+ *
+ * LOCKING:
+ * None. Should be called with kernel context, might sleep.
+ *
+ * RETURNS:
+ * Zero on success, AC_ERR_* mask on failure
+ */
+unsigned ata_exec_internal(struct ata_device *dev,
+ struct ata_taskfile *tf, const u8 *cdb,
+ int dma_dir, void *buf, unsigned int buflen)
+{
+ struct scatterlist sg;
+
+ sg_init_one(&sg, buf, buflen);
+
+ return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
+}
+
+/**
* ata_do_simple_cmd - execute simple internal command
* @dev: Device to which the command is sent
* @cmd: Opcode to execute
@@ -1224,7 +1424,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
* ata_dev_read_id - Read ID data from the specified device
* @dev: target device
* @p_class: pointer to class of the target device (may be changed)
- * @post_reset: is this read ID post-reset?
+ * @flags: ATA_READID_* flags
* @id: buffer to read IDENTIFY data into
*
* Read ID data from the specified device. ATA_CMD_ID_ATA is
@@ -1239,7 +1439,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
* 0 on success, -errno otherwise.
*/
int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
- int post_reset, u16 *id)
+ unsigned int flags, u16 *id)
{
struct ata_port *ap = dev->ap;
unsigned int class = *p_class;
@@ -1271,10 +1471,17 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
}
tf.protocol = ATA_PROT_PIO;
+ tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS);
if (err_mask) {
+ if (err_mask & AC_ERR_NODEV_HINT) {
+ DPRINTK("ata%u.%d: NODEV after polling detection\n",
+ ap->id, dev->devno);
+ return -ENOENT;
+ }
+
rc = -EIO;
reason = "I/O error";
goto err_out;
@@ -1294,7 +1501,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
goto err_out;
}
- if (post_reset && class == ATA_DEV_ATA) {
+ if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
/*
* The exact sequence expected by certain pre-ATA4 drives is:
* SRST RESET
@@ -1314,7 +1521,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
/* current CHS translation info (id[53-58]) might be
* changed. reread the identify device info.
*/
- post_reset = 0;
+ flags &= ~ATA_READID_POSTRESET;
goto retry;
}
}
@@ -1345,7 +1552,10 @@ static void ata_dev_config_ncq(struct ata_device *dev,
desc[0] = '\0';
return;
}
-
+ if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+ snprintf(desc, desc_sz, "NCQ (not used)");
+ return;
+ }
if (ap->flags & ATA_FLAG_NCQ) {
hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
dev->flags |= ATA_DFLAG_NCQ;
@@ -1374,7 +1584,6 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
* @dev: Target device to configure
- * @print_info: Enable device info printout
*
* Configure @dev according to @dev->id. Generic and low-level
* driver specific fixups are also applied.
@@ -1385,9 +1594,10 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
* RETURNS:
* 0 on success, -errno otherwise
*/
-int ata_dev_configure(struct ata_device *dev, int print_info)
+int ata_dev_configure(struct ata_device *dev)
{
struct ata_port *ap = dev->ap;
+ int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
const u16 *id = dev->id;
unsigned int xfer_mask;
char revbuf[7]; /* XYZ-99\0 */
@@ -1454,6 +1664,10 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
if (ata_id_has_lba48(id)) {
dev->flags |= ATA_DFLAG_LBA48;
lba_desc = "LBA48";
+
+ if (dev->n_sectors >= (1UL << 28) &&
+ ata_id_has_flush_ext(id))
+ dev->flags |= ATA_DFLAG_FLUSH_EXT;
}
/* config NCQ */
@@ -1530,6 +1744,11 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
cdb_intr_string);
}
+ /* determine max_sectors */
+ dev->max_sectors = ATA_MAX_SECTORS;
+ if (dev->flags & ATA_DFLAG_LBA48)
+ dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
/* Let the user know. We don't want to disallow opens for
rescue purposes, or in case the vendor is just a blithering
@@ -1631,11 +1850,14 @@ int ata_bus_probe(struct ata_port *ap)
if (!ata_dev_enabled(dev))
continue;
- rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
+ rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,
+ dev->id);
if (rc)
goto fail;
- rc = ata_dev_configure(dev, 1);
+ ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
+ rc = ata_dev_configure(dev);
+ ap->eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
if (rc)
goto fail;
}
@@ -2153,6 +2375,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
static int ata_dev_set_mode(struct ata_device *dev)
{
+ struct ata_eh_context *ehc = &dev->ap->eh_context;
unsigned int err_mask;
int rc;
@@ -2167,7 +2390,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
return -EIO;
}
+ ehc->i.flags |= ATA_EHI_POST_SETMODE;
rc = ata_dev_revalidate(dev, 0);
+ ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
if (rc)
return rc;
@@ -2325,11 +2550,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
* Sleep until ATA Status register bit BSY clears,
* or a timeout occurs.
*
- * LOCKING: None.
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
*/
-
-unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat, unsigned long tmout)
+int ata_busy_sleep(struct ata_port *ap,
+ unsigned long tmout_pat, unsigned long tmout)
{
unsigned long timer_start, timeout;
u8 status;
@@ -2337,27 +2565,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
status = ata_busy_wait(ap, ATA_BUSY, 300);
timer_start = jiffies;
timeout = timer_start + tmout_pat;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_busy_wait(ap, ATA_BUSY, 3);
}
- if (status & ATA_BUSY)
+ if (status != 0xff && (status & ATA_BUSY))
ata_port_printk(ap, KERN_WARNING,
"port is slow to respond, please be patient "
"(Status 0x%x)\n", status);
timeout = timer_start + tmout;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_chk_status(ap);
}
+ if (status == 0xff)
+ return -ENODEV;
+
if (status & ATA_BUSY) {
ata_port_printk(ap, KERN_ERR, "port failed to respond "
"(%lu secs, Status 0x%x)\n",
tmout / HZ, status);
- return 1;
+ return -EBUSY;
}
return 0;
@@ -2448,10 +2681,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
* the bus shows 0xFF because the odd clown forgets the D7
* pulldown resistor.
*/
- if (ata_check_status(ap) == 0xFF) {
- ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
- return AC_ERR_OTHER;
- }
+ if (ata_check_status(ap) == 0xFF)
+ return 0;
ata_bus_post_reset(ap, devmask);
@@ -2777,9 +3008,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
}
/**
- * sata_std_hardreset - reset host port via SATA phy reset
+ * sata_port_hardreset - reset port via SATA phy reset
* @ap: port to reset
- * @class: resulting class of attached device
+ * @timing: timing parameters { interval, duratinon, timeout } in msec
*
* SATA phy-reset host port using DET bits of SControl register.
*
@@ -2789,10 +3020,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
{
- struct ata_eh_context *ehc = &ap->eh_context;
- const unsigned long *timing = sata_ehc_deb_timing(ehc);
u32 scontrol;
int rc;
@@ -2805,24 +3034,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
* and Sil3124.
*/
if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
- return rc;
+ goto out;
scontrol = (scontrol & 0x0f0) | 0x304;
if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
- return rc;
+ goto out;
sata_set_spd(ap);
}
/* issue phy wake/reset */
if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
- return rc;
+ goto out;
scontrol = (scontrol & 0x0f0) | 0x301;
if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
- return rc;
+ goto out;
/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
* 10.4.2 says at least 1 ms.
@@ -2830,7 +3059,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
msleep(1);
/* bring phy back */
- sata_phy_resume(ap, timing);
+ rc = sata_phy_resume(ap, timing);
+ out:
+ DPRINTK("EXIT, rc=%d\n", rc);
+ return rc;
+}
+
+/**
+ * sata_std_hardreset - reset host port via SATA phy reset
+ * @ap: port to reset
+ * @class: resulting class of attached device
+ *
+ * SATA phy-reset host port using DET bits of SControl register,
+ * wait for !BSY and classify the attached device.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+{
+ const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+ int rc;
+
+ DPRINTK("ENTER\n");
+
+ /* do hardreset */
+ rc = sata_port_hardreset(ap, timing);
+ if (rc) {
+ ata_port_printk(ap, KERN_ERR,
+ "COMRESET failed (errno=%d)\n", rc);
+ return rc;
+ }
/* TODO: phy layer with polling, timeouts, etc. */
if (ata_port_offline(ap)) {
@@ -2969,7 +3231,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
/**
* ata_dev_revalidate - Revalidate ATA device
* @dev: device to revalidate
- * @post_reset: is this revalidation after reset?
+ * @readid_flags: read ID flags
*
* Re-read IDENTIFY page and make sure @dev is still attached to
* the port.
@@ -2980,7 +3242,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
* RETURNS:
* 0 on success, negative errno otherwise
*/
-int ata_dev_revalidate(struct ata_device *dev, int post_reset)
+int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
{
unsigned int class = dev->class;
u16 *id = (void *)dev->ap->sector_buf;
@@ -2992,7 +3254,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
}
/* read ID data */
- rc = ata_dev_read_id(dev, &class, post_reset, id);
+ rc = ata_dev_read_id(dev, &class, readid_flags, id);
if (rc)
goto fail;
@@ -3005,7 +3267,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
/* configure device according to the new ID */
- rc = ata_dev_configure(dev, 0);
+ rc = ata_dev_configure(dev);
if (rc == 0)
return 0;
@@ -3014,37 +3276,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
return rc;
}
-static const char * const ata_dma_blacklist [] = {
- "WDC AC11000H", NULL,
- "WDC AC22100H", NULL,
- "WDC AC32500H", NULL,
- "WDC AC33100H", NULL,
- "WDC AC31600H", NULL,
- "WDC AC32100H", "24.09P07",
- "WDC AC23200L", "21.10N21",
- "Compaq CRD-8241B", NULL,
- "CRD-8400B", NULL,
- "CRD-8480B", NULL,
- "CRD-8482B", NULL,
- "CRD-84", NULL,
- "SanDisk SDP3B", NULL,
- "SanDisk SDP3B-64", NULL,
- "SANYO CD-ROM CRD", NULL,
- "HITACHI CDR-8", NULL,
- "HITACHI CDR-8335", NULL,
- "HITACHI CDR-8435", NULL,
- "Toshiba CD-ROM XM-6202B", NULL,
- "TOSHIBA CD-ROM XM-1702BC", NULL,
- "CD-532E-A", NULL,
- "E-IDE CD-ROM CR-840", NULL,
- "CD-ROM Drive/F5A", NULL,
- "WPI CDD-820", NULL,
- "SAMSUNG CD-ROM SC-148C", NULL,
- "SAMSUNG CD-ROM SC", NULL,
- "SanDisk SDP3B-64", NULL,
- "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,
- "_NEC DV5800A", NULL,
- "SAMSUNG CD-ROM SN-124", "N001"
+struct ata_blacklist_entry {
+ const char *model_num;
+ const char *model_rev;
+ unsigned long horkage;
+};
+
+static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ /* Devices with DMA related problems under Linux */
+ { "WDC AC11000H", NULL, ATA_HORKAGE_NODMA },
+ { "WDC AC22100H", NULL, ATA_HORKAGE_NODMA },
+ { "WDC AC32500H", NULL, ATA_HORKAGE_NODMA },
+ { "WDC AC33100H", NULL, ATA_HORKAGE_NODMA },
+ { "WDC AC31600H", NULL, ATA_HORKAGE_NODMA },
+ { "WDC AC32100H", "24.09P07", ATA_HORKAGE_NODMA },
+ { "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA },
+ { "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA },
+ { "CRD-8400B", NULL, ATA_HORKAGE_NODMA },
+ { "CRD-8480B", NULL, ATA_HORKAGE_NODMA },
+ { "CRD-8482B", NULL, ATA_HORKAGE_NODMA },
+ { "CRD-84", NULL, ATA_HORKAGE_NODMA },
+ { "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA },
+ { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
+ { "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA },
+ { "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA },
+ { "HITACHI CDR-8335", NULL, ATA_HORKAGE_NODMA },
+ { "HITACHI CDR-8435", NULL, ATA_HORKAGE_NODMA },
+ { "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA },
+ { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA },
+ { "CD-532E-A", NULL, ATA_HORKAGE_NODMA },
+ { "E-IDE CD-ROM CR-840",NULL, ATA_HORKAGE_NODMA },
+ { "CD-ROM Drive/F5A", NULL, ATA_HORKAGE_NODMA },
+ { "WPI CDD-820", NULL, ATA_HORKAGE_NODMA },
+ { "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA },
+ { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA },
+ { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
+ { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
+ { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
+ { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
+
+ /* Devices we expect to fail diagnostics */
+
+ /* Devices where NCQ should be avoided */
+ /* NCQ is slow */
+ { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
+
+ /* Devices with NCQ limits */
+
+ /* End Marker */
+ { }
};
static int ata_strim(char *s, size_t len)
@@ -3059,20 +3339,12 @@ static int ata_strim(char *s, size_t len)
return len;
}
-static int ata_dma_blacklisted(const struct ata_device *dev)
+unsigned long ata_device_blacklisted(const struct ata_device *dev)
{
unsigned char model_num[40];
unsigned char model_rev[16];
unsigned int nlen, rlen;
- int i;
-
- /* We don't support polling DMA.
- * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
- * if the LLDD handles only interrupts in the HSM_ST_LAST state.
- */
- if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
- (dev->flags & ATA_DFLAG_CDB_INTR))
- return 1;
+ const struct ata_blacklist_entry *ad = ata_device_blacklist;
ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
sizeof(model_num));
@@ -3081,17 +3353,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
nlen = ata_strim(model_num, sizeof(model_num));
rlen = ata_strim(model_rev, sizeof(model_rev));
- for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) {
- if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) {
- if (ata_dma_blacklist[i+1] == NULL)
- return 1;
- if (!strncmp(ata_dma_blacklist[i], model_rev, rlen))
- return 1;
+ while (ad->model_num) {
+ if (!strncmp(ad->model_num, model_num, nlen)) {
+ if (ad->model_rev == NULL)
+ return ad->horkage;
+ if (!strncmp(ad->model_rev, model_rev, rlen))
+ return ad->horkage;
}
+ ad++;
}
return 0;
}
+static int ata_dma_blacklisted(const struct ata_device *dev)
+{
+ /* We don't support polling DMA.
+ * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
+ * if the LLDD handles only interrupts in the HSM_ST_LAST state.
+ */
+ if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
+ (dev->flags & ATA_DFLAG_CDB_INTR))
+ return 1;
+ return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+}
+
/**
* ata_dev_xfermask - Compute supported xfermask of the given device
* @dev: Device to compute xfermask for
@@ -3119,6 +3404,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
*/
if (ap->cbl == ATA_CBL_PATA40)
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+ /* Apply drive side cable rule. Unknown or 80 pin cables reported
+ * host side are checked drive side as well. Cases where we know a
+ * 40wire cable is used safely for 80 are not checked here.
+ */
+ if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
+ xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+
xfer_mask &= ata_pack_xfermask(dev->pio_mask,
dev->mwdma_mask, dev->udma_mask);
@@ -3236,8 +3528,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_sg_clean(struct ata_queued_cmd *qc)
+void ata_sg_clean(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->__sg;
@@ -3395,19 +3686,15 @@ void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
{
- struct scatterlist *sg;
-
qc->flags |= ATA_QCFLAG_SINGLE;
- memset(&qc->sgent, 0, sizeof(qc->sgent));
qc->__sg = &qc->sgent;
qc->n_elem = 1;
qc->orig_n_elem = 1;
qc->buf_virt = buf;
qc->nbytes = buflen;
- sg = qc->__sg;
- sg_init_one(sg, buf, buflen);
+ sg_init_one(&qc->sgent, buf, buflen);
}
/**
@@ -4200,8 +4487,12 @@ fsm_start:
/* device stops HSM for abort/error */
qc->err_mask |= AC_ERR_DEV;
else
- /* HSM violation. Let EH handle this */
- qc->err_mask |= AC_ERR_HSM;
+ /* HSM violation. Let EH handle this.
+ * Phantom devices also trigger this
+ * condition. Mark hint.
+ */
+ qc->err_mask |= AC_ERR_HSM |
+ AC_ERR_NODEV_HINT;
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
@@ -4295,10 +4586,11 @@ fsm_start:
return poll_next;
}
-static void ata_pio_task(void *_data)
+static void ata_pio_task(struct work_struct *work)
{
- struct ata_queued_cmd *qc = _data;
- struct ata_port *ap = qc->ap;
+ struct ata_port *ap =
+ container_of(work, struct ata_port, port_task.work);
+ struct ata_queued_cmd *qc = ap->port_task_data;
u8 status;
int poll_next;
@@ -4440,6 +4732,14 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
qc->complete_fn(qc);
}
+static void fill_result_tf(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ ap->ops->tf_read(ap, &qc->result_tf);
+ qc->result_tf.flags = qc->tf.flags;
+}
+
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
@@ -4477,7 +4777,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
if (!ata_tag_internal(qc->tag)) {
/* always fill result TF for failed qc */
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
ata_qc_schedule_eh(qc);
return;
}
@@ -4485,7 +4785,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
/* read result TF if requested */
if (qc->flags & ATA_QCFLAG_RESULT_TF)
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
__ata_qc_complete(qc);
} else {
@@ -4494,7 +4794,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
/* read result TF if failed or requested */
if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
__ata_qc_complete(qc);
}
@@ -4674,6 +4974,14 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
}
}
+ /* Some controllers show flaky interrupt behavior after
+ * setting xfer mode. Use polling instead.
+ */
+ if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
+ qc->tf.feature == SETFEATURES_XFER) &&
+ (ap->flags & ATA_FLAG_SETXFER_POLLING))
+ qc->tf.flags |= ATA_TFLAG_POLLING;
+
/* select the device */
ata_dev_select(ap, qc->dev->devno, 1, 0);
@@ -4782,6 +5090,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
inline unsigned int ata_host_intr (struct ata_port *ap,
struct ata_queued_cmd *qc)
{
+ struct ata_eh_info *ehi = &ap->eh_info;
u8 status, host_stat = 0;
VPRINTK("ata%u: protocol %d task_state %d\n",
@@ -4842,6 +5151,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap);
ata_hsm_move(ap, qc, status, 0);
+
+ if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
+ qc->tf.protocol == ATA_PROT_ATAPI_DMA))
+ ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
+
return 1; /* irq handled */
idle_irq:
@@ -5048,7 +5362,7 @@ int ata_flush_cache(struct ata_device *dev)
if (!ata_try_flush_cache(dev))
return 0;
- if (ata_id_has_flush_ext(dev->id))
+ if (dev->flags & ATA_DFLAG_FLUSH_EXT)
cmd = ATA_CMD_FLUSH_EXT;
else
cmd = ATA_CMD_FLUSH;
@@ -5320,9 +5634,9 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN;
#endif
- INIT_WORK(&ap->port_task, NULL, NULL);
- INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap);
- INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap);
+ INIT_DELAYED_WORK(&ap->port_task, NULL);
+ INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+ INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
INIT_LIST_HEAD(&ap->eh_done_q);
init_waitqueue_head(&ap->eh_wait_q);
@@ -5520,9 +5834,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
ap->ioaddr.bmdma_addr,
irq_line);
- ata_chk_status(ap);
- host->ops->irq_clear(ap);
- ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
+ /* freeze port before requesting IRQ */
+ ata_eh_freeze_port(ap);
}
/* obtain irq, that may be shared between channels */
@@ -6120,6 +6433,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_std_prereset);
EXPORT_SYMBOL_GPL(ata_std_softreset);
+EXPORT_SYMBOL_GPL(sata_port_hardreset);
EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
EXPORT_SYMBOL_GPL(ata_dev_classify);
@@ -6146,6 +6460,7 @@ EXPORT_SYMBOL_GPL(ata_host_suspend);
EXPORT_SYMBOL_GPL(ata_host_resume);
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_device_blacklisted);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 02b2b2787d9b..08ad44b3e48f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -332,7 +332,7 @@ void ata_scsi_error(struct Scsi_Host *host)
if (ap->pflags & ATA_PFLAG_LOADING)
ap->pflags &= ~ATA_PFLAG_LOADING;
else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG)
- queue_work(ata_aux_wq, &ap->hotplug_task);
+ queue_delayed_work(ata_aux_wq, &ap->hotplug_task, 0);
if (ap->pflags & ATA_PFLAG_RECOVERED)
ata_port_printk(ap, KERN_INFO, "EH complete\n");
@@ -1136,19 +1136,21 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
break;
case ATA_DEV_ATAPI:
- tmp = atapi_eh_request_sense(qc->dev,
- qc->scsicmd->sense_buffer);
- if (!tmp) {
- /* ATA_QCFLAG_SENSE_VALID is used to tell
- * atapi_qc_complete() that sense data is
- * already valid.
- *
- * TODO: interpret sense data and set
- * appropriate err_mask.
- */
- qc->flags |= ATA_QCFLAG_SENSE_VALID;
- } else
- qc->err_mask |= tmp;
+ if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
+ tmp = atapi_eh_request_sense(qc->dev,
+ qc->scsicmd->sense_buffer);
+ if (!tmp) {
+ /* ATA_QCFLAG_SENSE_VALID is used to
+ * tell atapi_qc_complete() that sense
+ * data is already valid.
+ *
+ * TODO: interpret sense data and set
+ * appropriate err_mask.
+ */
+ qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ } else
+ qc->err_mask |= tmp;
+ }
}
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
@@ -1433,16 +1435,39 @@ static void ata_eh_report(struct ata_port *ap)
}
for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+ static const char *dma_str[] = {
+ [DMA_BIDIRECTIONAL] = "bidi",
+ [DMA_TO_DEVICE] = "out",
+ [DMA_FROM_DEVICE] = "in",
+ [DMA_NONE] = "",
+ };
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+ struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
+ unsigned int nbytes;
if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
continue;
- ata_dev_printk(qc->dev, KERN_ERR, "tag %d cmd 0x%x "
- "Emask 0x%x stat 0x%x err 0x%x (%s)\n",
- qc->tag, qc->tf.command, qc->err_mask,
- qc->result_tf.command, qc->result_tf.feature,
- ata_err_string(qc->err_mask));
+ nbytes = qc->nbytes;
+ if (!nbytes)
+ nbytes = qc->nsect << 9;
+
+ ata_dev_printk(qc->dev, KERN_ERR,
+ "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
+ "tag %d cdb 0x%x data %u %s\n "
+ "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
+ "Emask 0x%x (%s)\n",
+ cmd->command, cmd->feature, cmd->nsect,
+ cmd->lbal, cmd->lbam, cmd->lbah,
+ cmd->hob_feature, cmd->hob_nsect,
+ cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
+ cmd->device, qc->tag, qc->cdb[0], nbytes,
+ dma_str[qc->dma_dir],
+ res->command, res->feature, res->nsect,
+ res->lbal, res->lbam, res->lbah,
+ res->hob_feature, res->hob_nsect,
+ res->hob_lbal, res->hob_lbam, res->hob_lbah,
+ res->device, qc->err_mask, ata_err_string(qc->err_mask));
}
}
@@ -1634,11 +1659,14 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
DPRINTK("ENTER\n");
for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned int action;
+ unsigned int action, readid_flags = 0;
dev = &ap->device[i];
action = ata_eh_dev_action(dev);
+ if (ehc->i.flags & ATA_EHI_DID_RESET)
+ readid_flags |= ATA_READID_POSTRESET;
+
if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
if (ata_port_offline(ap)) {
rc = -EIO;
@@ -1646,13 +1674,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
}
ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
- rc = ata_dev_revalidate(dev,
- ehc->i.flags & ATA_EHI_DID_RESET);
+ rc = ata_dev_revalidate(dev, readid_flags);
if (rc)
break;
ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
+ /* Configuration may have changed, reconfigure
+ * transfer mode.
+ */
+ ehc->i.flags |= ATA_EHI_SETMODE;
+
/* schedule the scsi_rescan_device() here */
queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
} else if (dev->class == ATA_DEV_UNKNOWN &&
@@ -1660,18 +1692,35 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
ata_class_enabled(ehc->classes[dev->devno])) {
dev->class = ehc->classes[dev->devno];
- rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
- if (rc == 0)
- rc = ata_dev_configure(dev, 1);
+ rc = ata_dev_read_id(dev, &dev->class, readid_flags,
+ dev->id);
+ if (rc == 0) {
+ ehc->i.flags |= ATA_EHI_PRINTINFO;
+ rc = ata_dev_configure(dev);
+ ehc->i.flags &= ~ATA_EHI_PRINTINFO;
+ } else if (rc == -ENOENT) {
+ /* IDENTIFY was issued to non-existent
+ * device. No need to reset. Just
+ * thaw and kill the device.
+ */
+ ata_eh_thaw_port(ap);
+ dev->class = ATA_DEV_UNKNOWN;
+ rc = 0;
+ }
if (rc) {
dev->class = ATA_DEV_UNKNOWN;
break;
}
- spin_lock_irqsave(ap->lock, flags);
- ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
- spin_unlock_irqrestore(ap->lock, flags);
+ if (ata_dev_enabled(dev)) {
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* new device discovered, configure xfermode */
+ ehc->i.flags |= ATA_EHI_SETMODE;
+ }
}
}
@@ -1987,13 +2036,14 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
if (rc)
goto dev_fail;
- /* configure transfer mode if the port has been reset */
- if (ehc->i.flags & ATA_EHI_DID_RESET) {
+ /* configure transfer mode if necessary */
+ if (ehc->i.flags & ATA_EHI_SETMODE) {
rc = ata_set_mode(ap, &dev);
if (rc) {
down_xfermask = 1;
goto dev_fail;
}
+ ehc->i.flags &= ~ATA_EHI_SETMODE;
}
/* suspend devices */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 47ea111d5ace..664e1377b54c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -671,7 +671,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
}
/*
- * ata_gen_ata_desc_sense - Generate check condition sense block.
+ * ata_gen_passthru_sense - Generate check condition sense block.
* @qc: Command that completed.
*
* This function is specific to the ATA descriptor format sense
@@ -681,9 +681,9 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
* block. Clear sense key, ASC & ASCQ if there is no error.
*
* LOCKING:
- * spin_lock_irqsave(host lock)
+ * None.
*/
-void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
+static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->result_tf;
@@ -713,12 +713,9 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
desc[0] = 0x09;
- /*
- * Set length of additional sense data.
- * Since we only populate descriptor 0, the total
- * length is the same (fixed) length as descriptor 0.
- */
- desc[1] = sb[7] = 14;
+ /* set length of additional sense data */
+ sb[7] = 14;
+ desc[1] = 12;
/*
* Copy registers into sense buffer.
@@ -746,56 +743,56 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
}
/**
- * ata_gen_fixed_sense - generate a SCSI fixed sense block
+ * ata_gen_ata_sense - generate a SCSI fixed sense block
* @qc: Command that we are erroring out
*
- * Leverage ata_to_sense_error() to give us the codes. Fit our
- * LBA in here if there's room.
+ * Generate sense block for a failed ATA command @qc. Descriptor
+ * format is used to accomodate LBA48 block address.
*
* LOCKING:
- * inherited from caller
+ * None.
*/
-void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
+static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
{
+ struct ata_device *dev = qc->dev;
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->result_tf;
unsigned char *sb = cmd->sense_buffer;
+ unsigned char *desc = sb + 8;
int verbose = qc->ap->ops->error_handler == NULL;
+ u64 block;
memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
- /*
- * Use ata_to_sense_error() to map status register bits
+ /* sense data is current and format is descriptor */
+ sb[0] = 0x72;
+
+ /* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
if (qc->err_mask ||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
- &sb[2], &sb[12], &sb[13], verbose);
- sb[2] &= 0x0f;
+ &sb[1], &sb[2], &sb[3], verbose);
+ sb[1] &= 0x0f;
}
- sb[0] = 0x70;
- sb[7] = 0x0a;
-
- if (tf->flags & ATA_TFLAG_LBA48) {
- /* TODO: find solution for LBA48 descriptors */
- }
+ block = ata_tf_read_block(&qc->result_tf, dev);
- else if (tf->flags & ATA_TFLAG_LBA) {
- /* A small (28b) LBA will fit in the 32b info field */
- sb[0] |= 0x80; /* set valid bit */
- sb[3] = tf->device & 0x0f;
- sb[4] = tf->lbah;
- sb[5] = tf->lbam;
- sb[6] = tf->lbal;
- }
+ /* information sense data descriptor */
+ sb[7] = 12;
+ desc[0] = 0x00;
+ desc[1] = 10;
- else {
- /* TODO: C/H/S */
- }
+ desc[2] |= 0x80; /* valid */
+ desc[6] = block >> 40;
+ desc[7] = block >> 32;
+ desc[8] = block >> 24;
+ desc[9] = block >> 16;
+ desc[10] = block >> 8;
+ desc[11] = block;
}
static void ata_scsi_sdev_config(struct scsi_device *sdev)
@@ -807,23 +804,10 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
static void ata_scsi_dev_config(struct scsi_device *sdev,
struct ata_device *dev)
{
- unsigned int max_sectors;
-
- /* TODO: 2048 is an arbitrary number, not the
- * hardware maximum. This should be increased to
- * 65534 when Jens Axboe's patch for dynamically
- * determining max_sectors is merged.
- */
- max_sectors = ATA_MAX_SECTORS;
- if (dev->flags & ATA_DFLAG_LBA48)
- max_sectors = ATA_MAX_SECTORS_LBA48;
- if (dev->max_sectors)
- max_sectors = dev->max_sectors;
+ /* configure max sectors */
+ blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
- blk_queue_max_sectors(sdev->request_queue, max_sectors);
-
- /*
- * SATA DMA transfers must be multiples of 4 byte, so
+ /* SATA DMA transfers must be multiples of 4 byte, so
* we need to pad ATAPI transfers using an extra sg.
* Decrement max hw segments accordingly.
*/
@@ -1040,8 +1024,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
tf->flags |= ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
- (ata_id_has_flush_ext(qc->dev->id)))
+ if (qc->dev->flags & ATA_DFLAG_FLUSH_EXT)
tf->command = ATA_CMD_FLUSH_EXT;
else
tf->command = ATA_CMD_FLUSH;
@@ -1282,17 +1265,14 @@ nothing_to_do:
static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
- struct ata_taskfile *tf = &qc->tf;
- struct ata_device *dev = qc->dev;
+ unsigned int tf_flags = 0;
u64 block;
u32 n_block;
-
- qc->flags |= ATA_QCFLAG_IO;
- tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ int rc;
if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
scsicmd[0] == WRITE_16)
- tf->flags |= ATA_TFLAG_WRITE;
+ tf_flags |= ATA_TFLAG_WRITE;
/* Calculate the SCSI LBA, transfer length and FUA. */
switch (scsicmd[0]) {
@@ -1300,7 +1280,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
case WRITE_10:
scsi_10_lba_len(scsicmd, &block, &n_block);
if (unlikely(scsicmd[1] & (1 << 3)))
- tf->flags |= ATA_TFLAG_FUA;
+ tf_flags |= ATA_TFLAG_FUA;
break;
case READ_6:
case WRITE_6:
@@ -1316,7 +1296,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
case WRITE_16:
scsi_16_lba_len(scsicmd, &block, &n_block);
if (unlikely(scsicmd[1] & (1 << 3)))
- tf->flags |= ATA_TFLAG_FUA;
+ tf_flags |= ATA_TFLAG_FUA;
break;
default:
DPRINTK("no-byte command\n");
@@ -1334,106 +1314,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
*/
goto nothing_to_do;
- if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
- ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
- /* yay, NCQ */
- if (!lba_48_ok(block, n_block))
- goto out_of_range;
-
- tf->protocol = ATA_PROT_NCQ;
- tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
-
- if (tf->flags & ATA_TFLAG_WRITE)
- tf->command = ATA_CMD_FPDMA_WRITE;
- else
- tf->command = ATA_CMD_FPDMA_READ;
-
- qc->nsect = n_block;
-
- tf->nsect = qc->tag << 3;
- tf->hob_feature = (n_block >> 8) & 0xff;
- tf->feature = n_block & 0xff;
-
- tf->hob_lbah = (block >> 40) & 0xff;
- tf->hob_lbam = (block >> 32) & 0xff;
- tf->hob_lbal = (block >> 24) & 0xff;
- tf->lbah = (block >> 16) & 0xff;
- tf->lbam = (block >> 8) & 0xff;
- tf->lbal = block & 0xff;
-
- tf->device = 1 << 6;
- if (tf->flags & ATA_TFLAG_FUA)
- tf->device |= 1 << 7;
- } else if (dev->flags & ATA_DFLAG_LBA) {
- tf->flags |= ATA_TFLAG_LBA;
-
- if (lba_28_ok(block, n_block)) {
- /* use LBA28 */
- tf->device |= (block >> 24) & 0xf;
- } else if (lba_48_ok(block, n_block)) {
- if (!(dev->flags & ATA_DFLAG_LBA48))
- goto out_of_range;
-
- /* use LBA48 */
- tf->flags |= ATA_TFLAG_LBA48;
-
- tf->hob_nsect = (n_block >> 8) & 0xff;
-
- tf->hob_lbah = (block >> 40) & 0xff;
- tf->hob_lbam = (block >> 32) & 0xff;
- tf->hob_lbal = (block >> 24) & 0xff;
- } else
- /* request too large even for LBA48 */
- goto out_of_range;
-
- if (unlikely(ata_rwcmd_protocol(qc) < 0))
- goto invalid_fld;
-
- qc->nsect = n_block;
- tf->nsect = n_block & 0xff;
-
- tf->lbah = (block >> 16) & 0xff;
- tf->lbam = (block >> 8) & 0xff;
- tf->lbal = block & 0xff;
-
- tf->device |= ATA_LBA;
- } else {
- /* CHS */
- u32 sect, head, cyl, track;
-
- /* The request -may- be too large for CHS addressing. */
- if (!lba_28_ok(block, n_block))
- goto out_of_range;
-
- if (unlikely(ata_rwcmd_protocol(qc) < 0))
- goto invalid_fld;
-
- /* Convert LBA to CHS */
- track = (u32)block / dev->sectors;
- cyl = track / dev->heads;
- head = track % dev->heads;
- sect = (u32)block % dev->sectors + 1;
-
- DPRINTK("block %u track %u cyl %u head %u sect %u\n",
- (u32)block, track, cyl, head, sect);
-
- /* Check whether the converted CHS can fit.
- Cylinder: 0-65535
- Head: 0-15
- Sector: 1-255*/
- if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
- goto out_of_range;
-
- qc->nsect = n_block;
- tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
- tf->lbal = sect;
- tf->lbam = cyl;
- tf->lbah = cyl >> 8;
- tf->device |= head;
- }
+ qc->flags |= ATA_QCFLAG_IO;
+ qc->nsect = n_block;
- return 0;
+ rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
+ qc->tag);
+ if (likely(rc == 0))
+ return 0;
+ if (rc == -ERANGE)
+ goto out_of_range;
+ /* treat all other errors as -EINVAL, fall through */
invalid_fld:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
@@ -1477,7 +1368,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
*/
if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
((cdb[2] & 0x20) || need_sense)) {
- ata_gen_ata_desc_sense(qc);
+ ata_gen_passthru_sense(qc);
} else {
if (!need_sense) {
cmd->result = SAM_STAT_GOOD;
@@ -1488,7 +1379,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* good for smaller LBA (and maybe CHS?)
* devices.
*/
- ata_gen_fixed_sense(qc);
+ ata_gen_ata_sense(qc);
}
}
@@ -1715,6 +1606,22 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
}
/**
+ * ATA_SCSI_RBUF_SET - helper to set values in SCSI response buffer
+ * @idx: byte index into SCSI response buffer
+ * @val: value to set
+ *
+ * To be used by SCSI command simulator functions. This macros
+ * expects two local variables, u8 *rbuf and unsigned int buflen,
+ * are in scope.
+ *
+ * LOCKING:
+ * None.
+ */
+#define ATA_SCSI_RBUF_SET(idx, val) do { \
+ if ((idx) < buflen) rbuf[(idx)] = (u8)(val); \
+ } while (0)
+
+/**
* ata_scsiop_inq_std - Simulate INQUIRY command
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
@@ -2173,67 +2080,42 @@ saving_not_supp:
* Simulate READ CAPACITY commands.
*
* LOCKING:
- * spin_lock_irqsave(host lock)
+ * None.
*/
-
unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
- u64 n_sectors;
- u32 tmp;
+ u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
VPRINTK("ENTER\n");
- if (ata_id_has_lba(args->id)) {
- if (ata_id_has_lba48(args->id))
- n_sectors = ata_id_u64(args->id, 100);
- else
- n_sectors = ata_id_u32(args->id, 60);
- } else {
- /* CHS default translation */
- n_sectors = args->id[1] * args->id[3] * args->id[6];
-
- if (ata_id_current_chs_valid(args->id))
- /* CHS current translation */
- n_sectors = ata_id_u32(args->id, 57);
- }
-
- n_sectors--; /* ATA TotalUserSectors - 1 */
-
if (args->cmd->cmnd[0] == READ_CAPACITY) {
- if( n_sectors >= 0xffffffffULL )
- tmp = 0xffffffff ; /* Return max count on overflow */
- else
- tmp = n_sectors ;
+ if (last_lba >= 0xffffffffULL)
+ last_lba = 0xffffffff;
/* sector count, 32-bit */
- rbuf[0] = tmp >> (8 * 3);
- rbuf[1] = tmp >> (8 * 2);
- rbuf[2] = tmp >> (8 * 1);
- rbuf[3] = tmp;
+ ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 3));
+ ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 2));
+ ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 1));
+ ATA_SCSI_RBUF_SET(3, last_lba);
/* sector size */
- tmp = ATA_SECT_SIZE;
- rbuf[6] = tmp >> 8;
- rbuf[7] = tmp;
-
+ ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8);
+ ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE);
} else {
/* sector count, 64-bit */
- tmp = n_sectors >> (8 * 4);
- rbuf[2] = tmp >> (8 * 3);
- rbuf[3] = tmp >> (8 * 2);
- rbuf[4] = tmp >> (8 * 1);
- rbuf[5] = tmp;
- tmp = n_sectors;
- rbuf[6] = tmp >> (8 * 3);
- rbuf[7] = tmp >> (8 * 2);
- rbuf[8] = tmp >> (8 * 1);
- rbuf[9] = tmp;
+ ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7));
+ ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 6));
+ ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 5));
+ ATA_SCSI_RBUF_SET(3, last_lba >> (8 * 4));
+ ATA_SCSI_RBUF_SET(4, last_lba >> (8 * 3));
+ ATA_SCSI_RBUF_SET(5, last_lba >> (8 * 2));
+ ATA_SCSI_RBUF_SET(6, last_lba >> (8 * 1));
+ ATA_SCSI_RBUF_SET(7, last_lba);
/* sector size */
- tmp = ATA_SECT_SIZE;
- rbuf[12] = tmp >> 8;
- rbuf[13] = tmp;
+ ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8);
+ ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE);
}
return 0;
@@ -2319,7 +2201,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc)
* a sense descriptors, since that's only
* correct for ATA, not ATAPI
*/
- ata_gen_ata_desc_sense(qc);
+ ata_gen_passthru_sense(qc);
}
qc->scsidone(qc->scsicmd);
@@ -2394,7 +2276,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
* sense descriptors, since that's only
* correct for ATA, not ATAPI
*/
- ata_gen_ata_desc_sense(qc);
+ ata_gen_passthru_sense(qc);
}
/* SCSI EH automatically locks door if sdev->locked is
@@ -2427,7 +2309,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
* a sense descriptors, since that's only
* correct for ATA, not ATAPI
*/
- ata_gen_ata_desc_sense(qc);
+ ata_gen_passthru_sense(qc);
} else {
u8 *scsicmd = cmd->cmnd;
@@ -3081,7 +2963,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
/**
* ata_scsi_hotplug - SCSI part of hotplug
- * @data: Pointer to ATA port to perform SCSI hotplug on
+ * @work: Pointer to ATA port to perform SCSI hotplug on
*
* Perform SCSI part of hotplug. It's executed from a separate
* workqueue after EH completes. This is necessary because SCSI
@@ -3091,9 +2973,10 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
* LOCKING:
* Kernel thread context (may sleep).
*/
-void ata_scsi_hotplug(void *data)
+void ata_scsi_hotplug(struct work_struct *work)
{
- struct ata_port *ap = data;
+ struct ata_port *ap =
+ container_of(work, struct ata_port, hotplug_task.work);
int i;
if (ap->pflags & ATA_PFLAG_UNLOADING) {
@@ -3182,17 +3065,19 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
rc = -EINVAL;
}
- if (rc == 0)
+ if (rc == 0) {
ata_port_schedule_eh(ap);
-
- spin_unlock_irqrestore(ap->lock, flags);
+ spin_unlock_irqrestore(ap->lock, flags);
+ ata_port_wait_eh(ap);
+ } else
+ spin_unlock_irqrestore(ap->lock, flags);
return rc;
}
/**
* ata_scsi_dev_rescan - initiate scsi_rescan_device()
- * @data: Pointer to ATA port to perform scsi_rescan_device()
+ * @work: Pointer to ATA port to perform scsi_rescan_device()
*
* After ATA pass thru (SAT) commands are executed successfully,
* libata need to propagate the changes to SCSI layer. This
@@ -3202,18 +3087,31 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
* LOCKING:
* Kernel thread context (may sleep).
*/
-void ata_scsi_dev_rescan(void *data)
+void ata_scsi_dev_rescan(struct work_struct *work)
{
- struct ata_port *ap = data;
- struct ata_device *dev;
+ struct ata_port *ap =
+ container_of(work, struct ata_port, scsi_rescan_task);
+ unsigned long flags;
unsigned int i;
+ spin_lock_irqsave(ap->lock, flags);
+
for (i = 0; i < ATA_MAX_DEVICES; i++) {
- dev = &ap->device[i];
+ struct ata_device *dev = &ap->device[i];
+ struct scsi_device *sdev = dev->sdev;
- if (ata_dev_enabled(dev) && dev->sdev)
- scsi_rescan_device(&(dev->sdev->sdev_gendev));
+ if (!ata_dev_enabled(dev) || !sdev)
+ continue;
+ if (scsi_device_get(sdev))
+ continue;
+
+ spin_unlock_irqrestore(ap->lock, flags);
+ scsi_rescan_device(&(sdev->sdev_gendev));
+ scsi_device_put(sdev);
+ spin_lock_irqsave(ap->lock, flags);
}
+
+ spin_unlock_irqrestore(ap->lock, flags);
}
/**
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 7645f2b30ccf..10ee22ae5c15 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -39,6 +39,35 @@
#include "libata.h"
/**
+ * ata_irq_on - Enable interrupts on a port.
+ * @ap: Port on which interrupts are enabled.
+ *
+ * Enable interrupts on a legacy IDE device using MMIO or PIO,
+ * wait for idle, clear any pending interrupts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+u8 ata_irq_on(struct ata_port *ap)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ u8 tmp;
+
+ ap->ctl &= ~ATA_NIEN;
+ ap->last_ctl = ap->ctl;
+
+ if (ap->flags & ATA_FLAG_MMIO)
+ writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
+ else
+ outb(ap->ctl, ioaddr->ctl_addr);
+ tmp = ata_wait_idle(ap);
+
+ ap->ops->irq_clear(ap);
+
+ return tmp;
+}
+
+/**
* ata_tf_load_pio - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
@@ -671,6 +700,14 @@ void ata_bmdma_freeze(struct ata_port *ap)
writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
else
outb(ap->ctl, ioaddr->ctl_addr);
+
+ /* Under certain circumstances, some controllers raise IRQ on
+ * ATA_NIEN manipulation. Also, many controllers fail to mask
+ * previously pending IRQ on ATA_NIEN assertion. Clear it.
+ */
+ ata_chk_status(ap);
+
+ ap->ops->irq_clear(ap);
}
/**
@@ -714,7 +751,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset)
{
- struct ata_eh_context *ehc = &ap->eh_context;
struct ata_queued_cmd *qc;
unsigned long flags;
int thaw = 0;
@@ -732,9 +768,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
qc->tf.protocol == ATA_PROT_ATAPI_DMA)) {
u8 host_stat;
- host_stat = ata_bmdma_status(ap);
-
- ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat);
+ host_stat = ap->ops->bmdma_status(ap);
/* BMDMA controllers indicate host bus error by
* setting DMA_ERR bit and timing out. As it wasn't
@@ -877,6 +911,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
return NULL;
probe_ent->n_ports = 2;
+ probe_ent->irq_flags = IRQF_SHARED;
if (port_mask & ATA_PORT_PRIMARY) {
probe_ent->irq = ATA_PRIMARY_IRQ;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 0ed263be652a..81ae41d5f23f 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -39,26 +39,39 @@ struct ata_scsi_args {
};
/* libata-core.c */
+enum {
+ /* flags for ata_dev_read_id() */
+ ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */
+};
+
extern struct workqueue_struct *ata_aux_wq;
extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
-extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
+ u64 block, u32 n_block, unsigned int tf_flags,
+ unsigned int tag);
+extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
extern void ata_dev_disable(struct ata_device *dev);
extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen);
+extern unsigned ata_exec_internal_sg(struct ata_device *dev,
+ struct ata_taskfile *tf, const u8 *cdb,
+ int dma_dir, struct scatterlist *sg,
+ unsigned int n_elem);
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
- int post_reset, u16 *id);
-extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
-extern int ata_dev_configure(struct ata_device *dev, int print_info);
+ unsigned int flags, u16 *id);
+extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
+extern int ata_dev_configure(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_port *ap);
extern int sata_set_spd_needed(struct ata_port *ap);
extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
+extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
@@ -81,7 +94,7 @@ extern struct scsi_transport_template ata_scsi_transport_template;
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_offline_dev(struct ata_device *dev);
-extern void ata_scsi_hotplug(void *data);
+extern void ata_scsi_hotplug(struct work_struct *work);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
@@ -111,7 +124,7 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int (*actor) (struct ata_scsi_args *args,
u8 *rbuf, unsigned int buflen));
extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
-extern void ata_scsi_dev_rescan(void *data);
+extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap);
/* libata-eh.c */
@@ -120,4 +133,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
extern void ata_port_wait_eh(struct ata_port *ap);
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
+/* libata-sff.c */
+extern u8 ata_irq_on(struct ata_port *ap);
+
#endif /* __LIBATA_H__ */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 64eed99f6814..c5d61d1911a5 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -34,7 +34,7 @@
#include <linux/dmi.h>
#define DRV_NAME "pata_ali"
-#define DRV_VERSION "0.6.6"
+#define DRV_VERSION "0.7.2"
/*
* Cable special cases
@@ -78,7 +78,7 @@ static int ali_c2_cable_detect(struct ata_port *ap)
implement the detect logic */
if (ali_cable_override(pdev))
- return ATA_CBL_PATA80;
+ return ATA_CBL_PATA40_SHORT;
/* Host view cable detect 0x4A bit 0 primary bit 1 secondary
Bit set for 40 pin */
@@ -337,9 +337,6 @@ static struct scsi_host_template ali_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- /* Keep LBA28 counts so large I/O's don't turn LBA48 and PIO
- with older controllers. Not locked so will grow on C5 or later */
- .max_sectors = 255,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -348,6 +345,8 @@ static struct scsi_host_template ali_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
/*
@@ -497,6 +496,69 @@ static struct ata_port_operations ali_c5_port_ops = {
.host_stop = ata_host_stop
};
+
+/**
+ * ali_init_chipset - chip setup function
+ * @pdev: PCI device of ATA controller
+ *
+ * Perform the setup on the device that must be done both at boot
+ * and at resume time.
+ */
+
+static void ali_init_chipset(struct pci_dev *pdev)
+{
+ u8 rev, tmp;
+ struct pci_dev *north, *isa_bridge;
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+
+ /*
+ * The chipset revision selects the driver operations and
+ * mode data.
+ */
+
+ if (rev >= 0x20 && rev < 0xC2) {
+ /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
+ pci_read_config_byte(pdev, 0x4B, &tmp);
+ /* Clear CD-ROM DMA write bit */
+ tmp &= 0x7F;
+ pci_write_config_byte(pdev, 0x4B, tmp);
+ } else if (rev >= 0xC2) {
+ /* Enable cable detection logic */
+ pci_read_config_byte(pdev, 0x4B, &tmp);
+ pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
+ }
+ north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+ isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+
+ if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) {
+ /* Configure the ALi bridge logic. For non ALi rely on BIOS.
+ Set the south bridge enable bit */
+ pci_read_config_byte(isa_bridge, 0x79, &tmp);
+ if (rev == 0xC2)
+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
+ else if (rev > 0xC2 && rev < 0xC5)
+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
+ }
+ if (rev >= 0x20) {
+ /*
+ * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
+ * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
+ * via 0x54/55.
+ */
+ pci_read_config_byte(pdev, 0x53, &tmp);
+ if (rev <= 0x20)
+ tmp &= ~0x02;
+ if (rev >= 0xc7)
+ tmp |= 0x03;
+ else
+ tmp |= 0x01; /* CD_ROM enable for DMA */
+ pci_write_config_byte(pdev, 0x53, tmp);
+ }
+ pci_dev_put(isa_bridge);
+ pci_dev_put(north);
+ ata_pci_clear_simplex(pdev);
+}
/**
* ali_init_one - discovery callback
* @pdev: PCI device ID
@@ -570,7 +632,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static struct ata_port_info *port_info[2];
u8 rev, tmp;
- struct pci_dev *north, *isa_bridge;
+ struct pci_dev *isa_bridge;
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
@@ -582,11 +644,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rev < 0x20) {
port_info[0] = port_info[1] = &info_early;
} else if (rev < 0xC2) {
- /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
- pci_read_config_byte(pdev, 0x4B, &tmp);
- /* Clear CD-ROM DMA write bit */
- tmp &= 0x7F;
- pci_write_config_byte(pdev, 0x4B, tmp);
port_info[0] = port_info[1] = &info_20;
} else if (rev == 0xC2) {
port_info[0] = port_info[1] = &info_c2;
@@ -597,54 +654,25 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
} else
port_info[0] = port_info[1] = &info_c5;
- if (rev >= 0xC2) {
- /* Enable cable detection logic */
- pci_read_config_byte(pdev, 0x4B, &tmp);
- pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
- }
-
- north = pci_get_slot(pdev->bus, PCI_DEVFN(0,0));
+ ali_init_chipset(pdev);
+
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
-
- if (north && north->vendor == PCI_VENDOR_ID_AL) {
- /* Configure the ALi bridge logic. For non ALi rely on BIOS.
- Set the south bridge enable bit */
- pci_read_config_byte(isa_bridge, 0x79, &tmp);
- if (rev == 0xC2)
- pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
- else if (rev > 0xC2)
- pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
- }
-
- if (rev >= 0x20) {
- if (rev < 0xC2) {
- /* Are we paired with a UDMA capable chip */
- pci_read_config_byte(isa_bridge, 0x5E, &tmp);
- if ((tmp & 0x1E) == 0x12)
- port_info[0] = port_info[1] = &info_20_udma;
- }
- /*
- * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
- * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
- * via 0x54/55.
- */
- pci_read_config_byte(pdev, 0x53, &tmp);
- if (rev <= 0x20)
- tmp &= ~0x02;
- if (rev >= 0xc7)
- tmp |= 0x03;
- else
- tmp |= 0x01; /* CD_ROM enable for DMA */
- pci_write_config_byte(pdev, 0x53, tmp);
+ if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
+ /* Are we paired with a UDMA capable chip */
+ pci_read_config_byte(isa_bridge, 0x5E, &tmp);
+ if ((tmp & 0x1E) == 0x12)
+ port_info[0] = port_info[1] = &info_20_udma;
+ pci_dev_put(isa_bridge);
}
-
- pci_dev_put(isa_bridge);
- pci_dev_put(north);
-
- ata_pci_clear_simplex(pdev);
return ata_pci_init_one(pdev, port_info, 2);
}
+static int ali_reinit_one(struct pci_dev *pdev)
+{
+ ali_init_chipset(pdev);
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id ali[] = {
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), },
@@ -656,7 +684,9 @@ static struct pci_driver ali_pci_driver = {
.name = DRV_NAME,
.id_table = ali,
.probe = ali_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ali_reinit_one,
};
static int __init ali_init(void)
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 8be46a63af74..a6b330089f22 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_amd"
-#define DRV_VERSION "0.2.4"
+#define DRV_VERSION "0.2.7"
/**
* timing_setup - shared timing computation and load
@@ -326,7 +326,6 @@ static struct scsi_host_template amd_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -335,6 +334,8 @@ static struct scsi_host_template amd_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations amd33_port_ops = {
@@ -662,6 +663,23 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+static int amd_reinit_one(struct pci_dev *pdev)
+{
+ if (pdev->vendor == PCI_VENDOR_ID_AMD) {
+ u8 fifo;
+ pci_read_config_byte(pdev, 0x41, &fifo);
+ if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
+ /* FIFO is broken */
+ pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
+ else
+ pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
+ if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
+ pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
+ ata_pci_clear_simplex(pdev);
+ }
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id amd[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 },
@@ -689,7 +707,9 @@ static struct pci_driver amd_pci_driver = {
.name = DRV_NAME,
.id_table = amd,
.probe = amd_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = amd_reinit_one,
};
static int __init amd_init(void)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 2cd30761ca1f..37bc1323bda7 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -307,7 +307,6 @@ static struct scsi_host_template artop_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 4e1d3b59adbb..6f6672c55131 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -22,7 +22,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_atiixp"
-#define DRV_VERSION "0.4.3"
+#define DRV_VERSION "0.4.4"
enum {
ATIIXP_IDE_PIO_TIMING = 0x40,
@@ -209,7 +209,6 @@ static struct scsi_host_template atiixp_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -218,6 +217,8 @@ static struct scsi_host_template atiixp_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations atiixp_port_ops = {
@@ -281,7 +282,9 @@ static struct pci_driver atiixp_pci_driver = {
.name = DRV_NAME,
.id_table = atiixp,
.probe = atiixp_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .resume = ata_pci_device_resume,
+ .suspend = ata_pci_device_suspend,
};
static int __init atiixp_init(void)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 29a60df465da..15841a563694 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -31,7 +31,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_cmd64x"
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.2.2"
/*
* CMD64x specific registers definition.
@@ -268,7 +268,6 @@ static struct scsi_host_template cmd64x_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -277,6 +276,8 @@ static struct scsi_host_template cmd64x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cmd64x_port_ops = {
@@ -469,6 +470,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+static int cmd64x_reinit_one(struct pci_dev *pdev)
+{
+ u8 mrdmode;
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pdev, MRDMODE, &mrdmode);
+ mrdmode &= ~ 0x30; /* IRQ set up */
+ mrdmode |= 0x02; /* Memory read line enable */
+ pci_write_config_byte(pdev, MRDMODE, mrdmode);
+#ifdef CONFIG_PPC
+ pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
+#endif
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id cmd64x[] = {
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
@@ -482,7 +497,9 @@ static struct pci_driver cmd64x_pci_driver = {
.name = DRV_NAME,
.id_table = cmd64x,
.probe = cmd64x_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = cmd64x_reinit_one,
};
static int __init cmd64x_init(void)
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 33d2b88f9c79..9f165a8e032d 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_cs5520"
-#define DRV_VERSION "0.6.2"
+#define DRV_VERSION "0.6.3"
struct pio_clocks
{
@@ -159,7 +159,6 @@ static struct scsi_host_template cs5520_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -168,6 +167,8 @@ static struct scsi_host_template cs5520_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cs5520_port_ops = {
@@ -297,6 +298,22 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
dev_set_drvdata(dev, NULL);
}
+/**
+ * cs5520_reinit_one - device resume
+ * @pdev: PCI device
+ *
+ * Do any reconfiguration work needed by a resume from RAM. We need
+ * to restore DMA mode support on BIOSen which disabled it
+ */
+
+static int cs5520_reinit_one(struct pci_dev *pdev)
+{
+ u8 pcicfg;
+ pci_read_config_byte(pdev, 0x60, &pcicfg);
+ if ((pcicfg & 0x40) == 0)
+ pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
+ return ata_pci_device_resume(pdev);
+}
/* For now keep DMA off. We can set it for all but A rev CS5510 once the
core ATA code can handle it */
@@ -311,7 +328,9 @@ static struct pci_driver cs5520_pci_driver = {
.name = DRV_NAME,
.id_table = pata_cs5520,
.probe = cs5520_init_one,
- .remove = cs5520_remove_one
+ .remove = cs5520_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = cs5520_reinit_one,
};
static int __init cs5520_init(void)
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 981f49223469..1c628014dae6 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -35,7 +35,7 @@
#include <linux/dmi.h>
#define DRV_NAME "pata_cs5530"
-#define DRV_VERSION "0.6"
+#define DRV_VERSION "0.7.1"
/**
* cs5530_set_piomode - PIO setup
@@ -173,7 +173,6 @@ static struct scsi_host_template cs5530_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -182,6 +181,8 @@ static struct scsi_host_template cs5530_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cs5530_port_ops = {
@@ -239,38 +240,18 @@ static int cs5530_is_palmax(void)
return 0;
}
+
/**
- * cs5530_init_one - Initialise a CS5530
- * @dev: PCI device
- * @id: Entry in match table
+ * cs5530_init_chip - Chipset init
*
- * Install a driver for the newly found CS5530 companion chip. Most of
- * this is just housekeeping. We have to set the chip up correctly and
- * turn off various bits of emulation magic.
+ * Perform the chip initialisation work that is shared between both
+ * setup and resume paths
*/
-
-static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+
+static int cs5530_init_chip(void)
{
- int compiler_warning_pointless_fix;
- struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
- static struct ata_port_info info = {
- .sht = &cs5530_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
- .port_ops = &cs5530_port_ops
- };
- /* The docking connector doesn't do UDMA, and it seems not MWDMA */
- static struct ata_port_info info_palmax_secondary = {
- .sht = &cs5530_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .port_ops = &cs5530_port_ops
- };
- static struct ata_port_info *port_info[2] = { &info, &info };
+ struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL;
- dev = NULL;
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
@@ -291,7 +272,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
}
pci_set_master(cs5530_0);
- compiler_warning_pointless_fix = pci_set_mwi(cs5530_0);
+ pci_set_mwi(cs5530_0);
/*
* Set PCI CacheLineSize to 16-bytes:
@@ -339,13 +320,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_dev_put(master_0);
pci_dev_put(cs5530_0);
-
- if (cs5530_is_palmax())
- port_info[1] = &info_palmax_secondary;
-
- /* Now kick off ATA set up */
- return ata_pci_init_one(dev, port_info, 2);
-
+ return 0;
fail_put:
if (master_0)
pci_dev_put(master_0);
@@ -354,6 +329,53 @@ fail_put:
return -ENODEV;
}
+/**
+ * cs5530_init_one - Initialise a CS5530
+ * @dev: PCI device
+ * @id: Entry in match table
+ *
+ * Install a driver for the newly found CS5530 companion chip. Most of
+ * this is just housekeeping. We have to set the chip up correctly and
+ * turn off various bits of emulation magic.
+ */
+
+static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ static struct ata_port_info info = {
+ .sht = &cs5530_sht,
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x07,
+ .port_ops = &cs5530_port_ops
+ };
+ /* The docking connector doesn't do UDMA, and it seems not MWDMA */
+ static struct ata_port_info info_palmax_secondary = {
+ .sht = &cs5530_sht,
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .port_ops = &cs5530_port_ops
+ };
+ static struct ata_port_info *port_info[2] = { &info, &info };
+
+ /* Chip initialisation */
+ if (cs5530_init_chip())
+ return -ENODEV;
+
+ if (cs5530_is_palmax())
+ port_info[1] = &info_palmax_secondary;
+
+ /* Now kick off ATA set up */
+ return ata_pci_init_one(pdev, port_info, 2);
+}
+
+static int cs5530_reinit_one(struct pci_dev *pdev)
+{
+ /* If we fail on resume we are doomed */
+ BUG_ON(cs5530_init_chip());
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id cs5530[] = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
@@ -364,7 +386,9 @@ static struct pci_driver cs5530_pci_driver = {
.name = DRV_NAME,
.id_table = cs5530,
.probe = cs5530_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = cs5530_reinit_one,
};
static int __init cs5530_init(void)
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 8dafa4a49fdc..e3efec4ffc79 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -39,7 +39,7 @@
#include <asm/msr.h>
#define DRV_NAME "cs5535"
-#define DRV_VERSION "0.2.10"
+#define DRV_VERSION "0.2.11"
/*
* The Geode (Aka Athlon GX now) uses an internal MSR based
@@ -177,7 +177,6 @@ static struct scsi_host_template cs5535_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -186,6 +185,8 @@ static struct scsi_host_template cs5535_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cs5535_port_ops = {
@@ -268,7 +269,9 @@ static struct pci_driver cs5535_pci_driver = {
.name = DRV_NAME,
.id_table = cs5535,
.probe = cs5535_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init cs5535_init(void)
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 5a0b811907ee..e2a95699bae7 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -18,7 +18,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_cypress"
-#define DRV_VERSION "0.1.2"
+#define DRV_VERSION "0.1.4"
/* here are the offset definitions for the registers */
@@ -128,7 +128,6 @@ static struct scsi_host_template cy82c693_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -137,6 +136,8 @@ static struct scsi_host_template cy82c693_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations cy82c693_port_ops = {
@@ -204,7 +205,9 @@ static struct pci_driver cy82c693_pci_driver = {
.name = DRV_NAME,
.id_table = cy82c693,
.probe = cy82c693_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init cy82c693_init(void)
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 755f79279de3..edf8a63f50af 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -22,7 +22,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_efar"
-#define DRV_VERSION "0.4.2"
+#define DRV_VERSION "0.4.3"
/**
* efar_pre_reset - check for 40/80 pin
@@ -226,7 +226,6 @@ static struct scsi_host_template efar_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -235,6 +234,8 @@ static struct scsi_host_template efar_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static const struct ata_port_operations efar_ops = {
@@ -316,6 +317,8 @@ static struct pci_driver efar_pci_driver = {
.id_table = efar_pci_tbl,
.probe = efar_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init efar_init(void)
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index c0e150a9586b..2663599a7c02 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -27,7 +27,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt366"
-#define DRV_VERSION "0.5"
+#define DRV_VERSION "0.5.3"
struct hpt_clock {
u8 xfer_speed;
@@ -222,9 +222,17 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
static int hpt36x_pre_reset(struct ata_port *ap)
{
+ static const struct pci_bits hpt36x_enable_bits[] = {
+ { 0x50, 1, 0x04, 0x04 },
+ { 0x54, 1, 0x04, 0x04 }
+ };
+
u8 ata66;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
+ return -ENOENT;
+
pci_read_config_byte(pdev, 0x5A, &ata66);
if (ata66 & (1 << ap->port_no))
ap->cbl = ATA_CBL_PATA40;
@@ -322,7 +330,6 @@ static struct scsi_host_template hpt36x_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -331,6 +338,8 @@ static struct scsi_host_template hpt36x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
/*
@@ -373,6 +382,27 @@ static struct ata_port_operations hpt366_port_ops = {
};
/**
+ * hpt36x_init_chipset - common chip setup
+ * @dev: PCI device
+ *
+ * Perform the chip setup work that must be done at both init and
+ * resume time
+ */
+
+static void hpt36x_init_chipset(struct pci_dev *dev)
+{
+ u8 drive_fast;
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
+
+ pci_read_config_byte(dev, 0x51, &drive_fast);
+ if (drive_fast & 0x80)
+ pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
+}
+
+/**
* hpt36x_init_one - Initialise an HPT366/368
* @dev: PCI device
* @id: Entry in match table
@@ -407,7 +437,6 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
u32 class_rev;
u32 reg1;
- u8 drive_fast;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -417,14 +446,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (class_rev > 2)
return -ENODEV;
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
- pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
- pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
-
- pci_read_config_byte(dev, 0x51, &drive_fast);
- if (drive_fast & 0x80)
- pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
+ hpt36x_init_chipset(dev);
pci_read_config_dword(dev, 0x40, &reg1);
@@ -445,9 +467,15 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return ata_pci_init_one(dev, port_info, 2);
}
+static int hpt36x_reinit_one(struct pci_dev *dev)
+{
+ hpt36x_init_chipset(dev);
+ return ata_pci_device_resume(dev);
+}
+
+
static const struct pci_device_id hpt36x[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
-
{ },
};
@@ -455,7 +483,9 @@ static struct pci_driver hpt36x_pci_driver = {
.name = DRV_NAME,
.id_table = hpt36x,
.probe = hpt36x_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = hpt36x_reinit_one,
};
static int __init hpt36x_init(void)
@@ -463,13 +493,11 @@ static int __init hpt36x_init(void)
return pci_register_driver(&hpt36x_pci_driver);
}
-
static void __exit hpt36x_exit(void)
{
pci_unregister_driver(&hpt36x_pci_driver);
}
-
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368");
MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 1eeb16f0fb02..47082df7199e 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -768,7 +768,6 @@ static struct scsi_host_template hpt37x_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 47d7664e9eee..f6817b4093a4 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -334,7 +334,6 @@ static struct scsi_host_template hpt3x2n_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index d216cc564b56..5f1d385eb592 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -23,7 +23,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x3"
-#define DRV_VERSION "0.4.1"
+#define DRV_VERSION "0.4.2"
static int hpt3x3_probe_init(struct ata_port *ap)
{
@@ -111,7 +111,6 @@ static struct scsi_host_template hpt3x3_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -120,6 +119,8 @@ static struct scsi_host_template hpt3x3_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations hpt3x3_port_ops = {
@@ -158,6 +159,27 @@ static struct ata_port_operations hpt3x3_port_ops = {
};
/**
+ * hpt3x3_init_chipset - chip setup
+ * @dev: PCI device
+ *
+ * Perform the setup required at boot and on resume.
+ */
+
+static void hpt3x3_init_chipset(struct pci_dev *dev)
+{
+ u16 cmd;
+ /* Initialize the board */
+ pci_write_config_word(dev, 0x80, 0x00);
+ /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (cmd & PCI_COMMAND_MEMORY)
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
+ else
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
+}
+
+
+/**
* hpt3x3_init_one - Initialise an HPT343/363
* @dev: PCI device
* @id: Entry in match table
@@ -178,21 +200,18 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt3x3_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
- u16 cmd;
-
- /* Initialize the board */
- pci_write_config_word(dev, 0x80, 0x00);
- /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (cmd & PCI_COMMAND_MEMORY)
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
- else
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
+ hpt3x3_init_chipset(dev);
/* Now kick off ATA set up */
return ata_pci_init_one(dev, port_info, 2);
}
+static int hpt3x3_reinit_one(struct pci_dev *dev)
+{
+ hpt3x3_init_chipset(dev);
+ return ata_pci_device_resume(dev);
+}
+
static const struct pci_device_id hpt3x3[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
@@ -203,7 +222,9 @@ static struct pci_driver hpt3x3_pci_driver = {
.name = DRV_NAME,
.id_table = hpt3x3,
.probe = hpt3x3_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = hpt3x3_reinit_one,
};
static int __init hpt3x3_init(void)
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 40ca2b82b7fc..a97d55ae95c9 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -27,7 +27,6 @@ static struct scsi_host_template isapnp_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 7f68f14be6fd..0b56ff3d1cfe 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -80,7 +80,7 @@
#define DRV_NAME "pata_it821x"
-#define DRV_VERSION "0.3.2"
+#define DRV_VERSION "0.3.3"
struct it821x_dev
{
@@ -666,9 +666,6 @@ static struct scsi_host_template it821x_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- /* 255 sectors to begin with. This is locked in smart mode but not
- in pass through */
- .max_sectors = 255,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -677,6 +674,8 @@ static struct scsi_host_template it821x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations it821x_smart_port_ops = {
@@ -809,6 +808,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+static int it821x_reinit_one(struct pci_dev *pdev)
+{
+ /* Resume - turn raid back off if need be */
+ if (it8212_noraid)
+ it821x_disable_raid(pdev);
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id it821x[] = {
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
@@ -820,7 +827,9 @@ static struct pci_driver it821x_pci_driver = {
.name = DRV_NAME,
.id_table = it821x,
.probe = it821x_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = it821x_reinit_one,
};
static int __init it821x_init(void)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
new file mode 100644
index 000000000000..cb8924109f59
--- /dev/null
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -0,0 +1,271 @@
+/*
+ * ixp4xx PATA/Compact Flash driver
+ * Copyright (c) 2006 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * An ATA driver to handle a Compact Flash connected
+ * to the ixp4xx expansion bus in TrueIDE mode. The CF
+ * must have it chip selects connected to two CS lines
+ * on the ixp4xx. The interrupt line is optional, if not
+ * specified the driver will run in polling mode.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/libata.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <scsi/scsi_host.h>
+
+#define DRV_NAME "pata_ixp4xx_cf"
+#define DRV_VERSION "0.1.1"
+
+static void ixp4xx_set_mode(struct ata_port *ap)
+{
+ int i;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ struct ata_device *dev = &ap->device[i];
+ if (ata_dev_enabled(dev)) {
+ dev->pio_mode = XFER_PIO_0;
+ dev->xfer_mode = XFER_PIO_0;
+ dev->xfer_shift = ATA_SHIFT_PIO;
+ dev->flags |= ATA_DFLAG_PIO;
+ }
+ }
+}
+
+static void ixp4xx_phy_reset(struct ata_port *ap)
+{
+ ap->cbl = ATA_CBL_PATA40;
+ ata_port_probe(ap);
+ ata_bus_reset(ap);
+}
+
+static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
+ unsigned int buflen, int write_data)
+{
+ unsigned int i;
+ unsigned int words = buflen >> 1;
+ u16 *buf16 = (u16 *) buf;
+ struct ata_port *ap = adev->ap;
+ void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
+ struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
+
+ /* set the expansion bus in 16bit mode and restore
+ * 8 bit mode after the transaction.
+ */
+ *data->cs0_cfg &= ~(0x01);
+ udelay(100);
+
+ /* Transfer multiple of 2 bytes */
+ if (write_data) {
+ for (i = 0; i < words; i++)
+ writew(buf16[i], mmio);
+ } else {
+ for (i = 0; i < words; i++)
+ buf16[i] = readw(mmio);
+ }
+
+ /* Transfer trailing 1 byte, if any. */
+ if (unlikely(buflen & 0x01)) {
+ u16 align_buf[1] = { 0 };
+ unsigned char *trailing_buf = buf + buflen - 1;
+
+ if (write_data) {
+ memcpy(align_buf, trailing_buf, 1);
+ writew(align_buf[0], mmio);
+ } else {
+ align_buf[0] = readw(mmio);
+ memcpy(trailing_buf, align_buf, 1);
+ }
+ }
+
+ udelay(100);
+ *data->cs0_cfg |= 0x01;
+}
+
+static void ixp4xx_irq_clear(struct ata_port *ap)
+{
+}
+
+static void ixp4xx_host_stop (struct ata_host *host)
+{
+ struct ixp4xx_pata_data *data = host->dev->platform_data;
+
+ iounmap(data->cs0);
+ iounmap(data->cs1);
+}
+
+static struct scsi_host_template ixp4xx_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations ixp4xx_port_ops = {
+ .set_mode = ixp4xx_set_mode,
+ .mode_filter = ata_pci_default_filter,
+
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .eng_timeout = ata_eng_timeout,
+ .data_xfer = ixp4xx_mmio_data_xfer,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ixp4xx_irq_clear,
+
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = ixp4xx_host_stop,
+
+ .phy_reset = ixp4xx_phy_reset,
+};
+
+static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
+ struct ixp4xx_pata_data *data)
+{
+ ioaddr->cmd_addr = (unsigned long) data->cs0;
+ ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
+ ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
+
+ ata_std_ports(ioaddr);
+
+#ifndef __ARMEB__
+
+ /* adjust the addresses to handle the address swizzling of the
+ * ixp4xx in little endian mode.
+ */
+
+ ioaddr->data_addr ^= 0x02;
+ ioaddr->cmd_addr ^= 0x03;
+ ioaddr->altstatus_addr ^= 0x03;
+ ioaddr->ctl_addr ^= 0x03;
+ ioaddr->error_addr ^= 0x03;
+ ioaddr->feature_addr ^= 0x03;
+ ioaddr->nsect_addr ^= 0x03;
+ ioaddr->lbal_addr ^= 0x03;
+ ioaddr->lbam_addr ^= 0x03;
+ ioaddr->lbah_addr ^= 0x03;
+ ioaddr->device_addr ^= 0x03;
+ ioaddr->status_addr ^= 0x03;
+ ioaddr->command_addr ^= 0x03;
+#endif
+}
+
+static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
+{
+ int ret;
+ unsigned int irq;
+ struct resource *cs0, *cs1;
+ struct ata_probe_ent ae;
+
+ struct ixp4xx_pata_data *data = pdev->dev.platform_data;
+
+ cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+ if (!cs0 || !cs1)
+ return -EINVAL;
+
+ pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+ data->cs0 = ioremap(cs0->start, 0x1000);
+ data->cs1 = ioremap(cs1->start, 0x1000);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq)
+ set_irq_type(irq, IRQT_HIGH);
+
+ /* Setup expansion bus chip selects */
+ *data->cs0_cfg = data->cs0_bits;
+ *data->cs1_cfg = data->cs1_bits;
+
+ memset(&ae, 0, sizeof(struct ata_probe_ent));
+ INIT_LIST_HEAD(&ae.node);
+
+ ae.dev = &pdev->dev;
+ ae.port_ops = &ixp4xx_port_ops;
+ ae.sht = &ixp4xx_sht;
+ ae.n_ports = 1;
+ ae.pio_mask = 0x1f; /* PIO4 */
+ ae.irq = irq;
+ ae.irq_flags = 0;
+ ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
+ | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
+
+ /* run in polling mode if no irq has been assigned */
+ if (!irq)
+ ae.port_flags |= ATA_FLAG_PIO_POLLING;
+
+ ixp4xx_setup_port(&ae.port[0], data);
+
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+ ret = ata_device_add(&ae);
+ if (ret == 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
+{
+ struct ata_host *host = platform_get_drvdata(dev);
+
+ ata_host_remove(host);
+ platform_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ixp4xx_pata_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ixp4xx_pata_probe,
+ .remove = __devexit_p(ixp4xx_pata_remove),
+};
+
+static int __init ixp4xx_pata_init(void)
+{
+ return platform_driver_register(&ixp4xx_pata_platform_driver);
+}
+
+static void __exit ixp4xx_pata_exit(void)
+{
+ platform_driver_unregister(&ixp4xx_pata_platform_driver);
+}
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("low-level driver for ixp4xx Compact Flash PATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(ixp4xx_pata_init);
+module_exit(ixp4xx_pata_exit);
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 0210b10d49cd..2d661cb4df3c 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -19,7 +19,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_jmicron"
-#define DRV_VERSION "0.1.2"
+#define DRV_VERSION "0.1.4"
typedef enum {
PORT_PATA0 = 0,
@@ -128,8 +128,6 @@ static struct scsi_host_template jmicron_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- /* Special handling needed if you have sector or LBA48 limits */
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -213,12 +211,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
/* FIXME: We may want a way to override this in future */
pci_write_config_byte(pdev, 0x41, 0xa1);
- }
-
- /* PATA controller is fn 1, AHCI is fn 0 */
- if (PCI_FUNC(pdev->devfn) != 1)
- return -ENODEV;
+ /* PATA controller is fn 1, AHCI is fn 0 */
+ if (PCI_FUNC(pdev->devfn) != 1)
+ return -ENODEV;
+ }
if ( id->driver_data == 365 || id->driver_data == 366) {
/* The 365/66 have two PATA channels, redirect the second */
pci_read_config_dword(pdev, 0x80, &reg);
@@ -229,6 +226,27 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
return ata_pci_init_one(pdev, port_info, 2);
}
+static int jmicron_reinit_one(struct pci_dev *pdev)
+{
+ u32 reg;
+
+ switch(pdev->device) {
+ case PCI_DEVICE_ID_JMICRON_JMB368:
+ break;
+ case PCI_DEVICE_ID_JMICRON_JMB365:
+ case PCI_DEVICE_ID_JMICRON_JMB366:
+ /* Restore mapping or disks swap and boy does it get ugly */
+ pci_read_config_dword(pdev, 0x80, &reg);
+ reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
+ pci_write_config_dword(pdev, 0x80, reg);
+ /* Fall through */
+ default:
+ /* Make sure AHCI is turned back on */
+ pci_write_config_byte(pdev, 0x41, 0xa1);
+ }
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id jmicron_pci_tbl[] = {
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
@@ -244,6 +262,8 @@ static struct pci_driver jmicron_pci_driver = {
.id_table = jmicron_pci_tbl,
.probe = jmicron_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = jmicron_reinit_one,
};
static int __init jmicron_init(void)
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index b39078b2a47b..c7d1738e4e69 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -128,7 +128,6 @@ static struct scsi_host_template legacy_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
new file mode 100644
index 000000000000..1c810ea00253
--- /dev/null
+++ b/drivers/ata/pata_marvell.c
@@ -0,0 +1,224 @@
+/*
+ * Marvell PATA driver.
+ *
+ * For the moment we drive the PATA port in legacy mode. That
+ * isn't making full use of the device functionality but it is
+ * easy to get working.
+ *
+ * (c) 2006 Red Hat <alan@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define DRV_NAME "pata_marvell"
+#define DRV_VERSION "0.1.1"
+
+/**
+ * marvell_pre_reset - check for 40/80 pin
+ * @ap: Port
+ *
+ * Perform the PATA port setup we need.
+ */
+
+static int marvell_pre_reset(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 devices;
+ void __iomem *barp;
+ int i;
+
+ /* Check if our port is enabled */
+
+ barp = pci_iomap(pdev, 5, 0x10);
+ if (barp == NULL)
+ return -ENOMEM;
+ printk("BAR5:");
+ for(i = 0; i <= 0x0F; i++)
+ printk("%02X:%02X ", i, readb(barp + i));
+ printk("\n");
+
+ devices = readl(barp + 0x0C);
+ pci_iounmap(pdev, barp);
+
+ if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
+ (!(devices & 0x10))) /* PATA enable ? */
+ return -ENOENT;
+
+ /* Cable type */
+ switch(ap->port_no)
+ {
+ case 0:
+ if (inb(ap->ioaddr.bmdma_addr + 1) & 1)
+ ap->cbl = ATA_CBL_PATA40;
+ else
+ ap->cbl = ATA_CBL_PATA80;
+ break;
+
+ case 1: /* Legacy SATA port */
+ ap->cbl = ATA_CBL_SATA;
+ break;
+ }
+ return ata_std_prereset(ap);
+}
+
+/**
+ * marvell_error_handler - Setup and error handler
+ * @ap: Port to handle
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void marvell_error_handler(struct ata_port *ap)
+{
+ return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset,
+ NULL, ata_std_postreset);
+}
+
+/* No PIO or DMA methods needed for this device */
+
+static struct scsi_host_template marvell_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ /* Use standard CHS mapping rules */
+ .bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
+};
+
+static const struct ata_port_operations marvell_ops = {
+ .port_disable = ata_port_disable,
+
+ /* Task file is PCI ATA format, use helpers */
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = marvell_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ /* BMDMA handling is PCI ATA format, use helpers */
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_pio_data_xfer,
+
+ /* Timeout handling */
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+
+ /* Generic PATA PCI ATA helpers */
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = ata_host_stop,
+};
+
+
+/**
+ * marvell_init_one - Register Marvell ATA PCI device with kernel services
+ * @pdev: PCI device to register
+ * @ent: Entry in marvell_pci_tbl matching with @pdev
+ *
+ * Called from kernel PCI layer.
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, or -ERRNO value.
+ */
+
+static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ static struct ata_port_info info = {
+ .sht = &marvell_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x3f,
+
+ .port_ops = &marvell_ops,
+ };
+ static struct ata_port_info info_sata = {
+ .sht = &marvell_sht,
+ /* Slave possible as its magically mapped not real */
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+
+ .port_ops = &marvell_ops,
+ };
+ struct ata_port_info *port_info[2] = { &info, &info_sata };
+ int n_port = 2;
+
+ if (pdev->device == 0x6101)
+ n_port = 1;
+
+ return ata_pci_init_one(pdev, port_info, n_port);
+}
+
+static const struct pci_device_id marvell_pci_tbl[] = {
+ { PCI_DEVICE(0x11AB, 0x6101), },
+ { PCI_DEVICE(0x11AB, 0x6145), },
+ { } /* terminate list */
+};
+
+static struct pci_driver marvell_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = marvell_pci_tbl,
+ .probe = marvell_init_one,
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+};
+
+static int __init marvell_init(void)
+{
+ return pci_register_driver(&marvell_pci_driver);
+}
+
+static void __exit marvell_exit(void)
+{
+ pci_unregister_driver(&marvell_pci_driver);
+}
+
+module_init(marvell_init);
+module_exit(marvell_exit);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, marvell_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index e00d406bfdf5..4ccca938675e 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_mpiix"
-#define DRV_VERSION "0.7.2"
+#define DRV_VERSION "0.7.3"
enum {
IDETIM = 0x6C, /* IDE control register */
@@ -159,7 +159,6 @@ static struct scsi_host_template mpiix_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -168,6 +167,8 @@ static struct scsi_host_template mpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations mpiix_port_ops = {
@@ -285,7 +286,9 @@ static struct pci_driver mpiix_pci_driver = {
.name = DRV_NAME,
.id_table = mpiix,
.probe = mpiix_init_one,
- .remove = mpiix_remove_one
+ .remove = mpiix_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init mpiix_init(void)
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 1963a4d35873..cf7fe037471c 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -16,7 +16,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_netcell"
-#define DRV_VERSION "0.1.5"
+#define DRV_VERSION "0.1.6"
/**
* netcell_probe_init - check for 40/80 pin
@@ -54,8 +54,6 @@ static struct scsi_host_template netcell_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- /* Special handling needed if you have sector or LBA48 limits */
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -65,6 +63,8 @@ static struct scsi_host_template netcell_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static const struct ata_port_operations netcell_ops = {
@@ -153,6 +153,8 @@ static struct pci_driver netcell_pci_driver = {
.id_table = netcell_pci_tbl,
.probe = netcell_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init netcell_init(void)
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 7ec800f00ec8..c3032eb9010d 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -28,7 +28,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_ns87410"
-#define DRV_VERSION "0.4.2"
+#define DRV_VERSION "0.4.3"
/**
* ns87410_pre_reset - probe begin
@@ -149,7 +149,6 @@ static struct scsi_host_template ns87410_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -158,6 +157,8 @@ static struct scsi_host_template ns87410_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations ns87410_port_ops = {
@@ -210,7 +211,9 @@ static struct pci_driver ns87410_pci_driver = {
.name = DRV_NAME,
.id_table = ns87410,
.probe = ns87410_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init ns87410_init(void)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 8837256632e9..10ac3cc10181 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -224,7 +224,6 @@ static struct scsi_host_template oldpiix_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -233,6 +232,8 @@ static struct scsi_host_template oldpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static const struct ata_port_operations oldpiix_pata_ops = {
@@ -314,6 +315,8 @@ static struct pci_driver oldpiix_pci_driver = {
.id_table = oldpiix_pci_tbl,
.probe = oldpiix_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init oldpiix_init(void)
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index c6319cf50de4..c2988b0aa8ea 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -34,7 +34,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_opti"
-#define DRV_VERSION "0.2.5"
+#define DRV_VERSION "0.2.7"
enum {
READ_REG = 0, /* index of Read cycle timing register */
@@ -109,30 +109,6 @@ static void opti_write_reg(struct ata_port *ap, u8 val, int reg)
outb(0x83, regio + 2);
}
-#if 0
-/**
- * opti_read_reg - control register read
- * @ap: ATA port
- * @reg: control register number
- *
- * The Opti uses magic 'trapdoor' register accesses to do configuration
- * rather than using PCI space as other controllers do. The double inw
- * on the error register activates configuration mode. We can then read
- * the control register
- */
-
-static u8 opti_read_reg(struct ata_port *ap, int reg)
-{
- unsigned long regio = ap->ioaddr.cmd_addr;
- u8 ret;
- inw(regio + 1);
- inw(regio + 1);
- outb(3, regio + 2);
- ret = inb(regio + reg);
- outb(0x83, regio + 2);
-}
-#endif
-
/**
* opti_set_piomode - set initial PIO mode data
* @ap: ATA interface
@@ -195,7 +171,6 @@ static struct scsi_host_template opti_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -204,12 +179,13 @@ static struct scsi_host_template opti_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations opti_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = opti_set_piomode,
-/* .set_dmamode = opti_set_dmamode, */
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
@@ -267,7 +243,9 @@ static struct pci_driver opti_pci_driver = {
.name = DRV_NAME,
.id_table = opti,
.probe = opti_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init opti_init(void)
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 2f4770cce04e..80d111c569dc 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -33,7 +33,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_optidma"
-#define DRV_VERSION "0.2.2"
+#define DRV_VERSION "0.2.3"
enum {
READ_REG = 0, /* index of Read cycle timing register */
@@ -352,7 +352,6 @@ static struct scsi_host_template optidma_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -361,6 +360,8 @@ static struct scsi_host_template optidma_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations optidma_port_ops = {
@@ -522,7 +523,9 @@ static struct pci_driver optidma_pci_driver = {
.name = DRV_NAME,
.id_table = optidma,
.probe = optidma_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init optidma_init(void)
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 999922de476e..9ed7f58424a3 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -62,7 +62,6 @@ static struct scsi_host_template pcmcia_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -155,19 +154,12 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
-
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, &stk->parse));
- pdev->conf.ConfigBase = stk->parse.config.base;
- pdev->conf.Present = stk->parse.config.rmask[0];
/* See if we have a manufacturer identifier. Use it to set is_kme for
vendor quirks */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (!pcmcia_get_first_tuple(pdev, &tuple) && !pcmcia_get_tuple_data(pdev, &tuple) && !pcmcia_parse_tuple(pdev, &tuple, &stk->parse))
- is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
+ is_kme = ((pdev->manf_id == MANFID_KME) &&
+ ((pdev->card_id == PRODID_KME_KXLC005_A) ||
+ (pdev->card_id == PRODID_KME_KXLC005_B)));
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
@@ -357,8 +349,10 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
+ PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index beb6d10a234b..76dd1c935dbd 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -134,7 +134,6 @@ static struct scsi_host_template pdc2027x_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -854,7 +853,7 @@ static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
*/
static int __init pdc2027x_init(void)
{
- return pci_module_init(&pdc2027x_pci_driver);
+ return pci_register_driver(&pdc2027x_pci_driver);
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 6baf51b2fda1..ad691b9e7743 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -21,7 +21,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_pdc202xx_old"
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.2.3"
/**
* pdc2024x_pre_reset - probe begin
@@ -63,7 +63,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
}
/**
- * pdc_configure_piomode - set chip PIO timing
+ * pdc202xx_configure_piomode - set chip PIO timing
* @ap: ATA interface
* @adev: ATA device
* @pio: PIO mode
@@ -73,7 +73,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
* versa
*/
-static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
+static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
@@ -98,7 +98,7 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
}
/**
- * pdc_set_piomode - set initial PIO mode data
+ * pdc202xx_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
@@ -106,13 +106,13 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
* but we want to set the PIO timing by default.
*/
-static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
- pdc_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
+ pdc202xx_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
}
/**
- * pdc_configure_dmamode - set DMA mode in chip
+ * pdc202xx_configure_dmamode - set DMA mode in chip
* @ap: ATA interface
* @adev: ATA device
*
@@ -120,7 +120,7 @@ static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
* to occur.
*/
-static void pdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
@@ -184,7 +184,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
/* The DMA clocks may have been trashed by a reset. FIXME: make conditional
and move to qc_issue ? */
- pdc_set_dmamode(ap, qc->dev);
+ pdc202xx_set_dmamode(ap, qc->dev);
/* Cases the state machine will not complete correctly without help */
if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
@@ -254,7 +254,7 @@ static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
adev->max_sectors = 256;
}
-static struct scsi_host_template pdc_sht = {
+static struct scsi_host_template pdc202xx_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -262,7 +262,6 @@ static struct scsi_host_template pdc_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -271,12 +270,14 @@ static struct scsi_host_template pdc_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations pdc2024x_port_ops = {
.port_disable = ata_port_disable,
- .set_piomode = pdc_set_piomode,
- .set_dmamode = pdc_set_dmamode,
+ .set_piomode = pdc202xx_set_piomode,
+ .set_dmamode = pdc202xx_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -308,8 +309,8 @@ static struct ata_port_operations pdc2024x_port_ops = {
static struct ata_port_operations pdc2026x_port_ops = {
.port_disable = ata_port_disable,
- .set_piomode = pdc_set_piomode,
- .set_dmamode = pdc_set_dmamode,
+ .set_piomode = pdc202xx_set_piomode,
+ .set_dmamode = pdc202xx_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -340,11 +341,11 @@ static struct ata_port_operations pdc2026x_port_ops = {
.host_stop = ata_host_stop
};
-static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info[3] = {
{
- .sht = &pdc_sht,
+ .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -352,7 +353,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &pdc2024x_port_ops
},
{
- .sht = &pdc_sht,
+ .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -360,7 +361,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &pdc2026x_port_ops
},
{
- .sht = &pdc_sht,
+ .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -386,7 +387,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return ata_pci_init_one(dev, port_info, 2);
}
-static const struct pci_device_id pdc[] = {
+static const struct pci_device_id pdc202xx[] = {
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
@@ -396,28 +397,30 @@ static const struct pci_device_id pdc[] = {
{ },
};
-static struct pci_driver pdc_pci_driver = {
+static struct pci_driver pdc202xx_pci_driver = {
.name = DRV_NAME,
- .id_table = pdc,
- .probe = pdc_init_one,
- .remove = ata_pci_remove_one
+ .id_table = pdc202xx,
+ .probe = pdc202xx_init_one,
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
-static int __init pdc_init(void)
+static int __init pdc202xx_init(void)
{
- return pci_register_driver(&pdc_pci_driver);
+ return pci_register_driver(&pdc202xx_pci_driver);
}
-static void __exit pdc_exit(void)
+static void __exit pdc202xx_exit(void)
{
- pci_unregister_driver(&pdc_pci_driver);
+ pci_unregister_driver(&pdc202xx_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, pdc);
+MODULE_DEVICE_TABLE(pci, pdc202xx);
MODULE_VERSION(DRV_VERSION);
-module_init(pdc_init);
-module_exit(pdc_exit);
+module_init(pdc202xx_init);
+module_exit(pdc202xx_exit);
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
new file mode 100644
index 000000000000..443b1d85c6c4
--- /dev/null
+++ b/drivers/ata/pata_platform.c
@@ -0,0 +1,295 @@
+/*
+ * Generic platform device PATA driver
+ *
+ * Copyright (C) 2006 Paul Mundt
+ *
+ * Based on pata_pcmcia:
+ *
+ * Copyright 2005-2006 Red Hat Inc <alan@redhat.com>, all rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_host.h>
+#include <linux/ata.h>
+#include <linux/libata.h>
+#include <linux/platform_device.h>
+#include <linux/pata_platform.h>
+
+#define DRV_NAME "pata_platform"
+#define DRV_VERSION "0.1.2"
+
+static int pio_mask = 1;
+
+/*
+ * Provide our own set_mode() as we don't want to change anything that has
+ * already been configured..
+ */
+static void pata_platform_set_mode(struct ata_port *ap)
+{
+ int i;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ struct ata_device *dev = &ap->device[i];
+
+ if (ata_dev_enabled(dev)) {
+ /* We don't really care */
+ dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
+ dev->xfer_shift = ATA_SHIFT_PIO;
+ dev->flags |= ATA_DFLAG_PIO;
+ }
+ }
+}
+
+static void pata_platform_host_stop(struct ata_host *host)
+{
+ int i;
+
+ /*
+ * Unmap the bases for MMIO
+ */
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->flags & ATA_FLAG_MMIO) {
+ iounmap((void __iomem *)ap->ioaddr.ctl_addr);
+ iounmap((void __iomem *)ap->ioaddr.cmd_addr);
+ }
+ }
+}
+
+static struct scsi_host_template pata_platform_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations pata_platform_port_ops = {
+ .set_mode = pata_platform_set_mode,
+
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+
+ .data_xfer = ata_pio_data_xfer_noirq,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = pata_platform_host_stop
+};
+
+static void pata_platform_setup_port(struct ata_ioports *ioaddr,
+ struct pata_platform_info *info)
+{
+ unsigned int shift = 0;
+
+ /* Fixup the port shift for platforms that need it */
+ if (info && info->ioport_shift)
+ shift = info->ioport_shift;
+
+ ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift);
+ ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift);
+ ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
+ ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift);
+ ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift);
+ ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift);
+ ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift);
+ ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift);
+ ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift);
+ ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift);
+}
+
+/**
+ * pata_platform_probe - attach a platform interface
+ * @pdev: platform device
+ *
+ * Register a platform bus IDE interface. Such interfaces are PIO and we
+ * assume do not support IRQ sharing.
+ *
+ * Platform devices are expected to contain 3 resources per port:
+ *
+ * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
+ * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
+ * - IRQ (IORESOURCE_IRQ)
+ *
+ * If the base resources are both mem types, the ioremap() is handled
+ * here. For IORESOURCE_IO, it's assumed that there's no remapping
+ * necessary.
+ */
+static int __devinit pata_platform_probe(struct platform_device *pdev)
+{
+ struct resource *io_res, *ctl_res;
+ struct ata_probe_ent ae;
+ unsigned int mmio;
+ int ret;
+
+ /*
+ * Simple resource validation ..
+ */
+ if (unlikely(pdev->num_resources != 3)) {
+ dev_err(&pdev->dev, "invalid number of resources\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Get the I/O base first
+ */
+ io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (io_res == NULL) {
+ io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(io_res == NULL))
+ return -EINVAL;
+ }
+
+ /*
+ * Then the CTL base
+ */
+ ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
+ if (ctl_res == NULL) {
+ ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (unlikely(ctl_res == NULL))
+ return -EINVAL;
+ }
+
+ /*
+ * Check for MMIO
+ */
+ mmio = (( io_res->flags == IORESOURCE_MEM) &&
+ (ctl_res->flags == IORESOURCE_MEM));
+
+ /*
+ * Now that that's out of the way, wire up the port..
+ */
+ memset(&ae, 0, sizeof(struct ata_probe_ent));
+ INIT_LIST_HEAD(&ae.node);
+ ae.dev = &pdev->dev;
+ ae.port_ops = &pata_platform_port_ops;
+ ae.sht = &pata_platform_sht;
+ ae.n_ports = 1;
+ ae.pio_mask = pio_mask;
+ ae.irq = platform_get_irq(pdev, 0);
+ ae.irq_flags = 0;
+ ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+
+ /*
+ * Handle the MMIO case
+ */
+ if (mmio) {
+ ae.port_flags |= ATA_FLAG_MMIO;
+
+ ae.port[0].cmd_addr = (unsigned long)ioremap(io_res->start,
+ io_res->end - io_res->start + 1);
+ if (unlikely(!ae.port[0].cmd_addr)) {
+ dev_err(&pdev->dev, "failed to remap IO base\n");
+ return -ENXIO;
+ }
+
+ ae.port[0].ctl_addr = (unsigned long)ioremap(ctl_res->start,
+ ctl_res->end - ctl_res->start + 1);
+ if (unlikely(!ae.port[0].ctl_addr)) {
+ dev_err(&pdev->dev, "failed to remap CTL base\n");
+ ret = -ENXIO;
+ goto bad_remap;
+ }
+ } else {
+ ae.port[0].cmd_addr = io_res->start;
+ ae.port[0].ctl_addr = ctl_res->start;
+ }
+
+ ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
+
+ pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
+
+ if (unlikely(ata_device_add(&ae) == 0)) {
+ ret = -ENODEV;
+ goto add_failed;
+ }
+
+ return 0;
+
+add_failed:
+ if (ae.port[0].ctl_addr && mmio)
+ iounmap((void __iomem *)ae.port[0].ctl_addr);
+bad_remap:
+ if (ae.port[0].cmd_addr && mmio)
+ iounmap((void __iomem *)ae.port[0].cmd_addr);
+
+ return ret;
+}
+
+/**
+ * pata_platform_remove - unplug a platform interface
+ * @pdev: platform device
+ *
+ * A platform bus ATA device has been unplugged. Perform the needed
+ * cleanup. Also called on module unload for any active devices.
+ */
+static int __devexit pata_platform_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ata_host *host = dev_get_drvdata(dev);
+
+ ata_host_remove(host);
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver pata_platform_driver = {
+ .probe = pata_platform_probe,
+ .remove = __devexit_p(pata_platform_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pata_platform_init(void)
+{
+ return platform_driver_register(&pata_platform_driver);
+}
+
+static void __exit pata_platform_exit(void)
+{
+ platform_driver_unregister(&pata_platform_driver);
+}
+module_init(pata_platform_init);
+module_exit(pata_platform_exit);
+
+module_param(pio_mask, int, 0);
+
+MODULE_AUTHOR("Paul Mundt");
+MODULE_DESCRIPTION("low-level driver for platform device ATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 314938dea1fc..36f621abc390 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -157,7 +157,6 @@ static struct scsi_host_template qdi_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 048c2bb21ef1..065541d034ad 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -220,7 +220,6 @@ static struct scsi_host_template radisys_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -229,6 +228,8 @@ static struct scsi_host_template radisys_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static const struct ata_port_operations radisys_pata_ops = {
@@ -311,6 +312,8 @@ static struct pci_driver radisys_pci_driver = {
.id_table = radisys_pci_tbl,
.probe = radisys_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init radisys_init(void)
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index e4e5ea423fef..3677c642c9f9 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -21,7 +21,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_rz1000"
-#define DRV_VERSION "0.2.2"
+#define DRV_VERSION "0.2.3"
/**
@@ -83,7 +83,6 @@ static struct scsi_host_template rz1000_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -92,6 +91,8 @@ static struct scsi_host_template rz1000_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations rz1000_port_ops = {
@@ -129,6 +130,19 @@ static struct ata_port_operations rz1000_port_ops = {
.host_stop = ata_host_stop
};
+static int rz1000_fifo_disable(struct pci_dev *pdev)
+{
+ u16 reg;
+ /* Be exceptionally paranoid as we must be sure to apply the fix */
+ if (pci_read_config_word(pdev, 0x40, &reg) != 0)
+ return -1;
+ reg &= 0xDFFF;
+ if (pci_write_config_word(pdev, 0x40, reg) != 0)
+ return -1;
+ printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
+ return 0;
+}
+
/**
* rz1000_init_one - Register RZ1000 ATA PCI device with kernel services
* @pdev: PCI device to register
@@ -143,7 +157,6 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
{
static int printed_version;
struct ata_port_info *port_info[2];
- u16 reg;
static struct ata_port_info info = {
.sht = &rz1000_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -154,23 +167,25 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
if (!printed_version++)
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
- /* Be exceptionally paranoid as we must be sure to apply the fix */
- if (pci_read_config_word(pdev, 0x40, &reg) != 0)
- goto fail;
- reg &= 0xDFFF;
- if (pci_write_config_word(pdev, 0x40, reg) != 0)
- goto fail;
- printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
-
- port_info[0] = &info;
- port_info[1] = &info;
- return ata_pci_init_one(pdev, port_info, 2);
-fail:
+ if (rz1000_fifo_disable(pdev) == 0) {
+ port_info[0] = &info;
+ port_info[1] = &info;
+ return ata_pci_init_one(pdev, port_info, 2);
+ }
printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
/* Not safe to use so skip */
return -ENODEV;
}
+static int rz1000_reinit_one(struct pci_dev *pdev)
+{
+ /* If this fails on resume (which is a "cant happen" case), we
+ must stop as any progress risks data loss */
+ if (rz1000_fifo_disable(pdev))
+ panic("rz1000 fifo");
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id pata_rz1000[] = {
{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
@@ -182,7 +197,9 @@ static struct pci_driver rz1000_pci_driver = {
.name = DRV_NAME,
.id_table = pata_rz1000,
.probe = rz1000_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = rz1000_reinit_one,
};
static int __init rz1000_init(void)
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 0c75dae74764..a3b35bc50394 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -40,7 +40,7 @@
#include <linux/libata.h>
#define DRV_NAME "sc1200"
-#define DRV_VERSION "0.2.3"
+#define DRV_VERSION "0.2.4"
#define SC1200_REV_A 0x00
#define SC1200_REV_B1 0x01
@@ -186,7 +186,6 @@ static struct scsi_host_template sc1200_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -195,6 +194,8 @@ static struct scsi_host_template sc1200_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations sc1200_port_ops = {
@@ -264,7 +265,9 @@ static struct pci_driver sc1200_pci_driver = {
.name = DRV_NAME,
.id_table = sc1200,
.probe = sc1200_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init sc1200_init(void)
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index be7f60efcb61..f02b6a3b0f10 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_serverworks"
-#define DRV_VERSION "0.3.7"
+#define DRV_VERSION "0.3.9"
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
@@ -318,7 +318,6 @@ static struct scsi_host_template serverworks_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -327,6 +326,8 @@ static struct scsi_host_template serverworks_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations serverworks_osb4_port_ops = {
@@ -554,6 +555,30 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
return ata_pci_init_one(pdev, port_info, ports);
}
+static int serverworks_reinit_one(struct pci_dev *pdev)
+{
+ /* Force master latency timer to 64 PCI clocks */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
+
+ switch (pdev->device)
+ {
+ case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
+ serverworks_fixup_osb4(pdev);
+ break;
+ case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
+ ata_pci_clear_simplex(pdev);
+ /* fall through */
+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
+ serverworks_fixup_csb(pdev);
+ break;
+ case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
+ serverworks_fixup_ht1000(pdev);
+ break;
+ }
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id serverworks[] = {
{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
@@ -568,7 +593,9 @@ static struct pci_driver serverworks_pci_driver = {
.name = DRV_NAME,
.id_table = serverworks,
.probe = serverworks_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = serverworks_reinit_one,
};
static int __init serverworks_init(void)
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 11942fd03b55..32cf0bfa8921 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -33,7 +33,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_sil680"
-#define DRV_VERSION "0.3.2"
+#define DRV_VERSION "0.4.1"
/**
* sil680_selreg - return register base
@@ -218,7 +218,6 @@ static struct scsi_host_template sil680_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -263,32 +262,20 @@ static struct ata_port_operations sil680_port_ops = {
.host_stop = ata_host_stop
};
-static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+/**
+ * sil680_init_chip - chip setup
+ * @pdev: PCI device
+ *
+ * Perform all the chip setup which must be done both when the device
+ * is powered up on boot and when we resume in case we resumed from RAM.
+ * Returns the final clock settings.
+ */
+
+static u8 sil680_init_chip(struct pci_dev *pdev)
{
- static struct ata_port_info info = {
- .sht = &sil680_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x7f,
- .port_ops = &sil680_port_ops
- };
- static struct ata_port_info info_slow = {
- .sht = &sil680_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x3f,
- .port_ops = &sil680_port_ops
- };
- static struct ata_port_info *port_info[2] = {&info, &info};
- static int printed_version;
u32 class_rev = 0;
u8 tmpbyte = 0;
- if (!printed_version++)
- dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
-
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
/* FIXME: double check */
@@ -323,8 +310,6 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_read_config_byte(pdev, 0x8A, &tmpbyte);
printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
tmpbyte & 1, tmpbyte & 0x30);
- if ((tmpbyte & 0x30) == 0)
- port_info[0] = port_info[1] = &info_slow;
pci_write_config_byte(pdev, 0xA1, 0x72);
pci_write_config_word(pdev, 0xA2, 0x328A);
@@ -343,11 +328,51 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break;
/* This last case is _NOT_ ok */
case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n");
- return -EIO;
+ }
+ return tmpbyte & 0x30;
+}
+
+static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ static struct ata_port_info info = {
+ .sht = &sil680_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+ .port_ops = &sil680_port_ops
+ };
+ static struct ata_port_info info_slow = {
+ .sht = &sil680_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x3f,
+ .port_ops = &sil680_port_ops
+ };
+ static struct ata_port_info *port_info[2] = {&info, &info};
+ static int printed_version;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ switch(sil680_init_chip(pdev))
+ {
+ case 0:
+ port_info[0] = port_info[1] = &info_slow;
+ break;
+ case 0x30:
+ return -ENODEV;
}
return ata_pci_init_one(pdev, port_info, 2);
}
+static int sil680_reinit_one(struct pci_dev *pdev)
+{
+ sil680_init_chip(pdev);
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id sil680[] = {
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
@@ -358,7 +383,9 @@ static struct pci_driver sil680_pci_driver = {
.name = DRV_NAME,
.id_table = sil680,
.probe = sil680_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = sil680_reinit_one,
};
static int __init sil680_init(void)
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 91e85f90941d..916cedb3d755 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -34,7 +34,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_sis"
-#define DRV_VERSION "0.4.4"
+#define DRV_VERSION "0.4.5"
struct sis_chipset {
u16 device; /* PCI host ID */
@@ -538,7 +538,6 @@ static struct scsi_host_template sis_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -547,6 +546,8 @@ static struct scsi_host_template sis_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static const struct ata_port_operations sis_133_ops = {
@@ -1000,6 +1001,8 @@ static struct pci_driver sis_pci_driver = {
.id_table = sis_pci_tbl,
.probe = sis_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init sis_init(void)
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index dc1cfc6d805b..e94f515ef54b 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -230,7 +230,6 @@ static struct scsi_host_template sl82c105_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index bfda1f7e760a..a142971f1307 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -43,7 +43,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_triflex"
-#define DRV_VERSION "0.2.5"
+#define DRV_VERSION "0.2.7"
/**
* triflex_prereset - probe begin
@@ -185,7 +185,6 @@ static struct scsi_host_template triflex_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -194,6 +193,8 @@ static struct scsi_host_template triflex_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations triflex_port_ops = {
@@ -258,7 +259,9 @@ static struct pci_driver triflex_pci_driver = {
.name = DRV_NAME,
.id_table = triflex,
.probe = triflex_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static int __init triflex_init(void)
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index c5f1616d224d..cc09d47fb927 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -23,6 +23,7 @@
* VIA VT8233c - UDMA100
* VIA VT8235 - UDMA133
* VIA VT8237 - UDMA133
+ * VIA VT8251 - UDMA133
*
* Most registers remain compatible across chips. Others start reserved
* and acquire sensible semantics if set to 1 (eg cable detect). A few
@@ -60,7 +61,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_via"
-#define DRV_VERSION "0.1.14"
+#define DRV_VERSION "0.2.0"
/*
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -94,6 +95,7 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -288,7 +290,6 @@ static struct scsi_host_template via_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -297,6 +298,8 @@ static struct scsi_host_template via_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
};
static struct ata_port_operations via_port_ops = {
@@ -370,8 +373,42 @@ static struct ata_port_operations via_port_ops_noirq = {
};
/**
+ * via_config_fifo - set up the FIFO
+ * @pdev: PCI device
+ * @flags: configuration flags
+ *
+ * Set the FIFO properties for this device if neccessary. Used both on
+ * set up and on and the resume path
+ */
+
+static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
+{
+ u8 enable;
+
+ /* 0x40 low bits indicate enabled channels */
+ pci_read_config_byte(pdev, 0x40 , &enable);
+ enable &= 3;
+
+ if (flags & VIA_SET_FIFO) {
+ u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
+ u8 fifo;
+
+ pci_read_config_byte(pdev, 0x43, &fifo);
+
+ /* Clear PREQ# until DDACK# for errata */
+ if (flags & VIA_BAD_PREQ)
+ fifo &= 0x7F;
+ else
+ fifo &= 0x9f;
+ /* Turn on FIFO for enabled channels */
+ fifo |= fifo_setting[enable];
+ pci_write_config_byte(pdev, 0x43, fifo);
+ }
+}
+
+/**
* via_init_one - discovery callback
- * @pdev: PCI device ID
+ * @pdev: PCI device
* @id: PCI table info
*
* A VIA IDE interface has been discovered. Figure out what revision
@@ -383,7 +420,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Early VIA without UDMA support */
static struct ata_port_info via_mwdma_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &via_port_ops
@@ -391,7 +428,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Ditto with IRQ masking required */
static struct ata_port_info via_mwdma_info_borked = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &via_port_ops_noirq,
@@ -399,7 +436,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 33 devices (and borked 66) */
static struct ata_port_info via_udma33_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x7,
@@ -408,7 +445,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 66 devices */
static struct ata_port_info via_udma66_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x1f,
@@ -417,7 +454,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 100 devices */
static struct ata_port_info via_udma100_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x3f,
@@ -426,7 +463,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* UDMA133 with bad AST (All current 133) */
static struct ata_port_info via_udma133_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x7f, /* FIXME: should check north bridge */
@@ -471,21 +508,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* Initialise the FIFO for the enabled channels. */
- if (config->flags & VIA_SET_FIFO) {
- u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
- u8 fifo;
-
- pci_read_config_byte(pdev, 0x43, &fifo);
-
- /* Clear PREQ# until DDACK# for errata */
- if (config->flags & VIA_BAD_PREQ)
- fifo &= 0x7F;
- else
- fifo &= 0x9f;
- /* Turn on FIFO for enabled channels */
- fifo |= fifo_setting[enable];
- pci_write_config_byte(pdev, 0x43, fifo);
- }
+ via_config_fifo(pdev, config->flags);
+
/* Clock set up */
switch(config->flags & VIA_UDMA) {
case VIA_UDMA_NONE:
@@ -529,6 +553,39 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+/**
+ * via_reinit_one - reinit after resume
+ * @pdev; PCI device
+ *
+ * Called when the VIA PATA device is resumed. We must then
+ * reconfigure the fifo and other setup we may have altered. In
+ * addition the kernel needs to have the resume methods on PCI
+ * quirk supported.
+ */
+
+static int via_reinit_one(struct pci_dev *pdev)
+{
+ u32 timing;
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ const struct via_isa_bridge *config = host->private_data;
+
+ via_config_fifo(pdev, config->flags);
+
+ if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
+ /* The 66 MHz devices require we enable the clock */
+ pci_read_config_dword(pdev, 0x50, &timing);
+ timing |= 0x80008;
+ pci_write_config_dword(pdev, 0x50, timing);
+ }
+ if (config->flags & VIA_BAD_CLK66) {
+ /* Disable the 66MHz clock on problem devices */
+ pci_read_config_dword(pdev, 0x50, &timing);
+ timing &= ~0x80008;
+ pci_write_config_dword(pdev, 0x50, timing);
+ }
+ return ata_pci_device_resume(pdev);
+}
+
static const struct pci_device_id via[] = {
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
@@ -542,7 +599,9 @@ static struct pci_driver via_pci_driver = {
.name = DRV_NAME,
.id_table = via,
.probe = via_init_one,
- .remove = ata_pci_remove_one
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = via_reinit_one,
};
static int __init via_init(void)
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
new file mode 100644
index 000000000000..3ea345cde52e
--- /dev/null
+++ b/drivers/ata/pata_winbond.c
@@ -0,0 +1,306 @@
+/*
+ * pata_winbond.c - Winbond VLB ATA controllers
+ * (C) 2006 Red Hat <alan@redhat.com>
+ *
+ * Support for the Winbond 83759A when operating in advanced mode.
+ * Multichip mode is not currently supported.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/platform_device.h>
+
+#define DRV_NAME "pata_winbond"
+#define DRV_VERSION "0.0.1"
+
+#define NR_HOST 4 /* Two winbond controllers, two channels each */
+
+struct winbond_data {
+ unsigned long config;
+ struct platform_device *platform_dev;
+};
+
+static struct ata_host *winbond_host[NR_HOST];
+static struct winbond_data winbond_data[NR_HOST];
+static int nr_winbond_host;
+
+#ifdef MODULE
+static int probe_winbond = 1;
+#else
+static int probe_winbond;
+#endif
+
+static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
+
+static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&winbond_lock, flags);
+ outb(reg, port + 0x01);
+ outb(val, port + 0x02);
+ spin_unlock_irqrestore(&winbond_lock, flags);
+}
+
+static u8 winbond_readcfg(unsigned long port, u8 reg)
+{
+ u8 val;
+
+ unsigned long flags;
+ spin_lock_irqsave(&winbond_lock, flags);
+ outb(reg, port + 0x01);
+ val = inb(port + 0x02);
+ spin_unlock_irqrestore(&winbond_lock, flags);
+
+ return val;
+}
+
+static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct ata_timing t;
+ struct winbond_data *winbond = ap->host->private_data;
+ int active, recovery;
+ u8 reg;
+ int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
+
+ reg = winbond_readcfg(winbond->config, 0x81);
+
+ /* Get the timing data in cycles */
+ if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
+ ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
+ else
+ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
+
+ active = (FIT(t.active, 3, 17) - 1) & 0x0F;
+ recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
+ timing = (active << 4) | recovery;
+ winbond_writecfg(winbond->config, timing, reg);
+
+ /* Load the setup timing */
+
+ reg = 0x35;
+ if (adev->class != ATA_DEV_ATA)
+ reg |= 0x08; /* FIFO off */
+ if (!ata_pio_need_iordy(adev))
+ reg |= 0x02; /* IORDY off */
+ reg |= (FIT(t.setup, 0, 3) << 6);
+ winbond_writecfg(winbond->config, timing + 1, reg);
+}
+
+
+static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
+{
+ struct ata_port *ap = adev->ap;
+ int slop = buflen & 3;
+
+ if (ata_id_has_dword_io(adev->id)) {
+ if (write_data)
+ outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ else
+ insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+
+ if (unlikely(slop)) {
+ u32 pad;
+ if (write_data) {
+ memcpy(&pad, buf + buflen - slop, slop);
+ outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ } else {
+ pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ memcpy(buf + buflen - slop, &pad, slop);
+ }
+ }
+ } else
+ ata_pio_data_xfer(adev, buf, buflen, write_data);
+}
+
+static struct scsi_host_template winbond_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations winbond_port_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = winbond_set_piomode,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+
+ .data_xfer = winbond_data_xfer,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = ata_host_stop
+};
+
+/**
+ * winbond_init_one - attach a winbond interface
+ * @type: Type to display
+ * @io: I/O port start
+ * @irq: interrupt line
+ * @fast: True if on a > 33Mhz VLB
+ *
+ * Register a VLB bus IDE interface. Such interfaces are PIO and we
+ * assume do not support IRQ sharing.
+ */
+
+static __init int winbond_init_one(unsigned long port)
+{
+ struct ata_probe_ent ae;
+ struct platform_device *pdev;
+ int ret;
+ u8 reg;
+ int i;
+
+ reg = winbond_readcfg(port, 0x81);
+ reg |= 0x80; /* jumpered mode off */
+ winbond_writecfg(port, 0x81, reg);
+ reg = winbond_readcfg(port, 0x83);
+ reg |= 0xF0; /* local control */
+ winbond_writecfg(port, 0x83, reg);
+ reg = winbond_readcfg(port, 0x85);
+ reg |= 0xF0; /* programmable timing */
+ winbond_writecfg(port, 0x85, reg);
+
+ reg = winbond_readcfg(port, 0x81);
+
+ if (!(reg & 0x03)) /* Disabled */
+ return 0;
+
+ for (i = 0; i < 2 ; i ++) {
+
+ if (reg & (1 << i)) {
+ /*
+ * Fill in a probe structure first of all
+ */
+
+ pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
+ if (pdev == NULL)
+ return -ENOMEM;
+
+ memset(&ae, 0, sizeof(struct ata_probe_ent));
+ INIT_LIST_HEAD(&ae.node);
+ ae.dev = &pdev->dev;
+
+ ae.port_ops = &winbond_port_ops;
+ ae.pio_mask = 0x1F;
+
+ ae.sht = &winbond_sht;
+
+ ae.n_ports = 1;
+ ae.irq = 14 + i;
+ ae.irq_flags = 0;
+ ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ ae.port[0].cmd_addr = 0x1F0 - (0x80 * i);
+ ae.port[0].altstatus_addr = ae.port[0].cmd_addr + 0x0206;
+ ae.port[0].ctl_addr = ae.port[0].altstatus_addr;
+ ata_std_ports(&ae.port[0]);
+ /*
+ * Hook in a private data structure per channel
+ */
+ ae.private_data = &winbond_data[nr_winbond_host];
+ winbond_data[nr_winbond_host].config = port;
+ winbond_data[nr_winbond_host].platform_dev = pdev;
+
+ ret = ata_device_add(&ae);
+ if (ret == 0) {
+ platform_device_unregister(pdev);
+ return -ENODEV;
+ }
+ winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * winbond_init - attach winbond interfaces
+ *
+ * Attach winbond IDE interfaces by scanning the ports it may occupy.
+ */
+
+static __init int winbond_init(void)
+{
+ static const unsigned long config[2] = { 0x130, 0x1B0 };
+
+ int ct = 0;
+ int i;
+
+ if (probe_winbond == 0)
+ return -ENODEV;
+
+ /*
+ * Check both base addresses
+ */
+
+ for (i = 0; i < 2; i++) {
+ if (probe_winbond & (1<<i)) {
+ int ret = 0;
+ unsigned long port = config[i];
+
+ if (request_region(port, 2, "pata_winbond")) {
+ ret = winbond_init_one(port);
+ if(ret <= 0)
+ release_region(port, 2);
+ else ct+= ret;
+ }
+ }
+ }
+ if (ct != 0)
+ return 0;
+ return -ENODEV;
+}
+
+static __exit void winbond_exit(void)
+{
+ int i;
+
+ for (i = 0; i < nr_winbond_host; i++) {
+ ata_host_remove(winbond_host[i]);
+ release_region(winbond_data[i].config, 2);
+ platform_device_unregister(winbond_data[i].platform_dev);
+ }
+}
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("low-level driver for Winbond VL ATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(winbond_init);
+module_exit(winbond_exit);
+
+module_param(probe_winbond, int, 0);
+
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index d65ebfd7c7b2..0d316eb3c214 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -29,6 +29,11 @@
* NV-specific details such as register offsets, SATA phy location,
* hotplug info, etc.
*
+ * CK804/MCP04 controllers support an alternate programming interface
+ * similar to the ADMA specification (with some modifications).
+ * This allows the use of NCQ. Non-DMA-mapped ATA commands are still
+ * sent through the legacy interface.
+ *
*/
#include <linux/kernel.h>
@@ -40,10 +45,13 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
#include <linux/libata.h>
#define DRV_NAME "sata_nv"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "3.2"
+
+#define NV_ADMA_DMA_BOUNDARY 0xffffffffUL
enum {
NV_PORTS = 2,
@@ -78,8 +86,138 @@ enum {
// For PCI config register 20
NV_MCP_SATA_CFG_20 = 0x50,
NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04,
+ NV_MCP_SATA_CFG_20_PORT0_EN = (1 << 17),
+ NV_MCP_SATA_CFG_20_PORT1_EN = (1 << 16),
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN = (1 << 14),
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN = (1 << 12),
+
+ NV_ADMA_MAX_CPBS = 32,
+ NV_ADMA_CPB_SZ = 128,
+ NV_ADMA_APRD_SZ = 16,
+ NV_ADMA_SGTBL_LEN = (1024 - NV_ADMA_CPB_SZ) /
+ NV_ADMA_APRD_SZ,
+ NV_ADMA_SGTBL_TOTAL_LEN = NV_ADMA_SGTBL_LEN + 5,
+ NV_ADMA_SGTBL_SZ = NV_ADMA_SGTBL_LEN * NV_ADMA_APRD_SZ,
+ NV_ADMA_PORT_PRIV_DMA_SZ = NV_ADMA_MAX_CPBS *
+ (NV_ADMA_CPB_SZ + NV_ADMA_SGTBL_SZ),
+
+ /* BAR5 offset to ADMA general registers */
+ NV_ADMA_GEN = 0x400,
+ NV_ADMA_GEN_CTL = 0x00,
+ NV_ADMA_NOTIFIER_CLEAR = 0x30,
+
+ /* BAR5 offset to ADMA ports */
+ NV_ADMA_PORT = 0x480,
+
+ /* size of ADMA port register space */
+ NV_ADMA_PORT_SIZE = 0x100,
+
+ /* ADMA port registers */
+ NV_ADMA_CTL = 0x40,
+ NV_ADMA_CPB_COUNT = 0x42,
+ NV_ADMA_NEXT_CPB_IDX = 0x43,
+ NV_ADMA_STAT = 0x44,
+ NV_ADMA_CPB_BASE_LOW = 0x48,
+ NV_ADMA_CPB_BASE_HIGH = 0x4C,
+ NV_ADMA_APPEND = 0x50,
+ NV_ADMA_NOTIFIER = 0x68,
+ NV_ADMA_NOTIFIER_ERROR = 0x6C,
+
+ /* NV_ADMA_CTL register bits */
+ NV_ADMA_CTL_HOTPLUG_IEN = (1 << 0),
+ NV_ADMA_CTL_CHANNEL_RESET = (1 << 5),
+ NV_ADMA_CTL_GO = (1 << 7),
+ NV_ADMA_CTL_AIEN = (1 << 8),
+ NV_ADMA_CTL_READ_NON_COHERENT = (1 << 11),
+ NV_ADMA_CTL_WRITE_NON_COHERENT = (1 << 12),
+
+ /* CPB response flag bits */
+ NV_CPB_RESP_DONE = (1 << 0),
+ NV_CPB_RESP_ATA_ERR = (1 << 3),
+ NV_CPB_RESP_CMD_ERR = (1 << 4),
+ NV_CPB_RESP_CPB_ERR = (1 << 7),
+
+ /* CPB control flag bits */
+ NV_CPB_CTL_CPB_VALID = (1 << 0),
+ NV_CPB_CTL_QUEUE = (1 << 1),
+ NV_CPB_CTL_APRD_VALID = (1 << 2),
+ NV_CPB_CTL_IEN = (1 << 3),
+ NV_CPB_CTL_FPDMA = (1 << 4),
+
+ /* APRD flags */
+ NV_APRD_WRITE = (1 << 1),
+ NV_APRD_END = (1 << 2),
+ NV_APRD_CONT = (1 << 3),
+
+ /* NV_ADMA_STAT flags */
+ NV_ADMA_STAT_TIMEOUT = (1 << 0),
+ NV_ADMA_STAT_HOTUNPLUG = (1 << 1),
+ NV_ADMA_STAT_HOTPLUG = (1 << 2),
+ NV_ADMA_STAT_CPBERR = (1 << 4),
+ NV_ADMA_STAT_SERROR = (1 << 5),
+ NV_ADMA_STAT_CMD_COMPLETE = (1 << 6),
+ NV_ADMA_STAT_IDLE = (1 << 8),
+ NV_ADMA_STAT_LEGACY = (1 << 9),
+ NV_ADMA_STAT_STOPPED = (1 << 10),
+ NV_ADMA_STAT_DONE = (1 << 12),
+ NV_ADMA_STAT_ERR = NV_ADMA_STAT_CPBERR |
+ NV_ADMA_STAT_TIMEOUT,
+
+ /* port flags */
+ NV_ADMA_PORT_REGISTER_MODE = (1 << 0),
+ NV_ADMA_ATAPI_SETUP_COMPLETE = (1 << 1),
+
+};
+
+/* ADMA Physical Region Descriptor - one SG segment */
+struct nv_adma_prd {
+ __le64 addr;
+ __le32 len;
+ u8 flags;
+ u8 packet_len;
+ __le16 reserved;
+};
+
+enum nv_adma_regbits {
+ CMDEND = (1 << 15), /* end of command list */
+ WNB = (1 << 14), /* wait-not-BSY */
+ IGN = (1 << 13), /* ignore this entry */
+ CS1n = (1 << (4 + 8)), /* std. PATA signals follow... */
+ DA2 = (1 << (2 + 8)),
+ DA1 = (1 << (1 + 8)),
+ DA0 = (1 << (0 + 8)),
+};
+
+/* ADMA Command Parameter Block
+ The first 5 SG segments are stored inside the Command Parameter Block itself.
+ If there are more than 5 segments the remainder are stored in a separate
+ memory area indicated by next_aprd. */
+struct nv_adma_cpb {
+ u8 resp_flags; /* 0 */
+ u8 reserved1; /* 1 */
+ u8 ctl_flags; /* 2 */
+ /* len is length of taskfile in 64 bit words */
+ u8 len; /* 3 */
+ u8 tag; /* 4 */
+ u8 next_cpb_idx; /* 5 */
+ __le16 reserved2; /* 6-7 */
+ __le16 tf[12]; /* 8-31 */
+ struct nv_adma_prd aprd[5]; /* 32-111 */
+ __le64 next_aprd; /* 112-119 */
+ __le64 reserved3; /* 120-127 */
+};
+
+
+struct nv_adma_port_priv {
+ struct nv_adma_cpb *cpb;
+ dma_addr_t cpb_dma;
+ struct nv_adma_prd *aprd;
+ dma_addr_t aprd_dma;
+ u8 flags;
};
+#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
+
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static void nv_ck804_host_stop(struct ata_host *host);
static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
@@ -93,13 +231,28 @@ static void nv_nf2_thaw(struct ata_port *ap);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
static void nv_error_handler(struct ata_port *ap);
+static int nv_adma_slave_config(struct scsi_device *sdev);
+static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
+static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
+static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc);
+static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance);
+static void nv_adma_irq_clear(struct ata_port *ap);
+static int nv_adma_port_start(struct ata_port *ap);
+static void nv_adma_port_stop(struct ata_port *ap);
+static void nv_adma_error_handler(struct ata_port *ap);
+static void nv_adma_host_stop(struct ata_host *host);
+static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc);
+static void nv_adma_bmdma_start(struct ata_queued_cmd *qc);
+static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 nv_adma_bmdma_status(struct ata_port *ap);
enum nv_host_type
{
GENERIC,
NFORCE2,
NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
- CK804
+ CK804,
+ ADMA
};
static const struct pci_device_id nv_pci_tbl[] = {
@@ -160,6 +313,24 @@ static struct scsi_host_template nv_sht = {
.bios_param = ata_std_bios_param,
};
+static struct scsi_host_template nv_adma_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = NV_ADMA_MAX_CPBS,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = NV_ADMA_DMA_BOUNDARY,
+ .slave_configure = nv_adma_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
static const struct ata_port_operations nv_generic_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -241,11 +412,40 @@ static const struct ata_port_operations nv_ck804_ops = {
.host_stop = nv_ck804_host_stop,
};
+static const struct ata_port_operations nv_adma_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_atapi_dma = nv_adma_check_atapi_dma,
+ .exec_command = ata_exec_command,
+ .check_status = ata_check_status,
+ .dev_select = ata_std_dev_select,
+ .bmdma_setup = nv_adma_bmdma_setup,
+ .bmdma_start = nv_adma_bmdma_start,
+ .bmdma_stop = nv_adma_bmdma_stop,
+ .bmdma_status = nv_adma_bmdma_status,
+ .qc_prep = nv_adma_qc_prep,
+ .qc_issue = nv_adma_qc_issue,
+ .freeze = nv_ck804_freeze,
+ .thaw = nv_ck804_thaw,
+ .error_handler = nv_adma_error_handler,
+ .post_internal_cmd = nv_adma_bmdma_stop,
+ .data_xfer = ata_mmio_data_xfer,
+ .irq_handler = nv_adma_interrupt,
+ .irq_clear = nv_adma_irq_clear,
+ .scr_read = nv_scr_read,
+ .scr_write = nv_scr_write,
+ .port_start = nv_adma_port_start,
+ .port_stop = nv_adma_port_stop,
+ .host_stop = nv_adma_host_stop,
+};
+
static struct ata_port_info nv_port_info[] = {
/* generic */
{
.sht = &nv_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
@@ -254,7 +454,8 @@ static struct ata_port_info nv_port_info[] = {
/* nforce2/3 */
{
.sht = &nv_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
@@ -263,12 +464,23 @@ static struct ata_port_info nv_port_info[] = {
/* ck804 */
{
.sht = &nv_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_ck804_ops,
},
+ /* ADMA */
+ {
+ .sht = &nv_adma_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_NCQ,
+ .pio_mask = NV_PIO_MASK,
+ .mwdma_mask = NV_MWDMA_MASK,
+ .udma_mask = NV_UDMA_MASK,
+ .port_ops = &nv_adma_ops,
+ },
};
MODULE_AUTHOR("NVIDIA");
@@ -277,37 +489,220 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
+static int adma_enabled = 1;
+
+static inline void __iomem *__nv_adma_ctl_block(void __iomem *mmio,
+ unsigned int port_no)
{
- struct ata_host *host = dev_instance;
- unsigned int i;
- unsigned int handled = 0;
- unsigned long flags;
+ mmio += NV_ADMA_PORT + port_no * NV_ADMA_PORT_SIZE;
+ return mmio;
+}
- spin_lock_irqsave(&host->lock, flags);
+static inline void __iomem *nv_adma_ctl_block(struct ata_port *ap)
+{
+ return __nv_adma_ctl_block(ap->host->mmio_base, ap->port_no);
+}
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
+static inline void __iomem *nv_adma_gen_block(struct ata_port *ap)
+{
+ return (ap->host->mmio_base + NV_ADMA_GEN);
+}
- ap = host->ports[i];
- if (ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
+static inline void __iomem *nv_adma_notifier_clear_block(struct ata_port *ap)
+{
+ return (nv_adma_gen_block(ap) + NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no));
+}
- qc = ata_qc_from_tag(ap, ap->active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
- handled += ata_host_intr(ap, qc);
- else
- // No request pending? Clear interrupt status
- // anyway, in case there's one pending.
- ap->ops->check_status(ap);
- }
+static void nv_adma_register_mode(struct ata_port *ap)
+{
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ u16 tmp;
+
+ if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
+ return;
+
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+
+ pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
+}
+
+static void nv_adma_mode(struct ata_port *ap)
+{
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ u16 tmp;
+ if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
+ return;
+
+ WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
+
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+
+ pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE;
+}
+
+static int nv_adma_slave_config(struct scsi_device *sdev)
+{
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u64 bounce_limit;
+ unsigned long segment_boundary;
+ unsigned short sg_tablesize;
+ int rc;
+ int adma_enable;
+ u32 current_reg, new_reg, config_mask;
+
+ rc = ata_scsi_slave_config(sdev);
+
+ if (sdev->id >= ATA_MAX_DEVICES || sdev->channel || sdev->lun)
+ /* Not a proper libata device, ignore */
+ return rc;
+
+ if (ap->device[sdev->id].class == ATA_DEV_ATAPI) {
+ /*
+ * NVIDIA reports that ADMA mode does not support ATAPI commands.
+ * Therefore ATAPI commands are sent through the legacy interface.
+ * However, the legacy interface only supports 32-bit DMA.
+ * Restrict DMA parameters as required by the legacy interface
+ * when an ATAPI device is connected.
+ */
+ bounce_limit = ATA_DMA_MASK;
+ segment_boundary = ATA_DMA_BOUNDARY;
+ /* Subtract 1 since an extra entry may be needed for padding, see
+ libata-scsi.c */
+ sg_tablesize = LIBATA_MAX_PRD - 1;
+
+ /* Since the legacy DMA engine is in use, we need to disable ADMA
+ on the port. */
+ adma_enable = 0;
+ nv_adma_register_mode(ap);
+ }
+ else {
+ bounce_limit = *ap->dev->dma_mask;
+ segment_boundary = NV_ADMA_DMA_BOUNDARY;
+ sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
+ adma_enable = 1;
+ }
+
+ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &current_reg);
+
+ if(ap->port_no == 1)
+ config_mask = NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN;
+ else
+ config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
+
+ if(adma_enable) {
+ new_reg = current_reg | config_mask;
+ pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
+ }
+ else {
+ new_reg = current_reg & ~config_mask;
+ pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE;
}
+
+ if(current_reg != new_reg)
+ pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg);
+
+ blk_queue_bounce_limit(sdev->request_queue, bounce_limit);
+ blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
+ blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
+ ata_port_printk(ap, KERN_INFO,
+ "bounce limit 0x%llX, segment boundary 0x%lX, hw segs %hu\n",
+ (unsigned long long)bounce_limit, segment_boundary, sg_tablesize);
+ return rc;
+}
- spin_unlock_irqrestore(&host->lock, flags);
+static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
+ return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
+}
- return IRQ_RETVAL(handled);
+static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
+{
+ unsigned int idx = 0;
+
+ cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device | WNB);
+
+ if ((tf->flags & ATA_TFLAG_LBA48) == 0) {
+ cpb[idx++] = cpu_to_le16(IGN);
+ cpb[idx++] = cpu_to_le16(IGN);
+ cpb[idx++] = cpu_to_le16(IGN);
+ cpb[idx++] = cpu_to_le16(IGN);
+ cpb[idx++] = cpu_to_le16(IGN);
+ }
+ else {
+ cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature);
+ cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah);
+ }
+ cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature);
+ cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah);
+
+ cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND);
+
+ return idx;
+}
+
+static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ int complete = 0, have_err = 0;
+ u8 flags = pp->cpb[cpb_num].resp_flags;
+
+ VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags);
+
+ if (flags & NV_CPB_RESP_DONE) {
+ VPRINTK("CPB flags done, flags=0x%x\n", flags);
+ complete = 1;
+ }
+ if (flags & NV_CPB_RESP_ATA_ERR) {
+ ata_port_printk(ap, KERN_ERR, "CPB flags ATA err, flags=0x%x\n", flags);
+ have_err = 1;
+ complete = 1;
+ }
+ if (flags & NV_CPB_RESP_CMD_ERR) {
+ ata_port_printk(ap, KERN_ERR, "CPB flags CMD err, flags=0x%x\n", flags);
+ have_err = 1;
+ complete = 1;
+ }
+ if (flags & NV_CPB_RESP_CPB_ERR) {
+ ata_port_printk(ap, KERN_ERR, "CPB flags CPB err, flags=0x%x\n", flags);
+ have_err = 1;
+ complete = 1;
+ }
+ if(complete || force_err)
+ {
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
+ if(likely(qc)) {
+ u8 ata_status = 0;
+ /* Only use the ATA port status for non-NCQ commands.
+ For NCQ commands the current status may have nothing to do with
+ the command just completed. */
+ if(qc->tf.protocol != ATA_PROT_NCQ)
+ ata_status = readb(nv_adma_ctl_block(ap) + (ATA_REG_STATUS * 4));
+
+ if(have_err || force_err)
+ ata_status |= ATA_ERR;
+
+ qc->err_mask |= ac_err_mask(ata_status);
+ DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
+ qc->err_mask);
+ ata_qc_complete(qc);
+ }
+ }
}
static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
@@ -341,6 +736,486 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
return 1;
}
+static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ int i, handled = 0;
+ u32 notifier_clears[2];
+
+ spin_lock(&host->lock);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ notifier_clears[i] = 0;
+
+ if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ u16 status;
+ u32 gen_ctl;
+ int have_global_err = 0;
+ u32 notifier, notifier_error;
+
+ /* if in ATA register mode, use standard ata interrupt handler */
+ if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
+ u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
+ >> (NV_INT_PORT_SHIFT * i);
+ handled += nv_host_intr(ap, irq_stat);
+ continue;
+ }
+
+ notifier = readl(mmio + NV_ADMA_NOTIFIER);
+ notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+ notifier_clears[i] = notifier | notifier_error;
+
+ gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
+
+ if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
+ !notifier_error)
+ /* Nothing to do */
+ continue;
+
+ status = readw(mmio + NV_ADMA_STAT);
+
+ /* Clear status. Ensure the controller sees the clearing before we start
+ looking at any of the CPB statuses, so that any CPB completions after
+ this point in the handler will raise another interrupt. */
+ writew(status, mmio + NV_ADMA_STAT);
+ readw(mmio + NV_ADMA_STAT); /* flush posted write */
+ rmb();
+
+ /* freeze if hotplugged */
+ if (unlikely(status & (NV_ADMA_STAT_HOTPLUG | NV_ADMA_STAT_HOTUNPLUG))) {
+ ata_port_printk(ap, KERN_NOTICE, "Hotplug event, freezing\n");
+ ata_port_freeze(ap);
+ handled++;
+ continue;
+ }
+
+ if (status & NV_ADMA_STAT_TIMEOUT) {
+ ata_port_printk(ap, KERN_ERR, "timeout, stat=0x%x\n", status);
+ have_global_err = 1;
+ }
+ if (status & NV_ADMA_STAT_CPBERR) {
+ ata_port_printk(ap, KERN_ERR, "CPB error, stat=0x%x\n", status);
+ have_global_err = 1;
+ }
+ if ((status & NV_ADMA_STAT_DONE) || have_global_err) {
+ /** Check CPBs for completed commands */
+
+ if(ata_tag_valid(ap->active_tag))
+ /* Non-NCQ command */
+ nv_adma_check_cpb(ap, ap->active_tag, have_global_err ||
+ (notifier_error & (1 << ap->active_tag)));
+ else {
+ int pos;
+ u32 active = ap->sactive;
+ while( (pos = ffs(active)) ) {
+ pos--;
+ nv_adma_check_cpb(ap, pos, have_global_err ||
+ (notifier_error & (1 << pos)) );
+ active &= ~(1 << pos );
+ }
+ }
+ }
+
+ handled++; /* irq handled if we got here */
+ }
+ }
+
+ if(notifier_clears[0] || notifier_clears[1]) {
+ /* Note: Both notifier clear registers must be written
+ if either is set, even if one is zero, according to NVIDIA. */
+ writel(notifier_clears[0],
+ nv_adma_notifier_clear_block(host->ports[0]));
+ writel(notifier_clears[1],
+ nv_adma_notifier_clear_block(host->ports[1]));
+ }
+
+ spin_unlock(&host->lock);
+
+ return IRQ_RETVAL(handled);
+}
+
+static void nv_adma_irq_clear(struct ata_port *ap)
+{
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ u16 status = readw(mmio + NV_ADMA_STAT);
+ u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
+ u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+ unsigned long dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
+
+ /* clear ADMA status */
+ writew(status, mmio + NV_ADMA_STAT);
+ writel(notifier | notifier_error,
+ nv_adma_notifier_clear_block(ap));
+
+ /** clear legacy status */
+ outb(inb(dma_stat_addr), dma_stat_addr);
+}
+
+static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ u8 dmactl;
+
+ if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
+ WARN_ON(1);
+ return;
+ }
+
+ /* load PRD table addr. */
+ outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+
+ outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+
+ /* issue r/w command */
+ ata_exec_command(ap, &qc->tf);
+}
+
+static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct nv_adma_port_priv *pp = ap->private_data;
+ u8 dmactl;
+
+ if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
+ WARN_ON(1);
+ return;
+ }
+
+ /* start host DMA transaction */
+ dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ outb(dmactl | ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+}
+
+static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct nv_adma_port_priv *pp = ap->private_data;
+
+ if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
+ return;
+
+ /* clear start/stop bit */
+ outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_altstatus(ap); /* dummy read */
+}
+
+static u8 nv_adma_bmdma_status(struct ata_port *ap)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+
+ WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
+
+ return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+}
+
+static int nv_adma_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host->dev;
+ struct nv_adma_port_priv *pp;
+ int rc;
+ void *mem;
+ dma_addr_t mem_dma;
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ u16 tmp;
+
+ VPRINTK("ENTER\n");
+
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+
+ pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
+ mem = dma_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
+ &mem_dma, GFP_KERNEL);
+
+ if (!mem) {
+ rc = -ENOMEM;
+ goto err_out_kfree;
+ }
+ memset(mem, 0, NV_ADMA_PORT_PRIV_DMA_SZ);
+
+ /*
+ * First item in chunk of DMA memory:
+ * 128-byte command parameter block (CPB)
+ * one for each command tag
+ */
+ pp->cpb = mem;
+ pp->cpb_dma = mem_dma;
+
+ writel(mem_dma & 0xFFFFFFFF, mmio + NV_ADMA_CPB_BASE_LOW);
+ writel((mem_dma >> 16 ) >> 16, mmio + NV_ADMA_CPB_BASE_HIGH);
+
+ mem += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
+ mem_dma += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
+
+ /*
+ * Second item: block of ADMA_SGTBL_LEN s/g entries
+ */
+ pp->aprd = mem;
+ pp->aprd_dma = mem_dma;
+
+ ap->private_data = pp;
+
+ /* clear any outstanding interrupt conditions */
+ writew(0xffff, mmio + NV_ADMA_STAT);
+
+ /* initialize port variables */
+ pp->flags = NV_ADMA_PORT_REGISTER_MODE;
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* clear GO for register mode */
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ udelay(1);
+ writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+
+ return 0;
+
+err_out_kfree:
+ kfree(pp);
+err_out:
+ ata_port_stop(ap);
+ return rc;
+}
+
+static void nv_adma_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host->dev;
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+
+ VPRINTK("ENTER\n");
+
+ writew(0, mmio + NV_ADMA_CTL);
+
+ ap->private_data = NULL;
+ dma_free_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, pp->cpb, pp->cpb_dma);
+ kfree(pp);
+ ata_port_stop(ap);
+}
+
+
+static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
+{
+ void __iomem *mmio = probe_ent->mmio_base;
+ struct ata_ioports *ioport = &probe_ent->port[port];
+
+ VPRINTK("ENTER\n");
+
+ mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
+
+ ioport->cmd_addr = (unsigned long) mmio;
+ ioport->data_addr = (unsigned long) mmio + (ATA_REG_DATA * 4);
+ ioport->error_addr =
+ ioport->feature_addr = (unsigned long) mmio + (ATA_REG_ERR * 4);
+ ioport->nsect_addr = (unsigned long) mmio + (ATA_REG_NSECT * 4);
+ ioport->lbal_addr = (unsigned long) mmio + (ATA_REG_LBAL * 4);
+ ioport->lbam_addr = (unsigned long) mmio + (ATA_REG_LBAM * 4);
+ ioport->lbah_addr = (unsigned long) mmio + (ATA_REG_LBAH * 4);
+ ioport->device_addr = (unsigned long) mmio + (ATA_REG_DEVICE * 4);
+ ioport->status_addr =
+ ioport->command_addr = (unsigned long) mmio + (ATA_REG_STATUS * 4);
+ ioport->altstatus_addr =
+ ioport->ctl_addr = (unsigned long) mmio + 0x20;
+}
+
+static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
+{
+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+ unsigned int i;
+ u32 tmp32;
+
+ VPRINTK("ENTER\n");
+
+ /* enable ADMA on the ports */
+ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
+ tmp32 |= NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN |
+ NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN;
+
+ pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
+
+ for (i = 0; i < probe_ent->n_ports; i++)
+ nv_adma_setup_port(probe_ent, i);
+
+ for (i = 0; i < probe_ent->n_ports; i++) {
+ void __iomem *mmio = __nv_adma_ctl_block(probe_ent->mmio_base, i);
+ u16 tmp;
+
+ /* enable interrupt, clear reset if not already clear */
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
+ }
+
+ return 0;
+}
+
+static void nv_adma_fill_aprd(struct ata_queued_cmd *qc,
+ struct scatterlist *sg,
+ int idx,
+ struct nv_adma_prd *aprd)
+{
+ u8 flags;
+
+ memset(aprd, 0, sizeof(struct nv_adma_prd));
+
+ flags = 0;
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ flags |= NV_APRD_WRITE;
+ if (idx == qc->n_elem - 1)
+ flags |= NV_APRD_END;
+ else if (idx != 4)
+ flags |= NV_APRD_CONT;
+
+ aprd->addr = cpu_to_le64(((u64)sg_dma_address(sg)));
+ aprd->len = cpu_to_le32(((u32)sg_dma_len(sg))); /* len in bytes */
+ aprd->flags = flags;
+}
+
+static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
+{
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
+ unsigned int idx;
+ struct nv_adma_prd *aprd;
+ struct scatterlist *sg;
+
+ VPRINTK("ENTER\n");
+
+ idx = 0;
+
+ ata_for_each_sg(sg, qc) {
+ aprd = (idx < 5) ? &cpb->aprd[idx] : &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)];
+ nv_adma_fill_aprd(qc, sg, idx, aprd);
+ idx++;
+ }
+ if (idx > 5)
+ cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
+}
+
+static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
+ struct nv_adma_cpb *cpb = &pp->cpb[qc->tag];
+ u8 ctl_flags = NV_CPB_CTL_CPB_VALID |
+ NV_CPB_CTL_APRD_VALID |
+ NV_CPB_CTL_IEN;
+
+ VPRINTK("qc->flags = 0x%lx\n", qc->flags);
+
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
+ (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ nv_adma_register_mode(qc->ap);
+ ata_qc_prep(qc);
+ return;
+ }
+
+ memset(cpb, 0, sizeof(struct nv_adma_cpb));
+
+ cpb->len = 3;
+ cpb->tag = qc->tag;
+ cpb->next_cpb_idx = 0;
+
+ /* turn on NCQ flags for NCQ commands */
+ if (qc->tf.protocol == ATA_PROT_NCQ)
+ ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA;
+
+ nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
+
+ nv_adma_fill_sg(qc, cpb);
+
+ /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
+ finished filling in all of the contents */
+ wmb();
+ cpb->ctl_flags = ctl_flags;
+}
+
+static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
+ void __iomem *mmio = nv_adma_ctl_block(qc->ap);
+
+ VPRINTK("ENTER\n");
+
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
+ (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ /* use ATA register mode */
+ VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags);
+ nv_adma_register_mode(qc->ap);
+ return ata_qc_issue_prot(qc);
+ } else
+ nv_adma_mode(qc->ap);
+
+ /* write append register, command tag in lower 8 bits
+ and (number of cpbs to append -1) in top 8 bits */
+ wmb();
+ writew(qc->tag, mmio + NV_ADMA_APPEND);
+
+ DPRINTK("Issued tag %u\n",qc->tag);
+
+ return 0;
+}
+
+static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ unsigned int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap;
+
+ ap = host->ports[i];
+ if (ap &&
+ !(ap->flags & ATA_FLAG_DISABLED)) {
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
+ handled += ata_host_intr(ap, qc);
+ else
+ // No request pending? Clear interrupt status
+ // anyway, in case there's one pending.
+ ap->ops->check_status(ap);
+ }
+
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat)
{
int i, handled = 0;
@@ -466,6 +1341,56 @@ static void nv_error_handler(struct ata_port *ap)
nv_hardreset, ata_std_postreset);
}
+static void nv_adma_error_handler(struct ata_port *ap)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
+ void __iomem *mmio = nv_adma_ctl_block(ap);
+ int i;
+ u16 tmp;
+
+ u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
+ u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+ u32 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
+ u32 status = readw(mmio + NV_ADMA_STAT);
+
+ ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
+ "notifier_error 0x%X gen_ctl 0x%X status 0x%X\n",
+ notifier, notifier_error, gen_ctl, status);
+
+ for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
+ struct nv_adma_cpb *cpb = &pp->cpb[i];
+ if( cpb->ctl_flags || cpb->resp_flags )
+ ata_port_printk(ap, KERN_ERR,
+ "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
+ i, cpb->ctl_flags, cpb->resp_flags);
+ }
+
+ /* Push us back into port register mode for error handling. */
+ nv_adma_register_mode(ap);
+
+ ata_port_printk(ap, KERN_ERR, "Resetting port\n");
+
+ /* Mark all of the CPBs as invalid to prevent them from being executed */
+ for( i=0;i<NV_ADMA_MAX_CPBS;i++)
+ pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID;
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* Reset channel */
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ udelay(1);
+ writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ }
+
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
+ nv_hardreset, ata_std_postreset);
+}
+
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
@@ -475,6 +1400,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
int rc;
u32 bar;
unsigned long base;
+ unsigned long type = ent->driver_data;
+ int mask_set = 0;
// Make sure this is a SATA controller by counting the number of bars
// (NVIDIA SATA controllers will always have six bars). Otherwise,
@@ -483,7 +1410,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_resource_start(pdev, bar) == 0)
return -ENODEV;
- if (!printed_version++)
+ if ( !printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
@@ -496,16 +1423,26 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_disable;
}
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- goto err_out_regions;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- goto err_out_regions;
+ if(type >= CK804 && adma_enabled) {
+ dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
+ type = ADMA;
+ if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
+ !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ mask_set = 1;
+ }
+
+ if(!mask_set) {
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+ }
rc = -ENOMEM;
- ppi[0] = ppi[1] = &nv_port_info[ent->driver_data];
+ ppi[0] = ppi[1] = &nv_port_info[type];
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
goto err_out_regions;
@@ -522,7 +1459,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
/* enable SATA space for CK804 */
- if (ent->driver_data == CK804) {
+ if (type >= CK804) {
u8 regval;
pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
@@ -532,6 +1469,12 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
+ if (type == ADMA) {
+ rc = nv_adma_host_init(probe_ent);
+ if (rc)
+ goto err_out_iounmap;
+ }
+
rc = ata_device_add(probe_ent);
if (rc != NV_PORTS)
goto err_out_iounmap;
@@ -566,6 +1509,33 @@ static void nv_ck804_host_stop(struct ata_host *host)
ata_pci_host_stop(host);
}
+static void nv_adma_host_stop(struct ata_host *host)
+{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ int i;
+ u32 tmp32;
+
+ for (i = 0; i < host->n_ports; i++) {
+ void __iomem *mmio = __nv_adma_ctl_block(host->mmio_base, i);
+ u16 tmp;
+
+ /* disable interrupt */
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp & ~NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
+ }
+
+ /* disable ADMA on the ports */
+ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
+ tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN |
+ NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+
+ pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
+
+ nv_ck804_host_stop(host);
+}
+
static int __init nv_init(void)
{
return pci_register_driver(&nv_pci_driver);
@@ -578,3 +1548,5 @@ static void __exit nv_exit(void)
module_init(nv_init);
module_exit(nv_exit);
+module_param_named(adma, adma_enabled, bool, 0444);
+MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)");
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 72eda5160fad..a2778cf016bc 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -46,20 +46,19 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
-#define DRV_VERSION "1.04"
+#define DRV_VERSION "1.05"
enum {
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
- PDC_TBG_MODE = 0x41, /* TBG mode */
PDC_FLASH_CTL = 0x44, /* Flash control register */
- PDC_PCI_CTL = 0x48, /* PCI control and status register */
PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */
- PDC_SLEW_CTL = 0x470, /* slew rate control reg */
+ PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
+ PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
(1<<8) | (1<<9) | (1<<10),
@@ -78,6 +77,9 @@ enum {
PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
ATA_FLAG_PIO_POLLING,
+
+ /* hp->flags bits */
+ PDC_FLAG_GEN_II = (1 << 0),
};
@@ -87,6 +89,7 @@ struct pdc_port_priv {
};
struct pdc_host_priv {
+ unsigned long flags;
int hotplug_offset;
};
@@ -235,20 +238,20 @@ static const struct ata_port_info pdc_port_info[] = {
static const struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VDEVICE(PROMISE, 0x3371), board_2037x },
- { PCI_VDEVICE(PROMISE, 0x3570), board_2037x },
- { PCI_VDEVICE(PROMISE, 0x3571), board_2037x },
{ PCI_VDEVICE(PROMISE, 0x3373), board_2037x },
{ PCI_VDEVICE(PROMISE, 0x3375), board_2037x },
{ PCI_VDEVICE(PROMISE, 0x3376), board_2037x },
+ { PCI_VDEVICE(PROMISE, 0x3570), board_2057x },
+ { PCI_VDEVICE(PROMISE, 0x3571), board_2057x },
{ PCI_VDEVICE(PROMISE, 0x3574), board_2057x },
+ { PCI_VDEVICE(PROMISE, 0x3d73), board_2057x },
{ PCI_VDEVICE(PROMISE, 0x3d75), board_2057x },
- { PCI_VDEVICE(PROMISE, 0x3d73), board_2037x },
{ PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
{ PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
{ PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
{ PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
- { PCI_VDEVICE(PROMISE, 0x3d17), board_20319 },
+ { PCI_VDEVICE(PROMISE, 0x3d17), board_40518 },
{ PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
{ PCI_VDEVICE(PROMISE, 0x6629), board_20619 },
@@ -277,6 +280,7 @@ static struct pci_driver pdc_ata_pci_driver = {
static int pdc_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
+ struct pdc_host_priv *hp = ap->host->private_data;
struct pdc_port_priv *pp;
int rc;
@@ -298,6 +302,16 @@ static int pdc_port_start(struct ata_port *ap)
ap->private_data = pp;
+ /* fix up PHYMODE4 align timing */
+ if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
+ void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
+ unsigned int tmp;
+
+ tmp = readl(mmio + 0x014);
+ tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */
+ writel(tmp, mmio + 0x014);
+ }
+
return 0;
err_out_kfree:
@@ -640,9 +654,11 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
* "TODO: figure out why we do this"
*/
- /* change FIFO_SHD to 8 dwords, enable BMR_BURST */
+ /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
tmp = readl(mmio + PDC_FLASH_CTL);
- tmp |= 0x12000; /* bit 16 (fifo 8 dw) and 13 (bmr burst?) */
+ tmp |= 0x02000; /* bit 13 (enable bmr burst) */
+ if (!(hp->flags & PDC_FLAG_GEN_II))
+ tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
writel(tmp, mmio + PDC_FLASH_CTL);
/* clear plug/unplug flags for all ports */
@@ -653,6 +669,10 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
tmp = readl(mmio + hotplug_offset);
writel(tmp | 0xff0000, mmio + hotplug_offset);
+ /* don't initialise TBG or SLEW on 2nd generation chips */
+ if (hp->flags & PDC_FLAG_GEN_II)
+ return;
+
/* reduce TBG clock to 133 Mhz. */
tmp = readl(mmio + PDC_TBG_MODE);
tmp &= ~0x30000; /* clear bit 17, 16*/
@@ -746,6 +766,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* notice 4-port boards */
switch (board_idx) {
case board_40518:
+ hp->flags |= PDC_FLAG_GEN_II;
/* Override hotplug offset for SATAII150 */
hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
/* Fall through */
@@ -759,15 +780,14 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->port[3].scr_addr = base + 0x700;
break;
case board_2057x:
+ case board_20771:
+ hp->flags |= PDC_FLAG_GEN_II;
/* Override hotplug offset for SATAII150 */
hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
/* Fall through */
case board_2037x:
probe_ent->n_ports = 2;
break;
- case board_20771:
- probe_ent->n_ports = 2;
- break;
case board_20619:
probe_ent->n_ports = 4;
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index ca8d99312472..7808d0369d91 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -356,6 +356,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
{
+ struct ata_eh_info *ehi = &ap->eh_info;
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
u8 status;
@@ -428,6 +429,10 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
/* kick HSM in the ass */
ata_hsm_move(ap, qc, status, 0);
+ if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
+ qc->tf.protocol == ATA_PROT_ATAPI_DMA))
+ ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
+
return;
err_hsm:
@@ -534,6 +539,7 @@ static void sil_thaw(struct ata_port *ap)
*/
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
{
+ int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
unsigned int n, quirks = 0;
unsigned char model_num[41];
@@ -549,16 +555,18 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
if (slow_down ||
((ap->flags & SIL_FLAG_MOD15WRITE) &&
(quirks & SIL_QUIRK_MOD15WRITE))) {
- ata_dev_printk(dev, KERN_INFO, "applying Seagate errata fix "
- "(mod15write workaround)\n");
+ if (print_info)
+ ata_dev_printk(dev, KERN_INFO, "applying Seagate "
+ "errata fix (mod15write workaround)\n");
dev->max_sectors = 15;
return;
}
/* limit to udma5 */
if (quirks & SIL_QUIRK_UDMA5MAX) {
- ata_dev_printk(dev, KERN_INFO,
- "applying Maxtor errata fix %s\n", model_num);
+ if (print_info)
+ ata_dev_printk(dev, KERN_INFO, "applying Maxtor "
+ "errata fix %s\n", model_num);
dev->udma_mask &= ATA_UDMA5;
return;
}
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 169e200a6a71..5aa288d2fb86 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -100,10 +100,14 @@ enum {
*/
PORT_REGS_SIZE = 0x2000,
- PORT_LRAM = 0x0000, /* 31 LRAM slots and PM regs */
+ PORT_LRAM = 0x0000, /* 31 LRAM slots and PMP regs */
PORT_LRAM_SLOT_SZ = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
- PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
+ PORT_PMP = 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
+ PORT_PMP_STATUS = 0x0000, /* port device status offset */
+ PORT_PMP_QACTIVE = 0x0004, /* port device QActive offset */
+ PORT_PMP_SIZE = 0x0008, /* 8 bytes per PMP */
+
/* 32 bit regs */
PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
@@ -126,6 +130,7 @@ enum {
PORT_PHY_CFG = 0x1050,
PORT_SLOT_STAT = 0x1800,
PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
+ PORT_CONTEXT = 0x1e04,
PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
PORT_SCONTROL = 0x1f00,
@@ -139,9 +144,9 @@ enum {
PORT_CS_INIT = (1 << 2), /* port initialize */
PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */
- PORT_CS_RESUME = (1 << 6), /* port resume */
+ PORT_CS_PMP_RESUME = (1 << 6), /* PMP resume */
PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
- PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
+ PORT_CS_PMP_EN = (1 << 13), /* port multiplier enable */
PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
/* PORT_IRQ_STAT/ENABLE_SET/CLR */
@@ -562,7 +567,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
/* do SRST */
prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
- prb->fis[1] = 0; /* no PM yet */
+ prb->fis[1] = 0; /* no PMP yet */
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
@@ -1050,7 +1055,8 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
/* Clear port multiplier enable and resume bits */
- writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
+ writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME,
+ port + PORT_CTRL_CLR);
}
/* Turn on interrupts */
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9d1235ba06b1..9c25a1e91730 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -173,7 +173,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
- return val|val2;
+ return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
}
static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
@@ -212,7 +212,7 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
- return val | val2;
+ return (val | val2) & 0xfffffffb;
}
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -239,7 +239,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
int rc;
- u32 genctl;
+ u32 genctl, val;
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
int pci_dev_busy = 0;
u8 pmr;
@@ -285,17 +285,24 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (ent->device != 0x182) {
if ((pmr & SIS_PMR_COMBINED) == 0) {
dev_printk(KERN_INFO, &pdev->dev,
- "Detected SiS 180/181 chipset in SATA mode\n");
+ "Detected SiS 180/181/964 chipset in SATA mode\n");
port2_start = 64;
}
else {
dev_printk(KERN_INFO, &pdev->dev,
"Detected SiS 180/181 chipset in combined mode\n");
port2_start=0;
+ pi.flags |= ATA_FLAG_SLAVE_POSS;
}
}
else {
- dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
+ pci_read_config_dword ( pdev, 0x6C, &val);
+ if (val & (1L << 31)) {
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
+ pi.flags |= ATA_FLAG_SLAVE_POSS;
+ }
+ else
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
port2_start = 0x20;
}
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 9fffa7af6db1..afa7d750a593 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -972,7 +972,7 @@ static int make_rate (unsigned int rate, rounding r,
}
case round_up: {
// check all bits that we are discarding
- if (man & (-1>>9)) {
+ if (man & (~0U>>9)) {
man = (man>>(32-9)) + 1;
if (man == (1<<9)) {
// no need to check for round up outside of range
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 697ad82f6634..9c67df5ccfa4 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -512,7 +512,7 @@ static unsigned int make_rate (unsigned int rate, int r,
}
case ROUND_UP: {
/* check all bits that we are discarding */
- if (man & (-1>>9)) {
+ if (man & (~0U>>9)) {
man = (man>>(32-9)) + 1;
if (man == (1<<9)) {
/* no need to check for round up outside of range */
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 87b17c33b3f9..f40786121948 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -135,7 +135,7 @@ static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos,
int flags);
static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos,
char *page);
-static void idt77252_softint(void *dev_id);
+static void idt77252_softint(struct work_struct *work);
static struct atmdev_ops idt77252_ops =
@@ -2866,9 +2866,10 @@ out:
}
static void
-idt77252_softint(void *dev_id)
+idt77252_softint(struct work_struct *work)
{
- struct idt77252_dev *card = dev_id;
+ struct idt77252_dev *card =
+ container_of(work, struct idt77252_dev, tqueue);
u32 stat;
int done;
@@ -3697,7 +3698,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
card->pcidev = pcidev;
sprintf(card->name, "idt77252-%d", card->index);
- INIT_WORK(&card->tqueue, idt77252_softint, (void *)card);
+ INIT_WORK(&card->tqueue, idt77252_softint);
membase = pci_resource_start(pcidev, 1);
srambase = pci_resource_start(pcidev, 2);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4bef76a2f3f2..1f745f12f94e 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -5,6 +5,7 @@
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <linux/cpu.h>
#include <linux/topology.h>
#include <linux/device.h>
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 6d111228cfac..2308e83e5f33 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -159,7 +159,7 @@ void aoecmd_work(struct aoedev *d);
void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
void aoecmd_ata_rsp(struct sk_buff *);
void aoecmd_cfg_rsp(struct sk_buff *);
-void aoecmd_sleepwork(void *vp);
+void aoecmd_sleepwork(struct work_struct *);
struct sk_buff *new_skb(ulong);
int aoedev_init(void);
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 8a13b1af8bab..97f7f535f412 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -408,9 +408,9 @@ rexmit_timer(ulong vp)
/* this function performs work that has been deferred until sleeping is OK
*/
void
-aoecmd_sleepwork(void *vp)
+aoecmd_sleepwork(struct work_struct *work)
{
- struct aoedev *d = (struct aoedev *) vp;
+ struct aoedev *d = container_of(work, struct aoedev, work);
if (d->flags & DEVFL_GDALLOC)
aoeblk_gdalloc(d);
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 6125921bbec4..05a97197c918 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -88,7 +88,7 @@ aoedev_newdev(ulong nframes)
kfree(d);
return NULL;
}
- INIT_WORK(&d->work, aoecmd_sleepwork, d);
+ INIT_WORK(&d->work, aoecmd_sleepwork);
spin_lock_init(&d->lock);
init_timer(&d->timer);
d->timer.data = (ulong) d;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 9e6d3a87cbe3..3f1b38276e96 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -992,11 +992,11 @@ static void empty(void)
{
}
-static DECLARE_WORK(floppy_work, NULL, NULL);
+static DECLARE_WORK(floppy_work, NULL);
static void schedule_bh(void (*handler) (void))
{
- PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL);
+ PREPARE_WORK(&floppy_work, (work_func_t)handler);
schedule_work(&floppy_work);
}
@@ -1008,7 +1008,7 @@ static void cancel_activity(void)
spin_lock_irqsave(&floppy_lock, flags);
do_floppy = NULL;
- PREPARE_WORK(&floppy_work, (void *)empty, NULL);
+ PREPARE_WORK(&floppy_work, (work_func_t)empty);
del_timer(&fd_timer);
spin_unlock_irqrestore(&floppy_lock, flags);
}
@@ -1868,7 +1868,7 @@ static void show_floppy(void)
printk("fdc_busy=%lu\n", fdc_busy);
if (do_floppy)
printk("do_floppy=%p\n", do_floppy);
- if (floppy_work.pending)
+ if (work_pending(&floppy_work))
printk("floppy_work.func=%p\n", floppy_work.func);
if (timer_pending(&fd_timer))
printk("fd_timer.function=%p\n", fd_timer.function);
@@ -4498,7 +4498,7 @@ static void floppy_release_irq_and_dma(void)
printk("floppy timer still active:%s\n", timeout_message);
if (timer_pending(&fd_timer))
printk("auxiliary floppy timer still active\n");
- if (floppy_work.pending)
+ if (work_pending(&floppy_work))
printk("work still pending\n");
#endif
old_fdc = fdc;
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 40a11e567970..9d9bff23f426 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -352,19 +352,19 @@ static enum action (*phase)(void);
static void run_fsm(void);
-static void ps_tq_int( void *data);
+static void ps_tq_int(struct work_struct *work);
-static DECLARE_WORK(fsm_tq, ps_tq_int, NULL);
+static DECLARE_DELAYED_WORK(fsm_tq, ps_tq_int);
static void schedule_fsm(void)
{
if (!nice)
- schedule_work(&fsm_tq);
+ schedule_delayed_work(&fsm_tq, 0);
else
schedule_delayed_work(&fsm_tq, nice-1);
}
-static void ps_tq_int(void *data)
+static void ps_tq_int(struct work_struct *work)
{
run_fsm();
}
diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h
index 932342d7a8eb..bc3703294143 100644
--- a/drivers/block/paride/pseudo.h
+++ b/drivers/block/paride/pseudo.h
@@ -35,7 +35,7 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
-static void ps_tq_int( void *data);
+static void ps_tq_int(struct work_struct *work);
static void (* ps_continuation)(void);
static int (* ps_ready)(void);
@@ -45,7 +45,7 @@ static int ps_nice = 0;
static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused)));
-static DECLARE_WORK(ps_tq, ps_tq_int, NULL);
+static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int);
static void ps_set_intr(void (*continuation)(void),
int (*ready)(void),
@@ -63,14 +63,14 @@ static void ps_set_intr(void (*continuation)(void),
if (!ps_tq_active) {
ps_tq_active = 1;
if (!ps_nice)
- schedule_work(&ps_tq);
+ schedule_delayed_work(&ps_tq, 0);
else
schedule_delayed_work(&ps_tq, ps_nice-1);
}
spin_unlock_irqrestore(&ps_spinlock,flags);
}
-static void ps_tq_int(void *data)
+static void ps_tq_int(struct work_struct *work)
{
void (*con)(void);
unsigned long flags;
@@ -92,7 +92,7 @@ static void ps_tq_int(void *data)
}
ps_tq_active = 1;
if (!ps_nice)
- schedule_work(&ps_tq);
+ schedule_delayed_work(&ps_tq, 0);
else
schedule_delayed_work(&ps_tq, ps_nice-1);
spin_unlock_irqrestore(&ps_spinlock,flags);
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 47d6975268ff..54509eb3391b 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1244,9 +1244,10 @@ out:
return IRQ_RETVAL(handled);
}
-static void carm_fsm_task (void *_data)
+static void carm_fsm_task (struct work_struct *work)
{
- struct carm_host *host = _data;
+ struct carm_host *host =
+ container_of(work, struct carm_host, fsm_task);
unsigned long flags;
unsigned int state;
int rc, i, next_dev;
@@ -1619,7 +1620,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
host->pdev = pdev;
host->flags = pci_dac ? FL_DAC : 0;
spin_lock_init(&host->lock);
- INIT_WORK(&host->fsm_task, carm_fsm_task, host);
+ INIT_WORK(&host->fsm_task, carm_fsm_task);
init_completion(&host->probe_comp);
for (i = 0; i < ARRAY_SIZE(host->req); i++)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 0d5c73f07265..2098eff91e14 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -376,7 +376,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
int stalled_pipe);
static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
static void ub_reset_enter(struct ub_dev *sc, int try);
-static void ub_reset_task(void *arg);
+static void ub_reset_task(struct work_struct *work);
static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
struct ub_capacity *ret);
@@ -1558,9 +1558,9 @@ static void ub_reset_enter(struct ub_dev *sc, int try)
schedule_work(&sc->reset_work);
}
-static void ub_reset_task(void *arg)
+static void ub_reset_task(struct work_struct *work)
{
- struct ub_dev *sc = arg;
+ struct ub_dev *sc = container_of(work, struct ub_dev, reset_work);
unsigned long flags;
struct list_head *p;
struct ub_lun *lun;
@@ -2179,7 +2179,7 @@ static int ub_probe(struct usb_interface *intf,
usb_init_urb(&sc->work_urb);
tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
atomic_set(&sc->poison, 0);
- INIT_WORK(&sc->reset_work, ub_reset_task, sc);
+ INIT_WORK(&sc->reset_work, ub_reset_task);
init_waitqueue_head(&sc->reset_wait);
init_timer(&sc->work_timer);
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index ec5a1b90a0a2..e19ba4ebcd4e 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -759,6 +759,8 @@ static struct vio_driver viodasd_driver = {
}
};
+static int need_delete_probe;
+
/*
* Initialize the whole device driver. Handle module and non-module
* versions
@@ -773,46 +775,67 @@ static int __init viodasd_init(void)
if (viopath_hostLp == HvLpIndexInvalid) {
printk(VIOD_KERN_WARNING "invalid hosting partition\n");
- return -EIO;
+ rc = -EIO;
+ goto early_fail;
}
printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n",
viopath_hostLp);
/* register the block device */
- if (register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME)) {
+ rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
+ if (rc) {
printk(VIOD_KERN_WARNING
"Unable to get major number %d for %s\n",
VIODASD_MAJOR, VIOD_GENHD_NAME);
- return -EIO;
+ goto early_fail;
}
/* Actually open the path to the hosting partition */
- if (viopath_open(viopath_hostLp, viomajorsubtype_blockio,
- VIOMAXREQ + 2)) {
+ rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio,
+ VIOMAXREQ + 2);
+ if (rc) {
printk(VIOD_KERN_WARNING
"error opening path to host partition %d\n",
viopath_hostLp);
- unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
- return -EIO;
+ goto unregister_blk;
}
/* Initialize our request handler */
vio_setHandler(viomajorsubtype_blockio, handle_block_event);
rc = vio_register_driver(&viodasd_driver);
- if (rc == 0)
- driver_create_file(&viodasd_driver.driver, &driver_attr_probe);
+ if (rc) {
+ printk(VIOD_KERN_WARNING "vio_register_driver failed\n");
+ goto unset_handler;
+ }
+
+ /*
+ * If this call fails, it just means that we cannot dynamically
+ * add virtual disks, but the driver will still work fine for
+ * all existing disk, so ignore the failure.
+ */
+ if (!driver_create_file(&viodasd_driver.driver, &driver_attr_probe))
+ need_delete_probe = 1;
+
+ return 0;
+
+unset_handler:
+ vio_clearHandler(viomajorsubtype_blockio);
+ viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
+unregister_blk:
+ unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
+early_fail:
return rc;
}
module_init(viodasd_init);
-void viodasd_exit(void)
+void __exit viodasd_exit(void)
{
- driver_remove_file(&viodasd_driver.driver, &driver_attr_probe);
+ if (need_delete_probe)
+ driver_remove_file(&viodasd_driver.driver, &driver_attr_probe);
vio_unregister_driver(&viodasd_driver);
vio_clearHandler(viomajorsubtype_blockio);
- unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
+ unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
}
-
module_exit(viodasd_exit);
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 516751754aa9..9256985cbe36 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -157,9 +157,10 @@ static void bcm203x_complete(struct urb *urb)
}
}
-static void bcm203x_work(void *user_data)
+static void bcm203x_work(struct work_struct *work)
{
- struct bcm203x_data *data = user_data;
+ struct bcm203x_data *data =
+ container_of(work, struct bcm203x_data, work);
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
BT_ERR("Can't submit URB");
@@ -246,7 +247,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
release_firmware(firmware);
- INIT_WORK(&data->work, bcm203x_work, (void *) data);
+ INIT_WORK(&data->work, bcm203x_work);
usb_set_intfdata(intf, data);
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index cbc07250b898..acfb6a430dcc 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -892,43 +892,10 @@ static void bluecard_detach(struct pcmcia_device *link)
}
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int i;
-
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != CS_SUCCESS)
- return CS_NO_MORE_ITEMS;
-
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != CS_SUCCESS)
- return i;
-
- return pcmcia_parse_tuple(handle, tuple, parse);
-}
-
static int bluecard_config(struct pcmcia_device *link)
{
bluecard_info_t *info = link->priv;
- tuple_t tuple;
- u_short buf[256];
- cisparse_t parse;
- int i, n, last_ret, last_fn;
-
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-
- /* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, &tuple, &parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ int i, n;
link->conf.ConfigIndex = 0x20;
link->io.NumPorts1 = 64;
@@ -966,9 +933,6 @@ static int bluecard_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
bluecard_release(link);
return -ENODEV;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 3a96a0babc6a..aae3abace586 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -713,22 +713,7 @@ static int bt3c_config(struct pcmcia_device *link)
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
- int i, j, try, last_ret, last_fn;
-
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-
- /* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, &tuple, &parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ int i, j, try;
/* First pass: look for a config entry that looks normal. */
tuple.TupleData = (cisdata_t *)buf;
@@ -802,9 +787,6 @@ found_port:
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
bt3c_release(link);
return -ENODEV;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 3b29086b7c3f..92648ef2f5d0 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -644,22 +644,7 @@ static int btuart_config(struct pcmcia_device *link)
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
- int i, j, try, last_ret, last_fn;
-
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-
- /* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, &tuple, &parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ int i, j, try;
/* First pass: look for a config entry that looks normal. */
tuple.TupleData = (cisdata_t *) buf;
@@ -734,9 +719,6 @@ found_port:
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
btuart_release(link);
return -ENODEV;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 07eafbc5dc3a..77b99eecbc49 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -626,22 +626,7 @@ static int dtl1_config(struct pcmcia_device *link)
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
- int i, last_ret, last_fn;
-
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-
- /* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, &tuple, &parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ int i;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0;
@@ -690,9 +675,6 @@ static int dtl1_config(struct pcmcia_device *link)
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
-
failed:
dtl1_release(link);
return -ENODEV;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ad8b537ad47b..24f922f12783 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -855,39 +855,6 @@ config TANBAC_TB0219
depends TANBAC_TB022X
select GPIO_VR41XX
-menu "Ftape, the floppy tape device driver"
-
-config FTAPE
- tristate "Ftape (QIC-80/Travan) support"
- depends on BROKEN_ON_SMP && (ALPHA || X86)
- ---help---
- If you have a tape drive that is connected to your floppy
- controller, say Y here.
-
- Some tape drives (like the Seagate "Tape Store 3200" or the Iomega
- "Ditto 3200" or the Exabyte "Eagle TR-3") come with a "high speed"
- controller of their own. These drives (and their companion
- controllers) are also supported if you say Y here.
-
- If you have a special controller (such as the CMS FC-10, FC-20,
- Mountain Mach-II, or any controller that is based on the Intel 82078
- FDC like the high speed controllers by Seagate and Exabyte and
- Iomega's "Ditto Dash") you must configure it by selecting the
- appropriate entries from the "Floppy tape controllers" sub-menu
- below and possibly modify the default values for the IRQ and DMA
- channel and the IO base in ftape's configuration menu.
-
- If you want to use your floppy tape drive on a PCI-bus based system,
- please read the file <file:drivers/char/ftape/README.PCI>.
-
- The ftape kernel driver is also available as a runtime loadable
- module. To compile this driver as a module, choose M here: the
- module will be called ftape.
-
-source "drivers/char/ftape/Kconfig"
-
-endmenu
-
source "drivers/char/agp/Kconfig"
source "drivers/char/drm/Kconfig"
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 777cad045094..b1fcdab90947 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -78,7 +78,6 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_HW_RANDOM) += hw_random/
-obj-$(CONFIG_FTAPE) += ftape/
obj-$(CONFIG_COBALT_LCD) += lcd.o
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index e608dadece2f..acb2de5e3a98 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -926,9 +926,10 @@ cy_sched_event(struct cyclades_port *info, int event)
* had to poll every port to see if that port needed servicing.
*/
static void
-do_softint(void *private_)
+do_softint(struct work_struct *work)
{
- struct cyclades_port *info = (struct cyclades_port *) private_;
+ struct cyclades_port *info =
+ container_of(work, struct cyclades_port, tqueue);
struct tty_struct *tty;
tty = info->tty;
@@ -5328,7 +5329,7 @@ cy_init(void)
info->blocked_open = 0;
info->default_threshold = 0;
info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
+ INIT_WORK(&info->tqueue, do_softint);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->shutdown_wait);
@@ -5403,7 +5404,7 @@ cy_init(void)
info->blocked_open = 0;
info->default_threshold = 0;
info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
+ INIT_WORK(&info->tqueue, do_softint);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->shutdown_wait);
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 60c1695db300..806f9ce5f47b 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -500,9 +500,9 @@ via_dmablit_timer(unsigned long data)
static void
-via_dmablit_workqueue(void *data)
+via_dmablit_workqueue(struct work_struct *work)
{
- drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
+ drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq);
drm_device_t *dev = blitq->dev;
unsigned long irqsave;
drm_via_sg_info_t *cur_sg;
@@ -571,7 +571,7 @@ via_init_dmablit(drm_device_t *dev)
DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
}
DRM_INIT_WAITQUEUE(&blitq->busy_queue);
- INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq);
+ INIT_WORK(&blitq->wq, via_dmablit_workqueue);
init_timer(&blitq->poll_timer);
blitq->poll_timer.function = &via_dmablit_timer;
blitq->poll_timer.data = (unsigned long) blitq;
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 706733c0b36a..7c71eb779802 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -200,7 +200,7 @@ static int pc_ioctl(struct tty_struct *, struct file *,
static int info_ioctl(struct tty_struct *, struct file *,
unsigned int, unsigned long);
static void pc_set_termios(struct tty_struct *, struct termios *);
-static void do_softint(void *);
+static void do_softint(struct work_struct *work);
static void pc_stop(struct tty_struct *);
static void pc_start(struct tty_struct *);
static void pc_throttle(struct tty_struct * tty);
@@ -1505,7 +1505,7 @@ static void post_fep_init(unsigned int crd)
ch->brdchan = bc;
ch->mailbox = gd;
- INIT_WORK(&ch->tqueue, do_softint, ch);
+ INIT_WORK(&ch->tqueue, do_softint);
ch->board = &boards[crd];
spin_lock_irqsave(&epca_lock, flags);
@@ -2566,9 +2566,9 @@ static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios)
/* --------------------- Begin do_softint ----------------------- */
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *work)
{ /* Begin do_softint */
- struct channel *ch = (struct channel *) private_;
+ struct channel *ch = container_of(work, struct channel, tqueue);
/* Called in response to a modem change event */
if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */
struct tty_struct *tty = ch->tty;
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 15a4ea896328..93b551962513 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -723,9 +723,10 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
* -------------------------------------------------------------------
*/
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *work)
{
- struct esp_struct *info = (struct esp_struct *) private_;
+ struct esp_struct *info =
+ container_of(work, struct esp_struct, tqueue);
struct tty_struct *tty;
tty = info->tty;
@@ -746,9 +747,10 @@ static void do_softint(void *private_)
* do_serial_hangup() -> tty->hangup() -> esp_hangup()
*
*/
-static void do_serial_hangup(void *private_)
+static void do_serial_hangup(struct work_struct *work)
{
- struct esp_struct *info = (struct esp_struct *) private_;
+ struct esp_struct *info =
+ container_of(work, struct esp_struct, tqueue_hangup);
struct tty_struct *tty;
tty = info->tty;
@@ -2501,8 +2503,8 @@ static int __init espserial_init(void)
info->magic = ESP_MAGIC;
info->close_delay = 5*HZ/10;
info->closing_wait = 30*HZ;
- INIT_WORK(&info->tqueue, do_softint, info);
- INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
+ INIT_WORK(&info->tqueue, do_softint);
+ INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
info->config.rx_timeout = rx_timeout;
info->config.flow_on = flow_on;
info->config.flow_off = flow_off;
diff --git a/drivers/char/ftape/Kconfig b/drivers/char/ftape/Kconfig
deleted file mode 100644
index 0d65189a7ae8..000000000000
--- a/drivers/char/ftape/Kconfig
+++ /dev/null
@@ -1,330 +0,0 @@
-#
-# Ftape configuration
-#
-config ZFTAPE
- tristate "Zftape, the VFS interface"
- depends on FTAPE
- ---help---
- Normally, you want to say Y or M. DON'T say N here or you
- WON'T BE ABLE TO USE YOUR FLOPPY TAPE DRIVE.
-
- The ftape module itself no longer contains the routines necessary
- to interface with the kernel VFS layer (i.e. to actually write data
- to and read data from the tape drive). Instead the file system
- interface (i.e. the hardware independent part of the driver) has
- been moved to a separate module.
-
- To compile this driver as a module, choose M here: the
- module will be called zftape.
-
- Regardless of whether you say Y or M here, an additional runtime
- loadable module called `zft-compressor' which contains code to
- support user transparent on-the-fly compression based on Ross
- William's lzrw3 algorithm will be produced. If you have enabled the
- kernel module loader (i.e. have said Y to "Kernel module loader
- support", above) then `zft-compressor' will be loaded
- automatically by zftape when needed.
-
- Despite its name, zftape does NOT use compression by default.
-
-config ZFT_DFLT_BLK_SZ
- int "Default block size"
- depends on ZFTAPE
- default "10240"
- ---help---
- If unsure leave this at its default value, i.e. 10240. Note that
- you specify only the default block size here. The block size can be
- changed at run time using the MTSETBLK tape operation with the
- MTIOCTOP ioctl (i.e. with "mt -f /dev/qft0 setblk #BLKSZ" from the
- shell command line).
-
- The probably most striking difference between zftape and previous
- versions of ftape is the fact that all data must be written or read
- in multiples of a fixed block size. The block size defaults to
- 10240 which is what GNU tar uses. The values for the block size
- should be either 1 or multiples of 1024 up to a maximum value of
- 63488 (i.e. 62 K). If you specify `1' then zftape's builtin
- compression will be disabled.
-
- Reasonable values are `10240' (GNU tar's default block size),
- `5120' (afio's default block size), `32768' (default block size some
- backup programs assume for SCSI tape drives) or `1' (no restriction
- on block size, but disables builtin compression).
-
-comment "The compressor will be built as a module only!"
- depends on FTAPE && ZFTAPE
-
-config ZFT_COMPRESSOR
- tristate
- depends on FTAPE!=n && ZFTAPE!=n
- default m
-
-config FT_NR_BUFFERS
- int "Number of ftape buffers (EXPERIMENTAL)"
- depends on FTAPE && EXPERIMENTAL
- default "3"
- help
- Please leave this at `3' unless you REALLY know what you are doing.
- It is not necessary to change this value. Values below 3 make the
- proper use of ftape impossible, values greater than 3 are a waste of
- memory. You can change the amount of DMA memory used by ftape at
- runtime with "mt -f /dev/qft0 setdrvbuffer #NUMBUFFERS". Each buffer
- wastes 32 KB of memory. Please note that this memory cannot be
- swapped out.
-
-config FT_PROC_FS
- bool "Enable procfs status report (+2kb)"
- depends on FTAPE && PROC_FS
- ---help---
- Optional. Saying Y will result in creation of a directory
- `/proc/ftape' under the /proc file system. The files can be viewed
- with your favorite pager (i.e. use "more /proc/ftape/history" or
- "less /proc/ftape/history" or simply "cat /proc/ftape/history"). The
- file will contain some status information about the inserted
- cartridge, the kernel driver, your tape drive, the floppy disk
- controller and the error history for the most recent use of the
- kernel driver. Saying Y will enlarge the size of the ftape driver
- by approximately 2 KB.
-
- WARNING: When compiling ftape as a module (i.e. saying M to "Floppy
- tape drive") it is dangerous to use ftape's /proc file system
- interface. Accessing `/proc/ftape' while the module is unloaded will
- result in a kernel Oops. This cannot be fixed from inside ftape.
-
-choice
- prompt "Debugging output"
- depends on FTAPE
- default FT_NORMAL_DEBUG
-
-config FT_NORMAL_DEBUG
- bool "Normal"
- ---help---
- This option controls the amount of debugging output the ftape driver
- is ABLE to produce; it does not increase or diminish the debugging
- level itself. If unsure, leave this at its default setting,
- i.e. choose "Normal".
-
- Ftape can print lots of debugging messages to the system console
- resp. kernel log files. Reducing the amount of possible debugging
- output reduces the size of the kernel module by some KB, so it might
- be a good idea to use "None" for emergency boot floppies.
-
- If you want to save memory then the following strategy is
- recommended: leave this option at its default setting "Normal" until
- you know that the driver works as expected, afterwards reconfigure
- the kernel, this time specifying "Reduced" or "None" and recompile
- and install the kernel as usual. Note that choosing "Excessive"
- debugging output does not increase the amount of debugging output
- printed to the console but only makes it possible to produce
- "Excessive" debugging output.
-
- Please read <file:Documentation/ftape.txt> for a short description
- how to control the amount of debugging output.
-
-config FT_FULL_DEBUG
- bool "Excessive"
- help
- Extremely verbose output for driver debugging purposes.
-
-config FT_NO_TRACE
- bool "Reduced"
- help
- Reduced tape driver debugging output.
-
-config FT_NO_TRACE_AT_ALL
- bool "None"
- help
- Suppress all debugging output from the tape drive.
-
-endchoice
-
-comment "Hardware configuration"
- depends on FTAPE
-
-choice
- prompt "Floppy tape controllers"
- depends on FTAPE
- default FT_STD_FDC
-
-config FT_STD_FDC
- bool "Standard"
- ---help---
- Only change this setting if you have a special controller. If you
- didn't plug any add-on card into your computer system but just
- plugged the floppy tape cable into the already existing floppy drive
- controller then you don't want to change the default setting,
- i.e. choose "Standard".
-
- Choose "MACH-2" if you have a Mountain Mach-2 controller.
- Choose "FC-10/FC-20" if you have a Colorado FC-10 or FC-20
- controller.
- Choose "Alt/82078" if you have another controller that is located at
- an IO base address different from the standard floppy drive
- controller's base address of `0x3f0', or uses an IRQ (interrupt)
- channel different from `6', or a DMA channel different from
- `2'. This is necessary for any controller card that is based on
- Intel's 82078 FDC such as Seagate's, Exabyte's and Iomega's "high
- speed" controllers.
-
- If you choose something other than "Standard" then please make
- sure that the settings for the IO base address and the IRQ and DMA
- channel in the configuration menus below are correct. Use the manual
- of your tape drive to determine the correct settings!
-
- If you are already successfully using your tape drive with another
- operating system then you definitely should use the same settings
- for the IO base, the IRQ and DMA channel that have proven to work
- with that other OS.
-
- Note that this menu lets you specify only the default setting for
- the hardware setup. The hardware configuration can be changed at
- boot time (when ftape is compiled into the kernel, i.e. if you
- have said Y to "Floppy tape drive") or module load time (i.e. if you
- have said M to "Floppy tape drive").
-
- Please read also the file <file:Documentation/ftape.txt> which
- contains a short description of the parameters that can be set at
- boot or load time. If you want to use your floppy tape drive on a
- PCI-bus based system, please read the file
- <file:drivers/char/ftape/README.PCI>.
-
-config FT_MACH2
- bool "MACH-2"
-
-config FT_PROBE_FC10
- bool "FC-10/FC-20"
-
-config FT_ALT_FDC
- bool "Alt/82078"
-
-endchoice
-
-comment "Consult the manuals of your tape drive for the correct settings!"
- depends on FTAPE && !FT_STD_FDC
-
-config FT_FDC_BASE
- hex "IO base of the floppy disk controller"
- depends on FTAPE && !FT_STD_FDC
- default "0"
- ---help---
- You don't need to specify a value if the following default
- settings for the base IO address are correct:
- <<< MACH-2 : 0x1E0 >>>
- <<< FC-10/FC-20: 0x180 >>>
- <<< Secondary : 0x370 >>>
- Secondary refers to a secondary FDC controller like the "high speed"
- controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
- Please make sure that the setting for the IO base address
- specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
- CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
- successfully using the tape drive with another operating system then
- you definitely should use the same settings for the IO base that has
- proven to work with that other OS.
-
- Note that this menu lets you specify only the default setting for
- the IO base. The hardware configuration can be changed at boot time
- (when ftape is compiled into the kernel, i.e. if you specified Y to
- "Floppy tape drive") or module load time (i.e. if you have said M to
- "Floppy tape drive").
-
- Please read also the file <file:Documentation/ftape.txt> which
- contains a short description of the parameters that can be set at
- boot or load time.
-
-config FT_FDC_IRQ
- int "IRQ channel of the floppy disk controller"
- depends on FTAPE && !FT_STD_FDC
- default "0"
- ---help---
- You don't need to specify a value if the following default
- settings for the interrupt channel are correct:
- <<< MACH-2 : 6 >>>
- <<< FC-10/FC-20: 9 >>>
- <<< Secondary : 6 >>>
- Secondary refers to secondary a FDC controller like the "high speed"
- controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
- Please make sure that the setting for the IO base address
- specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
- CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
- successfully using the tape drive with another operating system then
- you definitely should use the same settings for the IO base that has
- proven to work with that other OS.
-
- Note that this menu lets you specify only the default setting for
- the IRQ channel. The hardware configuration can be changed at boot
- time (when ftape is compiled into the kernel, i.e. if you said Y to
- "Floppy tape drive") or module load time (i.e. if you said M to
- "Floppy tape drive").
-
- Please read also the file <file:Documentation/ftape.txt> which
- contains a short description of the parameters that can be set at
- boot or load time.
-
-config FT_FDC_DMA
- int "DMA channel of the floppy disk controller"
- depends on FTAPE && !FT_STD_FDC
- default "0"
- ---help---
- You don't need to specify a value if the following default
- settings for the DMA channel are correct:
- <<< MACH-2 : 2 >>>
- <<< FC-10/FC-20: 3 >>>
- <<< Secondary : 2 >>>
- Secondary refers to a secondary FDC controller like the "high speed"
- controllers delivered by Seagate or Exabyte or Iomega's Ditto Dash.
- Please make sure that the setting for the IO base address
- specified here is correct. USE THE MANUAL OF YOUR TAPE DRIVE OR
- CONTROLLER CARD TO DETERMINE THE CORRECT SETTING. If you are already
- successfully using the tape drive with another operating system then
- you definitely should use the same settings for the IO base that has
- proven to work with that other OS.
-
- Note that this menu lets you specify only the default setting for
- the DMA channel. The hardware configuration can be changed at boot
- time (when ftape is compiled into the kernel, i.e. if you said Y to
- "Floppy tape drive") or module load time (i.e. if you said M to
- "Floppy tape drive").
-
- Please read also the file <file:Documentation/ftape.txt> which
- contains a short description of the parameters that can be set at
- boot or load time.
-
-config FT_FDC_THR
- int "Default FIFO threshold (EXPERIMENTAL)"
- depends on FTAPE && EXPERIMENTAL
- default "8"
- help
- Set the FIFO threshold of the FDC. If this is higher the DMA
- controller may serve the FDC after a higher latency time. If this is
- lower, fewer DMA transfers occur leading to less bus contention.
- You may try to tune this if ftape annoys you with "reduced data
- rate because of excessive overrun errors" messages. However, this
- doesn't seem to have too much effect.
-
- If unsure, don't touch the initial value, i.e. leave it at "8".
-
-config FT_FDC_MAX_RATE
- int "Maximal data rate to use (EXPERIMENTAL)"
- depends on FTAPE && EXPERIMENTAL
- default "2000"
- ---help---
- With some motherboard/FDC combinations ftape will not be able to
- run your FDC/tape drive combination at the highest available
- speed. If this is the case you'll encounter "reduced data rate
- because of excessive overrun errors" messages and lots of retries
- before ftape finally decides to reduce the data rate.
-
- In this case it might be desirable to tell ftape beforehand that
- it need not try to run the tape drive at the highest available
- speed. If unsure, leave this disabled, i.e. leave it at 2000
- bits/sec.
-
-config FT_ALPHA_CLOCK
- int "CPU clock frequency of your DEC Alpha" if ALPHA
- depends on FTAPE
- default "0"
- help
- On some DEC Alpha machines the CPU clock frequency cannot be
- determined automatically, so you need to specify it here ONLY if
- running a DEC Alpha, otherwise this setting has no effect.
-
diff --git a/drivers/char/ftape/Makefile b/drivers/char/ftape/Makefile
deleted file mode 100644
index 0e67d2f8b7ec..000000000000
--- a/drivers/char/ftape/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 1997 Claus Heine.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/05 19:17:56 $
-#
-# Makefile for the QIC-40/80/3010/3020 floppy-tape driver for
-# Linux.
-#
-
-obj-$(CONFIG_FTAPE) += lowlevel/
-obj-$(CONFIG_ZFTAPE) += zftape/
-obj-$(CONFIG_ZFT_COMPRESSOR) += compressor/
diff --git a/drivers/char/ftape/README.PCI b/drivers/char/ftape/README.PCI
deleted file mode 100644
index 18de159d36e0..000000000000
--- a/drivers/char/ftape/README.PCI
+++ /dev/null
@@ -1,81 +0,0 @@
-Some notes for ftape users with PCI motherboards:
-=================================================
-
-The problem:
-------------
-
-There have been some problem reports from people using PCI-bus based
-systems getting overrun errors.
-I wasn't able to reproduce these until I ran ftape on a Intel Plato
-(Premiere PCI II) motherboard with bios version 1.00.08AX1.
-It turned out that if GAT (Guaranteed Access Timing) is enabled (?)
-ftape gets a lot of overrun errors.
-The problem disappears when disabling GAT in the bios.
-Note that Intel removed this setting (permanently disabled) from the
-1.00.10AX1 bios !
-
-It looks like that if GAT is enabled there are often large periods
-(greater than 120 us !??) on the ISA bus that the DMA controller cannot
-service the floppy disk controller.
-I cannot imagine this being acceptable in a decent PCI implementation.
-Maybe this is a `feature' of the chipset. I can only speculate why
-Intel choose to remove the option from the latest Bios...
-
-The lesson of this all is that there may be other motherboard
-implementations having the same of similar problems.
-If you experience a lot of overrun errors during a backup to tape,
-see if there is some setting in the Bios that may influence the
-bus timing.
-
-I judge this a hardware problem and not a limitation of ftape ;-)
-My DOS backup software seems to be suffering from the same problems
-and even refuses to run at 1 Mbps !
-Ftape will reduce the data-rate from 1 Mbps to 500 Kbps if the number
-of overrun errors on a track exceeds a threshold.
-
-
-Possible solutions:
--------------------
-
-Some of the problems were solved by upgrading the (flash) bios.
-Other suggest that it has to do with the FDC being on the PCI
-bus, but that is not the case with the Intel Premiere II boards.
-[If upgrading the bios doesn't solve the problem you could try
-a floppy disk controller on the isa-bus].
-
-Here is a list of systems and recommended BIOS settings:
-
-
- Intel Premiere PCI (Revenge):
-
-Bios version 1.00.09.AF2 is reported to work.
-
-
-
- Intel Premiere PCI II (Plato):
-
-Bios version 1.00.10.AX1 and version 11 beta are ok.
-If using version 1.00.08.AX1, GAT must be disabled !
-
-
-
- ASUS PCI/I-SP3G:
-
-Preferred settings: ISA-GAT-mode : disabled
- DMA-linebuffer-mode : standard
- ISA-masterbuffer-mode : standard
-
-
- DELL Dimension XPS P90
-
-Bios version A2 is reported to be broken, while bios version A5 works.
-You can get a flash bios upgrade from http://www.dell.com
-
-
-To see if you're having the GAT problem, try making a backup
-under DOS. If it's very slow and often repositions you're
-probably having this problem.
-
- --//--
- LocalWords: ftape PCI bios GAT ISA DMA chipset Mbps Kbps FDC isa AF ok ASUS
- LocalWords: SP linebuffer masterbuffer XPS http www com
diff --git a/drivers/char/ftape/RELEASE-NOTES b/drivers/char/ftape/RELEASE-NOTES
deleted file mode 100644
index 03799dbc05a4..000000000000
--- a/drivers/char/ftape/RELEASE-NOTES
+++ /dev/null
@@ -1,966 +0,0 @@
-Hey, Emacs, we're -*-Text-*- mode!
-
-===== Release notes for ftape-3.04d 25/11/97 =====
-- The correct pre-processor statement for "else if" is "#elif" not
- "elsif".
-- Need to call zft_reset_position() when overwriting cartridges
- previously written with ftape-2.x, sftape, or ancient
- (pre-ftape-3.x) versions of zftape.
-
-===== Release notes for ftape-3.04c 16/11/97 =====
-- fdc_probe() was calling DUMPREGS with a result length of "1" which
- was just fine. Undo previous change.
-
-===== Release notes for ftape-3.04b 14/11/97 =====
-
-- patches/2.x.x/floppy.c.diff was somewhat broken, releasing i/o
- regions it never had allocated.
-- fdc_probe() was calling DUMPREGS with a result length of "1" instead
- of "10"
-- Writing deleted data marks if the first segents on track zero are
- should work now.
-- ftformat should now be able to handle those cases where the tape
- drive sets the read only status bit (QIC-40/80 cartridges with
- QIC-3010/3020 tape drives) because the header segment is damaged.
-- the MTIOCFTCMD ioctl may now be issued by the superuser ONLY.
-
-===== Release notes for ftape-3.04a 12/11/97 =====
-- Fix an "infinite loop can't be killed by signal" bug in
- ftape_get_drive_status(). Only relevant when trying to access
- buggy/misconfigured hardware
-- Try to compensate a bug in the HP Colorado T3000's firmware: it
- doesn't set the write protect bit for QIC80/QIC40 cartridges.
-
-===== Release notes for ftape-3.04 06/11/97 =====
-- If positioning with fast seeking fails fall back to a slow seek
- before giving up.
-- (nearly) no retries on "no data errors" when verifying after
- formatting. Improved tuning of the bad sector map after formatting.
-- the directory layout has changed again to allow for easier kernel
- integration
-- Module parameter "ftape_tracing" now is called "ft_tracing" because
- the "ftape_tracing" variable has the version checksum attached to it.
-- `/proc/ftape' interface for 2.0.* kernels. `/proc/ftape' no longer
- is a directory but a file that contains all the information formerly
- provided in separate files under the `/proc/ftape/' directory.
-- Most of the configuration options have been prefixed by "CONFIG_FT_"
- in preparation of the kernel inclusion. The Makefiles under
- "./ftape/" should be directly usable by the kernel.
-- The MODVERSIONS stuff is now auto-detected.
-- Broke backslashed multi line options in MCONFIG into separate lines
- using GNU-make's "+=" feature.
-- The html and dvi version of the manual is now installed under
- '/usr/doc/ftape` with 'make install`
-- New SMP define in MCONFIG. ftape works with SMP if this is defined.
-- attempt to cope with "excessive overrun errors" by gradually
- increasing FDC FIFO threshold. But this doesn't seem to have too
- much an effect.
-- New load time configuration parameter "ft_fdc_rate_limit". If you
- encounter too many overrun errors with a 2Mb controller then you
- might want to set this to 1000.
-- overrun errors on the last sector in a segment sometimes result in
- a zero DMA residue. Dunno why, but compensate for it.
-- there were still fdc_read() timeout errors. I think I have fixed it
- now, please FIXME.
-- Sometimes ftape_write() failed to re-start the tape drive when a
- segment without a good sector was reached ("wait for empty segment
- failed"). This is fixed. Especially important for > QIC-3010.
-- sftape (aka ftape-2.x) has vanished. I didn't work on it for
- ages. It is probably still possible to use the old code with
- ftape-3.04, if one really needs it (BUT RECOMPILE IT)
-- zftape no longer alters the contents of already existing volume
- table entries, which makes it possible to fill in missing fields,
- like time stamps using some user space program.
-- ./contrib/vtblc/ contains such a program.
-- new perl script ./contrib/scripts/listtape that list the contents of a
- floppy tape cartridge parsing the output of "mt volinfo" + "mt fsf"
-- the MTWEOF implementation has changed a little bit (after I had a
- look at amanda). Calling MTWEOF while the tape is still held open
- after writing something to the tape now will terminate the current
- volume, and start a new one at the current position.
-- the volume table maintained by zftape now is a doubly linked list
- that grows dynamically as needed.
-
- formatting floppy tape cartridges
- ---------------------------------
- * there is a new user space formatting program that does most of the
- dirty work in user space (auto-detect, computing the sector
- coordinates, adjusting time stamps and statistics). It has a
- simple command line interface.
- * ftape-format.o has vanished, it has been folded into the low level
- ftape.o module, and the ioctl interface into zftape.o. Most of the
- complicated stuff has been moved to user space, so there was no
- need for a separate module anymore.
- * there is a new ioctl MTIOCFTCMD that sends a bare QIC-117 command
- to the tape drive.
- * there is a new mmap() feature to map the dma buffers into user
- space to be used by the user level formatting program.
- * Formatting of yet unformatted or totally degaussed cartridges
- should be possible now. FIXME.
-
-===== Release notes for ftape-3.03b, <forgot the exact date> ====
-
-ftape-3.03b was released as a beta release only. Its main new feature
-was support of the DITTO-2GB drive. This was made possible by reverse
-engineering done by <fill in his name> after Iomega failed to support
-ftape. Although they had promised to do so (this makes me feel a bit
-sad and uncomfortable about Iomega).
-
-===== Release notes for ftape-3.03a, 22/05/97 ====
-
-- Finally fixed auto-un-loading of modules for kernels > 2.1.18
-- Add an "uninstall" target to the Makefile
-- removed the kdtime hack
-- texi2www didn't properly set the back-reference from a footnote back
- to the regular text.
-
- zftape specific
- ---------------
- * hide the old compression map volume. Taper doesn't accept the
- presence of non-Taper volumes and Taper-written volume on the same
- tape.
- * EOD (End Of Data) handling was still broken: the expected behavior
- is to return a zero byte count at the first attempt to read past
- EOD, return a zero byte count at the second attempt to read past
- EOD and THEN return -EIO.
-
- ftape-format specific
- ---------------------
- * Detection of QIC-40 cartridges in select_tape_format() was broken
- and made it impossible to format QIC-3010/3020 cartridges.
- * There are strange "TR-1 Extra" cartridges out there which weren't
- detected properly because the don't strictly conform to the
- QIC-80, Rev. N, spec.
-
-===== Release notes for ftape-3.03, 30/04/97 =====
-
-- Removed kernel integration code from the package. I plan to provide
- a package that can be integrated into the stock kernel separately
- (hopefully soon).
- As a result, a simple `make' command now will build everything.
-- ALL compile time configuration options have been moved to the file
- `MCONFIG'.
-- Quite a few `low level' changes to allow formatting of cartridges.
-- formatting is implemented as a separate module `ftape-format.o'. The
- modified `mt' program contains sample code that shows how to use it.
-- The VFS interface has been moved from the `ftape.o' module to the
- high level modules `zftape.o' resp. `sftape.o'. `ftape.o' contains
- the hardware support only.
-- A bit of /proc support for kernels > 2.1.28
-- Moved documentation to Doc subdir. INSTALL now contains some real
- installation notes.
-- `install' target in Makefile.
-
-zftape specific:
-----------------
-
-- zftape works for large cartridges now ( > 2^31 bytes)
-- MTIOCVOLINFO and MTIOCGETSIZE now return the size in KILOBYTES,
- NO LONGER in bytes.
-
-- permissions for write access to a cartridge have changed:
- * zftape now also takes the file access mode into account
- * zftape no longer allows writing in the middle of the recorded
- media. The tape has to be positioned at BOT or EOD for write
- access.
-
-- MTBSF has changed. It used to position at the beginning of the
- previous file when called with count 1. This was different from the
- expected behavior for other Un*x tape drivers (i.e. SCSI). MTBSF
- with count 1 should merely position at the beginning of the current
- volume. Fixed. As a result, `tar --verify' now produces the desired
- result: it verifies the last written volume, not the pre-last
- written volume.
-
-- The compression map has vanished --> no need for `mt erase' any
- more. Fast seeking in a compressed volume is still be possible, but
- takes slightly longer. As a side effect, you may experience an
- additional volume showing up in front of all others for old
- cartridges. This is the tape volume that holds the compression map.
-
-- The compression support for zftape has been moved to a separate
- module `zft-compressor'. DON'T forget to load it before trying to
- read back compressed volumes. The stock `zftape.o' module probes for
- the module `zft-compressor' using the kerneld message channel; you
- have to install `zft-compressor.o' in a place where modprobe can
- find it if you want to use this.
-
-- New experimental feature that tries to get the broken down GMT time
- from user space via a kernel daemon message channel. You need to
- compile and start the `kdtime' daemon contained in the contrib
- directory to use it. Needed (?) for time stamps in the header
- segments and the volume table.
-
-- variable block size mode via MTSETBLK 0
-
-- keep modules locked in memory after the block size has been changed
-
-sftape specific:
-----------------
-
-- end of tape handling should be fixed, i.e. multi volume archives
- written with `afio' can be read back now.
-
-
-===== Release notes for ftape-3.02a, 09/01/97 =====
-
-No big news:
-- call zft_init() resp. sft_init() when compiling the entire stuff
- into the kernel image.
-- fix bug in ftape-setup.c when NO_TRACE_AT_ALL was defined.
-- fix bug in sftape-eof.c/zftape-eof.c for old kernels (1.2.*)
-- add support for new module interface for recent kernels
-
-===== Release notes for ftape-3.02, 16/12/96 =====
-- Fixed the `FDC unlock command failed' bug in fdc-io.c. When the FIFO
- was already locked when ftape was loaded, ftape failed to unlock it.
-- Fixed compilation of `contrib/gnumt'. It now finds `mtio.h' even if
- ftape is NOT included into the kernel source tree.
-- fc-10.c: include <asm/io.h> for inb() and outb().
-- ftape/sftape/zftape: all global variable now have either a `ftape_',
- a `ft_', `sft_', `zft_' or `qic_' prefix to prevent name clashes
- with other parts of the kernel when including ftape into the kernel
- source tree.
-- Kerneld support has changed. `ftape' now searches for a module
- `ftape-frontend' when none of the frontend (`sftape' or `zftape') is
- loaded. Please refer to the `Installation/Loading ftape' section of
- the TeXinfo manual.
-- Add load resp. boot-time configuration of ftape. There are now
- variables ft_fdc_base, ft_fdc_dma and ft_fdc_irq corresponding to
- the former FDC_BASE etc. compile time definitions. One can also use
- the kernel command line parameters to configure the driver if it is
- compiled into the kernel. Also, the FC-10/FC-20 support is load-time
- configurable now as well as the MACH-II hack (ft_probe_fc10,
- resp. ft_mach2). Please refer to the section `Installation/Configure
- ftape' of the TeXinfo manual.
-- I removed the MODVERSIONS option from `Makefile.module'. Let me alone
- with ftape and MODVERSIONS unless you include the ftape sources into
- the kernel source tree.
-- new vendors in `vendors.h':
- * HP Colorado T3000
- * ComByte DoublePlay (including a bug fix for their broken
- formatting software, thanks to whraven@njackn.com)
- * Iomega DITTO 2GIG. NOTE: this drive cannot work with ftape because
- the logical data layout of the cartridges used by this drive does
- NOT conform to the QIC standards, it is a special Iomega specific
- format. I've sent mail to Iomega but didn't receive an answer
- yet. If you want this drive to be supported by ftape, ask Iomega
- to give me information about it.
-- zftape:
- * re-introduced the MTIOC_ZFTAPE_GETBLKSZ ioctl for compatibility
- with zftape 1.06a and earlier. Please don't use it when writing
- new software, use the MTIOCVOLINFO ioctl instead.
- * Major overhaul of the code that updates the header segments. Never
- change the tape label unless erasing the tape. Thus we almost
- never need to write the header segments, unless we would modify
- the bad sector map which isn't done yet. Updating of volume table
- and compression map more secure now although it takes a bit
- longer.
- * Fixed bug when aborting a write operation with a signal: zftape
- now finishes the current volume (i.e. writes an eof marker) at the
- current position. It didn't before which led to somehow *strange*
- behavior in this cases.
- * Keep module locked in memory when using it with the non-rewinding
- devices and the tape is not logical at BOT. Needed for kerneld
- support.
-- sftape:
- * Keep module locked in memory when using it with the non-rewinding
- devices and the tape is not logical at BOT. Needed for kerneld
- support.
-
-===== Release notes for ftape-3.01, 14/11/96 =====
-
-- Fixed silly bugs in ftape-3.00:
- * MAKEDEV.ftape: major device number must be 27, not 23
- * sftape/sftape-read.c: sftape_read_header_segments() called
- itself recursively instead of calling ftape_read_header_segment()
- * zftape/qic-vtbl.h: conversion of ftape's file marks to zftape's
- internal volume table was broken.
- * patches/2.x.x/linux-2.0.21.dif: my RCS (resp. CVS) system replaced
- the `$Revison:' etc. macros in the `ftape.h' concerning part of the
- patch :-( Fixed.
- * info/ftape.info: Fixed misspellings (`cp' <-> `cp -r' etc.)
- * when ftape/sftape or ftape/zftape was compiled into the kernel the
- variable ftape_status was declared twice. Fixed.
- * removed reference to undeclared variable kernel_version when not
- compiling as module
- * fixed a bug introduced by the use of bit-fields for some flags
- (i.e. write_protected, no_cartridge, formatted)
- * flag `header_read' is now reset correctly to zero when tape is
- removed.
-- fixed a bug in sftape/sftape-eof.c that was already in the original
- ftape code. MTFSF/BSF was not handled correctly when positioned
- right before the file mark (think of tar)
-- Changed TRACE macros (following a suggestion of Marcin Dalecki) to use
- the predefined __FUNCTION__ macro of GCC. Spares about 4k of code.
-- added new vendor id for Iomega DITTO 2GIG
-- fixed a bug already present in zftape-1.06 when aborting a write
- with a signal: we now finish the current volume at that
- position. Header segments remain NOT up to date until an explicit call
- to MTREW or MTOFFL is done.
-
-===== Release notes for ftape-3.00, 14/10/96 =====
-
-- Merged ftape with zftape. There are three modules now:
- ftape for the hardware support, sftape for the implementation of the
- original ftape eof mark stuff and zftape that implements zftape's way
- of handling things (compression, volume table, tape blocks of
- constant length)
-- Documentation in TeXinfo format in the `info' subdirectory.
-- New ioctls for zftape. See zftape/zftape.h
-- Dummy formatting ioctl for ftape. See ftape.h
-- Kernel patch files for the 2.*.* series to include ftape-3.00 in the
- kernel source tree. These includes a kernel compatible Config.in
- script and fairly large online information for the kernel configure
- script.
-- Support for compiling with Linux-1.2.13.
-- Modified GNU mt from their cpio package that can handle the new
- ioctls.
-- ftape/sftape/zftape is kerneld save now!
-
-Notes on sftape:
-- sftape implements the eof handling code of the original ftape. If
- you like to stick with the original ftape stuff, you have to use
- this module, not zftape.
-- sftape is kerneld save, unlike the original ftape.
-- we keep the entire header segment now in memory, so no need to read
- it before updating the header segments. Additional memory
- consumption: 256 bytes.
-
-Notes for zftape:
-- zftape has support for tapes with format code 6 now, which use a
- slightly different volume table format compared with other floppy
- tapes.
-- new ioctls for zftape. Have a look at zftape/zftape.h
-- The internal volume table representation has changed for zftape. Old
- cartridges are converted automatically.
-- zftape no longer uses compression map segments, which have vanished
- from the QIC specs, but creates volume table entry that reserves
- enough space for the compression map.
-- zftape is kerneld save now.
-- we keep the entire header segment now in memory, so no need to read
- it before updating the header segments. Additional memory
- consumption: 256 bytes.
-
-Notes for contrib/gnumt:
-- modified mt from the GNU cpio package that supports all the new
- ioctls of zftape.
-Notes for contrib/swapout:
-- This contains the swapout.c program that was written by Kai
- Harrekilde-Pederson. I simply added a Makefile.
-
-===== Release notes for ftape-2.10, 14/10/96 =====
-
-The ftape maintainer has changed.
-Kai Harrekilde-Petersen <khp@dolphinics.no>
-has resigned from maintaining ftape, and I,
-Claus-Justus Heine <claus@momo.math.rwth-aachen.de>,
-have taken over.
-
-- Added support for tapes with `format code 6', i.e. QIC-3020 tapes
- with more than 2^16 segments.
-- merged changes made by Bas Laarhoven with ftape-2.09. Refer
- to his release notes below. I've included them into this
- file unchanged for your reference.
-- disabled call stack back trace for now. This new feature
- introduced by the interim release 2.0.x still seems to
- be buggy.
-- Tried to minimize differences between the ftape version
- to be included into the kernel source tree and the standalone
- module version.
-- Reintroduced support for Linux-1.2.13. Please refer to the
- Install-guide.
-
-===== Release notes for ftape-2.09, 16/06/96 =====
-
-There aren't any really big news in this release, mostly just that I
-(the maintainer) have changed my email address (due to a new job). My
-new address is <khp@dolphinics.no>
-
-- The CLK_48MHZ and FDC_82078SL options has gone (all 2Mbps cards seem
- to use a 48MHz oscillator anyway and I haven't heard of an 'SL
- chip out there).
-- The S82078B has been `downgraded' to i82077AA compability.
-- TESTING option revived. Right now, it'll enable the (seriously broken)
- 2Mbps code. If you enable it, you'll experience a tape drive that's
- *really* out to lunch!
-- Some (bold) changes in the init code. Please notify me if they
- break things for you.
-
-===== Release notes for ftape-2.08, 14/03/96 =====
-
-If you correct a problem with ftape, please send your patch to
-khp@dolphinics.no too.
-
-- Updated to reflect that NR_MEM_LISTS is gone in 1.3.74
-- Teac 700 added to list of known drives.
-- The registered device name is now "ft" rather than "ftape".
-
-===== Release notes for ftape-2.07a, 14/03/96 =====
-
-Bugfixes by Marcin Dalecki <dalecki@namu03.gwdg.de>:
-- In the last release it just compiled against 1.3.70;
- now the params to request_irq() and free_irq are() are fixed, so it also
- works in 1.3.73 :-)
-- Support for modules is now correct for newer kernels.
-
-===== Release notes for ftape-2.07, 04/03/96 =====
-
-
-- ftape updated to compile against 1.3.70.
-- Iomega 700 and Wangtek 3200 recognised.
-
-
-===== Release notes for ftape-2.06b, 13/02/96 =====
-
-Another simple bugfix version.
-
-- Jumbo 700 recognised.
-- Typo in vendors.h fixed.
-
-
-===== Release notes for ftape-2.06a, 10/02/96 =====
-
-This release is a simple bugfix version.
-
-- Linux/SMP: ftape *should* work.
-- FC-10/20: Only accepts IRQs 3-7, or 9. If IRQ 9, properly tell the card
- to use IRQ 2. Thanks to Greg Crider (gcrider@iclnet.org) for finding and
- locating this bug and testing the patch.
-- Insight drive recognised correctly again.
-- Motor-on wakeup version of the Iomega 250 drive added
-
-
-===== Release notes for ftape-2.06, 28/01/96 =====
-
-Special thanks go to Neal Friedman and Steven Sorbom for their
-help in producing and testing this release.
-
-I have continued to clean up the code, with an eye towards inclusion
-of ftape in Linus' official kernel (In fact, as I type this, I am
-running on a kernel with ftape support statically linked). I have
-test-compiled ftape against my 1.2.13 tree without problems.
-Hopefully, everything should be OK for the v1.2.x people.
-
-WARNING! Alan Cox has mailed me that ftape does *NOT* work with
-Linux/SMP. If you try to run ftape under Linux/SMP, it will cause a
-kernel deadlock (which is worse than a panic).
-
-- QIC-3020/TR-3: 1Mbps support works. Neal is capable of reading and
- writing data to a tape. ftape will automatically detect the type of
- tape (e.g. TR-3 vs QIC-80) and move the fdc in and out of
- "perpendicular mode" as necessary.
-- 2Mbps support is disabled by default, since it is not fully
- debugged. If you are adventurous, remove -DFDC_82078SL in the
- Makefile and see what happens :-)
-- fdc detection: silly bugs removed (Only 2Mbps fdcs were affected)
- and added detection of the National Semiconductors PC8744 fdc chip
- (used in the PC873xx "super-IO" chips).
-- Removed warning about incompatible types when compiling with Linux
- 1.2.x.
-- README.PCI updated with info about the DELL Dimension XPS P90.
-- Connor TST3200R added to detected drives.
-- `swapout' utility added to distribution. It will dirty 5Meg of
- memory, trying to swap out other programs. Just say `make swapout'
- to build it. ftape will do this automatically Real Soon Now (ie:
- when I have found out which kernel memory alloc function to call).
-
-
-===== Release notes for ftape-2.05, 08/01/96 =====
-
-- For v1.2.x Kernels, you must apply the patch linux-1.2/ksyms.patch to
- the kernel and rebuild it (it adds the __get_dma_pages symbol to
- ksyms.c).
-- Included new asm-i386/io.h file from v1.3.x kernel series, to enable
- gcc v.2.7.[12] to compile v1.2.x kernels (linux-1.2/io.h).
-- Module versions: If you wish to compile ftape as a versioned module,
- you must first compile your kernel with CONFIG_MODVERSIONS=y.
- Otherwise, you will get complaints that <linux/modversions.h> does not
- exist (if that happens, a `touch modversions.h' will help you out).
-- CLK_48MHZ: new define in the Makefile (default: non-zero). If you have
- a tape controller card that uses the i82078(-1) chip, but cannot get
- it to work with ftape, try set it to 0 (and please report this).
-- QIC-3010/3020: Complete support is still missing, but will hopefully
- come soon. Steven Sorbom has kindly provided me with hints about
- this. Writing of QIC-3020 tapes definitely does NOT work (do not try
- it! - the drive will not be in "perpendicular mode" and this will ruin
- the formatting info on the tape).
-- ftape_num_buffers is out of fashion: use NR_BUFFERS instead (and
- recompile if you want to change it :-).
-
-
-===== Release notes for ftape-2.04, 01/01/96 =====
-
-This version by Kai Harrekilde-Petersen <khp@dolphinics.no>
-
-- ALERT! Support for Kernels earlier then v1.1.85 is about to go away.
- I intend to clean up some of the code (getting rid of an annoyingly
- large numbers of #ifdef mostly), which means that support for
- pre-1.1.85 kernels must go as well.
-- NR_FTAPE_BUFFERS is gone; You can instead select the number of dma
- buffers by saying `insmod ftape.o ftape_num_buffer=<n>' instead.
-- Configure script gone. ftape will now automagically determine your
- kernel version by /usr/include/linux/version.h instead.
-- CONFIG_MODVERSIONS now work. All combinations of versioned /
- unversioned kernel and ftape module works (at least with my 1.3.52
- kernel).
-- If you have problems with inserting ftape into an old (1.2.x)
- kernel (e.g. insmod says "1.2.8 does not match 1.2.8), recompile
- your modules utilities with your new compiler.
-- Reveal TB1400 drive added to vendors.h
-- Support for the i82078-1 (2Mbps) chip is coming along. The
- biggest problem is that I don't have such a card, which makes
- testing / debugging somewhat problematic. The second biggest
- problem is that I do not have the QIC-3010/3020 standards either.
- Status right now is that the chip is detected, and it should be
- possible to put it into 2Mbps mode. However, I do not know what
- "extras" are needed to complete the support. Although putting the
- i82078 into 1Mbps mode ought to work out of the box, it doesn't
- (right now, ftape complains about id am errors).
-
-
-===== Release notes for ftape-2.04beta5, 29/12/95 =====
-
-Bas offline linux-tape
-----------------------
-For reasons only known to the majordomo mail list processor, Bas was
-kicked off the linux-tape list sometime during the summer. Being
-overworked at his for-pay job, he didn't notice it much. Instead I
-(Kai, khp@dolphinics.no) has worked on ftape to produce the 2.04(beta)
-version.
-
-zftape
-------
-Note that there exists a much improved version of ftape, written by
-Claus-Justus Heine <claus@willi.math.rwth-aachen.de> which is named
-zftape, which conforms to the QIC-80 specs on how to mark backups, and
-is capable of doing automatic compression. However, zftape makes
-substantial changes to ftape, and I (Kai) have therefore declined to
-integrate zftape into ftape. Hopefully, this will happen soon.
-
-CONFIG_QIC117 removed from the kernel
--------------------------------------
-The biggest change of all is that ftape now will allocate its dma
-buffers when it is inserted. The means that the CONFIG_QIC117 option
-has disappeared from the Linux kernel as of v1.3.34. If you have an
-earlier kernel, simply answer 'no' to the question will do the trick
-(if you get complains about __get_free_pages() missing, contact the
-linux-tape mailing list).
-
-Note that ftape-2.04beta will work equally well on kernels with and
-without `ftape support'. The only catch is, that you will waste
-around 96-128Kb of precious DMA'able memory on a box that has ftape
-support compiled in.
-
-Now for the real changes:
-
-- FC-20 can now use DMA channels 1, 2, and 3. Thanks to Daniel
- Cohen, catman@wpi.edu.
-- ftape no longer requires a (gigantic) 96Kb buffer to be statically
- allocated by the kernel.
-- Added new Iomega drive (8882) to vendors.h
-- -fno-strength-reduce added to Makefile, since GCC is broken.
-- i82078-1 (2Mbps) FDC support started.
-
-
-===== Release notes for ftape-2.03b, 27/05/95 =====
-
-- Prevented verify_area to return error if called with zero length.
-- Fixed a bug in flush_buffers that caused too much padding to be
- written when a final segment had bad sectors.
-- Increased maximum fast-seek overshoot value from 5 to 10 segments.
-- Breaking loop after 5 retries when positioning fails.
-- Fixed wrong calculation of tape length for QIC-3010 and QIC-3020
- tapes (densities were swapped).
-- Fixed wrong calculation of overshoot on seek_forward: Wrong sign
- of error.
-- Suppress (false) error message due to new tape loaded.
-- Added two new CMS drives (11c3 and 11c5) to vendors.h.
-
-
-===== Release notes for ftape-2.03a, 09/05/95 =====
-
-- Fixed display of old error (even if already cleared) in ftape_open.
-- Improved tape length detection, ioctls would fail for 425 ft tapes.
- Until the tape length is calculated with data from the header
- segment, we'll use worst-case values.
-- Clear eof_mark after rewinding ioctls.
-- Fixed wrong version message (2.03 had 2.02g id).
-- Fixed bug that caused the fdc to be reset very frequently.
- This shouldn't affect normal operation but the timing of the
- report routines has changed again and that may cause problems.
- We'll just have to find out....
-- Implemented correct write precompensation setting for QIC-3010/3020.
-- Cleaned up fdc_interrupt_wait routine. Hope it still works :-)
-- Finally removed (already disabled) special eof mark handling for
- gnu tar.
-- Changed order of get_dma_residue and disable_dma in fdc-isr.c
- because the current order would fail on at least one system.
- We're back to the original order again, hope (and expect) this
- doesn't break any other system.
-
-
-===== Release notes for ftape-2.03, 07/05/95 =====
-
-(Changes refer to the first ftape-2.02 release)
-
-Support for wide and extended length tapes
-------------------------------------------
-The Conner TSM 420 and 850 drives are reported to be working.
-I haven't received any reports about other brands; the TSM 420
-and 850 seem to be the most widely used wide drives.
-Extended length tapes (425 ft) with normal QIC-80 drives
-are operating too (At least I've had no reports stating otherwise).
-_Not_ yet completely supported (although they may work) are
-QIC-3020 drives and 2 Mbps floppy disk controllers won't work at
-the highest speed.
-If someone is kind enough to send me one of these, I'll include
-support for it too ;-)
-
-Easier configuration
---------------------
-Problems due to wrong settings in the Makefile are prevented
-by using a configuration script that sets the necessary (kernel
-version dependent) compile time options.
-This kernel version is now determined from the sources found
-at /usr/src/linux, or if not found, the old way using
-/proc/version.
-Versioned modules will be used automatically when supported
-by- and configured in- the kernel.
-Note that the current modules code (1.1.87) is still broken
-and _needs_ the fix included in the insmod directory.
-Please don't send me any more Oops reports caused by insmod :-(
-
-Reduced module size
--------------------
-The standard module size is much reduced and some compile time
-options can even reduce it further. (I don't recommend this
-for normal use but it can be handy for rescue diskettes)
-
-Option: Approx. module size:
-
-<standard> 150 Kb
-NO_TRACE 125 Kb
-NO_TRACE_AT_ALL 67 Kb
-
-
-Much improved driver interruption
----------------------------------
-Most possible loops have been broken and signal detection
-has been improved.
-In most cases the driver can be aborted by ^C (SIGINT) and
-SIGKILL (kill -9) will generate be a sure kill.
-(Note that aborting a tape operation may damage the last
-data written to tape)
-
-Improved error recovery
------------------------
-Ftape now returns an error (ENODATA) to the application if
-a segment proves to be unrecoverable and then skips the
-bad segment.
-This causes most applications to continue to work (tar
-and afio) loosing only a small amount (up to 29 Kb) of data.
-Retried read operations will now be done slightly off-track
-to improve the chance of success. Serious head off-track
-errors will be detected.
-
-FC-10 and FC-20 controllers
----------------------------
-Ftape now supports both the old CMS FC-10 and the newer FC-20
-controllers.
-Because the operation of these cards is still undocumented,
-thus far they will only work with the default settings (See
-Makefile). Any feed-back on how to use them with other settings
-will be welcome !
-Compilation will fail if one changes the settings to illegal
-values.
-
-Kernels and compilers
----------------------
-Ftape is currently being developed using the 2.5.8 compiler.
-The older 2.4.5 probably works too (Set option in Makefile!).
-I have no experience with any later compilers nor Elf support.
-Any information on this is welcome.
-The latest kernel I have tested ftape with is 1.2.6.
-
-Compression
------------
-An impressive collection of changes for ftape including
-on-the-fly compression is still lying on my desk.
-If 2.03 proves to be reliable I might start integrating these
-but as usual, I'm short in time :-(
-
-Formatting
-----------
-There is still no way to format tapes under Linux. As far as
-I know all attempts to write such a program have died now.
-Since formatted tapes are rather common now, I think all we
-need is a utility that writes a worst case pattern and verifies
-that with the drive put in verify mode, reducing margins.
-Any takers ?
-
-Furthermore
------------
-Cleaned up messages.
-Prepared to support multiple tape drives on one fdc.
-Thanks to all the people who sent bug reports and helped me
-improve the driver. Without trying to be complete I'll mention
-Gary Anderson (without his accurate reports and unreliable
-hardware there wouldn't be a 2.03), Stefan Kneifel (FC-20),
-Robert Broughton (FC-20, you were almost there ;-), Bjorn
-Ekwall (for the versioned modules and buggy insmod ;-), Peter
-Fox, Christopher Oliver, Ralph Whittaker and not the least
-Linus Torvalds (for Linux and keeping me busy because of
-changes to the kernel ;-)
-Thanks to anyone I forgot, for the bug reports, the ftape
-bashing and the mental support...
-
-
-That's it for now. Have Fun,
-
-Bas.
-
-
-===== Release notes for ftape-2.02g, 06/05/95 =====
-
-- Added extra test to break read-id loop with signal.
-- Changed rewind code to handle negative overshoot for drives
- that take very long to start or stop.
-- Let use of get/set i/o-regions depend on kernel version.
-- Changed code to use a more general test for conditional
- compilations depending on kernel version.
-- Improved micro-step functionality to go off-track only
- while reading (id & data).
-- Added failure on tape-not-referenced bit in ftape_command.
-- Added FOREVER option to read-wait routine.
-- Changed read-id to use shorter timeout causing smaller
- rewinds on timeout.
-- Made kernel-interface functions static.
-
-
-===== Release notes for ftape-2.02f, 03/05/95 =====
-
-- Added support for dual tape drives on my system, extended Configure
- script to detect host 'dodo'.
-- Log media defect in history if ecc failed and no data was returned.
-- Fixed Configure script that was failing for kernel versions with
- double digit version or revision numbers.
-
-
-===== Release notes for ftape-2.02e, 01/05/95 =====
-
-- Fixed reposition loop at logical eot (failing read_id).
-- Fixed 34 segment offset when rewinding.
-- Added fast seek capability for more than 255 segments.
-- Fixed wrong busy result from ftape_command causing reverse
- seek to fail.
-- Added breakout from infinite rewind loop (if something fails).
-
-
-===== Release notes for ftape-2.02d, 30/04/95 =====
-
-- Improved abortion on signals: Interrupt will make a graceful
- exit, Kill will be less nice and should be used if everything
- else fails.
-- Included check for tape-head off track.
-- Implemented exit from tape-start loop.
-- Added kernel io-port registration.
-- Implemented skip of failing segment (ENODATA) on ecc failure.
- This allows afio and tar to continue when the tape is damaged.
-- Made distinction between drive names with different codes.
-
-
-===== Release notes for ftape-2.02c, 22/04/95 =====
-
-- Fixed too tight command queueing after tape stop/pause command
- issued from within interrupt service routine (Showed as timeout
- on Acknowledge errors during retries on some systems)
-- Tried to fix timeouts when using 425 ft tape because the extended
- length doesn't seem to be detected by the hardware.
- We now use the format code from the header segment so adjust the
- timing after reading the header segment.
-- Fixed some messages stating 'unexpected something...' being not
- unexpected anymore.
-- Started preparations for merge of dynamic buffer allocation and
- compression code.
-- Changed some debug messages to include relevant segment information
- at level 4.
-- Included early bail-out when drive offline, preventing a lot of
- false messages.
-- Moved ftape_parameter_xxx() offsets into function instead of in calls.
-- Removed 'weird, drive busy but no data' error when caused by
- an error during a read-id.
-- Improved 'timeout on acknowledge' diagnostics.
-- Moved MODULE option into Configure.
-- Reduced code size when no tracing at all was set (Claus Heine).
-- No longer log error code 0 (no error) as an error.
-
-
-===== Release notes for ftape-2.02b, 09/04/95 =====
-
-- Relaxed timing for status operation and displaying
- abnormal results. Hopefully this shows what's going
- wrong with the Conner TSM850R drives.
-- Created script for configuration, using version number
- of kernel source if available, otherwise /proc/version.
-- Fixed conditionals in kernel-interface.c.
-- Removed unavoidable TRACE output.
-
-
-===== Release notes for ftape-2.02a, 01/04/95 =====
-
-- Implemented `new-style' (versioned) modules support for new
- kernels.
-- Reduced size of module by moving static data to bss.
-- Now using version number of kernel source instead of running
- kernel for kernel versions >= 1.1.82
-- Added feedback on drive speeds to vendor information.
-- Included fixed insmod sources to distribution (Let's hope
- the modules distribution get fixed soon :-/).
-
-Note that I haven't yet implemented any of the code extension I
-received. I hope to find some time to do this soon.
-
-
-===== Release notes for ftape-2.02, 15/01/95 =====
-
-
-- Fixed failing repositioning when overshoot was incremented.
-- Fixed rate selection: Because of a deficiency in the QIC-117
- specification one cannot distinguish between a not implemented
- and a failing command. Therefor we now try to find out if the
- drive does support this command before usage.
-- Fixed error retry using wrong offset in fdc-isr.
-- Improved retry code to retry only once on a single no-data
- error in a segment.
-- Validate sector number extracted from eof mark because an
- invalid file mark (due to ???) could cause kernel panic.
-- Split ftape-io.c into ftape-io.c and ftape-ctl.c files.
-- Corrected too high media error count after writing to
- a bad tape.
-- Added #include <asm/segment.h> again because old kernel versions
- need it.
-- Fixed fdc not being disabled when open failed because no tape
- drive was found.
-- Fixed problem with soft error in sector 32 (shift operator with
- shiftcount 32 is not defined).
-
-
-===== Release notes for ftape-2.01, 08/01/95 =====
-
-
-- Removed TESTING setting from distributed Makefile.
-- Fixed `mt asf' failure: Rewind was deferred to close which
- overruled the fsf ioctl.
-- Prevented non-interruptible commands being interrupted.
-- Added missing timeout.pause setting.
-- Maximum tape speed read from drive type information table.
- If the information is not in the table (0) the drive will
- determine the speed itself and put a message in the logfile.
- This information should then be added to the table in the
- vendors.h file (and reported to me).
-- Added call to ftape_init_drive after soft reset for those
- (antique) drives that don't do an implicit seek_load_point
- after a reset or power up.
-- Don't try to set data rate if reset failed.
-- Prevent update of seek variables when starting from the
- beginning or the end of the tape.
-- Fixed wrong adjustment of overshoot in seek_forward().
-- Added sync to Makefile (again).
-- Added code to diagnose timer problems (calibr.c).
-- Replaced time differences by timediff calls.
-- Removed reference to do_floppy from object for recent kernels.
-- Fixed wrong display of 'failing dma controller' message.
-- Removed various no longer used #include statements.
-- Added max. tape speed value to vendor-struct.
-- Changed ftape-command to check pre-conditions and wait
- if needed.
-- Further updated qic117.h to rev G.
-- Combined command name table and restrictions table to one.
- Extended this table with some new fields.
-- Increased timeout on Ack timer value and included code to
- report out of spec behaviour.
-- Increased rewind timeout margin to calculated + 20%.
-- Improved data rate selection so it won't fail on some
- older (pre standard) drives.
-- Changed initialisation code so drive will be rewound if the
- driver is reloaded and the tape is not at bot.
-- Moved some of the flush operations from close to the ioctls.
-- Added exit code value to failing verify area message.
-- Loop until tape halted in smart-stop.
-- Fast seek handled specially if located at bot or eot.
-- Being more conservative on overshoot value.
-
-
-===== Release notes for ftape-2.00, 31/12/94 =====
-
- The Install-guide is completely rewritten and now also includes
-some information on how to use the driver. If you're either new
-to ftape or new to Unix tape devices make sure to read it !
-
- If you own a pci system and experience problems with the
-ftape driver make sure to read the README.PCI file. It contains
-some hints on how to fix your hardware.
-
- For anybody who hasn't noticed: The version number of the
-driver has been incremented (The latest released version has
-been version 1.14d).
- This has been done for two major reasons:
-
- o A new (better) error recovery scheme is implemented.
- o Support for new drive types has been added.
-
- All these improvements/changes will probably include a couple
-of new (and old?) bugs. If you encounter any problems that you think
-I'm not yet aware of, feel free to send a report to <bas@vimec.nl>.
- I recommend keeping a version of ftape-1.14d available, just
-in case ;-)
-
- This version should work with all kernel versions from 1.0.9 up
-to 1.1.72 (and probably earlier and later versions too).
-
-
-Major new features:
-
-- Better handling of tapes with defects: When a sector repeatedly
- (SOFT_RETRIES in ftape.h) cannot be written to or read from it is
- marked as an hard error and gets skipped.
- The error correction code can handle up to three of these hard
- errors provided there are no other errors in that segment (32 Kb).
-
-- Allows writing to tapes with defects (although the risk of loosing
- data increases !)
- Look for the media-defects entry printed with the statistics when
- the tape is closed. A non-zero value here shows a bad tape.
- [the actual count is wrong (too high), this is a known bug].
-
-- Use of backup header segment if first one is failing.
-
-- Support for extended length tapes with QIC-80: both 425 and 1100 ft.
- 0.25 inch tapes are now recognized and handled.
-
-- Support for new QIC-80 drives with 8 mm `wide' tapes (e.g. Conner
- TSM 420).
-
-- Support for new QIC-3010 and QIC-3020 drives (experimental) with
- both 0.25 inch and 8 mm tapes.
-
-Some minor features were added, a couple of small bugs were fixed and
-probably some new ones introduced ;-).
-
-[lseek() didn't make it into this version]
-
-Have fun,
-
-Bas.
-----
- LocalWords: ftape MCONFIG mt VFS zftape resp sftape proc subdir MTIOCVOLINFO
- LocalWords: MTIOCGETSIZE BOT EOD MTBSF zft kerneld modprobe kdtime contrib TR
- LocalWords: MTSETBLK afio uninstall texi www EIO QIC init sft eof aka dma GB
- LocalWords: SIGKILL MTIOCFTCMD mmap Iomega FDC fdc io gnumt mtio fc asm inb
- LocalWords: outb ft qic frontend TeXinfo irq mach MODVERSIONS CONFIG html dvi
- LocalWords: usr doc SMP Mb Dunno FIXME vtblc perl listtape volinfo fsf MTWEOF
- LocalWords: amanda degaussed ComByte DoublePlay whraven njackn com MTIOC vtbl
- LocalWords: GETBLKSZ MAKEDEV zftape's linux dif CVS Revison cp MTREW MTOFFL
- LocalWords: MTFSF BSF Marcin Dalecki GCC Config cpio swapout Kai Harrekilde
- LocalWords: Pederson khp dolphinics Justus claus momo rwth aachen Laarhoven
diff --git a/drivers/char/ftape/compressor/Makefile b/drivers/char/ftape/compressor/Makefile
deleted file mode 100644
index 1fbd6c4019db..000000000000
--- a/drivers/char/ftape/compressor/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 1997 Claus-Justus Heine.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/compressor/Makefile,v $
-# $Revision: 1.1 $
-# $Date: 1997/10/05 19:12:28 $
-#
-# Makefile for the optional compressor for th zftape VFS
-# interface to the QIC-40/80/3010/3020 floppy-tape driver for
-# Linux.
-#
-
-obj-$(CONFIG_ZFT_COMPRESSOR) += zft-compressor.o
-
-zft-compressor-objs := zftape-compress.o lzrw3.o
-
-CFLAGS_lzrw3.o := -O6 -funroll-all-loops
diff --git a/drivers/char/ftape/compressor/lzrw3.c b/drivers/char/ftape/compressor/lzrw3.c
deleted file mode 100644
index a032a0ee2a99..000000000000
--- a/drivers/char/ftape/compressor/lzrw3.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.c,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:29 $
- *
- * Implementation of Ross Williams lzrw3 algorithm. Adaption for zftape.
- *
- */
-
-#include "../compressor/lzrw3.h" /* Defines single exported function "compress". */
-
-/******************************************************************************/
-/* */
-/* LZRW3.C */
-/* */
-/******************************************************************************/
-/* */
-/* Author : Ross Williams. */
-/* Date : 30-Jun-1991. */
-/* Release : 1. */
-/* */
-/******************************************************************************/
-/* */
-/* This file contains an implementation of the LZRW3 data compression */
-/* algorithm in C. */
-/* */
-/* The algorithm is a general purpose compression algorithm that runs fast */
-/* and gives reasonable compression. The algorithm is a member of the Lempel */
-/* Ziv family of algorithms and bases its compression on the presence in the */
-/* data of repeated substrings. */
-/* */
-/* This algorithm is unpatented and the code is public domain. As the */
-/* algorithm is based on the LZ77 class of algorithms, it is unlikely to be */
-/* the subject of a patent challenge. */
-/* */
-/* Unlike the LZRW1 and LZRW1-A algorithms, the LZRW3 algorithm is */
-/* deterministic and is guaranteed to yield the same compressed */
-/* representation for a given file each time it is run. */
-/* */
-/* The LZRW3 algorithm was originally designed and implemented */
-/* by Ross Williams on 31-Dec-1990. */
-/* */
-/* Here are the results of applying this code, compiled under THINK C 4.0 */
-/* and running on a Mac-SE (8MHz 68000), to the standard calgary corpus. */
-/* */
-/* +----------------------------------------------------------------+ */
-/* | DATA COMPRESSION TEST | */
-/* | ===================== | */
-/* | Time of run : Sun 30-Jun-1991 09:31PM | */
-/* | Timing accuracy : One part in 100 | */
-/* | Context length : 262144 bytes (= 256.0000K) | */
-/* | Test suite : Calgary Corpus Suite | */
-/* | Files in suite : 14 | */
-/* | Algorithm : LZRW3 | */
-/* | Note: All averages are calculated from the un-rounded values. | */
-/* +----------------------------------------------------------------+ */
-/* | File Name Length CxB ComLen %Remn Bits Com K/s Dec K/s | */
-/* | ---------- ------ --- ------ ----- ---- ------- ------- | */
-/* | rpus:Bib.D 111261 1 55033 49.5 3.96 19.46 32.27 | */
-/* | us:Book1.D 768771 3 467962 60.9 4.87 17.03 31.07 | */
-/* | us:Book2.D 610856 3 317102 51.9 4.15 19.39 34.15 | */
-/* | rpus:Geo.D 102400 1 82424 80.5 6.44 11.65 18.18 | */
-/* | pus:News.D 377109 2 205670 54.5 4.36 17.14 27.47 | */
-/* | pus:Obj1.D 21504 1 13027 60.6 4.85 13.40 18.95 | */
-/* | pus:Obj2.D 246814 1 116286 47.1 3.77 19.31 30.10 | */
-/* | s:Paper1.D 53161 1 27522 51.8 4.14 18.60 31.15 | */
-/* | s:Paper2.D 82199 1 45160 54.9 4.40 18.45 32.84 | */
-/* | rpus:Pic.D 513216 2 122388 23.8 1.91 35.29 51.05 | */
-/* | us:Progc.D 39611 1 19669 49.7 3.97 18.87 30.64 | */
-/* | us:Progl.D 71646 1 28247 39.4 3.15 24.34 40.66 | */
-/* | us:Progp.D 49379 1 19377 39.2 3.14 23.91 39.23 | */
-/* | us:Trans.D 93695 1 33481 35.7 2.86 25.48 40.37 | */
-/* +----------------------------------------------------------------+ */
-/* | Average 224401 1 110953 50.0 4.00 20.17 32.72 | */
-/* +----------------------------------------------------------------+ */
-/* */
-/******************************************************************************/
-
-/******************************************************************************/
-
-/* The following structure is returned by the "compress" function below when */
-/* the user asks the function to return identifying information. */
-/* The most important field in the record is the working memory field which */
-/* tells the calling program how much working memory should be passed to */
-/* "compress" when it is called to perform a compression or decompression. */
-/* LZRW3 uses the same amount of memory during compression and decompression. */
-/* For more information on this structure see "compress.h". */
-
-#define U(X) ((ULONG) X)
-#define SIZE_P_BYTE (U(sizeof(UBYTE *)))
-#define SIZE_WORD (U(sizeof(UWORD )))
-#define ALIGNMENT_FUDGE (U(16))
-#define MEM_REQ ( U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE )
-
-static struct compress_identity identity =
-{
- U(0x032DDEA8), /* Algorithm identification number. */
- MEM_REQ, /* Working memory (bytes) required. */
- "LZRW3", /* Name of algorithm. */
- "1.0", /* Version number of algorithm. */
- "31-Dec-1990", /* Date of algorithm. */
- "Public Domain", /* Copyright notice. */
- "Ross N. Williams", /* Author of algorithm. */
- "Renaissance Software", /* Affiliation of author. */
- "Public Domain" /* Vendor of algorithm. */
-};
-
-LOCAL void compress_compress (UBYTE *,UBYTE *,ULONG,UBYTE *, LONG *);
-LOCAL void compress_decompress(UBYTE *,UBYTE *,LONG, UBYTE *, ULONG *);
-
-/******************************************************************************/
-
-/* This function is the only function exported by this module. */
-/* Depending on its first parameter, the function can be requested to */
-/* compress a block of memory, decompress a block of memory, or to identify */
-/* itself. For more information, see the specification file "compress.h". */
-
-EXPORT void lzrw3_compress(
- UWORD action, /* Action to be performed. */
- UBYTE *wrk_mem, /* Address of working memory we can use.*/
- UBYTE *src_adr, /* Address of input data. */
- LONG src_len, /* Length of input data. */
- UBYTE *dst_adr, /* Address to put output data. */
- void *p_dst_len /* Address of longword for length of output data.*/
-)
-{
- switch (action)
- {
- case COMPRESS_ACTION_IDENTITY:
- *((struct compress_identity **)p_dst_len)= &identity;
- break;
- case COMPRESS_ACTION_COMPRESS:
- compress_compress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len);
- break;
- case COMPRESS_ACTION_DECOMPRESS:
- compress_decompress(wrk_mem,src_adr,src_len,dst_adr,(LONG *)p_dst_len);
- break;
- }
-}
-
-/******************************************************************************/
-/* */
-/* BRIEF DESCRIPTION OF THE LZRW3 ALGORITHM */
-/* ======================================== */
-/* The LZRW3 algorithm is identical to the LZRW1-A algorithm except that */
-/* instead of transmitting history offsets, it transmits hash table indexes. */
-/* In order to decode the indexes, the decompressor must maintain an */
-/* identical hash table. Copy items are straightforward:when the decompressor */
-/* receives a copy item, it simply looks up the hash table to translate the */
-/* index into a pointer into the data already decompressed. To update the */
-/* hash table, it replaces the same table entry with a pointer to the start */
-/* of the newly decoded phrase. The tricky part is with literal items, for at */
-/* the time that the decompressor receives a literal item the decompressor */
-/* does not have the three bytes in the Ziv (that the compressor has) to */
-/* perform the three-byte hash. To solve this problem, in LZRW3, both the */
-/* compressor and decompressor are wired up so that they "buffer" these */
-/* literals and update their hash tables only when three bytes are available. */
-/* This makes the maximum buffering 2 bytes. */
-/* */
-/* Replacement of offsets by hash table indexes yields a few percent extra */
-/* compression at the cost of some speed. LZRW3 is slower than LZRW1, LZRW1-A */
-/* and LZRW2, but yields better compression. */
-/* */
-/* Extra compression could be obtained by using a hash table of depth two. */
-/* However, increasing the depth above one incurs a significant decrease in */
-/* compression speed which was not considered worthwhile. Another reason for */
-/* keeping the depth down to one was to allow easy comparison with the */
-/* LZRW1-A and LZRW2 algorithms so as to demonstrate the exact effect of the */
-/* use of direct hash indexes. */
-/* */
-/* +---+ */
-/* |___|4095 */
-/* |___| */
-/* +---------------------*_|<---+ /----+---\ */
-/* | |___| +---|Hash | */
-/* | |___| |Function| */
-/* | |___| \--------/ */
-/* | |___|0 ^ */
-/* | +---+ | */
-/* | Hash +-----+ */
-/* | Table | */
-/* | --- */
-/* v ^^^ */
-/* +-------------------------------------|----------------+ */
-/* |||||||||||||||||||||||||||||||||||||||||||||||||||||||| */
-/* +-------------------------------------|----------------+ */
-/* | |1......18| | */
-/* |<------- Lempel=History ------------>|<--Ziv-->| | */
-/* | (=bytes already processed) |<-Still to go-->| */
-/* |<-------------------- INPUT BLOCK ------------------->| */
-/* */
-/* The diagram above for LZRW3 looks almost identical to the diagram for */
-/* LZRW1. The difference is that in LZRW3, the compressor transmits hash */
-/* table indices instead of Lempel offsets. For this to work, the */
-/* decompressor must maintain a hash table as well as the compressor and both */
-/* compressor and decompressor must "buffer" literals, as the decompressor */
-/* cannot hash phrases commencing with a literal until another two bytes have */
-/* arrived. */
-/* */
-/* LZRW3 Algorithm Execution Summary */
-/* --------------------------------- */
-/* 1. Hash the first three bytes of the Ziv to yield a hash table index h. */
-/* 2. Look up the hash table yielding history pointer p. */
-/* 3. Match where p points with the Ziv. If there is a match of three or */
-/* more bytes, code those bytes (in the Ziv) as a copy item, otherwise */
-/* code the next byte in the Ziv as a literal item. */
-/* 4. Update the hash table as possible subject to the constraint that only */
-/* phrases commencing three bytes back from the Ziv can be hashed and */
-/* entered into the hash table. (This enables the decompressor to keep */
-/* pace). See the description and code for more details. */
-/* */
-/******************************************************************************/
-/* */
-/* DEFINITION OF COMPRESSED FILE FORMAT */
-/* ==================================== */
-/* * A compressed file consists of a COPY FLAG followed by a REMAINDER. */
-/* * The copy flag CF uses up four bytes with the first byte being the */
-/* least significant. */
-/* * If CF=1, then the compressed file represents the remainder of the file */
-/* exactly. Otherwise CF=0 and the remainder of the file consists of zero */
-/* or more GROUPS, each of which represents one or more bytes. */
-/* * Each group consists of two bytes of CONTROL information followed by */
-/* sixteen ITEMs except for the last group which can contain from one */
-/* to sixteen items. */
-/* * An item can be either a LITERAL item or a COPY item. */
-/* * Each item corresponds to a bit in the control bytes. */
-/* * The first control byte corresponds to the first 8 items in the group */
-/* with bit 0 corresponding to the first item in the group and bit 7 to */
-/* the eighth item in the group. */
-/* * The second control byte corresponds to the second 8 items in the group */
-/* with bit 0 corresponding to the ninth item in the group and bit 7 to */
-/* the sixteenth item in the group. */
-/* * A zero bit in a control word means that the corresponding item is a */
-/* literal item. A one bit corresponds to a copy item. */
-/* * A literal item consists of a single byte which represents itself. */
-/* * A copy item consists of two bytes that represent from 3 to 18 bytes. */
-/* * The first byte in a copy item will be denoted C1. */
-/* * The second byte in a copy item will be denoted C2. */
-/* * Bits will be selected using square brackets. */
-/* For example: C1[0..3] is the low nibble of the first control byte. */
-/* of copy item C1. */
-/* * The LENGTH of a copy item is defined to be C1[0..3]+3 which is a number */
-/* in the range [3,18]. */
-/* * The INDEX of a copy item is defined to be C1[4..7]*256+C2[0..8] which */
-/* is a number in the range [0,4095]. */
-/* * A copy item represents the sequence of bytes */
-/* text[POS-OFFSET..POS-OFFSET+LENGTH-1] where */
-/* text is the entire text of the uncompressed string. */
-/* POS is the index in the text of the character following the */
-/* string represented by all the items preceeding the item */
-/* being defined. */
-/* OFFSET is obtained from INDEX by looking up the hash table. */
-/* */
-/******************************************************************************/
-
-/* The following #define defines the length of the copy flag that appears at */
-/* the start of the compressed file. The value of four bytes was chosen */
-/* because the fast_copy routine on my Macintosh runs faster if the source */
-/* and destination blocks are relatively longword aligned. */
-/* The actual flag data appears in the first byte. The rest are zeroed so as */
-/* to normalize the compressed representation (i.e. not non-deterministic). */
-#define FLAG_BYTES 4
-
-/* The following #defines define the meaning of the values of the copy */
-/* flag at the start of the compressed file. */
-#define FLAG_COMPRESS 0 /* Signals that output was result of compression. */
-#define FLAG_COPY 1 /* Signals that output was simply copied over. */
-
-/* The 68000 microprocessor (on which this algorithm was originally developed */
-/* is fussy about non-aligned arrays of words. To avoid these problems the */
-/* following macro can be used to "waste" from 0 to 3 bytes so as to align */
-/* the argument pointer. */
-#define ULONG_ALIGN_UP(X) ((((ULONG)X)+sizeof(ULONG)-1)&~(sizeof(ULONG)-1))
-
-
-/* The following constant defines the maximum length of an uncompressed item. */
-/* This definition must not be changed; its value is hardwired into the code. */
-/* The longest number of bytes that can be spanned by a single item is 18 */
-/* for the longest copy item. */
-#define MAX_RAW_ITEM (18)
-
-/* The following constant defines the maximum length of an uncompressed group.*/
-/* This definition must not be changed; its value is hardwired into the code. */
-/* A group contains at most 16 items which explains this definition. */
-#define MAX_RAW_GROUP (16*MAX_RAW_ITEM)
-
-/* The following constant defines the maximum length of a compressed group. */
-/* This definition must not be changed; its value is hardwired into the code. */
-/* A compressed group consists of two control bytes followed by up to 16 */
-/* compressed items each of which can have a maximum length of two bytes. */
-#define MAX_CMP_GROUP (2+16*2)
-
-/* The following constant defines the number of entries in the hash table. */
-/* This definition must not be changed; its value is hardwired into the code. */
-#define HASH_TABLE_LENGTH (4096)
-
-/* LZRW3, unlike LZRW1(-A), must initialize its hash table so as to enable */
-/* the compressor and decompressor to stay in step maintaining identical hash */
-/* tables. In an early version of the algorithm, the tables were simply */
-/* initialized to zero and a check for zero was included just before the */
-/* matching code. However, this test costs time. A better solution is to */
-/* initialize all the entries in the hash table to point to a constant */
-/* string. The decompressor does the same. This solution requires no extra */
-/* test. The contents of the string do not matter so long as the string is */
-/* the same for the compressor and decompressor and contains at least */
-/* MAX_RAW_ITEM bytes. I chose consecutive decimal digits because they do not */
-/* have white space problems (e.g. there is no chance that the compiler will */
-/* replace more than one space by a TAB) and because they make the length of */
-/* the string obvious by inspection. */
-#define START_STRING_18 ((UBYTE *) "123456789012345678")
-
-/* In this algorithm, hash values have to be calculated at more than one */
-/* point. The following macro neatens the code up for this. */
-#define HASH(PTR) \
- (((40543*(((*(PTR))<<8)^((*((PTR)+1))<<4)^(*((PTR)+2))))>>4) & 0xFFF)
-
-/******************************************************************************/
-
-/* Input : Hand over the required amount of working memory in p_wrk_mem. */
-/* Input : Specify input block using p_src_first and src_len. */
-/* Input : Point p_dst_first to the start of the output zone (OZ). */
-/* Input : Point p_dst_len to a ULONG to receive the output length. */
-/* Input : Input block and output zone must not overlap. */
-/* Output : Length of output block written to *p_dst_len. */
-/* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. May */
-/* Output : write in OZ=Mem[p_dst_first..p_dst_first+src_len+MAX_CMP_GROUP-1].*/
-/* Output : Upon completion guaranteed *p_dst_len<=src_len+FLAG_BYTES. */
-LOCAL void compress_compress(UBYTE *p_wrk_mem,
- UBYTE *p_src_first, ULONG src_len,
- UBYTE *p_dst_first, LONG *p_dst_len)
-{
- /* p_src and p_dst step through the source and destination blocks. */
- register UBYTE *p_src = p_src_first;
- register UBYTE *p_dst = p_dst_first;
-
- /* The following variables are never modified and are used in the */
- /* calculations that determine when the main loop terminates. */
- UBYTE *p_src_post = p_src_first+src_len;
- UBYTE *p_dst_post = p_dst_first+src_len;
- UBYTE *p_src_max1 = p_src_first+src_len-MAX_RAW_ITEM;
- UBYTE *p_src_max16 = p_src_first+src_len-MAX_RAW_ITEM*16;
-
- /* The variables 'p_control' and 'control' are used to buffer control bits. */
- /* Before each group is processed, the next two bytes of the output block */
- /* are set aside for the control word for the group about to be processed. */
- /* 'p_control' is set to point to the first byte of that word. Meanwhile, */
- /* 'control' buffers the control bits being generated during the processing */
- /* of the group. Instead of having a counter to keep track of how many items */
- /* have been processed (=the number of bits in the control word), at the */
- /* start of each group, the top word of 'control' is filled with 1 bits. */
- /* As 'control' is shifted for each item, the 1 bits in the top word are */
- /* absorbed or destroyed. When they all run out (i.e. when the top word is */
- /* all zero bits, we know that we are at the end of a group. */
-# define TOPWORD 0xFFFF0000
- UBYTE *p_control;
- register ULONG control=TOPWORD;
-
- /* THe variable 'hash' always points to the first element of the hash table. */
- UBYTE **hash= (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem);
-
- /* The following two variables represent the literal buffer. p_h1 points to */
- /* the hash table entry corresponding to the youngest literal. p_h2 points */
- /* to the hash table entry corresponding to the second youngest literal. */
- /* Note: p_h1=0=>p_h2=0 because zero values denote absence of a pending */
- /* literal. The variables are initialized to zero meaning an empty "buffer". */
- UBYTE **p_h1=NULL;
- UBYTE **p_h2=NULL;
-
- /* To start, we write the flag bytes. Being optimistic, we set the flag to */
- /* FLAG_COMPRESS. The remaining flag bytes are zeroed so as to keep the */
- /* algorithm deterministic. */
- *p_dst++=FLAG_COMPRESS;
- {UWORD i; for (i=2;i<=FLAG_BYTES;i++) *p_dst++=0;}
-
- /* Reserve the first word of output as the control word for the first group. */
- /* Note: This is undone at the end if the input block is empty. */
- p_control=p_dst; p_dst+=2;
-
- /* Initialize all elements of the hash table to point to a constant string. */
- /* Use of an unrolled loop speeds this up considerably. */
- {UWORD i; UBYTE **p_h=hash;
-# define ZH *p_h++=START_STRING_18
- for (i=0;i<256;i++) /* 256=HASH_TABLE_LENGTH/16. */
- {ZH;ZH;ZH;ZH;
- ZH;ZH;ZH;ZH;
- ZH;ZH;ZH;ZH;
- ZH;ZH;ZH;ZH;}
- }
-
- /* The main loop processes either 1 or 16 items per iteration. As its */
- /* termination logic is complicated, I have opted for an infinite loop */
- /* structure containing 'break' and 'goto' statements. */
- while (TRUE)
- {/* Begin main processing loop. */
-
- /* Note: All the variables here except unroll should be defined within */
- /* the inner loop. Unfortunately the loop hasn't got a block. */
- register UBYTE *p; /* Scans through targ phrase during matching. */
- register UBYTE *p_ziv= NULL ; /* Points to first byte of current Ziv. */
- register UWORD unroll; /* Loop counter for unrolled inner loop. */
- register UWORD index; /* Index of current hash table entry. */
- register UBYTE **p_h0 = NULL ; /* Pointer to current hash table entry. */
-
- /* Test for overrun and jump to overrun code if necessary. */
- if (p_dst>p_dst_post)
- goto overrun;
-
- /* The following cascade of if statements efficiently catches and deals */
- /* with varying degrees of closeness to the end of the input block. */
- /* When we get very close to the end, we stop updating the table and */
- /* code the remaining bytes as literals. This makes the code simpler. */
- unroll=16;
- if (p_src>p_src_max16)
- {
- unroll=1;
- if (p_src>p_src_max1)
- {
- if (p_src==p_src_post)
- break;
- else
- goto literal;
- }
- }
-
- /* This inner unrolled loop processes 'unroll' (whose value is either 1 */
- /* or 16) items. I have chosen to implement this loop with labels and */
- /* gotos to heighten the ease with which the loop may be implemented with */
- /* a single decrement and branch instruction in assembly language and */
- /* also because the labels act as highly readable place markers. */
- /* (Also because we jump into the loop for endgame literals (see above)). */
-
- begin_unrolled_loop:
-
- /* To process the next phrase, we hash the next three bytes and use */
- /* the resultant hash table index to look up the hash table. A pointer */
- /* to the entry is stored in p_h0 so as to avoid an array lookup. The */
- /* hash table entry *p_h0 is looked up yielding a pointer p to a */
- /* potential match of the Ziv in the history. */
- index=HASH(p_src);
- p_h0=&hash[index];
- p=*p_h0;
-
- /* Having looked up the candidate position, we are in a position to */
- /* attempt a match. The match loop has been unrolled using the PS */
- /* macro so that failure within the first three bytes automatically */
- /* results in the literal branch being taken. The coding is simple. */
- /* p_ziv saves p_src so we can let p_src wander. */
-# define PS *p++!=*p_src++
- p_ziv=p_src;
- if (PS || PS || PS)
- {
- /* Literal. */
-
- /* Code the literal byte as itself and a zero control bit. */
- p_src=p_ziv; literal: *p_dst++=*p_src++; control&=0xFFFEFFFF;
-
- /* We have just coded a literal. If we had two pending ones, that */
- /* makes three and we can update the hash table. */
- if (p_h2!=0)
- {*p_h2=p_ziv-2;}
-
- /* In any case, rotate the hash table pointers for next time. */
- p_h2=p_h1; p_h1=p_h0;
-
- }
- else
- {
- /* Copy */
-
- /* Match up to 15 remaining bytes using an unrolled loop and code. */
-#if 0
- PS || PS || PS || PS || PS || PS || PS || PS ||
- PS || PS || PS || PS || PS || PS || PS || p_src++;
-#else
- if (
- !( PS || PS || PS || PS || PS || PS || PS || PS ||
- PS || PS || PS || PS || PS || PS || PS )
- ) p_src++;
-#endif
- *p_dst++=((index&0xF00)>>4)|(--p_src-p_ziv-3);
- *p_dst++=index&0xFF;
-
- /* As we have just coded three bytes, we are now in a position to */
- /* update the hash table with the literal bytes that were pending */
- /* upon the arrival of extra context bytes. */
- if (p_h1!=0)
- {
- if (p_h2)
- {*p_h2=p_ziv-2; p_h2=NULL;}
- *p_h1=p_ziv-1; p_h1=NULL;
- }
-
- /* In any case, we can update the hash table based on the current */
- /* position as we just coded at least three bytes in a copy items. */
- *p_h0=p_ziv;
-
- }
- control>>=1;
-
- /* This loop is all set up for a decrement and jump instruction! */
-#ifndef linux
-` end_unrolled_loop: if (--unroll) goto begin_unrolled_loop;
-#else
- /* end_unrolled_loop: */ if (--unroll) goto begin_unrolled_loop;
-#endif
-
- /* At this point it will nearly always be the end of a group in which */
- /* case, we have to do some control-word processing. However, near the */
- /* end of the input block, the inner unrolled loop is only executed once. */
- /* This necessitates the 'if' test. */
- if ((control&TOPWORD)==0)
- {
- /* Write the control word to the place we saved for it in the output. */
- *p_control++= control &0xFF;
- *p_control = (control>>8) &0xFF;
-
- /* Reserve the next word in the output block for the control word */
- /* for the group about to be processed. */
- p_control=p_dst; p_dst+=2;
-
- /* Reset the control bits buffer. */
- control=TOPWORD;
- }
-
- } /* End main processing loop. */
-
- /* After the main processing loop has executed, all the input bytes have */
- /* been processed. However, the control word has still to be written to the */
- /* word reserved for it in the output at the start of the most recent group. */
- /* Before writing, the control word has to be shifted so that all the bits */
- /* are in the right place. The "empty" bit positions are filled with 1s */
- /* which partially fill the top word. */
- while(control&TOPWORD) control>>=1;
- *p_control++= control &0xFF;
- *p_control++=(control>>8) &0xFF;
-
- /* If the last group contained no items, delete the control word too. */
- if (p_control==p_dst) p_dst-=2;
-
- /* Write the length of the output block to the dst_len parameter and return. */
- *p_dst_len=p_dst-p_dst_first;
- return;
-
- /* Jump here as soon as an overrun is detected. An overrun is defined to */
- /* have occurred if p_dst>p_dst_first+src_len. That is, the moment the */
- /* length of the output written so far exceeds the length of the input block.*/
- /* The algorithm checks for overruns at least at the end of each group */
- /* which means that the maximum overrun is MAX_CMP_GROUP bytes. */
- /* Once an overrun occurs, the only thing to do is to set the copy flag and */
- /* copy the input over. */
- overrun:
-#if 0
- *p_dst_first=FLAG_COPY;
- fast_copy(p_src_first,p_dst_first+FLAG_BYTES,src_len);
- *p_dst_len=src_len+FLAG_BYTES;
-#else
- fast_copy(p_src_first,p_dst_first,src_len);
- *p_dst_len= -src_len; /* return a negative number to indicate uncompressed data */
-#endif
-}
-
-/******************************************************************************/
-
-/* Input : Hand over the required amount of working memory in p_wrk_mem. */
-/* Input : Specify input block using p_src_first and src_len. */
-/* Input : Point p_dst_first to the start of the output zone. */
-/* Input : Point p_dst_len to a ULONG to receive the output length. */
-/* Input : Input block and output zone must not overlap. User knows */
-/* Input : upperbound on output block length from earlier compression. */
-/* Input : In any case, maximum expansion possible is nine times. */
-/* Output : Length of output block written to *p_dst_len. */
-/* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
-/* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
-LOCAL void compress_decompress( UBYTE *p_wrk_mem,
- UBYTE *p_src_first, LONG src_len,
- UBYTE *p_dst_first, ULONG *p_dst_len)
-{
- /* Byte pointers p_src and p_dst scan through the input and output blocks. */
- register UBYTE *p_src = p_src_first+FLAG_BYTES;
- register UBYTE *p_dst = p_dst_first;
- /* we need to avoid a SEGV when trying to uncompress corrupt data */
- register UBYTE *p_dst_post = p_dst_first + *p_dst_len;
-
- /* The following two variables are never modified and are used to control */
- /* the main loop. */
- UBYTE *p_src_post = p_src_first+src_len;
- UBYTE *p_src_max16 = p_src_first+src_len-(MAX_CMP_GROUP-2);
-
- /* The hash table is the only resident of the working memory. The hash table */
- /* contains HASH_TABLE_LENGTH=4096 pointers to positions in the history. To */
- /* keep Macintoshes happy, it is longword aligned. */
- UBYTE **hash = (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem);
-
- /* The variable 'control' is used to buffer the control bits which appear in */
- /* groups of 16 bits (control words) at the start of each compressed group. */
- /* When each group is read, bit 16 of the register is set to one. Whenever */
- /* a new bit is needed, the register is shifted right. When the value of the */
- /* register becomes 1, we know that we have reached the end of a group. */
- /* Initializing the register to 1 thus instructs the code to follow that it */
- /* should read a new control word immediately. */
- register ULONG control=1;
-
- /* The value of 'literals' is always in the range 0..3. It is the number of */
- /* consecutive literal items just seen. We have to record this number so as */
- /* to know when to update the hash table. When literals gets to 3, there */
- /* have been three consecutive literals and we can update at the position of */
- /* the oldest of the three. */
- register UWORD literals=0;
-
- /* Check the leading copy flag to see if the compressor chose to use a copy */
- /* operation instead of a compression operation. If a copy operation was */
- /* used, then all we need to do is copy the data over, set the output length */
- /* and return. */
-#if 0
- if (*p_src_first==FLAG_COPY)
- {
- fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES);
- *p_dst_len=src_len-FLAG_BYTES;
- return;
- }
-#else
- if ( src_len < 0 )
- {
- fast_copy(p_src_first,p_dst_first,-src_len );
- *p_dst_len = (ULONG)-src_len;
- return;
- }
-#endif
-
- /* Initialize all elements of the hash table to point to a constant string. */
- /* Use of an unrolled loop speeds this up considerably. */
- {UWORD i; UBYTE **p_h=hash;
-# define ZJ *p_h++=START_STRING_18
- for (i=0;i<256;i++) /* 256=HASH_TABLE_LENGTH/16. */
- {ZJ;ZJ;ZJ;ZJ;
- ZJ;ZJ;ZJ;ZJ;
- ZJ;ZJ;ZJ;ZJ;
- ZJ;ZJ;ZJ;ZJ;}
- }
-
- /* The outer loop processes either 1 or 16 items per iteration depending on */
- /* how close p_src is to the end of the input block. */
- while (p_src!=p_src_post)
- {/* Start of outer loop */
-
- register UWORD unroll; /* Counts unrolled loop executions. */
-
- /* When 'control' has the value 1, it means that the 16 buffered control */
- /* bits that were read in at the start of the current group have all been */
- /* shifted out and that all that is left is the 1 bit that was injected */
- /* into bit 16 at the start of the current group. When we reach the end */
- /* of a group, we have to load a new control word and inject a new 1 bit. */
- if (control==1)
- {
- control=0x10000|*p_src++;
- control|=(*p_src++)<<8;
- }
-
- /* If it is possible that we are within 16 groups from the end of the */
- /* input, execute the unrolled loop only once, else process a whole group */
- /* of 16 items by looping 16 times. */
- unroll= p_src<=p_src_max16 ? 16 : 1;
-
- /* This inner loop processes one phrase (item) per iteration. */
- while (unroll--)
- { /* Begin unrolled inner loop. */
-
- /* Process a literal or copy item depending on the next control bit. */
- if (control&1)
- {
- /* Copy item. */
-
- register UBYTE *p; /* Points to place from which to copy. */
- register UWORD lenmt; /* Length of copy item minus three. */
- register UBYTE **p_hte; /* Pointer to current hash table entry.*/
- register UBYTE *p_ziv=p_dst; /* Pointer to start of current Ziv. */
-
- /* Read and dismantle the copy word. Work out from where to copy. */
- lenmt=*p_src++;
- p_hte=&hash[((lenmt&0xF0)<<4)|*p_src++];
- p=*p_hte;
- lenmt&=0xF;
-
- /* Now perform the copy using a half unrolled loop. */
- *p_dst++=*p++;
- *p_dst++=*p++;
- *p_dst++=*p++;
- while (lenmt--)
- *p_dst++=*p++;
-
- /* Because we have just received 3 or more bytes in a copy item */
- /* (whose bytes we have just installed in the output), we are now */
- /* in a position to flush all the pending literal hashings that had */
- /* been postponed for lack of bytes. */
- if (literals>0)
- {
- register UBYTE *r=p_ziv-literals;
- hash[HASH(r)]=r;
- if (literals==2)
- {r++; hash[HASH(r)]=r;}
- literals=0;
- }
-
- /* In any case, we can immediately update the hash table with the */
- /* current position. We don't need to do a HASH(...) to work out */
- /* where to put the pointer, as the compressor just told us!!! */
- *p_hte=p_ziv;
-
- }
- else
- {
- /* Literal item. */
-
- /* Copy over the literal byte. */
- *p_dst++=*p_src++;
-
- /* If we now have three literals waiting to be hashed into the hash */
- /* table, we can do one of them now (because there are three). */
- if (++literals == 3)
- {register UBYTE *p=p_dst-3; hash[HASH(p)]=p; literals=2;}
- }
-
- /* Shift the control buffer so the next control bit is in bit 0. */
- control>>=1;
-#if 1
- if (p_dst > p_dst_post)
- {
- /* Shit: we tried to decompress corrupt data */
- *p_dst_len = 0;
- return;
- }
-#endif
- } /* End unrolled inner loop. */
-
- } /* End of outer loop */
-
- /* Write the length of the decompressed data before returning. */
- *p_dst_len=p_dst-p_dst_first;
-}
-
-/******************************************************************************/
-/* End of LZRW3.C */
-/******************************************************************************/
diff --git a/drivers/char/ftape/compressor/lzrw3.h b/drivers/char/ftape/compressor/lzrw3.h
deleted file mode 100644
index 533feba47526..000000000000
--- a/drivers/char/ftape/compressor/lzrw3.h
+++ /dev/null
@@ -1,253 +0,0 @@
-#ifndef _LZRW3_H
-#define _LZRW3_H
-/*
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/lzrw3.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:30 $
- *
- * include files for lzrw3. Only slighty modified from the original
- * version. Assembles the three include files compress.h, port.h and
- * fastcopy.h from the original lzrw3 package.
- *
- */
-
-#include <linux/types.h>
-#include <linux/string.h>
-
-/******************************************************************************/
-/* */
-/* COMPRESS.H */
-/* */
-/******************************************************************************/
-/* */
-/* Author : Ross Williams. */
-/* Date : December 1989. */
-/* */
-/* This header file defines the interface to a set of functions called */
-/* 'compress', each member of which implements a particular data compression */
-/* algorithm. */
-/* */
-/* Normally in C programming, for each .H file, there is a corresponding .C */
-/* file that implements the functions promised in the .H file. */
-/* Here, there are many .C files corresponding to this header file. */
-/* Each comforming implementation file contains a single function */
-/* called 'compress' that implements a single data compression */
-/* algorithm that conforms with the interface specified in this header file. */
-/* Only one algorithm can be linked in at a time in this organization. */
-/* */
-/******************************************************************************/
-/* */
-/* DEFINITION OF FUNCTION COMPRESS */
-/* =============================== */
-/* */
-/* Summary of Function Compress */
-/* ---------------------------- */
-/* The action that 'compress' takes depends on its first argument called */
-/* 'action'. The function provides three actions: */
-/* */
-/* - Return information about the algorithm. */
-/* - Compress a block of memory. */
-/* - Decompress a block of memory. */
-/* */
-/* Parameters */
-/* ---------- */
-/* See the formal C definition later for a description of the parameters. */
-/* */
-/* Constants */
-/* --------- */
-/* COMPRESS_OVERRUN: The constant COMPRESS_OVERRUN defines by how many bytes */
-/* an algorithm is allowed to expand a block during a compression operation. */
-/* */
-/* Although compression algorithms usually compress data, there will always */
-/* be data that a given compressor will expand (this can be proven). */
-/* Fortunately, the degree of expansion can be limited to a single bit, by */
-/* copying over the input data if the data gets bigger during compression. */
-/* To allow for this possibility, the first bit of a compressed */
-/* representation can be used as a flag indicating whether the */
-/* input data was copied over, or truly compressed. In practice, the first */
-/* byte would be used to store this bit so as to maintain byte alignment. */
-/* */
-/* Unfortunately, in general, the only way to tell if an algorithm will */
-/* expand a particular block of data is to run the algorithm on the data. */
-/* If the algorithm does not continuously monitor how many output bytes it */
-/* has written, it might write an output block far larger than the input */
-/* block before realizing that it has done so. */
-/* On the other hand, continuous checks on output length are inefficient. */
-/* */
-/* To cater for all these problems, this interface definition: */
-/* > Allows a compression algorithm to return an output block that is up to */
-/* COMPRESS_OVERRUN bytes longer than the input block. */
-/* > Allows a compression algorithm to write up to COMPRESS_OVERRUN bytes */
-/* more than the length of the input block to the memory of the output */
-/* block regardless of the length of the output block eventually returned. */
-/* This allows an algorithm to overrun the length of the input block in the */
-/* output block by up to COMPRESS_OVERRUN bytes between expansion checks. */
-/* */
-/* The problem does not arise for decompression. */
-/* */
-/* Identity Action */
-/* --------------- */
-/* > action must be COMPRESS_ACTION_IDENTITY. */
-/* > p_dst_len must point to a longword to receive a longword address. */
-/* > The value of the other parameters does not matter. */
-/* > After execution, the longword that p_dst_len points to will be a pointer */
-/* to a structure of type compress_identity. */
-/* Thus, for example, after the call, (*p_dst_len)->memory will return the */
-/* number of bytes of working memory that the algorithm requires to run. */
-/* > The values of the identity structure returned are fixed constant */
-/* attributes of the algorithm and must not vary from call to call. */
-/* */
-/* Common Requirements for Compression and Decompression Actions */
-/* ------------------------------------------------------------- */
-/* > wrk_mem must point to an unused block of memory of a length specified in */
-/* the algorithm's identity block. The identity block can be obtained by */
-/* making a separate call to compress, specifying the identity action. */
-/* > The INPUT BLOCK is defined to be Memory[src_addr,src_addr+src_len-1]. */
-/* > dst_len will be used to denote *p_dst_len. */
-/* > dst_len is not read by compress, only written. */
-/* > The value of dst_len is defined only upon termination. */
-/* > The OUTPUT BLOCK is defined to be Memory[dst_addr,dst_addr+dst_len-1]. */
-/* */
-/* Compression Action */
-/* ------------------ */
-/* > action must be COMPRESS_ACTION_COMPRESS. */
-/* > src_len must be in the range [0,COMPRESS_MAX_ORG]. */
-/* > The OUTPUT ZONE is defined to be */
-/* Memory[dst_addr,dst_addr+src_len-1+COMPRESS_OVERRUN]. */
-/* > The function can modify any part of the output zone regardless of the */
-/* final length of the output block. */
-/* > The input block and the output zone must not overlap. */
-/* > dst_len will be in the range [0,src_len+COMPRESS_OVERRUN]. */
-/* > dst_len will be in the range [0,COMPRESS_MAX_COM] (from prev fact). */
-/* > The output block will consist of a representation of the input block. */
-/* */
-/* Decompression Action */
-/* -------------------- */
-/* > action must be COMPRESS_ACTION_DECOMPRESS. */
-/* > The input block must be the result of an earlier compression operation. */
-/* > If the previous fact is true, the following facts must also be true: */
-/* > src_len will be in the range [0,COMPRESS_MAX_COM]. */
-/* > dst_len will be in the range [0,COMPRESS_MAX_ORG]. */
-/* > The input and output blocks must not overlap. */
-/* > Only the output block is modified. */
-/* > Upon termination, the output block will consist of the bytes contained */
-/* in the input block passed to the earlier compression operation. */
-/* */
-/******************************************************************************/
-
-/******************************************************************************/
-/* */
-/* PORT.H */
-/* */
-/******************************************************************************/
-/* */
-/* This module contains macro definitions and types that are likely to */
-/* change between computers. */
-/* */
-/******************************************************************************/
-
-#ifndef DONE_PORT /* Only do this if not previously done. */
-
- #ifdef THINK_C
- #define UBYTE unsigned char /* Unsigned byte */
- #define UWORD unsigned int /* Unsigned word (2 bytes) */
- #define ULONG unsigned long /* Unsigned word (4 bytes) */
- #define BOOL unsigned char /* Boolean */
- #define FOPEN_BINARY_READ "rb" /* Mode string for binary reading. */
- #define FOPEN_BINARY_WRITE "wb" /* Mode string for binary writing. */
- #define FOPEN_TEXT_APPEND "a" /* Mode string for text appending. */
- #define REAL double /* USed for floating point stuff. */
- #endif
- #if defined(LINUX) || defined(linux)
- #define UBYTE __u8 /* Unsigned byte */
- #define UWORD __u16 /* Unsigned word (2 bytes) */
- #define ULONG __u32 /* Unsigned word (4 bytes) */
- #define LONG __s32 /* Signed word (4 bytes) */
- #define BOOL is not used here /* Boolean */
- #define FOPEN_BINARY_READ not used /* Mode string for binary reading. */
- #define FOPEN_BINARY_WRITE not used /* Mode string for binary writing. */
- #define FOPEN_TEXT_APPEND not used /* Mode string for text appending. */
- #define REAL not used /* USed for floating point stuff. */
- #ifndef TRUE
- #define TRUE 1
- #endif
- #endif
-
- #define DONE_PORT /* Don't do all this again. */
- #define MALLOC_FAIL NULL /* Failure status from malloc() */
- #define LOCAL static /* For non-exported routines. */
- #define EXPORT /* Signals exported function. */
- #define then /* Useful for aligning ifs. */
-
-#endif
-
-/******************************************************************************/
-/* End of PORT.H */
-/******************************************************************************/
-
-#define COMPRESS_ACTION_IDENTITY 0
-#define COMPRESS_ACTION_COMPRESS 1
-#define COMPRESS_ACTION_DECOMPRESS 2
-
-#define COMPRESS_OVERRUN 1024
-#define COMPRESS_MAX_COM 0x70000000
-#define COMPRESS_MAX_ORG (COMPRESS_MAX_COM-COMPRESS_OVERRUN)
-
-#define COMPRESS_MAX_STRLEN 255
-
-/* The following structure provides information about the algorithm. */
-/* > The top bit of id must be zero. The remaining bits must be chosen by */
-/* the author of the algorithm by tossing a coin 31 times. */
-/* > The amount of memory requested by the algorithm is specified in bytes */
-/* and must be in the range [0,0x70000000]. */
-/* > All strings s must be such that strlen(s)<=COMPRESS_MAX_STRLEN. */
-struct compress_identity
- {
- ULONG id; /* Identifying number of algorithm. */
- ULONG memory; /* Number of bytes of working memory required. */
-
- char *name; /* Name of algorithm. */
- char *version; /* Version number. */
- char *date; /* Date of release of this version. */
- char *copyright; /* Copyright message. */
-
- char *author; /* Author of algorithm. */
- char *affiliation; /* Affiliation of author. */
- char *vendor; /* Where the algorithm can be obtained. */
- };
-
-void lzrw3_compress( /* Single function interface to compression algorithm. */
-UWORD action, /* Action to be performed. */
-UBYTE *wrk_mem, /* Working memory temporarily given to routine to use. */
-UBYTE *src_adr, /* Address of input data. */
-LONG src_len, /* Length of input data. */
-UBYTE *dst_adr, /* Address of output data. */
-void *p_dst_len /* Pointer to a longword where routine will write: */
- /* If action=..IDENTITY => Adr of id structure. */
- /* If action=..COMPRESS => Length of output data. */
- /* If action=..DECOMPRESS => Length of output data. */
-);
-
-/******************************************************************************/
-/* End of COMPRESS.H */
-/******************************************************************************/
-
-
-/******************************************************************************/
-/* fast_copy.h */
-/******************************************************************************/
-
-/* This function copies a block of memory very quickly. */
-/* The exact speed depends on the relative alignment of the blocks of memory. */
-/* PRE : 0<=src_len<=(2^32)-1 . */
-/* PRE : Source and destination blocks must not overlap. */
-/* POST : MEM[dst_adr,dst_adr+src_len-1]=MEM[src_adr,src_adr+src_len-1]. */
-/* POST : MEM[dst_adr,dst_adr+src_len-1] is the only memory changed. */
-
-#define fast_copy(src,dst,len) memcpy(dst,src,len)
-
-/******************************************************************************/
-/* End of fast_copy.h */
-/******************************************************************************/
-
-#endif
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
deleted file mode 100644
index 65ffc0be3df9..000000000000
--- a/drivers/char/ftape/compressor/zftape-compress.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-/*
- * Copyright (C) 1994-1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * This file implements a "generic" interface between the *
- * zftape-driver and a compression-algorithm. The *
- * compression-algorithm currently used is a LZ77. I use the *
- * implementation lzrw3 by Ross N. Williams (Renaissance *
- * Software). The compression program itself is in the file
- * lzrw3.c * and lzrw3.h. To adopt another compression algorithm
- * the functions * zft_compress() and zft_uncompress() must be
- * changed * appropriately. See below.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../compressor/zftape-compress.h"
-#include "../zftape/zftape-vtbl.h"
-#include "../compressor/lzrw3.h"
-
-/*
- * global variables
- */
-
-/* I handle the allocation of this buffer as a special case, because
- * it's size varies depending on the tape length inserted.
- */
-
-/* local variables
- */
-static void *zftc_wrk_mem = NULL;
-static __u8 *zftc_buf = NULL;
-static void *zftc_scratch_buf = NULL;
-
-/* compression statistics
- */
-static unsigned int zftc_wr_uncompressed = 0;
-static unsigned int zftc_wr_compressed = 0;
-static unsigned int zftc_rd_uncompressed = 0;
-static unsigned int zftc_rd_compressed = 0;
-
-/* forward */
-static int zftc_write(int *write_cnt,
- __u8 *dst_buf, const int seg_sz,
- const __u8 __user *src_buf, const int req_len,
- const zft_position *pos, const zft_volinfo *volume);
-static int zftc_read(int *read_cnt,
- __u8 __user *dst_buf, const int to_do,
- const __u8 *src_buf, const int seg_sz,
- const zft_position *pos, const zft_volinfo *volume);
-static int zftc_seek(unsigned int new_block_pos,
- zft_position *pos, const zft_volinfo *volume,
- __u8 *buffer);
-static void zftc_lock (void);
-static void zftc_reset (void);
-static void zftc_cleanup(void);
-static void zftc_stats (void);
-
-/* compressed segment. This conforms to QIC-80-MC, Revision K.
- *
- * Rev. K applies to tapes with `fixed length format' which is
- * indicated by format code 2,3 and 5. See below for format code 4 and 6
- *
- * 2 bytes: offset of compression segment structure
- * 29k > offset >= 29k-18: data from previous segment ens in this
- * segment and no compressed block starts
- * in this segment
- * offset == 0: data from previous segment occupies entire
- * segment and continues in next segment
- * n bytes: remainder from previous segment
- *
- * Rev. K:
- * 4 bytes: 4 bytes: files set byte offset
- * Post Rev. K and QIC-3020/3020:
- * 8 bytes: 8 bytes: files set byte offset
- * 2 bytes: byte count N (amount of data following)
- * bit 15 is set if data is compressed, bit 15 is not
- * set if data is uncompressed
- * N bytes: data (as much as specified in the byte count)
- * 2 bytes: byte count N_1 of next cluster
- * N_1 bytes: data of next cluset
- * 2 bytes: byte count N_2 of next cluster
- * N_2 bytes: ...
- *
- * Note that the `N' byte count accounts only for the bytes that in the
- * current segment if the cluster spans to the next segment.
- */
-
-typedef struct
-{
- int cmpr_pos; /* actual position in compression buffer */
- int cmpr_sz; /* what is left in the compression buffer
- * when copying the compressed data to the
- * deblock buffer
- */
- unsigned int first_block; /* location of header information in
- * this segment
- */
- unsigned int count; /* amount of data of current block
- * contained in current segment
- */
- unsigned int offset; /* offset in current segment */
- unsigned int spans:1; /* might continue in next segment */
- unsigned int uncmpr; /* 0x8000 if this block contains
- * uncompressed data
- */
- __s64 foffs; /* file set byte offset, same as in
- * compression map segment
- */
-} cmpr_info;
-
-static cmpr_info cseg; /* static data. Must be kept uptodate and shared by
- * read, write and seek functions
- */
-
-#define DUMP_CMPR_INFO(level, msg, info) \
- TRACE(level, msg "\n" \
- KERN_INFO "cmpr_pos : %d\n" \
- KERN_INFO "cmpr_sz : %d\n" \
- KERN_INFO "first_block: %d\n" \
- KERN_INFO "count : %d\n" \
- KERN_INFO "offset : %d\n" \
- KERN_INFO "spans : %d\n" \
- KERN_INFO "uncmpr : 0x%04x\n" \
- KERN_INFO "foffs : " LL_X, \
- (info)->cmpr_pos, (info)->cmpr_sz, (info)->first_block, \
- (info)->count, (info)->offset, (info)->spans == 1, \
- (info)->uncmpr, LL((info)->foffs))
-
-/* dispatch compression segment info, return error code
- *
- * afterwards, cseg->offset points to start of data of the NEXT
- * compressed block, and cseg->count contains the amount of data
- * left in the actual compressed block. cseg->spans is set to 1 if
- * the block is continued in the following segment. Otherwise it is
- * set to 0.
- */
-static int get_cseg (cmpr_info *cinfo, const __u8 *buff,
- const unsigned int seg_sz,
- const zft_volinfo *volume)
-{
- TRACE_FUN(ft_t_flow);
-
- cinfo->first_block = GET2(buff, 0);
- if (cinfo->first_block == 0) { /* data spans to next segment */
- cinfo->count = seg_sz - sizeof(__u16);
- cinfo->offset = seg_sz;
- cinfo->spans = 1;
- } else { /* cluster definetely ends in this segment */
- if (cinfo->first_block > seg_sz) {
- /* data corrupted */
- TRACE_ABORT(-EIO, ft_t_err, "corrupted data:\n"
- KERN_INFO "segment size: %d\n"
- KERN_INFO "first block : %d",
- seg_sz, cinfo->first_block);
- }
- cinfo->count = cinfo->first_block - sizeof(__u16);
- cinfo->offset = cinfo->first_block;
- cinfo->spans = 0;
- }
- /* now get the offset the first block should have in the
- * uncompressed data stream.
- *
- * For this magic `18' refer to CRF-3 standard or QIC-80MC,
- * Rev. K.
- */
- if ((seg_sz - cinfo->offset) > 18) {
- if (volume->qic113) { /* > revision K */
- TRACE(ft_t_data_flow, "New QIC-113 compliance");
- cinfo->foffs = GET8(buff, cinfo->offset);
- cinfo->offset += sizeof(__s64);
- } else {
- TRACE(/* ft_t_data_flow */ ft_t_noise, "pre QIC-113 version");
- cinfo->foffs = (__s64)GET4(buff, cinfo->offset);
- cinfo->offset += sizeof(__u32);
- }
- }
- if (cinfo->foffs > volume->size) {
- TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
- KERN_INFO "offset in current volume: %d\n"
- KERN_INFO "size of current volume : %d",
- (int)(cinfo->foffs>>10), (int)(volume->size>>10));
- }
- if (cinfo->cmpr_pos + cinfo->count > volume->blk_sz) {
- TRACE_ABORT(-EIO, ft_t_err, "Inconsistency:\n"
- KERN_INFO "block size : %d\n"
- KERN_INFO "data record: %d",
- volume->blk_sz, cinfo->cmpr_pos + cinfo->count);
- }
- DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", cinfo);
- TRACE_EXIT 0;
-}
-
-/* This one is called, when a new cluster starts in same segment.
- *
- * Note: if this is the first cluster in the current segment, we must
- * not check whether there are more than 18 bytes available because
- * this have already been done in get_cseg() and there may be less
- * than 18 bytes available due to header information.
- *
- */
-static void get_next_cluster(cmpr_info *cluster, const __u8 *buff,
- const int seg_sz, const int finish)
-{
- TRACE_FUN(ft_t_flow);
-
- if (seg_sz - cluster->offset > 18 || cluster->foffs != 0) {
- cluster->count = GET2(buff, cluster->offset);
- cluster->uncmpr = cluster->count & 0x8000;
- cluster->count -= cluster->uncmpr;
- cluster->offset += sizeof(__u16);
- cluster->foffs = 0;
- if ((cluster->offset + cluster->count) < seg_sz) {
- cluster->spans = 0;
- } else if (cluster->offset + cluster->count == seg_sz) {
- cluster->spans = !finish;
- } else {
- /* either an error or a volume written by an
- * old version. If this is a data error, then we'll
- * catch it later.
- */
- TRACE(ft_t_data_flow, "Either error or old volume");
- cluster->spans = 1;
- cluster->count = seg_sz - cluster->offset;
- }
- } else {
- cluster->count = 0;
- cluster->spans = 0;
- cluster->foffs = 0;
- }
- DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */ , "", cluster);
- TRACE_EXIT;
-}
-
-static void zftc_lock(void)
-{
-}
-
-/* this function is needed for zftape_reset_position in zftape-io.c
- */
-static void zftc_reset(void)
-{
- TRACE_FUN(ft_t_flow);
-
- memset((void *)&cseg, '\0', sizeof(cseg));
- zftc_stats();
- TRACE_EXIT;
-}
-
-static int cmpr_mem_initialized = 0;
-static unsigned int alloc_blksz = 0;
-
-static int zft_allocate_cmpr_mem(unsigned int blksz)
-{
- TRACE_FUN(ft_t_flow);
-
- if (cmpr_mem_initialized && blksz == alloc_blksz) {
- TRACE_EXIT 0;
- }
- TRACE_CATCH(zft_vmalloc_once(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE),
- zftc_cleanup());
- TRACE_CATCH(zft_vmalloc_always(&zftc_buf, blksz + CMPR_OVERRUN),
- zftc_cleanup());
- alloc_blksz = blksz;
- TRACE_CATCH(zft_vmalloc_always(&zftc_scratch_buf, blksz+CMPR_OVERRUN),
- zftc_cleanup());
- cmpr_mem_initialized = 1;
- TRACE_EXIT 0;
-}
-
-static void zftc_cleanup(void)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_vfree(&zftc_wrk_mem, CMPR_WRK_MEM_SIZE);
- zft_vfree(&zftc_buf, alloc_blksz + CMPR_OVERRUN);
- zft_vfree(&zftc_scratch_buf, alloc_blksz + CMPR_OVERRUN);
- cmpr_mem_initialized = alloc_blksz = 0;
- TRACE_EXIT;
-}
-
-/*****************************************************************************
- * *
- * The following two functions "ftape_compress()" and *
- * "ftape_uncompress()" are the interface to the actual compression *
- * algorithm (i.e. they are calling the "compress()" function from *
- * the lzrw3 package for now). These routines could quite easily be *
- * changed to adopt another compression algorithm instead of lzrw3, *
- * which currently is used. *
- * *
- *****************************************************************************/
-
-/* called by zft_compress_write() to perform the compression. Must
- * return the size of the compressed data.
- *
- * NOTE: The size of the compressed data should not exceed the size of
- * the uncompressed data. Most compression algorithms have means
- * to store data unchanged if the "compressed" data amount would
- * exceed the original one. Mostly this is done by storing some
- * flag-bytes in front of the compressed data to indicate if it
- * is compressed or not. Thus the worst compression result
- * length is the original length plus those flag-bytes.
- *
- * We don't want that, as the QIC-80 standard provides a means
- * of marking uncompressed blocks by simply setting bit 15 of
- * the compressed block's length. Thus a compessed block can
- * have at most a length of 2^15-1 bytes. The QIC-80 standard
- * restricts the block-length even further, allowing only 29k -
- * 6 bytes.
- *
- * Currently, the maximum blocksize used by zftape is 28k.
- *
- * In short: don't exceed the length of the input-package, set
- * bit 15 of the compressed size to 1 if you have copied data
- * instead of compressing it.
- */
-static int zft_compress(__u8 *in_buffer, unsigned int in_sz, __u8 *out_buffer)
-{
- __s32 compressed_sz;
- TRACE_FUN(ft_t_flow);
-
-
- lzrw3_compress(COMPRESS_ACTION_COMPRESS, zftc_wrk_mem,
- in_buffer, in_sz, out_buffer, &compressed_sz);
- if (TRACE_LEVEL >= ft_t_info) {
- /* the compiler will optimize this away when
- * compiled with NO_TRACE_AT_ALL option
- */
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "before compression: %d bytes\n"
- KERN_INFO "after compresison : %d bytes",
- in_sz,
- (int)(compressed_sz < 0
- ? -compressed_sz : compressed_sz));
- /* for statistical purposes
- */
- zftc_wr_compressed += (compressed_sz < 0
- ? -compressed_sz : compressed_sz);
- zftc_wr_uncompressed += in_sz;
- }
- TRACE_EXIT (int)compressed_sz;
-}
-
-/* called by zft_compress_read() to decompress the data. Must
- * return the size of the decompressed data for sanity checks
- * (compared with zft_blk_sz)
- *
- * NOTE: Read the note for zft_compress() above! If bit 15 of the
- * parameter in_sz is set, then the data in in_buffer isn't
- * compressed, which must be handled by the un-compression
- * algorithm. (I changed lzrw3 to handle this.)
- *
- * The parameter max_out_sz is needed to prevent buffer overruns when
- * uncompressing corrupt data.
- */
-static unsigned int zft_uncompress(__u8 *in_buffer,
- int in_sz,
- __u8 *out_buffer,
- unsigned int max_out_sz)
-{
- TRACE_FUN(ft_t_flow);
-
- lzrw3_compress(COMPRESS_ACTION_DECOMPRESS, zftc_wrk_mem,
- in_buffer, (__s32)in_sz,
- out_buffer, (__u32 *)&max_out_sz);
-
- if (TRACE_LEVEL >= ft_t_info) {
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "before decompression: %d bytes\n"
- KERN_INFO "after decompression : %d bytes",
- in_sz < 0 ? -in_sz : in_sz,(int)max_out_sz);
- /* for statistical purposes
- */
- zftc_rd_compressed += in_sz < 0 ? -in_sz : in_sz;
- zftc_rd_uncompressed += max_out_sz;
- }
- TRACE_EXIT (unsigned int)max_out_sz;
-}
-
-/* print some statistics about the efficiency of the compression to
- * the kernel log
- */
-static void zftc_stats(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (TRACE_LEVEL < ft_t_info) {
- TRACE_EXIT;
- }
- if (zftc_wr_uncompressed != 0) {
- if (zftc_wr_compressed > (1<<14)) {
- TRACE(ft_t_info, "compression statistics (writing):\n"
- KERN_INFO " compr./uncmpr. : %3d %%",
- (((zftc_wr_compressed>>10) * 100)
- / (zftc_wr_uncompressed>>10)));
- } else {
- TRACE(ft_t_info, "compression statistics (writing):\n"
- KERN_INFO " compr./uncmpr. : %3d %%",
- ((zftc_wr_compressed * 100)
- / zftc_wr_uncompressed));
- }
- }
- if (zftc_rd_uncompressed != 0) {
- if (zftc_rd_compressed > (1<<14)) {
- TRACE(ft_t_info, "compression statistics (reading):\n"
- KERN_INFO " compr./uncmpr. : %3d %%",
- (((zftc_rd_compressed>>10) * 100)
- / (zftc_rd_uncompressed>>10)));
- } else {
- TRACE(ft_t_info, "compression statistics (reading):\n"
- KERN_INFO " compr./uncmpr. : %3d %%",
- ((zftc_rd_compressed * 100)
- / zftc_rd_uncompressed));
- }
- }
- /* only print it once: */
- zftc_wr_uncompressed =
- zftc_wr_compressed =
- zftc_rd_uncompressed =
- zftc_rd_compressed = 0;
- TRACE_EXIT;
-}
-
-/* start new compressed block
- */
-static int start_new_cseg(cmpr_info *cluster,
- char *dst_buf,
- const zft_position *pos,
- const unsigned int blk_sz,
- const char *src_buf,
- const int this_segs_sz,
- const int qic113)
-{
- int size_left;
- int cp_cnt;
- int buf_pos;
- TRACE_FUN(ft_t_flow);
-
- size_left = this_segs_sz - sizeof(__u16) - cluster->cmpr_sz;
- TRACE(ft_t_data_flow,"\n"
- KERN_INFO "segment size : %d\n"
- KERN_INFO "compressed_sz: %d\n"
- KERN_INFO "size_left : %d",
- this_segs_sz, cluster->cmpr_sz, size_left);
- if (size_left > 18) { /* start a new cluseter */
- cp_cnt = cluster->cmpr_sz;
- cluster->cmpr_sz = 0;
- buf_pos = cp_cnt + sizeof(__u16);
- PUT2(dst_buf, 0, buf_pos);
-
- if (qic113) {
- __s64 foffs = pos->volume_pos;
- if (cp_cnt) foffs += (__s64)blk_sz;
-
- TRACE(ft_t_data_flow, "new style QIC-113 header");
- PUT8(dst_buf, buf_pos, foffs);
- buf_pos += sizeof(__s64);
- } else {
- __u32 foffs = (__u32)pos->volume_pos;
- if (cp_cnt) foffs += (__u32)blk_sz;
-
- TRACE(ft_t_data_flow, "old style QIC-80MC header");
- PUT4(dst_buf, buf_pos, foffs);
- buf_pos += sizeof(__u32);
- }
- } else if (size_left >= 0) {
- cp_cnt = cluster->cmpr_sz;
- cluster->cmpr_sz = 0;
- buf_pos = cp_cnt + sizeof(__u16);
- PUT2(dst_buf, 0, buf_pos);
- /* zero unused part of segment. */
- memset(dst_buf + buf_pos, '\0', size_left);
- buf_pos = this_segs_sz;
- } else { /* need entire segment and more space */
- PUT2(dst_buf, 0, 0);
- cp_cnt = this_segs_sz - sizeof(__u16);
- cluster->cmpr_sz -= cp_cnt;
- buf_pos = this_segs_sz;
- }
- memcpy(dst_buf + sizeof(__u16), src_buf + cluster->cmpr_pos, cp_cnt);
- cluster->cmpr_pos += cp_cnt;
- TRACE_EXIT buf_pos;
-}
-
-/* return-value: the number of bytes removed from the user-buffer
- * `src_buf' or error code
- *
- * int *write_cnt : how much actually has been moved to the
- * dst_buf. Need not be initialized when
- * function returns with an error code
- * (negativ return value)
- * __u8 *dst_buf : kernel space buffer where the has to be
- * copied to. The contents of this buffers
- * goes to a specific segment.
- * const int seg_sz : the size of the segment dst_buf will be
- * copied to.
- * const zft_position *pos : struct containing the coordinates in
- * the current volume (byte position,
- * segment id of current segment etc)
- * const zft_volinfo *volume: information about the current volume,
- * size etc.
- * const __u8 *src_buf : user space buffer that contains the
- * data the user wants to be written to
- * tape.
- * const int req_len : the amount of data the user wants to be
- * written to tape.
- */
-static int zftc_write(int *write_cnt,
- __u8 *dst_buf, const int seg_sz,
- const __u8 __user *src_buf, const int req_len,
- const zft_position *pos, const zft_volinfo *volume)
-{
- int req_len_left = req_len;
- int result;
- int len_left;
- int buf_pos_write = pos->seg_byte_pos;
- TRACE_FUN(ft_t_flow);
-
- /* Note: we do not unlock the module because
- * there are some values cached in that `cseg' variable. We
- * don't don't want to use this information when being
- * unloaded by kerneld even when the tape is full or when we
- * cannot allocate enough memory.
- */
- if (pos->tape_pos > (volume->size-volume->blk_sz-ZFT_CMPR_OVERHEAD)) {
- TRACE_EXIT -ENOSPC;
- }
- if (zft_allocate_cmpr_mem(volume->blk_sz) < 0) {
- /* should we unlock the module? But it shouldn't
- * be locked anyway ...
- */
- TRACE_EXIT -ENOMEM;
- }
- if (buf_pos_write == 0) { /* fill a new segment */
- *write_cnt = buf_pos_write = start_new_cseg(&cseg,
- dst_buf,
- pos,
- volume->blk_sz,
- zftc_buf,
- seg_sz,
- volume->qic113);
- if (cseg.cmpr_sz == 0 && cseg.cmpr_pos != 0) {
- req_len_left -= result = volume->blk_sz;
- cseg.cmpr_pos = 0;
- } else {
- result = 0;
- }
- } else {
- *write_cnt = result = 0;
- }
-
- len_left = seg_sz - buf_pos_write;
- while ((req_len_left > 0) && (len_left > 18)) {
- /* now we have some size left for a new compressed
- * block. We know, that the compression buffer is
- * empty (else there wouldn't be any space left).
- */
- if (copy_from_user(zftc_scratch_buf, src_buf + result,
- volume->blk_sz) != 0) {
- TRACE_EXIT -EFAULT;
- }
- req_len_left -= volume->blk_sz;
- cseg.cmpr_sz = zft_compress(zftc_scratch_buf, volume->blk_sz,
- zftc_buf);
- if (cseg.cmpr_sz < 0) {
- cseg.uncmpr = 0x8000;
- cseg.cmpr_sz = -cseg.cmpr_sz;
- } else {
- cseg.uncmpr = 0;
- }
- /* increment "result" iff we copied the entire
- * compressed block to the zft_deblock_buf
- */
- len_left -= sizeof(__u16);
- if (len_left >= cseg.cmpr_sz) {
- len_left -= cseg.count = cseg.cmpr_sz;
- cseg.cmpr_pos = cseg.cmpr_sz = 0;
- result += volume->blk_sz;
- } else {
- cseg.cmpr_sz -=
- cseg.cmpr_pos =
- cseg.count = len_left;
- len_left = 0;
- }
- PUT2(dst_buf, buf_pos_write, cseg.uncmpr | cseg.count);
- buf_pos_write += sizeof(__u16);
- memcpy(dst_buf + buf_pos_write, zftc_buf, cseg.count);
- buf_pos_write += cseg.count;
- *write_cnt += cseg.count + sizeof(__u16);
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- }
- /* erase the remainder of the segment if less than 18 bytes
- * left (18 bytes is due to the QIC-80 standard)
- */
- if (len_left <= 18) {
- memset(dst_buf + buf_pos_write, '\0', len_left);
- (*write_cnt) += len_left;
- }
- TRACE(ft_t_data_flow, "returning %d", result);
- TRACE_EXIT result;
-}
-
-/* out:
- *
- * int *read_cnt: the number of bytes we removed from the zft_deblock_buf
- * (result)
- * int *to_do : the remaining size of the read-request.
- *
- * in:
- *
- * char *buff : buff is the address of the upper part of the user
- * buffer, that hasn't been filled with data yet.
-
- * int buf_pos_read : copy of from _ftape_read()
- * int buf_len_read : copy of buf_len_rd from _ftape_read()
- * char *zft_deblock_buf: zft_deblock_buf
- * unsigned short blk_sz: the block size valid for this volume, may differ
- * from zft_blk_sz.
- * int finish: if != 0 means that this is the last segment belonging
- * to this volume
- * returns the amount of data actually copied to the user-buffer
- *
- * to_do MUST NOT SHRINK except to indicate an EOF. In this case *to_do has to
- * be set to 0
- */
-static int zftc_read (int *read_cnt,
- __u8 __user *dst_buf, const int to_do,
- const __u8 *src_buf, const int seg_sz,
- const zft_position *pos, const zft_volinfo *volume)
-{
- int uncompressed_sz;
- int result = 0;
- int remaining = to_do;
- TRACE_FUN(ft_t_flow);
-
- TRACE_CATCH(zft_allocate_cmpr_mem(volume->blk_sz),);
- if (pos->seg_byte_pos == 0) {
- /* new segment just read
- */
- TRACE_CATCH(get_cseg(&cseg, src_buf, seg_sz, volume),
- *read_cnt = 0);
- memcpy(zftc_buf + cseg.cmpr_pos, src_buf + sizeof(__u16),
- cseg.count);
- cseg.cmpr_pos += cseg.count;
- *read_cnt = cseg.offset;
- DUMP_CMPR_INFO(ft_t_noise /* ft_t_any */, "", &cseg);
- } else {
- *read_cnt = 0;
- }
- /* loop and uncompress until user buffer full or
- * deblock-buffer empty
- */
- TRACE(ft_t_data_flow, "compressed_sz: %d, compos : %d, *read_cnt: %d",
- cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
- while ((cseg.spans == 0) && (remaining > 0)) {
- if (cseg.cmpr_pos != 0) { /* cmpr buf is not empty */
- uncompressed_sz =
- zft_uncompress(zftc_buf,
- cseg.uncmpr == 0x8000 ?
- -cseg.cmpr_pos : cseg.cmpr_pos,
- zftc_scratch_buf,
- volume->blk_sz);
- if (uncompressed_sz != volume->blk_sz) {
- *read_cnt = 0;
- TRACE_ABORT(-EIO, ft_t_warn,
- "Uncompressed blk (%d) != blk size (%d)",
- uncompressed_sz, volume->blk_sz);
- }
- if (copy_to_user(dst_buf + result,
- zftc_scratch_buf,
- uncompressed_sz) != 0 ) {
- TRACE_EXIT -EFAULT;
- }
- remaining -= uncompressed_sz;
- result += uncompressed_sz;
- cseg.cmpr_pos = 0;
- }
- if (remaining > 0) {
- get_next_cluster(&cseg, src_buf, seg_sz,
- volume->end_seg == pos->seg_pos);
- if (cseg.count != 0) {
- memcpy(zftc_buf, src_buf + cseg.offset,
- cseg.count);
- cseg.cmpr_pos = cseg.count;
- cseg.offset += cseg.count;
- *read_cnt += cseg.count + sizeof(__u16);
- } else {
- remaining = 0;
- }
- }
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "compressed_sz: %d\n"
- KERN_INFO "compos : %d\n"
- KERN_INFO "*read_cnt : %d",
- cseg.cmpr_sz, cseg.cmpr_pos, *read_cnt);
- }
- if (seg_sz - cseg.offset <= 18) {
- *read_cnt += seg_sz - cseg.offset;
- TRACE(ft_t_data_flow, "expanding read cnt to: %d", *read_cnt);
- }
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "segment size : %d\n"
- KERN_INFO "read count : %d\n"
- KERN_INFO "buf_pos_read : %d\n"
- KERN_INFO "remaining : %d",
- seg_sz, *read_cnt, pos->seg_byte_pos,
- seg_sz - *read_cnt - pos->seg_byte_pos);
- TRACE(ft_t_data_flow, "returning: %d", result);
- TRACE_EXIT result;
-}
-
-/* seeks to the new data-position. Reads sometimes a segment.
- *
- * start_seg and end_seg give the boundaries of the current volume
- * blk_sz is the blk_sz of the current volume as stored in the
- * volume label
- *
- * We don't allow blocksizes less than 1024 bytes, therefore we don't need
- * a 64 bit argument for new_block_pos.
- */
-
-static int seek_in_segment(const unsigned int to_do, cmpr_info *c_info,
- const char *src_buf, const int seg_sz,
- const int seg_pos, const zft_volinfo *volume);
-static int slow_seek_forward_until_error(const unsigned int distance,
- cmpr_info *c_info, zft_position *pos,
- const zft_volinfo *volume, __u8 *buf);
-static int search_valid_segment(unsigned int segment,
- const unsigned int end_seg,
- const unsigned int max_foffs,
- zft_position *pos, cmpr_info *c_info,
- const zft_volinfo *volume, __u8 *buf);
-static int slow_seek_forward(unsigned int dest, cmpr_info *c_info,
- zft_position *pos, const zft_volinfo *volume,
- __u8 *buf);
-static int compute_seg_pos(unsigned int dest, zft_position *pos,
- const zft_volinfo *volume);
-
-#define ZFT_SLOW_SEEK_THRESHOLD 10 /* segments */
-#define ZFT_FAST_SEEK_MAX_TRIALS 10 /* times */
-#define ZFT_FAST_SEEK_BACKUP 10 /* segments */
-
-static int zftc_seek(unsigned int new_block_pos,
- zft_position *pos, const zft_volinfo *volume, __u8 *buf)
-{
- unsigned int dest;
- int limit;
- int distance;
- int result = 0;
- int seg_dist;
- int new_seg;
- int old_seg = 0;
- int fast_seek_trials = 0;
- TRACE_FUN(ft_t_flow);
-
- if (new_block_pos == 0) {
- pos->seg_pos = volume->start_seg;
- pos->seg_byte_pos = 0;
- pos->volume_pos = 0;
- zftc_reset();
- TRACE_EXIT 0;
- }
- dest = new_block_pos * (volume->blk_sz >> 10);
- distance = dest - (pos->volume_pos >> 10);
- while (distance != 0) {
- seg_dist = compute_seg_pos(dest, pos, volume);
- TRACE(ft_t_noise, "\n"
- KERN_INFO "seg_dist: %d\n"
- KERN_INFO "distance: %d\n"
- KERN_INFO "dest : %d\n"
- KERN_INFO "vpos : %d\n"
- KERN_INFO "seg_pos : %d\n"
- KERN_INFO "trials : %d",
- seg_dist, distance, dest,
- (unsigned int)(pos->volume_pos>>10), pos->seg_pos,
- fast_seek_trials);
- if (distance > 0) {
- if (seg_dist < 0) {
- TRACE(ft_t_bug, "BUG: distance %d > 0, "
- "segment difference %d < 0",
- distance, seg_dist);
- result = -EIO;
- break;
- }
- new_seg = pos->seg_pos + seg_dist;
- if (new_seg > volume->end_seg) {
- new_seg = volume->end_seg;
- }
- if (old_seg == new_seg || /* loop */
- seg_dist <= ZFT_SLOW_SEEK_THRESHOLD ||
- fast_seek_trials >= ZFT_FAST_SEEK_MAX_TRIALS) {
- TRACE(ft_t_noise, "starting slow seek:\n"
- KERN_INFO "fast seek failed too often: %s\n"
- KERN_INFO "near target position : %s\n"
- KERN_INFO "looping between two segs : %s",
- (fast_seek_trials >=
- ZFT_FAST_SEEK_MAX_TRIALS)
- ? "yes" : "no",
- (seg_dist <= ZFT_SLOW_SEEK_THRESHOLD)
- ? "yes" : "no",
- (old_seg == new_seg)
- ? "yes" : "no");
- result = slow_seek_forward(dest, &cseg,
- pos, volume, buf);
- break;
- }
- old_seg = new_seg;
- limit = volume->end_seg;
- fast_seek_trials ++;
- for (;;) {
- result = search_valid_segment(new_seg, limit,
- volume->size,
- pos, &cseg,
- volume, buf);
- if (result == 0 || result == -EINTR) {
- break;
- }
- if (new_seg == volume->start_seg) {
- result = -EIO; /* set errror
- * condition
- */
- break;
- }
- limit = new_seg;
- new_seg -= ZFT_FAST_SEEK_BACKUP;
- if (new_seg < volume->start_seg) {
- new_seg = volume->start_seg;
- }
- }
- if (result < 0) {
- TRACE(ft_t_warn,
- "Couldn't find a readable segment");
- break;
- }
- } else /* if (distance < 0) */ {
- if (seg_dist > 0) {
- TRACE(ft_t_bug, "BUG: distance %d < 0, "
- "segment difference %d >0",
- distance, seg_dist);
- result = -EIO;
- break;
- }
- new_seg = pos->seg_pos + seg_dist;
- if (fast_seek_trials > 0 && seg_dist == 0) {
- /* this avoids sticking to the same
- * segment all the time. On the other hand:
- * if we got here for the first time, and the
- * deblock_buffer still contains a valid
- * segment, then there is no need to skip to
- * the previous segment if the desired position
- * is inside this segment.
- */
- new_seg --;
- }
- if (new_seg < volume->start_seg) {
- new_seg = volume->start_seg;
- }
- limit = pos->seg_pos;
- fast_seek_trials ++;
- for (;;) {
- result = search_valid_segment(new_seg, limit,
- pos->volume_pos,
- pos, &cseg,
- volume, buf);
- if (result == 0 || result == -EINTR) {
- break;
- }
- if (new_seg == volume->start_seg) {
- result = -EIO; /* set errror
- * condition
- */
- break;
- }
- limit = new_seg;
- new_seg -= ZFT_FAST_SEEK_BACKUP;
- if (new_seg < volume->start_seg) {
- new_seg = volume->start_seg;
- }
- }
- if (result < 0) {
- TRACE(ft_t_warn,
- "Couldn't find a readable segment");
- break;
- }
- }
- distance = dest - (pos->volume_pos >> 10);
- }
- TRACE_EXIT result;
-}
-
-
-/* advance inside the given segment at most to_do bytes.
- * of kilobytes moved
- */
-
-static int seek_in_segment(const unsigned int to_do,
- cmpr_info *c_info,
- const char *src_buf,
- const int seg_sz,
- const int seg_pos,
- const zft_volinfo *volume)
-{
- int result = 0;
- int blk_sz = volume->blk_sz >> 10;
- int remaining = to_do;
- TRACE_FUN(ft_t_flow);
-
- if (c_info->offset == 0) {
- /* new segment just read
- */
- TRACE_CATCH(get_cseg(c_info, src_buf, seg_sz, volume),);
- c_info->cmpr_pos += c_info->count;
- DUMP_CMPR_INFO(ft_t_noise, "", c_info);
- }
- /* loop and uncompress until user buffer full or
- * deblock-buffer empty
- */
- TRACE(ft_t_noise, "compressed_sz: %d, compos : %d",
- c_info->cmpr_sz, c_info->cmpr_pos);
- while (c_info->spans == 0 && remaining > 0) {
- if (c_info->cmpr_pos != 0) { /* cmpr buf is not empty */
- result += blk_sz;
- remaining -= blk_sz;
- c_info->cmpr_pos = 0;
- }
- if (remaining > 0) {
- get_next_cluster(c_info, src_buf, seg_sz,
- volume->end_seg == seg_pos);
- if (c_info->count != 0) {
- c_info->cmpr_pos = c_info->count;
- c_info->offset += c_info->count;
- } else {
- break;
- }
- }
- /* Allow escape from this loop on signal!
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- DUMP_CMPR_INFO(ft_t_noise, "", c_info);
- TRACE(ft_t_noise, "to_do: %d", remaining);
- }
- if (seg_sz - c_info->offset <= 18) {
- c_info->offset = seg_sz;
- }
- TRACE(ft_t_noise, "\n"
- KERN_INFO "segment size : %d\n"
- KERN_INFO "buf_pos_read : %d\n"
- KERN_INFO "remaining : %d",
- seg_sz, c_info->offset,
- seg_sz - c_info->offset);
- TRACE_EXIT result;
-}
-
-static int slow_seek_forward_until_error(const unsigned int distance,
- cmpr_info *c_info,
- zft_position *pos,
- const zft_volinfo *volume,
- __u8 *buf)
-{
- unsigned int remaining = distance;
- int seg_sz;
- int seg_pos;
- int result;
- TRACE_FUN(ft_t_flow);
-
- seg_pos = pos->seg_pos;
- do {
- TRACE_CATCH(seg_sz = zft_fetch_segment(seg_pos, buf,
- FT_RD_AHEAD),);
- /* now we have the contents of the actual segment in
- * the deblock buffer
- */
- TRACE_CATCH(result = seek_in_segment(remaining, c_info, buf,
- seg_sz, seg_pos,volume),);
- remaining -= result;
- pos->volume_pos += result<<10;
- pos->seg_pos = seg_pos;
- pos->seg_byte_pos = c_info->offset;
- seg_pos ++;
- if (seg_pos <= volume->end_seg && c_info->offset == seg_sz) {
- pos->seg_pos ++;
- pos->seg_byte_pos = 0;
- c_info->offset = 0;
- }
- /* Allow escape from this loop on signal!
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- TRACE(ft_t_noise, "\n"
- KERN_INFO "remaining: %d\n"
- KERN_INFO "seg_pos: %d\n"
- KERN_INFO "end_seg: %d\n"
- KERN_INFO "result: %d",
- remaining, seg_pos, volume->end_seg, result);
- } while (remaining > 0 && seg_pos <= volume->end_seg);
- TRACE_EXIT 0;
-}
-
-/* return segment id of next segment containing valid data, -EIO otherwise
- */
-static int search_valid_segment(unsigned int segment,
- const unsigned int end_seg,
- const unsigned int max_foffs,
- zft_position *pos,
- cmpr_info *c_info,
- const zft_volinfo *volume,
- __u8 *buf)
-{
- cmpr_info tmp_info;
- int seg_sz;
- TRACE_FUN(ft_t_flow);
-
- memset(&tmp_info, 0, sizeof(cmpr_info));
- while (segment <= end_seg) {
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- TRACE(ft_t_noise,
- "Searching readable segment between %d and %d",
- segment, end_seg);
- seg_sz = zft_fetch_segment(segment, buf, FT_RD_AHEAD);
- if ((seg_sz > 0) &&
- (get_cseg (&tmp_info, buf, seg_sz, volume) >= 0) &&
- (tmp_info.foffs != 0 || segment == volume->start_seg)) {
- if ((tmp_info.foffs>>10) > max_foffs) {
- TRACE_ABORT(-EIO, ft_t_noise, "\n"
- KERN_INFO "cseg.foff: %d\n"
- KERN_INFO "dest : %d",
- (int)(tmp_info.foffs >> 10),
- max_foffs);
- }
- DUMP_CMPR_INFO(ft_t_noise, "", &tmp_info);
- *c_info = tmp_info;
- pos->seg_pos = segment;
- pos->volume_pos = c_info->foffs;
- pos->seg_byte_pos = c_info->offset;
- TRACE(ft_t_noise, "found segment at %d", segment);
- TRACE_EXIT 0;
- }
- segment++;
- }
- TRACE_EXIT -EIO;
-}
-
-static int slow_seek_forward(unsigned int dest,
- cmpr_info *c_info,
- zft_position *pos,
- const zft_volinfo *volume,
- __u8 *buf)
-{
- unsigned int distance;
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- distance = dest - (pos->volume_pos >> 10);
- while ((distance > 0) &&
- (result = slow_seek_forward_until_error(distance,
- c_info,
- pos,
- volume,
- buf)) < 0) {
- if (result == -EINTR) {
- break;
- }
- TRACE(ft_t_noise, "seg_pos: %d", pos->seg_pos);
- /* the failing segment is either pos->seg_pos or
- * pos->seg_pos + 1. There is no need to further try
- * that segment, because ftape_read_segment() already
- * has tried very much to read it. So we start with
- * following segment, which is pos->seg_pos + 1
- */
- if(search_valid_segment(pos->seg_pos+1, volume->end_seg, dest,
- pos, c_info,
- volume, buf) < 0) {
- TRACE(ft_t_noise, "search_valid_segment() failed");
- result = -EIO;
- break;
- }
- distance = dest - (pos->volume_pos >> 10);
- result = 0;
- TRACE(ft_t_noise, "segment: %d", pos->seg_pos);
- /* found valid segment, retry the seek */
- }
- TRACE_EXIT result;
-}
-
-static int compute_seg_pos(const unsigned int dest,
- zft_position *pos,
- const zft_volinfo *volume)
-{
- int segment;
- int distance = dest - (pos->volume_pos >> 10);
- unsigned int raw_size;
- unsigned int virt_size;
- unsigned int factor;
- TRACE_FUN(ft_t_flow);
-
- if (distance >= 0) {
- raw_size = volume->end_seg - pos->seg_pos + 1;
- virt_size = ((unsigned int)(volume->size>>10)
- - (unsigned int)(pos->volume_pos>>10)
- + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
- virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
- if (virt_size == 0 || raw_size == 0) {
- TRACE_EXIT 0;
- }
- if (raw_size >= (1<<25)) {
- factor = raw_size/(virt_size>>7);
- } else {
- factor = (raw_size<<7)/virt_size;
- }
- segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
- segment = (segment * factor)>>7;
- } else {
- raw_size = pos->seg_pos - volume->start_seg + 1;
- virt_size = ((unsigned int)(pos->volume_pos>>10)
- + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);
- virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;
- if (virt_size == 0 || raw_size == 0) {
- TRACE_EXIT 0;
- }
- if (raw_size >= (1<<25)) {
- factor = raw_size/(virt_size>>7);
- } else {
- factor = (raw_size<<7)/virt_size;
- }
- segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);
- }
- TRACE(ft_t_noise, "factor: %d/%d", factor, 1<<7);
- TRACE_EXIT segment;
-}
-
-static struct zft_cmpr_ops cmpr_ops = {
- zftc_write,
- zftc_read,
- zftc_seek,
- zftc_lock,
- zftc_reset,
- zftc_cleanup
-};
-
-int zft_compressor_init(void)
-{
- TRACE_FUN(ft_t_flow);
-
-#ifdef MODULE
- printk(KERN_INFO "zftape compressor v1.00a 970514 for " FTAPE_VERSION "\n");
- if (TRACE_LEVEL >= ft_t_info) {
- printk(
-KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
- }
-#else /* !MODULE */
- /* print a short no-nonsense boot message */
- printk(KERN_INFO "zftape compressor v1.00a 970514\n");
- printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
-#endif /* MODULE */
- TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
- TRACE(ft_t_info, "installing compressor for zftape ...");
- TRACE_CATCH(zft_cmpr_register(&cmpr_ops),);
- TRACE_EXIT 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR(
- "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de");
-MODULE_DESCRIPTION(
-"Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams");
-MODULE_LICENSE("GPL");
-
-/* Called by modules package when installing the driver
- */
-int init_module(void)
-{
- return zft_compressor_init();
-}
-
-#endif /* MODULE */
diff --git a/drivers/char/ftape/compressor/zftape-compress.h b/drivers/char/ftape/compressor/zftape-compress.h
deleted file mode 100644
index f200741e33bf..000000000000
--- a/drivers/char/ftape/compressor/zftape-compress.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef _ZFTAPE_COMPRESS_H
-#define _ZFTAPE_COMPRESS_H
-/*
- * Copyright (c) 1994-1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/compressor/zftape-compress.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/10/05 19:12:32 $
- *
- * This file contains macros and definitions for zftape's
- * builtin compression code.
- *
- */
-
-#include "../zftape/zftape-buffers.h"
-#include "../zftape/zftape-vtbl.h"
-#include "../compressor/lzrw3.h"
-
-/* CMPR_WRK_MEM_SIZE gives the size of the compression wrk_mem */
-/* I got these out of lzrw3.c */
-#define U(X) ((__u32) X)
-#define SIZE_P_BYTE (U(sizeof(__u8 *)))
-#define ALIGNMENT_FUDGE (U(16))
-
-#define CMPR_WRK_MEM_SIZE (U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE)
-
-/* the maximum number of bytes the size of the "compressed" data can
- * exceed the uncompressed data. As it is quite useless to compress
- * data twice it is sometimes the case that it is more efficient to
- * copy a block of data but to feed it to the "compression"
- * algorithm. In this case there are some flag bytes or the like
- * proceding the "compressed" data. THAT MUST NOT BE THE CASE for the
- * algorithm we use for this driver. Instead, the high bit 15 of
- * compressed_size:
- *
- * compressed_size = ftape_compress()
- *
- * must be set in such a case.
- *
- * Nevertheless, it might also be as for lzrw3 that there is an
- * "intermediate" overrun that exceeds the amount of the compressed
- * data that is actually produced. During the algorithm we need in the
- * worst case MAX_CMP_GROUP bytes more than the input-size.
- */
-#define MAX_CMP_GROUP (2+16*2) /* from lzrw3.c */
-
-#define CMPR_OVERRUN MAX_CMP_GROUP /* during compression */
-
-/****************************************************/
-
-#define CMPR_BUFFER_SIZE (MAX_BLOCK_SIZE + CMPR_OVERRUN)
-
-/* the compression map stores the byte offset compressed blocks within
- * the current volume for catridges with format code 2,3 and 5
- * (and old versions of zftape) and the offset measured in kilobytes for
- * format code 4 and 6. This gives us a possible max. size of a
- * compressed volume of 1024*4GIG which should be enough.
- */
-typedef __u32 CmprMap;
-
-/* globals
- */
-
-/* exported functions
- */
-
-#endif /* _ZFTAPE_COMPRESS_H */
diff --git a/drivers/char/ftape/lowlevel/Makefile b/drivers/char/ftape/lowlevel/Makefile
deleted file mode 100644
index febab07ba427..000000000000
--- a/drivers/char/ftape/lowlevel/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Copyright (C) 1996, 1997 Clau-Justus Heine.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/07 09:26:02 $
-#
-# Makefile for the lowlevel part QIC-40/80/3010/3020 floppy-tape
-# driver for Linux.
-#
-
-obj-$(CONFIG_FTAPE) += ftape.o
-
-ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \
- ftape-bsm.o ftape-ctl.o ftape-read.o ftape-rw.o \
- ftape-write.o ftape-io.o ftape-calibr.o ftape-ecc.o fc-10.o \
- ftape-buffer.o ftape-format.o ftape_syms.o
-
-ifeq ($(CONFIG_FTAPE),y)
-ftape-objs += ftape-setup.o
-endif
-
-ifndef CONFIG_FT_NO_TRACE_AT_ALL
-ftape-objs += ftape-tracing.o
-endif
-
-ifeq ($(CONFIG_FT_PROC_FS),y)
-ftape-objs += ftape-proc.o
-endif
diff --git a/drivers/char/ftape/lowlevel/fc-10.c b/drivers/char/ftape/lowlevel/fc-10.c
deleted file mode 100644
index 9bc1cddade76..000000000000
--- a/drivers/char/ftape/lowlevel/fc-10.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *
-
- Copyright (C) 1993,1994 Jon Tombs.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- The entire guts of this program was written by dosemu, modified to
- record reads and writes to the ports in the 0x180-0x188 address space,
- while running the CMS program TAPE.EXE V2.0.5 supplied with the drive.
-
- Modified to use an array of addresses and generally cleaned up (made
- much shorter) 4 June 94, dosemu isn't that good at writing short code it
- would seem :-). Made independent of 0x180, but I doubt it will work
- at any other address.
-
- Modified for distribution with ftape source. 21 June 94, SJL.
-
- Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu):
- Modified to support different DMA, IRQ, and IO Ports. Borland's
- Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints
- provided by the TDH386.SYS Device Driver) was used on the CMS program
- TAPE V4.0.5. I set breakpoints on I/O to ports 0x180-0x187. Note that
- CMS's program will not successfully configure the tape drive if you set
- breakpoints on IO Reads, but you can set them on IO Writes without problems.
- Known problems:
- - You can not use DMA Channels 5 or 7.
-
- Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu):
- Modified to only accept IRQs 3 - 7, or 9. Since we can only send a 3 bit
- number representing the IRQ to the card, special handling is required when
- IRQ 9 is selected. IRQ 2 and 9 are the same, and we should request IRQ 9
- from the kernel while telling the card to use IRQ 2. Thanks to Greg
- Crider (gcrider@iclnet.org) for finding and locating this bug, as well as
- testing the patch.
-
- Modification on 11 December 96, by Claus Heine (claus@momo.math.rwth-aachen.de):
- Modified a little to use variahle ft_fdc_base, ft_fdc_irq, ft_fdc_dma
- instead of preprocessor symbols. Thus we can compile this into the module
- or kernel and let the user specify the options as command line arguments.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:04 $
- *
- * This file contains code for the CMS FC-10/FC-20 card.
- */
-
-#include <asm/io.h>
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/fc-10.h"
-
-static __u16 inbs_magic[] = {
- 0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
- 0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
- 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
-};
-
-static __u16 fc10_ports[] = {
- 0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
-};
-
-int fc10_enable(void)
-{
- int i;
- __u8 cardConfig = 0x00;
- __u8 x;
- TRACE_FUN(ft_t_flow);
-
-/* This code will only work if the FC-10 (or FC-20) is set to
- * use DMA channels 1, 2, or 3. DMA channels 5 and 7 seem to be
- * initialized by the same command as channels 1 and 3, respectively.
- */
- if (ft_fdc_dma > 3) {
- TRACE_ABORT(0, ft_t_err,
-"Error: The FC-10/20 must be set to use DMA channels 1, 2, or 3!");
- }
-/* Only allow the FC-10/20 to use IRQ 3-7, or 9. Note that CMS's program
- * only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9.
- */
- if (ft_fdc_irq < 3 || ft_fdc_irq == 8 || ft_fdc_irq > 9) {
- TRACE_ABORT(0, ft_t_err,
-"Error: The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!\n"
-KERN_INFO "Note: IRQ 9 is the same as IRQ 2");
- }
- /* Clear state machine ???
- */
- for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
- inb(ft_fdc_base + inbs_magic[i]);
- }
- outb(0x0, ft_fdc_base);
-
- x = inb(ft_fdc_base);
- if (x == 0x13 || x == 0x93) {
- for (i = 1; i < 8; i++) {
- if (inb(ft_fdc_base + i) != x) {
- TRACE_EXIT 0;
- }
- }
- } else {
- TRACE_EXIT 0;
- }
-
- outb(0x8, ft_fdc_base);
-
- for (i = 0; i < 8; i++) {
- if (inb(ft_fdc_base + i) != 0x0) {
- TRACE_EXIT 0;
- }
- }
- outb(0x10, ft_fdc_base);
-
- for (i = 0; i < 8; i++) {
- if (inb(ft_fdc_base + i) != 0xff) {
- TRACE_EXIT 0;
- }
- }
-
- /* Okay, we found a FC-10 card ! ???
- */
- outb(0x0, fdc.ccr);
-
- /* Clear state machine again ???
- */
- for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
- inb(ft_fdc_base + inbs_magic[i]);
- }
- /* Send io port */
- for (i = 0; i < NR_ITEMS(fc10_ports); i++)
- if (ft_fdc_base == fc10_ports[i])
- cardConfig = i + 1;
- if (cardConfig == 0) {
- TRACE_EXIT 0; /* Invalid I/O Port */
- }
- /* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */
- if (ft_fdc_irq != 9)
- cardConfig |= ft_fdc_irq << 3;
- else
- cardConfig |= 2 << 3;
-
- /* and finally DMA Channel */
- cardConfig |= ft_fdc_dma << 6;
- outb(cardConfig, ft_fdc_base); /* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */
-
- /* Enable FC-10 ???
- */
- outb(0, fdc.ccr);
- outb(0, fdc.dor2);
- outb(FDC_DMA_MODE /* 8 */, fdc.dor);
- outb(FDC_DMA_MODE /* 8 */, fdc.dor);
- outb(1, fdc.dor2);
-
- /*************************************
- *
- * cH: why the hell should this be necessary? This is done
- * by fdc_reset()!!!
- *
- *************************************/
- /* Initialize fdc, select drive B:
- */
- outb(FDC_DMA_MODE, fdc.dor); /* assert reset, dma & irq enabled */
- /* 0x08 */
- outb(FDC_DMA_MODE|FDC_RESET_NOT, fdc.dor); /* release reset */
- /* 0x08 | 0x04 = 0x0c */
- outb(FDC_DMA_MODE|FDC_RESET_NOT|FDC_MOTOR_1|FTAPE_SEL_B, fdc.dor);
- /* 0x08 | 0x04 | 0x20 | 0x01 = 0x2d */
- /* select drive 1 */ /* why not drive 0 ???? */
- TRACE_EXIT (x == 0x93) ? 2 : 1;
-}
diff --git a/drivers/char/ftape/lowlevel/fc-10.h b/drivers/char/ftape/lowlevel/fc-10.h
deleted file mode 100644
index da7b88bca889..000000000000
--- a/drivers/char/ftape/lowlevel/fc-10.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _FC_10_H
-#define _FC_10_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/09/19 09:05:22 $
- *
- * This file contains definitions for the FC-10 code
- * of the QIC-40/80 floppy-tape driver for Linux.
- */
-
-/*
- * fc-10.c defined global vars.
- */
-
-/*
- * fc-10.c defined global functions.
- */
-extern int fc10_enable(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
deleted file mode 100644
index bbcf918f056f..000000000000
--- a/drivers/char/ftape/lowlevel/fdc-io.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.c,v $
- * $Revision: 1.7.4.2 $
- * $Date: 1997/11/16 14:48:17 $
- *
- * This file contains the low-level floppy disk interface code
- * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- * Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/fdc-isr.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/fc-10.h"
-
-/* Global vars.
- */
-static int ftape_motor;
-volatile int ftape_current_cylinder = -1;
-volatile fdc_mode_enum fdc_mode = fdc_idle;
-fdc_config_info fdc;
-DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr);
-
-unsigned int ft_fdc_base = CONFIG_FT_FDC_BASE;
-unsigned int ft_fdc_irq = CONFIG_FT_FDC_IRQ;
-unsigned int ft_fdc_dma = CONFIG_FT_FDC_DMA;
-unsigned int ft_fdc_threshold = CONFIG_FT_FDC_THR; /* bytes */
-unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */
-int ft_probe_fc10 = CONFIG_FT_PROBE_FC10;
-int ft_mach2 = CONFIG_FT_MACH2;
-
-/* Local vars.
- */
-static spinlock_t fdc_io_lock;
-static unsigned int fdc_calibr_count;
-static unsigned int fdc_calibr_time;
-static int fdc_status;
-volatile __u8 fdc_head; /* FDC head from sector id */
-volatile __u8 fdc_cyl; /* FDC track from sector id */
-volatile __u8 fdc_sect; /* FDC sector from sector id */
-static int fdc_data_rate = 500; /* data rate (Kbps) */
-static int fdc_rate_code; /* data rate code (0 == 500 Kbps) */
-static int fdc_seek_rate = 2; /* step rate (msec) */
-static void (*do_ftape) (void);
-static int fdc_fifo_state; /* original fifo setting - fifo enabled */
-static int fdc_fifo_thr; /* original fifo setting - threshold */
-static int fdc_lock_state; /* original lock setting - locked */
-static int fdc_fifo_locked; /* has fifo && lock set ? */
-static __u8 fdc_precomp; /* default precomp. value (nsec) */
-static __u8 fdc_prec_code; /* fdc precomp. select code */
-
-static char ftape_id[] = "ftape"; /* used by request irq and free irq */
-
-static int fdc_set_seek_rate(int seek_rate);
-
-void fdc_catch_stray_interrupts(int count)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fdc_io_lock, flags);
- if (count == 0) {
- ft_expected_stray_interrupts = 0;
- } else {
- ft_expected_stray_interrupts += count;
- }
- spin_unlock_irqrestore(&fdc_io_lock, flags);
-}
-
-/* Wait during a timeout period for a given FDC status.
- * If usecs == 0 then just test status, else wait at least for usecs.
- * Returns -ETIME on timeout. Function must be calibrated first !
- */
-static int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
-{
- int count_1 = (fdc_calibr_count * usecs +
- fdc_calibr_count - 1) / fdc_calibr_time;
-
- do {
- fdc_status = inb_p(fdc.msr);
- if ((fdc_status & mask) == state) {
- return 0;
- }
- } while (count_1-- >= 0);
- return -ETIME;
-}
-
-int fdc_ready_wait(unsigned int usecs)
-{
- return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY);
-}
-
-/* Why can't we just use udelay()?
- */
-static void fdc_usec_wait(unsigned int usecs)
-{
- fdc_wait(usecs, 0, 1); /* will always timeout ! */
-}
-
-static int fdc_ready_out_wait(unsigned int usecs)
-{
- fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
- return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
-}
-
-void fdc_wait_calibrate(void)
-{
- ftape_calibrate("fdc_wait",
- fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time);
-}
-
-/* Wait for a (short) while for the FDC to become ready
- * and transfer the next command byte.
- * Return -ETIME on timeout on getting ready (depends on hardware!).
- */
-static int fdc_write(const __u8 data)
-{
- fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
- if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) {
- return -ETIME;
- } else {
- outb(data, fdc.fifo);
- return 0;
- }
-}
-
-/* Wait for a (short) while for the FDC to become ready
- * and transfer the next result byte.
- * Return -ETIME if timeout on getting ready (depends on hardware!).
- */
-static int fdc_read(__u8 * data)
-{
- fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
- if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) {
- return -ETIME;
- } else {
- *data = inb(fdc.fifo);
- return 0;
- }
-}
-
-/* Output a cmd_len long command string to the FDC.
- * The FDC should be ready to receive a new command or
- * an error (EBUSY or ETIME) will occur.
- */
-int fdc_command(const __u8 * cmd_data, int cmd_len)
-{
- int result = 0;
- unsigned long flags;
- int count = cmd_len;
- int retry = 0;
-#ifdef TESTING
- static unsigned int last_time;
- unsigned int time;
-#endif
- TRACE_FUN(ft_t_any);
-
- fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
- spin_lock_irqsave(&fdc_io_lock, flags);
- if (!in_interrupt())
- /* Yes, I know, too much comments inside this function
- * ...
- *
- * Yet another bug in the original driver. All that
- * havoc is caused by the fact that the isr() sends
- * itself a command to the floppy tape driver (pause,
- * micro step pause). Now, the problem is that
- * commands are transmitted via the fdc_seek
- * command. But: the fdc performs seeks in the
- * background i.e. it doesn't signal busy while
- * sending the step pulses to the drive. Therefore the
- * non-interrupt level driver has no chance to tell
- * whether the isr() just has issued a seek. Therefore
- * we HAVE TO have a look at the ft_hide_interrupt
- * flag: it signals the non-interrupt level part of
- * the driver that it has to wait for the fdc until it
- * has completet seeking.
- *
- * THIS WAS PRESUMABLY THE REASON FOR ALL THAT
- * "fdc_read timeout" errors, I HOPE :-)
- */
- if (ft_hide_interrupt) {
- restore_flags(flags);
- TRACE(ft_t_info,
- "Waiting for the isr() completing fdc_seek()");
- if (fdc_interrupt_wait(2 * FT_SECOND) < 0) {
- TRACE(ft_t_warn,
- "Warning: timeout waiting for isr() seek to complete");
- }
- if (ft_hide_interrupt || !ft_seek_completed) {
- /* There cannot be another
- * interrupt. The isr() only stops
- * the tape and the next interrupt
- * won't come until we have send our
- * command to the drive.
- */
- TRACE_ABORT(-EIO, ft_t_bug,
- "BUG? isr() is still seeking?\n"
- KERN_INFO "hide: %d\n"
- KERN_INFO "seek: %d",
- ft_hide_interrupt,
- ft_seek_completed);
-
- }
- fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
- spin_lock_irqsave(&fdc_io_lock, flags);
- }
- fdc_status = inb(fdc.msr);
- if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
- }
- fdc_mode = *cmd_data; /* used by isr */
-#ifdef TESTING
- if (fdc_mode == FDC_SEEK) {
- time = ftape_timediff(last_time, ftape_timestamp());
- if (time < 6000) {
- TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d",
- time);
- }
- }
-#endif
- if (!in_interrupt()) {
- /* shouldn't be cleared if called from isr
- */
- ft_interrupt_seen = 0;
- }
- while (count) {
- result = fdc_write(*cmd_data);
- if (result < 0) {
- TRACE(ft_t_fdc_dma,
- "fdc_mode = %02x, status = %02x at index %d",
- (int) fdc_mode, (int) fdc_status,
- cmd_len - count);
- if (++retry <= 3) {
- TRACE(ft_t_warn, "fdc_write timeout, retry");
- } else {
- TRACE(ft_t_err, "fdc_write timeout, fatal");
- /* recover ??? */
- break;
- }
- } else {
- --count;
- ++cmd_data;
- }
- }
-#ifdef TESTING
- if (fdc_mode == FDC_SEEK) {
- last_time = ftape_timestamp();
- }
-#endif
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- TRACE_EXIT result;
-}
-
-/* Input a res_len long result string from the FDC.
- * The FDC should be ready to send the result or an error
- * (EBUSY or ETIME) will occur.
- */
-int fdc_result(__u8 * res_data, int res_len)
-{
- int result = 0;
- unsigned long flags;
- int count = res_len;
- int retry = 0;
- TRACE_FUN(ft_t_any);
-
- spin_lock_irqsave(&fdc_io_lock, flags);
- fdc_status = inb(fdc.msr);
- if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
- TRACE(ft_t_err, "fdc not ready");
- result = -EBUSY;
- } else while (count) {
- if (!(fdc_status & FDC_BUSY)) {
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
- }
- result = fdc_read(res_data);
- if (result < 0) {
- TRACE(ft_t_fdc_dma,
- "fdc_mode = %02x, status = %02x at index %d",
- (int) fdc_mode,
- (int) fdc_status,
- res_len - count);
- if (++retry <= 3) {
- TRACE(ft_t_warn, "fdc_read timeout, retry");
- } else {
- TRACE(ft_t_err, "fdc_read timeout, fatal");
- /* recover ??? */
- break;
- ++retry;
- }
- } else {
- --count;
- ++res_data;
- }
- }
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- fdc_usec_wait(FT_RQM_DELAY); /* allow FDC to negate BSY */
- TRACE_EXIT result;
-}
-
-/* Handle command and result phases for
- * commands without data phase.
- */
-static int fdc_issue_command(const __u8 * out_data, int out_count,
- __u8 * in_data, int in_count)
-{
- TRACE_FUN(ft_t_any);
-
- if (out_count > 0) {
- TRACE_CATCH(fdc_command(out_data, out_count),);
- }
- /* will take 24 - 30 usec for fdc_sense_drive_status and
- * fdc_sense_interrupt_status commands.
- * 35 fails sometimes (5/9/93 SJL)
- * On a loaded system it incidentally takes longer than
- * this for the fdc to get ready ! ?????? WHY ??????
- * So until we know what's going on use a very long timeout.
- */
- TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),);
- if (in_count > 0) {
- TRACE_CATCH(fdc_result(in_data, in_count),
- TRACE(ft_t_err, "result phase aborted"));
- }
- TRACE_EXIT 0;
-}
-
-/* Wait for FDC interrupt with timeout (in milliseconds).
- * Signals are blocked so the wait will not be aborted.
- * Note: interrupts must be enabled ! (23/05/93 SJL)
- */
-int fdc_interrupt_wait(unsigned int time)
-{
- DECLARE_WAITQUEUE(wait,current);
- sigset_t old_sigmask;
- static int resetting;
- long timeout;
-
- TRACE_FUN(ft_t_fdc_dma);
-
- if (waitqueue_active(&ftape_wait_intr)) {
- TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
- }
- /* timeout time will be up to USPT microseconds too long ! */
- timeout = (1000 * time + FT_USPT - 1) / FT_USPT;
-
- spin_lock_irq(&current->sighand->siglock);
- old_sigmask = current->blocked;
- sigfillset(&current->blocked);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&ftape_wait_intr, &wait);
- while (!ft_interrupt_seen && timeout)
- timeout = schedule_timeout_interruptible(timeout);
-
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = old_sigmask;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- remove_wait_queue(&ftape_wait_intr, &wait);
- /* the following IS necessary. True: as well
- * wake_up_interruptible() as the schedule() set TASK_RUNNING
- * when they wakeup a task, BUT: it may very well be that
- * ft_interrupt_seen is already set to 1 when we enter here
- * in which case schedule() gets never called, and
- * TASK_RUNNING never set. This has the funny effect that we
- * execute all the code until we leave kernel space, but then
- * the task is stopped (a task CANNOT be preempted while in
- * kernel mode. Sending a pair of SIGSTOP/SIGCONT to the
- * tasks wakes it up again. Funny! :-)
- */
- current->state = TASK_RUNNING;
- if (ft_interrupt_seen) { /* woken up by interrupt */
- ft_interrupt_seen = 0;
- TRACE_EXIT 0;
- }
- /* Original comment:
- * In first instance, next statement seems unnecessary since
- * it will be cleared in fdc_command. However, a small part of
- * the software seems to rely on this being cleared here
- * (ftape_close might fail) so stick to it until things get fixed !
- */
- /* My deeply sought of knowledge:
- * Behold NO! It is obvious. fdc_reset() doesn't call fdc_command()
- * but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to
- * be reset here.
- */
- ft_interrupt_seen = 0; /* clear for next call */
- if (!resetting) {
- resetting = 1; /* break infinite recursion if reset fails */
- TRACE(ft_t_any, "cleanup reset");
- fdc_reset();
- resetting = 0;
- }
- TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME;
-}
-
-/* Start/stop drive motor. Enable DMA mode.
- */
-void fdc_motor(int motor)
-{
- int unit = ft_drive_sel;
- int data = unit | FDC_RESET_NOT | FDC_DMA_MODE;
- TRACE_FUN(ft_t_any);
-
- ftape_motor = motor;
- if (ftape_motor) {
- data |= FDC_MOTOR_0 << unit;
- TRACE(ft_t_noise, "turning motor %d on", unit);
- } else {
- TRACE(ft_t_noise, "turning motor %d off", unit);
- }
- if (ft_mach2) {
- outb_p(data, fdc.dor2);
- } else {
- outb_p(data, fdc.dor);
- }
- ftape_sleep(10 * FT_MILLISECOND);
- TRACE_EXIT;
-}
-
-static void fdc_update_dsr(void)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns",
- fdc_data_rate, fdc_precomp);
- if (fdc.type >= i82077) {
- outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr);
- } else {
- outb_p(fdc_rate_code & 0x03, fdc.ccr);
- }
- TRACE_EXIT;
-}
-
-void fdc_set_write_precomp(int precomp)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_noise, "New precomp: %d nsec", precomp);
- fdc_precomp = precomp;
- /* write precompensation can be set in multiples of 41.67 nsec.
- * round the parameter to the nearest multiple and convert it
- * into a fdc setting. Note that 0 means default to the fdc,
- * 7 is used instead of that.
- */
- fdc_prec_code = ((fdc_precomp + 21) / 42) << 2;
- if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) {
- fdc_prec_code = 7 << 2;
- }
- fdc_update_dsr();
- TRACE_EXIT;
-}
-
-/* Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
- */
-static void fdc_set_drive_specs(void)
-{
- __u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
- int result;
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_flow, "Setting of drive specs called");
- if (fdc.type >= i82078_1) {
- cmd[1] = (0 << 5) | (2 << 2);
- cmd[2] = (1 << 5) | (2 << 2);
- cmd[3] = (2 << 5) | (2 << 2);
- cmd[4] = (3 << 5) | (2 << 2);
- result = fdc_command(cmd, NR_ITEMS(cmd));
- if (result < 0) {
- TRACE(ft_t_err, "Setting of drive specs failed");
- }
- }
- TRACE_EXIT;
-}
-
-/* Select clock for fdc, must correspond with tape drive setting !
- * This also influences the fdc timing so we must adjust some values.
- */
-int fdc_set_data_rate(int rate)
-{
- int bad_rate = 0;
- TRACE_FUN(ft_t_any);
-
- /* Select clock for fdc, must correspond with tape drive setting !
- * This also influences the fdc timing so we must adjust some values.
- */
- TRACE(ft_t_fdc_dma, "new rate = %d", rate);
- switch (rate) {
- case 250:
- fdc_rate_code = fdc_data_rate_250;
- break;
- case 500:
- fdc_rate_code = fdc_data_rate_500;
- break;
- case 1000:
- if (fdc.type < i82077) {
- bad_rate = 1;
- } else {
- fdc_rate_code = fdc_data_rate_1000;
- }
- break;
- case 2000:
- if (fdc.type < i82078_1) {
- bad_rate = 1;
- } else {
- fdc_rate_code = fdc_data_rate_2000;
- }
- break;
- default:
- bad_rate = 1;
- }
- if (bad_rate) {
- TRACE_ABORT(-EIO,
- ft_t_fdc_dma, "%d is not a valid data rate", rate);
- }
- fdc_data_rate = rate;
- fdc_update_dsr();
- fdc_set_seek_rate(fdc_seek_rate); /* clock changed! */
- ftape_udelay(1000);
- TRACE_EXIT 0;
-}
-
-/* keep the unit select if keep_select is != 0,
- */
-static void fdc_dor_reset(int keep_select)
-{
- __u8 fdc_ctl = ft_drive_sel;
-
- if (keep_select != 0) {
- fdc_ctl |= FDC_DMA_MODE;
- if (ftape_motor) {
- fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel;
- }
- }
- ftape_udelay(10); /* ??? but seems to be necessary */
- if (ft_mach2) {
- outb_p(fdc_ctl & 0x0f, fdc.dor);
- outb_p(fdc_ctl, fdc.dor2);
- } else {
- outb_p(fdc_ctl, fdc.dor);
- }
- fdc_usec_wait(10); /* delay >= 14 fdc clocks */
- if (keep_select == 0) {
- fdc_ctl = 0;
- }
- fdc_ctl |= FDC_RESET_NOT;
- if (ft_mach2) {
- outb_p(fdc_ctl & 0x0f, fdc.dor);
- outb_p(fdc_ctl, fdc.dor2);
- } else {
- outb_p(fdc_ctl, fdc.dor);
- }
-}
-
-/* Reset the floppy disk controller. Leave the ftape_unit selected.
- */
-void fdc_reset(void)
-{
- int st0;
- int i;
- int dummy;
- unsigned long flags;
- TRACE_FUN(ft_t_any);
-
- spin_lock_irqsave(&fdc_io_lock, flags);
-
- fdc_dor_reset(1); /* keep unit selected */
-
- fdc_mode = fdc_idle;
-
- /* maybe the spin_lock_irq* pair is not necessary, BUT:
- * the following line MUST be here. Otherwise fdc_interrupt_wait()
- * won't wait. Note that fdc_reset() is called from
- * ftape_dumb_stop() when the fdc is busy transferring data. In this
- * case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries
- * to get the result bytes from the fdc etc. CLASH.
- */
- ft_interrupt_seen = 0;
-
- /* Program data rate
- */
- fdc_update_dsr(); /* restore data rate and precomp */
-
- spin_unlock_irqrestore(&fdc_io_lock, flags);
-
- /*
- * Wait for first polling cycle to complete
- */
- if (fdc_interrupt_wait(1 * FT_SECOND) < 0) {
- TRACE(ft_t_err, "no drive polling interrupt!");
- } else { /* clear all disk-changed statuses */
- for (i = 0; i < 4; ++i) {
- if(fdc_sense_interrupt_status(&st0, &dummy) != 0) {
- TRACE(ft_t_err, "sense failed for %d", i);
- }
- if (i == ft_drive_sel) {
- ftape_current_cylinder = dummy;
- }
- }
- TRACE(ft_t_noise, "drive polling completed");
- }
- /*
- * SPECIFY COMMAND
- */
- fdc_set_seek_rate(fdc_seek_rate);
- /*
- * DRIVE SPECIFICATION COMMAND (if fdc type known)
- */
- if (fdc.type >= i82078_1) {
- fdc_set_drive_specs();
- }
- TRACE_EXIT;
-}
-
-#if !defined(CLK_48MHZ)
-# define CLK_48MHZ 1
-#endif
-
-/* When we're done, put the fdc into reset mode so that the regular
- * floppy disk driver will figure out that something is wrong and
- * initialize the controller the way it wants.
- */
-void fdc_disable(void)
-{
- __u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00};
- __u8 cmd2[] = {FDC_LOCK};
- __u8 cmd3[] = {FDC_UNLOCK};
- __u8 stat[1];
- TRACE_FUN(ft_t_flow);
-
- if (!fdc_fifo_locked) {
- fdc_reset();
- TRACE_EXIT;
- }
- if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) {
- fdc_dor_reset(0);
- TRACE_ABORT(/**/, ft_t_bug,
- "couldn't unlock fifo, configuration remains changed");
- }
- fdc_fifo_locked = 0;
- if (CLK_48MHZ && fdc.type >= i82078) {
- cmd1[0] |= FDC_CLK48_BIT;
- }
- cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1);
- if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) {
- fdc_dor_reset(0);
- TRACE_ABORT(/**/, ft_t_bug,
- "couldn't reconfigure fifo to old state");
- }
- if (fdc_lock_state &&
- fdc_issue_command(cmd2, 1, stat, 1) < 0) {
- fdc_dor_reset(0);
- TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again");
- }
- TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked",
- fdc_fifo_state ? "en" : "dis",
- fdc_fifo_thr, (fdc_lock_state) ? "" : "not ");
- fdc_dor_reset(0);
- TRACE_EXIT;
-}
-
-/* Specify FDC seek-rate (milliseconds)
- */
-static int fdc_set_seek_rate(int seek_rate)
-{
- /* set step rate, dma mode, and minimal head load and unload times
- */
- __u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)};
-
- fdc_seek_rate = seek_rate;
- in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4;
-
- return fdc_command(in, 3);
-}
-
-/* Sense drive status: get unit's drive status (ST3)
- */
-int fdc_sense_drive_status(int *st3)
-{
- __u8 out[2];
- __u8 in[1];
- TRACE_FUN(ft_t_any);
-
- out[0] = FDC_SENSED;
- out[1] = ft_drive_sel;
- TRACE_CATCH(fdc_issue_command(out, 2, in, 1),);
- *st3 = in[0];
- TRACE_EXIT 0;
-}
-
-/* Sense Interrupt Status command:
- * should be issued at the end of each seek.
- * get ST0 and current cylinder.
- */
-int fdc_sense_interrupt_status(int *st0, int *current_cylinder)
-{
- __u8 out[1];
- __u8 in[2];
- TRACE_FUN(ft_t_any);
-
- out[0] = FDC_SENSEI;
- TRACE_CATCH(fdc_issue_command(out, 1, in, 2),);
- *st0 = in[0];
- *current_cylinder = in[1];
- TRACE_EXIT 0;
-}
-
-/* step to track
- */
-int fdc_seek(int track)
-{
- __u8 out[3];
- int st0, pcn;
-#ifdef TESTING
- unsigned int time;
-#endif
- TRACE_FUN(ft_t_any);
-
- out[0] = FDC_SEEK;
- out[1] = ft_drive_sel;
- out[2] = track;
-#ifdef TESTING
- time = ftape_timestamp();
-#endif
- /* We really need this command to work !
- */
- ft_seek_completed = 0;
- TRACE_CATCH(fdc_command(out, 3),
- fdc_reset();
- TRACE(ft_t_noise, "destination was: %d, resetting FDC...",
- track));
- /* Handle interrupts until ft_seek_completed or timeout.
- */
- for (;;) {
- TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
- if (ft_seek_completed) {
- TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
- if ((st0 & ST0_SEEK_END) == 0) {
- TRACE_ABORT(-EIO, ft_t_err,
- "no seek-end after seek completion !??");
- }
- break;
- }
- }
-#ifdef TESTING
- time = ftape_timediff(time, ftape_timestamp()) / abs(track - ftape_current_cylinder);
- if ((time < 900 || time > 3100) && abs(track - ftape_current_cylinder) > 5) {
- TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)",
- time, track - ftape_current_cylinder);
- }
-#endif
- /* Verify whether we issued the right tape command.
- */
- /* Verify that we seek to the proper track. */
- if (pcn != track) {
- TRACE_ABORT(-EIO, ft_t_err, "bad seek..");
- }
- ftape_current_cylinder = track;
- TRACE_EXIT 0;
-}
-
-static int perpend_mode; /* set if fdc is in perpendicular mode */
-
-static int perpend_off(void)
-{
- __u8 perpend[] = {FDC_PERPEND, 0x00};
- TRACE_FUN(ft_t_any);
-
- if (perpend_mode) {
- /* Turn off perpendicular mode */
- perpend[1] = 0x80;
- TRACE_CATCH(fdc_command(perpend, 2),
- TRACE(ft_t_err,"Perpendicular mode exit failed!"));
- perpend_mode = 0;
- }
- TRACE_EXIT 0;
-}
-
-static int handle_perpend(int segment_id)
-{
- __u8 perpend[] = {FDC_PERPEND, 0x00};
- TRACE_FUN(ft_t_any);
-
- /* When writing QIC-3020 tapes, turn on perpendicular mode
- * if tape is moving in forward direction (even tracks).
- */
- if (ft_qic_std == QIC_TAPE_QIC3020 &&
- ((segment_id / ft_segments_per_track) & 1) == 0) {
-/* FIXME: some i82077 seem to support perpendicular mode as
- * well.
- */
-#if 0
- if (fdc.type < i82077AA) {}
-#else
- if (fdc.type < i82077 && ft_data_rate < 1000) {
-#endif
- /* fdc does not support perpendicular mode: complain
- */
- TRACE_ABORT(-EIO, ft_t_err,
- "Your FDC does not support QIC-3020.");
- }
- perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ;
- TRACE_CATCH(fdc_command(perpend, 2),
- TRACE(ft_t_err,"Perpendicular mode entry failed!"));
- TRACE(ft_t_flow, "Perpendicular mode set");
- perpend_mode = 1;
- TRACE_EXIT 0;
- }
- TRACE_EXIT perpend_off();
-}
-
-static inline void fdc_setup_dma(char mode,
- volatile void *addr, unsigned int count)
-{
- /* Program the DMA controller.
- */
- disable_dma(fdc.dma);
- clear_dma_ff(fdc.dma);
- set_dma_mode(fdc.dma, mode);
- set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
- set_dma_count(fdc.dma, count);
- enable_dma(fdc.dma);
-}
-
-/* Setup fdc and dma for formatting the next segment
- */
-int fdc_setup_formatting(buffer_struct * buff)
-{
- unsigned long flags;
- __u8 out[6] = {
- FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b
- };
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(handle_perpend(buff->segment_id),);
- /* Program the DMA controller.
- */
- TRACE(ft_t_fdc_dma,
- "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
- spin_lock_irqsave(&fdc_io_lock, flags);
- fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
- /* Issue FDC command to start reading/writing.
- */
- out[1] = ft_drive_sel;
- out[4] = buff->gap3;
- TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
- restore_flags(flags); fdc_mode = fdc_idle);
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- TRACE_EXIT 0;
-}
-
-
-/* Setup Floppy Disk Controller and DMA to read or write the next cluster
- * of good sectors from or to the current segment.
- */
-int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
-{
- unsigned long flags;
- __u8 out[9];
- int dma_mode;
- TRACE_FUN(ft_t_any);
-
- switch(operation) {
- case FDC_VERIFY:
- if (fdc.type < i82077) {
- operation = FDC_READ;
- }
- case FDC_READ:
- case FDC_READ_DELETED:
- dma_mode = DMA_MODE_READ;
- TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p",
- buff->sector_count, buff->ptr);
- TRACE_CATCH(perpend_off(),);
- break;
- case FDC_WRITE_DELETED:
- TRACE(ft_t_noise, "deleting segment %d", buff->segment_id);
- case FDC_WRITE:
- dma_mode = DMA_MODE_WRITE;
- /* When writing QIC-3020 tapes, turn on perpendicular mode
- * if tape is moving in forward direction (even tracks).
- */
- TRACE_CATCH(handle_perpend(buff->segment_id),);
- TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p",
- buff->sector_count, buff->ptr);
- break;
- default:
- TRACE_ABORT(-EIO,
- ft_t_bug, "bug: invalid operation parameter");
- }
- TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
- spin_lock_irqsave(&fdc_io_lock, flags);
- if (operation != FDC_VERIFY) {
- fdc_setup_dma(dma_mode, buff->ptr,
- FT_SECTOR_SIZE * buff->sector_count);
- }
- /* Issue FDC command to start reading/writing.
- */
- out[0] = operation;
- out[1] = ft_drive_sel;
- out[2] = buff->cyl;
- out[3] = buff->head;
- out[4] = buff->sect + buff->sector_offset;
- out[5] = 3; /* Sector size of 1K. */
- out[6] = out[4] + buff->sector_count - 1; /* last sector */
- out[7] = 109; /* Gap length. */
- out[8] = 0xff; /* No limit to transfer size. */
- TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
- out[2], out[3], out[4], out[6] - out[4] + 1);
- spin_unlock_irqrestore(&fdc_io_lock, flags);
- TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
- TRACE_EXIT 0;
-}
-
-int fdc_fifo_threshold(__u8 threshold,
- int *fifo_state, int *lock_state, int *fifo_thr)
-{
- const __u8 cmd0[] = {FDC_DUMPREGS};
- __u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0};
- const __u8 cmd2[] = {FDC_LOCK};
- const __u8 cmd3[] = {FDC_UNLOCK};
- __u8 reg[10];
- __u8 stat;
- int i;
- int result;
- TRACE_FUN(ft_t_any);
-
- if (CLK_48MHZ && fdc.type >= i82078) {
- cmd1[0] |= FDC_CLK48_BIT;
- }
- /* Dump fdc internal registers for examination
- */
- TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)),
- TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged"));
- /* Now read fdc internal registers from fifo
- */
- for (i = 0; i < (int)NR_ITEMS(reg); ++i) {
- fdc_read(&reg[i]);
- TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]);
- }
- if (fifo_state && lock_state && fifo_thr) {
- *fifo_state = (reg[8] & 0x20) == 0;
- *lock_state = reg[7] & 0x80;
- *fifo_thr = 1 + (reg[8] & 0x0f);
- }
- TRACE(ft_t_noise,
- "original fifo state: %sabled, threshold %d, %slocked",
- ((reg[8] & 0x20) == 0) ? "en" : "dis",
- 1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not ");
- /* If fdc is already locked, unlock it first ! */
- if (reg[7] & 0x80) {
- fdc_ready_wait(100);
- TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1),
- TRACE(ft_t_bug, "FDC unlock command failed, "
- "configuration unchanged"));
- }
- fdc_fifo_locked = 0;
- /* Enable fifo and set threshold at xx bytes to allow a
- * reasonably large latency and reduce number of dma bursts.
- */
- fdc_ready_wait(100);
- if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) {
- TRACE(ft_t_bug, "configure cmd failed, fifo unchanged");
- }
- /* Now lock configuration so reset will not change it
- */
- if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 ||
- stat != 0x10) {
- TRACE_ABORT(-EIO, ft_t_bug,
- "FDC lock command failed, stat = 0x%02x", stat);
- }
- fdc_fifo_locked = 1;
- TRACE_EXIT result;
-}
-
-static int fdc_fifo_enable(void)
-{
- TRACE_FUN(ft_t_any);
-
- if (fdc_fifo_locked) {
- TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked");
- }
- TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
- &fdc_fifo_state,
- &fdc_lock_state,
- &fdc_fifo_thr),);
- TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
- NULL, NULL, NULL),);
- TRACE_EXIT 0;
-}
-
-/* Determine fd controller type
- */
-static __u8 fdc_save_state[2];
-
-static int fdc_probe(void)
-{
- __u8 cmd[1];
- __u8 stat[16]; /* must be able to hold dumpregs & save results */
- int i;
- TRACE_FUN(ft_t_any);
-
- /* Try to find out what kind of fd controller we have to deal with
- * Scheme borrowed from floppy driver:
- * first try if FDC_DUMPREGS command works
- * (this indicates that we have a 82072 or better)
- * then try the FDC_VERSION command (82072 doesn't support this)
- * then try the FDC_UNLOCK command (some older 82077's don't support this)
- * then try the FDC_PARTID command (82078's support this)
- */
- cmd[0] = FDC_DUMPREGS;
- if (fdc_issue_command(cmd, 1, stat, 1) != 0) {
- TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found");
- }
- if (stat[0] == 0x80) {
- /* invalid command: must be pre 82072 */
- TRACE_ABORT(i8272,
- ft_t_warn, "Type 8272A/765A compatible FDC found");
- }
- fdc_result(&stat[1], 9);
- fdc_save_state[0] = stat[7];
- fdc_save_state[1] = stat[8];
- cmd[0] = FDC_VERSION;
- if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
- TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found");
- }
- if (*stat != 0x90) {
- TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found");
- }
- cmd[0] = FDC_UNLOCK;
- if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) {
- TRACE_ABORT(i8272, ft_t_warn,
- "Type pre-1991 82077 FDC found, "
- "treating it like a 82072");
- }
- if (fdc_save_state[0] & 0x80) { /* was locked */
- cmd[0] = FDC_LOCK; /* restore lock */
- (void)fdc_issue_command(cmd, 1, stat, 1);
- TRACE(ft_t_warn, "FDC is already locked");
- }
- /* Test for a i82078 FDC */
- cmd[0] = FDC_PARTID;
- if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
- /* invalid command: not a i82078xx type FDC */
- for (i = 0; i < 4; ++i) {
- outb_p(i, fdc.tdr);
- if ((inb_p(fdc.tdr) & 0x03) != i) {
- TRACE_ABORT(i82077,
- ft_t_warn, "Type 82077 FDC found");
- }
- }
- TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found");
- }
- /* FDC_PARTID cmd succeeded */
- switch (stat[0] >> 5) {
- case 0x0:
- /* i82078SL or i82078-1. The SL part cannot run at
- * 2Mbps (the SL and -1 dies are identical; they are
- * speed graded after production, according to Intel).
- * Some SL's can be detected by doing a SAVE cmd and
- * look at bit 7 of the first byte (the SEL3V# bit).
- * If it is 0, the part runs off 3Volts, and hence it
- * is a SL.
- */
- cmd[0] = FDC_SAVE;
- if(fdc_issue_command(cmd, 1, stat, 16) < 0) {
- TRACE(ft_t_err, "FDC_SAVE failed. Dunno why");
- /* guess we better claim the fdc to be a i82078 */
- TRACE_ABORT(i82078,
- ft_t_warn,
- "Type i82078 FDC (i suppose) found");
- }
- if ((stat[0] & FDC_SEL3V_BIT)) {
- /* fdc running off 5Volts; Pray that it's a i82078-1
- */
- TRACE_ABORT(i82078_1, ft_t_warn,
- "Type i82078-1 or 5Volt i82078SL FDC found");
- }
- TRACE_ABORT(i82078, ft_t_warn,
- "Type 3Volt i82078SL FDC (1Mbps) found");
- case 0x1:
- case 0x2: /* S82078B */
- /* The '78B isn't '78 compatible. Detect it as a '77AA */
- TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found");
- case 0x3: /* NSC PC8744 core; used in several super-IO chips */
- TRACE_ABORT(i82077AA,
- ft_t_warn, "Type 82077AA compatible FDC found");
- default:
- TRACE(ft_t_warn, "A previously undetected FDC found");
- TRACE_ABORT(i82077AA, ft_t_warn,
- "Treating it as a 82077AA. Please report partid= %d",
- stat[0]);
- } /* switch(stat[ 0] >> 5) */
- TRACE_EXIT no_fdc;
-}
-
-static int fdc_request_regions(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (ft_mach2 || ft_probe_fc10) {
- if (!request_region(fdc.sra, 8, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
- TRACE_EXIT -EBUSY;
-#else
- TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
-#endif
- }
- } else {
- if (!request_region(fdc.sra, 6, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
- TRACE_EXIT -EBUSY;
-#else
- TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
-#endif
- }
- if (!request_region(fdc.sra + 7, 1, "fdc (ft)")) {
-#ifndef BROKEN_FLOPPY_DRIVER
- release_region(fdc.sra, 6);
- TRACE_EXIT -EBUSY;
-#else
- TRACE(ft_t_warn,
-"address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra + 7);
-#endif
- }
- }
- TRACE_EXIT 0;
-}
-
-void fdc_release_regions(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (fdc.sra != 0) {
- if (fdc.dor2 != 0) {
- release_region(fdc.sra, 8);
- } else {
- release_region(fdc.sra, 6);
- release_region(fdc.dir, 1);
- }
- }
- TRACE_EXIT;
-}
-
-static int fdc_config_regs(unsigned int fdc_base,
- unsigned int fdc_irq,
- unsigned int fdc_dma)
-{
- TRACE_FUN(ft_t_flow);
-
- fdc.irq = fdc_irq;
- fdc.dma = fdc_dma;
- fdc.sra = fdc_base;
- fdc.srb = fdc_base + 1;
- fdc.dor = fdc_base + 2;
- fdc.tdr = fdc_base + 3;
- fdc.msr = fdc.dsr = fdc_base + 4;
- fdc.fifo = fdc_base + 5;
- fdc.dir = fdc.ccr = fdc_base + 7;
- fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0;
- TRACE_CATCH(fdc_request_regions(), fdc.sra = 0);
- TRACE_EXIT 0;
-}
-
-static int fdc_config(void)
-{
- static int already_done;
- TRACE_FUN(ft_t_any);
-
- if (already_done) {
- TRACE_CATCH(fdc_request_regions(),);
- *(fdc.hook) = fdc_isr; /* hook our handler in */
- TRACE_EXIT 0;
- }
- if (ft_probe_fc10) {
- int fc_type;
-
- TRACE_CATCH(fdc_config_regs(ft_fdc_base,
- ft_fdc_irq, ft_fdc_dma),);
- fc_type = fc10_enable();
- if (fc_type != 0) {
- TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type);
- fdc.type = fc10;
- fdc.hook = &do_ftape;
- *(fdc.hook) = fdc_isr; /* hook our handler in */
- already_done = 1;
- TRACE_EXIT 0;
- } else {
- TRACE(ft_t_warn, "FC-10/20 controller not found");
- fdc_release_regions();
- fdc.type = no_fdc;
- ft_probe_fc10 = 0;
- ft_fdc_base = 0x3f0;
- ft_fdc_irq = 6;
- ft_fdc_dma = 2;
- }
- }
- TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d",
- ft_fdc_base, ft_fdc_irq, ft_fdc_dma);
- TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),);
- fdc.hook = &do_ftape;
- *(fdc.hook) = fdc_isr; /* hook our handler in */
- already_done = 1;
- TRACE_EXIT 0;
-}
-
-static irqreturn_t ftape_interrupt(int irq, void *dev_id)
-{
- void (*handler) (void) = *fdc.hook;
- int handled = 0;
- TRACE_FUN(ft_t_any);
-
- *fdc.hook = NULL;
- if (handler) {
- handled = 1;
- handler();
- } else {
- TRACE(ft_t_bug, "Unexpected ftape interrupt");
- }
- TRACE_EXIT IRQ_RETVAL(handled);
-}
-
-static int fdc_grab_irq_and_dma(void)
-{
- TRACE_FUN(ft_t_any);
-
- if (fdc.hook == &do_ftape) {
- /* Get fast interrupt handler.
- */
- if (request_irq(fdc.irq, ftape_interrupt,
- IRQF_DISABLED, "ft", ftape_id)) {
- TRACE_ABORT(-EIO, ft_t_bug,
- "Unable to grab IRQ%d for ftape driver",
- fdc.irq);
- }
- if (request_dma(fdc.dma, ftape_id)) {
- free_irq(fdc.irq, ftape_id);
- TRACE_ABORT(-EIO, ft_t_bug,
- "Unable to grab DMA%d for ftape driver",
- fdc.dma);
- }
- }
- if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
- /* Using same dma channel or irq as standard fdc, need
- * to disable the dma-gate on the std fdc. This
- * couldn't be done in the floppy driver as some
- * laptops are using the dma-gate to enter a low power
- * or even suspended state :-(
- */
- outb_p(FDC_RESET_NOT, 0x3f2);
- TRACE(ft_t_noise, "DMA-gate on standard fdc disabled");
- }
- TRACE_EXIT 0;
-}
-
-int fdc_release_irq_and_dma(void)
-{
- TRACE_FUN(ft_t_any);
-
- if (fdc.hook == &do_ftape) {
- disable_dma(fdc.dma); /* just in case... */
- free_dma(fdc.dma);
- free_irq(fdc.irq, ftape_id);
- }
- if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
- /* Using same dma channel as standard fdc, need to
- * disable the dma-gate on the std fdc. This couldn't
- * be done in the floppy driver as some laptops are
- * using the dma-gate to enter a low power or even
- * suspended state :-(
- */
- outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2);
- TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again");
- }
- TRACE_EXIT 0;
-}
-
-int fdc_init(void)
-{
- TRACE_FUN(ft_t_any);
-
- /* find a FDC to use */
- TRACE_CATCH(fdc_config(),);
- TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions());
- ftape_motor = 0;
- fdc_catch_stray_interrupts(0); /* clear number of awainted
- * stray interrupte
- */
- fdc_catch_stray_interrupts(1); /* one always comes (?) */
- TRACE(ft_t_flow, "resetting fdc");
- fdc_set_seek_rate(2); /* use nominal QIC step rate */
- fdc_reset(); /* init fdc & clear track counters */
- if (fdc.type == no_fdc) { /* no FC-10 or FC-20 found */
- fdc.type = fdc_probe();
- fdc_reset(); /* update with new knowledge */
- }
- if (fdc.type == no_fdc) {
- fdc_release_irq_and_dma();
- fdc_release_regions();
- TRACE_EXIT -ENXIO;
- }
- if (fdc.type >= i82077) {
- if (fdc_fifo_enable() < 0) {
- TRACE(ft_t_warn, "couldn't enable fdc fifo !");
- } else {
- TRACE(ft_t_flow, "fdc fifo enabled and locked");
- }
- }
- TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/fdc-io.h b/drivers/char/ftape/lowlevel/fdc-io.h
deleted file mode 100644
index 7ec3c72178bb..000000000000
--- a/drivers/char/ftape/lowlevel/fdc-io.h
+++ /dev/null
@@ -1,252 +0,0 @@
-#ifndef _FDC_IO_H
-#define _FDC_IO_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.h,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:18:06 $
- *
- * This file contains the declarations for the low level
- * functions that communicate with the floppy disk controller,
- * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- * Linux.
- */
-
-#include <linux/fdreg.h>
-
-#include "../lowlevel/ftape-bsm.h"
-
-#define FDC_SK_BIT (0x20)
-#define FDC_MT_BIT (0x80)
-
-#define FDC_READ (FD_READ & ~(FDC_SK_BIT | FDC_MT_BIT))
-#define FDC_WRITE (FD_WRITE & ~FDC_MT_BIT)
-#define FDC_READ_DELETED (0x4c)
-#define FDC_WRITE_DELETED (0x49)
-#define FDC_VERIFY (0x56)
-#define FDC_READID (0x4a)
-#define FDC_SENSED (0x04)
-#define FDC_SENSEI (FD_SENSEI)
-#define FDC_FORMAT (FD_FORMAT)
-#define FDC_RECAL (FD_RECALIBRATE)
-#define FDC_SEEK (FD_SEEK)
-#define FDC_SPECIFY (FD_SPECIFY)
-#define FDC_RECALIBR (FD_RECALIBRATE)
-#define FDC_VERSION (FD_VERSION)
-#define FDC_PERPEND (FD_PERPENDICULAR)
-#define FDC_DUMPREGS (FD_DUMPREGS)
-#define FDC_LOCK (FD_LOCK)
-#define FDC_UNLOCK (FD_UNLOCK)
-#define FDC_CONFIGURE (FD_CONFIGURE)
-#define FDC_DRIVE_SPEC (0x8e) /* i82078 has this (any others?) */
-#define FDC_PARTID (0x18) /* i82078 has this */
-#define FDC_SAVE (0x2e) /* i82078 has this (any others?) */
-#define FDC_RESTORE (0x4e) /* i82078 has this (any others?) */
-
-#define FDC_STATUS_MASK (STATUS_BUSY | STATUS_DMA | STATUS_DIR | STATUS_READY)
-#define FDC_DATA_READY (STATUS_READY)
-#define FDC_DATA_OUTPUT (STATUS_DIR)
-#define FDC_DATA_READY_MASK (STATUS_READY | STATUS_DIR)
-#define FDC_DATA_OUT_READY (STATUS_READY | STATUS_DIR)
-#define FDC_DATA_IN_READY (STATUS_READY)
-#define FDC_BUSY (STATUS_BUSY)
-#define FDC_CLK48_BIT (0x80)
-#define FDC_SEL3V_BIT (0x40)
-
-#define ST0_INT_MASK (ST0_INTR)
-#define FDC_INT_NORMAL (ST0_INTR & 0x00)
-#define FDC_INT_ABNORMAL (ST0_INTR & 0x40)
-#define FDC_INT_INVALID (ST0_INTR & 0x80)
-#define FDC_INT_READYCH (ST0_INTR & 0xC0)
-#define ST0_SEEK_END (ST0_SE)
-#define ST3_TRACK_0 (ST3_TZ)
-
-#define FDC_RESET_NOT (0x04)
-#define FDC_DMA_MODE (0x08)
-#define FDC_MOTOR_0 (0x10)
-#define FDC_MOTOR_1 (0x20)
-
-typedef struct {
- void (**hook) (void); /* our wedge into the isr */
- enum {
- no_fdc, i8272, i82077, i82077AA, fc10,
- i82078, i82078_1
- } type; /* FDC type */
- unsigned int irq; /* FDC irq nr */
- unsigned int dma; /* FDC dma channel nr */
- __u16 sra; /* Status register A (PS/2 only) */
- __u16 srb; /* Status register B (PS/2 only) */
- __u16 dor; /* Digital output register */
- __u16 tdr; /* Tape Drive Register (82077SL-1 &
- 82078 only) */
- __u16 msr; /* Main Status Register */
- __u16 dsr; /* Datarate Select Register (8207x only) */
- __u16 fifo; /* Data register / Fifo on 8207x */
- __u16 dir; /* Digital Input Register */
- __u16 ccr; /* Configuration Control Register */
- __u16 dor2; /* Alternate dor on MACH-2 controller,
- also used with FC-10, meaning unknown */
-} fdc_config_info;
-
-typedef enum {
- fdc_data_rate_250 = 2,
- fdc_data_rate_300 = 1, /* any fdc in default configuration */
- fdc_data_rate_500 = 0,
- fdc_data_rate_1000 = 3,
- fdc_data_rate_2000 = 1, /* i82078-1: when using Data Rate Table #2 */
-} fdc_data_rate_type;
-
-typedef enum {
- fdc_idle = 0,
- fdc_reading_data = FDC_READ,
- fdc_seeking = FDC_SEEK,
- fdc_writing_data = FDC_WRITE,
- fdc_deleting = FDC_WRITE_DELETED,
- fdc_reading_id = FDC_READID,
- fdc_recalibrating = FDC_RECAL,
- fdc_formatting = FDC_FORMAT,
- fdc_verifying = FDC_VERIFY
-} fdc_mode_enum;
-
-typedef enum {
- waiting = 0,
- reading,
- writing,
- formatting,
- verifying,
- deleting,
- done,
- error,
- mmapped,
-} buffer_state_enum;
-
-typedef struct {
- __u8 *address;
- volatile buffer_state_enum status;
- volatile __u8 *ptr;
- volatile unsigned int bytes;
- volatile unsigned int segment_id;
-
- /* bitmap for remainder of segment not yet handled.
- * one bit set for each bad sector that must be skipped.
- */
- volatile SectorMap bad_sector_map;
-
- /* bitmap with bad data blocks in data buffer.
- * the errors in this map may be retried.
- */
- volatile SectorMap soft_error_map;
-
- /* bitmap with bad data blocks in data buffer
- * the errors in this map may not be retried.
- */
- volatile SectorMap hard_error_map;
-
- /* retry counter for soft errors.
- */
- volatile int retry;
-
- /* sectors to skip on retry ???
- */
- volatile unsigned int skip;
-
- /* nr of data blocks in data buffer
- */
- volatile unsigned int data_offset;
-
- /* offset in segment for first sector to be handled.
- */
- volatile unsigned int sector_offset;
-
- /* size of cluster of good sectors to be handled.
- */
- volatile unsigned int sector_count;
-
- /* size of remaining part of segment to be handled.
- */
- volatile unsigned int remaining;
-
- /* points to next segment (contiguous) to be handled,
- * or is zero if no read-ahead is allowed.
- */
- volatile unsigned int next_segment;
-
- /* flag being set if deleted data was read.
- */
- volatile int deleted;
-
- /* floppy coordinates of first sector in segment */
- volatile __u8 head;
- volatile __u8 cyl;
- volatile __u8 sect;
-
- /* gap to use when formatting */
- __u8 gap3;
- /* flag set when buffer is mmaped */
- int mmapped;
-} buffer_struct;
-
-/*
- * fdc-io.c defined public variables
- */
-extern volatile fdc_mode_enum fdc_mode;
-extern int fdc_setup_error; /* outdated ??? */
-extern wait_queue_head_t ftape_wait_intr;
-extern volatile int ftape_current_cylinder; /* track nr FDC thinks we're on */
-extern volatile __u8 fdc_head; /* FDC head */
-extern volatile __u8 fdc_cyl; /* FDC track */
-extern volatile __u8 fdc_sect; /* FDC sector */
-extern fdc_config_info fdc; /* FDC hardware configuration */
-
-extern unsigned int ft_fdc_base;
-extern unsigned int ft_fdc_irq;
-extern unsigned int ft_fdc_dma;
-extern unsigned int ft_fdc_threshold;
-extern unsigned int ft_fdc_rate_limit;
-extern int ft_probe_fc10;
-extern int ft_mach2;
-/*
- * fdc-io.c defined public functions
- */
-extern void fdc_catch_stray_interrupts(int count);
-extern int fdc_ready_wait(unsigned int timeout);
-extern int fdc_command(const __u8 * cmd_data, int cmd_len);
-extern int fdc_result(__u8 * res_data, int res_len);
-extern int fdc_interrupt_wait(unsigned int time);
-extern int fdc_seek(int track);
-extern int fdc_sense_drive_status(int *st3);
-extern void fdc_motor(int motor);
-extern void fdc_reset(void);
-extern void fdc_disable(void);
-extern int fdc_fifo_threshold(__u8 threshold,
- int *fifo_state, int *lock_state, int *fifo_thr);
-extern void fdc_wait_calibrate(void);
-extern int fdc_sense_interrupt_status(int *st0, int *current_cylinder);
-extern void fdc_save_drive_specs(void);
-extern void fdc_restore_drive_specs(void);
-extern int fdc_set_data_rate(int rate);
-extern void fdc_set_write_precomp(int precomp);
-extern int fdc_release_irq_and_dma(void);
-extern void fdc_release_regions(void);
-extern int fdc_init(void);
-extern int fdc_setup_read_write(buffer_struct * buff, __u8 operation);
-extern int fdc_setup_formatting(buffer_struct * buff);
-#endif
diff --git a/drivers/char/ftape/lowlevel/fdc-isr.c b/drivers/char/ftape/lowlevel/fdc-isr.c
deleted file mode 100644
index ad2bc733ae1b..000000000000
--- a/drivers/char/ftape/lowlevel/fdc-isr.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.c,v $
- * $Revision: 1.9 $
- * $Date: 1997/10/17 23:01:53 $
- *
- * This file contains the interrupt service routine and
- * associated code for the QIC-40/80/3010/3020 floppy-tape driver
- * "ftape" for Linux.
- */
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define volatile /* */
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-isr.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/* Global vars.
- */
-volatile int ft_expected_stray_interrupts;
-volatile int ft_interrupt_seen;
-volatile int ft_seek_completed;
-volatile int ft_hide_interrupt;
-/* Local vars.
- */
-typedef enum {
- no_error = 0, id_am_error = 0x01, id_crc_error = 0x02,
- data_am_error = 0x04, data_crc_error = 0x08,
- no_data_error = 0x10, overrun_error = 0x20,
-} error_cause;
-static int stop_read_ahead;
-
-
-static void print_error_cause(int cause)
-{
- TRACE_FUN(ft_t_any);
-
- switch (cause) {
- case no_data_error:
- TRACE(ft_t_noise, "no data error");
- break;
- case id_am_error:
- TRACE(ft_t_noise, "id am error");
- break;
- case id_crc_error:
- TRACE(ft_t_noise, "id crc error");
- break;
- case data_am_error:
- TRACE(ft_t_noise, "data am error");
- break;
- case data_crc_error:
- TRACE(ft_t_noise, "data crc error");
- break;
- case overrun_error:
- TRACE(ft_t_noise, "overrun error");
- break;
- default:;
- }
- TRACE_EXIT;
-}
-
-static char *fdc_mode_txt(fdc_mode_enum mode)
-{
- switch (mode) {
- case fdc_idle:
- return "fdc_idle";
- case fdc_reading_data:
- return "fdc_reading_data";
- case fdc_seeking:
- return "fdc_seeking";
- case fdc_writing_data:
- return "fdc_writing_data";
- case fdc_reading_id:
- return "fdc_reading_id";
- case fdc_recalibrating:
- return "fdc_recalibrating";
- case fdc_formatting:
- return "fdc_formatting";
- case fdc_verifying:
- return "fdc_verifying";
- default:
- return "unknown";
- }
-}
-
-static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[])
-{
- error_cause cause = no_error;
- TRACE_FUN(ft_t_any);
-
- /* Valid st[], decode cause of interrupt.
- */
- switch (st[0] & ST0_INT_MASK) {
- case FDC_INT_NORMAL:
- TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode));
- break;
- case FDC_INT_ABNORMAL:
- TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode));
- TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x",
- st[0], st[1], st[2]);
- TRACE(ft_t_fdc_dma,
- "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x",
- st[3], st[4], st[5], st[6]);
- if (st[1] & 0x01) {
- if (st[2] & 0x01) {
- cause = data_am_error;
- } else {
- cause = id_am_error;
- }
- } else if (st[1] & 0x20) {
- if (st[2] & 0x20) {
- cause = data_crc_error;
- } else {
- cause = id_crc_error;
- }
- } else if (st[1] & 0x04) {
- cause = no_data_error;
- } else if (st[1] & 0x10) {
- cause = overrun_error;
- }
- print_error_cause(cause);
- break;
- case FDC_INT_INVALID:
- TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode));
- break;
- case FDC_INT_READYCH:
- if (st[0] & ST0_SEEK_END) {
- TRACE(ft_t_flow, "drive poll completed");
- } else {
- TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode));
- }
- break;
- default:
- break;
- }
- TRACE_EXIT cause;
-}
-
-static void update_history(error_cause cause)
-{
- switch (cause) {
- case id_am_error:
- ft_history.id_am_errors++;
- break;
- case id_crc_error:
- ft_history.id_crc_errors++;
- break;
- case data_am_error:
- ft_history.data_am_errors++;
- break;
- case data_crc_error:
- ft_history.data_crc_errors++;
- break;
- case overrun_error:
- ft_history.overrun_errors++;
- break;
- case no_data_error:
- ft_history.no_data_errors++;
- break;
- default:;
- }
-}
-
-static void skip_bad_sector(buffer_struct * buff)
-{
- TRACE_FUN(ft_t_any);
-
- /* Mark sector as soft error and skip it
- */
- if (buff->remaining > 0) {
- ++buff->sector_offset;
- ++buff->data_offset;
- --buff->remaining;
- buff->ptr += FT_SECTOR_SIZE;
- buff->bad_sector_map >>= 1;
- } else {
- /* Hey, what is this????????????? C code: if we shift
- * more than 31 bits, we get no shift. That's bad!!!!!!
- */
- ++buff->sector_offset; /* hack for error maps */
- TRACE(ft_t_warn, "skipping last sector in segment");
- }
- TRACE_EXIT;
-}
-
-static void update_error_maps(buffer_struct * buff, unsigned int error_offset)
-{
- int hard = 0;
- TRACE_FUN(ft_t_any);
-
- if (buff->retry < FT_SOFT_RETRIES) {
- buff->soft_error_map |= (1 << error_offset);
- } else {
- buff->hard_error_map |= (1 << error_offset);
- buff->soft_error_map &= ~buff->hard_error_map;
- buff->retry = -1; /* will be set to 0 in setup_segment */
- hard = 1;
- }
- TRACE(ft_t_noise, "sector %d : %s error\n"
- KERN_INFO "hard map: 0x%08lx\n"
- KERN_INFO "soft map: 0x%08lx",
- FT_SECTOR(error_offset), hard ? "hard" : "soft",
- (long) buff->hard_error_map, (long) buff->soft_error_map);
- TRACE_EXIT;
-}
-
-static void print_progress(buffer_struct *buff, error_cause cause)
-{
- TRACE_FUN(ft_t_any);
-
- switch (cause) {
- case no_error:
- TRACE(ft_t_flow,"%d Sector(s) transferred", buff->sector_count);
- break;
- case no_data_error:
- TRACE(ft_t_flow, "Sector %d not found",
- FT_SECTOR(buff->sector_offset));
- break;
- case overrun_error:
- /* got an overrun error on the first byte, must be a
- * hardware problem
- */
- TRACE(ft_t_bug,
- "Unexpected error: failing DMA or FDC controller ?");
- break;
- case data_crc_error:
- TRACE(ft_t_flow, "Error in sector %d",
- FT_SECTOR(buff->sector_offset - 1));
- break;
- case id_crc_error:
- case id_am_error:
- case data_am_error:
- TRACE(ft_t_flow, "Error in sector %d",
- FT_SECTOR(buff->sector_offset));
- break;
- default:
- TRACE(ft_t_flow, "Unexpected error at sector %d",
- FT_SECTOR(buff->sector_offset));
- break;
- }
- TRACE_EXIT;
-}
-
-/*
- * Error cause: Amount xferred: Action:
- *
- * id_am_error 0 mark bad and skip
- * id_crc_error 0 mark bad and skip
- * data_am_error 0 mark bad and skip
- * data_crc_error % 1024 mark bad and skip
- * no_data_error 0 retry on write
- * mark bad and skip on read
- * overrun_error [ 0..all-1 ] mark bad and skip
- * no_error all continue
- */
-
-/* the arg `sector' is returned by the fdc and tells us at which sector we
- * are positioned at (relative to starting sector of segment)
- */
-static void determine_verify_progress(buffer_struct *buff,
- error_cause cause,
- __u8 sector)
-{
- TRACE_FUN(ft_t_any);
-
- if (cause == no_error && sector == 1) {
- buff->sector_offset = FT_SECTORS_PER_SEGMENT;
- buff->remaining = 0;
- if (TRACE_LEVEL >= ft_t_flow) {
- print_progress(buff, cause);
- }
- } else {
- buff->sector_offset = sector - buff->sect;
- buff->remaining = FT_SECTORS_PER_SEGMENT - buff->sector_offset;
- TRACE(ft_t_noise, "%ssector offset: 0x%04x",
- (cause == no_error) ? "unexpected " : "",
- buff->sector_offset);
- switch (cause) {
- case overrun_error:
- break;
-#if 0
- case no_data_error:
- buff->retry = FT_SOFT_RETRIES;
- if (buff->hard_error_map &&
- buff->sector_offset > 1 &&
- (buff->hard_error_map &
- (1 << (buff->sector_offset-2)))) {
- buff->retry --;
- }
- break;
-#endif
- default:
- buff->retry = FT_SOFT_RETRIES;
- break;
- }
- if (TRACE_LEVEL >= ft_t_flow) {
- print_progress(buff, cause);
- }
- /* Sector_offset points to the problem area Now adjust
- * sector_offset so it always points one past he failing
- * sector. I.e. skip the bad sector.
- */
- ++buff->sector_offset;
- --buff->remaining;
- update_error_maps(buff, buff->sector_offset - 1);
- }
- TRACE_EXIT;
-}
-
-static void determine_progress(buffer_struct *buff,
- error_cause cause,
- __u8 sector)
-{
- unsigned int dma_residue;
- TRACE_FUN(ft_t_any);
-
- /* Using less preferred order of disable_dma and
- * get_dma_residue because this seems to fail on at least one
- * system if reversed!
- */
- dma_residue = get_dma_residue(fdc.dma);
- disable_dma(fdc.dma);
- if (cause != no_error || dma_residue != 0) {
- TRACE(ft_t_noise, "%sDMA residue: 0x%04x",
- (cause == no_error) ? "unexpected " : "",
- dma_residue);
- /* adjust to actual value: */
- if (dma_residue == 0) {
- /* this happens sometimes with overrun errors.
- * I don't know whether we could ignore the
- * overrun error. Play save.
- */
- buff->sector_count --;
- } else {
- buff->sector_count -= ((dma_residue +
- (FT_SECTOR_SIZE - 1)) /
- FT_SECTOR_SIZE);
- }
- }
- /* Update var's influenced by the DMA operation.
- */
- if (buff->sector_count > 0) {
- buff->sector_offset += buff->sector_count;
- buff->data_offset += buff->sector_count;
- buff->ptr += (buff->sector_count *
- FT_SECTOR_SIZE);
- buff->remaining -= buff->sector_count;
- buff->bad_sector_map >>= buff->sector_count;
- }
- if (TRACE_LEVEL >= ft_t_flow) {
- print_progress(buff, cause);
- }
- if (cause != no_error) {
- if (buff->remaining == 0) {
- TRACE(ft_t_warn, "foo?\n"
- KERN_INFO "count : %d\n"
- KERN_INFO "offset: %d\n"
- KERN_INFO "soft : %08x\n"
- KERN_INFO "hard : %08x",
- buff->sector_count,
- buff->sector_offset,
- buff->soft_error_map,
- buff->hard_error_map);
- }
- /* Sector_offset points to the problem area, except if we got
- * a data_crc_error. In that case it points one past the
- * failing sector.
- *
- * Now adjust sector_offset so it always points one past he
- * failing sector. I.e. skip the bad sector.
- */
- if (cause != data_crc_error) {
- skip_bad_sector(buff);
- }
- update_error_maps(buff, buff->sector_offset - 1);
- }
- TRACE_EXIT;
-}
-
-static int calc_steps(int cmd)
-{
- if (ftape_current_cylinder > cmd) {
- return ftape_current_cylinder - cmd;
- } else {
- return ftape_current_cylinder + cmd;
- }
-}
-
-static void pause_tape(int retry, int mode)
-{
- int result;
- __u8 out[3] = {FDC_SEEK, ft_drive_sel, 0};
- TRACE_FUN(ft_t_any);
-
- /* We'll use a raw seek command to get the tape to rewind and
- * stop for a retry.
- */
- ++ft_history.rewinds;
- if (qic117_cmds[ftape_current_command].non_intr) {
- TRACE(ft_t_warn, "motion command may be issued too soon");
- }
- if (retry && (mode == fdc_reading_data ||
- mode == fdc_reading_id ||
- mode == fdc_verifying)) {
- ftape_current_command = QIC_MICRO_STEP_PAUSE;
- ftape_might_be_off_track = 1;
- } else {
- ftape_current_command = QIC_PAUSE;
- }
- out[2] = calc_steps(ftape_current_command);
- result = fdc_command(out, 3); /* issue QIC_117 command */
- ftape_current_cylinder = out[ 2];
- if (result < 0) {
- TRACE(ft_t_noise, "qic-pause failed, status = %d", result);
- } else {
- ft_location.known = 0;
- ft_runner_status = idle;
- ft_hide_interrupt = 1;
- ftape_tape_running = 0;
- }
- TRACE_EXIT;
-}
-
-static void continue_xfer(buffer_struct *buff,
- fdc_mode_enum mode,
- unsigned int skip)
-{
- int write = 0;
- TRACE_FUN(ft_t_any);
-
- if (mode == fdc_writing_data || mode == fdc_deleting) {
- write = 1;
- }
- /* This part can be removed if it never happens
- */
- if (skip > 0 &&
- (ft_runner_status != running ||
- (write && (buff->status != writing)) ||
- (!write && (buff->status != reading &&
- buff->status != verifying)))) {
- TRACE(ft_t_err, "unexpected runner/buffer state %d/%d",
- ft_runner_status, buff->status);
- buff->status = error;
- /* finish this buffer: */
- (void)ftape_next_buffer(ft_queue_head);
- ft_runner_status = aborting;
- fdc_mode = fdc_idle;
- } else if (buff->remaining > 0 && ftape_calc_next_cluster(buff) > 0) {
- /* still sectors left in current segment, continue
- * with this segment
- */
- if (fdc_setup_read_write(buff, mode) < 0) {
- /* failed, abort operation
- */
- buff->bytes = buff->ptr - buff->address;
- buff->status = error;
- /* finish this buffer: */
- (void)ftape_next_buffer(ft_queue_head);
- ft_runner_status = aborting;
- fdc_mode = fdc_idle;
- }
- } else {
- /* current segment completed
- */
- unsigned int last_segment = buff->segment_id;
- int eot = ((last_segment + 1) % ft_segments_per_track) == 0;
- unsigned int next = buff->next_segment; /* 0 means stop ! */
-
- buff->bytes = buff->ptr - buff->address;
- buff->status = done;
- buff = ftape_next_buffer(ft_queue_head);
- if (eot) {
- /* finished last segment on current track,
- * can't continue
- */
- ft_runner_status = logical_eot;
- fdc_mode = fdc_idle;
- TRACE_EXIT;
- }
- if (next <= 0) {
- /* don't continue with next segment
- */
- TRACE(ft_t_noise, "no %s allowed, stopping tape",
- (write) ? "write next" : "read ahead");
- pause_tape(0, mode);
- ft_runner_status = idle; /* not quite true until
- * next irq
- */
- TRACE_EXIT;
- }
- /* continue with next segment
- */
- if (buff->status != waiting) {
- TRACE(ft_t_noise, "all input buffers %s, pausing tape",
- (write) ? "empty" : "full");
- pause_tape(0, mode);
- ft_runner_status = idle; /* not quite true until
- * next irq
- */
- TRACE_EXIT;
- }
- if (write && next != buff->segment_id) {
- TRACE(ft_t_noise,
- "segments out of order, aborting write");
- ft_runner_status = do_abort;
- fdc_mode = fdc_idle;
- TRACE_EXIT;
- }
- ftape_setup_new_segment(buff, next, 0);
- if (stop_read_ahead) {
- buff->next_segment = 0;
- stop_read_ahead = 0;
- }
- if (ftape_calc_next_cluster(buff) == 0 ||
- fdc_setup_read_write(buff, mode) != 0) {
- TRACE(ft_t_err, "couldn't start %s-ahead",
- write ? "write" : "read");
- ft_runner_status = do_abort;
- fdc_mode = fdc_idle;
- } else {
- /* keep on going */
- switch (ft_driver_state) {
- case reading: buff->status = reading; break;
- case verifying: buff->status = verifying; break;
- case writing: buff->status = writing; break;
- case deleting: buff->status = deleting; break;
- default:
- TRACE(ft_t_err,
- "BUG: ft_driver_state %d should be one out of "
- "{reading, writing, verifying, deleting}",
- ft_driver_state);
- buff->status = write ? writing : reading;
- break;
- }
- }
- }
- TRACE_EXIT;
-}
-
-static void retry_sector(buffer_struct *buff,
- int mode,
- unsigned int skip)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_noise, "%s error, will retry",
- (mode == fdc_writing_data || mode == fdc_deleting) ? "write" : "read");
- pause_tape(1, mode);
- ft_runner_status = aborting;
- buff->status = error;
- buff->skip = skip;
- TRACE_EXIT;
-}
-
-static unsigned int find_resume_point(buffer_struct *buff)
-{
- int i = 0;
- SectorMap mask;
- SectorMap map;
- TRACE_FUN(ft_t_any);
-
- /* This function is to be called after all variables have been
- * updated to point past the failing sector.
- * If there are any soft errors before the failing sector,
- * find the first soft error and return the sector offset.
- * Otherwise find the last hard error.
- * Note: there should always be at least one hard or soft error !
- */
- if (buff->sector_offset < 1 || buff->sector_offset > 32) {
- TRACE(ft_t_bug, "BUG: sector_offset = %d",
- buff->sector_offset);
- TRACE_EXIT 0;
- }
- if (buff->sector_offset >= 32) { /* C-limitation on shift ! */
- mask = 0xffffffff;
- } else {
- mask = (1 << buff->sector_offset) - 1;
- }
- map = buff->soft_error_map & mask;
- if (map) {
- while ((map & (1 << i)) == 0) {
- ++i;
- }
- TRACE(ft_t_noise, "at sector %d", FT_SECTOR(i));
- } else {
- map = buff->hard_error_map & mask;
- i = buff->sector_offset - 1;
- if (map) {
- while ((map & (1 << i)) == 0) {
- --i;
- }
- TRACE(ft_t_noise, "after sector %d", FT_SECTOR(i));
- ++i; /* first sector after last hard error */
- } else {
- TRACE(ft_t_bug, "BUG: no soft or hard errors");
- }
- }
- TRACE_EXIT i;
-}
-
-/* check possible dma residue when formatting, update position record in
- * buffer struct. This is, of course, modelled after determine_progress(), but
- * we don't need to set up for retries because the format process cannot be
- * interrupted (except at the end of the tape track).
- */
-static int determine_fmt_progress(buffer_struct *buff, error_cause cause)
-{
- unsigned int dma_residue;
- TRACE_FUN(ft_t_any);
-
- /* Using less preferred order of disable_dma and
- * get_dma_residue because this seems to fail on at least one
- * system if reversed!
- */
- dma_residue = get_dma_residue(fdc.dma);
- disable_dma(fdc.dma);
- if (cause != no_error || dma_residue != 0) {
- TRACE(ft_t_info, "DMA residue = 0x%04x", dma_residue);
- fdc_mode = fdc_idle;
- switch(cause) {
- case no_error:
- ft_runner_status = aborting;
- buff->status = idle;
- break;
- case overrun_error:
- /* got an overrun error on the first byte, must be a
- * hardware problem
- */
- TRACE(ft_t_bug,
- "Unexpected error: failing DMA controller ?");
- ft_runner_status = do_abort;
- buff->status = error;
- break;
- default:
- TRACE(ft_t_noise, "Unexpected error at segment %d",
- buff->segment_id);
- ft_runner_status = do_abort;
- buff->status = error;
- break;
- }
- TRACE_EXIT -EIO; /* can only retry entire track in format mode
- */
- }
- /* Update var's influenced by the DMA operation.
- */
- buff->ptr += FT_SECTORS_PER_SEGMENT * 4;
- buff->bytes -= FT_SECTORS_PER_SEGMENT * 4;
- buff->remaining -= FT_SECTORS_PER_SEGMENT;
- buff->segment_id ++; /* done with segment */
- TRACE_EXIT 0;
-}
-
-/*
- * Continue formatting, switch buffers if there is no data left in
- * current buffer. This is, of course, modelled after
- * continue_xfer(), but we don't need to set up for retries because
- * the format process cannot be interrupted (except at the end of the
- * tape track).
- */
-static void continue_formatting(buffer_struct *buff)
-{
- TRACE_FUN(ft_t_any);
-
- if (buff->remaining <= 0) { /* no space left in dma buffer */
- unsigned int next = buff->next_segment;
-
- if (next == 0) { /* end of tape track */
- buff->status = done;
- ft_runner_status = logical_eot;
- fdc_mode = fdc_idle;
- TRACE(ft_t_noise, "Done formatting track %d",
- ft_location.track);
- TRACE_EXIT;
- }
- /*
- * switch to next buffer!
- */
- buff->status = done;
- buff = ftape_next_buffer(ft_queue_head);
-
- if (buff->status != waiting || next != buff->segment_id) {
- goto format_setup_error;
- }
- }
- if (fdc_setup_formatting(buff) < 0) {
- goto format_setup_error;
- }
- buff->status = formatting;
- TRACE(ft_t_fdc_dma, "Formatting segment %d on track %d",
- buff->segment_id, ft_location.track);
- TRACE_EXIT;
- format_setup_error:
- ft_runner_status = do_abort;
- fdc_mode = fdc_idle;
- buff->status = error;
- TRACE(ft_t_err, "Error setting up for segment %d on track %d",
- buff->segment_id, ft_location.track);
- TRACE_EXIT;
-
-}
-
-/* this handles writing, read id, reading and formatting
- */
-static void handle_fdc_busy(buffer_struct *buff)
-{
- static int no_data_error_count;
- int retry = 0;
- error_cause cause;
- __u8 in[7];
- int skip;
- fdc_mode_enum fmode = fdc_mode;
- TRACE_FUN(ft_t_any);
-
- if (fdc_result(in, 7) < 0) { /* better get it fast ! */
- TRACE(ft_t_err,
- "Probably fatal error during FDC Result Phase\n"
- KERN_INFO
- "drive may hang until (power on) reset :-(");
- /* what to do next ????
- */
- TRACE_EXIT;
- }
- cause = decode_irq_cause(fdc_mode, in);
-#ifdef TESTING
- { int i;
- for (i = 0; i < (int)ft_nr_buffers; ++i)
- TRACE(ft_t_any, "buffer[%d] status: %d, segment_id: %d",
- i, ft_buffer[i]->status, ft_buffer[i]->segment_id);
- }
-#endif
- if (fmode == fdc_reading_data && ft_driver_state == verifying) {
- fmode = fdc_verifying;
- }
- switch (fmode) {
- case fdc_verifying:
- if (ft_runner_status == aborting ||
- ft_runner_status == do_abort) {
- TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
- break;
- }
- if (buff->retry > 0) {
- TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
- }
- switch (cause) {
- case no_error:
- no_data_error_count = 0;
- determine_verify_progress(buff, cause, in[5]);
- if (in[2] & 0x40) {
- /* This should not happen when verifying
- */
- TRACE(ft_t_warn,
- "deleted data in segment %d/%d",
- buff->segment_id,
- FT_SECTOR(buff->sector_offset - 1));
- buff->remaining = 0; /* abort transfer */
- buff->hard_error_map = EMPTY_SEGMENT;
- skip = 1;
- } else {
- skip = 0;
- }
- continue_xfer(buff, fdc_mode, skip);
- break;
- case no_data_error:
- no_data_error_count ++;
- case overrun_error:
- retry ++;
- case id_am_error:
- case id_crc_error:
- case data_am_error:
- case data_crc_error:
- determine_verify_progress(buff, cause, in[5]);
- if (cause == no_data_error) {
- if (no_data_error_count >= 2) {
- TRACE(ft_t_warn,
- "retrying because of successive "
- "no data errors");
- no_data_error_count = 0;
- } else {
- retry --;
- }
- } else {
- no_data_error_count = 0;
- }
- if (retry) {
- skip = find_resume_point(buff);
- } else {
- skip = buff->sector_offset;
- }
- if (retry && skip < 32) {
- retry_sector(buff, fdc_mode, skip);
- } else {
- continue_xfer(buff, fdc_mode, skip);
- }
- update_history(cause);
- break;
- default:
- /* Don't know why this could happen
- * but find out.
- */
- determine_verify_progress(buff, cause, in[5]);
- retry_sector(buff, fdc_mode, 0);
- TRACE(ft_t_err, "Error: unexpected error");
- break;
- }
- break;
- case fdc_reading_data:
-#ifdef TESTING
- /* I'm sorry, but: NOBODY ever used this trace
- * messages for ages. I guess that Bas was the last person
- * that ever really used this (thank you, between the lines)
- */
- if (cause == no_error) {
- TRACE(ft_t_flow,"reading segment %d",buff->segment_id);
- } else {
- TRACE(ft_t_noise, "error reading segment %d",
- buff->segment_id);
- TRACE(ft_t_noise, "\n"
- KERN_INFO
- "IRQ:C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x\n"
- KERN_INFO
- "BUF:C: 0x%02x, H: 0x%02x, R: 0x%02x",
- in[3], in[4], in[5], in[6],
- buff->cyl, buff->head, buff->sect);
- }
-#endif
- if (ft_runner_status == aborting ||
- ft_runner_status == do_abort) {
- TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
- break;
- }
- if (buff->bad_sector_map == FAKE_SEGMENT) {
- /* This condition occurs when reading a `fake'
- * sector that's not accessible. Doesn't
- * really matter as we would have ignored it
- * anyway !
- *
- * Chance is that we're past the next segment
- * now, so the next operation may fail and
- * result in a retry.
- */
- buff->remaining = 0; /* skip failing sector */
- /* buff->ptr = buff->address; */
- /* fake success: */
- continue_xfer(buff, fdc_mode, 1);
- /* trace calls are expensive: place them AFTER
- * the real stuff has been done.
- *
- */
- TRACE(ft_t_noise, "skipping empty segment %d (read), size? %d",
- buff->segment_id, buff->ptr - buff->address);
- TRACE_EXIT;
- }
- if (buff->retry > 0) {
- TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
- }
- switch (cause) {
- case no_error:
- determine_progress(buff, cause, in[5]);
- if (in[2] & 0x40) {
- /* Handle deleted data in header segments.
- * Skip segment and force read-ahead.
- */
- TRACE(ft_t_warn,
- "deleted data in segment %d/%d",
- buff->segment_id,
- FT_SECTOR(buff->sector_offset - 1));
- buff->deleted = 1;
- buff->remaining = 0;/*abort transfer */
- buff->soft_error_map |=
- (-1L << buff->sector_offset);
- if (buff->segment_id == 0) {
- /* stop on next segment */
- stop_read_ahead = 1;
- }
- /* force read-ahead: */
- buff->next_segment =
- buff->segment_id + 1;
- skip = (FT_SECTORS_PER_SEGMENT -
- buff->sector_offset);
- } else {
- skip = 0;
- }
- continue_xfer(buff, fdc_mode, skip);
- break;
- case no_data_error:
- /* Tape started too far ahead of or behind the
- * right sector. This may also happen in the
- * middle of a segment !
- *
- * Handle no-data as soft error. If next
- * sector fails too, a retry (with needed
- * reposition) will follow.
- */
- retry ++;
- case id_am_error:
- case id_crc_error:
- case data_am_error:
- case data_crc_error:
- case overrun_error:
- retry += (buff->soft_error_map != 0 ||
- buff->hard_error_map != 0);
- determine_progress(buff, cause, in[5]);
-#if 1 || defined(TESTING)
- if (cause == overrun_error) retry ++;
-#endif
- if (retry) {
- skip = find_resume_point(buff);
- } else {
- skip = buff->sector_offset;
- }
- /* Try to resume with next sector on single
- * errors (let ecc correct it), but retry on
- * no_data (we'll be past the target when we
- * get here so we cannot retry) or on
- * multiple errors (reduce chance on ecc
- * failure).
- */
- /* cH: 23/02/97: if the last sector in the
- * segment was a hard error, then there is
- * no sense in a retry. This occasion seldom
- * occurs but ... @:³²¸`@%&§$
- */
- if (retry && skip < 32) {
- retry_sector(buff, fdc_mode, skip);
- } else {
- continue_xfer(buff, fdc_mode, skip);
- }
- update_history(cause);
- break;
- default:
- /* Don't know why this could happen
- * but find out.
- */
- determine_progress(buff, cause, in[5]);
- retry_sector(buff, fdc_mode, 0);
- TRACE(ft_t_err, "Error: unexpected error");
- break;
- }
- break;
- case fdc_reading_id:
- if (cause == no_error) {
- fdc_cyl = in[3];
- fdc_head = in[4];
- fdc_sect = in[5];
- TRACE(ft_t_fdc_dma,
- "id read: C: 0x%02x, H: 0x%02x, R: 0x%02x",
- fdc_cyl, fdc_head, fdc_sect);
- } else { /* no valid information, use invalid sector */
- fdc_cyl = fdc_head = fdc_sect = 0;
- TRACE(ft_t_flow, "Didn't find valid sector Id");
- }
- fdc_mode = fdc_idle;
- break;
- case fdc_deleting:
- case fdc_writing_data:
-#ifdef TESTING
- if (cause == no_error) {
- TRACE(ft_t_flow, "writing segment %d", buff->segment_id);
- } else {
- TRACE(ft_t_noise, "error writing segment %d",
- buff->segment_id);
- }
-#endif
- if (ft_runner_status == aborting ||
- ft_runner_status == do_abort) {
- TRACE(ft_t_flow, "aborting %s",fdc_mode_txt(fdc_mode));
- break;
- }
- if (buff->retry > 0) {
- TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
- }
- if (buff->bad_sector_map == FAKE_SEGMENT) {
- /* This condition occurs when trying to write to a
- * `fake' sector that's not accessible. Doesn't really
- * matter as it isn't used anyway ! Might be located
- * at wrong segment, then we'll fail on the next
- * segment.
- */
- TRACE(ft_t_noise, "skipping empty segment (write)");
- buff->remaining = 0; /* skip failing sector */
- /* fake success: */
- continue_xfer(buff, fdc_mode, 1);
- break;
- }
- switch (cause) {
- case no_error:
- determine_progress(buff, cause, in[5]);
- continue_xfer(buff, fdc_mode, 0);
- break;
- case no_data_error:
- case id_am_error:
- case id_crc_error:
- case data_am_error:
- case overrun_error:
- update_history(cause);
- determine_progress(buff, cause, in[5]);
- skip = find_resume_point(buff);
- retry_sector(buff, fdc_mode, skip);
- break;
- default:
- if (in[1] & 0x02) {
- TRACE(ft_t_err, "media not writable");
- } else {
- TRACE(ft_t_bug, "unforeseen write error");
- }
- fdc_mode = fdc_idle;
- break;
- }
- break; /* fdc_deleting || fdc_writing_data */
- case fdc_formatting:
- /* The interrupt comes after formatting a segment. We then
- * have to set up QUICKLY for the next segment. But
- * afterwards, there is plenty of time.
- */
- switch (cause) {
- case no_error:
- /* would like to keep most of the formatting stuff
- * outside the isr code, but timing is too critical
- */
- if (determine_fmt_progress(buff, cause) >= 0) {
- continue_formatting(buff);
- }
- break;
- case no_data_error:
- case id_am_error:
- case id_crc_error:
- case data_am_error:
- case overrun_error:
- default:
- determine_fmt_progress(buff, cause);
- update_history(cause);
- if (in[1] & 0x02) {
- TRACE(ft_t_err, "media not writable");
- } else {
- TRACE(ft_t_bug, "unforeseen write error");
- }
- break;
- } /* cause */
- break;
- default:
- TRACE(ft_t_warn, "Warning: unexpected irq during: %s",
- fdc_mode_txt(fdc_mode));
- fdc_mode = fdc_idle;
- break;
- }
- TRACE_EXIT;
-}
-
-/* FDC interrupt service routine.
- */
-void fdc_isr(void)
-{
- static int isr_active;
-#ifdef TESTING
- unsigned int t0 = ftape_timestamp();
-#endif
- TRACE_FUN(ft_t_any);
-
- if (isr_active++) {
- --isr_active;
- TRACE(ft_t_bug, "BUG: nested interrupt, not good !");
- *fdc.hook = fdc_isr; /* hook our handler into the fdc
- * code again
- */
- TRACE_EXIT;
- }
- sti();
- if (inb_p(fdc.msr) & FDC_BUSY) { /* Entering Result Phase */
- ft_hide_interrupt = 0;
- handle_fdc_busy(ftape_get_buffer(ft_queue_head));
- if (ft_runner_status == do_abort) {
- /* cease operation, remember tape position
- */
- TRACE(ft_t_flow, "runner aborting");
- ft_runner_status = aborting;
- ++ft_expected_stray_interrupts;
- }
- } else { /* !FDC_BUSY */
- /* clear interrupt, cause should be gotten by issuing
- * a Sense Interrupt Status command.
- */
- if (fdc_mode == fdc_recalibrating || fdc_mode == fdc_seeking) {
- if (ft_hide_interrupt) {
- int st0;
- int pcn;
-
- if (fdc_sense_interrupt_status(&st0, &pcn) < 0)
- TRACE(ft_t_err,
- "sense interrupt status failed");
- ftape_current_cylinder = pcn;
- TRACE(ft_t_flow, "handled hidden interrupt");
- }
- ft_seek_completed = 1;
- fdc_mode = fdc_idle;
- } else if (!waitqueue_active(&ftape_wait_intr)) {
- if (ft_expected_stray_interrupts == 0) {
- TRACE(ft_t_warn, "unexpected stray interrupt");
- } else {
- TRACE(ft_t_flow, "expected stray interrupt");
- --ft_expected_stray_interrupts;
- }
- } else {
- if (fdc_mode == fdc_reading_data ||
- fdc_mode == fdc_verifying ||
- fdc_mode == fdc_writing_data ||
- fdc_mode == fdc_deleting ||
- fdc_mode == fdc_formatting ||
- fdc_mode == fdc_reading_id) {
- if (inb_p(fdc.msr) & FDC_BUSY) {
- TRACE(ft_t_bug,
- "***** FDC failure, busy too late");
- } else {
- TRACE(ft_t_bug,
- "***** FDC failure, no busy");
- }
- } else {
- TRACE(ft_t_fdc_dma, "awaited stray interrupt");
- }
- }
- ft_hide_interrupt = 0;
- }
- /* Handle sleep code.
- */
- if (!ft_hide_interrupt) {
- ft_interrupt_seen ++;
- if (waitqueue_active(&ftape_wait_intr)) {
- wake_up_interruptible(&ftape_wait_intr);
- }
- } else {
- TRACE(ft_t_flow, "hiding interrupt while %s",
- waitqueue_active(&ftape_wait_intr) ? "waiting":"active");
- }
-#ifdef TESTING
- t0 = ftape_timediff(t0, ftape_timestamp());
- if (t0 >= 1000) {
- /* only tell us about long calls */
- TRACE(ft_t_noise, "isr() duration: %5d usec", t0);
- }
-#endif
- *fdc.hook = fdc_isr; /* hook our handler into the fdc code again */
- --isr_active;
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/fdc-isr.h b/drivers/char/ftape/lowlevel/fdc-isr.h
deleted file mode 100644
index 065aa978942d..000000000000
--- a/drivers/char/ftape/lowlevel/fdc-isr.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _FDC_ISR_H
-#define _FDC_ISR_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:07 $
- *
- * This file declares the global variables necessary to
- * synchronize the interrupt service routine (isr) with the
- * remainder of the QIC-40/80/3010/3020 floppy-tape driver
- * "ftape" for Linux.
- */
-
-/*
- * fdc-isr.c defined public variables
- */
-extern volatile int ft_expected_stray_interrupts; /* masks stray interrupts */
-extern volatile int ft_seek_completed; /* flag set by isr */
-extern volatile int ft_interrupt_seen; /* flag set by isr */
-extern volatile int ft_hide_interrupt; /* flag set by isr */
-
-/*
- * fdc-io.c defined public functions
- */
-extern void fdc_isr(void);
-
-/*
- * A kernel hook that steals one interrupt from the floppy
- * driver (Should be fixed when the new fdc driver gets ready)
- * See the linux kernel source files:
- * drivers/block/floppy.c & drivers/block/blk.h
- * for the details.
- */
-extern void (*do_floppy) (void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-bsm.c b/drivers/char/ftape/lowlevel/ftape-bsm.c
deleted file mode 100644
index d1a301cc344f..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-bsm.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:15:15 $
- *
- * This file contains the bad-sector map handling code for
- * the QIC-117 floppy tape driver for Linux.
- * QIC-40, QIC-80, QIC-3010 and QIC-3020 maps are implemented.
- */
-
-#include <linux/string.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-
-/* Global vars.
- */
-
-/* Local vars.
- */
-static __u8 *bad_sector_map;
-static SectorCount *bsm_hash_ptr;
-
-typedef enum {
- forward, backward
-} mode_type;
-
-#if 0
-static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map);
-#endif
-
-#if 0
-/* fix_tape converts a normal QIC-80 tape into a 'wide' tape.
- * For testing purposes only !
- */
-void fix_tape(__u8 * buffer, ft_format_type new_code)
-{
- static __u8 list[BAD_SECTOR_MAP_SIZE];
- SectorMap *src_ptr = (SectorMap *) list;
- __u8 *dst_ptr = bad_sector_map;
- SectorMap map;
- unsigned int sector = 1;
- int i;
-
- if (format_code != fmt_var && format_code != fmt_big) {
- memcpy(list, bad_sector_map, sizeof(list));
- memset(bad_sector_map, 0, sizeof(bad_sector_map));
- while ((__u8 *) src_ptr - list < sizeof(list)) {
- map = *src_ptr++;
- if (map == EMPTY_SEGMENT) {
- *(SectorMap *) dst_ptr = 0x800000 + sector;
- dst_ptr += 3;
- sector += SECTORS_PER_SEGMENT;
- } else {
- for (i = 0; i < SECTORS_PER_SEGMENT; ++i) {
- if (map & 1) {
- *(SewctorMap *) dst_ptr = sector;
- dst_ptr += 3;
- }
- map >>= 1;
- ++sector;
- }
- }
- }
- }
- bad_sector_map_changed = 1;
- *(buffer + 4) = new_code; /* put new format code */
- if (format_code != fmt_var && new_code == fmt_big) {
- PUT4(buffer, FT_6_HSEG_1, (__u32)GET2(buffer, 6));
- PUT4(buffer, FT_6_HSEG_2, (__u32)GET2(buffer, 8));
- PUT4(buffer, FT_6_FRST_SEG, (__u32)GET2(buffer, 10));
- PUT4(buffer, FT_6_LAST_SEG, (__u32)GET2(buffer, 12));
- memset(buffer+6, '\0', 8);
- }
- format_code = new_code;
-}
-
-#endif
-
-/* given buffer that contains a header segment, find the end of
- * of the bsm list
- */
-__u8 * ftape_find_end_of_bsm_list(__u8 * address)
-{
- __u8 *ptr = address + FT_HEADER_END; /* start of bsm list */
- __u8 *limit = address + FT_SEGMENT_SIZE;
- while (ptr + 2 < limit) {
- if (ptr[0] || ptr[1] || ptr[2]) {
- ptr += 3;
- } else {
- return ptr;
- }
- }
- return NULL;
-}
-
-static inline void put_sector(SectorCount *ptr, unsigned int sector)
-{
- ptr->bytes[0] = sector & 0xff;
- sector >>= 8;
- ptr->bytes[1] = sector & 0xff;
- sector >>= 8;
- ptr->bytes[2] = sector & 0xff;
-}
-
-static inline unsigned int get_sector(SectorCount *ptr)
-{
-#if 1
- unsigned int sector;
-
- sector = ptr->bytes[0];
- sector += ptr->bytes[1] << 8;
- sector += ptr->bytes[2] << 16;
-
- return sector;
-#else
- /* GET4 gets the next four bytes in Intel little endian order
- * and converts them to host byte order and handles unaligned
- * access.
- */
- return (GET4(ptr, 0) & 0x00ffffff); /* back to host byte order */
-#endif
-}
-
-static void bsm_debug_fake(void)
-{
- /* for testing of bad sector handling at end of tape
- */
-#if 0
- ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 3,
- 0x000003e0;
- ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 2,
- 0xff3fffff;
- ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 1,
- 0xffffe000;
-#endif
- /* Enable to test bad sector handling
- */
-#if 0
- ftape_put_bad_sector_entry(30, 0xfffffffe)
- ftape_put_bad_sector_entry(32, 0x7fffffff);
- ftape_put_bad_sector_entry(34, 0xfffeffff);
- ftape_put_bad_sector_entry(36, 0x55555555);
- ftape_put_bad_sector_entry(38, 0xffffffff);
- ftape_put_bad_sector_entry(50, 0xffff0000);
- ftape_put_bad_sector_entry(51, 0xffffffff);
- ftape_put_bad_sector_entry(52, 0xffffffff);
- ftape_put_bad_sector_entry(53, 0x0000ffff);
-#endif
- /* Enable when testing multiple volume tar dumps.
- */
-#if 0
- {
- int i;
-
- for (i = ft_first_data_segment;
- i <= ft_last_data_segment - 7; ++i) {
- ftape_put_bad_sector_entry(i, EMPTY_SEGMENT);
- }
- }
-#endif
- /* Enable when testing bit positions in *_error_map
- */
-#if 0
- {
- int i;
-
- for (i = first_data_segment; i <= last_data_segment; ++i) {
- ftape_put_bad_sector_entry(i,
- ftape_get_bad_sector_entry(i)
- | 0x00ff00ff);
- }
- }
-#endif
-}
-
-static void print_bad_sector_map(void)
-{
- unsigned int good_sectors;
- unsigned int total_bad = 0;
- int i;
- TRACE_FUN(ft_t_flow);
-
- if (ft_format_code == fmt_big ||
- ft_format_code == fmt_var ||
- ft_format_code == fmt_1100ft) {
- SectorCount *ptr = (SectorCount *)bad_sector_map;
- unsigned int sector;
- __u16 *ptr16;
-
- while((sector = get_sector(ptr++)) != 0) {
- if ((ft_format_code == fmt_big ||
- ft_format_code == fmt_var) &&
- sector & 0x800000) {
- total_bad += FT_SECTORS_PER_SEGMENT - 3;
- TRACE(ft_t_noise, "bad segment at sector: %6d",
- sector & 0x7fffff);
- } else {
- ++total_bad;
- TRACE(ft_t_noise, "bad sector: %6d", sector);
- }
- }
- /* Display old ftape's end-of-file marks
- */
- ptr16 = (__u16*)ptr;
- while ((sector = get_unaligned(ptr16++)) != 0) {
- TRACE(ft_t_noise, "Old ftape eof mark: %4d/%2d",
- sector, get_unaligned(ptr16++));
- }
- } else { /* fixed size format */
- for (i = ft_first_data_segment;
- i < (int)(ft_segments_per_track * ft_tracks_per_tape); ++i) {
- SectorMap map = ((SectorMap *) bad_sector_map)[i];
-
- if (map) {
- TRACE(ft_t_noise,
- "bsm for segment %4d: 0x%08x", i, (unsigned int)map);
- total_bad += ((map == EMPTY_SEGMENT)
- ? FT_SECTORS_PER_SEGMENT - 3
- : count_ones(map));
- }
- }
- }
- good_sectors =
- ((ft_segments_per_track * ft_tracks_per_tape - ft_first_data_segment)
- * (FT_SECTORS_PER_SEGMENT - 3)) - total_bad;
- TRACE(ft_t_info, "%d Kb usable on this tape", good_sectors);
- if (total_bad == 0) {
- TRACE(ft_t_info,
- "WARNING: this tape has no bad blocks registered !");
- } else {
- TRACE(ft_t_info, "%d bad sectors", total_bad);
- }
- TRACE_EXIT;
-}
-
-
-void ftape_extract_bad_sector_map(__u8 * buffer)
-{
- TRACE_FUN(ft_t_any);
-
- /* Fill the bad sector map with the contents of buffer.
- */
- if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
- /* QIC-3010/3020 and wide QIC-80 tapes no longer have a failed
- * sector log but use this area to extend the bad sector map.
- */
- bad_sector_map = &buffer[FT_HEADER_END];
- } else {
- /* non-wide QIC-80 tapes have a failed sector log area that
- * mustn't be included in the bad sector map.
- */
- bad_sector_map = &buffer[FT_FSL + FT_FSL_SIZE];
- }
- if (ft_format_code == fmt_1100ft ||
- ft_format_code == fmt_var ||
- ft_format_code == fmt_big) {
- bsm_hash_ptr = (SectorCount *)bad_sector_map;
- } else {
- bsm_hash_ptr = NULL;
- }
- bsm_debug_fake();
- if (TRACE_LEVEL >= ft_t_info) {
- print_bad_sector_map();
- }
- TRACE_EXIT;
-}
-
-static inline SectorMap cvt2map(unsigned int sector)
-{
- return 1 << (((sector & 0x7fffff) - 1) % FT_SECTORS_PER_SEGMENT);
-}
-
-static inline int cvt2segment(unsigned int sector)
-{
- return ((sector & 0x7fffff) - 1) / FT_SECTORS_PER_SEGMENT;
-}
-
-static int forward_seek_entry(int segment_id,
- SectorCount **ptr,
- SectorMap *map)
-{
- unsigned int sector;
- int segment;
-
- do {
- sector = get_sector((*ptr)++);
- segment = cvt2segment(sector);
- } while (sector != 0 && segment < segment_id);
- (*ptr) --; /* point to first sector >= segment_id */
- /* Get all sectors in segment_id
- */
- if (sector == 0 || segment != segment_id) {
- *map = 0;
- return 0;
- } else if ((sector & 0x800000) &&
- (ft_format_code == fmt_var || ft_format_code == fmt_big)) {
- *map = EMPTY_SEGMENT;
- return FT_SECTORS_PER_SEGMENT;
- } else {
- int count = 1;
- SectorCount *tmp_ptr = (*ptr) + 1;
-
- *map = cvt2map(sector);
- while ((sector = get_sector(tmp_ptr++)) != 0 &&
- (segment = cvt2segment(sector)) == segment_id) {
- *map |= cvt2map(sector);
- ++count;
- }
- return count;
- }
-}
-
-static int backwards_seek_entry(int segment_id,
- SectorCount **ptr,
- SectorMap *map)
-{
- unsigned int sector;
- int segment; /* max unsigned int */
-
- if (*ptr <= (SectorCount *)bad_sector_map) {
- *map = 0;
- return 0;
- }
- do {
- sector = get_sector(--(*ptr));
- segment = cvt2segment(sector);
- } while (*ptr > (SectorCount *)bad_sector_map && segment > segment_id);
- if (segment > segment_id) { /* at start of list, no entry found */
- *map = 0;
- return 0;
- } else if (segment < segment_id) {
- /* before smaller entry, adjust for overshoot */
- (*ptr) ++;
- *map = 0;
- return 0;
- } else if ((sector & 0x800000) &&
- (ft_format_code == fmt_big || ft_format_code == fmt_var)) {
- *map = EMPTY_SEGMENT;
- return FT_SECTORS_PER_SEGMENT;
- } else { /* get all sectors in segment_id */
- int count = 1;
-
- *map = cvt2map(sector);
- while(*ptr > (SectorCount *)bad_sector_map) {
- sector = get_sector(--(*ptr));
- segment = cvt2segment(sector);
- if (segment != segment_id) {
- break;
- }
- *map |= cvt2map(sector);
- ++count;
- }
- if (segment < segment_id) {
- (*ptr) ++;
- }
- return count;
- }
-}
-
-#if 0
-static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map)
-{
- SectorCount *ptr = (SectorCount *)bad_sector_map;
- int count;
- int new_count;
- SectorMap map;
- TRACE_FUN(ft_t_any);
-
- if (ft_format_code == fmt_1100ft ||
- ft_format_code == fmt_var ||
- ft_format_code == fmt_big) {
- count = forward_seek_entry(segment_id, &ptr, &map);
- new_count = count_ones(new_map);
- /* If format code == 4 put empty segment instead of 32
- * bad sectors.
- */
- if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
- if (new_count == FT_SECTORS_PER_SEGMENT) {
- new_count = 1;
- }
- if (count == FT_SECTORS_PER_SEGMENT) {
- count = 1;
- }
- }
- if (count != new_count) {
- /* insert (or delete if < 0) new_count - count
- * entries. Move trailing part of list
- * including terminating 0.
- */
- SectorCount *hi_ptr = ptr;
-
- do {
- } while (get_sector(hi_ptr++) != 0);
- /* Note: ptr is of type byte *, and each bad sector
- * consumes 3 bytes.
- */
- memmove(ptr + new_count, ptr + count,
- (size_t)(hi_ptr - (ptr + count))*sizeof(SectorCount));
- }
- TRACE(ft_t_noise, "putting map 0x%08x at %p, segment %d",
- (unsigned int)new_map, ptr, segment_id);
- if (new_count == 1 && new_map == EMPTY_SEGMENT) {
- put_sector(ptr++, (0x800001 +
- segment_id *
- FT_SECTORS_PER_SEGMENT));
- } else {
- int i = 0;
-
- while (new_map) {
- if (new_map & 1) {
- put_sector(ptr++,
- 1 + segment_id *
- FT_SECTORS_PER_SEGMENT + i);
- }
- ++i;
- new_map >>= 1;
- }
- }
- } else {
- ((SectorMap *) bad_sector_map)[segment_id] = new_map;
- }
- TRACE_EXIT;
-}
-#endif /* 0 */
-
-SectorMap ftape_get_bad_sector_entry(int segment_id)
-{
- if (ft_used_header_segment == -1) {
- /* When reading header segment we'll need a blank map.
- */
- return 0;
- } else if (bsm_hash_ptr != NULL) {
- /* Invariants:
- * map - mask value returned on last call.
- * bsm_hash_ptr - points to first sector greater or equal to
- * first sector in last_referenced segment.
- * last_referenced - segment id used in the last call,
- * sector and map belong to this id.
- * This code is designed for sequential access and retries.
- * For true random access it may have to be redesigned.
- */
- static int last_reference = -1;
- static SectorMap map;
-
- if (segment_id > last_reference) {
- /* Skip all sectors before segment_id
- */
- forward_seek_entry(segment_id, &bsm_hash_ptr, &map);
- } else if (segment_id < last_reference) {
- /* Skip backwards until begin of buffer or
- * first sector in segment_id
- */
- backwards_seek_entry(segment_id, &bsm_hash_ptr, &map);
- } /* segment_id == last_reference : keep map */
- last_reference = segment_id;
- return map;
- } else {
- return ((SectorMap *) bad_sector_map)[segment_id];
- }
-}
-
-/* This is simply here to prevent us from overwriting other kernel
- * data. Writes will result in NULL Pointer dereference.
- */
-void ftape_init_bsm(void)
-{
- bad_sector_map = NULL;
- bsm_hash_ptr = NULL;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-bsm.h b/drivers/char/ftape/lowlevel/ftape-bsm.h
deleted file mode 100644
index ed45465af4d4..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-bsm.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _FTAPE_BSM_H
-#define _FTAPE_BSM_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:07 $
- *
- * This file contains definitions for the bad sector map handling
- * routines for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-#include <linux/ftape-header-segment.h>
-
-#define EMPTY_SEGMENT (0xffffffff)
-#define FAKE_SEGMENT (0xfffffffe)
-
-/* maximum (format code 4) bad sector map size (bytes).
- */
-#define BAD_SECTOR_MAP_SIZE (29 * SECTOR_SIZE - 256)
-
-/* format code 4 bad sector entry, ftape uses this
- * internally for all format codes
- */
-typedef __u32 SectorMap;
-/* variable and 1100 ft bad sector map entry. These three bytes represent
- * a single sector address measured from BOT.
- */
-typedef struct NewSectorMap {
- __u8 bytes[3];
-} SectorCount;
-
-
-/*
- * ftape-bsm.c defined global vars.
- */
-
-/*
- * ftape-bsm.c defined global functions.
- */
-extern void update_bad_sector_map(__u8 * buffer);
-extern void ftape_extract_bad_sector_map(__u8 * buffer);
-extern SectorMap ftape_get_bad_sector_entry(int segment_id);
-extern __u8 *ftape_find_end_of_bsm_list(__u8 * address);
-extern void ftape_init_bsm(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.c b/drivers/char/ftape/lowlevel/ftape-buffer.c
deleted file mode 100644
index c706ff162771..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-buffer.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/16 23:33:11 $
- *
- * This file contains the allocator/dealloctor for ftape's dynamic dma
- * buffer.
- */
-
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <asm/dma.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-buffer.h"
-
-/* DMA'able memory allocation stuff.
- */
-
-static inline void *dmaalloc(size_t size)
-{
- unsigned long addr;
-
- if (size == 0) {
- return NULL;
- }
- addr = __get_dma_pages(GFP_KERNEL, get_order(size));
- if (addr) {
- struct page *page;
-
- for (page = virt_to_page(addr); page < virt_to_page(addr+size); page++)
- SetPageReserved(page);
- }
- return (void *)addr;
-}
-
-static inline void dmafree(void *addr, size_t size)
-{
- if (size > 0) {
- struct page *page;
-
- for (page = virt_to_page((unsigned long)addr);
- page < virt_to_page((unsigned long)addr+size); page++)
- ClearPageReserved(page);
- free_pages((unsigned long) addr, get_order(size));
- }
-}
-
-static int add_one_buffer(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (ft_nr_buffers >= FT_MAX_NR_BUFFERS) {
- TRACE_EXIT -ENOMEM;
- }
- ft_buffer[ft_nr_buffers] = kmalloc(sizeof(buffer_struct), GFP_KERNEL);
- if (ft_buffer[ft_nr_buffers] == NULL) {
- TRACE_EXIT -ENOMEM;
- }
- memset(ft_buffer[ft_nr_buffers], 0, sizeof(buffer_struct));
- ft_buffer[ft_nr_buffers]->address = dmaalloc(FT_BUFF_SIZE);
- if (ft_buffer[ft_nr_buffers]->address == NULL) {
- kfree(ft_buffer[ft_nr_buffers]);
- ft_buffer[ft_nr_buffers] = NULL;
- TRACE_EXIT -ENOMEM;
- }
- ft_nr_buffers ++;
- TRACE(ft_t_info, "buffer nr #%d @ %p, dma area @ %p",
- ft_nr_buffers,
- ft_buffer[ft_nr_buffers-1],
- ft_buffer[ft_nr_buffers-1]->address);
- TRACE_EXIT 0;
-}
-
-static void del_one_buffer(void)
-{
- TRACE_FUN(ft_t_flow);
- if (ft_nr_buffers > 0) {
- TRACE(ft_t_info, "releasing buffer nr #%d @ %p, dma area @ %p",
- ft_nr_buffers,
- ft_buffer[ft_nr_buffers-1],
- ft_buffer[ft_nr_buffers-1]->address);
- ft_nr_buffers --;
- dmafree(ft_buffer[ft_nr_buffers]->address, FT_BUFF_SIZE);
- kfree(ft_buffer[ft_nr_buffers]);
- ft_buffer[ft_nr_buffers] = NULL;
- }
- TRACE_EXIT;
-}
-
-int ftape_set_nr_buffers(int cnt)
-{
- int delta = cnt - ft_nr_buffers;
- TRACE_FUN(ft_t_flow);
-
- if (delta > 0) {
- while (delta--) {
- if (add_one_buffer() < 0) {
- TRACE_EXIT -ENOMEM;
- }
- }
- } else if (delta < 0) {
- while (delta++) {
- del_one_buffer();
- }
- }
- ftape_zap_read_buffers();
- TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.h b/drivers/char/ftape/lowlevel/ftape-buffer.h
deleted file mode 100644
index eec99cee8f82..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-buffer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _FTAPE_BUFFER_H
-#define _FTAPE_BUFFER_H
-
-/*
- * Copyright (C) 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:08 $
- *
- * This file contains the allocator/dealloctor for ftape's dynamic dma
- * buffer.
- */
-
-extern int ftape_set_nr_buffers(int cnt);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-calibr.c b/drivers/char/ftape/lowlevel/ftape-calibr.c
deleted file mode 100644
index 8e50bfd35a52..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-calibr.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:08 $
- *
- * GP calibration routine for processor speed dependent
- * functions.
- */
-
-#include <linux/errno.h>
-#include <linux/jiffies.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#if defined(__alpha__)
-# include <asm/hwrpb.h>
-#elif defined(__x86_64__)
-# include <asm/msr.h>
-# include <asm/timex.h>
-#elif defined(__i386__)
-# include <linux/timex.h>
-#endif
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-calibr.h"
-#include "../lowlevel/fdc-io.h"
-
-#undef DEBUG
-
-#if !defined(__alpha__) && !defined(__i386__) && !defined(__x86_64__)
-# error Ftape is not implemented for this architecture!
-#endif
-
-#if defined(__alpha__) || defined(__x86_64__)
-static unsigned long ps_per_cycle = 0;
-#endif
-
-static spinlock_t calibr_lock;
-
-/*
- * Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is
- * too slow for certain timeouts (and that clock doesn't even tick
- * when interrupts are disabled). For that reason, the 8254 timer is
- * used directly to implement fine-grained timeouts. However, on
- * Alpha PCs, the 8254 is *not* used to implement the clock tick
- * (which is 1024 Hz, normally) and the 8254 timer runs at some
- * "random" frequency (it seems to run at 18Hz, but it's not safe to
- * rely on this value). Instead, we use the Alpha's "rpcc"
- * instruction to read cycle counts. As this is a 32 bit counter,
- * it will overflow only once per 30 seconds (on a 200MHz machine),
- * which is plenty.
- */
-
-unsigned int ftape_timestamp(void)
-{
-#if defined(__alpha__)
- unsigned long r;
-
- asm volatile ("rpcc %0" : "=r" (r));
- return r;
-#elif defined(__x86_64__)
- unsigned long r;
- rdtscl(r);
- return r;
-#elif defined(__i386__)
-
-/*
- * Note that there is some time between counter underflowing and jiffies
- * increasing, so the code below won't always give correct output.
- * -Vojtech
- */
-
- unsigned long flags;
- __u16 lo;
- __u16 hi;
-
- spin_lock_irqsave(&calibr_lock, flags);
- outb_p(0x00, 0x43); /* latch the count ASAP */
- lo = inb_p(0x40); /* read the latched count */
- lo |= inb(0x40) << 8;
- hi = jiffies;
- spin_unlock_irqrestore(&calibr_lock, flags);
- return ((hi + 1) * (unsigned int) LATCH) - lo; /* downcounter ! */
-#endif
-}
-
-static unsigned int short_ftape_timestamp(void)
-{
-#if defined(__alpha__) || defined(__x86_64__)
- return ftape_timestamp();
-#elif defined(__i386__)
- unsigned int count;
- unsigned long flags;
-
- spin_lock_irqsave(&calibr_lock, flags);
- outb_p(0x00, 0x43); /* latch the count ASAP */
- count = inb_p(0x40); /* read the latched count */
- count |= inb(0x40) << 8;
- spin_unlock_irqrestore(&calibr_lock, flags);
- return (LATCH - count); /* normal: downcounter */
-#endif
-}
-
-static unsigned int diff(unsigned int t0, unsigned int t1)
-{
-#if defined(__alpha__) || defined(__x86_64__)
- return (t1 - t0);
-#elif defined(__i386__)
- /*
- * This is tricky: to work for both short and full ftape_timestamps
- * we'll have to discriminate between these.
- * If it _looks_ like short stamps with wrapping around we'll
- * asume it are. This will generate a small error if it really
- * was a (very large) delta from full ftape_timestamps.
- */
- return (t1 <= t0 && t0 <= LATCH) ? t1 + LATCH - t0 : t1 - t0;
-#endif
-}
-
-static unsigned int usecs(unsigned int count)
-{
-#if defined(__alpha__) || defined(__x86_64__)
- return (ps_per_cycle * count) / 1000000UL;
-#elif defined(__i386__)
- return (10000 * count) / ((CLOCK_TICK_RATE + 50) / 100);
-#endif
-}
-
-unsigned int ftape_timediff(unsigned int t0, unsigned int t1)
-{
- /*
- * Calculate difference in usec for ftape_timestamp results t0 & t1.
- * Note that on the i386 platform with short time-stamps, the
- * maximum allowed timespan is 1/HZ or we'll lose ticks!
- */
- return usecs(diff(t0, t1));
-}
-
-/* To get an indication of the I/O performance,
- * measure the duration of the inb() function.
- */
-static void time_inb(void)
-{
- int i;
- int t0, t1;
- unsigned long flags;
- int status;
- TRACE_FUN(ft_t_any);
-
- spin_lock_irqsave(&calibr_lock, flags);
- t0 = short_ftape_timestamp();
- for (i = 0; i < 1000; ++i) {
- status = inb(fdc.msr);
- }
- t1 = short_ftape_timestamp();
- spin_unlock_irqrestore(&calibr_lock, flags);
- TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1));
- TRACE_EXIT;
-}
-
-static void init_clock(void)
-{
- TRACE_FUN(ft_t_any);
-
-#if defined(__x86_64__)
- ps_per_cycle = 1000000000UL / cpu_khz;
-#elif defined(__alpha__)
- extern struct hwrpb_struct *hwrpb;
- ps_per_cycle = (1000*1000*1000*1000UL) / hwrpb->cycle_freq;
-#endif
- TRACE_EXIT;
-}
-
-/*
- * Input: function taking int count as parameter.
- * pointers to calculated calibration variables.
- */
-void ftape_calibrate(char *name,
- void (*fun) (unsigned int),
- unsigned int *calibr_count,
- unsigned int *calibr_time)
-{
- static int first_time = 1;
- int i;
- unsigned int tc = 0;
- unsigned int count;
- unsigned int time;
-#if defined(__i386__)
- unsigned int old_tc = 0;
- unsigned int old_count = 1;
- unsigned int old_time = 1;
-#endif
- TRACE_FUN(ft_t_flow);
-
- if (first_time) { /* get idea of I/O performance */
- init_clock();
- time_inb();
- first_time = 0;
- }
- /* value of timeout must be set so that on very slow systems
- * it will give a time less than one jiffy, and on
- * very fast systems it'll give reasonable precision.
- */
-
- count = 40;
- for (i = 0; i < 15; ++i) {
- unsigned int t0;
- unsigned int t1;
- unsigned int once;
- unsigned int multiple;
- unsigned long flags;
-
- *calibr_count =
- *calibr_time = count; /* set TC to 1 */
- spin_lock_irqsave(&calibr_lock, flags);
- fun(0); /* dummy, get code into cache */
- t0 = short_ftape_timestamp();
- fun(0); /* overhead + one test */
- t1 = short_ftape_timestamp();
- once = diff(t0, t1);
- t0 = short_ftape_timestamp();
- fun(count); /* overhead + count tests */
- t1 = short_ftape_timestamp();
- multiple = diff(t0, t1);
- spin_unlock_irqrestore(&calibr_lock, flags);
- time = ftape_timediff(0, multiple - once);
- tc = (1000 * time) / (count - 1);
- TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns",
- usecs(once), count - 1, usecs(multiple), tc);
-#if defined(__alpha__) || defined(__x86_64__)
- /*
- * Increase the calibration count exponentially until the
- * calibration time exceeds 100 ms.
- */
- if (time >= 100*1000) {
- break;
- }
-#elif defined(__i386__)
- /*
- * increase the count until the resulting time nears 2/HZ,
- * then the tc will drop sharply because we lose LATCH counts.
- */
- if (tc <= old_tc / 2) {
- time = old_time;
- count = old_count;
- break;
- }
- old_tc = tc;
- old_count = count;
- old_time = time;
-#endif
- count *= 2;
- }
- *calibr_count = count - 1;
- *calibr_time = time;
- TRACE(ft_t_info, "TC for `%s()' = %d nsec (at %d counts)",
- name, (1000 * *calibr_time) / *calibr_count, *calibr_count);
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-calibr.h b/drivers/char/ftape/lowlevel/ftape-calibr.h
deleted file mode 100644
index 0c7e75246c7d..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-calibr.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _FTAPE_CALIBR_H
-#define _FTAPE_CALIBR_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-calibr.h,v $
- * $Revision: 1.1 $
- * $Date: 1997/09/19 09:05:26 $
- *
- * This file contains a gp calibration routine for
- * hardware dependent timeout functions.
- */
-
-extern void ftape_calibrate(char *name,
- void (*fun) (unsigned int),
- unsigned int *calibr_count,
- unsigned int *calibr_time);
-extern unsigned int ftape_timestamp(void);
-extern unsigned int ftape_timediff(unsigned int t0, unsigned int t1);
-
-#endif /* _FTAPE_CALIBR_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-ctl.c b/drivers/char/ftape/lowlevel/ftape-ctl.c
deleted file mode 100644
index 5d7c1ce92d59..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-ctl.c
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/11/11 14:37:44 $
- *
- * This file contains the non-read/write ftape functions for the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-/* ease porting between pre-2.4.x and later kernels */
-#define vma_get_pgoff(v) ((v)->vm_pgoff)
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/* Global vars.
- */
-ftape_info ftape_status = {
-/* vendor information */
- { 0, }, /* drive type */
-/* data rates */
- 500, /* used data rate */
- 500, /* drive max rate */
- 500, /* fdc max rate */
-/* drive selection, either FTAPE_SEL_A/B/C/D */
- -1, /* drive selection */
-/* flags set after decode the drive and tape status */
- 0, /* formatted */
- 1, /* no tape */
- 1, /* write protected */
- 1, /* new tape */
-/* values of last queried drive/tape status and error */
- {{0,}}, /* last error code */
- {{0,}}, /* drive status, configuration, tape status */
-/* cartridge geometry */
- 20, /* tracks_per_tape */
- 102, /* segments_per_track */
-/* location of header segments, etc. */
- -1, /* used_header_segment */
- -1, /* header_segment_1 */
- -1, /* header_segment_2 */
- -1, /* first_data_segment */
- -1, /* last_data_segment */
-/* the format code as stored in the header segment */
- fmt_normal, /* format code */
-/* the default for the qic std: unknown */
- -1,
-/* is tape running? */
- idle, /* runner_state */
-/* is tape reading/writing/verifying/formatting/deleting */
- idle, /* driver state */
-/* flags fatal hardware error */
- 1, /* failure */
-/* history record */
- { 0, } /* history record */
-};
-
-int ftape_segments_per_head = 1020;
-int ftape_segments_per_cylinder = 4;
-int ftape_init_drive_needed = 1; /* need to be global for ftape_reset_drive()
- * in ftape-io.c
- */
-
-/* Local vars.
- */
-static const vendor_struct vendors[] = QIC117_VENDORS;
-static const wakeup_method methods[] = WAKEUP_METHODS;
-
-const ftape_info *ftape_get_status(void)
-{
-#if defined(STATUS_PARANOYA)
- static ftape_info get_status;
-
- get_status = ftape_status;
- return &get_status;
-#else
- return &ftape_status; /* maybe return only a copy of it to assure
- * read only access
- */
-#endif
-}
-
-static int ftape_not_operational(int status)
-{
- /* return true if status indicates tape can not be used.
- */
- return ((status ^ QIC_STATUS_CARTRIDGE_PRESENT) &
- (QIC_STATUS_ERROR |
- QIC_STATUS_CARTRIDGE_PRESENT |
- QIC_STATUS_NEW_CARTRIDGE));
-}
-
-int ftape_seek_to_eot(void)
-{
- int status;
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
- while ((status & QIC_STATUS_AT_EOT) == 0) {
- if (ftape_not_operational(status)) {
- TRACE_EXIT -EIO;
- }
- TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_FORWARD,
- ftape_timeout.rewind,&status),);
- }
- TRACE_EXIT 0;
-}
-
-int ftape_seek_to_bot(void)
-{
- int status;
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
- while ((status & QIC_STATUS_AT_BOT) == 0) {
- if (ftape_not_operational(status)) {
- TRACE_EXIT -EIO;
- }
- TRACE_CATCH(ftape_command_wait(QIC_PHYSICAL_REVERSE,
- ftape_timeout.rewind,&status),);
- }
- TRACE_EXIT 0;
-}
-
-static int ftape_new_cartridge(void)
-{
- ft_location.track = -1; /* force seek on first access */
- ftape_zap_read_buffers();
- ftape_zap_write_buffers();
- return 0;
-}
-
-int ftape_abort_operation(void)
-{
- int result = 0;
- int status;
- TRACE_FUN(ft_t_flow);
-
- if (ft_runner_status == running) {
- TRACE(ft_t_noise, "aborting runner, waiting");
-
- ft_runner_status = do_abort;
- /* set timeout so that the tape will run to logical EOT
- * if we missed the last sector and there are no queue pulses.
- */
- result = ftape_dumb_stop();
- }
- if (ft_runner_status != idle) {
- if (ft_runner_status == do_abort) {
- TRACE(ft_t_noise, "forcing runner abort");
- }
- TRACE(ft_t_noise, "stopping tape");
- result = ftape_stop_tape(&status);
- ft_location.known = 0;
- ft_runner_status = idle;
- }
- ftape_reset_buffer();
- ftape_zap_read_buffers();
- ftape_set_state(idle);
- TRACE_EXIT result;
-}
-
-static int lookup_vendor_id(unsigned int vendor_id)
-{
- int i = 0;
-
- while (vendors[i].vendor_id != vendor_id) {
- if (++i >= NR_ITEMS(vendors)) {
- return -1;
- }
- }
- return i;
-}
-
-static void ftape_detach_drive(void)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_flow, "disabling tape drive and fdc");
- ftape_put_drive_to_sleep(ft_drive_type.wake_up);
- fdc_catch_stray_interrupts(1); /* one always comes */
- fdc_disable();
- fdc_release_irq_and_dma();
- fdc_release_regions();
- TRACE_EXIT;
-}
-
-static void clear_history(void)
-{
- ft_history.used = 0;
- ft_history.id_am_errors =
- ft_history.id_crc_errors =
- ft_history.data_am_errors =
- ft_history.data_crc_errors =
- ft_history.overrun_errors =
- ft_history.no_data_errors =
- ft_history.retries =
- ft_history.crc_errors =
- ft_history.crc_failures =
- ft_history.ecc_failures =
- ft_history.corrected =
- ft_history.defects =
- ft_history.rewinds = 0;
-}
-
-static int ftape_activate_drive(vendor_struct * drive_type)
-{
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- /* If we already know the drive type, wake it up.
- * Else try to find out what kind of drive is attached.
- */
- if (drive_type->wake_up != unknown_wake_up) {
- TRACE(ft_t_flow, "enabling tape drive and fdc");
- result = ftape_wakeup_drive(drive_type->wake_up);
- if (result < 0) {
- TRACE(ft_t_err, "known wakeup method failed");
- }
- } else {
- wake_up_types method;
- const ft_trace_t old_tracing = TRACE_LEVEL;
- if (TRACE_LEVEL < ft_t_flow) {
- SET_TRACE_LEVEL(ft_t_bug);
- }
-
- /* Try to awaken the drive using all known methods.
- * Lower tracing for a while.
- */
- for (method=no_wake_up; method < NR_ITEMS(methods); ++method) {
- drive_type->wake_up = method;
-#ifdef CONFIG_FT_TWO_DRIVES
- /* Test setup for dual drive configuration.
- * /dev/rft2 uses mountain wakeup
- * /dev/rft3 uses colorado wakeup
- * Other systems will use the normal scheme.
- */
- if ((ft_drive_sel < 2) ||
- (ft_drive_sel == 2 && method == FT_WAKE_UP_1) ||
- (ft_drive_sel == 3 && method == FT_WAKE_UP_2)) {
- result=ftape_wakeup_drive(drive_type->wake_up);
- } else {
- result = -EIO;
- }
-#else
- result = ftape_wakeup_drive(drive_type->wake_up);
-#endif
- if (result >= 0) {
- TRACE(ft_t_warn, "drive wakeup method: %s",
- methods[drive_type->wake_up].name);
- break;
- }
- }
- SET_TRACE_LEVEL(old_tracing);
-
- if (method >= NR_ITEMS(methods)) {
- /* no response at all, cannot open this drive */
- drive_type->wake_up = unknown_wake_up;
- TRACE(ft_t_err, "no tape drive found !");
- result = -ENODEV;
- }
- }
- TRACE_EXIT result;
-}
-
-static int ftape_get_drive_status(void)
-{
- int result;
- int status;
- TRACE_FUN(ft_t_flow);
-
- ft_no_tape = ft_write_protected = 0;
- /* Tape drive is activated now.
- * First clear error status if present.
- */
- do {
- result = ftape_ready_wait(ftape_timeout.reset, &status);
- if (result < 0) {
- if (result == -ETIME) {
- TRACE(ft_t_err, "ftape_ready_wait timeout");
- } else if (result == -EINTR) {
- TRACE(ft_t_err, "ftape_ready_wait aborted");
- } else {
- TRACE(ft_t_err, "ftape_ready_wait failed");
- }
- TRACE_EXIT -EIO;
- }
- /* Clear error condition (drive is ready !)
- */
- if (status & QIC_STATUS_ERROR) {
- unsigned int error;
- qic117_cmd_t command;
-
- TRACE(ft_t_err, "error status set");
- result = ftape_report_error(&error, &command, 1);
- if (result < 0) {
- TRACE(ft_t_err,
- "report_error_code failed: %d", result);
- /* hope it's working next time */
- ftape_reset_drive();
- TRACE_EXIT -EIO;
- } else if (error != 0) {
- TRACE(ft_t_noise, "error code : %d", error);
- TRACE(ft_t_noise, "error command: %d", command);
- }
- }
- if (status & QIC_STATUS_NEW_CARTRIDGE) {
- unsigned int error;
- qic117_cmd_t command;
- const ft_trace_t old_tracing = TRACE_LEVEL;
- SET_TRACE_LEVEL(ft_t_bug);
-
- /* Undocumented feature: Must clear (not present!)
- * error here or we'll fail later.
- */
- ftape_report_error(&error, &command, 1);
-
- SET_TRACE_LEVEL(old_tracing);
- TRACE(ft_t_info, "status: new cartridge");
- ft_new_tape = 1;
- } else {
- ft_new_tape = 0;
- }
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- } while (status & QIC_STATUS_ERROR);
-
- ft_no_tape = !(status & QIC_STATUS_CARTRIDGE_PRESENT);
- ft_write_protected = (status & QIC_STATUS_WRITE_PROTECT) != 0;
- if (ft_no_tape) {
- TRACE(ft_t_warn, "no cartridge present");
- } else {
- if (ft_write_protected) {
- TRACE(ft_t_noise, "Write protected cartridge");
- }
- }
- TRACE_EXIT 0;
-}
-
-static void ftape_log_vendor_id(void)
-{
- int vendor_index;
- TRACE_FUN(ft_t_flow);
-
- ftape_report_vendor_id(&ft_drive_type.vendor_id);
- vendor_index = lookup_vendor_id(ft_drive_type.vendor_id);
- if (ft_drive_type.vendor_id == UNKNOWN_VENDOR &&
- ft_drive_type.wake_up == wake_up_colorado) {
- vendor_index = 0;
- /* hack to get rid of all this mail */
- ft_drive_type.vendor_id = 0;
- }
- if (vendor_index < 0) {
- /* Unknown vendor id, first time opening device. The
- * drive_type remains set to type found at wakeup
- * time, this will probably keep the driver operating
- * for this new vendor.
- */
- TRACE(ft_t_warn, "\n"
- KERN_INFO "============ unknown vendor id ===========\n"
- KERN_INFO "A new, yet unsupported tape drive is found\n"
- KERN_INFO "Please report the following values:\n"
- KERN_INFO " Vendor id : 0x%04x\n"
- KERN_INFO " Wakeup method : %s\n"
- KERN_INFO "And a description of your tape drive\n"
- KERN_INFO "to "THE_FTAPE_MAINTAINER"\n"
- KERN_INFO "==========================================",
- ft_drive_type.vendor_id,
- methods[ft_drive_type.wake_up].name);
- ft_drive_type.speed = 0; /* unknown */
- } else {
- ft_drive_type.name = vendors[vendor_index].name;
- ft_drive_type.speed = vendors[vendor_index].speed;
- TRACE(ft_t_info, "tape drive type: %s", ft_drive_type.name);
- /* scan all methods for this vendor_id in table */
- while(ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
- if (vendor_index < NR_ITEMS(vendors) - 1 &&
- vendors[vendor_index + 1].vendor_id
- ==
- ft_drive_type.vendor_id) {
- ++vendor_index;
- } else {
- break;
- }
- }
- if (ft_drive_type.wake_up != vendors[vendor_index].wake_up) {
- TRACE(ft_t_warn, "\n"
- KERN_INFO "==========================================\n"
- KERN_INFO "wakeup type mismatch:\n"
- KERN_INFO "found: %s, expected: %s\n"
- KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
- KERN_INFO "==========================================",
- methods[ft_drive_type.wake_up].name,
- methods[vendors[vendor_index].wake_up].name);
- }
- }
- TRACE_EXIT;
-}
-
-void ftape_calc_timeouts(unsigned int qic_std,
- unsigned int data_rate,
- unsigned int tape_len)
-{
- int speed; /* deci-ips ! */
- int ff_speed;
- int length;
- TRACE_FUN(ft_t_any);
-
- /* tape transport speed
- * data rate: QIC-40 QIC-80 QIC-3010 QIC-3020
- *
- * 250 Kbps 25 ips n/a n/a n/a
- * 500 Kbps 50 ips 34 ips 22.6 ips n/a
- * 1 Mbps n/a 68 ips 45.2 ips 22.6 ips
- * 2 Mbps n/a n/a n/a 45.2 ips
- *
- * fast tape transport speed is at least 68 ips.
- */
- switch (qic_std) {
- case QIC_TAPE_QIC40:
- speed = (data_rate == 250) ? 250 : 500;
- break;
- case QIC_TAPE_QIC80:
- speed = (data_rate == 500) ? 340 : 680;
- break;
- case QIC_TAPE_QIC3010:
- speed = (data_rate == 500) ? 226 : 452;
- break;
- case QIC_TAPE_QIC3020:
- speed = (data_rate == 1000) ? 226 : 452;
- break;
- default:
- TRACE(ft_t_bug, "Unknown qic_std (bug) ?");
- speed = 500;
- break;
- }
- if (ft_drive_type.speed == 0) {
- unsigned long t0;
- static int dt = 0; /* keep gcc from complaining */
- static int first_time = 1;
-
- /* Measure the time it takes to wind to EOT and back to BOT.
- * If the tape length is known, calculate the rewind speed.
- * Else keep the time value for calculation of the rewind
- * speed later on, when the length _is_ known.
- * Ask for a report only when length and speed are both known.
- */
- if (first_time) {
- ftape_seek_to_bot();
- t0 = jiffies;
- ftape_seek_to_eot();
- ftape_seek_to_bot();
- dt = (int) (((jiffies - t0) * FT_USPT) / 1000);
- if (dt < 1) {
- dt = 1; /* prevent div by zero on failures */
- }
- first_time = 0;
- TRACE(ft_t_info,
- "trying to determine seek timeout, got %d msec",
- dt);
- }
- if (tape_len != 0) {
- ft_drive_type.speed =
- (2 * 12 * tape_len * 1000) / dt;
- TRACE(ft_t_warn, "\n"
- KERN_INFO "==========================================\n"
- KERN_INFO "drive type: %s\n"
- KERN_INFO "delta time = %d ms, length = %d ft\n"
- KERN_INFO "has a maximum tape speed of %d ips\n"
- KERN_INFO "please report this to "THE_FTAPE_MAINTAINER"\n"
- KERN_INFO "==========================================",
- ft_drive_type.name, dt, tape_len,
- ft_drive_type.speed);
- }
- }
- /* Handle unknown length tapes as very long ones. We'll
- * determine the actual length from a header segment later.
- * This is normal for all modern (Wide,TR1/2/3) formats.
- */
- if (tape_len <= 0) {
- TRACE(ft_t_noise,
- "Unknown tape length, using maximal timeouts");
- length = QIC_TOP_TAPE_LEN; /* use worst case values */
- } else {
- length = tape_len; /* use actual values */
- }
- if (ft_drive_type.speed == 0) {
- ff_speed = speed;
- } else {
- ff_speed = ft_drive_type.speed;
- }
- /* time to go from bot to eot at normal speed (data rate):
- * time = (1+delta) * length (ft) * 12 (inch/ft) / speed (ips)
- * delta = 10 % for seek speed, 20 % for rewind speed.
- */
- ftape_timeout.seek = (length * 132 * FT_SECOND) / speed;
- ftape_timeout.rewind = (length * 144 * FT_SECOND) / (10 * ff_speed);
- ftape_timeout.reset = 20 * FT_SECOND + ftape_timeout.rewind;
- TRACE(ft_t_noise, "timeouts for speed = %d, length = %d\n"
- KERN_INFO "seek timeout : %d sec\n"
- KERN_INFO "rewind timeout: %d sec\n"
- KERN_INFO "reset timeout : %d sec",
- speed, length,
- (ftape_timeout.seek + 500) / 1000,
- (ftape_timeout.rewind + 500) / 1000,
- (ftape_timeout.reset + 500) / 1000);
- TRACE_EXIT;
-}
-
-/* This function calibrates the datarate (i.e. determines the maximal
- * usable data rate) and sets the global variable ft_qic_std to qic_std
- *
- */
-int ftape_calibrate_data_rate(unsigned int qic_std)
-{
- int rate = ft_fdc_rate_limit;
- int result;
- TRACE_FUN(ft_t_flow);
-
- ft_qic_std = qic_std;
-
- if (ft_qic_std == -1) {
- TRACE_ABORT(-EIO, ft_t_err,
- "Unable to determine data rate if QIC standard is unknown");
- }
-
- /* Select highest rate supported by both fdc and drive.
- * Start with highest rate supported by the fdc.
- */
- while (fdc_set_data_rate(rate) < 0 && rate > 250) {
- rate /= 2;
- }
- TRACE(ft_t_info,
- "Highest FDC supported data rate: %d Kbps", rate);
- ft_fdc_max_rate = rate;
- do {
- result = ftape_set_data_rate(rate, ft_qic_std);
- } while (result == -EINVAL && (rate /= 2) > 250);
- if (result < 0) {
- TRACE_ABORT(-EIO, ft_t_err, "set datarate failed");
- }
- ft_data_rate = rate;
- TRACE_EXIT 0;
-}
-
-static int ftape_init_drive(void)
-{
- int status;
- qic_model model;
- unsigned int qic_std;
- unsigned int data_rate;
- TRACE_FUN(ft_t_flow);
-
- ftape_init_drive_needed = 0; /* don't retry if this fails ? */
- TRACE_CATCH(ftape_report_raw_drive_status(&status),);
- if (status & QIC_STATUS_CARTRIDGE_PRESENT) {
- if (!(status & QIC_STATUS_AT_BOT)) {
- /* Antique drives will get here after a soft reset,
- * modern ones only if the driver is loaded when the
- * tape wasn't rewound properly.
- */
- /* Tape should be at bot if new cartridge ! */
- ftape_seek_to_bot();
- }
- if (!(status & QIC_STATUS_REFERENCED)) {
- TRACE(ft_t_flow, "starting seek_load_point");
- TRACE_CATCH(ftape_command_wait(QIC_SEEK_LOAD_POINT,
- ftape_timeout.reset,
- &status),);
- }
- }
- ft_formatted = (status & QIC_STATUS_REFERENCED) != 0;
- if (!ft_formatted) {
- TRACE(ft_t_warn, "Warning: tape is not formatted !");
- }
-
- /* report configuration aborts when ftape_tape_len == -1
- * unknown qic_std is okay if not formatted.
- */
- TRACE_CATCH(ftape_report_configuration(&model,
- &data_rate,
- &qic_std,
- &ftape_tape_len),);
-
- /* Maybe add the following to the /proc entry
- */
- TRACE(ft_t_info, "%s drive @ %d Kbps",
- (model == prehistoric) ? "prehistoric" :
- ((model == pre_qic117c) ? "pre QIC-117C" :
- ((model == post_qic117b) ? "post QIC-117B" :
- "post QIC-117D")), data_rate);
-
- if (ft_formatted) {
- /* initialize ft_used_data_rate to maximum value
- * and set ft_qic_std
- */
- TRACE_CATCH(ftape_calibrate_data_rate(qic_std),);
- if (ftape_tape_len == 0) {
- TRACE(ft_t_info, "unknown length QIC-%s tape",
- (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
- ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
- ((ft_qic_std == QIC_TAPE_QIC3010)
- ? "3010" : "3020")));
- } else {
- TRACE(ft_t_info, "%d ft. QIC-%s tape", ftape_tape_len,
- (ft_qic_std == QIC_TAPE_QIC40) ? "40" :
- ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
- ((ft_qic_std == QIC_TAPE_QIC3010)
- ? "3010" : "3020")));
- }
- ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
- /* soft write-protect QIC-40/QIC-80 cartridges used with a
- * Colorado T3000 drive. Buggy hardware!
- */
- if ((ft_drive_type.vendor_id == 0x011c6) &&
- ((ft_qic_std == QIC_TAPE_QIC40 ||
- ft_qic_std == QIC_TAPE_QIC80) &&
- !ft_write_protected)) {
- TRACE(ft_t_warn, "\n"
- KERN_INFO "The famous Colorado T3000 bug:\n"
- KERN_INFO "%s drives can't write QIC40 and QIC80\n"
- KERN_INFO "cartridges but don't set the write-protect flag!",
- ft_drive_type.name);
- ft_write_protected = 1;
- }
- } else {
- /* Doesn't make too much sense to set the data rate
- * because we don't know what to use for the write
- * precompensation.
- * Need to do this again when formatting the cartridge.
- */
- ft_data_rate = data_rate;
- ftape_calc_timeouts(QIC_TAPE_QIC40,
- data_rate,
- ftape_tape_len);
- }
- ftape_new_cartridge();
- TRACE_EXIT 0;
-}
-
-static void ftape_munmap(void)
-{
- int i;
- TRACE_FUN(ft_t_flow);
-
- for (i = 0; i < ft_nr_buffers; i++) {
- ft_buffer[i]->mmapped = 0;
- }
- TRACE_EXIT;
-}
-
-/* Map the dma buffers into the virtual address range given by vma.
- * We only check the caller doesn't map non-existent buffers. We
- * don't check for multiple mappings.
- */
-int ftape_mmap(struct vm_area_struct *vma)
-{
- int num_buffers;
- int i;
- TRACE_FUN(ft_t_flow);
-
- if (ft_failure) {
- TRACE_EXIT -ENODEV;
- }
- if (!(vma->vm_flags & (VM_READ|VM_WRITE))) {
- TRACE_ABORT(-EINVAL, ft_t_err, "Undefined mmap() access");
- }
- if (vma_get_pgoff(vma) != 0) {
- TRACE_ABORT(-EINVAL, ft_t_err, "page offset must be 0");
- }
- if ((vma->vm_end - vma->vm_start) % FT_BUFF_SIZE != 0) {
- TRACE_ABORT(-EINVAL, ft_t_err,
- "size = %ld, should be a multiple of %d",
- vma->vm_end - vma->vm_start,
- FT_BUFF_SIZE);
- }
- num_buffers = (vma->vm_end - vma->vm_start) / FT_BUFF_SIZE;
- if (num_buffers > ft_nr_buffers) {
- TRACE_ABORT(-EINVAL,
- ft_t_err, "size = %ld, should be less than %d",
- vma->vm_end - vma->vm_start,
- ft_nr_buffers * FT_BUFF_SIZE);
- }
- if (ft_driver_state != idle) {
- /* this also clears the buffer states
- */
- ftape_abort_operation();
- } else {
- ftape_reset_buffer();
- }
- for (i = 0; i < num_buffers; i++) {
- unsigned long pfn;
-
- pfn = virt_to_phys(ft_buffer[i]->address) >> PAGE_SHIFT;
- TRACE_CATCH(remap_pfn_range(vma, vma->vm_start +
- i * FT_BUFF_SIZE,
- pfn,
- FT_BUFF_SIZE,
- vma->vm_page_prot),
- _res = -EAGAIN);
- TRACE(ft_t_noise, "remapped dma buffer @ %p to location @ %p",
- ft_buffer[i]->address,
- (void *)(vma->vm_start + i * FT_BUFF_SIZE));
- }
- for (i = 0; i < num_buffers; i++) {
- memset(ft_buffer[i]->address, 0xAA, FT_BUFF_SIZE);
- ft_buffer[i]->mmapped++;
- }
- TRACE_EXIT 0;
-}
-
-static void ftape_init_driver(void); /* forward declaration */
-
-/* OPEN routine called by kernel-interface code
- */
-int ftape_enable(int drive_selection)
-{
- TRACE_FUN(ft_t_any);
-
- if (ft_drive_sel == -1 || ft_drive_sel != drive_selection) {
- /* Other selection than last time
- */
- ftape_init_driver();
- }
- ft_drive_sel = FTAPE_SEL(drive_selection);
- ft_failure = 0;
- TRACE_CATCH(fdc_init(),); /* init & detect fdc */
- TRACE_CATCH(ftape_activate_drive(&ft_drive_type),
- fdc_disable();
- fdc_release_irq_and_dma();
- fdc_release_regions());
- TRACE_CATCH(ftape_get_drive_status(), ftape_detach_drive());
- if (ft_drive_type.vendor_id == UNKNOWN_VENDOR) {
- ftape_log_vendor_id();
- }
- if (ft_new_tape) {
- ftape_init_drive_needed = 1;
- }
- if (!ft_no_tape && ftape_init_drive_needed) {
- TRACE_CATCH(ftape_init_drive(), ftape_detach_drive());
- }
- ftape_munmap(); /* clear the mmap flag */
- clear_history();
- TRACE_EXIT 0;
-}
-
-/* release routine called by the high level interface modules
- * zftape or sftape.
- */
-void ftape_disable(void)
-{
- int i;
- TRACE_FUN(ft_t_any);
-
- for (i = 0; i < ft_nr_buffers; i++) {
- if (ft_buffer[i]->mmapped) {
- TRACE(ft_t_noise, "first byte of buffer %d: 0x%02x",
- i, *ft_buffer[i]->address);
- }
- }
- if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) &&
- !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) &&
- ftape_tape_running) {
- TRACE(ft_t_warn,
- "Interrupted by fatal signal and tape still running");
- ftape_dumb_stop();
- ftape_abort_operation(); /* it's annoying */
- } else {
- ftape_set_state(idle);
- }
- ftape_detach_drive();
- if (ft_history.used) {
- TRACE(ft_t_info, "== Non-fatal errors this run: ==");
- TRACE(ft_t_info, "fdc isr statistics:\n"
- KERN_INFO " id_am_errors : %3d\n"
- KERN_INFO " id_crc_errors : %3d\n"
- KERN_INFO " data_am_errors : %3d\n"
- KERN_INFO " data_crc_errors : %3d\n"
- KERN_INFO " overrun_errors : %3d\n"
- KERN_INFO " no_data_errors : %3d\n"
- KERN_INFO " retries : %3d",
- ft_history.id_am_errors, ft_history.id_crc_errors,
- ft_history.data_am_errors, ft_history.data_crc_errors,
- ft_history.overrun_errors, ft_history.no_data_errors,
- ft_history.retries);
- if (ft_history.used & 1) {
- TRACE(ft_t_info, "ecc statistics:\n"
- KERN_INFO " crc_errors : %3d\n"
- KERN_INFO " crc_failures : %3d\n"
- KERN_INFO " ecc_failures : %3d\n"
- KERN_INFO " sectors corrected: %3d",
- ft_history.crc_errors, ft_history.crc_failures,
- ft_history.ecc_failures, ft_history.corrected);
- }
- if (ft_history.defects > 0) {
- TRACE(ft_t_warn, "Warning: %d media defects!",
- ft_history.defects);
- }
- if (ft_history.rewinds > 0) {
- TRACE(ft_t_info, "tape motion statistics:\n"
- KERN_INFO "repositions : %3d",
- ft_history.rewinds);
- }
- }
- ft_failure = 1;
- TRACE_EXIT;
-}
-
-static void ftape_init_driver(void)
-{
- TRACE_FUN(ft_t_flow);
-
- ft_drive_type.vendor_id = UNKNOWN_VENDOR;
- ft_drive_type.speed = 0;
- ft_drive_type.wake_up = unknown_wake_up;
- ft_drive_type.name = "Unknown";
-
- ftape_timeout.seek = 650 * FT_SECOND;
- ftape_timeout.reset = 670 * FT_SECOND;
- ftape_timeout.rewind = 650 * FT_SECOND;
- ftape_timeout.head_seek = 15 * FT_SECOND;
- ftape_timeout.stop = 5 * FT_SECOND;
- ftape_timeout.pause = 16 * FT_SECOND;
-
- ft_qic_std = -1;
- ftape_tape_len = 0; /* unknown */
- ftape_current_command = 0;
- ftape_current_cylinder = -1;
-
- ft_segments_per_track = 102;
- ftape_segments_per_head = 1020;
- ftape_segments_per_cylinder = 4;
- ft_tracks_per_tape = 20;
-
- ft_failure = 1;
-
- ft_formatted = 0;
- ft_no_tape = 1;
- ft_write_protected = 1;
- ft_new_tape = 1;
-
- ft_driver_state = idle;
-
- ft_data_rate =
- ft_fdc_max_rate = 500;
- ft_drive_max_rate = 0; /* triggers set_rate_test() */
-
- ftape_init_drive_needed = 1;
-
- ft_header_segment_1 = -1;
- ft_header_segment_2 = -1;
- ft_used_header_segment = -1;
- ft_first_data_segment = -1;
- ft_last_data_segment = -1;
-
- ft_location.track = -1;
- ft_location.known = 0;
-
- ftape_tape_running = 0;
- ftape_might_be_off_track = 1;
-
- ftape_new_cartridge(); /* init some tape related variables */
- ftape_init_bsm();
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-ctl.h b/drivers/char/ftape/lowlevel/ftape-ctl.h
deleted file mode 100644
index 5f5e30bc3615..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-ctl.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef _FTAPE_CTL_H
-#define _FTAPE_CTL_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ctl.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:09 $
- *
- * This file contains the non-standard IOCTL related definitions
- * for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
- * Linux.
- */
-
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-#include <linux/ftape-vendors.h>
-
-#include "../lowlevel/ftape-rw.h"
-#include <linux/ftape-header-segment.h>
-
-typedef struct {
- int used; /* any reading or writing done */
- /* isr statistics */
- unsigned int id_am_errors; /* id address mark not found */
- unsigned int id_crc_errors; /* crc error in id address mark */
- unsigned int data_am_errors; /* data address mark not found */
- unsigned int data_crc_errors; /* crc error in data field */
- unsigned int overrun_errors; /* fdc access timing problem */
- unsigned int no_data_errors; /* sector not found */
- unsigned int retries; /* number of tape retries */
- /* ecc statistics */
- unsigned int crc_errors; /* crc error in data */
- unsigned int crc_failures; /* bad data without crc error */
- unsigned int ecc_failures; /* failed to correct */
- unsigned int corrected; /* total sectors corrected */
- /* general statistics */
- unsigned int rewinds; /* number of tape rewinds */
- unsigned int defects; /* bad sectors due to media defects */
-} history_record;
-
-/* this structure contains * ALL * information that we want
- * our child modules to know about, but don't want them to
- * modify.
- */
-typedef struct {
- /* vendor information */
- vendor_struct fti_drive_type;
- /* data rates */
- unsigned int fti_used_data_rate;
- unsigned int fti_drive_max_rate;
- unsigned int fti_fdc_max_rate;
- /* drive selection, either FTAPE_SEL_A/B/C/D */
- int fti_drive_sel;
- /* flags set after decode the drive and tape status */
- unsigned int fti_formatted :1;
- unsigned int fti_no_tape :1;
- unsigned int fti_write_protected:1;
- unsigned int fti_new_tape :1;
- /* values of last queried drive/tape status and error */
- ft_drive_error fti_last_error;
- ft_drive_status fti_last_status;
- /* cartridge geometry */
- unsigned int fti_tracks_per_tape;
- unsigned int fti_segments_per_track;
- /* location of header segments, etc. */
- int fti_used_header_segment;
- int fti_header_segment_1;
- int fti_header_segment_2;
- int fti_first_data_segment;
- int fti_last_data_segment;
- /* the format code as stored in the header segment */
- ft_format_type fti_format_code;
- /* the following is the sole reason for the ftape_set_status() call */
- unsigned int fti_qic_std;
- /* is tape running? */
- volatile enum runner_status_enum fti_runner_status;
- /* is tape reading/writing/verifying/formatting/deleting */
- buffer_state_enum fti_state;
- /* flags fatal hardware error */
- unsigned int fti_failure:1;
- /* history record */
- history_record fti_history;
-} ftape_info;
-
-/* vendor information */
-#define ft_drive_type ftape_status.fti_drive_type
-/* data rates */
-#define ft_data_rate ftape_status.fti_used_data_rate
-#define ft_drive_max_rate ftape_status.fti_drive_max_rate
-#define ft_fdc_max_rate ftape_status.fti_fdc_max_rate
-/* drive selection, either FTAPE_SEL_A/B/C/D */
-#define ft_drive_sel ftape_status.fti_drive_sel
-/* flags set after decode the drive and tape status */
-#define ft_formatted ftape_status.fti_formatted
-#define ft_no_tape ftape_status.fti_no_tape
-#define ft_write_protected ftape_status.fti_write_protected
-#define ft_new_tape ftape_status.fti_new_tape
-/* values of last queried drive/tape status and error */
-#define ft_last_error ftape_status.fti_last_error
-#define ft_last_status ftape_status.fti_last_status
-/* cartridge geometry */
-#define ft_tracks_per_tape ftape_status.fti_tracks_per_tape
-#define ft_segments_per_track ftape_status.fti_segments_per_track
-/* the format code as stored in the header segment */
-#define ft_format_code ftape_status.fti_format_code
-/* the qic status as returned by report drive configuration */
-#define ft_qic_std ftape_status.fti_qic_std
-#define ft_used_header_segment ftape_status.fti_used_header_segment
-#define ft_header_segment_1 ftape_status.fti_header_segment_1
-#define ft_header_segment_2 ftape_status.fti_header_segment_2
-#define ft_first_data_segment ftape_status.fti_first_data_segment
-#define ft_last_data_segment ftape_status.fti_last_data_segment
-/* is tape running? */
-#define ft_runner_status ftape_status.fti_runner_status
-/* is tape reading/writing/verifying/formatting/deleting */
-#define ft_driver_state ftape_status.fti_state
-/* flags fatal hardware error */
-#define ft_failure ftape_status.fti_failure
-/* history record */
-#define ft_history ftape_status.fti_history
-
-/*
- * ftape-ctl.c defined global vars.
- */
-extern ftape_info ftape_status;
-extern int ftape_segments_per_head;
-extern int ftape_segments_per_cylinder;
-extern int ftape_init_drive_needed;
-
-/*
- * ftape-ctl.c defined global functions.
- */
-extern int ftape_mmap(struct vm_area_struct *vma);
-extern int ftape_enable(int drive_selection);
-extern void ftape_disable(void);
-extern int ftape_seek_to_bot(void);
-extern int ftape_seek_to_eot(void);
-extern int ftape_abort_operation(void);
-extern void ftape_calc_timeouts(unsigned int qic_std,
- unsigned int data_rate,
- unsigned int tape_len);
-extern int ftape_calibrate_data_rate(unsigned int qic_std);
-extern const ftape_info *ftape_get_status(void);
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-ecc.c b/drivers/char/ftape/lowlevel/ftape-ecc.c
deleted file mode 100644
index e5632f674bc8..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-ecc.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- *
- * Copyright (c) 1993 Ning and David Mosberger.
-
- This is based on code originally written by Bas Laarhoven (bas@vimec.nl)
- and David L. Brown, Jr., and incorporates improvements suggested by
- Kai Harrekilde-Petersen.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:18:10 $
- *
- * This file contains the Reed-Solomon error correction code
- * for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-ecc.h"
-
-/* Machines that are big-endian should define macro BIG_ENDIAN.
- * Unfortunately, there doesn't appear to be a standard include file
- * that works for all OSs.
- */
-
-#if defined(__sparc__) || defined(__hppa)
-#define BIG_ENDIAN
-#endif /* __sparc__ || __hppa */
-
-#if defined(__mips__)
-#error Find a smart way to determine the Endianness of the MIPS CPU
-#endif
-
-/* Notice: to minimize the potential for confusion, we use r to
- * denote the independent variable of the polynomials in the
- * Galois Field GF(2^8). We reserve x for polynomials that
- * that have coefficients in GF(2^8).
- *
- * The Galois Field in which coefficient arithmetic is performed are
- * the polynomials over Z_2 (i.e., 0 and 1) modulo the irreducible
- * polynomial f(r), where f(r)=r^8 + r^7 + r^2 + r + 1. A polynomial
- * is represented as a byte with the MSB as the coefficient of r^7 and
- * the LSB as the coefficient of r^0. For example, the binary
- * representation of f(x) is 0x187 (of course, this doesn't fit into 8
- * bits). In this field, the polynomial r is a primitive element.
- * That is, r^i with i in 0,...,255 enumerates all elements in the
- * field.
- *
- * The generator polynomial for the QIC-80 ECC is
- *
- * g(x) = x^3 + r^105*x^2 + r^105*x + 1
- *
- * which can be factored into:
- *
- * g(x) = (x-r^-1)(x-r^0)(x-r^1)
- *
- * the byte representation of the coefficients are:
- *
- * r^105 = 0xc0
- * r^-1 = 0xc3
- * r^0 = 0x01
- * r^1 = 0x02
- *
- * Notice that r^-1 = r^254 as exponent arithmetic is performed
- * modulo 2^8-1 = 255.
- *
- * For more information on Galois Fields and Reed-Solomon codes, refer
- * to any good book. I found _An Introduction to Error Correcting
- * Codes with Applications_ by S. A. Vanstone and P. C. van Oorschot
- * to be a good introduction into the former. _CODING THEORY: The
- * Essentials_ I found very useful for its concise description of
- * Reed-Solomon encoding/decoding.
- *
- */
-
-typedef __u8 Matrix[3][3];
-
-/*
- * gfpow[] is defined such that gfpow[i] returns r^i if
- * i is in the range [0..255].
- */
-static const __u8 gfpow[] =
-{
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x87, 0x89, 0x95, 0xad, 0xdd, 0x3d, 0x7a, 0xf4,
- 0x6f, 0xde, 0x3b, 0x76, 0xec, 0x5f, 0xbe, 0xfb,
- 0x71, 0xe2, 0x43, 0x86, 0x8b, 0x91, 0xa5, 0xcd,
- 0x1d, 0x3a, 0x74, 0xe8, 0x57, 0xae, 0xdb, 0x31,
- 0x62, 0xc4, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x67,
- 0xce, 0x1b, 0x36, 0x6c, 0xd8, 0x37, 0x6e, 0xdc,
- 0x3f, 0x7e, 0xfc, 0x7f, 0xfe, 0x7b, 0xf6, 0x6b,
- 0xd6, 0x2b, 0x56, 0xac, 0xdf, 0x39, 0x72, 0xe4,
- 0x4f, 0x9e, 0xbb, 0xf1, 0x65, 0xca, 0x13, 0x26,
- 0x4c, 0x98, 0xb7, 0xe9, 0x55, 0xaa, 0xd3, 0x21,
- 0x42, 0x84, 0x8f, 0x99, 0xb5, 0xed, 0x5d, 0xba,
- 0xf3, 0x61, 0xc2, 0x03, 0x06, 0x0c, 0x18, 0x30,
- 0x60, 0xc0, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0,
- 0x47, 0x8e, 0x9b, 0xb1, 0xe5, 0x4d, 0x9a, 0xb3,
- 0xe1, 0x45, 0x8a, 0x93, 0xa1, 0xc5, 0x0d, 0x1a,
- 0x34, 0x68, 0xd0, 0x27, 0x4e, 0x9c, 0xbf, 0xf9,
- 0x75, 0xea, 0x53, 0xa6, 0xcb, 0x11, 0x22, 0x44,
- 0x88, 0x97, 0xa9, 0xd5, 0x2d, 0x5a, 0xb4, 0xef,
- 0x59, 0xb2, 0xe3, 0x41, 0x82, 0x83, 0x81, 0x85,
- 0x8d, 0x9d, 0xbd, 0xfd, 0x7d, 0xfa, 0x73, 0xe6,
- 0x4b, 0x96, 0xab, 0xd1, 0x25, 0x4a, 0x94, 0xaf,
- 0xd9, 0x35, 0x6a, 0xd4, 0x2f, 0x5e, 0xbc, 0xff,
- 0x79, 0xf2, 0x63, 0xc6, 0x0b, 0x16, 0x2c, 0x58,
- 0xb0, 0xe7, 0x49, 0x92, 0xa3, 0xc1, 0x05, 0x0a,
- 0x14, 0x28, 0x50, 0xa0, 0xc7, 0x09, 0x12, 0x24,
- 0x48, 0x90, 0xa7, 0xc9, 0x15, 0x2a, 0x54, 0xa8,
- 0xd7, 0x29, 0x52, 0xa4, 0xcf, 0x19, 0x32, 0x64,
- 0xc8, 0x17, 0x2e, 0x5c, 0xb8, 0xf7, 0x69, 0xd2,
- 0x23, 0x46, 0x8c, 0x9f, 0xb9, 0xf5, 0x6d, 0xda,
- 0x33, 0x66, 0xcc, 0x1f, 0x3e, 0x7c, 0xf8, 0x77,
- 0xee, 0x5b, 0xb6, 0xeb, 0x51, 0xa2, 0xc3, 0x01
-};
-
-/*
- * This is a log table. That is, gflog[r^i] returns i (modulo f(r)).
- * gflog[0] is undefined and the first element is therefore not valid.
- */
-static const __u8 gflog[256] =
-{
- 0xff, 0x00, 0x01, 0x63, 0x02, 0xc6, 0x64, 0x6a,
- 0x03, 0xcd, 0xc7, 0xbc, 0x65, 0x7e, 0x6b, 0x2a,
- 0x04, 0x8d, 0xce, 0x4e, 0xc8, 0xd4, 0xbd, 0xe1,
- 0x66, 0xdd, 0x7f, 0x31, 0x6c, 0x20, 0x2b, 0xf3,
- 0x05, 0x57, 0x8e, 0xe8, 0xcf, 0xac, 0x4f, 0x83,
- 0xc9, 0xd9, 0xd5, 0x41, 0xbe, 0x94, 0xe2, 0xb4,
- 0x67, 0x27, 0xde, 0xf0, 0x80, 0xb1, 0x32, 0x35,
- 0x6d, 0x45, 0x21, 0x12, 0x2c, 0x0d, 0xf4, 0x38,
- 0x06, 0x9b, 0x58, 0x1a, 0x8f, 0x79, 0xe9, 0x70,
- 0xd0, 0xc2, 0xad, 0xa8, 0x50, 0x75, 0x84, 0x48,
- 0xca, 0xfc, 0xda, 0x8a, 0xd6, 0x54, 0x42, 0x24,
- 0xbf, 0x98, 0x95, 0xf9, 0xe3, 0x5e, 0xb5, 0x15,
- 0x68, 0x61, 0x28, 0xba, 0xdf, 0x4c, 0xf1, 0x2f,
- 0x81, 0xe6, 0xb2, 0x3f, 0x33, 0xee, 0x36, 0x10,
- 0x6e, 0x18, 0x46, 0xa6, 0x22, 0x88, 0x13, 0xf7,
- 0x2d, 0xb8, 0x0e, 0x3d, 0xf5, 0xa4, 0x39, 0x3b,
- 0x07, 0x9e, 0x9c, 0x9d, 0x59, 0x9f, 0x1b, 0x08,
- 0x90, 0x09, 0x7a, 0x1c, 0xea, 0xa0, 0x71, 0x5a,
- 0xd1, 0x1d, 0xc3, 0x7b, 0xae, 0x0a, 0xa9, 0x91,
- 0x51, 0x5b, 0x76, 0x72, 0x85, 0xa1, 0x49, 0xeb,
- 0xcb, 0x7c, 0xfd, 0xc4, 0xdb, 0x1e, 0x8b, 0xd2,
- 0xd7, 0x92, 0x55, 0xaa, 0x43, 0x0b, 0x25, 0xaf,
- 0xc0, 0x73, 0x99, 0x77, 0x96, 0x5c, 0xfa, 0x52,
- 0xe4, 0xec, 0x5f, 0x4a, 0xb6, 0xa2, 0x16, 0x86,
- 0x69, 0xc5, 0x62, 0xfe, 0x29, 0x7d, 0xbb, 0xcc,
- 0xe0, 0xd3, 0x4d, 0x8c, 0xf2, 0x1f, 0x30, 0xdc,
- 0x82, 0xab, 0xe7, 0x56, 0xb3, 0x93, 0x40, 0xd8,
- 0x34, 0xb0, 0xef, 0x26, 0x37, 0x0c, 0x11, 0x44,
- 0x6f, 0x78, 0x19, 0x9a, 0x47, 0x74, 0xa7, 0xc1,
- 0x23, 0x53, 0x89, 0xfb, 0x14, 0x5d, 0xf8, 0x97,
- 0x2e, 0x4b, 0xb9, 0x60, 0x0f, 0xed, 0x3e, 0xe5,
- 0xf6, 0x87, 0xa5, 0x17, 0x3a, 0xa3, 0x3c, 0xb7
-};
-
-/* This is a multiplication table for the factor 0xc0 (i.e., r^105 (mod f(r)).
- * gfmul_c0[f] returns r^105 * f(r) (modulo f(r)).
- */
-static const __u8 gfmul_c0[256] =
-{
- 0x00, 0xc0, 0x07, 0xc7, 0x0e, 0xce, 0x09, 0xc9,
- 0x1c, 0xdc, 0x1b, 0xdb, 0x12, 0xd2, 0x15, 0xd5,
- 0x38, 0xf8, 0x3f, 0xff, 0x36, 0xf6, 0x31, 0xf1,
- 0x24, 0xe4, 0x23, 0xe3, 0x2a, 0xea, 0x2d, 0xed,
- 0x70, 0xb0, 0x77, 0xb7, 0x7e, 0xbe, 0x79, 0xb9,
- 0x6c, 0xac, 0x6b, 0xab, 0x62, 0xa2, 0x65, 0xa5,
- 0x48, 0x88, 0x4f, 0x8f, 0x46, 0x86, 0x41, 0x81,
- 0x54, 0x94, 0x53, 0x93, 0x5a, 0x9a, 0x5d, 0x9d,
- 0xe0, 0x20, 0xe7, 0x27, 0xee, 0x2e, 0xe9, 0x29,
- 0xfc, 0x3c, 0xfb, 0x3b, 0xf2, 0x32, 0xf5, 0x35,
- 0xd8, 0x18, 0xdf, 0x1f, 0xd6, 0x16, 0xd1, 0x11,
- 0xc4, 0x04, 0xc3, 0x03, 0xca, 0x0a, 0xcd, 0x0d,
- 0x90, 0x50, 0x97, 0x57, 0x9e, 0x5e, 0x99, 0x59,
- 0x8c, 0x4c, 0x8b, 0x4b, 0x82, 0x42, 0x85, 0x45,
- 0xa8, 0x68, 0xaf, 0x6f, 0xa6, 0x66, 0xa1, 0x61,
- 0xb4, 0x74, 0xb3, 0x73, 0xba, 0x7a, 0xbd, 0x7d,
- 0x47, 0x87, 0x40, 0x80, 0x49, 0x89, 0x4e, 0x8e,
- 0x5b, 0x9b, 0x5c, 0x9c, 0x55, 0x95, 0x52, 0x92,
- 0x7f, 0xbf, 0x78, 0xb8, 0x71, 0xb1, 0x76, 0xb6,
- 0x63, 0xa3, 0x64, 0xa4, 0x6d, 0xad, 0x6a, 0xaa,
- 0x37, 0xf7, 0x30, 0xf0, 0x39, 0xf9, 0x3e, 0xfe,
- 0x2b, 0xeb, 0x2c, 0xec, 0x25, 0xe5, 0x22, 0xe2,
- 0x0f, 0xcf, 0x08, 0xc8, 0x01, 0xc1, 0x06, 0xc6,
- 0x13, 0xd3, 0x14, 0xd4, 0x1d, 0xdd, 0x1a, 0xda,
- 0xa7, 0x67, 0xa0, 0x60, 0xa9, 0x69, 0xae, 0x6e,
- 0xbb, 0x7b, 0xbc, 0x7c, 0xb5, 0x75, 0xb2, 0x72,
- 0x9f, 0x5f, 0x98, 0x58, 0x91, 0x51, 0x96, 0x56,
- 0x83, 0x43, 0x84, 0x44, 0x8d, 0x4d, 0x8a, 0x4a,
- 0xd7, 0x17, 0xd0, 0x10, 0xd9, 0x19, 0xde, 0x1e,
- 0xcb, 0x0b, 0xcc, 0x0c, 0xc5, 0x05, 0xc2, 0x02,
- 0xef, 0x2f, 0xe8, 0x28, 0xe1, 0x21, 0xe6, 0x26,
- 0xf3, 0x33, 0xf4, 0x34, 0xfd, 0x3d, 0xfa, 0x3a
-};
-
-
-/* Returns V modulo 255 provided V is in the range -255,-254,...,509.
- */
-static inline __u8 mod255(int v)
-{
- if (v > 0) {
- if (v < 255) {
- return v;
- } else {
- return v - 255;
- }
- } else {
- return v + 255;
- }
-}
-
-
-/* Add two numbers in the field. Addition in this field is equivalent
- * to a bit-wise exclusive OR operation---subtraction is therefore
- * identical to addition.
- */
-static inline __u8 gfadd(__u8 a, __u8 b)
-{
- return a ^ b;
-}
-
-
-/* Add two vectors of numbers in the field. Each byte in A and B gets
- * added individually.
- */
-static inline unsigned long gfadd_long(unsigned long a, unsigned long b)
-{
- return a ^ b;
-}
-
-
-/* Multiply two numbers in the field:
- */
-static inline __u8 gfmul(__u8 a, __u8 b)
-{
- if (a && b) {
- return gfpow[mod255(gflog[a] + gflog[b])];
- } else {
- return 0;
- }
-}
-
-
-/* Just like gfmul, except we have already looked up the log of the
- * second number.
- */
-static inline __u8 gfmul_exp(__u8 a, int b)
-{
- if (a) {
- return gfpow[mod255(gflog[a] + b)];
- } else {
- return 0;
- }
-}
-
-
-/* Just like gfmul_exp, except that A is a vector of numbers. That
- * is, each byte in A gets multiplied by gfpow[mod255(B)].
- */
-static inline unsigned long gfmul_exp_long(unsigned long a, int b)
-{
- __u8 t;
-
- if (sizeof(long) == 4) {
- return (
- ((t = (__u32)a >> 24 & 0xff) ?
- (((__u32) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
- ((t = (__u32)a >> 16 & 0xff) ?
- (((__u32) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
- ((t = (__u32)a >> 8 & 0xff) ?
- (((__u32) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
- ((t = (__u32)a >> 0 & 0xff) ?
- (((__u32) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
- } else if (sizeof(long) == 8) {
- return (
- ((t = (__u64)a >> 56 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 56) : 0) |
- ((t = (__u64)a >> 48 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 48) : 0) |
- ((t = (__u64)a >> 40 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 40) : 0) |
- ((t = (__u64)a >> 32 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 32) : 0) |
- ((t = (__u64)a >> 24 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
- ((t = (__u64)a >> 16 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
- ((t = (__u64)a >> 8 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
- ((t = (__u64)a >> 0 & 0xff) ?
- (((__u64) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
- } else {
- TRACE_FUN(ft_t_any);
- TRACE_ABORT(-1, ft_t_err, "Error: size of long is %d bytes",
- (int)sizeof(long));
- }
-}
-
-
-/* Divide two numbers in the field. Returns a/b (modulo f(x)).
- */
-static inline __u8 gfdiv(__u8 a, __u8 b)
-{
- if (!b) {
- TRACE_FUN(ft_t_any);
- TRACE_ABORT(0xff, ft_t_bug, "Error: division by zero");
- } else if (a == 0) {
- return 0;
- } else {
- return gfpow[mod255(gflog[a] - gflog[b])];
- }
-}
-
-
-/* The following functions return the inverse of the matrix of the
- * linear system that needs to be solved to determine the error
- * magnitudes. The first deals with matrices of rank 3, while the
- * second deals with matrices of rank 2. The error indices are passed
- * in arguments L0,..,L2 (0=first sector, 31=last sector). The error
- * indices must be sorted in ascending order, i.e., L0<L1<L2.
- *
- * The linear system that needs to be solved for the error magnitudes
- * is A * b = s, where s is the known vector of syndromes, b is the
- * vector of error magnitudes and A in the ORDER=3 case:
- *
- * A_3 = {{1/r^L[0], 1/r^L[1], 1/r^L[2]},
- * { 1, 1, 1},
- * { r^L[0], r^L[1], r^L[2]}}
- */
-static inline int gfinv3(__u8 l0,
- __u8 l1,
- __u8 l2,
- Matrix Ainv)
-{
- __u8 det;
- __u8 t20, t10, t21, t12, t01, t02;
- int log_det;
-
- /* compute some intermediate results: */
- t20 = gfpow[l2 - l0]; /* t20 = r^l2/r^l0 */
- t10 = gfpow[l1 - l0]; /* t10 = r^l1/r^l0 */
- t21 = gfpow[l2 - l1]; /* t21 = r^l2/r^l1 */
- t12 = gfpow[l1 - l2 + 255]; /* t12 = r^l1/r^l2 */
- t01 = gfpow[l0 - l1 + 255]; /* t01 = r^l0/r^l1 */
- t02 = gfpow[l0 - l2 + 255]; /* t02 = r^l0/r^l2 */
- /* Calculate the determinant of matrix A_3^-1 (sometimes
- * called the Vandermonde determinant):
- */
- det = gfadd(t20, gfadd(t10, gfadd(t21, gfadd(t12, gfadd(t01, t02)))));
- if (!det) {
- TRACE_FUN(ft_t_any);
- TRACE_ABORT(0, ft_t_err,
- "Inversion failed (3 CRC errors, >0 CRC failures)");
- }
- log_det = 255 - gflog[det];
-
- /* Now, calculate all of the coefficients:
- */
- Ainv[0][0]= gfmul_exp(gfadd(gfpow[l1], gfpow[l2]), log_det);
- Ainv[0][1]= gfmul_exp(gfadd(t21, t12), log_det);
- Ainv[0][2]= gfmul_exp(gfadd(gfpow[255 - l1], gfpow[255 - l2]),log_det);
-
- Ainv[1][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l2]), log_det);
- Ainv[1][1]= gfmul_exp(gfadd(t20, t02), log_det);
- Ainv[1][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l2]),log_det);
-
- Ainv[2][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l1]), log_det);
- Ainv[2][1]= gfmul_exp(gfadd(t10, t01), log_det);
- Ainv[2][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l1]),log_det);
-
- return 1;
-}
-
-
-static inline int gfinv2(__u8 l0, __u8 l1, Matrix Ainv)
-{
- __u8 det;
- __u8 t1, t2;
- int log_det;
-
- t1 = gfpow[255 - l0];
- t2 = gfpow[255 - l1];
- det = gfadd(t1, t2);
- if (!det) {
- TRACE_FUN(ft_t_any);
- TRACE_ABORT(0, ft_t_err,
- "Inversion failed (2 CRC errors, >0 CRC failures)");
- }
- log_det = 255 - gflog[det];
-
- /* Now, calculate all of the coefficients:
- */
- Ainv[0][0] = Ainv[1][0] = gfpow[log_det];
-
- Ainv[0][1] = gfmul_exp(t2, log_det);
- Ainv[1][1] = gfmul_exp(t1, log_det);
-
- return 1;
-}
-
-
-/* Multiply matrix A by vector S and return result in vector B. M is
- * assumed to be of order NxN, S and B of order Nx1.
- */
-static inline void gfmat_mul(int n, Matrix A,
- __u8 *s, __u8 *b)
-{
- int i, j;
- __u8 dot_prod;
-
- for (i = 0; i < n; ++i) {
- dot_prod = 0;
- for (j = 0; j < n; ++j) {
- dot_prod = gfadd(dot_prod, gfmul(A[i][j], s[j]));
- }
- b[i] = dot_prod;
- }
-}
-
-
-
-/* The Reed Solomon ECC codes are computed over the N-th byte of each
- * block, where N=SECTOR_SIZE. There are up to 29 blocks of data, and
- * 3 blocks of ECC. The blocks are stored contiguously in memory. A
- * segment, consequently, is assumed to have at least 4 blocks: one or
- * more data blocks plus three ECC blocks.
- *
- * Notice: In QIC-80 speak, a CRC error is a sector with an incorrect
- * CRC. A CRC failure is a sector with incorrect data, but
- * a valid CRC. In the error control literature, the former
- * is usually called "erasure", the latter "error."
- */
-/* Compute the parity bytes for C columns of data, where C is the
- * number of bytes that fit into a long integer. We use a linear
- * feed-back register to do this. The parity bytes P[0], P[STRIDE],
- * P[2*STRIDE] are computed such that:
- *
- * x^k * p(x) + m(x) = 0 (modulo g(x))
- *
- * where k = NBLOCKS,
- * p(x) = P[0] + P[STRIDE]*x + P[2*STRIDE]*x^2, and
- * m(x) = sum_{i=0}^k m_i*x^i.
- * m_i = DATA[i*SECTOR_SIZE]
- */
-static inline void set_parity(unsigned long *data,
- int nblocks,
- unsigned long *p,
- int stride)
-{
- unsigned long p0, p1, p2, t1, t2, *end;
-
- end = data + nblocks * (FT_SECTOR_SIZE / sizeof(long));
- p0 = p1 = p2 = 0;
- while (data < end) {
- /* The new parity bytes p0_i, p1_i, p2_i are computed
- * from the old values p0_{i-1}, p1_{i-1}, p2_{i-1}
- * recursively as:
- *
- * p0_i = p1_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
- * p1_i = p2_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
- * p2_i = (m_{i-1} - p0_{i-1})
- *
- * With the initial condition: p0_0 = p1_0 = p2_0 = 0.
- */
- t1 = gfadd_long(*data, p0);
- /*
- * Multiply each byte in t1 by 0xc0:
- */
- if (sizeof(long) == 4) {
- t2= (((__u32) gfmul_c0[(__u32)t1 >> 24 & 0xff]) << 24 |
- ((__u32) gfmul_c0[(__u32)t1 >> 16 & 0xff]) << 16 |
- ((__u32) gfmul_c0[(__u32)t1 >> 8 & 0xff]) << 8 |
- ((__u32) gfmul_c0[(__u32)t1 >> 0 & 0xff]) << 0);
- } else if (sizeof(long) == 8) {
- t2= (((__u64) gfmul_c0[(__u64)t1 >> 56 & 0xff]) << 56 |
- ((__u64) gfmul_c0[(__u64)t1 >> 48 & 0xff]) << 48 |
- ((__u64) gfmul_c0[(__u64)t1 >> 40 & 0xff]) << 40 |
- ((__u64) gfmul_c0[(__u64)t1 >> 32 & 0xff]) << 32 |
- ((__u64) gfmul_c0[(__u64)t1 >> 24 & 0xff]) << 24 |
- ((__u64) gfmul_c0[(__u64)t1 >> 16 & 0xff]) << 16 |
- ((__u64) gfmul_c0[(__u64)t1 >> 8 & 0xff]) << 8 |
- ((__u64) gfmul_c0[(__u64)t1 >> 0 & 0xff]) << 0);
- } else {
- TRACE_FUN(ft_t_any);
- TRACE(ft_t_err, "Error: long is of size %d",
- (int) sizeof(long));
- TRACE_EXIT;
- }
- p0 = gfadd_long(t2, p1);
- p1 = gfadd_long(t2, p2);
- p2 = t1;
- data += FT_SECTOR_SIZE / sizeof(long);
- }
- *p = p0;
- p += stride;
- *p = p1;
- p += stride;
- *p = p2;
- return;
-}
-
-
-/* Compute the 3 syndrome values. DATA should point to the first byte
- * of the column for which the syndromes are desired. The syndromes
- * are computed over the first NBLOCKS of rows. The three bytes will
- * be placed in S[0], S[1], and S[2].
- *
- * S[i] is the value of the "message" polynomial m(x) evaluated at the
- * i-th root of the generator polynomial g(x).
- *
- * As g(x)=(x-r^-1)(x-1)(x-r^1) we evaluate the message polynomial at
- * x=r^-1 to get S[0], at x=r^0=1 to get S[1], and at x=r to get S[2].
- * This could be done directly and efficiently via the Horner scheme.
- * However, it would require multiplication tables for the factors
- * r^-1 (0xc3) and r (0x02). The following scheme does not require
- * any multiplication tables beyond what's needed for set_parity()
- * anyway and is slightly faster if there are no errors and slightly
- * slower if there are errors. The latter is hopefully the infrequent
- * case.
- *
- * To understand the alternative algorithm, notice that set_parity(m,
- * k, p) computes parity bytes such that:
- *
- * x^k * p(x) = m(x) (modulo g(x)).
- *
- * That is, to evaluate m(r^m), where r^m is a root of g(x), we can
- * simply evaluate (r^m)^k*p(r^m). Also, notice that p is 0 if and
- * only if s is zero. That is, if all parity bytes are 0, we know
- * there is no error in the data and consequently there is no need to
- * compute s(x) at all! In all other cases, we compute s(x) from p(x)
- * by evaluating (r^m)^k*p(r^m) for m=-1, m=0, and m=1. The p(x)
- * polynomial is evaluated via the Horner scheme.
- */
-static int compute_syndromes(unsigned long *data, int nblocks, unsigned long *s)
-{
- unsigned long p[3];
-
- set_parity(data, nblocks, p, 1);
- if (p[0] | p[1] | p[2]) {
- /* Some of the checked columns do not have a zero
- * syndrome. For simplicity, we compute the syndromes
- * for all columns that we have computed the
- * remainders for.
- */
- s[0] = gfmul_exp_long(
- gfadd_long(p[0],
- gfmul_exp_long(
- gfadd_long(p[1],
- gfmul_exp_long(p[2], -1)),
- -1)),
- -nblocks);
- s[1] = gfadd_long(gfadd_long(p[2], p[1]), p[0]);
- s[2] = gfmul_exp_long(
- gfadd_long(p[0],
- gfmul_exp_long(
- gfadd_long(p[1],
- gfmul_exp_long(p[2], 1)),
- 1)),
- nblocks);
- return 0;
- } else {
- return 1;
- }
-}
-
-
-/* Correct the block in the column pointed to by DATA. There are NBAD
- * CRC errors and their indices are in BAD_LOC[0], up to
- * BAD_LOC[NBAD-1]. If NBAD>1, Ainv holds the inverse of the matrix
- * of the linear system that needs to be solved to determine the error
- * magnitudes. S[0], S[1], and S[2] are the syndrome values. If row
- * j gets corrected, then bit j will be set in CORRECTION_MAP.
- */
-static inline int correct_block(__u8 *data, int nblocks,
- int nbad, int *bad_loc, Matrix Ainv,
- __u8 *s,
- SectorMap * correction_map)
-{
- int ncorrected = 0;
- int i;
- __u8 t1, t2;
- __u8 c0, c1, c2; /* check bytes */
- __u8 error_mag[3], log_error_mag;
- __u8 *dp, l, e;
- TRACE_FUN(ft_t_any);
-
- switch (nbad) {
- case 0:
- /* might have a CRC failure: */
- if (s[0] == 0) {
- /* more than one error */
- TRACE_ABORT(-1, ft_t_err,
- "ECC failed (0 CRC errors, >1 CRC failures)");
- }
- t1 = gfdiv(s[1], s[0]);
- if ((bad_loc[nbad++] = gflog[t1]) >= nblocks) {
- TRACE(ft_t_err,
- "ECC failed (0 CRC errors, >1 CRC failures)");
- TRACE_ABORT(-1, ft_t_err,
- "attempt to correct data at %d", bad_loc[0]);
- }
- error_mag[0] = s[1];
- break;
- case 1:
- t1 = gfadd(gfmul_exp(s[1], bad_loc[0]), s[2]);
- t2 = gfadd(gfmul_exp(s[0], bad_loc[0]), s[1]);
- if (t1 == 0 && t2 == 0) {
- /* one erasure, no error: */
- Ainv[0][0] = gfpow[bad_loc[0]];
- } else if (t1 == 0 || t2 == 0) {
- /* one erasure and more than one error: */
- TRACE_ABORT(-1, ft_t_err,
- "ECC failed (1 erasure, >1 error)");
- } else {
- /* one erasure, one error: */
- if ((bad_loc[nbad++] = gflog[gfdiv(t1, t2)])
- >= nblocks) {
- TRACE(ft_t_err, "ECC failed "
- "(1 CRC errors, >1 CRC failures)");
- TRACE_ABORT(-1, ft_t_err,
- "attempt to correct data at %d",
- bad_loc[1]);
- }
- if (!gfinv2(bad_loc[0], bad_loc[1], Ainv)) {
- /* inversion failed---must have more
- * than one error
- */
- TRACE_EXIT -1;
- }
- }
- /* FALL THROUGH TO ERROR MAGNITUDE COMPUTATION:
- */
- case 2:
- case 3:
- /* compute error magnitudes: */
- gfmat_mul(nbad, Ainv, s, error_mag);
- break;
-
- default:
- TRACE_ABORT(-1, ft_t_err,
- "Internal Error: number of CRC errors > 3");
- }
-
- /* Perform correction by adding ERROR_MAG[i] to the byte at
- * offset BAD_LOC[i]. Also add the value of the computed
- * error polynomial to the syndrome values. If the correction
- * was successful, the resulting check bytes should be zero
- * (i.e., the corrected data is a valid code word).
- */
- c0 = s[0];
- c1 = s[1];
- c2 = s[2];
- for (i = 0; i < nbad; ++i) {
- e = error_mag[i];
- if (e) {
- /* correct the byte at offset L by magnitude E: */
- l = bad_loc[i];
- dp = &data[l * FT_SECTOR_SIZE];
- *dp = gfadd(*dp, e);
- *correction_map |= 1 << l;
- ++ncorrected;
-
- log_error_mag = gflog[e];
- c0 = gfadd(c0, gfpow[mod255(log_error_mag - l)]);
- c1 = gfadd(c1, e);
- c2 = gfadd(c2, gfpow[mod255(log_error_mag + l)]);
- }
- }
- if (c0 || c1 || c2) {
- TRACE_ABORT(-1, ft_t_err,
- "ECC self-check failed, too many errors");
- }
- TRACE_EXIT ncorrected;
-}
-
-
-#if defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID)
-
-/* Perform a sanity check on the computed parity bytes:
- */
-static int sanity_check(unsigned long *data, int nblocks)
-{
- TRACE_FUN(ft_t_any);
- unsigned long s[3];
-
- if (!compute_syndromes(data, nblocks, s)) {
- TRACE_ABORT(0, ft_bug,
- "Internal Error: syndrome self-check failed");
- }
- TRACE_EXIT 1;
-}
-
-#endif /* defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID) */
-
-/* Compute the parity for an entire segment of data.
- */
-int ftape_ecc_set_segment_parity(struct memory_segment *mseg)
-{
- int i;
- __u8 *parity_bytes;
-
- parity_bytes = &mseg->data[(mseg->blocks - 3) * FT_SECTOR_SIZE];
- for (i = 0; i < FT_SECTOR_SIZE; i += sizeof(long)) {
- set_parity((unsigned long *) &mseg->data[i], mseg->blocks - 3,
- (unsigned long *) &parity_bytes[i],
- FT_SECTOR_SIZE / sizeof(long));
-#ifdef ECC_PARANOID
- if (!sanity_check((unsigned long *) &mseg->data[i],
- mseg->blocks)) {
- return -1;
- }
-#endif /* ECC_PARANOID */
- }
- return 0;
-}
-
-
-/* Checks and corrects (if possible) the segment MSEG. Returns one of
- * ECC_OK, ECC_CORRECTED, and ECC_FAILED.
- */
-int ftape_ecc_correct_data(struct memory_segment *mseg)
-{
- int col, i, result;
- int ncorrected = 0;
- int nerasures = 0; /* # of erasures (CRC errors) */
- int erasure_loc[3]; /* erasure locations */
- unsigned long ss[3];
- __u8 s[3];
- Matrix Ainv;
- TRACE_FUN(ft_t_flow);
-
- mseg->corrected = 0;
-
- /* find first column that has non-zero syndromes: */
- for (col = 0; col < FT_SECTOR_SIZE; col += sizeof(long)) {
- if (!compute_syndromes((unsigned long *) &mseg->data[col],
- mseg->blocks, ss)) {
- /* something is wrong---have to fix things */
- break;
- }
- }
- if (col >= FT_SECTOR_SIZE) {
- /* all syndromes are ok, therefore nothing to correct */
- TRACE_EXIT ECC_OK;
- }
- /* count the number of CRC errors if there were any: */
- if (mseg->read_bad) {
- for (i = 0; i < mseg->blocks; i++) {
- if (BAD_CHECK(mseg->read_bad, i)) {
- if (nerasures >= 3) {
- /* this is too much for ECC */
- TRACE_ABORT(ECC_FAILED, ft_t_err,
- "ECC failed (>3 CRC errors)");
- } /* if */
- erasure_loc[nerasures++] = i;
- }
- }
- }
- /*
- * If there are at least 2 CRC errors, determine inverse of matrix
- * of linear system to be solved:
- */
- switch (nerasures) {
- case 2:
- if (!gfinv2(erasure_loc[0], erasure_loc[1], Ainv)) {
- TRACE_EXIT ECC_FAILED;
- }
- break;
- case 3:
- if (!gfinv3(erasure_loc[0], erasure_loc[1],
- erasure_loc[2], Ainv)) {
- TRACE_EXIT ECC_FAILED;
- }
- break;
- default:
- /* this is not an error condition... */
- break;
- }
-
- do {
- for (i = 0; i < sizeof(long); ++i) {
- s[0] = ss[0];
- s[1] = ss[1];
- s[2] = ss[2];
- if (s[0] | s[1] | s[2]) {
-#ifdef BIG_ENDIAN
- result = correct_block(
- &mseg->data[col + sizeof(long) - 1 - i],
- mseg->blocks,
- nerasures,
- erasure_loc,
- Ainv,
- s,
- &mseg->corrected);
-#else
- result = correct_block(&mseg->data[col + i],
- mseg->blocks,
- nerasures,
- erasure_loc,
- Ainv,
- s,
- &mseg->corrected);
-#endif
- if (result < 0) {
- TRACE_EXIT ECC_FAILED;
- }
- ncorrected += result;
- }
- ss[0] >>= 8;
- ss[1] >>= 8;
- ss[2] >>= 8;
- }
-
-#ifdef ECC_SANITY_CHECK
- if (!sanity_check((unsigned long *) &mseg->data[col],
- mseg->blocks)) {
- TRACE_EXIT ECC_FAILED;
- }
-#endif /* ECC_SANITY_CHECK */
-
- /* find next column with non-zero syndromes: */
- while ((col += sizeof(long)) < FT_SECTOR_SIZE) {
- if (!compute_syndromes((unsigned long *)
- &mseg->data[col], mseg->blocks, ss)) {
- /* something is wrong---have to fix things */
- break;
- }
- }
- } while (col < FT_SECTOR_SIZE);
- if (ncorrected && nerasures == 0) {
- TRACE(ft_t_warn, "block contained error not caught by CRC");
- }
- TRACE((ncorrected > 0) ? ft_t_noise : ft_t_any, "number of corrections: %d", ncorrected);
- TRACE_EXIT ncorrected ? ECC_CORRECTED : ECC_OK;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-ecc.h b/drivers/char/ftape/lowlevel/ftape-ecc.h
deleted file mode 100644
index 4829146fe9a0..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-ecc.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _FTAPE_ECC_H_
-#define _FTAPE_ECC_H_
-
-/*
- * Copyright (C) 1993 Ning and David Mosberger.
- * Original:
- * Copyright (C) 1993 Bas Laarhoven.
- * Copyright (C) 1992 David L. Brown, Jr.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:11 $
- *
- * This file contains the definitions for the
- * Reed-Solomon error correction code
- * for the QIC-40/80 tape streamer device driver.
- */
-
-#include "../lowlevel/ftape-bsm.h"
-
-#define BAD_CLEAR(entry) ((entry)=0)
-#define BAD_SET(entry,sector) ((entry)|=(1<<(sector)))
-#define BAD_CHECK(entry,sector) ((entry)&(1<<(sector)))
-
-/*
- * Return values for ecc_correct_data:
- */
-enum {
- ECC_OK, /* Data was correct. */
- ECC_CORRECTED, /* Correctable error in data. */
- ECC_FAILED, /* Could not correct data. */
-};
-
-/*
- * Representation of an in memory segment. MARKED_BAD lists the
- * sectors that were marked bad during formatting. If the N-th sector
- * in a segment is marked bad, bit 1<<N will be set in MARKED_BAD.
- * The sectors should be read in from the disk and packed, as if the
- * bad sectors were not there, and the segment just contained fewer
- * sectors. READ_SECTORS is a bitmap of errors encountered while
- * reading the data. These offsets are relative to the packed data.
- * BLOCKS is a count of the sectors not marked bad. This is just to
- * prevent having to count the zero bits in MARKED_BAD each time this
- * is needed. DATA is the actual sector packed data from (or to) the
- * tape.
- */
- struct memory_segment {
- SectorMap marked_bad;
- SectorMap read_bad;
- int blocks;
- __u8 *data;
- SectorMap corrected;
- };
-
-/*
- * ecc.c defined global variables:
- */
-#ifdef TEST
-extern int ftape_ecc_tracing;
-#endif
-
-/*
- * ecc.c defined global functions:
- */
-extern int ftape_ecc_correct_data(struct memory_segment *data);
-extern int ftape_ecc_set_segment_parity(struct memory_segment *data);
-
-#endif /* _FTAPE_ECC_H_ */
diff --git a/drivers/char/ftape/lowlevel/ftape-format.c b/drivers/char/ftape/lowlevel/ftape-format.c
deleted file mode 100644
index 5dd4c59a3f34..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-format.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.c,v $
- * $Revision: 1.2.4.1 $
- * $Date: 1997/11/14 16:05:39 $
- *
- * This file contains the code to support formatting of floppy
- * tape cartridges with the QIC-40/80/3010/3020 floppy-tape
- * driver "ftape" for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-format.h"
-
-#if defined(TESTING)
-#define FT_FMT_SEGS_PER_BUF 50
-#else
-#define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT))
-#endif
-
-static spinlock_t ftape_format_lock;
-
-/*
- * first segment of the new buffer
- */
-static int switch_segment;
-
-/*
- * at most 256 segments fit into one 32 kb buffer. Even TR-1 cartridges have
- * more than this many segments per track, so better be careful.
- *
- * buffer_struct *buff: buffer to store the formatting coordinates in
- * int start: starting segment for this buffer.
- * int spt: segments per track
- *
- * Note: segment ids are relative to the start of the track here.
- */
-static void setup_format_buffer(buffer_struct *buff, int start, int spt,
- __u8 gap3)
-{
- int to_do = spt - start;
- TRACE_FUN(ft_t_flow);
-
- if (to_do > FT_FMT_SEGS_PER_BUF) {
- to_do = FT_FMT_SEGS_PER_BUF;
- }
- buff->ptr = buff->address;
- buff->remaining = to_do * FT_SECTORS_PER_SEGMENT; /* # sectors */
- buff->bytes = buff->remaining * 4; /* need 4 bytes per sector */
- buff->gap3 = gap3;
- buff->segment_id = start;
- buff->next_segment = start + to_do;
- if (buff->next_segment >= spt) {
- buff->next_segment = 0; /* 0 means: stop runner */
- }
- buff->status = waiting; /* tells the isr that it can use
- * this buffer
- */
- TRACE_EXIT;
-}
-
-
-/*
- * start formatting a new track.
- */
-int ftape_format_track(const unsigned int track, const __u8 gap3)
-{
- unsigned long flags;
- buffer_struct *tail, *head;
- int status;
- TRACE_FUN(ft_t_flow);
-
- TRACE_CATCH(ftape_ready_wait(ftape_timeout.pause, &status),);
- if (track & 1) {
- if (!(status & QIC_STATUS_AT_EOT)) {
- TRACE_CATCH(ftape_seek_to_eot(),);
- }
- } else {
- if (!(status & QIC_STATUS_AT_BOT)) {
- TRACE_CATCH(ftape_seek_to_bot(),);
- }
- }
- ftape_abort_operation(); /* this sets ft_head = ft_tail = 0 */
- ftape_set_state(formatting);
-
- TRACE(ft_t_noise,
- "Formatting track %d, logical: from segment %d to %d",
- track, track * ft_segments_per_track,
- (track + 1) * ft_segments_per_track - 1);
-
- /*
- * initialize the buffer switching protocol for this track
- */
- head = ftape_get_buffer(ft_queue_head); /* tape isn't running yet */
- tail = ftape_get_buffer(ft_queue_tail); /* tape isn't running yet */
- switch_segment = 0;
- do {
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- setup_format_buffer(tail, switch_segment,
- ft_segments_per_track, gap3);
- switch_segment = tail->next_segment;
- } while ((switch_segment != 0) &&
- ((tail = ftape_next_buffer(ft_queue_tail)) != head));
- /* go */
- head->status = formatting;
- TRACE_CATCH(ftape_seek_head_to_track(track),);
- TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),);
- spin_lock_irqsave(&ftape_format_lock, flags);
- TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags));
- spin_unlock_irqrestore(&ftape_format_lock, flags);
- TRACE_EXIT 0;
-}
-
-/* return segment id of segment currently being formatted and do the
- * buffer switching stuff.
- */
-int ftape_format_status(unsigned int *segment_id)
-{
- buffer_struct *tail = ftape_get_buffer(ft_queue_tail);
- int result;
- TRACE_FUN(ft_t_flow);
-
- while (switch_segment != 0 &&
- ftape_get_buffer(ft_queue_head) != tail) {
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- /* need more buffers, first wait for empty buffer
- */
- TRACE_CATCH(ftape_wait_segment(formatting),);
- /* don't worry for gap3. If we ever hit this piece of code,
- * then all buffer already have the correct gap3 set!
- */
- setup_format_buffer(tail, switch_segment,
- ft_segments_per_track, tail->gap3);
- switch_segment = tail->next_segment;
- if (switch_segment != 0) {
- tail = ftape_next_buffer(ft_queue_tail);
- }
- }
- /* should runner stop ?
- */
- if (ft_runner_status == aborting || ft_runner_status == do_abort) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
- TRACE(ft_t_warn, "Error formatting segment %d",
- ftape_get_buffer(ft_queue_head)->segment_id);
- (void)ftape_abort_operation();
- TRACE_EXIT (head->status != error) ? -EAGAIN : -EIO;
- }
- /*
- * don't care if the timer expires, this is just kind of a
- * "select" operation that lets the calling process sleep
- * until something has happened
- */
- if (fdc_interrupt_wait(5 * FT_SECOND) < 0) {
- TRACE(ft_t_noise, "End of track %d at segment %d",
- ft_location.track,
- ftape_get_buffer(ft_queue_head)->segment_id);
- result = 1; /* end of track, unlock module */
- } else {
- result = 0;
- }
- /*
- * the calling process should use the seg id to determine
- * which parts of the dma buffers can be safely overwritten
- * with new data.
- */
- *segment_id = ftape_get_buffer(ft_queue_head)->segment_id;
- /*
- * Internally we start counting segment ids from the start of
- * each track when formatting, but externally we keep them
- * relative to the start of the tape:
- */
- *segment_id += ft_location.track * ft_segments_per_track;
- TRACE_EXIT result;
-}
-
-/*
- * The segment id is relative to the start of the tape
- */
-int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm)
-{
- int result;
- int verify_done = 0;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Verifying segment %d", segment_id);
-
- if (ft_driver_state != verifying) {
- TRACE(ft_t_noise, "calling ftape_abort_operation");
- if (ftape_abort_operation() < 0) {
- TRACE(ft_t_err, "ftape_abort_operation failed");
- TRACE_EXIT -EIO;
- }
- }
- *bsm = 0x00000000;
- ftape_set_state(verifying);
- for (;;) {
- buffer_struct *tail;
- /*
- * Allow escape from this loop on signal
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- /*
- * Search all full buffers for the first matching the
- * wanted segment. Clear other buffers on the fly.
- */
- tail = ftape_get_buffer(ft_queue_tail);
- while (!verify_done && tail->status == done) {
- /*
- * Allow escape from this loop on signal !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- if (tail->segment_id == segment_id) {
- /* If out buffer is already full,
- * return its contents.
- */
- TRACE(ft_t_flow, "found segment in cache: %d",
- segment_id);
- if ((tail->soft_error_map |
- tail->hard_error_map) != 0) {
- TRACE(ft_t_info,"bsm[%d] = 0x%08lx",
- segment_id,
- (unsigned long)
- (tail->soft_error_map |
- tail->hard_error_map));
- *bsm = (tail->soft_error_map |
- tail->hard_error_map);
- }
- verify_done = 1;
- } else {
- TRACE(ft_t_flow,"zapping segment in cache: %d",
- tail->segment_id);
- }
- tail->status = waiting;
- tail = ftape_next_buffer(ft_queue_tail);
- }
- if (!verify_done && tail->status == verifying) {
- if (tail->segment_id == segment_id) {
- switch(ftape_wait_segment(verifying)) {
- case 0:
- break;
- case -EINTR:
- TRACE_ABORT(-EINTR, ft_t_warn,
- "interrupted by "
- "non-blockable signal");
- break;
- default:
- ftape_abort_operation();
- ftape_set_state(verifying);
- /* be picky */
- TRACE_ABORT(-EIO, ft_t_warn,
- "wait_segment failed");
- }
- } else {
- /* We're reading the wrong segment,
- * stop runner.
- */
- TRACE(ft_t_noise, "verifying wrong segment");
- ftape_abort_operation();
- ftape_set_state(verifying);
- }
- }
- /* should runner stop ?
- */
- if (ft_runner_status == aborting) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
- if (head->status == error ||
- head->status == verifying) {
- /* no data or overrun error */
- head->status = waiting;
- }
- TRACE_CATCH(ftape_dumb_stop(),);
- } else {
- /* If just passed last segment on tape: wait
- * for BOT or EOT mark. Sets ft_runner_status to
- * idle if at lEOT and successful
- */
- TRACE_CATCH(ftape_handle_logical_eot(),);
- }
- if (verify_done) {
- TRACE_EXIT 0;
- }
- /* Now at least one buffer is idle!
- * Restart runner & tape if needed.
- */
- /* We could optimize the following a little bit. We know that
- * the bad sector map is empty.
- */
- tail = ftape_get_buffer(ft_queue_tail);
- if (tail->status == waiting) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
-
- ftape_setup_new_segment(head, segment_id, -1);
- ftape_calc_next_cluster(head);
- if (ft_runner_status == idle) {
- result = ftape_start_tape(segment_id,
- head->sector_offset);
- switch(result) {
- case 0:
- break;
- case -ETIME:
- case -EINTR:
- TRACE_ABORT(result, ft_t_err, "Error: "
- "segment %d unreachable",
- segment_id);
- break;
- default:
- *bsm = EMPTY_SEGMENT;
- TRACE_EXIT 0;
- break;
- }
- }
- head->status = verifying;
- fdc_setup_read_write(head, FDC_VERIFY);
- }
- }
- /* not reached */
- TRACE_EXIT -EIO;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-format.h b/drivers/char/ftape/lowlevel/ftape-format.h
deleted file mode 100644
index f15161566643..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-format.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _FTAPE_FORMAT_H
-#define _FTAPE_FORMAT_H
-
-/*
- * Copyright (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-format.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:13 $
- *
- * This file contains the low level definitions for the
- * formatting support for the QIC-40/80/3010/3020 floppy-tape
- * driver "ftape" for Linux.
- */
-
-#ifdef __KERNEL__
-extern int ftape_format_track(const unsigned int track, const __u8 gap3);
-extern int ftape_format_status(unsigned int *segment_id);
-extern int ftape_verify_segment(const unsigned int segment_id, SectorMap *bsm);
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c
deleted file mode 100644
index 4998132a81d1..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-init.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * This file contains the code that interfaces the kernel
- * for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include <linux/qic117.h>
-#ifdef CONFIG_ZFTAPE
-#include <linux/zftape.h>
-#endif
-
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-proc.h"
-#include "../lowlevel/ftape-tracing.h"
-
-
-#if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL)
-static int ft_tracing = -1;
-#endif
-
-
-/* Called by modules package when installing the driver
- * or by kernel during the initialization phase
- */
-static int __init ftape_init(void)
-{
- TRACE_FUN(ft_t_flow);
-
-#ifdef MODULE
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
- if (ft_tracing != -1) {
- ftape_tracing = ft_tracing;
- }
-#endif
- printk(KERN_INFO FTAPE_VERSION "\n");
- if (TRACE_LEVEL >= ft_t_info) {
- printk(
-KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n"
-KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n"
-KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n");
- }
-#else /* !MODULE */
- /* print a short no-nonsense boot message */
- printk(KERN_INFO FTAPE_VERSION "\n");
-#endif /* MODULE */
- TRACE(ft_t_info, "installing QIC-117 floppy tape hardware drive ... ");
- TRACE(ft_t_info, "ftape_init @ 0x%p", ftape_init);
- /* Allocate the DMA buffers. They are deallocated at cleanup() time.
- */
-#ifdef TESTING
-#ifdef MODULE
- while (ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS) < 0) {
- ftape_sleep(FT_SECOND/20);
- if (signal_pending(current)) {
- (void)ftape_set_nr_buffers(0);
- TRACE(ft_t_bug,
- "Killed by signal while allocating buffers.");
- TRACE_ABORT(-EINTR,
- ft_t_bug, "Free up memory and retry");
- }
- }
-#else
- TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
- (void)ftape_set_nr_buffers(0));
-#endif
-#else
- TRACE_CATCH(ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS),
- (void)ftape_set_nr_buffers(0));
-#endif
- ft_drive_sel = -1;
- ft_failure = 1; /* inhibit any operation but open */
- ftape_udelay_calibrate(); /* must be before fdc_wait_calibrate ! */
- fdc_wait_calibrate();
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
- (void)ftape_proc_init();
-#endif
-#ifdef CONFIG_ZFTAPE
- (void)zft_init();
-#endif
- TRACE_EXIT 0;
-}
-
-module_param(ft_fdc_base, uint, 0);
-MODULE_PARM_DESC(ft_fdc_base, "Base address of FDC controller.");
-module_param(ft_fdc_irq, uint, 0);
-MODULE_PARM_DESC(ft_fdc_irq, "IRQ (interrupt channel) to use.");
-module_param(ft_fdc_dma, uint, 0);
-MODULE_PARM_DESC(ft_fdc_dma, "DMA channel to use.");
-module_param(ft_fdc_threshold, uint, 0);
-MODULE_PARM_DESC(ft_fdc_threshold, "Threshold of the FDC Fifo.");
-module_param(ft_fdc_rate_limit, uint, 0);
-MODULE_PARM_DESC(ft_fdc_rate_limit, "Maximal data rate for FDC.");
-module_param(ft_probe_fc10, bool, 0);
-MODULE_PARM_DESC(ft_probe_fc10,
- "If non-zero, probe for a Colorado FC-10/FC-20 controller.");
-module_param(ft_mach2, bool, 0);
-MODULE_PARM_DESC(ft_mach2,
- "If non-zero, probe for a Mountain MACH-2 controller.");
-#if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL)
-module_param(ft_tracing, int, 0644);
-MODULE_PARM_DESC(ft_tracing,
- "Amount of debugging output, 0 <= tracing <= 8, default 3.");
-#endif
-
-MODULE_AUTHOR(
- "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl), "
- "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no), "
- "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)");
-MODULE_DESCRIPTION(
- "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives.");
-MODULE_LICENSE("GPL");
-
-static void __exit ftape_exit(void)
-{
- TRACE_FUN(ft_t_flow);
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
- ftape_proc_destroy();
-#endif
- (void)ftape_set_nr_buffers(0);
- printk(KERN_INFO "ftape: unloaded.\n");
- TRACE_EXIT;
-}
-
-module_init(ftape_init);
-module_exit(ftape_exit);
diff --git a/drivers/char/ftape/lowlevel/ftape-init.h b/drivers/char/ftape/lowlevel/ftape-init.h
deleted file mode 100644
index 99a7b8ab086f..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-init.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _FTAPE_INIT_H
-#define _FTAPE_INIT_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-init.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:16 $
- *
- * This file contains the definitions for the interface to
- * the Linux kernel for floppy tape driver ftape.
- *
- */
-
-#include <linux/linkage.h>
-#include <linux/signal.h>
-
-#define _NEVER_BLOCK (sigmask(SIGKILL) | sigmask(SIGSTOP))
-#define _DONT_BLOCK (_NEVER_BLOCK | sigmask(SIGINT))
-#define _DO_BLOCK (sigmask(SIGPIPE))
-
-#ifndef QIC117_TAPE_MAJOR
-#define QIC117_TAPE_MAJOR 27
-#endif
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-io.c b/drivers/char/ftape/lowlevel/ftape-io.c
deleted file mode 100644
index 259015aeff55..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-io.c
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996 Kai Harrekilde-Petersen,
- * (C) 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/11/11 14:02:36 $
- *
- * This file contains the general control functions for the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/system.h>
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-#include <linux/delay.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-calibr.h"
-
-/* Global vars.
- */
-/* NOTE: sectors start numbering at 1, all others at 0 ! */
-ft_timeout_table ftape_timeout;
-unsigned int ftape_tape_len;
-volatile qic117_cmd_t ftape_current_command;
-const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS;
-int ftape_might_be_off_track;
-
-/* Local vars.
- */
-static int diagnostic_mode;
-static unsigned int ftape_udelay_count;
-static unsigned int ftape_udelay_time;
-
-void ftape_udelay(unsigned int usecs)
-{
- volatile int count = (ftape_udelay_count * usecs +
- ftape_udelay_count - 1) / ftape_udelay_time;
- volatile int i;
-
- while (count-- > 0) {
- for (i = 0; i < 20; ++i);
- }
-}
-
-void ftape_udelay_calibrate(void)
-{
- ftape_calibrate("ftape_udelay",
- ftape_udelay, &ftape_udelay_count, &ftape_udelay_time);
-}
-
-/* Delay (msec) routine.
- */
-void ftape_sleep(unsigned int time)
-{
- TRACE_FUN(ft_t_any);
-
- time *= 1000; /* msecs -> usecs */
- if (time < FT_USPT) {
- /* Time too small for scheduler, do a busy wait ! */
- ftape_udelay(time);
- } else {
- long timeout;
- unsigned long flags;
- unsigned int ticks = (time + FT_USPT - 1) / FT_USPT;
-
- TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks);
- timeout = ticks;
- save_flags(flags);
- sti();
- msleep_interruptible(jiffies_to_msecs(timeout));
- /* Mmm. Isn't current->blocked == 0xffffffff ?
- */
- if (signal_pending(current)) {
- TRACE(ft_t_err, "awoken by non-blocked signal :-(");
- }
- restore_flags(flags);
- }
- TRACE_EXIT;
-}
-
-/* send a command or parameter to the drive
- * Generates # of step pulses.
- */
-static inline int ft_send_to_drive(int arg)
-{
- /* Always wait for a command_timeout period to separate
- * individuals commands and/or parameters.
- */
- ftape_sleep(3 * FT_MILLISECOND);
- /* Keep cylinder nr within range, step towards home if possible.
- */
- if (ftape_current_cylinder >= arg) {
- return fdc_seek(ftape_current_cylinder - arg);
- } else {
- return fdc_seek(ftape_current_cylinder + arg);
- }
-}
-
-/* forward */ int ftape_report_raw_drive_status(int *status);
-
-static int ft_check_cmd_restrictions(qic117_cmd_t command)
-{
- int status = -1;
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_flow, "%s", qic117_cmds[command].name);
- /* A new motion command during an uninterruptible (motion)
- * command requires a ready status before the new command can
- * be issued. Otherwise a new motion command needs to be
- * checked against required status.
- */
- if (qic117_cmds[command].cmd_type == motion &&
- qic117_cmds[ftape_current_command].non_intr) {
- ftape_report_raw_drive_status(&status);
- if ((status & QIC_STATUS_READY) == 0) {
- TRACE(ft_t_noise,
- "motion cmd (%d) during non-intr cmd (%d)",
- command, ftape_current_command);
- TRACE(ft_t_noise, "waiting until drive gets ready");
- ftape_ready_wait(ftape_timeout.seek,
- &status);
- }
- }
- if (qic117_cmds[command].mask != 0) {
- __u8 difference;
- /* Some commands do require a certain status:
- */
- if (status == -1) { /* not yet set */
- ftape_report_raw_drive_status(&status);
- }
- difference = ((status ^ qic117_cmds[command].state) &
- qic117_cmds[command].mask);
- /* Wait until the drive gets
- * ready. This may last forever if
- * the drive never gets ready...
- */
- while ((difference & QIC_STATUS_READY) != 0) {
- TRACE(ft_t_noise, "command %d issued while not ready",
- command);
- TRACE(ft_t_noise, "waiting until drive gets ready");
- if (ftape_ready_wait(ftape_timeout.seek,
- &status) == -EINTR) {
- /* Bail out on signal !
- */
- TRACE_ABORT(-EINTR, ft_t_warn,
- "interrupted by non-blockable signal");
- }
- difference = ((status ^ qic117_cmds[command].state) &
- qic117_cmds[command].mask);
- }
- while ((difference & QIC_STATUS_ERROR) != 0) {
- int err;
- qic117_cmd_t cmd;
-
- TRACE(ft_t_noise,
- "command %d issued while error pending",
- command);
- TRACE(ft_t_noise, "clearing error status");
- ftape_report_error(&err, &cmd, 1);
- ftape_report_raw_drive_status(&status);
- difference = ((status ^ qic117_cmds[command].state) &
- qic117_cmds[command].mask);
- if ((difference & QIC_STATUS_ERROR) != 0) {
- /* Bail out on fatal signal !
- */
- FT_SIGNAL_EXIT(_NEVER_BLOCK);
- }
- }
- if (difference) {
- /* Any remaining difference can't be solved
- * here.
- */
- if (difference & (QIC_STATUS_CARTRIDGE_PRESENT |
- QIC_STATUS_NEW_CARTRIDGE |
- QIC_STATUS_REFERENCED)) {
- TRACE(ft_t_warn,
- "Fatal: tape removed or reinserted !");
- ft_failure = 1;
- } else {
- TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x",
- status & qic117_cmds[command].mask,
- qic117_cmds[command].state);
- }
- TRACE_EXIT -EIO;
- }
- if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) {
- TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!");
- }
- }
- TRACE_EXIT 0;
-}
-
-/* Issue a tape command:
- */
-int ftape_command(qic117_cmd_t command)
-{
- int result = 0;
- static int level;
- TRACE_FUN(ft_t_any);
-
- if ((unsigned int)command > NR_ITEMS(qic117_cmds)) {
- /* This is a bug we'll want to know about too.
- */
- TRACE_ABORT(-EIO, ft_t_bug, "bug - bad command: %d", command);
- }
- if (++level > 5) { /* This is a bug we'll want to know about. */
- --level;
- TRACE_ABORT(-EIO, ft_t_bug, "bug - recursion for command: %d",
- command);
- }
- /* disable logging and restriction check for some commands,
- * check all other commands that have a prescribed starting
- * status.
- */
- if (diagnostic_mode) {
- TRACE(ft_t_flow, "diagnostic command %d", command);
- } else if (command == QIC_REPORT_DRIVE_STATUS ||
- command == QIC_REPORT_NEXT_BIT) {
- TRACE(ft_t_any, "%s", qic117_cmds[command].name);
- } else {
- TRACE_CATCH(ft_check_cmd_restrictions(command), --level);
- }
- /* Now all conditions are met or result was < 0.
- */
- result = ft_send_to_drive((unsigned int)command);
- if (qic117_cmds[command].cmd_type == motion &&
- command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) {
- ft_location.known = 0;
- }
- ftape_current_command = command;
- --level;
- TRACE_EXIT result;
-}
-
-/* Send a tape command parameter:
- * Generates command # of step pulses.
- * Skips tape-status call !
- */
-int ftape_parameter(unsigned int parameter)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE(ft_t_flow, "called with parameter = %d", parameter);
- TRACE_EXIT ft_send_to_drive(parameter + 2);
-}
-
-/* Wait for the drive to get ready.
- * timeout time in milli-seconds
- * Returned status is valid if result != -EIO
- *
- * Should we allow to be killed by SIGINT? (^C)
- * Would be nice at least for large timeouts.
- */
-int ftape_ready_wait(unsigned int timeout, int *status)
-{
- unsigned long t0;
- unsigned int poll_delay;
- int signal_retries;
- TRACE_FUN(ft_t_any);
-
- /* the following ** REALLY ** reduces the system load when
- * e.g. one simply rewinds or retensions. The tape is slow
- * anyway. It is really not necessary to detect error
- * conditions with 1/10 seconds granularity
- *
- * On my AMD 133MHZ 486: 100 ms: 23% system load
- * 1 sec: 5%
- * 5 sec: 0.6%, yeah
- */
- if (timeout <= FT_SECOND) {
- poll_delay = 100 * FT_MILLISECOND;
- signal_retries = 20; /* two seconds */
- } else if (timeout < 20 * FT_SECOND) {
- TRACE(ft_t_flow, "setting poll delay to 1 second");
- poll_delay = FT_SECOND;
- signal_retries = 2; /* two seconds */
- } else {
- TRACE(ft_t_flow, "setting poll delay to 5 seconds");
- poll_delay = 5 * FT_SECOND;
- signal_retries = 1; /* five seconds */
- }
- for (;;) {
- t0 = jiffies;
- TRACE_CATCH(ftape_report_raw_drive_status(status),);
- if (*status & QIC_STATUS_READY) {
- TRACE_EXIT 0;
- }
- if (!signal_retries--) {
- FT_SIGNAL_EXIT(_NEVER_BLOCK);
- }
- if ((int)timeout >= 0) {
- /* this will fail when jiffies wraps around about
- * once every year :-)
- */
- timeout -= ((jiffies - t0) * FT_SECOND) / HZ;
- if (timeout <= 0) {
- TRACE_ABORT(-ETIME, ft_t_err, "timeout");
- }
- ftape_sleep(poll_delay);
- timeout -= poll_delay;
- } else {
- ftape_sleep(poll_delay);
- }
- }
- TRACE_EXIT -ETIME;
-}
-
-/* Issue command and wait up to timeout milli seconds for drive ready
- */
-int ftape_command_wait(qic117_cmd_t command, unsigned int timeout, int *status)
-{
- int result;
-
- /* Drive should be ready, issue command
- */
- result = ftape_command(command);
- if (result >= 0) {
- result = ftape_ready_wait(timeout, status);
- }
- return result;
-}
-
-static int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status)
-{
- int result;
-
- /* Drive should be ready, issue command
- */
- result = ftape_parameter(parm);
- if (result >= 0) {
- result = ftape_ready_wait(timeout, status);
- }
- return result;
-}
-
-/*--------------------------------------------------------------------------
- * Report operations
- */
-
-/* Query the drive about its status. The command is sent and
- result_length bits of status are returned (2 extra bits are read
- for start and stop). */
-
-int ftape_report_operation(int *status,
- qic117_cmd_t command,
- int result_length)
-{
- int i, st3;
- unsigned int t0;
- unsigned int dt;
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(ftape_command(command),);
- t0 = ftape_timestamp();
- i = 0;
- do {
- ++i;
- ftape_sleep(3 * FT_MILLISECOND); /* see remark below */
- TRACE_CATCH(fdc_sense_drive_status(&st3),);
- dt = ftape_timediff(t0, ftape_timestamp());
- /* Ack should be asserted within Ttimout + Tack = 6 msec.
- * Looks like some drives fail to do this so extend this
- * period to 300 msec.
- */
- } while (!(st3 & ST3_TRACK_0) && dt < 300000);
- if (!(st3 & ST3_TRACK_0)) {
- TRACE(ft_t_err,
- "No acknowledge after %u msec. (%i iter)", dt / 1000, i);
- TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge");
- }
- /* dt may be larger than expected because of other tasks
- * scheduled while we were sleeping.
- */
- if (i > 1 && dt > 6000) {
- TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)",
- dt / 1000, i);
- }
- *status = 0;
- for (i = 0; i < result_length + 1; i++) {
- TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),);
- TRACE_CATCH(fdc_sense_drive_status(&st3),);
- if (i < result_length) {
- *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i;
- } else if ((st3 & ST3_TRACK_0) == 0) {
- TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit");
- }
- }
- /* this command will put track zero and index back into normal state */
- (void)ftape_command(QIC_REPORT_NEXT_BIT);
- TRACE_EXIT 0;
-}
-
-/* Report the current drive status. */
-
-int ftape_report_raw_drive_status(int *status)
-{
- int result;
- int count = 0;
- TRACE_FUN(ft_t_any);
-
- do {
- result = ftape_report_operation(status,
- QIC_REPORT_DRIVE_STATUS, 8);
- } while (result < 0 && ++count <= 3);
- if (result < 0) {
- TRACE_ABORT(-EIO, ft_t_err,
- "report_operation failed after %d trials", count);
- }
- if ((*status & 0xff) == 0xff) {
- TRACE_ABORT(-EIO, ft_t_err,
- "impossible drive status 0xff");
- }
- if (*status & QIC_STATUS_READY) {
- ftape_current_command = QIC_NO_COMMAND; /* completed */
- }
- ft_last_status.status.drive_status = (__u8)(*status & 0xff);
- TRACE_EXIT 0;
-}
-
-int ftape_report_drive_status(int *status)
-{
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(ftape_report_raw_drive_status(status),);
- if (*status & QIC_STATUS_NEW_CARTRIDGE ||
- !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) {
- ft_failure = 1; /* will inhibit further operations */
- TRACE_EXIT -EIO;
- }
- if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) {
- /* Let caller handle all errors */
- TRACE_ABORT(1, ft_t_warn, "warning: error status set!");
- }
- TRACE_EXIT 0;
-}
-
-int ftape_report_error(unsigned int *error,
- qic117_cmd_t *command, int report)
-{
- static const ftape_error ftape_errors[] = QIC117_ERRORS;
- int code;
- TRACE_FUN(ft_t_any);
-
- TRACE_CATCH(ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16),);
- *error = (unsigned int)(code & 0xff);
- *command = (qic117_cmd_t)((code>>8)&0xff);
- /* remember hardware status, maybe useful for status ioctls
- */
- ft_last_error.error.command = (__u8)*command;
- ft_last_error.error.error = (__u8)*error;
- if (!report) {
- TRACE_EXIT 0;
- }
- if (*error == 0) {
- TRACE_ABORT(0, ft_t_info, "No error");
- }
- TRACE(ft_t_info, "errorcode: %d", *error);
- if (*error < NR_ITEMS(ftape_errors)) {
- TRACE(ft_t_noise, "%sFatal ERROR:",
- (ftape_errors[*error].fatal ? "" : "Non-"));
- TRACE(ft_t_noise, "%s ...", ftape_errors[*error].message);
- } else {
- TRACE(ft_t_noise, "Unknown ERROR !");
- }
- if ((unsigned int)*command < NR_ITEMS(qic117_cmds) &&
- qic117_cmds[*command].name != NULL) {
- TRACE(ft_t_noise, "... caused by command \'%s\'",
- qic117_cmds[*command].name);
- } else {
- TRACE(ft_t_noise, "... caused by unknown command %d",
- *command);
- }
- TRACE_EXIT 0;
-}
-
-int ftape_report_configuration(qic_model *model,
- unsigned int *rate,
- int *qic_std,
- int *tape_len)
-{
- int result;
- int config;
- int status;
- static const unsigned int qic_rates[ 4] = { 250, 2000, 500, 1000 };
- TRACE_FUN(ft_t_any);
-
- result = ftape_report_operation(&config,
- QIC_REPORT_DRIVE_CONFIGURATION, 8);
- if (result < 0) {
- ft_last_status.status.drive_config = (__u8)0x00;
- *model = prehistoric;
- *rate = 500;
- *qic_std = QIC_TAPE_QIC40;
- *tape_len = 205;
- TRACE_EXIT 0;
- } else {
- ft_last_status.status.drive_config = (__u8)(config & 0xff);
- }
- *rate = qic_rates[(config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT];
- result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8);
- if (result < 0) {
- ft_last_status.status.tape_status = (__u8)0x00;
- /* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid.
- */
- *qic_std = (config & QIC_CONFIG_80) ?
- QIC_TAPE_QIC80 : QIC_TAPE_QIC40;
- /* ?? how's about 425ft tapes? */
- *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 0;
- *model = pre_qic117c;
- result = 0;
- } else {
- ft_last_status.status.tape_status = (__u8)(status & 0xff);
- *model = post_qic117b;
- TRACE(ft_t_any, "report tape status result = %02x", status);
- /* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is
- * invalid.
- */
- switch (status & QIC_TAPE_STD_MASK) {
- case QIC_TAPE_QIC40:
- case QIC_TAPE_QIC80:
- case QIC_TAPE_QIC3020:
- case QIC_TAPE_QIC3010:
- *qic_std = status & QIC_TAPE_STD_MASK;
- break;
- default:
- *qic_std = -1;
- break;
- }
- switch (status & QIC_TAPE_LEN_MASK) {
- case QIC_TAPE_205FT:
- /* 205 or 425+ ft 550 Oe tape */
- *tape_len = 0;
- break;
- case QIC_TAPE_307FT:
- /* 307.5 ft 550 Oe Extended Length (XL) tape */
- *tape_len = 307;
- break;
- case QIC_TAPE_VARIABLE:
- /* Variable length 550 Oe tape */
- *tape_len = 0;
- break;
- case QIC_TAPE_1100FT:
- /* 1100 ft 550 Oe tape */
- *tape_len = 1100;
- break;
- case QIC_TAPE_FLEX:
- /* Variable length 900 Oe tape */
- *tape_len = 0;
- break;
- default:
- *tape_len = -1;
- break;
- }
- if (*qic_std == -1 || *tape_len == -1) {
- TRACE(ft_t_any,
- "post qic-117b spec drive with unknown tape");
- }
- result = *tape_len == -1 ? -EIO : 0;
- if (status & QIC_TAPE_WIDE) {
- switch (*qic_std) {
- case QIC_TAPE_QIC80:
- TRACE(ft_t_info, "TR-1 tape detected");
- break;
- case QIC_TAPE_QIC3010:
- TRACE(ft_t_info, "TR-2 tape detected");
- break;
- case QIC_TAPE_QIC3020:
- TRACE(ft_t_info, "TR-3 tape detected");
- break;
- default:
- TRACE(ft_t_warn,
- "Unknown Travan tape type detected");
- break;
- }
- }
- }
- TRACE_EXIT (result < 0) ? -EIO : 0;
-}
-
-static int ftape_report_rom_version(int *version)
-{
-
- if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) {
- return -EIO;
- } else {
- return 0;
- }
-}
-
-void ftape_report_vendor_id(unsigned int *id)
-{
- int result;
- TRACE_FUN(ft_t_any);
-
- /* We'll try to get a vendor id from the drive. First
- * according to the QIC-117 spec, a 16-bit id is requested.
- * If that fails we'll try an 8-bit version, otherwise we'll
- * try an undocumented query.
- */
- result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16);
- if (result < 0) {
- result = ftape_report_operation((int *) id,
- QIC_REPORT_VENDOR_ID, 8);
- if (result < 0) {
- /* The following is an undocumented call found
- * in the CMS code.
- */
- result = ftape_report_operation((int *) id, 24, 8);
- if (result < 0) {
- *id = UNKNOWN_VENDOR;
- } else {
- TRACE(ft_t_noise, "got old 8 bit id: %04x",
- *id);
- *id |= 0x20000;
- }
- } else {
- TRACE(ft_t_noise, "got 8 bit id: %04x", *id);
- *id |= 0x10000;
- }
- } else {
- TRACE(ft_t_noise, "got 16 bit id: %04x", *id);
- }
- if (*id == 0x0047) {
- int version;
- int sign;
-
- if (ftape_report_rom_version(&version) < 0) {
- TRACE(ft_t_bug, "report rom version failed");
- TRACE_EXIT;
- }
- TRACE(ft_t_noise, "CMS rom version: %d", version);
- ftape_command(QIC_ENTER_DIAGNOSTIC_1);
- ftape_command(QIC_ENTER_DIAGNOSTIC_1);
- diagnostic_mode = 1;
- if (ftape_report_operation(&sign, 9, 8) < 0) {
- unsigned int error;
- qic117_cmd_t command;
-
- ftape_report_error(&error, &command, 1);
- ftape_command(QIC_ENTER_PRIMARY_MODE);
- diagnostic_mode = 0;
- TRACE_EXIT; /* failure ! */
- } else {
- TRACE(ft_t_noise, "CMS signature: %02x", sign);
- }
- if (sign == 0xa5) {
- result = ftape_report_operation(&sign, 37, 8);
- if (result < 0) {
- if (version >= 63) {
- *id = 0x8880;
- TRACE(ft_t_noise,
- "This is an Iomega drive !");
- } else {
- *id = 0x0047;
- TRACE(ft_t_noise,
- "This is a real CMS drive !");
- }
- } else {
- *id = 0x0047;
- TRACE(ft_t_noise, "CMS status: %d", sign);
- }
- } else {
- *id = UNKNOWN_VENDOR;
- }
- ftape_command(QIC_ENTER_PRIMARY_MODE);
- diagnostic_mode = 0;
- }
- TRACE_EXIT;
-}
-
-static int qic_rate_code(unsigned int rate)
-{
- switch (rate) {
- case 250:
- return QIC_CONFIG_RATE_250;
- case 500:
- return QIC_CONFIG_RATE_500;
- case 1000:
- return QIC_CONFIG_RATE_1000;
- case 2000:
- return QIC_CONFIG_RATE_2000;
- default:
- return QIC_CONFIG_RATE_500;
- }
-}
-
-static int ftape_set_rate_test(unsigned int *max_rate)
-{
- unsigned int error;
- qic117_cmd_t command;
- int status;
- int supported = 0;
- TRACE_FUN(ft_t_any);
-
- /* Check if the drive does support the select rate command
- * by testing all different settings. If any one is accepted
- * we assume the command is supported, else not.
- */
- for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) {
- if (ftape_command(QIC_SELECT_RATE) < 0) {
- continue;
- }
- if (ftape_parameter_wait(qic_rate_code(*max_rate),
- 1 * FT_SECOND, &status) < 0) {
- continue;
- }
- if (status & QIC_STATUS_ERROR) {
- ftape_report_error(&error, &command, 0);
- continue;
- }
- supported = 1; /* did accept a request */
- break;
- }
- TRACE(ft_t_noise, "Select Rate command is%s supported",
- supported ? "" : " not");
- TRACE_EXIT supported;
-}
-
-int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std)
-{
- int status;
- int result = 0;
- unsigned int data_rate = new_rate;
- static int supported;
- int rate_changed = 0;
- qic_model dummy_model;
- unsigned int dummy_qic_std, dummy_tape_len;
- TRACE_FUN(ft_t_any);
-
- if (ft_drive_max_rate == 0) { /* first time */
- supported = ftape_set_rate_test(&ft_drive_max_rate);
- }
- if (supported) {
- ftape_command(QIC_SELECT_RATE);
- result = ftape_parameter_wait(qic_rate_code(new_rate),
- 1 * FT_SECOND, &status);
- if (result >= 0 && !(status & QIC_STATUS_ERROR)) {
- rate_changed = 1;
- }
- }
- TRACE_CATCH(result = ftape_report_configuration(&dummy_model,
- &data_rate,
- &dummy_qic_std,
- &dummy_tape_len),);
- if (data_rate != new_rate) {
- if (!supported) {
- TRACE(ft_t_warn, "Rate change not supported!");
- } else if (rate_changed) {
- TRACE(ft_t_warn, "Requested: %d, got %d",
- new_rate, data_rate);
- } else {
- TRACE(ft_t_warn, "Rate change failed!");
- }
- result = -EINVAL;
- }
- /*
- * Set data rate and write precompensation as specified:
- *
- * | QIC-40/80 | QIC-3010/3020
- * rate | precomp | precomp
- * ----------+-------------+--------------
- * 250 Kbps. | 250 ns. | 0 ns.
- * 500 Kbps. | 125 ns. | 0 ns.
- * 1 Mbps. | 42 ns. | 0 ns.
- * 2 Mbps | N/A | 0 ns.
- */
- if ((qic_std == QIC_TAPE_QIC40 && data_rate > 500) ||
- (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) {
- TRACE_ABORT(-EINVAL,
- ft_t_warn, "Datarate too high for QIC-mode");
- }
- TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL);
- ft_data_rate = data_rate;
- if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) {
- switch (data_rate) {
- case 250:
- fdc_set_write_precomp(250);
- break;
- default:
- case 500:
- fdc_set_write_precomp(125);
- break;
- case 1000:
- fdc_set_write_precomp(42);
- break;
- }
- } else {
- fdc_set_write_precomp(0);
- }
- TRACE_EXIT result;
-}
-
-/* The next two functions are used to cope with excessive overrun errors
- */
-int ftape_increase_threshold(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (fdc.type < i82077 || ft_fdc_threshold >= 12) {
- TRACE_ABORT(-EIO, ft_t_err, "cannot increase fifo threshold");
- }
- if (fdc_fifo_threshold(++ft_fdc_threshold, NULL, NULL, NULL) < 0) {
- TRACE(ft_t_err, "cannot increase fifo threshold");
- ft_fdc_threshold --;
- fdc_reset();
- }
- TRACE(ft_t_info, "New FIFO threshold: %d", ft_fdc_threshold);
- TRACE_EXIT 0;
-}
-
-int ftape_half_data_rate(void)
-{
- if (ft_data_rate < 500) {
- return -1;
- }
- if (ftape_set_data_rate(ft_data_rate / 2, ft_qic_std) < 0) {
- return -EIO;
- }
- ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
- return 0;
-}
-
-/* Seek the head to the specified track.
- */
-int ftape_seek_head_to_track(unsigned int track)
-{
- int status;
- TRACE_FUN(ft_t_any);
-
- ft_location.track = -1; /* remains set in case of error */
- if (track >= ft_tracks_per_tape) {
- TRACE_ABORT(-EINVAL, ft_t_bug, "track out of bounds");
- }
- TRACE(ft_t_flow, "seeking track %d", track);
- TRACE_CATCH(ftape_command(QIC_SEEK_HEAD_TO_TRACK),);
- TRACE_CATCH(ftape_parameter_wait(track, ftape_timeout.head_seek,
- &status),);
- ft_location.track = track;
- ftape_might_be_off_track = 0;
- TRACE_EXIT 0;
-}
-
-int ftape_wakeup_drive(wake_up_types method)
-{
- int status;
- int motor_on = 0;
- TRACE_FUN(ft_t_any);
-
- switch (method) {
- case wake_up_colorado:
- TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),);
- TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),);
- break;
- case wake_up_mountain:
- TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),);
- ftape_sleep(FT_MILLISECOND); /* NEEDED */
- TRACE_CATCH(ftape_parameter(18),);
- break;
- case wake_up_insight:
- ftape_sleep(100 * FT_MILLISECOND);
- motor_on = 1;
- fdc_motor(motor_on); /* enable is done by motor-on */
- case no_wake_up:
- break;
- default:
- TRACE_EXIT -ENODEV; /* unknown wakeup method */
- break;
- }
- /* If wakeup succeeded we shouldn't get an error here..
- */
- TRACE_CATCH(ftape_report_raw_drive_status(&status),
- if (motor_on) {
- fdc_motor(0);
- });
- TRACE_EXIT 0;
-}
-
-int ftape_put_drive_to_sleep(wake_up_types method)
-{
- TRACE_FUN(ft_t_any);
-
- switch (method) {
- case wake_up_colorado:
- TRACE_CATCH(ftape_command(QIC_PHANTOM_DESELECT),);
- break;
- case wake_up_mountain:
- TRACE_CATCH(ftape_command(QIC_SOFT_DESELECT),);
- break;
- case wake_up_insight:
- fdc_motor(0); /* enable is done by motor-on */
- case no_wake_up: /* no wakeup / no sleep ! */
- break;
- default:
- TRACE_EXIT -ENODEV; /* unknown wakeup method */
- }
- TRACE_EXIT 0;
-}
-
-int ftape_reset_drive(void)
-{
- int result = 0;
- int status;
- unsigned int err_code;
- qic117_cmd_t err_command;
- int i;
- TRACE_FUN(ft_t_any);
-
- /* We want to re-establish contact with our drive. Fire a
- * number of reset commands (single step pulses) and pray for
- * success.
- */
- for (i = 0; i < 2; ++i) {
- TRACE(ft_t_flow, "Resetting fdc");
- fdc_reset();
- ftape_sleep(10 * FT_MILLISECOND);
- TRACE(ft_t_flow, "Reset command to drive");
- result = ftape_command(QIC_RESET);
- if (result == 0) {
- ftape_sleep(1 * FT_SECOND); /* drive not
- * accessible
- * during 1 second
- */
- TRACE(ft_t_flow, "Re-selecting drive");
-
- /* Strange, the QIC-117 specs don't mention
- * this but the drive gets deselected after a
- * soft reset ! So we need to enable it
- * again.
- */
- if (ftape_wakeup_drive(ft_drive_type.wake_up) < 0) {
- TRACE(ft_t_err, "Wakeup failed !");
- }
- TRACE(ft_t_flow, "Waiting until drive gets ready");
- result= ftape_ready_wait(ftape_timeout.reset, &status);
- if (result == 0 && (status & QIC_STATUS_ERROR)) {
- result = ftape_report_error(&err_code,
- &err_command, 1);
- if (result == 0 && err_code == 27) {
- /* Okay, drive saw reset
- * command and responded as it
- * should
- */
- break;
- } else {
- result = -EIO;
- }
- } else {
- result = -EIO;
- }
- }
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- }
- if (result != 0) {
- TRACE(ft_t_err, "General failure to reset tape drive");
- } else {
- /* Restore correct settings: keep original rate
- */
- ftape_set_data_rate(ft_data_rate, ft_qic_std);
- }
- ftape_init_drive_needed = 1;
- TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-io.h b/drivers/char/ftape/lowlevel/ftape-io.h
deleted file mode 100644
index 26a7baad8717..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-io.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _FTAPE_IO_H
-#define _FTAPE_IO_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:18 $
- *
- * This file contains definitions for the glue part of the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/qic117.h>
-#include <linux/ftape-vendors.h>
-
-typedef struct {
- unsigned int seek;
- unsigned int reset;
- unsigned int rewind;
- unsigned int head_seek;
- unsigned int stop;
- unsigned int pause;
-} ft_timeout_table;
-
-typedef enum {
- prehistoric, pre_qic117c, post_qic117b, post_qic117d
-} qic_model;
-
-/*
- * ftape-io.c defined global vars.
- */
-extern ft_timeout_table ftape_timeout;
-extern unsigned int ftape_tape_len;
-extern volatile qic117_cmd_t ftape_current_command;
-extern const struct qic117_command_table qic117_cmds[];
-extern int ftape_might_be_off_track;
-
-/*
- * ftape-io.c defined global functions.
- */
-extern void ftape_udelay(unsigned int usecs);
-extern void ftape_udelay_calibrate(void);
-extern void ftape_sleep(unsigned int time);
-extern void ftape_report_vendor_id(unsigned int *id);
-extern int ftape_command(qic117_cmd_t command);
-extern int ftape_command_wait(qic117_cmd_t command,
- unsigned int timeout,
- int *status);
-extern int ftape_parameter(unsigned int parameter);
-extern int ftape_report_operation(int *status,
- qic117_cmd_t command,
- int result_length);
-extern int ftape_report_configuration(qic_model *model,
- unsigned int *rate,
- int *qic_std,
- int *tape_len);
-extern int ftape_report_drive_status(int *status);
-extern int ftape_report_raw_drive_status(int *status);
-extern int ftape_report_status(int *status);
-extern int ftape_ready_wait(unsigned int timeout, int *status);
-extern int ftape_seek_head_to_track(unsigned int track);
-extern int ftape_set_data_rate(unsigned int new_rate, unsigned int qic_std);
-extern int ftape_report_error(unsigned int *error,
- qic117_cmd_t *command,
- int report);
-extern int ftape_reset_drive(void);
-extern int ftape_put_drive_to_sleep(wake_up_types method);
-extern int ftape_wakeup_drive(wake_up_types method);
-extern int ftape_increase_threshold(void);
-extern int ftape_half_data_rate(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-proc.c b/drivers/char/ftape/lowlevel/ftape-proc.c
deleted file mode 100644
index e805b15e0a12..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-proc.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.c,v $
- * $Revision: 1.11 $
- * $Date: 1997/10/24 14:47:37 $
- *
- * This file contains the procfs interface for the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
-
- * Old code removed, switched to dynamic proc entry.
- */
-
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
-
-#include <linux/proc_fs.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include <linux/qic117.h>
-
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-proc.h"
-#include "../lowlevel/ftape-tracing.h"
-
-static size_t get_driver_info(char *buf)
-{
- const char *debug_level[] = { "bugs" ,
- "errors",
- "warnings",
- "informational",
- "noisy",
- "program flow",
- "fdc and dma",
- "data flow",
- "anything" };
-
- return sprintf(buf,
- "version : %s\n"
- "used data rate: %d kbit/sec\n"
- "dma memory : %d kb\n"
- "debug messages: %s\n",
- FTAPE_VERSION,
- ft_data_rate,
- FT_BUFF_SIZE * ft_nr_buffers >> 10,
- debug_level[TRACE_LEVEL]);
-}
-
-static size_t get_tapedrive_info(char *buf)
-{
- return sprintf(buf,
- "vendor id : 0x%04x\n"
- "drive name: %s\n"
- "wind speed: %d ips\n"
- "wakeup : %s\n"
- "max. rate : %d kbit/sec\n",
- ft_drive_type.vendor_id,
- ft_drive_type.name,
- ft_drive_type.speed,
- ((ft_drive_type.wake_up == no_wake_up)
- ? "No wakeup needed" :
- ((ft_drive_type.wake_up == wake_up_colorado)
- ? "Colorado" :
- ((ft_drive_type.wake_up == wake_up_mountain)
- ? "Mountain" :
- ((ft_drive_type.wake_up == wake_up_insight)
- ? "Motor on" :
- "Unknown")))),
- ft_drive_max_rate);
-}
-
-static size_t get_cartridge_info(char *buf)
-{
- if (ftape_init_drive_needed) {
- return sprintf(buf, "uninitialized\n");
- }
- if (ft_no_tape) {
- return sprintf(buf, "no cartridge inserted\n");
- }
- return sprintf(buf,
- "segments : %5d\n"
- "tracks : %5d\n"
- "length : %5dft\n"
- "formatted : %3s\n"
- "writable : %3s\n"
- "QIC spec. : QIC-%s\n"
- "fmt-code : %1d\n",
- ft_segments_per_track,
- ft_tracks_per_tape,
- ftape_tape_len,
- (ft_formatted == 1) ? "yes" : "no",
- (ft_write_protected == 1) ? "no" : "yes",
- ((ft_qic_std == QIC_TAPE_QIC40) ? "40" :
- ((ft_qic_std == QIC_TAPE_QIC80) ? "80" :
- ((ft_qic_std == QIC_TAPE_QIC3010) ? "3010" :
- ((ft_qic_std == QIC_TAPE_QIC3020) ? "3020" :
- "???")))),
- ft_format_code);
-}
-
-static size_t get_controller_info(char *buf)
-{
- const char *fdc_name[] = { "no fdc",
- "i8272",
- "i82077",
- "i82077AA",
- "Colorado FC-10 or FC-20",
- "i82078",
- "i82078_1" };
-
- return sprintf(buf,
- "FDC type : %s\n"
- "FDC base : 0x%03x\n"
- "FDC irq : %d\n"
- "FDC dma : %d\n"
- "FDC thr. : %d\n"
- "max. rate : %d kbit/sec\n",
- ft_mach2 ? "Mountain MACH-2" : fdc_name[fdc.type],
- fdc.sra, fdc.irq, fdc.dma,
- ft_fdc_threshold, ft_fdc_max_rate);
-}
-
-static size_t get_history_info(char *buf)
-{
- size_t len;
-
- len = sprintf(buf,
- "\nFDC isr statistics\n"
- " id_am_errors : %3d\n"
- " id_crc_errors : %3d\n"
- " data_am_errors : %3d\n"
- " data_crc_errors : %3d\n"
- " overrun_errors : %3d\n"
- " no_data_errors : %3d\n"
- " retries : %3d\n",
- ft_history.id_am_errors, ft_history.id_crc_errors,
- ft_history.data_am_errors, ft_history.data_crc_errors,
- ft_history.overrun_errors, ft_history.no_data_errors,
- ft_history.retries);
- len += sprintf(buf + len,
- "\nECC statistics\n"
- " crc_errors : %3d\n"
- " crc_failures : %3d\n"
- " ecc_failures : %3d\n"
- " sectors corrected: %3d\n",
- ft_history.crc_errors, ft_history.crc_failures,
- ft_history.ecc_failures, ft_history.corrected);
- len += sprintf(buf + len,
- "\ntape quality statistics\n"
- " media defects : %3d\n",
- ft_history.defects);
- len += sprintf(buf + len,
- "\ntape motion statistics\n"
- " repositions : %3d\n",
- ft_history.rewinds);
- return len;
-}
-
-static int ftape_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *ptr = page;
- size_t len;
-
- ptr += sprintf(ptr, "Kernel Driver\n\n");
- ptr += get_driver_info(ptr);
- ptr += sprintf(ptr, "\nTape Drive\n\n");
- ptr += get_tapedrive_info(ptr);
- ptr += sprintf(ptr, "\nFDC Controller\n\n");
- ptr += get_controller_info(ptr);
- ptr += sprintf(ptr, "\nTape Cartridge\n\n");
- ptr += get_cartridge_info(ptr);
- ptr += sprintf(ptr, "\nHistory Record\n\n");
- ptr += get_history_info(ptr);
-
- len = strlen(page);
- *start = NULL;
- if (off+count >= len) {
- *eof = 1;
- } else {
- *eof = 0;
- }
- return len;
-}
-
-int __init ftape_proc_init(void)
-{
- return create_proc_read_entry("ftape", 0, &proc_root,
- ftape_read_proc, NULL) != NULL;
-}
-
-void ftape_proc_destroy(void)
-{
- remove_proc_entry("ftape", &proc_root);
-}
-
-#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) */
diff --git a/drivers/char/ftape/lowlevel/ftape-proc.h b/drivers/char/ftape/lowlevel/ftape-proc.h
deleted file mode 100644
index 264dfcc1d22d..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-proc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _FTAPE_PROC_H
-#define _FTAPE_PROC_H
-
-/*
- * Copyright (C) 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:20 $
- *
- * This file contains definitions for the procfs interface of the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/proc_fs.h>
-
-extern int ftape_proc_init(void);
-extern void ftape_proc_destroy(void);
-
-#endif
diff --git a/drivers/char/ftape/lowlevel/ftape-read.c b/drivers/char/ftape/lowlevel/ftape-read.c
deleted file mode 100644
index d967d8cd86dc..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-read.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.c,v $
- * $Revision: 1.6 $
- * $Date: 1997/10/21 14:39:22 $
- *
- * This file contains the reading code
- * for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/* Global vars.
- */
-
-/* Local vars.
- */
-
-void ftape_zap_read_buffers(void)
-{
- int i;
-
- for (i = 0; i < ft_nr_buffers; ++i) {
-/* changed to "fit" with dynamic allocation of tape_buffer. --khp */
- ft_buffer[i]->status = waiting;
- ft_buffer[i]->bytes = 0;
- ft_buffer[i]->skip = 0;
- ft_buffer[i]->retry = 0;
- }
-/* ftape_reset_buffer(); */
-}
-
-static SectorMap convert_sector_map(buffer_struct * buff)
-{
- int i = 0;
- SectorMap bad_map = ftape_get_bad_sector_entry(buff->segment_id);
- SectorMap src_map = buff->soft_error_map | buff->hard_error_map;
- SectorMap dst_map = 0;
- TRACE_FUN(ft_t_any);
-
- if (bad_map || src_map) {
- TRACE(ft_t_flow, "bad_map = 0x%08lx", (long) bad_map);
- TRACE(ft_t_flow, "src_map = 0x%08lx", (long) src_map);
- }
- while (bad_map) {
- while ((bad_map & 1) == 0) {
- if (src_map & 1) {
- dst_map |= (1 << i);
- }
- src_map >>= 1;
- bad_map >>= 1;
- ++i;
- }
- /* (bad_map & 1) == 1 */
- src_map >>= 1;
- bad_map >>= 1;
- }
- if (src_map) {
- dst_map |= (src_map << i);
- }
- if (dst_map) {
- TRACE(ft_t_flow, "dst_map = 0x%08lx", (long) dst_map);
- }
- TRACE_EXIT dst_map;
-}
-
-static int correct_and_copy_fraction(buffer_struct *buff, __u8 * destination,
- int start, int size)
-{
- struct memory_segment mseg;
- int result;
- SectorMap read_bad;
- TRACE_FUN(ft_t_any);
-
- mseg.read_bad = convert_sector_map(buff);
- mseg.marked_bad = 0; /* not used... */
- mseg.blocks = buff->bytes / FT_SECTOR_SIZE;
- mseg.data = buff->address;
- /* If there are no data sectors we can skip this segment.
- */
- if (mseg.blocks <= 3) {
- TRACE_ABORT(0, ft_t_noise, "empty segment");
- }
- read_bad = mseg.read_bad;
- ft_history.crc_errors += count_ones(read_bad);
- result = ftape_ecc_correct_data(&mseg);
- if (read_bad != 0 || mseg.corrected != 0) {
- TRACE(ft_t_noise, "crc error map: 0x%08lx", (unsigned long)read_bad);
- TRACE(ft_t_noise, "corrected map: 0x%08lx", (unsigned long)mseg.corrected);
- ft_history.corrected += count_ones(mseg.corrected);
- }
- if (result == ECC_CORRECTED || result == ECC_OK) {
- if (result == ECC_CORRECTED) {
- TRACE(ft_t_info, "ecc corrected segment: %d", buff->segment_id);
- }
- if(start < 0) {
- start= 0;
- }
- if((start+size) > ((mseg.blocks - 3) * FT_SECTOR_SIZE)) {
- size = (mseg.blocks - 3) * FT_SECTOR_SIZE - start;
- }
- if (size < 0) {
- size= 0;
- }
- if(size > 0) {
- memcpy(destination + start, mseg.data + start, size);
- }
- if ((read_bad ^ mseg.corrected) & mseg.corrected) {
- /* sectors corrected without crc errors set */
- ft_history.crc_failures++;
- }
- TRACE_EXIT size; /* (mseg.blocks - 3) * FT_SECTOR_SIZE; */
- } else {
- ft_history.ecc_failures++;
- TRACE_ABORT(-EAGAIN,
- ft_t_err, "ecc failure on segment %d",
- buff->segment_id);
- }
- TRACE_EXIT 0;
-}
-
-/* Read given segment into buffer at address.
- */
-int ftape_read_segment_fraction(const int segment_id,
- void *address,
- const ft_read_mode_t read_mode,
- const int start,
- const int size)
-{
- int result = 0;
- int retry = 0;
- int bytes_read = 0;
- int read_done = 0;
- TRACE_FUN(ft_t_flow);
-
- ft_history.used |= 1;
- TRACE(ft_t_data_flow, "segment_id = %d", segment_id);
- if (ft_driver_state != reading) {
- TRACE(ft_t_noise, "calling ftape_abort_operation");
- TRACE_CATCH(ftape_abort_operation(),);
- ftape_set_state(reading);
- }
- for(;;) {
- buffer_struct *tail;
- /* Allow escape from this loop on signal !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- /* Search all full buffers for the first matching the
- * wanted segment. Clear other buffers on the fly.
- */
- tail = ftape_get_buffer(ft_queue_tail);
- while (!read_done && tail->status == done) {
- /* Allow escape from this loop on signal !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- if (tail->segment_id == segment_id) {
- /* If out buffer is already full,
- * return its contents.
- */
- TRACE(ft_t_flow, "found segment in cache: %d",
- segment_id);
- if (tail->deleted) {
- /* Return a value that
- * read_header_segment
- * understands. As this
- * should only occur when
- * searching for the header
- * segments it shouldn't be
- * misinterpreted elsewhere.
- */
- TRACE_EXIT 0;
- }
- result = correct_and_copy_fraction(
- tail,
- address,
- start,
- size);
- TRACE(ft_t_flow, "segment contains (bytes): %d",
- result);
- if (result < 0) {
- if (result != -EAGAIN) {
- TRACE_EXIT result;
- }
- /* keep read_done == 0, will
- * trigger
- * ftape_abort_operation
- * because reading wrong
- * segment.
- */
- TRACE(ft_t_err, "ecc failed, retry");
- ++retry;
- } else {
- read_done = 1;
- bytes_read = result;
- }
- } else {
- TRACE(ft_t_flow,"zapping segment in cache: %d",
- tail->segment_id);
- }
- tail->status = waiting;
- tail = ftape_next_buffer(ft_queue_tail);
- }
- if (!read_done && tail->status == reading) {
- if (tail->segment_id == segment_id) {
- switch(ftape_wait_segment(reading)) {
- case 0:
- break;
- case -EINTR:
- TRACE_ABORT(-EINTR, ft_t_warn,
- "interrupted by "
- "non-blockable signal");
- break;
- default:
- TRACE(ft_t_noise,
- "wait_segment failed");
- ftape_abort_operation();
- ftape_set_state(reading);
- break;
- }
- } else {
- /* We're reading the wrong segment,
- * stop runner.
- */
- TRACE(ft_t_noise, "reading wrong segment");
- ftape_abort_operation();
- ftape_set_state(reading);
- }
- }
- /* should runner stop ?
- */
- if (ft_runner_status == aborting) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
- switch(head->status) {
- case error:
- ft_history.defects +=
- count_ones(head->hard_error_map);
- case reading:
- head->status = waiting;
- break;
- default:
- break;
- }
- TRACE_CATCH(ftape_dumb_stop(),);
- } else {
- /* If just passed last segment on tape: wait
- * for BOT or EOT mark. Sets ft_runner_status to
- * idle if at lEOT and successful
- */
- TRACE_CATCH(ftape_handle_logical_eot(),);
- }
- /* If we got a segment: quit, or else retry up to limit.
- *
- * If segment to read is empty, do not start runner for it,
- * but wait for next read call.
- */
- if (read_done ||
- ftape_get_bad_sector_entry(segment_id) == EMPTY_SEGMENT ) {
- /* bytes_read = 0; should still be zero */
- TRACE_EXIT bytes_read;
-
- }
- if (retry > FT_RETRIES_ON_ECC_ERROR) {
- ft_history.defects++;
- TRACE_ABORT(-ENODATA, ft_t_err,
- "too many retries on ecc failure");
- }
- /* Now at least one buffer is empty !
- * Restart runner & tape if needed.
- */
- TRACE(ft_t_any, "head: %d, tail: %d, ft_runner_status: %d",
- ftape_buffer_id(ft_queue_head),
- ftape_buffer_id(ft_queue_tail),
- ft_runner_status);
- TRACE(ft_t_any, "buffer[].status, [head]: %d, [tail]: %d",
- ftape_get_buffer(ft_queue_head)->status,
- ftape_get_buffer(ft_queue_tail)->status);
- tail = ftape_get_buffer(ft_queue_tail);
- if (tail->status == waiting) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
-
- ftape_setup_new_segment(head, segment_id, -1);
- if (read_mode == FT_RD_SINGLE) {
- /* disable read-ahead */
- head->next_segment = 0;
- }
- ftape_calc_next_cluster(head);
- if (ft_runner_status == idle) {
- result = ftape_start_tape(segment_id,
- head->sector_offset);
- if (result < 0) {
- TRACE_ABORT(result, ft_t_err, "Error: "
- "segment %d unreachable",
- segment_id);
- }
- }
- head->status = reading;
- fdc_setup_read_write(head, FDC_READ);
- }
- }
- /* not reached */
- TRACE_EXIT -EIO;
-}
-
-int ftape_read_header_segment(__u8 *address)
-{
- int result;
- int header_segment;
- int first_failed = 0;
- int status;
- TRACE_FUN(ft_t_flow);
-
- ft_used_header_segment = -1;
- TRACE_CATCH(ftape_report_drive_status(&status),);
- TRACE(ft_t_flow, "reading...");
- /* We're looking for the first header segment.
- * A header segment cannot contain bad sectors, therefor at the
- * tape start, segments with bad sectors are (according to QIC-40/80)
- * written with deleted data marks and must be skipped.
- */
- memset(address, '\0', (FT_SECTORS_PER_SEGMENT - 3) * FT_SECTOR_SIZE);
- result = 0;
-#define HEADER_SEGMENT_BOUNDARY 68 /* why not 42? */
- for (header_segment = 0;
- header_segment < HEADER_SEGMENT_BOUNDARY && result == 0;
- ++header_segment) {
- /* Set no read-ahead, the isr will force read-ahead whenever
- * it encounters deleted data !
- */
- result = ftape_read_segment(header_segment,
- address,
- FT_RD_SINGLE);
- if (result < 0 && !first_failed) {
- TRACE(ft_t_err, "header segment damaged, trying backup");
- first_failed = 1;
- result = 0; /* force read of next (backup) segment */
- }
- }
- if (result < 0 || header_segment >= HEADER_SEGMENT_BOUNDARY) {
- TRACE_ABORT(-EIO, ft_t_err,
- "no readable header segment found");
- }
- TRACE_CATCH(ftape_abort_operation(),);
- ft_used_header_segment = header_segment;
- result = ftape_decode_header_segment(address);
- TRACE_EXIT result;
-}
-
-int ftape_decode_header_segment(__u8 *address)
-{
- unsigned int max_floppy_side;
- unsigned int max_floppy_track;
- unsigned int max_floppy_sector;
- unsigned int new_tape_len;
- TRACE_FUN(ft_t_flow);
-
- if (GET4(address, FT_SIGNATURE) == FT_D2G_MAGIC) {
- /* Ditto 2GB header segment. They encrypt the bad sector map.
- * We decrypt it and store them in normal format.
- * I hope this is correct.
- */
- int i;
- TRACE(ft_t_warn,
- "Found Ditto 2GB tape, "
- "trying to decrypt bad sector map");
- for (i=256; i < 29 * FT_SECTOR_SIZE; i++) {
- address[i] = ~(address[i] - (i&0xff));
- }
- PUT4(address, 0,FT_HSEG_MAGIC);
- } else if (GET4(address, FT_SIGNATURE) != FT_HSEG_MAGIC) {
- TRACE_ABORT(-EIO, ft_t_err,
- "wrong signature in header segment");
- }
- ft_format_code = (ft_format_type) address[FT_FMT_CODE];
- if (ft_format_code != fmt_big) {
- ft_header_segment_1 = GET2(address, FT_HSEG_1);
- ft_header_segment_2 = GET2(address, FT_HSEG_2);
- ft_first_data_segment = GET2(address, FT_FRST_SEG);
- ft_last_data_segment = GET2(address, FT_LAST_SEG);
- } else {
- ft_header_segment_1 = GET4(address, FT_6_HSEG_1);
- ft_header_segment_2 = GET4(address, FT_6_HSEG_2);
- ft_first_data_segment = GET4(address, FT_6_FRST_SEG);
- ft_last_data_segment = GET4(address, FT_6_LAST_SEG);
- }
- TRACE(ft_t_noise, "first data segment: %d", ft_first_data_segment);
- TRACE(ft_t_noise, "last data segment: %d", ft_last_data_segment);
- TRACE(ft_t_noise, "header segments are %d and %d",
- ft_header_segment_1, ft_header_segment_2);
-
- /* Verify tape parameters...
- * QIC-40/80 spec: tape_parameters:
- *
- * segments-per-track segments_per_track
- * tracks-per-cartridge tracks_per_tape
- * max-floppy-side (segments_per_track *
- * tracks_per_tape - 1) /
- * ftape_segments_per_head
- * max-floppy-track ftape_segments_per_head /
- * ftape_segments_per_cylinder - 1
- * max-floppy-sector ftape_segments_per_cylinder *
- * FT_SECTORS_PER_SEGMENT
- */
- ft_segments_per_track = GET2(address, FT_SPT);
- ft_tracks_per_tape = address[FT_TPC];
- max_floppy_side = address[FT_FHM];
- max_floppy_track = address[FT_FTM];
- max_floppy_sector = address[FT_FSM];
- TRACE(ft_t_noise, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",
- ft_format_code, ft_segments_per_track, ft_tracks_per_tape,
- max_floppy_side, max_floppy_track, max_floppy_sector);
- new_tape_len = ftape_tape_len;
- switch (ft_format_code) {
- case fmt_425ft:
- new_tape_len = 425;
- break;
- case fmt_normal:
- if (ftape_tape_len == 0) { /* otherwise 307 ft */
- new_tape_len = 205;
- }
- break;
- case fmt_1100ft:
- new_tape_len = 1100;
- break;
- case fmt_var:{
- int segments_per_1000_inch = 1; /* non-zero default for switch */
- switch (ft_qic_std) {
- case QIC_TAPE_QIC40:
- segments_per_1000_inch = 332;
- break;
- case QIC_TAPE_QIC80:
- segments_per_1000_inch = 488;
- break;
- case QIC_TAPE_QIC3010:
- segments_per_1000_inch = 730;
- break;
- case QIC_TAPE_QIC3020:
- segments_per_1000_inch = 1430;
- break;
- }
- new_tape_len = (1000 * ft_segments_per_track +
- (segments_per_1000_inch - 1)) / segments_per_1000_inch;
- break;
- }
- case fmt_big:{
- int segments_per_1000_inch = 1; /* non-zero default for switch */
- switch (ft_qic_std) {
- case QIC_TAPE_QIC40:
- segments_per_1000_inch = 332;
- break;
- case QIC_TAPE_QIC80:
- segments_per_1000_inch = 488;
- break;
- case QIC_TAPE_QIC3010:
- segments_per_1000_inch = 730;
- break;
- case QIC_TAPE_QIC3020:
- segments_per_1000_inch = 1430;
- break;
- default:
- TRACE_ABORT(-EIO, ft_t_bug,
- "%x QIC-standard with fmt-code %d, please report",
- ft_qic_std, ft_format_code);
- }
- new_tape_len = ((1000 * ft_segments_per_track +
- (segments_per_1000_inch - 1)) /
- segments_per_1000_inch);
- break;
- }
- default:
- TRACE_ABORT(-EIO, ft_t_err,
- "unknown tape format, please report !");
- }
- if (new_tape_len != ftape_tape_len) {
- ftape_tape_len = new_tape_len;
- TRACE(ft_t_info, "calculated tape length is %d ft",
- ftape_tape_len);
- ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);
- }
- if (ft_segments_per_track == 0 && ft_tracks_per_tape == 0 &&
- max_floppy_side == 0 && max_floppy_track == 0 &&
- max_floppy_sector == 0) {
- /* QIC-40 Rev E and earlier has no values in the header.
- */
- ft_segments_per_track = 68;
- ft_tracks_per_tape = 20;
- max_floppy_side = 1;
- max_floppy_track = 169;
- max_floppy_sector = 128;
- }
- /* This test will compensate for the wrong parameter on tapes
- * formatted by Conner software.
- */
- if (ft_segments_per_track == 150 &&
- ft_tracks_per_tape == 28 &&
- max_floppy_side == 7 &&
- max_floppy_track == 149 &&
- max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous CONNER bug: max_floppy_side off by one !");
- max_floppy_side = 6;
- }
- /* These tests will compensate for the wrong parameter on tapes
- * formatted by ComByte Windows software.
- *
- * First, for 205 foot tapes
- */
- if (ft_segments_per_track == 100 &&
- ft_tracks_per_tape == 28 &&
- max_floppy_side == 9 &&
- max_floppy_track == 149 &&
- max_floppy_sector == 128) {
-TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
- max_floppy_side = 4;
- }
- /* Next, for 307 foot tapes. */
- if (ft_segments_per_track == 150 &&
- ft_tracks_per_tape == 28 &&
- max_floppy_side == 9 &&
- max_floppy_track == 149 &&
- max_floppy_sector == 128) {
-TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");
- max_floppy_side = 6;
- }
- /* This test will compensate for the wrong parameter on tapes
- * formatted by Colorado Windows software.
- */
- if (ft_segments_per_track == 150 &&
- ft_tracks_per_tape == 28 &&
- max_floppy_side == 6 &&
- max_floppy_track == 150 &&
- max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous Colorado bug: max_floppy_track off by one !");
- max_floppy_track = 149;
- }
- ftape_segments_per_head = ((max_floppy_sector/FT_SECTORS_PER_SEGMENT) *
- (max_floppy_track + 1));
- /* This test will compensate for some bug reported by Dima
- * Brodsky. Seems to be a Colorado bug, either. (freebee
- * Imation tape shipped together with Colorado T3000
- */
- if ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&
- ft_tracks_per_tape == 50 &&
- max_floppy_side == 54 &&
- max_floppy_track == 255 &&
- max_floppy_sector == 128) {
-TRACE(ft_t_info, "the famous ??? bug: max_floppy_track off by one !");
- max_floppy_track = 254;
- }
- /*
- * Verify drive_configuration with tape parameters
- */
- if (ftape_segments_per_head == 0 || ftape_segments_per_cylinder == 0 ||
- ((ft_segments_per_track * ft_tracks_per_tape - 1) / ftape_segments_per_head
- != max_floppy_side) ||
- (ftape_segments_per_head / ftape_segments_per_cylinder - 1 != max_floppy_track) ||
- (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT != max_floppy_sector)
-#ifdef TESTING
- || ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&
- (max_floppy_track != 254 || max_floppy_sector != 128))
-#endif
- ) {
- char segperheadz = ftape_segments_per_head ? ' ' : '?';
- char segpercylz = ftape_segments_per_cylinder ? ' ' : '?';
- TRACE(ft_t_err,"Tape parameters inconsistency, please report");
- TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d",
- ft_format_code,
- ft_segments_per_track,
- ft_tracks_per_tape,
- max_floppy_side,
- max_floppy_track,
- max_floppy_sector);
- TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d",
- ft_format_code,
- ft_segments_per_track,
- ft_tracks_per_tape,
- ftape_segments_per_head ?
- ((ft_segments_per_track * ft_tracks_per_tape -1) /
- ftape_segments_per_head ) :
- (ft_segments_per_track * ft_tracks_per_tape -1),
- segperheadz,
- ftape_segments_per_cylinder ?
- (ftape_segments_per_head /
- ftape_segments_per_cylinder - 1 ) :
- ftape_segments_per_head - 1,
- segpercylz,
- (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT));
- TRACE_EXIT -EIO;
- }
- ftape_extract_bad_sector_map(address);
- TRACE_EXIT 0;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-read.h b/drivers/char/ftape/lowlevel/ftape-read.h
deleted file mode 100644
index 069f99f2a984..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-read.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _FTAPE_READ_H
-#define _FTAPE_READ_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-read.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:22 $
- *
- * This file contains the definitions for the read functions
- * for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-/* ftape-read.c defined global functions.
- */
-typedef enum {
- FT_RD_SINGLE = 0,
- FT_RD_AHEAD = 1,
-} ft_read_mode_t;
-
-extern int ftape_read_header_segment(__u8 *address);
-extern int ftape_decode_header_segment(__u8 *address);
-extern int ftape_read_segment_fraction(const int segment,
- void *address,
- const ft_read_mode_t read_mode,
- const int start,
- const int size);
-#define ftape_read_segment(segment, address, read_mode) \
- ftape_read_segment_fraction(segment, address, read_mode, \
- 0, FT_SEGMENT_SIZE)
-extern void ftape_zap_read_buffers(void);
-
-#endif /* _FTAPE_READ_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-rw.c b/drivers/char/ftape/lowlevel/ftape-rw.c
deleted file mode 100644
index c0d6dc2cbfd3..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-rw.c
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.c,v $
- * $Revision: 1.7 $
- * $Date: 1997/10/28 14:26:49 $
- *
- * This file contains some common code for the segment read and
- * segment write routines for the QIC-117 floppy-tape driver for
- * Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-
-/* Global vars.
- */
-int ft_nr_buffers;
-buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS];
-static volatile int ft_head;
-static volatile int ft_tail; /* not volatile but need same type as head */
-int fdc_setup_error;
-location_record ft_location = {-1, 0};
-volatile int ftape_tape_running;
-
-/* Local vars.
- */
-static int overrun_count_offset;
-static int inhibit_correction;
-
-/* maxmimal allowed overshoot when fast seeking
- */
-#define OVERSHOOT_LIMIT 10
-
-/* Increment cyclic buffer nr.
- */
-buffer_struct *ftape_next_buffer(ft_buffer_queue_t pos)
-{
- switch (pos) {
- case ft_queue_head:
- if (++ft_head >= ft_nr_buffers) {
- ft_head = 0;
- }
- return ft_buffer[ft_head];
- case ft_queue_tail:
- if (++ft_tail >= ft_nr_buffers) {
- ft_tail = 0;
- }
- return ft_buffer[ft_tail];
- default:
- return NULL;
- }
-}
-int ftape_buffer_id(ft_buffer_queue_t pos)
-{
- switch(pos) {
- case ft_queue_head: return ft_head;
- case ft_queue_tail: return ft_tail;
- default: return -1;
- }
-}
-buffer_struct *ftape_get_buffer(ft_buffer_queue_t pos)
-{
- switch(pos) {
- case ft_queue_head: return ft_buffer[ft_head];
- case ft_queue_tail: return ft_buffer[ft_tail];
- default: return NULL;
- }
-}
-void ftape_reset_buffer(void)
-{
- ft_head = ft_tail = 0;
-}
-
-buffer_state_enum ftape_set_state(buffer_state_enum new_state)
-{
- buffer_state_enum old_state = ft_driver_state;
-
- ft_driver_state = new_state;
- return old_state;
-}
-/* Calculate Floppy Disk Controller and DMA parameters for a segment.
- * head: selects buffer struct in array.
- * offset: number of physical sectors to skip (including bad ones).
- * count: number of physical sectors to handle (including bad ones).
- */
-static int setup_segment(buffer_struct * buff,
- int segment_id,
- unsigned int sector_offset,
- unsigned int sector_count,
- int retry)
-{
- SectorMap offset_mask;
- SectorMap mask;
- TRACE_FUN(ft_t_any);
-
- buff->segment_id = segment_id;
- buff->sector_offset = sector_offset;
- buff->remaining = sector_count;
- buff->head = segment_id / ftape_segments_per_head;
- buff->cyl = (segment_id % ftape_segments_per_head) / ftape_segments_per_cylinder;
- buff->sect = (segment_id % ftape_segments_per_cylinder) * FT_SECTORS_PER_SEGMENT + 1;
- buff->deleted = 0;
- offset_mask = (1 << buff->sector_offset) - 1;
- mask = ftape_get_bad_sector_entry(segment_id) & offset_mask;
- while (mask) {
- if (mask & 1) {
- offset_mask >>= 1; /* don't count bad sector */
- }
- mask >>= 1;
- }
- buff->data_offset = count_ones(offset_mask); /* good sectors to skip */
- buff->ptr = buff->address + buff->data_offset * FT_SECTOR_SIZE;
- TRACE(ft_t_flow, "data offset = %d sectors", buff->data_offset);
- if (retry) {
- buff->soft_error_map &= offset_mask; /* keep skipped part */
- } else {
- buff->hard_error_map = buff->soft_error_map = 0;
- }
- buff->bad_sector_map = ftape_get_bad_sector_entry(buff->segment_id);
- if (buff->bad_sector_map != 0) {
- TRACE(ft_t_noise, "segment: %d, bad sector map: %08lx",
- buff->segment_id, (long)buff->bad_sector_map);
- } else {
- TRACE(ft_t_flow, "segment: %d", buff->segment_id);
- }
- if (buff->sector_offset > 0) {
- buff->bad_sector_map >>= buff->sector_offset;
- }
- if (buff->sector_offset != 0 || buff->remaining != FT_SECTORS_PER_SEGMENT) {
- TRACE(ft_t_flow, "sector offset = %d, count = %d",
- buff->sector_offset, buff->remaining);
- }
- /* Segments with 3 or less sectors are not written with valid
- * data because there is no space left for the ecc. The
- * data written is whatever happens to be in the buffer.
- * Reading such a segment will return a zero byte-count.
- * To allow us to read/write segments with all bad sectors
- * we fake one readable sector in the segment. This
- * prevents having to handle these segments in a very
- * special way. It is not important if the reading of this
- * bad sector fails or not (the data is ignored). It is
- * only read to keep the driver running.
- *
- * The QIC-40/80 spec. has no information on how to handle
- * this case, so this is my interpretation.
- */
- if (buff->bad_sector_map == EMPTY_SEGMENT) {
- TRACE(ft_t_flow, "empty segment %d, fake first sector good",
- buff->segment_id);
- if (buff->ptr != buff->address) {
- TRACE(ft_t_bug, "This is a bug: %p/%p",
- buff->ptr, buff->address);
- }
- buff->bad_sector_map = FAKE_SEGMENT;
- }
- fdc_setup_error = 0;
- buff->next_segment = segment_id + 1;
- TRACE_EXIT 0;
-}
-
-/* Calculate Floppy Disk Controller and DMA parameters for a new segment.
- */
-int ftape_setup_new_segment(buffer_struct * buff, int segment_id, int skip)
-{
- int result = 0;
- static int old_segment_id = -1;
- static buffer_state_enum old_ft_driver_state = idle;
- int retry = 0;
- unsigned offset = 0;
- int count = FT_SECTORS_PER_SEGMENT;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_flow, "%s segment %d (old = %d)",
- (ft_driver_state == reading || ft_driver_state == verifying)
- ? "reading" : "writing",
- segment_id, old_segment_id);
- if (ft_driver_state != old_ft_driver_state) { /* when verifying */
- old_segment_id = -1;
- old_ft_driver_state = ft_driver_state;
- }
- if (segment_id == old_segment_id) {
- ++buff->retry;
- ++ft_history.retries;
- TRACE(ft_t_flow, "setting up for retry nr %d", buff->retry);
- retry = 1;
- if (skip && buff->skip > 0) { /* allow skip on retry */
- offset = buff->skip;
- count -= offset;
- TRACE(ft_t_flow, "skipping %d sectors", offset);
- }
- } else {
- buff->retry = 0;
- buff->skip = 0;
- old_segment_id = segment_id;
- }
- result = setup_segment(buff, segment_id, offset, count, retry);
- TRACE_EXIT result;
-}
-
-/* Determine size of next cluster of good sectors.
- */
-int ftape_calc_next_cluster(buffer_struct * buff)
-{
- /* Skip bad sectors.
- */
- while (buff->remaining > 0 && (buff->bad_sector_map & 1) != 0) {
- buff->bad_sector_map >>= 1;
- ++buff->sector_offset;
- --buff->remaining;
- }
- /* Find next cluster of good sectors
- */
- if (buff->bad_sector_map == 0) { /* speed up */
- buff->sector_count = buff->remaining;
- } else {
- SectorMap map = buff->bad_sector_map;
-
- buff->sector_count = 0;
- while (buff->sector_count < buff->remaining && (map & 1) == 0) {
- ++buff->sector_count;
- map >>= 1;
- }
- }
- return buff->sector_count;
-}
-
-/* if just passed the last segment on a track, wait for BOT
- * or EOT mark.
- */
-int ftape_handle_logical_eot(void)
-{
- TRACE_FUN(ft_t_flow);
-
- if (ft_runner_status == logical_eot) {
- int status;
-
- TRACE(ft_t_noise, "tape at logical EOT");
- TRACE_CATCH(ftape_ready_wait(ftape_timeout.seek, &status),);
- if ((status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) {
- TRACE_ABORT(-EIO, ft_t_err, "eot/bot not reached");
- }
- ft_runner_status = end_of_tape;
- }
- if (ft_runner_status == end_of_tape) {
- TRACE(ft_t_noise, "runner stopped because of logical EOT");
- ft_runner_status = idle;
- }
- TRACE_EXIT 0;
-}
-
-static int check_bot_eot(int status)
-{
- TRACE_FUN(ft_t_flow);
-
- if (status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) {
- ft_location.bot = ((ft_location.track & 1) == 0 ?
- (status & QIC_STATUS_AT_BOT) != 0:
- (status & QIC_STATUS_AT_EOT) != 0);
- ft_location.eot = !ft_location.bot;
- ft_location.segment = (ft_location.track +
- (ft_location.bot ? 0 : 1)) * ft_segments_per_track - 1;
- ft_location.sector = -1;
- ft_location.known = 1;
- TRACE(ft_t_flow, "tape at logical %s",
- ft_location.bot ? "bot" : "eot");
- TRACE(ft_t_flow, "segment = %d", ft_location.segment);
- } else {
- ft_location.known = 0;
- }
- TRACE_EXIT ft_location.known;
-}
-
-/* Read Id of first sector passing tape head.
- */
-static int ftape_read_id(void)
-{
- int status;
- __u8 out[2];
- TRACE_FUN(ft_t_any);
-
- /* Assume tape is running on entry, be able to handle
- * situation where it stopped or is stopping.
- */
- ft_location.known = 0; /* default is location not known */
- out[0] = FDC_READID;
- out[1] = ft_drive_sel;
- TRACE_CATCH(fdc_command(out, 2),);
- switch (fdc_interrupt_wait(20 * FT_SECOND)) {
- case 0:
- if (fdc_sect == 0) {
- if (ftape_report_drive_status(&status) >= 0 &&
- (status & QIC_STATUS_READY)) {
- ftape_tape_running = 0;
- TRACE(ft_t_flow, "tape has stopped");
- check_bot_eot(status);
- }
- } else {
- ft_location.known = 1;
- ft_location.segment = (ftape_segments_per_head
- * fdc_head
- + ftape_segments_per_cylinder
- * fdc_cyl
- + (fdc_sect - 1)
- / FT_SECTORS_PER_SEGMENT);
- ft_location.sector = ((fdc_sect - 1)
- % FT_SECTORS_PER_SEGMENT);
- ft_location.eot = ft_location.bot = 0;
- }
- break;
- case -ETIME:
- /* Didn't find id on tape, must be near end: Wait
- * until stopped.
- */
- if (ftape_ready_wait(FT_FOREVER, &status) >= 0) {
- ftape_tape_running = 0;
- TRACE(ft_t_flow, "tape has stopped");
- check_bot_eot(status);
- }
- break;
- default:
- /* Interrupted or otherwise failing
- * fdc_interrupt_wait()
- */
- TRACE(ft_t_err, "fdc_interrupt_wait failed");
- break;
- }
- if (!ft_location.known) {
- TRACE_ABORT(-EIO, ft_t_flow, "no id found");
- }
- if (ft_location.sector == 0) {
- TRACE(ft_t_flow, "passing segment %d/%d",
- ft_location.segment, ft_location.sector);
- } else {
- TRACE(ft_t_fdc_dma, "passing segment %d/%d",
- ft_location.segment, ft_location.sector);
- }
- TRACE_EXIT 0;
-}
-
-static int logical_forward(void)
-{
- ftape_tape_running = 1;
- return ftape_command(QIC_LOGICAL_FORWARD);
-}
-
-int ftape_stop_tape(int *pstatus)
-{
- int retry = 0;
- int result;
- TRACE_FUN(ft_t_flow);
-
- do {
- result = ftape_command_wait(QIC_STOP_TAPE,
- ftape_timeout.stop, pstatus);
- if (result == 0) {
- if ((*pstatus & QIC_STATUS_READY) == 0) {
- result = -EIO;
- } else {
- ftape_tape_running = 0;
- }
- }
- } while (result < 0 && ++retry <= 3);
- if (result < 0) {
- TRACE(ft_t_err, "failed ! (fatal)");
- }
- TRACE_EXIT result;
-}
-
-int ftape_dumb_stop(void)
-{
- int result;
- int status;
- TRACE_FUN(ft_t_flow);
-
- /* Abort current fdc operation if it's busy (probably read
- * or write operation pending) with a reset.
- */
- if (fdc_ready_wait(100 /* usec */) < 0) {
- TRACE(ft_t_noise, "aborting fdc operation");
- fdc_reset();
- }
- /* Reading id's after the last segment on a track may fail
- * but eventually the drive will become ready (logical eot).
- */
- result = ftape_report_drive_status(&status);
- ft_location.known = 0;
- do {
- if (result == 0 && status & QIC_STATUS_READY) {
- /* Tape is not running any more.
- */
- TRACE(ft_t_noise, "tape already halted");
- check_bot_eot(status);
- ftape_tape_running = 0;
- } else if (ftape_tape_running) {
- /* Tape is (was) still moving.
- */
-#ifdef TESTING
- ftape_read_id();
-#endif
- result = ftape_stop_tape(&status);
- } else {
- /* Tape not yet ready but stopped.
- */
- result = ftape_ready_wait(ftape_timeout.pause,&status);
- }
- } while (ftape_tape_running
- && !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)));
-#ifndef TESTING
- ft_location.known = 0;
-#endif
- if (ft_runner_status == aborting || ft_runner_status == do_abort) {
- ft_runner_status = idle;
- }
- TRACE_EXIT result;
-}
-
-/* Wait until runner has finished tail buffer.
- *
- */
-int ftape_wait_segment(buffer_state_enum state)
-{
- int status;
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- while (ft_buffer[ft_tail]->status == state) {
- TRACE(ft_t_flow, "state: %d", ft_buffer[ft_tail]->status);
- /* First buffer still being worked on, wait up to timeout.
- *
- * Note: we check two times for being killed. 50
- * seconds are quite long. Note that
- * fdc_interrupt_wait() is not killable by any
- * means. ftape_read_segment() wants us to return
- * -EINTR in case of a signal.
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- result = fdc_interrupt_wait(50 * FT_SECOND);
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- if (result < 0) {
- TRACE_ABORT(result,
- ft_t_err, "fdc_interrupt_wait failed");
- }
- if (fdc_setup_error) {
- /* recover... FIXME */
- TRACE_ABORT(-EIO, ft_t_err, "setup error");
- }
- }
- if (ft_buffer[ft_tail]->status != error) {
- TRACE_EXIT 0;
- }
- TRACE_CATCH(ftape_report_drive_status(&status),);
- TRACE(ft_t_noise, "ftape_report_drive_status: 0x%02x", status);
- if ((status & QIC_STATUS_READY) &&
- (status & QIC_STATUS_ERROR)) {
- unsigned int error;
- qic117_cmd_t command;
-
- /* Report and clear error state.
- * In case the drive can't operate at the selected
- * rate, select the next lower data rate.
- */
- ftape_report_error(&error, &command, 1);
- if (error == 31 && command == QIC_LOGICAL_FORWARD) {
- /* drive does not accept this data rate */
- if (ft_data_rate > 250) {
- TRACE(ft_t_info,
- "Probable data rate conflict");
- TRACE(ft_t_info,
- "Lowering data rate to %d Kbps",
- ft_data_rate / 2);
- ftape_half_data_rate();
- if (ft_buffer[ft_tail]->retry > 0) {
- /* give it a chance */
- --ft_buffer[ft_tail]->retry;
- }
- } else {
- /* no rate is accepted... */
- TRACE(ft_t_err, "We're dead :(");
- }
- } else {
- TRACE(ft_t_err, "Unknown error");
- }
- TRACE_EXIT -EIO; /* g.p. error */
- }
- TRACE_EXIT 0;
-}
-
-/* forward */ static int seek_forward(int segment_id, int fast);
-
-static int fast_seek(int count, int reverse)
-{
- int result = 0;
- int status;
- TRACE_FUN(ft_t_flow);
-
- if (count > 0) {
- /* If positioned at begin or end of tape, fast seeking needs
- * special treatment.
- * Starting from logical bot needs a (slow) seek to the first
- * segment before the high speed seek. Most drives do this
- * automatically but some older don't, so we treat them
- * all the same.
- * Starting from logical eot is even more difficult because
- * we cannot (slow) reverse seek to the last segment.
- * TO BE IMPLEMENTED.
- */
- inhibit_correction = 0;
- if (ft_location.known &&
- ((ft_location.bot && !reverse) ||
- (ft_location.eot && reverse))) {
- if (!reverse) {
- /* (slow) skip to first segment on a track
- */
- seek_forward(ft_location.track * ft_segments_per_track, 0);
- --count;
- } else {
- /* When seeking backwards from
- * end-of-tape the number of erased
- * gaps found seems to be higher than
- * expected. Therefor the drive must
- * skip some more segments than
- * calculated, but we don't know how
- * many. Thus we will prevent the
- * re-calculation of offset and
- * overshoot when seeking backwards.
- */
- inhibit_correction = 1;
- count += 3; /* best guess */
- }
- }
- } else {
- TRACE(ft_t_flow, "warning: zero or negative count: %d", count);
- }
- if (count > 0) {
- int i;
- int nibbles = count > 255 ? 3 : 2;
-
- if (count > 4095) {
- TRACE(ft_t_noise, "skipping clipped at 4095 segment");
- count = 4095;
- }
- /* Issue this tape command first. */
- if (!reverse) {
- TRACE(ft_t_noise, "skipping %d segment(s)", count);
- result = ftape_command(nibbles == 3 ?
- QIC_SKIP_EXTENDED_FORWARD : QIC_SKIP_FORWARD);
- } else {
- TRACE(ft_t_noise, "backing up %d segment(s)", count);
- result = ftape_command(nibbles == 3 ?
- QIC_SKIP_EXTENDED_REVERSE : QIC_SKIP_REVERSE);
- }
- if (result < 0) {
- TRACE(ft_t_noise, "Skip command failed");
- } else {
- --count; /* 0 means one gap etc. */
- for (i = 0; i < nibbles; ++i) {
- if (result >= 0) {
- result = ftape_parameter(count & 15);
- count /= 16;
- }
- }
- result = ftape_ready_wait(ftape_timeout.rewind, &status);
- if (result >= 0) {
- ftape_tape_running = 0;
- }
- }
- }
- TRACE_EXIT result;
-}
-
-static int validate(int id)
-{
- /* Check to see if position found is off-track as reported
- * once. Because all tracks in one direction lie next to
- * each other, if off-track the error will be approximately
- * 2 * ft_segments_per_track.
- */
- if (ft_location.track == -1) {
- return 1; /* unforseen situation, don't generate error */
- } else {
- /* Use margin of ft_segments_per_track on both sides
- * because ftape needs some margin and the error we're
- * looking for is much larger !
- */
- int lo = (ft_location.track - 1) * ft_segments_per_track;
- int hi = (ft_location.track + 2) * ft_segments_per_track;
-
- return (id >= lo && id < hi);
- }
-}
-
-static int seek_forward(int segment_id, int fast)
-{
- int failures = 0;
- int count;
- static int margin = 1; /* fixed: stop this before target */
- static int overshoot = 1;
- static int min_count = 8;
- int expected = -1;
- int target = segment_id - margin;
- int fast_seeking;
- int prev_segment = ft_location.segment;
- TRACE_FUN(ft_t_flow);
-
- if (!ft_location.known) {
- TRACE_ABORT(-EIO, ft_t_err,
- "fatal: cannot seek from unknown location");
- }
- if (!validate(segment_id)) {
- ftape_sleep(1 * FT_SECOND);
- ft_failure = 1;
- TRACE_ABORT(-EIO, ft_t_err,
- "fatal: head off track (bad hardware?)");
- }
- TRACE(ft_t_noise, "from %d/%d to %d/0 - %d",
- ft_location.segment, ft_location.sector,segment_id,margin);
- count = target - ft_location.segment - overshoot;
- fast_seeking = (fast &&
- count > (min_count + (ft_location.bot ? 1 : 0)));
- if (fast_seeking) {
- TRACE(ft_t_noise, "fast skipping %d segments", count);
- expected = segment_id - margin;
- fast_seek(count, 0);
- }
- if (!ftape_tape_running) {
- logical_forward();
- }
- while (ft_location.segment < segment_id) {
- /* This requires at least one sector in a (bad) segment to
- * have a valid and readable sector id !
- * It looks like this is not guaranteed, so we must try
- * to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!!
- */
- if (ftape_read_id() < 0 || !ft_location.known ||
- sigtestsetmask(&current->pending.signal, _DONT_BLOCK)) {
- ft_location.known = 0;
- if (!ftape_tape_running ||
- ++failures > FT_SECTORS_PER_SEGMENT) {
- TRACE_ABORT(-EIO, ft_t_err,
- "read_id failed completely");
- }
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- TRACE(ft_t_flow, "read_id failed, retry (%d)",
- failures);
- continue;
- }
- if (fast_seeking) {
- TRACE(ft_t_noise, "ended at %d/%d (%d,%d)",
- ft_location.segment, ft_location.sector,
- overshoot, inhibit_correction);
- if (!inhibit_correction &&
- (ft_location.segment < expected ||
- ft_location.segment > expected + margin)) {
- int error = ft_location.segment - expected;
- TRACE(ft_t_noise,
- "adjusting overshoot from %d to %d",
- overshoot, overshoot + error);
- overshoot += error;
- /* All overshoots have the same
- * direction, so it should never
- * become negative, but who knows.
- */
- if (overshoot < -5 ||
- overshoot > OVERSHOOT_LIMIT) {
- if (overshoot < 0) {
- /* keep sane value */
- overshoot = -5;
- } else {
- /* keep sane value */
- overshoot = OVERSHOOT_LIMIT;
- }
- TRACE(ft_t_noise,
- "clipped overshoot to %d",
- overshoot);
- }
- }
- fast_seeking = 0;
- }
- if (ft_location.known) {
- if (ft_location.segment > prev_segment + 1) {
- TRACE(ft_t_noise,
- "missed segment %d while skipping",
- prev_segment + 1);
- }
- prev_segment = ft_location.segment;
- }
- }
- if (ft_location.segment > segment_id) {
- TRACE_ABORT(-EIO,
- ft_t_noise, "failed: skip ended at segment %d/%d",
- ft_location.segment, ft_location.sector);
- }
- TRACE_EXIT 0;
-}
-
-static int skip_reverse(int segment_id, int *pstatus)
-{
- int failures = 0;
- static int overshoot = 1;
- static int min_rewind = 2; /* 1 + overshoot */
- static const int margin = 1; /* stop this before target */
- int expected = 0;
- int count = 1;
- int short_seek;
- int target = segment_id - margin;
- TRACE_FUN(ft_t_flow);
-
- if (ft_location.known && !validate(segment_id)) {
- ftape_sleep(1 * FT_SECOND);
- ft_failure = 1;
- TRACE_ABORT(-EIO, ft_t_err,
- "fatal: head off track (bad hardware?)");
- }
- do {
- if (!ft_location.known) {
- TRACE(ft_t_warn, "warning: location not known");
- }
- TRACE(ft_t_noise, "from %d/%d to %d/0 - %d",
- ft_location.segment, ft_location.sector,
- segment_id, margin);
- /* min_rewind == 1 + overshoot_when_doing_minimum_rewind
- * overshoot == overshoot_when_doing_larger_rewind
- * Initially min_rewind == 1 + overshoot, optimization
- * of both values will be done separately.
- * overshoot and min_rewind can be negative as both are
- * sums of three components:
- * any_overshoot == rewind_overshoot -
- * stop_overshoot -
- * start_overshoot
- */
- if (ft_location.segment - target - (min_rewind - 1) < 1) {
- short_seek = 1;
- } else {
- count = ft_location.segment - target - overshoot;
- short_seek = (count < 1);
- }
- if (short_seek) {
- count = 1; /* do shortest rewind */
- expected = ft_location.segment - min_rewind;
- if (expected/ft_segments_per_track != ft_location.track) {
- expected = (ft_location.track *
- ft_segments_per_track);
- }
- } else {
- expected = target;
- }
- fast_seek(count, 1);
- logical_forward();
- if (ftape_read_id() < 0 || !ft_location.known ||
- (sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
- if ((!ftape_tape_running && !ft_location.known) ||
- ++failures > FT_SECTORS_PER_SEGMENT) {
- TRACE_ABORT(-EIO, ft_t_err,
- "read_id failed completely");
- }
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- TRACE_CATCH(ftape_report_drive_status(pstatus),);
- TRACE(ft_t_noise, "ftape_read_id failed, retry (%d)",
- failures);
- continue;
- }
- TRACE(ft_t_noise, "ended at %d/%d (%d,%d,%d)",
- ft_location.segment, ft_location.sector,
- min_rewind, overshoot, inhibit_correction);
- if (!inhibit_correction &&
- (ft_location.segment < expected ||
- ft_location.segment > expected + margin)) {
- int error = expected - ft_location.segment;
- if (short_seek) {
- TRACE(ft_t_noise,
- "adjusting min_rewind from %d to %d",
- min_rewind, min_rewind + error);
- min_rewind += error;
- if (min_rewind < -5) {
- /* is this right ? FIXME ! */
- /* keep sane value */
- min_rewind = -5;
- TRACE(ft_t_noise,
- "clipped min_rewind to %d",
- min_rewind);
- }
- } else {
- TRACE(ft_t_noise,
- "adjusting overshoot from %d to %d",
- overshoot, overshoot + error);
- overshoot += error;
- if (overshoot < -5 ||
- overshoot > OVERSHOOT_LIMIT) {
- if (overshoot < 0) {
- /* keep sane value */
- overshoot = -5;
- } else {
- /* keep sane value */
- overshoot = OVERSHOOT_LIMIT;
- }
- TRACE(ft_t_noise,
- "clipped overshoot to %d",
- overshoot);
- }
- }
- }
- } while (ft_location.segment > segment_id);
- if (ft_location.known) {
- TRACE(ft_t_noise, "current location: %d/%d",
- ft_location.segment, ft_location.sector);
- }
- TRACE_EXIT 0;
-}
-
-static int determine_position(void)
-{
- int retry = 0;
- int status;
- int result;
- TRACE_FUN(ft_t_flow);
-
- if (!ftape_tape_running) {
- /* This should only happen if tape is stopped by isr.
- */
- TRACE(ft_t_flow, "waiting for tape stop");
- if (ftape_ready_wait(ftape_timeout.pause, &status) < 0) {
- TRACE(ft_t_flow, "drive still running (fatal)");
- ftape_tape_running = 1; /* ? */
- }
- } else {
- ftape_report_drive_status(&status);
- }
- if (status & QIC_STATUS_READY) {
- /* Drive must be ready to check error state !
- */
- TRACE(ft_t_flow, "drive is ready");
- if (status & QIC_STATUS_ERROR) {
- unsigned int error;
- qic117_cmd_t command;
-
- /* Report and clear error state, try to continue.
- */
- TRACE(ft_t_flow, "error status set");
- ftape_report_error(&error, &command, 1);
- ftape_ready_wait(ftape_timeout.reset, &status);
- ftape_tape_running = 0; /* ? */
- }
- if (check_bot_eot(status)) {
- if (ft_location.bot) {
- if ((status & QIC_STATUS_READY) == 0) {
- /* tape moving away from
- * bot/eot, let's see if we
- * can catch up with the first
- * segment on this track.
- */
- } else {
- TRACE(ft_t_flow,
- "start tape from logical bot");
- logical_forward(); /* start moving */
- }
- } else {
- if ((status & QIC_STATUS_READY) == 0) {
- TRACE(ft_t_noise, "waiting for logical end of track");
- result = ftape_ready_wait(ftape_timeout.reset, &status);
- /* error handling needed ? */
- } else {
- TRACE(ft_t_noise,
- "tape at logical end of track");
- }
- }
- } else {
- TRACE(ft_t_flow, "start tape");
- logical_forward(); /* start moving */
- ft_location.known = 0; /* not cleared by logical forward ! */
- }
- }
- /* tape should be moving now, start reading id's
- */
- while (!ft_location.known &&
- retry++ < FT_SECTORS_PER_SEGMENT &&
- (result = ftape_read_id()) < 0) {
-
- TRACE(ft_t_flow, "location unknown");
-
- /* exit on signal
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
-
- /* read-id somehow failed, tape may
- * have reached end or some other
- * error happened.
- */
- TRACE(ft_t_flow, "read-id failed");
- TRACE_CATCH(ftape_report_drive_status(&status),);
- TRACE(ft_t_err, "ftape_report_drive_status: 0x%02x", status);
- if (status & QIC_STATUS_READY) {
- ftape_tape_running = 0;
- TRACE(ft_t_noise, "tape stopped for unknown reason! "
- "status = 0x%02x", status);
- if (status & QIC_STATUS_ERROR ||
- !check_bot_eot(status)) {
- /* oops, tape stopped but not at end!
- */
- TRACE_EXIT -EIO;
- }
- }
- }
- TRACE(ft_t_flow,
- "tape is positioned at segment %d", ft_location.segment);
- TRACE_EXIT ft_location.known ? 0 : -EIO;
-}
-
-/* Get the tape running and position it just before the
- * requested segment.
- * Seek tape-track and reposition as needed.
- */
-int ftape_start_tape(int segment_id, int sector_offset)
-{
- int track = segment_id / ft_segments_per_track;
- int result = -EIO;
- int status;
- static int last_segment = -1;
- static int bad_bus_timing = 0;
- /* number of segments passing the head between starting the tape
- * and being able to access the first sector.
- */
- static int start_offset = 1;
- int retry;
- TRACE_FUN(ft_t_flow);
-
- /* If sector_offset > 0, seek into wanted segment instead of
- * into previous.
- * This allows error recovery if a part of the segment is bad
- * (erased) causing the tape drive to generate an index pulse
- * thus causing a no-data error before the requested sector
- * is reached.
- */
- ftape_tape_running = 0;
- TRACE(ft_t_noise, "target segment: %d/%d%s", segment_id, sector_offset,
- ft_buffer[ft_head]->retry > 0 ? " retry" : "");
- if (ft_buffer[ft_head]->retry > 0) { /* this is a retry */
- int dist = segment_id - last_segment;
-
- if ((int)ft_history.overrun_errors < overrun_count_offset) {
- overrun_count_offset = ft_history.overrun_errors;
- } else if (dist < 0 || dist > 50) {
- overrun_count_offset = ft_history.overrun_errors;
- } else if ((ft_history.overrun_errors -
- overrun_count_offset) >= 8) {
- if (ftape_increase_threshold() >= 0) {
- --ft_buffer[ft_head]->retry;
- overrun_count_offset =
- ft_history.overrun_errors;
- TRACE(ft_t_warn, "increased threshold because "
- "of excessive overrun errors");
- } else if (!bad_bus_timing && ft_data_rate >= 1000) {
- ftape_half_data_rate();
- --ft_buffer[ft_head]->retry;
- bad_bus_timing = 1;
- overrun_count_offset =
- ft_history.overrun_errors;
- TRACE(ft_t_warn, "reduced datarate because "
- "of excessive overrun errors");
- }
- }
- }
- last_segment = segment_id;
- if (ft_location.track != track ||
- (ftape_might_be_off_track && ft_buffer[ft_head]->retry== 0)) {
- /* current track unknown or not equal to destination
- */
- ftape_ready_wait(ftape_timeout.seek, &status);
- ftape_seek_head_to_track(track);
- /* overrun_count_offset = ft_history.overrun_errors; */
- }
- result = -EIO;
- retry = 0;
- while (result < 0 &&
- retry++ <= 5 &&
- !ft_failure &&
- !(sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
-
- if (retry && start_offset < 5) {
- start_offset ++;
- }
- /* Check if we are able to catch the requested
- * segment in time.
- */
- if ((ft_location.known || (determine_position() == 0)) &&
- ft_location.segment >=
- (segment_id -
- ((ftape_tape_running || ft_location.bot)
- ? 0 : start_offset))) {
- /* Too far ahead (in or past target segment).
- */
- if (ftape_tape_running) {
- if ((result = ftape_stop_tape(&status)) < 0) {
- TRACE(ft_t_err,
- "stop tape failed with code %d",
- result);
- break;
- }
- TRACE(ft_t_noise, "tape stopped");
- ftape_tape_running = 0;
- }
- TRACE(ft_t_noise, "repositioning");
- ++ft_history.rewinds;
- if (segment_id % ft_segments_per_track < start_offset){
- TRACE(ft_t_noise, "end of track condition\n"
- KERN_INFO "segment_id : %d\n"
- KERN_INFO "ft_segments_per_track: %d\n"
- KERN_INFO "start_offset : %d",
- segment_id, ft_segments_per_track,
- start_offset);
-
- /* If seeking to first segments on
- * track better do a complete rewind
- * to logical begin of track to get a
- * more steady tape motion.
- */
- result = ftape_command_wait(
- (ft_location.track & 1)
- ? QIC_PHYSICAL_FORWARD
- : QIC_PHYSICAL_REVERSE,
- ftape_timeout.rewind, &status);
- check_bot_eot(status); /* update location */
- } else {
- result= skip_reverse(segment_id - start_offset,
- &status);
- }
- }
- if (!ft_location.known) {
- TRACE(ft_t_bug, "panic: location not known");
- result = -EIO;
- continue; /* while() will check for failure */
- }
- TRACE(ft_t_noise, "current segment: %d/%d",
- ft_location.segment, ft_location.sector);
- /* We're on the right track somewhere before the
- * wanted segment. Start tape movement if needed and
- * skip to just before or inside the requested
- * segment. Keep tape running.
- */
- result = 0;
- if (ft_location.segment <
- (segment_id - ((ftape_tape_running || ft_location.bot)
- ? 0 : start_offset))) {
- if (sector_offset > 0) {
- result = seek_forward(segment_id,
- retry <= 3);
- } else {
- result = seek_forward(segment_id - 1,
- retry <= 3);
- }
- }
- if (result == 0 &&
- ft_location.segment !=
- (segment_id - (sector_offset > 0 ? 0 : 1))) {
- result = -EIO;
- }
- }
- if (result < 0) {
- TRACE(ft_t_err, "failed to reposition");
- } else {
- ft_runner_status = running;
- }
- TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-rw.h b/drivers/char/ftape/lowlevel/ftape-rw.h
deleted file mode 100644
index 32f4feeb887c..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-rw.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _FTAPE_RW_H
-#define _FTAPE_RW_H
-
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-rw.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:25 $
- *
- * This file contains the definitions for the read and write
- * functions for the QIC-117 floppy-tape driver for Linux.
- *
- * Claus-Justus Heine (1996/09/20): Add definition of format code 6
- * Claus-Justus Heine (1996/10/04): Changed GET/PUT macros to cast to (__u8 *)
- *
- */
-
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/ftape-bsm.h"
-
-#include <asm/unaligned.h>
-
-#define GET2(address, offset) get_unaligned((__u16*)((__u8 *)address + offset))
-#define GET4(address, offset) get_unaligned((__u32*)((__u8 *)address + offset))
-#define GET8(address, offset) get_unaligned((__u64*)((__u8 *)address + offset))
-#define PUT2(address, offset , value) put_unaligned((value), (__u16*)((__u8 *)address + offset))
-#define PUT4(address, offset , value) put_unaligned((value), (__u32*)((__u8 *)address + offset))
-#define PUT8(address, offset , value) put_unaligned((value), (__u64*)((__u8 *)address + offset))
-
-enum runner_status_enum {
- idle = 0,
- running,
- do_abort,
- aborting,
- logical_eot,
- end_of_tape,
-};
-
-typedef enum ft_buffer_queue {
- ft_queue_head = 0,
- ft_queue_tail = 1
-} ft_buffer_queue_t;
-
-
-typedef struct {
- int track; /* tape head position */
- volatile int segment; /* current segment */
- volatile int sector; /* sector offset within current segment */
- volatile unsigned int bot; /* logical begin of track */
- volatile unsigned int eot; /* logical end of track */
- volatile unsigned int known; /* validates bot, segment, sector */
-} location_record;
-
-/* Count nr of 1's in pattern.
- */
-static inline int count_ones(unsigned long mask)
-{
- int bits;
-
- for (bits = 0; mask != 0; mask >>= 1) {
- if (mask & 1) {
- ++bits;
- }
- }
- return bits;
-}
-
-#define FT_MAX_NR_BUFFERS 16 /* arbitrary value */
-/* ftape-rw.c defined global vars.
- */
-extern buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS];
-extern int ft_nr_buffers;
-extern location_record ft_location;
-extern volatile int ftape_tape_running;
-
-/* ftape-rw.c defined global functions.
- */
-extern int ftape_setup_new_segment(buffer_struct * buff,
- int segment_id,
- int offset);
-extern int ftape_calc_next_cluster(buffer_struct * buff);
-extern buffer_struct *ftape_next_buffer (ft_buffer_queue_t pos);
-extern buffer_struct *ftape_get_buffer (ft_buffer_queue_t pos);
-extern int ftape_buffer_id (ft_buffer_queue_t pos);
-extern void ftape_reset_buffer(void);
-extern void ftape_tape_parameters(__u8 drive_configuration);
-extern int ftape_wait_segment(buffer_state_enum state);
-extern int ftape_dumb_stop(void);
-extern int ftape_start_tape(int segment_id, int offset);
-extern int ftape_stop_tape(int *pstatus);
-extern int ftape_handle_logical_eot(void);
-extern buffer_state_enum ftape_set_state(buffer_state_enum new_state);
-#endif /* _FTAPE_RW_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-setup.c b/drivers/char/ftape/lowlevel/ftape-setup.c
deleted file mode 100644
index 678340acd0b7..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-setup.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-setup.c,v $
- * $Revision: 1.7 $
- * $Date: 1997/10/10 09:57:06 $
- *
- * This file contains the code for processing the kernel command
- * line options for the QIC-40/80/3010/3020 floppy-tape driver
- * "ftape" for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/init.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/fdc-io.h"
-
-static struct param_table {
- const char *name;
- int *var;
- int def_param;
- int min;
- int max;
-} config_params[] __initdata = {
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
- { "tracing", &ftape_tracing, 3, ft_t_bug, ft_t_any},
-#endif
- { "ioport", &ft_fdc_base, CONFIG_FT_FDC_BASE, 0x0, 0xfff},
- { "irq", &ft_fdc_irq, CONFIG_FT_FDC_IRQ, 2, 15},
- { "dma", &ft_fdc_dma, CONFIG_FT_FDC_DMA, 0, 3},
- { "threshold", &ft_fdc_threshold, CONFIG_FT_FDC_THR, 1, 16},
- { "datarate", &ft_fdc_rate_limit, CONFIG_FT_FDC_MAX_RATE, 500, 2000},
- { "fc10", &ft_probe_fc10, CONFIG_FT_PROBE_FC10, 0, 1},
- { "mach2", &ft_mach2, CONFIG_FT_MACH2, 0, 1}
-};
-
-static int __init ftape_setup(char *str)
-{
- int i;
- int param;
- int ints[2];
-
- TRACE_FUN(ft_t_flow);
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
- if (str) {
- for (i=0; i < NR_ITEMS(config_params); i++) {
- if (strcmp(str,config_params[i].name) == 0){
- if (ints[0]) {
- param = ints[1];
- } else {
- param = config_params[i].def_param;
- }
- if (param < config_params[i].min ||
- param > config_params[i].max) {
- TRACE(ft_t_err,
- "parameter %s out of range %d ... %d",
- config_params[i].name,
- config_params[i].min,
- config_params[i].max);
- goto out;
- }
- if(config_params[i].var) {
- TRACE(ft_t_info, "%s=%d", str, param);
- *config_params[i].var = param;
- }
- goto out;
- }
- }
- }
- if (str) {
- TRACE(ft_t_err, "unknown ftape option [%s]", str);
-
- TRACE(ft_t_err, "allowed options are:");
- for (i=0; i < NR_ITEMS(config_params); i++) {
- TRACE(ft_t_err, " %s",config_params[i].name);
- }
- } else {
- TRACE(ft_t_err, "botched ftape option");
- }
- out:
- TRACE_EXIT 1;
-}
-
-__setup("ftape=", ftape_setup);
diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.c b/drivers/char/ftape/lowlevel/ftape-tracing.c
deleted file mode 100644
index 7fdc6567440b..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-tracing.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 1993-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:27 $
- *
- * This file contains the reading code
- * for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-
-/* Global vars.
- */
-/* tracing
- * set it to: to log :
- * 0 bugs
- * 1 + errors
- * 2 + warnings
- * 3 + information
- * 4 + more information
- * 5 + program flow
- * 6 + fdc/dma info
- * 7 + data flow
- * 8 + everything else
- */
-ft_trace_t ftape_tracing = ft_t_info; /* Default level: information and up */
-int ftape_function_nest_level;
-
-/* Local vars.
- */
-static __u8 trace_id;
-static char spacing[] = "* ";
-
-void ftape_trace_call(const char *file, const char *name)
-{
- char *indent;
-
- /* Since printk seems not to work with "%*s" format
- * we'll use this work-around.
- */
- if (ftape_function_nest_level < 0) {
- printk(KERN_INFO "function nest level (%d) < 0\n",
- ftape_function_nest_level);
- ftape_function_nest_level = 0;
- }
- if (ftape_function_nest_level < sizeof(spacing)) {
- indent = (spacing +
- sizeof(spacing) - 1 -
- ftape_function_nest_level);
- } else {
- indent = spacing;
- }
- printk(KERN_INFO "[%03d]%s+%s (%s)\n",
- (int) trace_id++, indent, file, name);
-}
-
-void ftape_trace_exit(const char *file, const char *name)
-{
- char *indent;
-
- /* Since printk seems not to work with "%*s" format
- * we'll use this work-around.
- */
- if (ftape_function_nest_level < 0) {
- printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level);
- ftape_function_nest_level = 0;
- }
- if (ftape_function_nest_level < sizeof(spacing)) {
- indent = (spacing +
- sizeof(spacing) - 1 -
- ftape_function_nest_level);
- } else {
- indent = spacing;
- }
- printk(KERN_INFO "[%03d]%s-%s (%s)\n",
- (int) trace_id++, indent, file, name);
-}
-
-void ftape_trace_log(const char *file, const char *function)
-{
- char *indent;
-
- /* Since printk seems not to work with "%*s" format
- * we'll use this work-around.
- */
- if (ftape_function_nest_level < 0) {
- printk(KERN_INFO "function nest level (%d) < 0\n", ftape_function_nest_level);
- ftape_function_nest_level = 0;
- }
- if (ftape_function_nest_level < sizeof(spacing)) {
- indent = (spacing +
- sizeof(spacing) - 1 -
- ftape_function_nest_level);
- } else {
- indent = spacing;
- }
- printk(KERN_INFO "[%03d]%s%s (%s) - ",
- (int) trace_id++, indent, file, function);
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.h b/drivers/char/ftape/lowlevel/ftape-tracing.h
deleted file mode 100644
index 2950810c7085..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-tracing.h
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef _FTAPE_TRACING_H
-#define _FTAPE_TRACING_H
-
-/*
- * Copyright (C) 1994-1996 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:28 $
- *
- * This file contains definitions that eases the debugging of the
- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
- */
-
-#include <linux/kernel.h>
-
-/*
- * Be very careful with TRACE_EXIT and TRACE_ABORT.
- *
- * if (something) TRACE_EXIT error;
- *
- * will NOT work. Use
- *
- * if (something) {
- * TRACE_EXIT error;
- * }
- *
- * instead. Maybe a bit dangerous, but save lots of lines of code.
- */
-
-#define LL_X "%d/%d KB"
-#define LL(x) (unsigned int)((__u64)(x)>>10), (unsigned int)((x)&1023)
-
-typedef enum {
- ft_t_nil = -1,
- ft_t_bug,
- ft_t_err,
- ft_t_warn,
- ft_t_info,
- ft_t_noise,
- ft_t_flow,
- ft_t_fdc_dma,
- ft_t_data_flow,
- ft_t_any
-} ft_trace_t;
-
-#ifdef CONFIG_FT_NO_TRACE_AT_ALL
-/* the compiler will optimize away most TRACE() macros
- */
-#define FT_TRACE_TOP_LEVEL ft_t_bug
-#define TRACE_FUN(level) do {} while(0)
-#define TRACE_EXIT return
-#define TRACE(l, m, i...) \
-{ \
- if ((ft_trace_t)(l) == FT_TRACE_TOP_LEVEL) { \
- printk(KERN_INFO"ftape%s(%s):\n" \
- KERN_INFO m".\n" ,__FILE__, __FUNCTION__ , ##i); \
- } \
-}
-#define SET_TRACE_LEVEL(l) if ((l) == (l)) do {} while(0)
-#define TRACE_LEVEL FT_TRACE_TOP_LEVEL
-
-#else
-
-#ifdef CONFIG_FT_NO_TRACE
-/* the compiler will optimize away many TRACE() macros
- * the ftape_simple_trace_call() function simply increments
- * the function nest level.
- */
-#define FT_TRACE_TOP_LEVEL ft_t_warn
-#define TRACE_FUN(level) ftape_function_nest_level++
-#define TRACE_EXIT ftape_function_nest_level--; return
-
-#else
-#ifdef CONFIG_FT_FULL_DEBUG
-#define FT_TRACE_TOP_LEVEL ft_t_any
-#else
-#define FT_TRACE_TOP_LEVEL ft_t_flow
-#endif
-#define TRACE_FUN(level) \
- const ft_trace_t _tracing = level; \
- if (ftape_tracing >= (ft_trace_t)(level) && \
- (ft_trace_t)(level) <= FT_TRACE_TOP_LEVEL) \
- ftape_trace_call(__FILE__, __FUNCTION__); \
- ftape_function_nest_level ++;
-
-#define TRACE_EXIT \
- --ftape_function_nest_level; \
- if (ftape_tracing >= (ft_trace_t)(_tracing) && \
- (ft_trace_t)(_tracing) <= FT_TRACE_TOP_LEVEL) \
- ftape_trace_exit(__FILE__, __FUNCTION__); \
- return
-
-#endif
-
-#define TRACE(l, m, i...) \
-{ \
- if (ftape_tracing >= (ft_trace_t)(l) && \
- (ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) { \
- ftape_trace_log(__FILE__, __FUNCTION__); \
- printk(m".\n" ,##i); \
- } \
-}
-
-#define SET_TRACE_LEVEL(l) \
-{ \
- if ((ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) { \
- ftape_tracing = (ft_trace_t)(l); \
- } else { \
- ftape_tracing = FT_TRACE_TOP_LEVEL; \
- } \
-}
-#define TRACE_LEVEL \
-((ftape_tracing <= FT_TRACE_TOP_LEVEL) ? ftape_tracing : FT_TRACE_TOP_LEVEL)
-
-
-/* Global variables declared in tracing.c
- */
-extern ft_trace_t ftape_tracing; /* sets default level */
-extern int ftape_function_nest_level;
-
-/* Global functions declared in tracing.c
- */
-extern void ftape_trace_call(const char *file, const char *name);
-extern void ftape_trace_exit(const char *file, const char *name);
-extern void ftape_trace_log (const char *file, const char *name);
-
-#endif /* !defined(CONFIG_FT_NO_TRACE_AT_ALL) */
-
-/*
- * Abort with a message.
- */
-#define TRACE_ABORT(res, i...) \
-{ \
- TRACE(i); \
- TRACE_EXIT res; \
-}
-
-/* The following transforms the common "if(result < 0) ... " into a
- * one-liner.
- */
-#define _TRACE_CATCH(level, fun, action) \
-{ \
- int _res = (fun); \
- if (_res < 0) { \
- do { action /* */ ; } while(0); \
- TRACE_ABORT(_res, level, "%s failed: %d", #fun, _res); \
- } \
-}
-
-#define TRACE_CATCH(fun, fail) _TRACE_CATCH(ft_t_err, fun, fail)
-
-/* Abort the current function when signalled. This doesn't belong here,
- * but rather into ftape-rw.h (maybe)
- */
-#define FT_SIGNAL_EXIT(sig_mask) \
- if (sigtestsetmask(&current->pending.signal, sig_mask)) { \
- TRACE_ABORT(-EINTR, \
- ft_t_warn, \
- "interrupted by non-blockable signal"); \
- }
-
-#endif /* _FTAPE_TRACING_H */
diff --git a/drivers/char/ftape/lowlevel/ftape-write.c b/drivers/char/ftape/lowlevel/ftape-write.c
deleted file mode 100644
index 45601ec801ee..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-write.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 1993-1995 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.c,v $
- * $Revision: 1.3.4.1 $
- * $Date: 1997/11/14 18:07:04 $
- *
- * This file contains the writing code
- * for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/ftape.h>
-#include <linux/qic117.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-ecc.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/fdc-isr.h"
-
-/* Global vars.
- */
-
-/* Local vars.
- */
-static int last_write_failed;
-
-void ftape_zap_write_buffers(void)
-{
- int i;
-
- for (i = 0; i < ft_nr_buffers; ++i) {
- ft_buffer[i]->status = done;
- }
- ftape_reset_buffer();
-}
-
-static int copy_and_gen_ecc(void *destination,
- const void *source,
- const SectorMap bad_sector_map)
-{
- int result;
- struct memory_segment mseg;
- int bads = count_ones(bad_sector_map);
- TRACE_FUN(ft_t_any);
-
- if (bads > 0) {
- TRACE(ft_t_noise, "bad sectors in map: %d", bads);
- }
- if (bads + 3 >= FT_SECTORS_PER_SEGMENT) {
- TRACE(ft_t_noise, "empty segment");
- mseg.blocks = 0; /* skip entire segment */
- result = 0; /* nothing written */
- } else {
- mseg.blocks = FT_SECTORS_PER_SEGMENT - bads;
- mseg.data = destination;
- memcpy(mseg.data, source, (mseg.blocks - 3) * FT_SECTOR_SIZE);
- result = ftape_ecc_set_segment_parity(&mseg);
- if (result < 0) {
- TRACE(ft_t_err, "ecc_set_segment_parity failed");
- } else {
- result = (mseg.blocks - 3) * FT_SECTOR_SIZE;
- }
- }
- TRACE_EXIT result;
-}
-
-
-int ftape_start_writing(const ft_write_mode_t mode)
-{
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
- int segment_id = head->segment_id;
- int result;
- buffer_state_enum wanted_state = (mode == FT_WR_DELETE
- ? deleting
- : writing);
- TRACE_FUN(ft_t_flow);
-
- if ((ft_driver_state != wanted_state) || head->status != waiting) {
- TRACE_EXIT 0;
- }
- ftape_setup_new_segment(head, segment_id, 1);
- if (mode == FT_WR_SINGLE) {
- /* stop tape instead of pause */
- head->next_segment = 0;
- }
- ftape_calc_next_cluster(head); /* prepare */
- head->status = ft_driver_state; /* either writing or deleting */
- if (ft_runner_status == idle) {
- TRACE(ft_t_noise,
- "starting runner for segment %d", segment_id);
- TRACE_CATCH(ftape_start_tape(segment_id,head->sector_offset),);
- } else {
- TRACE(ft_t_noise, "runner not idle, not starting tape");
- }
- /* go */
- result = fdc_setup_read_write(head, (mode == FT_WR_DELETE
- ? FDC_WRITE_DELETED : FDC_WRITE));
- ftape_set_state(wanted_state); /* should not be necessary */
- TRACE_EXIT result;
-}
-
-/* Wait until all data is actually written to tape.
- *
- * There is a problem: when the tape runs into logical EOT, then this
- * failes. We need to restart the runner in this case.
- */
-int ftape_loop_until_writes_done(void)
-{
- buffer_struct *head;
- TRACE_FUN(ft_t_flow);
-
- while ((ft_driver_state == writing || ft_driver_state == deleting) &&
- ftape_get_buffer(ft_queue_head)->status != done) {
- /* set the runner status to idle if at lEOT */
- TRACE_CATCH(ftape_handle_logical_eot(), last_write_failed = 1);
- /* restart the tape if necessary */
- if (ft_runner_status == idle) {
- TRACE(ft_t_noise, "runner is idle, restarting");
- if (ft_driver_state == deleting) {
- TRACE_CATCH(ftape_start_writing(FT_WR_DELETE),
- last_write_failed = 1);
- } else {
- TRACE_CATCH(ftape_start_writing(FT_WR_MULTI),
- last_write_failed = 1);
- }
- }
- TRACE(ft_t_noise, "tail: %d, head: %d",
- ftape_buffer_id(ft_queue_tail),
- ftape_buffer_id(ft_queue_head));
- TRACE_CATCH(fdc_interrupt_wait(5 * FT_SECOND),
- last_write_failed = 1);
- head = ftape_get_buffer(ft_queue_head);
- if (head->status == error) {
- /* Allow escape from loop when signaled !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- if (head->hard_error_map != 0) {
- /* Implement hard write error recovery here
- */
- }
- /* retry this one */
- head->status = waiting;
- if (ft_runner_status == aborting) {
- ftape_dumb_stop();
- }
- if (ft_runner_status != idle) {
- TRACE_ABORT(-EIO, ft_t_err,
- "unexpected state: "
- "ft_runner_status != idle");
- }
- ftape_start_writing(ft_driver_state == deleting
- ? FT_WR_MULTI : FT_WR_DELETE);
- }
- TRACE(ft_t_noise, "looping until writes done");
- }
- ftape_set_state(idle);
- TRACE_EXIT 0;
-}
-
-/* Write given segment from buffer at address to tape.
- */
-static int write_segment(const int segment_id,
- const void *address,
- const ft_write_mode_t write_mode)
-{
- int bytes_written = 0;
- buffer_struct *tail;
- buffer_state_enum wanted_state = (write_mode == FT_WR_DELETE
- ? deleting : writing);
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "segment_id = %d", segment_id);
- if (ft_driver_state != wanted_state) {
- if (ft_driver_state == deleting ||
- wanted_state == deleting) {
- TRACE_CATCH(ftape_loop_until_writes_done(),);
- }
- TRACE(ft_t_noise, "calling ftape_abort_operation");
- TRACE_CATCH(ftape_abort_operation(),);
- ftape_zap_write_buffers();
- ftape_set_state(wanted_state);
- }
- /* if all buffers full we'll have to wait...
- */
- ftape_wait_segment(wanted_state);
- tail = ftape_get_buffer(ft_queue_tail);
- switch(tail->status) {
- case done:
- ft_history.defects += count_ones(tail->hard_error_map);
- break;
- case waiting:
- /* this could happen with multiple EMPTY_SEGMENTs, but
- * shouldn't happen any more as we re-start the runner even
- * with an empty segment.
- */
- bytes_written = -EAGAIN;
- break;
- case error:
- /* setup for a retry
- */
- tail->status = waiting;
- bytes_written = -EAGAIN; /* force retry */
- if (tail->hard_error_map != 0) {
- TRACE(ft_t_warn,
- "warning: %d hard error(s) in written segment",
- count_ones(tail->hard_error_map));
- TRACE(ft_t_noise, "hard_error_map = 0x%08lx",
- (long)tail->hard_error_map);
- /* Implement hard write error recovery here
- */
- }
- break;
- default:
- TRACE_ABORT(-EIO, ft_t_err,
- "wait for empty segment failed, tail status: %d",
- tail->status);
- }
- /* should runner stop ?
- */
- if (ft_runner_status == aborting) {
- buffer_struct *head = ftape_get_buffer(ft_queue_head);
- if (head->status == wanted_state) {
- head->status = done; /* ???? */
- }
- /* don't call abort_operation(), we don't want to zap
- * the dma buffers
- */
- TRACE_CATCH(ftape_dumb_stop(),);
- } else {
- /* If just passed last segment on tape: wait for BOT
- * or EOT mark. Sets ft_runner_status to idle if at lEOT
- * and successful
- */
- TRACE_CATCH(ftape_handle_logical_eot(),);
- }
- if (tail->status == done) {
- /* now at least one buffer is empty, fill it with our
- * data. skip bad sectors and generate ecc.
- * copy_and_gen_ecc return nr of bytes written, range
- * 0..29 Kb inclusive!
- *
- * Empty segments are handled inside coyp_and_gen_ecc()
- */
- if (write_mode != FT_WR_DELETE) {
- TRACE_CATCH(bytes_written = copy_and_gen_ecc(
- tail->address, address,
- ftape_get_bad_sector_entry(segment_id)),);
- }
- tail->segment_id = segment_id;
- tail->status = waiting;
- tail = ftape_next_buffer(ft_queue_tail);
- }
- /* Start tape only if all buffers full or flush mode.
- * This will give higher probability of streaming.
- */
- if (ft_runner_status != running &&
- ((tail->status == waiting &&
- ftape_get_buffer(ft_queue_head) == tail) ||
- write_mode != FT_WR_ASYNC)) {
- TRACE_CATCH(ftape_start_writing(write_mode),);
- }
- TRACE_EXIT bytes_written;
-}
-
-/* Write as much as fits from buffer to the given segment on tape
- * and handle retries.
- * Return the number of bytes written (>= 0), or:
- * -EIO write failed
- * -EINTR interrupted by signal
- * -ENOSPC device full
- */
-int ftape_write_segment(const int segment_id,
- const void *buffer,
- const ft_write_mode_t flush)
-{
- int retry = 0;
- int result;
- TRACE_FUN(ft_t_flow);
-
- ft_history.used |= 2;
- if (segment_id >= ft_tracks_per_tape*ft_segments_per_track) {
- /* tape full */
- TRACE_ABORT(-ENOSPC, ft_t_err,
- "invalid segment id: %d (max %d)",
- segment_id,
- ft_tracks_per_tape * ft_segments_per_track -1);
- }
- for (;;) {
- if ((result = write_segment(segment_id, buffer, flush)) >= 0) {
- if (result == 0) { /* empty segment */
- TRACE(ft_t_noise,
- "empty segment, nothing written");
- }
- TRACE_EXIT result;
- }
- if (result == -EAGAIN) {
- if (++retry > 100) { /* give up */
- TRACE_ABORT(-EIO, ft_t_err,
- "write failed, >100 retries in segment");
- }
- TRACE(ft_t_warn, "write error, retry %d (%d)",
- retry,
- ftape_get_buffer(ft_queue_tail)->segment_id);
- } else {
- TRACE_ABORT(result, ft_t_err,
- "write_segment failed, error: %d", result);
- }
- /* Allow escape from loop when signaled !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- }
-}
diff --git a/drivers/char/ftape/lowlevel/ftape-write.h b/drivers/char/ftape/lowlevel/ftape-write.h
deleted file mode 100644
index 0e7f898b7af9..000000000000
--- a/drivers/char/ftape/lowlevel/ftape-write.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _FTAPE_WRITE_H
-#define _FTAPE_WRITE_H
-
-/*
- * Copyright (C) 1994-1995 Bas Laarhoven,
- * (C) 1996-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-write.h,v $
- $Author: claus $
- *
- $Revision: 1.2 $
- $Date: 1997/10/05 19:18:30 $
- $State: Exp $
- *
- * This file contains the definitions for the write functions
- * for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-
-/* ftape-write.c defined global functions.
- */
-typedef enum {
- FT_WR_ASYNC = 0, /* start tape only when all buffers are full */
- FT_WR_MULTI = 1, /* start tape, but don't necessarily stop */
- FT_WR_SINGLE = 2, /* write a single segment and stop afterwards */
- FT_WR_DELETE = 3 /* write deleted data marks */
-} ft_write_mode_t;
-
-extern int ftape_start_writing(const ft_write_mode_t mode);
-extern int ftape_write_segment(const int segment,
- const void *address,
- const ft_write_mode_t flushing);
-extern void ftape_zap_write_buffers(void);
-extern int ftape_loop_until_writes_done(void);
-
-#endif /* _FTAPE_WRITE_H */
-
diff --git a/drivers/char/ftape/lowlevel/ftape_syms.c b/drivers/char/ftape/lowlevel/ftape_syms.c
deleted file mode 100644
index 8e0dc4a07ca6..000000000000
--- a/drivers/char/ftape/lowlevel/ftape_syms.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 1996-1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape_syms.c,v $
- * $Revision: 1.4 $
- * $Date: 1997/10/17 00:03:51 $
- *
- * This file contains the symbols that the ftape low level
- * part of the QIC-40/80/3010/3020 floppy-tape driver "ftape"
- * exports to its high level clients
- */
-
-#include <linux/module.h>
-
-#include <linux/ftape.h>
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-init.h"
-#include "../lowlevel/fdc-io.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-rw.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-format.h"
-
-/* bad sector handling from ftape-bsm.c */
-EXPORT_SYMBOL(ftape_get_bad_sector_entry);
-EXPORT_SYMBOL(ftape_find_end_of_bsm_list);
-/* from ftape-rw.c */
-EXPORT_SYMBOL(ftape_set_state);
-/* from ftape-ctl.c */
-EXPORT_SYMBOL(ftape_seek_to_bot);
-EXPORT_SYMBOL(ftape_seek_to_eot);
-EXPORT_SYMBOL(ftape_abort_operation);
-EXPORT_SYMBOL(ftape_get_status);
-EXPORT_SYMBOL(ftape_enable);
-EXPORT_SYMBOL(ftape_disable);
-EXPORT_SYMBOL(ftape_mmap);
-EXPORT_SYMBOL(ftape_calibrate_data_rate);
-/* from ftape-io.c */
-EXPORT_SYMBOL(ftape_reset_drive);
-EXPORT_SYMBOL(ftape_command);
-EXPORT_SYMBOL(ftape_parameter);
-EXPORT_SYMBOL(ftape_ready_wait);
-EXPORT_SYMBOL(ftape_report_operation);
-EXPORT_SYMBOL(ftape_report_error);
-/* from ftape-read.c */
-EXPORT_SYMBOL(ftape_read_segment_fraction);
-EXPORT_SYMBOL(ftape_zap_read_buffers);
-EXPORT_SYMBOL(ftape_read_header_segment);
-EXPORT_SYMBOL(ftape_decode_header_segment);
-/* from ftape-write.c */
-EXPORT_SYMBOL(ftape_write_segment);
-EXPORT_SYMBOL(ftape_start_writing);
-EXPORT_SYMBOL(ftape_loop_until_writes_done);
-/* from ftape-buffer.h */
-EXPORT_SYMBOL(ftape_set_nr_buffers);
-/* from ftape-format.h */
-EXPORT_SYMBOL(ftape_format_track);
-EXPORT_SYMBOL(ftape_format_status);
-EXPORT_SYMBOL(ftape_verify_segment);
-/* from tracing.c */
-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
-EXPORT_SYMBOL(ftape_tracing);
-EXPORT_SYMBOL(ftape_function_nest_level);
-EXPORT_SYMBOL(ftape_trace_call);
-EXPORT_SYMBOL(ftape_trace_exit);
-EXPORT_SYMBOL(ftape_trace_log);
-#endif
-
diff --git a/drivers/char/ftape/zftape/Makefile b/drivers/char/ftape/zftape/Makefile
deleted file mode 100644
index 6d91c1f77c05..000000000000
--- a/drivers/char/ftape/zftape/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 1996, 1997 Claus-Justus Heine.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# $Source: /homes/cvs/ftape-stacked/ftape/zftape/Makefile,v $
-# $Revision: 1.4 $
-# $Date: 1997/10/05 19:18:58 $
-#
-# Makefile for the QIC-40/80/3010/3020 zftape interface VFS to
-# ftape
-#
-
-
-# ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should
-# leave this enabled for compatibility with taper.
-
-obj-$(CONFIG_ZFTAPE) += zftape.o
-
-zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \
- zftape-write.o zftape-vtbl.o zftape-eof.o \
- zftape-init.o zftape-buffers.o zftape_syms.o
-
-EXTRA_CFLAGS := -DZFT_OBSOLETE
diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c
deleted file mode 100644
index 7ebce2ec7897..000000000000
--- a/drivers/char/ftape/zftape/zftape-buffers.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 1995-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:59 $
- *
- * This file contains the dynamic buffer allocation routines
- * of zftape
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/zftape.h>
-
-#include <linux/vmalloc.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/* global variables
- */
-
-/* local varibales
- */
-static unsigned int used_memory;
-static unsigned int peak_memory;
-
-void zft_memory_stats(void)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Memory usage (vmalloc allocations):\n"
- KERN_INFO "total allocated: %d\n"
- KERN_INFO "peak allocation: %d",
- used_memory, peak_memory);
- peak_memory = used_memory;
- TRACE_EXIT;
-}
-
-int zft_vcalloc_once(void *new, size_t size)
-{
- TRACE_FUN(ft_t_flow);
- if (zft_vmalloc_once(new, size) < 0) {
- TRACE_EXIT -ENOMEM;
- }
- memset(*(void **)new, '\0', size);
- TRACE_EXIT 0;
-}
-int zft_vmalloc_once(void *new, size_t size)
-{
- TRACE_FUN(ft_t_flow);
-
- if (*(void **)new != NULL || size == 0) {
- TRACE_EXIT 0;
- }
- if ((*(void **)new = vmalloc(size)) == NULL) {
- TRACE_EXIT -ENOMEM;
- }
- used_memory += size;
- if (peak_memory < used_memory) {
- peak_memory = used_memory;
- }
- TRACE_ABORT(0, ft_t_noise,
- "allocated buffer @ %p, %zd bytes", *(void **)new, size);
-}
-int zft_vmalloc_always(void *new, size_t size)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_vfree(new, size);
- TRACE_EXIT zft_vmalloc_once(new, size);
-}
-void zft_vfree(void *old, size_t size)
-{
- TRACE_FUN(ft_t_flow);
-
- if (*(void **)old) {
- vfree(*(void **)old);
- used_memory -= size;
- TRACE(ft_t_noise, "released buffer @ %p, %zd bytes",
- *(void **)old, size);
- *(void **)old = NULL;
- }
- TRACE_EXIT;
-}
-
-void *zft_kmalloc(size_t size)
-{
- void *new;
-
- while ((new = kmalloc(size, GFP_KERNEL)) == NULL) {
- msleep_interruptible(100);
- }
- memset(new, 0, size);
- used_memory += size;
- if (peak_memory < used_memory) {
- peak_memory = used_memory;
- }
- return new;
-}
-
-void zft_kfree(void *old, size_t size)
-{
- kfree(old);
- used_memory -= size;
-}
-
-/* there are some more buffers that are allocated on demand.
- * cleanup_module() calles this function to be sure to have released
- * them
- */
-void zft_uninit_mem(void)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_vfree(&zft_hseg_buf, FT_SEGMENT_SIZE);
- zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); zft_deblock_segment = -1;
- zft_free_vtbl();
- if (zft_cmpr_lock(0 /* don't load */) == 0) {
- (*zft_cmpr_ops->cleanup)();
- (*zft_cmpr_ops->reset)(); /* unlock it again */
- }
- zft_memory_stats();
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-buffers.h b/drivers/char/ftape/zftape/zftape-buffers.h
deleted file mode 100644
index 798e3128c682..000000000000
--- a/drivers/char/ftape/zftape/zftape-buffers.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _FTAPE_DYNMEM_H
-#define _FTAPE_DYNMEM_H
-
-/*
- * Copyright (C) 1995-1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:18:59 $
- *
- * memory allocation routines.
- *
- */
-
-/* we do not allocate all of the really large buffer memory before
- * someone tries to open the drive. ftape_open() may fail with
- * -ENOMEM, but that's better having 200k of vmalloced memory which
- * cannot be swapped out.
- */
-
-extern void zft_memory_stats(void);
-extern int zft_vmalloc_once(void *new, size_t size);
-extern int zft_vcalloc_once(void *new, size_t size);
-extern int zft_vmalloc_always(void *new, size_t size);
-extern void zft_vfree(void *old, size_t size);
-extern void *zft_kmalloc(size_t size);
-extern void zft_kfree(void *old, size_t size);
-
-/* called by cleanup_module()
- */
-extern void zft_uninit_mem(void);
-
-#endif
-
-
-
-
-
-
-
diff --git a/drivers/char/ftape/zftape/zftape-ctl.c b/drivers/char/ftape/zftape/zftape-ctl.c
deleted file mode 100644
index 22ba0f5d00cf..000000000000
--- a/drivers/char/ftape/zftape/zftape-ctl.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.c,v $
- * $Revision: 1.2.6.2 $
- * $Date: 1997/11/14 18:07:33 $
- *
- * This file contains the non-read/write zftape functions
- * for the QIC-40/80/3010/3020 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/fcntl.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/* Global vars.
- */
-int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */
-int zft_header_read;
-int zft_offline;
-unsigned int zft_unit;
-int zft_resid;
-int zft_mt_compression;
-
-/* Local vars.
- */
-static int going_offline;
-
-typedef int (mt_fun)(int *argptr);
-typedef int (*mt_funp)(int *argptr);
-typedef struct
-{
- mt_funp function;
- unsigned offline : 1; /* op permitted if offline or no_tape */
- unsigned write_protected : 1; /* op permitted if write-protected */
- unsigned not_formatted : 1; /* op permitted if tape not formatted */
- unsigned raw_mode : 1; /* op permitted if zft_mode == 0 */
- unsigned need_idle_state : 1; /* need to call def_idle_state */
- char *name;
-} fun_entry;
-
-static mt_fun mt_dummy, mt_reset, mt_fsr, mt_bsr, mt_rew, mt_offl, mt_nop,
- mt_weof, mt_erase, mt_ras2, mt_setblk, mt_setdensity,
- mt_seek, mt_tell, mt_reten, mt_eom, mt_fsf, mt_bsf,
- mt_fsfm, mt_bsfm, mt_setdrvbuffer, mt_compression;
-
-static fun_entry mt_funs[]=
-{
- {mt_reset , 1, 1, 1, 1, 0, "MT_RESET" }, /* 0 */
- {mt_fsf , 0, 1, 0, 0, 1, "MT_FSF" },
- {mt_bsf , 0, 1, 0, 0, 1, "MT_BSF" },
- {mt_fsr , 0, 1, 0, 1, 1, "MT_FSR" },
- {mt_bsr , 0, 1, 0, 1, 1, "MT_BSR" },
- {mt_weof , 0, 0, 0, 0, 0, "MT_WEOF" }, /* 5 */
- {mt_rew , 0, 1, 1, 1, 0, "MT_REW" },
- {mt_offl , 0, 1, 1, 1, 0, "MT_OFFL" },
- {mt_nop , 1, 1, 1, 1, 0, "MT_NOP" },
- {mt_reten , 0, 1, 1, 1, 0, "MT_RETEN" },
- {mt_bsfm , 0, 1, 0, 0, 1, "MT_BSFM" }, /* 10 */
- {mt_fsfm , 0, 1, 0, 0, 1, "MT_FSFM" },
- {mt_eom , 0, 1, 0, 0, 1, "MT_EOM" },
- {mt_erase , 0, 0, 0, 1, 0, "MT_ERASE" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_RAS1" },
- {mt_ras2 , 0, 0, 0, 1, 0, "MT_RAS2" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_RAS3" },
- {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" },
- {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" },
- {mt_dummy , 1, 1, 1, 1, 0, "UNKNOWN" },
- {mt_setblk , 1, 1, 1, 1, 1, "MT_SETBLK"}, /* 20 */
- {mt_setdensity , 1, 1, 1, 1, 0, "MT_SETDENSITY"},
- {mt_seek , 0, 1, 0, 1, 1, "MT_SEEK" },
- {mt_dummy , 0, 1, 0, 1, 1, "MT_TELL" }, /* wr-only ?! */
- {mt_setdrvbuffer, 1, 1, 1, 1, 0, "MT_SETDRVBUFFER" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_FSS" }, /* 25 */
- {mt_dummy , 1, 1, 1, 1, 0, "MT_BSS" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_WSM" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_LOCK" },
- {mt_dummy , 1, 1, 1, 1, 0, "MT_UNLOCK"},
- {mt_dummy , 1, 1, 1, 1, 0, "MT_LOAD" }, /* 30 */
- {mt_dummy , 1, 1, 1, 1, 0, "MT_UNLOAD"},
- {mt_compression , 1, 1, 1, 0, 1, "MT_COMPRESSION"},
- {mt_dummy , 1, 1, 1, 1, 0, "MT_SETPART"},
- {mt_dummy , 1, 1, 1, 1, 0, "MT_MKPART"}
-};
-
-#define NR_MT_CMDS NR_ITEMS(mt_funs)
-
-void zft_reset_position(zft_position *pos)
-{
- TRACE_FUN(ft_t_flow);
-
- pos->seg_byte_pos =
- pos->volume_pos = 0;
- if (zft_header_read) {
- /* need to keep track of the volume table and
- * compression map. We therefor simply
- * position at the beginning of the first
- * volume. This covers old ftape archives as
- * well has various flavours of the
- * compression map segments. The worst case is
- * that the compression map shows up as a
- * additional volume in front of all others.
- */
- pos->seg_pos = zft_find_volume(0)->start_seg;
- pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
- } else {
- pos->tape_pos = 0;
- pos->seg_pos = -1;
- }
- zft_just_before_eof = 0;
- zft_deblock_segment = -1;
- zft_io_state = zft_idle;
- zft_zap_read_buffers();
- zft_prevent_flush();
- /* unlock the compresison module if it is loaded.
- * The zero arg means not to try to load the module.
- */
- if (zft_cmpr_lock(0) == 0) {
- (*zft_cmpr_ops->reset)(); /* unlock */
- }
- TRACE_EXIT;
-}
-
-static void zft_init_driver(void)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_resid =
- zft_header_read =
- zft_old_ftape =
- zft_offline =
- zft_write_protected =
- going_offline =
- zft_mt_compression =
- zft_header_changed =
- zft_volume_table_changed =
- zft_written_segments = 0;
- zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ;
- zft_reset_position(&zft_pos); /* does most of the stuff */
- ftape_zap_read_buffers();
- ftape_set_state(idle);
- TRACE_EXIT;
-}
-
-int zft_def_idle_state(void)
-{
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- if (!zft_header_read) {
- result = zft_read_header_segments();
- } else if ((result = zft_flush_buffers()) >= 0 && zft_qic_mode) {
- /* don't move past eof
- */
- (void)zft_close_volume(&zft_pos);
- }
- if (ftape_abort_operation() < 0) {
- TRACE(ft_t_warn, "ftape_abort_operation() failed");
- result = -EIO;
- }
- /* clear remaining read buffers */
- zft_zap_read_buffers();
- zft_io_state = zft_idle;
- TRACE_EXIT result;
-}
-
-/*****************************************************************************
- * *
- * functions for the MTIOCTOP commands *
- * *
- *****************************************************************************/
-
-static int mt_dummy(int *dummy)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE_EXIT -ENOSYS;
-}
-
-static int mt_reset(int *dummy)
-{
- TRACE_FUN(ft_t_flow);
-
- (void)ftape_seek_to_bot();
- TRACE_CATCH(ftape_reset_drive(),
- zft_init_driver(); zft_uninit_mem(); zft_offline = 1);
- /* fake a re-open of the device. This will set all flage and
- * allocate buffers as appropriate. The new tape condition will
- * force the open routine to do anything we need.
- */
- TRACE_CATCH(_zft_open(-1 /* fake reopen */, 0 /* dummy */),);
- TRACE_EXIT 0;
-}
-
-static int mt_fsf(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = zft_skip_volumes(*arg, &zft_pos);
- zft_just_before_eof = 0;
- TRACE_EXIT result;
-}
-
-static int mt_bsf(int *arg)
-{
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- if (*arg != 0) {
- result = zft_skip_volumes(-*arg + 1, &zft_pos);
- }
- TRACE_EXIT result;
-}
-
-static int seek_block(__s64 data_offset,
- __s64 block_increment,
- zft_position *pos)
-{
- int result = 0;
- __s64 new_block_pos;
- __s64 vol_block_count;
- const zft_volinfo *volume;
- int exceed;
- TRACE_FUN(ft_t_flow);
-
- volume = zft_find_volume(pos->seg_pos);
- if (volume->start_seg == 0 || volume->end_seg == 0) {
- TRACE_EXIT -EIO;
- }
- new_block_pos = (zft_div_blksz(data_offset, volume->blk_sz)
- + block_increment);
- vol_block_count = zft_div_blksz(volume->size, volume->blk_sz);
- if (new_block_pos < 0) {
- TRACE(ft_t_noise,
- "new_block_pos " LL_X " < 0", LL(new_block_pos));
- zft_resid = (int)new_block_pos;
- new_block_pos = 0;
- exceed = 1;
- } else if (new_block_pos > vol_block_count) {
- TRACE(ft_t_noise,
- "new_block_pos " LL_X " exceeds size of volume " LL_X,
- LL(new_block_pos), LL(vol_block_count));
- zft_resid = (int)(vol_block_count - new_block_pos);
- new_block_pos = vol_block_count;
- exceed = 1;
- } else {
- exceed = 0;
- }
- if (zft_use_compression && volume->use_compression) {
- TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
- result = (*zft_cmpr_ops->seek)(new_block_pos, pos, volume,
- zft_deblock_buf);
- pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
- pos->tape_pos += pos->seg_byte_pos;
- } else {
- pos->volume_pos = zft_mul_blksz(new_block_pos, volume->blk_sz);
- pos->tape_pos = zft_calc_tape_pos(volume->start_seg);
- pos->tape_pos += pos->volume_pos;
- pos->seg_pos = zft_calc_seg_byte_coord(&pos->seg_byte_pos,
- pos->tape_pos);
- }
- zft_just_before_eof = volume->size == pos->volume_pos;
- if (zft_just_before_eof) {
- /* why this? because zft_file_no checks agains start
- * and end segment of a volume. We do not want to
- * advance to the next volume with this function.
- */
- TRACE(ft_t_noise, "set zft_just_before_eof");
- zft_position_before_eof(pos, volume);
- }
- TRACE(ft_t_noise, "\n"
- KERN_INFO "new_seg_pos : %d\n"
- KERN_INFO "new_tape_pos: " LL_X "\n"
- KERN_INFO "vol_size : " LL_X "\n"
- KERN_INFO "seg_byte_pos: %d\n"
- KERN_INFO "blk_sz : %d",
- pos->seg_pos, LL(pos->tape_pos),
- LL(volume->size), pos->seg_byte_pos,
- volume->blk_sz);
- if (!exceed) {
- zft_resid = new_block_pos - zft_div_blksz(pos->volume_pos,
- volume->blk_sz);
- }
- if (zft_resid < 0) {
- zft_resid = -zft_resid;
- }
- TRACE_EXIT ((exceed || zft_resid != 0) && result >= 0) ? -EINVAL : result;
-}
-
-static int mt_fsr(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = seek_block(zft_pos.volume_pos, *arg, &zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_bsr(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = seek_block(zft_pos.volume_pos, -*arg, &zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_weof(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- TRACE_CATCH(zft_flush_buffers(),);
- result = zft_weof(*arg, &zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_rew(int *dummy)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- if(zft_header_read) {
- (void)zft_def_idle_state();
- }
- result = ftape_seek_to_bot();
- zft_reset_position(&zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_offl(int *dummy)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- going_offline= 1;
- result = mt_rew(NULL);
- TRACE_EXIT result;
-}
-
-static int mt_nop(int *dummy)
-{
- TRACE_FUN(ft_t_flow);
- /* should we set tape status?
- */
- if (!zft_offline) { /* offline includes no_tape */
- (void)zft_def_idle_state();
- }
- TRACE_EXIT 0;
-}
-
-static int mt_reten(int *dummy)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- if(zft_header_read) {
- (void)zft_def_idle_state();
- }
- result = ftape_seek_to_eot();
- if (result >= 0) {
- result = ftape_seek_to_bot();
- }
- TRACE_EXIT(result);
-}
-
-static int fsfbsfm(int arg, zft_position *pos)
-{
- const zft_volinfo *vtbl;
- __s64 block_pos;
- TRACE_FUN(ft_t_flow);
-
- /* What to do? This should seek to the next file-mark and
- * position BEFORE. That is, a next write would just extend
- * the current file. Well. Let's just seek to the end of the
- * current file, if count == 1. If count > 1, then do a
- * "mt_fsf(count - 1)", and then seek to the end of that file.
- * If count == 0, do nothing
- */
- if (arg == 0) {
- TRACE_EXIT 0;
- }
- zft_just_before_eof = 0;
- TRACE_CATCH(zft_skip_volumes(arg < 0 ? arg : arg-1, pos),
- if (arg > 0) {
- zft_resid ++;
- });
- vtbl = zft_find_volume(pos->seg_pos);
- block_pos = zft_div_blksz(vtbl->size, vtbl->blk_sz);
- (void)seek_block(0, block_pos, pos);
- if (pos->volume_pos != vtbl->size) {
- zft_just_before_eof = 0;
- zft_resid = 1;
- /* we didn't managed to go there */
- TRACE_ABORT(-EIO, ft_t_err,
- "wanted file position " LL_X ", arrived at " LL_X,
- LL(vtbl->size), LL(pos->volume_pos));
- }
- zft_just_before_eof = 1;
- TRACE_EXIT 0;
-}
-
-static int mt_bsfm(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = fsfbsfm(-*arg, &zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_fsfm(int *arg)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = fsfbsfm(*arg, &zft_pos);
- TRACE_EXIT result;
-}
-
-static int mt_eom(int *dummy)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_skip_to_eom(&zft_pos);
- TRACE_EXIT 0;
-}
-
-static int mt_erase(int *dummy)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = zft_erase();
- TRACE_EXIT result;
-}
-
-static int mt_ras2(int *dummy)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- result = -ENOSYS;
- TRACE_EXIT result;
-}
-
-/* Sets the new blocksize in BYTES
- *
- */
-static int mt_setblk(int *new_size)
-{
- TRACE_FUN(ft_t_flow);
-
- if((unsigned int)(*new_size) > ZFT_MAX_BLK_SZ) {
- TRACE_ABORT(-EINVAL, ft_t_info,
- "desired blk_sz (%d) should be <= %d bytes",
- *new_size, ZFT_MAX_BLK_SZ);
- }
- if ((*new_size & (FT_SECTOR_SIZE-1)) != 0) {
- TRACE_ABORT(-EINVAL, ft_t_info,
- "desired blk_sz (%d) must be a multiple of %d bytes",
- *new_size, FT_SECTOR_SIZE);
- }
- if (*new_size == 0) {
- if (zft_use_compression) {
- TRACE_ABORT(-EINVAL, ft_t_info,
- "Variable block size not yet "
- "supported with compression");
- }
- *new_size = 1;
- }
- zft_blk_sz = *new_size;
- TRACE_EXIT 0;
-}
-
-static int mt_setdensity(int *arg)
-{
- TRACE_FUN(ft_t_flow);
-
- SET_TRACE_LEVEL(*arg);
- TRACE(TRACE_LEVEL, "tracing set to %d", TRACE_LEVEL);
- if ((int)TRACE_LEVEL != *arg) {
- TRACE_EXIT -EINVAL;
- }
- TRACE_EXIT 0;
-}
-
-static int mt_seek(int *new_block_pos)
-{
- int result= 0;
- TRACE_FUN(ft_t_any);
-
- result = seek_block(0, (__s64)*new_block_pos, &zft_pos);
- TRACE_EXIT result;
-}
-
-/* OK, this is totally different from SCSI, but the worst thing that can
- * happen is that there is not enough defragmentated memory that can be
- * allocated. Also, there is a hardwired limit of 16 dma buffers in the
- * stock ftape module. This shouldn't bring the system down.
- *
- * NOTE: the argument specifies the total number of dma buffers to use.
- * The driver needs at least 3 buffers to function at all.
- *
- */
-static int mt_setdrvbuffer(int *cnt)
-{
- TRACE_FUN(ft_t_flow);
-
- if (*cnt < 3) {
- TRACE_EXIT -EINVAL;
- }
- TRACE_CATCH(ftape_set_nr_buffers(*cnt),);
- TRACE_EXIT 0;
-}
-/* return the block position from start of volume
- */
-static int mt_tell(int *arg)
-{
- TRACE_FUN(ft_t_flow);
-
- *arg = zft_div_blksz(zft_pos.volume_pos,
- zft_find_volume(zft_pos.seg_pos)->blk_sz);
- TRACE_EXIT 0;
-}
-
-static int mt_compression(int *arg)
-{
- TRACE_FUN(ft_t_flow);
-
- /* Ok. We could also check whether compression is available at
- * all by trying to load the compression module. We could
- * also check for a block size of 1 byte which is illegal
- * with compression. Instead of doing it here we rely on
- * zftape_write() to do the proper checks.
- */
- if ((unsigned int)*arg > 1) {
- TRACE_EXIT -EINVAL;
- }
- if (*arg != 0 && zft_blk_sz == 1) { /* variable block size */
- TRACE_ABORT(-EINVAL, ft_t_info,
- "Compression not yet supported "
- "with variable block size");
- }
- zft_mt_compression = *arg;
- if ((zft_unit & ZFT_ZIP_MODE) == 0) {
- zft_use_compression = zft_mt_compression;
- }
- TRACE_EXIT 0;
-}
-
-/* check whether write access is allowed. Write access is denied when
- * + zft_write_protected == 1 -- this accounts for either hard write
- * protection of the cartridge or for
- * O_RDONLY access mode of the tape device
- * + zft_offline == 1 -- this meany that there is either no tape
- * or that the MTOFFLINE ioctl has been
- * previously issued (`soft eject')
- * + ft_formatted == 0 -- this means that the cartridge is not
- * formatted
- * Then we distinuguish two cases. When zft_qic_mode is TRUE, then we try
- * to emulate a `traditional' (aka SCSI like) UN*X tape device. Therefore we
- * deny writes when
- * + zft_qic_mode ==1 &&
- * (!zft_tape_at_lbot() && -- tape no at logical BOT
- * !(zft_tape_at_eom() || -- tape not at logical EOM (or EOD)
- * (zft_tape_at_eom() &&
- * zft_old_ftape()))) -- we can't add new volume to tapes
- * written by old ftape because ftape
- * don't use the volume table
- *
- * when the drive is in true raw mode (aka /dev/rawft0) then we don't
- * care about LBOT and EOM conditions. This device is intended for a
- * user level program that wants to truly implement the QIC-80 compliance
- * at the logical data layout level of the cartridge, i.e. implement all
- * that volume table and volume directory stuff etc.<
- */
-int zft_check_write_access(zft_position *pos)
-{
- TRACE_FUN(ft_t_flow);
-
- if (zft_offline) { /* offline includes no_tape */
- TRACE_ABORT(-ENXIO,
- ft_t_info, "tape is offline or no cartridge");
- }
- if (!ft_formatted) {
- TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
- }
- if (zft_write_protected) {
- TRACE_ABORT(-EACCES, ft_t_info, "cartridge write protected");
- }
- if (zft_qic_mode) {
- /* check BOT condition */
- if (!zft_tape_at_lbot(pos)) {
- /* protect cartridges written by old ftape if
- * not at BOT because they use the vtbl
- * segment for storing data
- */
- if (zft_old_ftape) {
- TRACE_ABORT(-EACCES, ft_t_warn,
- "Cannot write to cartridges written by old ftape when not at BOT");
- }
- /* not at BOT, but allow writes at EOD, of course
- */
- if (!zft_tape_at_eod(pos)) {
- TRACE_ABORT(-EACCES, ft_t_info,
- "tape not at BOT and not at EOD");
- }
- }
- /* fine. Now the tape is either at BOT or at EOD. */
- }
- /* or in raw mode in which case we don't care about BOT and EOD */
- TRACE_EXIT 0;
-}
-
-/* OPEN routine called by kernel-interface code
- *
- * NOTE: this is also called by mt_reset() with dev_minor == -1
- * to fake a reopen after a reset.
- */
-int _zft_open(unsigned int dev_minor, unsigned int access_mode)
-{
- static unsigned int tape_unit;
- static unsigned int file_access_mode;
- int result;
- TRACE_FUN(ft_t_flow);
-
- if ((int)dev_minor == -1) {
- /* fake reopen */
- zft_unit = tape_unit;
- access_mode = file_access_mode;
- zft_init_driver(); /* reset all static data to defaults */
- } else {
- tape_unit = dev_minor;
- file_access_mode = access_mode;
- if ((result = ftape_enable(FTAPE_SEL(dev_minor))) < 0) {
- TRACE_ABORT(-ENXIO, ft_t_err,
- "ftape_enable failed: %d", result);
- }
- if (ft_new_tape || ft_no_tape || !ft_formatted ||
- (FTAPE_SEL(zft_unit) != FTAPE_SEL(dev_minor)) ||
- (zft_unit & ZFT_RAW_MODE) != (dev_minor & ZFT_RAW_MODE)) {
- /* reset all static data to defaults,
- */
- zft_init_driver();
- }
- zft_unit = dev_minor;
- }
- zft_set_flags(zft_unit); /* decode the minor bits */
- if (zft_blk_sz == 1 && zft_use_compression) {
- ftape_disable(); /* resets ft_no_tape */
- TRACE_ABORT(-ENODEV, ft_t_warn, "Variable block size not yet "
- "supported with compression");
- }
- /* no need for most of the buffers when no tape or not
- * formatted. for the read/write operations, it is the
- * regardless whether there is no tape, a not-formatted tape
- * or the whether the driver is soft offline.
- * Nevertheless we allow some ioctls with non-formatted tapes,
- * like rewind and reset.
- */
- if (ft_no_tape || !ft_formatted) {
- zft_uninit_mem();
- }
- if (ft_no_tape) {
- zft_offline = 1; /* so we need not test two variables */
- }
- if ((access_mode == O_WRONLY || access_mode == O_RDWR) &&
- (ft_write_protected || ft_no_tape)) {
- ftape_disable(); /* resets ft_no_tape */
- TRACE_ABORT(ft_no_tape ? -ENXIO : -EROFS,
- ft_t_warn, "wrong access mode %s cartridge",
- ft_no_tape ? "without a" : "with write protected");
- }
- zft_write_protected = (access_mode == O_RDONLY ||
- ft_write_protected != 0);
- if (zft_write_protected) {
- TRACE(ft_t_noise,
- "read only access mode: %d, "
- "drive write protected: %d",
- access_mode == O_RDONLY,
- ft_write_protected != 0);
- }
- if (!zft_offline) {
- TRACE_CATCH(zft_vmalloc_once(&zft_deblock_buf,FT_SEGMENT_SIZE),
- ftape_disable());
- }
- /* zft_seg_pos should be greater than the vtbl segpos but not
- * if in compatibility mode and only after we read in the
- * header segments
- *
- * might also be a problem if the user makes a backup with a
- * *qft* device and rewinds it with a raw device.
- */
- if (zft_qic_mode &&
- !zft_old_ftape &&
- zft_pos.seg_pos >= 0 &&
- zft_header_read &&
- zft_pos.seg_pos <= ft_first_data_segment) {
- TRACE(ft_t_noise, "you probably mixed up the zftape devices!");
- zft_reset_position(&zft_pos);
- }
- TRACE_EXIT 0;
-}
-
-/* RELEASE routine called by kernel-interface code
- */
-int _zft_close(void)
-{
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- if (zft_offline) {
- /* call the hardware release routine. Puts the drive offline */
- ftape_disable();
- TRACE_EXIT 0;
- }
- if (!(ft_write_protected || zft_old_ftape)) {
- result = zft_flush_buffers();
- TRACE(ft_t_noise, "writing file mark at current position");
- if (zft_qic_mode && zft_close_volume(&zft_pos) == 0) {
- zft_move_past_eof(&zft_pos);
- }
- if ((zft_tape_at_lbot(&zft_pos) ||
- !(zft_unit & FTAPE_NO_REWIND))) {
- if (result >= 0) {
- result = zft_update_header_segments();
- } else {
- TRACE(ft_t_err,
- "Error: unable to update header segments");
- }
- }
- }
- ftape_abort_operation();
- if (!(zft_unit & FTAPE_NO_REWIND)) {
- TRACE(ft_t_noise, "rewinding tape");
- if (ftape_seek_to_bot() < 0 && result >= 0) {
- result = -EIO; /* keep old value */
- }
- zft_reset_position(&zft_pos);
- }
- zft_zap_read_buffers();
- /* now free up memory as much as possible. We don't destroy
- * the deblock buffer if it containes a valid segment.
- */
- if (zft_deblock_segment == -1) {
- zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE);
- }
- /* high level driver status, forces creation of a new volume
- * when calling ftape_write again and not zft_just_before_eof
- */
- zft_io_state = zft_idle;
- if (going_offline) {
- zft_init_driver();
- zft_uninit_mem();
- going_offline = 0;
- zft_offline = 1;
- } else if (zft_cmpr_lock(0 /* don't load */) == 0) {
- (*zft_cmpr_ops->reset)(); /* unlock it again */
- }
- zft_memory_stats();
- /* call the hardware release routine. Puts the drive offline */
- ftape_disable();
- TRACE_EXIT result;
-}
-
-/*
- * the wrapper function around the wrapper MTIOCTOP ioctl
- */
-static int mtioctop(struct mtop *mtop, int arg_size)
-{
- int result = 0;
- fun_entry *mt_fun_entry;
- TRACE_FUN(ft_t_flow);
-
- if (arg_size != sizeof(struct mtop) || mtop->mt_op >= NR_MT_CMDS) {
- TRACE_EXIT -EINVAL;
- }
- TRACE(ft_t_noise, "calling MTIOCTOP command: %s",
- mt_funs[mtop->mt_op].name);
- mt_fun_entry= &mt_funs[mtop->mt_op];
- zft_resid = mtop->mt_count;
- if (!mt_fun_entry->offline && zft_offline) {
- if (ft_no_tape) {
- TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
- } else {
- TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
- }
- }
- if (!mt_fun_entry->not_formatted && !ft_formatted) {
- TRACE_ABORT(-EACCES, ft_t_info, "tape is not formatted");
- }
- if (!mt_fun_entry->write_protected) {
- TRACE_CATCH(zft_check_write_access(&zft_pos),);
- }
- if (mt_fun_entry->need_idle_state && !(zft_offline || !ft_formatted)) {
- TRACE_CATCH(zft_def_idle_state(),);
- }
- if (!zft_qic_mode && !mt_fun_entry->raw_mode) {
- TRACE_ABORT(-EACCES, ft_t_info,
-"Drive needs to be in QIC-80 compatibility mode for this command");
- }
- result = (mt_fun_entry->function)(&mtop->mt_count);
- if (zft_tape_at_lbot(&zft_pos)) {
- TRACE_CATCH(zft_update_header_segments(),);
- }
- if (result >= 0) {
- zft_resid = 0;
- }
- TRACE_EXIT result;
-}
-
-/*
- * standard MTIOCGET ioctl
- */
-static int mtiocget(struct mtget *mtget, int arg_size)
-{
- const zft_volinfo *volume;
- __s64 max_tape_pos;
- TRACE_FUN(ft_t_flow);
-
- if (arg_size != sizeof(struct mtget)) {
- TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
- arg_size);
- }
- mtget->mt_type = ft_drive_type.vendor_id + 0x800000;
- mtget->mt_dsreg = ft_last_status.space;
- mtget->mt_erreg = ft_last_error.space; /* error register */
- mtget->mt_resid = zft_resid; /* residuum of writes, reads and
- * MTIOCTOP commands
- */
- if (!zft_offline) { /* neither no_tape nor soft offline */
- mtget->mt_gstat = GMT_ONLINE(~0UL);
- /* should rather return the status of the cartridge
- * than the access mode of the file, therefor use
- * ft_write_protected, not zft_write_protected
- */
- if (ft_write_protected) {
- mtget->mt_gstat |= GMT_WR_PROT(~0UL);
- }
- if(zft_header_read) { /* this catches non-formatted */
- volume = zft_find_volume(zft_pos.seg_pos);
- mtget->mt_fileno = volume->count;
- max_tape_pos = zft_capacity - zft_blk_sz;
- if (zft_use_compression) {
- max_tape_pos -= ZFT_CMPR_OVERHEAD;
- }
- if (zft_tape_at_eod(&zft_pos)) {
- mtget->mt_gstat |= GMT_EOD(~0UL);
- }
- if (zft_pos.tape_pos > max_tape_pos) {
- mtget->mt_gstat |= GMT_EOT(~0UL);
- }
- mtget->mt_blkno = zft_div_blksz(zft_pos.volume_pos,
- volume->blk_sz);
- if (zft_just_before_eof) {
- mtget->mt_gstat |= GMT_EOF(~0UL);
- }
- if (zft_tape_at_lbot(&zft_pos)) {
- mtget->mt_gstat |= GMT_BOT(~0UL);
- }
- } else {
- mtget->mt_fileno = mtget->mt_blkno = -1;
- if (mtget->mt_dsreg & QIC_STATUS_AT_BOT) {
- mtget->mt_gstat |= GMT_BOT(~0UL);
- }
- }
- } else {
- if (ft_no_tape) {
- mtget->mt_gstat = GMT_DR_OPEN(~0UL);
- } else {
- mtget->mt_gstat = 0UL;
- }
- mtget->mt_fileno = mtget->mt_blkno = -1;
- }
- TRACE_EXIT 0;
-}
-
-#ifdef MTIOCRDFTSEG
-/*
- * Read a floppy tape segment. This is useful for manipulating the
- * volume table, and read the old header segment before re-formatting
- * the cartridge.
- */
-static int mtiocrdftseg(struct mtftseg * mtftseg, int arg_size)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCRDFTSEG");
- if (zft_qic_mode) {
- TRACE_ABORT(-EACCES, ft_t_info,
- "driver needs to be in raw mode for this ioctl");
- }
- if (arg_size != sizeof(struct mtftseg)) {
- TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
- arg_size);
- }
- if (zft_offline) {
- TRACE_EXIT -ENXIO;
- }
- if (mtftseg->mt_mode != FT_RD_SINGLE &&
- mtftseg->mt_mode != FT_RD_AHEAD) {
- TRACE_ABORT(-EINVAL, ft_t_info, "invalid read mode");
- }
- if (!ft_formatted) {
- TRACE_EXIT -EACCES; /* -ENXIO ? */
-
- }
- if (!zft_header_read) {
- TRACE_CATCH(zft_def_idle_state(),);
- }
- if (mtftseg->mt_segno > ft_last_data_segment) {
- TRACE_ABORT(-EINVAL, ft_t_info, "segment number is too large");
- }
- mtftseg->mt_result = ftape_read_segment(mtftseg->mt_segno,
- zft_deblock_buf,
- mtftseg->mt_mode);
- if (mtftseg->mt_result < 0) {
- /* a negativ result is not an ioctl error. if
- * the user wants to read damaged tapes,
- * it's up to her/him
- */
- TRACE_EXIT 0;
- }
- if (copy_to_user(mtftseg->mt_data,
- zft_deblock_buf,
- mtftseg->mt_result) != 0) {
- TRACE_EXIT -EFAULT;
- }
- TRACE_EXIT 0;
-}
-#endif
-
-#ifdef MTIOCWRFTSEG
-/*
- * write a floppy tape segment. This version features writing of
- * deleted address marks, and gracefully ignores the (software)
- * ft_formatted flag to support writing of header segments after
- * formatting.
- */
-static int mtiocwrftseg(struct mtftseg * mtftseg, int arg_size)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCWRFTSEG");
- if (zft_write_protected || zft_qic_mode) {
- TRACE_EXIT -EACCES;
- }
- if (arg_size != sizeof(struct mtftseg)) {
- TRACE_ABORT(-EINVAL, ft_t_info, "bad argument size: %d",
- arg_size);
- }
- if (zft_offline) {
- TRACE_EXIT -ENXIO;
- }
- if (mtftseg->mt_mode != FT_WR_ASYNC &&
- mtftseg->mt_mode != FT_WR_MULTI &&
- mtftseg->mt_mode != FT_WR_SINGLE &&
- mtftseg->mt_mode != FT_WR_DELETE) {
- TRACE_ABORT(-EINVAL, ft_t_info, "invalid write mode");
- }
- /*
- * We don't check for ft_formatted, because this gives
- * only the software status of the driver.
- *
- * We assume that the user knows what it is
- * doing. And rely on the low level stuff to fail
- * when the tape isn't formatted. We only make sure
- * that The header segment buffer is allocated,
- * because it holds the bad sector map.
- */
- if (zft_hseg_buf == NULL) {
- TRACE_EXIT -ENXIO;
- }
- if (mtftseg->mt_mode != FT_WR_DELETE) {
- if (copy_from_user(zft_deblock_buf,
- mtftseg->mt_data,
- FT_SEGMENT_SIZE) != 0) {
- TRACE_EXIT -EFAULT;
- }
- }
- mtftseg->mt_result = ftape_write_segment(mtftseg->mt_segno,
- zft_deblock_buf,
- mtftseg->mt_mode);
- if (mtftseg->mt_result >= 0 && mtftseg->mt_mode == FT_WR_SINGLE) {
- /*
- * a negativ result is not an ioctl error. if
- * the user wants to write damaged tapes,
- * it's up to her/him
- */
- if ((result = ftape_loop_until_writes_done()) < 0) {
- mtftseg->mt_result = result;
- }
- }
- TRACE_EXIT 0;
-}
-#endif
-
-#ifdef MTIOCVOLINFO
-/*
- * get information about volume positioned at.
- */
-static int mtiocvolinfo(struct mtvolinfo *volinfo, int arg_size)
-{
- const zft_volinfo *volume;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCVOLINFO");
- if (arg_size != sizeof(struct mtvolinfo)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- if (zft_offline) {
- TRACE_EXIT -ENXIO;
- }
- if (!ft_formatted) {
- TRACE_EXIT -EACCES;
- }
- TRACE_CATCH(zft_def_idle_state(),);
- volume = zft_find_volume(zft_pos.seg_pos);
- volinfo->mt_volno = volume->count;
- volinfo->mt_blksz = volume->blk_sz == 1 ? 0 : volume->blk_sz;
- volinfo->mt_size = volume->size >> 10;
- volinfo->mt_rawsize = ((zft_calc_tape_pos(volume->end_seg + 1) >> 10) -
- (zft_calc_tape_pos(volume->start_seg) >> 10));
- volinfo->mt_cmpr = volume->use_compression;
- TRACE_EXIT 0;
-}
-#endif
-
-#ifdef ZFT_OBSOLETE
-static int mtioc_zftape_getblksz(struct mtblksz *blksz, int arg_size)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "\n"
- KERN_INFO "Mag tape ioctl command: MTIOC_ZTAPE_GETBLKSZ\n"
- KERN_INFO "This ioctl is here merely for compatibility.\n"
- KERN_INFO "Please use MTIOCVOLINFO instead");
- if (arg_size != sizeof(struct mtblksz)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- if (zft_offline) {
- TRACE_EXIT -ENXIO;
- }
- if (!ft_formatted) {
- TRACE_EXIT -EACCES;
- }
- TRACE_CATCH(zft_def_idle_state(),);
- blksz->mt_blksz = zft_find_volume(zft_pos.seg_pos)->blk_sz;
- TRACE_EXIT 0;
-}
-#endif
-
-#ifdef MTIOCGETSIZE
-/*
- * get the capacity of the tape cartridge.
- */
-static int mtiocgetsize(struct mttapesize *size, int arg_size)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOC_ZFTAPE_GETSIZE");
- if (arg_size != sizeof(struct mttapesize)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- if (zft_offline) {
- TRACE_EXIT -ENXIO;
- }
- if (!ft_formatted) {
- TRACE_EXIT -EACCES;
- }
- TRACE_CATCH(zft_def_idle_state(),);
- size->mt_capacity = (unsigned int)(zft_capacity>>10);
- size->mt_used = (unsigned int)(zft_get_eom_pos()>>10);
- TRACE_EXIT 0;
-}
-#endif
-
-static int mtiocpos(struct mtpos *mtpos, int arg_size)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCPOS");
- if (arg_size != sizeof(struct mtpos)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- result = mt_tell((int *)&mtpos->mt_blkno);
- TRACE_EXIT result;
-}
-
-#ifdef MTIOCFTFORMAT
-/*
- * formatting of floppy tape cartridges. This is intended to be used
- * together with the MTIOCFTCMD ioctl and the new mmap feature
- */
-
-/*
- * This function uses ftape_decode_header_segment() to inform the low
- * level ftape module about the new parameters.
- *
- * It erases the hseg_buf. The calling process must specify all
- * parameters to assure proper operation.
- *
- * return values: -EINVAL - wrong argument size
- * -EINVAL - if ftape_decode_header_segment() failed.
- */
-static int set_format_parms(struct ftfmtparms *p, __u8 *hseg_buf)
-{
- ft_trace_t old_level = TRACE_LEVEL;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_SETPARMS");
- memset(hseg_buf, 0, FT_SEGMENT_SIZE);
- PUT4(hseg_buf, FT_SIGNATURE, FT_HSEG_MAGIC);
-
- /* fill in user specified parameters
- */
- hseg_buf[FT_FMT_CODE] = (__u8)p->ft_fmtcode;
- PUT2(hseg_buf, FT_SPT, p->ft_spt);
- hseg_buf[FT_TPC] = (__u8)p->ft_tpc;
- hseg_buf[FT_FHM] = (__u8)p->ft_fhm;
- hseg_buf[FT_FTM] = (__u8)p->ft_ftm;
-
- /* fill in sane defaults to make ftape happy.
- */
- hseg_buf[FT_FSM] = (__u8)128; /* 128 is hard wired all over ftape */
- if (p->ft_fmtcode == fmt_big) {
- PUT4(hseg_buf, FT_6_HSEG_1, 0);
- PUT4(hseg_buf, FT_6_HSEG_2, 1);
- PUT4(hseg_buf, FT_6_FRST_SEG, 2);
- PUT4(hseg_buf, FT_6_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
- } else {
- PUT2(hseg_buf, FT_HSEG_1, 0);
- PUT2(hseg_buf, FT_HSEG_2, 1);
- PUT2(hseg_buf, FT_FRST_SEG, 2);
- PUT2(hseg_buf, FT_LAST_SEG, p->ft_spt * p->ft_tpc - 1);
- }
-
- /* Synchronize with the low level module. This is particularly
- * needed for unformatted cartridges as the QIC std was previously
- * unknown BUT is needed to set data rate and to calculate timeouts.
- */
- TRACE_CATCH(ftape_calibrate_data_rate(p->ft_qicstd&QIC_TAPE_STD_MASK),
- _res = -EINVAL);
-
- /* The following will also recalcualte the timeouts for the tape
- * length and QIC std we want to format to.
- * abort with -EINVAL rather than -EIO
- */
- SET_TRACE_LEVEL(ft_t_warn);
- TRACE_CATCH(ftape_decode_header_segment(hseg_buf),
- SET_TRACE_LEVEL(old_level); _res = -EINVAL);
- SET_TRACE_LEVEL(old_level);
- TRACE_EXIT 0;
-}
-
-/*
- * Return the internal SOFTWARE status of the kernel driver. This does
- * NOT query the tape drive about its status.
- */
-static int get_format_parms(struct ftfmtparms *p, __u8 *hseg_buffer)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "MTIOCFTFORMAT operation FTFMT_GETPARMS");
- p->ft_qicstd = ft_qic_std;
- p->ft_fmtcode = ft_format_code;
- p->ft_fhm = hseg_buffer[FT_FHM];
- p->ft_ftm = hseg_buffer[FT_FTM];
- p->ft_spt = ft_segments_per_track;
- p->ft_tpc = ft_tracks_per_tape;
- TRACE_EXIT 0;
-}
-
-static int mtiocftformat(struct mtftformat *mtftformat, int arg_size)
-{
- int result;
- union fmt_arg *arg = &mtftformat->fmt_arg;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTFORMAT");
- if (zft_offline) {
- if (ft_no_tape) {
- TRACE_ABORT(-ENXIO, ft_t_info, "no tape present");
- } else {
- TRACE_ABORT(-ENXIO, ft_t_info, "drive is offline");
- }
- }
- if (zft_qic_mode) {
- TRACE_ABORT(-EACCES, ft_t_info,
- "driver needs to be in raw mode for this ioctl");
- }
- if (zft_hseg_buf == NULL) {
- TRACE_CATCH(zft_vcalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),);
- }
- zft_header_read = 0;
- switch(mtftformat->fmt_op) {
- case FTFMT_SET_PARMS:
- TRACE_CATCH(set_format_parms(&arg->fmt_parms, zft_hseg_buf),);
- TRACE_EXIT 0;
- case FTFMT_GET_PARMS:
- TRACE_CATCH(get_format_parms(&arg->fmt_parms, zft_hseg_buf),);
- TRACE_EXIT 0;
- case FTFMT_FORMAT_TRACK:
- if ((ft_formatted && zft_check_write_access(&zft_pos) < 0) ||
- (!ft_formatted && zft_write_protected)) {
- TRACE_ABORT(-EACCES, ft_t_info, "Write access denied");
- }
- TRACE_CATCH(ftape_format_track(arg->fmt_track.ft_track,
- arg->fmt_track.ft_gap3),);
- TRACE_EXIT 0;
- case FTFMT_STATUS:
- TRACE_CATCH(ftape_format_status(&arg->fmt_status.ft_segment),);
- TRACE_EXIT 0;
- case FTFMT_VERIFY:
- TRACE_CATCH(ftape_verify_segment(arg->fmt_verify.ft_segment,
- (SectorMap *)&arg->fmt_verify.ft_bsm),);
- TRACE_EXIT 0;
- default:
- TRACE_ABORT(-EINVAL, ft_t_err, "Invalid format operation");
- }
- TRACE_EXIT result;
-}
-#endif
-
-#ifdef MTIOCFTCMD
-/*
- * send a QIC-117 command to the drive, with optional timeouts,
- * parameter and result bits. This is intended to be used together
- * with the formatting ioctl.
- */
-static int mtiocftcmd(struct mtftcmd *ftcmd, int arg_size)
-{
- int i;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "Mag tape ioctl command: MTIOCFTCMD");
- if (!capable(CAP_SYS_ADMIN)) {
- TRACE_ABORT(-EPERM, ft_t_info,
- "need CAP_SYS_ADMIN capability to send raw qic-117 commands");
- }
- if (zft_qic_mode) {
- TRACE_ABORT(-EACCES, ft_t_info,
- "driver needs to be in raw mode for this ioctl");
- }
- if (arg_size != sizeof(struct mtftcmd)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- if (ftcmd->ft_wait_before) {
- TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_before,
- &ftcmd->ft_status),);
- }
- if (ftcmd->ft_status & QIC_STATUS_ERROR)
- goto ftmtcmd_error;
- if (ftcmd->ft_result_bits != 0) {
- TRACE_CATCH(ftape_report_operation(&ftcmd->ft_result,
- ftcmd->ft_cmd,
- ftcmd->ft_result_bits),);
- } else {
- TRACE_CATCH(ftape_command(ftcmd->ft_cmd),);
- if (ftcmd->ft_status & QIC_STATUS_ERROR)
- goto ftmtcmd_error;
- for (i = 0; i < ftcmd->ft_parm_cnt; i++) {
- TRACE_CATCH(ftape_parameter(ftcmd->ft_parms[i]&0x0f),);
- if (ftcmd->ft_status & QIC_STATUS_ERROR)
- goto ftmtcmd_error;
- }
- }
- if (ftcmd->ft_wait_after != 0) {
- TRACE_CATCH(ftape_ready_wait(ftcmd->ft_wait_after,
- &ftcmd->ft_status),);
- }
-ftmtcmd_error:
- if (ftcmd->ft_status & QIC_STATUS_ERROR) {
- TRACE(ft_t_noise, "error status set");
- TRACE_CATCH(ftape_report_error(&ftcmd->ft_error,
- &ftcmd->ft_cmd, 1),);
- }
- TRACE_EXIT 0; /* this is not an i/o error */
-}
-#endif
-
-/* IOCTL routine called by kernel-interface code
- */
-int _zft_ioctl(unsigned int command, void __user * arg)
-{
- int result;
- union { struct mtop mtop;
- struct mtget mtget;
- struct mtpos mtpos;
-#ifdef MTIOCRDFTSEG
- struct mtftseg mtftseg;
-#endif
-#ifdef MTIOCVOLINFO
- struct mtvolinfo mtvolinfo;
-#endif
-#ifdef MTIOCGETSIZE
- struct mttapesize mttapesize;
-#endif
-#ifdef MTIOCFTFORMAT
- struct mtftformat mtftformat;
-#endif
-#ifdef ZFT_OBSOLETE
- struct mtblksz mtblksz;
-#endif
-#ifdef MTIOCFTCMD
- struct mtftcmd mtftcmd;
-#endif
- } krnl_arg;
- int arg_size = _IOC_SIZE(command);
- int dir = _IOC_DIR(command);
- TRACE_FUN(ft_t_flow);
-
- /* This check will only catch arguments that are too large !
- */
- if (dir & (_IOC_READ | _IOC_WRITE) && arg_size > sizeof(krnl_arg)) {
- TRACE_ABORT(-EINVAL,
- ft_t_info, "bad argument size: %d", arg_size);
- }
- if (dir & _IOC_WRITE) {
- if (copy_from_user(&krnl_arg, arg, arg_size) != 0) {
- TRACE_EXIT -EFAULT;
- }
- }
- TRACE(ft_t_flow, "called with ioctl command: 0x%08x", command);
- switch (command) {
- case MTIOCTOP:
- result = mtioctop(&krnl_arg.mtop, arg_size);
- break;
- case MTIOCGET:
- result = mtiocget(&krnl_arg.mtget, arg_size);
- break;
- case MTIOCPOS:
- result = mtiocpos(&krnl_arg.mtpos, arg_size);
- break;
-#ifdef MTIOCVOLINFO
- case MTIOCVOLINFO:
- result = mtiocvolinfo(&krnl_arg.mtvolinfo, arg_size);
- break;
-#endif
-#ifdef ZFT_OBSOLETE
- case MTIOC_ZFTAPE_GETBLKSZ:
- result = mtioc_zftape_getblksz(&krnl_arg.mtblksz, arg_size);
- break;
-#endif
-#ifdef MTIOCRDFTSEG
- case MTIOCRDFTSEG: /* read a segment via ioctl */
- result = mtiocrdftseg(&krnl_arg.mtftseg, arg_size);
- break;
-#endif
-#ifdef MTIOCWRFTSEG
- case MTIOCWRFTSEG: /* write a segment via ioctl */
- result = mtiocwrftseg(&krnl_arg.mtftseg, arg_size);
- break;
-#endif
-#ifdef MTIOCGETSIZE
- case MTIOCGETSIZE:
- result = mtiocgetsize(&krnl_arg.mttapesize, arg_size);
- break;
-#endif
-#ifdef MTIOCFTFORMAT
- case MTIOCFTFORMAT:
- result = mtiocftformat(&krnl_arg.mtftformat, arg_size);
- break;
-#endif
-#ifdef MTIOCFTCMD
- case MTIOCFTCMD:
- result = mtiocftcmd(&krnl_arg.mtftcmd, arg_size);
- break;
-#endif
- default:
- result = -EINVAL;
- break;
- }
- if ((result >= 0) && (dir & _IOC_READ)) {
- if (copy_to_user(arg, &krnl_arg, arg_size) != 0) {
- TRACE_EXIT -EFAULT;
- }
- }
- TRACE_EXIT result;
-}
diff --git a/drivers/char/ftape/zftape/zftape-ctl.h b/drivers/char/ftape/zftape/zftape-ctl.h
deleted file mode 100644
index 8e6f2d7ac74e..000000000000
--- a/drivers/char/ftape/zftape/zftape-ctl.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _ZFTAPE_CTL_H
-#define _ZFTAPE_CTL_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-ctl.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:02 $
- *
- * This file contains the non-standard IOCTL related definitions
- * for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ioctl.h>
-#include <linux/mtio.h>
-
-#include "../zftape/zftape-rw.h"
-
-#ifdef CONFIG_ZFTAPE_MODULE
-#define ftape_status (*zft_status)
-#endif
-
-extern int zft_offline;
-extern int zft_mt_compression;
-extern int zft_write_protected;
-extern int zft_header_read;
-extern unsigned int zft_unit;
-extern int zft_resid;
-
-extern void zft_reset_position(zft_position *pos);
-extern int zft_check_write_access(zft_position *pos);
-extern int zft_def_idle_state(void);
-
-/* hooks for the VFS interface
- */
-extern int _zft_open(unsigned int dev_minor, unsigned int access_mode);
-extern int _zft_close(void);
-extern int _zft_ioctl(unsigned int command, void __user *arg);
-#endif
-
-
-
diff --git a/drivers/char/ftape/zftape/zftape-eof.c b/drivers/char/ftape/zftape/zftape-eof.c
deleted file mode 100644
index dcadcaee9ac1..000000000000
--- a/drivers/char/ftape/zftape/zftape-eof.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * I use these routines just to decide when I have to fake a
- * volume-table to preserve compatibility to original ftape.
- */
-/*
- * Copyright (C) 1994-1995 Bas Laarhoven.
- *
- * Modified for zftape 1996, 1997 Claus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:02 $
- *
- * This file contains the eof mark handling code
- * for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/zftape.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-eof.h"
-
-/* Global vars.
- */
-
-/* a copy of the failed sector log from the header segment.
- */
-eof_mark_union *zft_eof_map;
-
-/* number of eof marks (entries in bad sector log) on tape.
- */
-int zft_nr_eof_marks = -1;
-
-
-/* Local vars.
- */
-
-static char linux_tape_label[] = "Linux raw format V";
-enum {
- min_fmt_version = 1, max_fmt_version = 2
-};
-static unsigned ftape_fmt_version = 0;
-
-
-/* Ftape (mis)uses the bad sector log to record end-of-file marks.
- * Initially (when the tape is erased) all entries in the bad sector
- * log are added to the tape's bad sector map. The bad sector log then
- * is cleared.
- *
- * The bad sector log normally contains entries of the form:
- * even 16-bit word: segment number of bad sector
- * odd 16-bit word: encoded date
- * There can be a total of 448 entries (1792 bytes).
- *
- * My guess is that no program is using this bad sector log (the *
- * format seems useless as there is no indication of the bad sector
- * itself, only the segment) However, if any program does use the bad
- * sector log, the format used by ftape will let the program think
- * there are some bad sectors and no harm is done.
- *
- * The eof mark entries that ftape stores in the bad sector log: even
- * 16-bit word: segment number of eof mark odd 16-bit word: sector
- * number of eof mark [1..32]
- *
- * The zft_eof_map as maintained is a sorted list of eof mark entries.
- *
- *
- * The tape name field in the header segments is used to store a linux
- * tape identification string and a version number. This way the tape
- * can be recognized as a Linux raw format tape when using tools under
- * other OS's.
- *
- * 'Wide' QIC tapes (format code 4) don't have a failed sector list
- * anymore. That space is used for the (longer) bad sector map that
- * now is a variable length list too. We now store our end-of-file
- * marker list after the bad-sector-map on tape. The list is delimited
- * by a (__u32) 0 entry.
- */
-
-int zft_ftape_validate_label(char *label)
-{
- static char tmp_label[45];
- int result = 0;
- TRACE_FUN(ft_t_any);
-
- memcpy(tmp_label, label, FT_LABEL_SZ);
- tmp_label[FT_LABEL_SZ] = '\0';
- TRACE(ft_t_noise, "tape label = `%s'", tmp_label);
- ftape_fmt_version = 0;
- if (memcmp(label, linux_tape_label, strlen(linux_tape_label)) == 0) {
- int pos = strlen(linux_tape_label);
- while (label[pos] >= '0' && label[pos] <= '9') {
- ftape_fmt_version *= 10;
- ftape_fmt_version = label[ pos++] - '0';
- }
- result = (ftape_fmt_version >= min_fmt_version &&
- ftape_fmt_version <= max_fmt_version);
- }
- TRACE(ft_t_noise, "format version = %d", ftape_fmt_version);
- TRACE_EXIT result;
-}
-
-static __u8 * find_end_of_eof_list(__u8 * ptr, __u8 * limit)
-{
- while (ptr + 3 < limit) {
-
- if (get_unaligned((__u32*)ptr)) {
- ptr += sizeof(__u32);
- } else {
- return ptr;
- }
- }
- return NULL;
-}
-
-void zft_ftape_extract_file_marks(__u8* address)
-{
- int i;
- TRACE_FUN(ft_t_any);
-
- zft_eof_map = NULL;
- if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
- __u8* end;
- __u8* start = ftape_find_end_of_bsm_list(address);
-
- zft_nr_eof_marks = 0;
- if (start) {
- start += 3; /* skip end of list mark */
- end = find_end_of_eof_list(start,
- address + FT_SEGMENT_SIZE);
- if (end && end - start <= FT_FSL_SIZE) {
- zft_nr_eof_marks = ((end - start) /
- sizeof(eof_mark_union));
- zft_eof_map = (eof_mark_union *)start;
- } else {
- TRACE(ft_t_err,
- "EOF Mark List is too long or damaged!");
- }
- } else {
- TRACE(ft_t_err,
- "Bad Sector List is too long or damaged !");
- }
- } else {
- zft_eof_map = (eof_mark_union *)&address[FT_FSL];
- zft_nr_eof_marks = GET2(address, FT_FSL_CNT);
- }
- TRACE(ft_t_noise, "number of file marks: %d", zft_nr_eof_marks);
- if (ftape_fmt_version == 1) {
- TRACE(ft_t_info, "swapping version 1 fields");
- /* version 1 format uses swapped sector and segment
- * fields, correct that !
- */
- for (i = 0; i < zft_nr_eof_marks; ++i) {
- __u16 tmp = GET2(&zft_eof_map[i].mark.segment,0);
- PUT2(&zft_eof_map[i].mark.segment, 0,
- GET2(&zft_eof_map[i].mark.date,0));
- PUT2(&zft_eof_map[i].mark.date, 0, tmp);
- }
- }
- for (i = 0; i < zft_nr_eof_marks; ++i) {
- TRACE(ft_t_noise, "eof mark: %5d/%2d",
- GET2(&zft_eof_map[i].mark.segment, 0),
- GET2(&zft_eof_map[i].mark.date,0));
- }
- TRACE_EXIT;
-}
-
-void zft_clear_ftape_file_marks(void)
-{
- TRACE_FUN(ft_t_flow);
- /* Clear failed sector log: remove all tape marks. We
- * don't use old ftape-style EOF-marks.
- */
- TRACE(ft_t_info, "Clearing old ftape's eof map");
- memset(zft_eof_map, 0, zft_nr_eof_marks * sizeof(__u32));
- zft_nr_eof_marks = 0;
- PUT2(zft_hseg_buf, FT_FSL_CNT, 0); /* nr of eof-marks */
- zft_header_changed = 1;
- zft_update_label(zft_hseg_buf);
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-eof.h b/drivers/char/ftape/zftape/zftape-eof.h
deleted file mode 100644
index 26568c26c518..000000000000
--- a/drivers/char/ftape/zftape/zftape-eof.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _ZFTAPE_EOF_H
-#define _ZFTAPE_EOF_H
-
-/*
- * Copyright (C) 1994-1995 Bas Laarhoven.
- * adaptaed for zftape 1996, 1997 by Claus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-eof.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:03 $
- *
- * Definitions and declarations for the end of file markers
- * for the QIC-40/80 floppy-tape driver for Linux.
- */
-
-#include <linux/ftape-header-segment.h>
-#include "../zftape/zftape-buffers.h"
-/* failed sector log size (only used if format code != 4).
- */
-
-typedef union {
- ft_fsl_entry mark;
- __u32 entry;
-} eof_mark_union;
-
-/* ftape-eof.c defined global vars.
- */
-extern int zft_nr_eof_marks;
-extern eof_mark_union *zft_eof_map;
-
-/* ftape-eof.c defined global functions.
- */
-extern void zft_ftape_extract_file_marks(__u8* address);
-extern int zft_ftape_validate_label(char* label);
-extern void zft_clear_ftape_file_marks(void);
-
-#endif
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
deleted file mode 100644
index 164a1aa77a2f..000000000000
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * This file contains the code that registers the zftape frontend
- * to the ftape floppy tape driver for Linux
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-
-#include <linux/zftape.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-buffers.h"
-
-MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine "
- "(claus@momo.math.rwth-aachen.de)");
-MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
- "VFS interface for the Linux floppy tape driver. "
- "Support for QIC-113 compatible volume table "
- "and builtin compression (lzrw3 algorithm)");
-MODULE_SUPPORTED_DEVICE("char-major-27");
-MODULE_LICENSE("GPL");
-
-/* Global vars.
- */
-struct zft_cmpr_ops *zft_cmpr_ops = NULL;
-const ftape_info *zft_status;
-
-/* Local vars.
- */
-static unsigned long busy_flag;
-
-static sigset_t orig_sigmask;
-
-/* the interface to the kernel vfs layer
- */
-
-/* Note about llseek():
- *
- * st.c and tpqic.c update fp->f_pos but don't implment llseek() and
- * initialize the llseek component of the file_ops struct with NULL.
- * This means that the user will get the default seek, but the tape
- * device will not respect the new position, but happily read from the
- * old position. Think a zftape specific llseek() function would be
- * better, returning -ESPIPE. TODO.
- */
-
-static int zft_open (struct inode *ino, struct file *filep);
-static int zft_close(struct inode *ino, struct file *filep);
-static int zft_ioctl(struct inode *ino, struct file *filep,
- unsigned int command, unsigned long arg);
-static int zft_mmap(struct file *filep, struct vm_area_struct *vma);
-static ssize_t zft_read (struct file *fp, char __user *buff,
- size_t req_len, loff_t *ppos);
-static ssize_t zft_write(struct file *fp, const char __user *buff,
- size_t req_len, loff_t *ppos);
-
-static const struct file_operations zft_cdev =
-{
- .owner = THIS_MODULE,
- .read = zft_read,
- .write = zft_write,
- .ioctl = zft_ioctl,
- .mmap = zft_mmap,
- .open = zft_open,
- .release = zft_close,
-};
-
-static struct class *zft_class;
-
-/* Open floppy tape device
- */
-static int zft_open(struct inode *ino, struct file *filep)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- nonseekable_open(ino, filep);
- TRACE(ft_t_flow, "called for minor %d", iminor(ino));
- if ( test_and_set_bit(0,&busy_flag) ) {
- TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy");
- }
- if ((iminor(ino) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND))
- >
- FTAPE_SEL_D) {
- clear_bit(0,&busy_flag);
- TRACE_ABORT(-ENXIO, ft_t_err, "failed: invalid unit nr");
- }
- orig_sigmask = current->blocked;
- sigfillset(&current->blocked);
- result = _zft_open(iminor(ino), filep->f_flags & O_ACCMODE);
- if (result < 0) {
- current->blocked = orig_sigmask; /* restore mask */
- clear_bit(0,&busy_flag);
- TRACE_ABORT(result, ft_t_err, "_ftape_open failed");
- } else {
- /* Mask signals that will disturb proper operation of the
- * program that is calling.
- */
- current->blocked = orig_sigmask;
- sigaddsetmask (&current->blocked, _DO_BLOCK);
- TRACE_EXIT 0;
- }
-}
-
-/* Close floppy tape device
- */
-static int zft_close(struct inode *ino, struct file *filep)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit) {
- TRACE(ft_t_err, "failed: not busy or wrong unit");
- TRACE_EXIT 0;
- }
- sigfillset(&current->blocked);
- result = _zft_close();
- if (result < 0) {
- TRACE(ft_t_err, "_zft_close failed");
- }
- current->blocked = orig_sigmask; /* restore before open state */
- clear_bit(0,&busy_flag);
- TRACE_EXIT 0;
-}
-
-/* Ioctl for floppy tape device
- */
-static int zft_ioctl(struct inode *ino, struct file *filep,
- unsigned int command, unsigned long arg)
-{
- int result = -EIO;
- sigset_t old_sigmask;
- TRACE_FUN(ft_t_flow);
-
- if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) {
- TRACE_ABORT(-EIO, ft_t_err,
- "failed: not busy, failure or wrong unit");
- }
- old_sigmask = current->blocked; /* save mask */
- sigfillset(&current->blocked);
- /* This will work as long as sizeof(void *) == sizeof(long) */
- result = _zft_ioctl(command, (void __user *) arg);
- current->blocked = old_sigmask; /* restore mask */
- TRACE_EXIT result;
-}
-
-/* Ioctl for floppy tape device
- */
-static int zft_mmap(struct file *filep, struct vm_area_struct *vma)
-{
- int result = -EIO;
- sigset_t old_sigmask;
- TRACE_FUN(ft_t_flow);
-
- if ( !test_bit(0,&busy_flag) ||
- iminor(filep->f_dentry->d_inode) != zft_unit ||
- ft_failure)
- {
- TRACE_ABORT(-EIO, ft_t_err,
- "failed: not busy, failure or wrong unit");
- }
- old_sigmask = current->blocked; /* save mask */
- sigfillset(&current->blocked);
- if ((result = ftape_mmap(vma)) >= 0) {
-#ifndef MSYNC_BUG_WAS_FIXED
- static struct vm_operations_struct dummy = { NULL, };
- vma->vm_ops = &dummy;
-#endif
- }
- current->blocked = old_sigmask; /* restore mask */
- TRACE_EXIT result;
-}
-
-/* Read from floppy tape device
- */
-static ssize_t zft_read(struct file *fp, char __user *buff,
- size_t req_len, loff_t *ppos)
-{
- int result = -EIO;
- sigset_t old_sigmask;
- struct inode *ino = fp->f_dentry->d_inode;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len);
- if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) {
- TRACE_ABORT(-EIO, ft_t_err,
- "failed: not busy, failure or wrong unit");
- }
- old_sigmask = current->blocked; /* save mask */
- sigfillset(&current->blocked);
- result = _zft_read(buff, req_len);
- current->blocked = old_sigmask; /* restore mask */
- TRACE(ft_t_data_flow, "return with count: %d", result);
- TRACE_EXIT result;
-}
-
-/* Write to tape device
- */
-static ssize_t zft_write(struct file *fp, const char __user *buff,
- size_t req_len, loff_t *ppos)
-{
- int result = -EIO;
- sigset_t old_sigmask;
- struct inode *ino = fp->f_dentry->d_inode;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len);
- if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) {
- TRACE_ABORT(-EIO, ft_t_err,
- "failed: not busy, failure or wrong unit");
- }
- old_sigmask = current->blocked; /* save mask */
- sigfillset(&current->blocked);
- result = _zft_write(buff, req_len);
- current->blocked = old_sigmask; /* restore mask */
- TRACE(ft_t_data_flow, "return with count: %d", result);
- TRACE_EXIT result;
-}
-
-/* END OF VFS INTERFACE
- *
- *****************************************************************************/
-
-/* driver/module initialization
- */
-
-/* the compression module has to call this function to hook into the zftape
- * code
- */
-int zft_cmpr_register(struct zft_cmpr_ops *new_ops)
-{
- TRACE_FUN(ft_t_flow);
-
- if (zft_cmpr_ops != NULL) {
- TRACE_EXIT -EBUSY;
- } else {
- zft_cmpr_ops = new_ops;
- TRACE_EXIT 0;
- }
-}
-
-/* lock the zft-compressor() module.
- */
-int zft_cmpr_lock(int try_to_load)
-{
- if (zft_cmpr_ops == NULL) {
-#ifdef CONFIG_KMOD
- if (try_to_load) {
- request_module("zft-compressor");
- if (zft_cmpr_ops == NULL) {
- return -ENOSYS;
- }
- } else {
- return -ENOSYS;
- }
-#else
- return -ENOSYS;
-#endif
- }
- (*zft_cmpr_ops->lock)();
- return 0;
-}
-
-#ifdef CONFIG_ZFT_COMPRESSOR
-extern int zft_compressor_init(void);
-#endif
-
-/* Called by modules package when installing the driver or by kernel
- * during the initialization phase
- */
-int __init zft_init(void)
-{
- int i;
- TRACE_FUN(ft_t_flow);
-
-#ifdef MODULE
- printk(KERN_INFO ZFTAPE_VERSION "\n");
- if (TRACE_LEVEL >= ft_t_info) {
- printk(
-KERN_INFO
-"(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO
-"vfs interface for ftape floppy tape driver.\n"
-KERN_INFO
-"Support for QIC-113 compatible volume table, dynamic memory allocation\n"
-KERN_INFO
-"and builtin compression (lzrw3 algorithm).\n");
- }
-#else /* !MODULE */
- /* print a short no-nonsense boot message */
- printk(KERN_INFO ZFTAPE_VERSION "\n");
-#endif /* MODULE */
- TRACE(ft_t_info, "zft_init @ 0x%p", zft_init);
- TRACE(ft_t_info,
- "installing zftape VFS interface for ftape driver ...");
- TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
-
- zft_class = class_create(THIS_MODULE, "zft");
- for (i = 0; i < 4; i++) {
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
- class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
- }
-
-#ifdef CONFIG_ZFT_COMPRESSOR
- (void)zft_compressor_init();
-#endif
- zft_status = ftape_get_status(); /* fetch global data of ftape
- * hardware driver
- */
- TRACE_EXIT 0;
-}
-
-
-/* Called by modules package when removing the driver
- */
-static void zft_exit(void)
-{
- int i;
- TRACE_FUN(ft_t_flow);
-
- if (unregister_chrdev(QIC117_TAPE_MAJOR, "zft") != 0) {
- TRACE(ft_t_warn, "failed");
- } else {
- TRACE(ft_t_info, "successful");
- }
- for (i = 0; i < 4; i++) {
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
- class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
- }
- class_destroy(zft_class);
- zft_uninit_mem(); /* release remaining memory, if any */
- printk(KERN_INFO "zftape successfully unloaded.\n");
- TRACE_EXIT;
-}
-
-module_init(zft_init);
-module_exit(zft_exit);
diff --git a/drivers/char/ftape/zftape/zftape-init.h b/drivers/char/ftape/zftape/zftape-init.h
deleted file mode 100644
index 937e5d48c20e..000000000000
--- a/drivers/char/ftape/zftape/zftape-init.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef _ZFTAPE_INIT_H
-#define _ZFTAPE_INIT_H
-
-/*
- * Copyright (C) 1996, 1997 Claus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-init.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:05 $
- *
- * This file contains definitions and macro for the vfs
- * interface defined by zftape
- *
- */
-
-#include <linux/ftape-header-segment.h>
-
-#include "../lowlevel/ftape-tracing.h"
-#include "../lowlevel/ftape-ctl.h"
-#include "../lowlevel/ftape-read.h"
-#include "../lowlevel/ftape-write.h"
-#include "../lowlevel/ftape-bsm.h"
-#include "../lowlevel/ftape-io.h"
-#include "../lowlevel/ftape-buffer.h"
-#include "../lowlevel/ftape-format.h"
-
-#include "../zftape/zftape-rw.h"
-
-#ifdef MODULE
-#define ftape_status (*zft_status)
-#endif
-
-extern const ftape_info *zft_status; /* needed for zftape-vtbl.h */
-
-#include "../zftape/zftape-vtbl.h"
-
-struct zft_cmpr_ops {
- int (*write)(int *write_cnt,
- __u8 *dst_buf, const int seg_sz,
- const __u8 __user *src_buf, const int req_len,
- const zft_position *pos, const zft_volinfo *volume);
- int (*read)(int *read_cnt,
- __u8 __user *dst_buf, const int req_len,
- const __u8 *src_buf, const int seg_sz,
- const zft_position *pos, const zft_volinfo *volume);
- int (*seek)(unsigned int new_block_pos,
- zft_position *pos, const zft_volinfo *volume,
- __u8 *buffer);
- void (*lock) (void);
- void (*reset) (void);
- void (*cleanup)(void);
-};
-
-extern struct zft_cmpr_ops *zft_cmpr_ops;
-/* zftape-init.c defined global functions.
- */
-extern int zft_cmpr_register(struct zft_cmpr_ops *new_ops);
-extern int zft_cmpr_lock(int try_to_load);
-
-#endif
-
-
diff --git a/drivers/char/ftape/zftape/zftape-read.c b/drivers/char/ftape/zftape/zftape-read.c
deleted file mode 100644
index 214bf03dce68..000000000000
--- a/drivers/char/ftape/zftape/zftape-read.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:06 $
- *
- * This file contains the high level reading code
- * for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/* Global vars.
- */
-int zft_just_before_eof;
-
-/* Local vars.
- */
-static int buf_len_rd;
-
-void zft_zap_read_buffers(void)
-{
- buf_len_rd = 0;
-}
-
-int zft_read_header_segments(void)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_header_read = 0;
- TRACE_CATCH(zft_vmalloc_once(&zft_hseg_buf, FT_SEGMENT_SIZE),);
- TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),);
- TRACE(ft_t_info, "Segments written since first format: %d",
- (int)GET4(zft_hseg_buf, FT_SEG_CNT));
- zft_qic113 = (ft_format_code != fmt_normal &&
- ft_format_code != fmt_1100ft &&
- ft_format_code != fmt_425ft);
- TRACE(ft_t_info, "ft_first_data_segment: %d, ft_last_data_segment: %d",
- ft_first_data_segment, ft_last_data_segment);
- zft_capacity = zft_get_capacity();
- zft_old_ftape = zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]);
- if (zft_old_ftape) {
- TRACE(ft_t_info,
-"Found old ftaped tape, emulating eof marks, entering read-only mode");
- zft_ftape_extract_file_marks(zft_hseg_buf);
- TRACE_CATCH(zft_fake_volume_headers(zft_eof_map,
- zft_nr_eof_marks),);
- } else {
- /* the specs say that the volume table must be
- * initialized with zeroes during formatting, so it
- * MUST be readable, i.e. contain vaid ECC
- * information.
- */
- TRACE_CATCH(ftape_read_segment(ft_first_data_segment,
- zft_deblock_buf,
- FT_RD_SINGLE),);
- TRACE_CATCH(zft_extract_volume_headers(zft_deblock_buf),);
- }
- zft_header_read = 1;
- zft_set_flags(zft_unit);
- zft_reset_position(&zft_pos);
- TRACE_EXIT 0;
-}
-
-int zft_fetch_segment_fraction(const unsigned int segment, void *buffer,
- const ft_read_mode_t read_mode,
- const unsigned int start,
- const unsigned int size)
-{
- int seg_sz;
- TRACE_FUN(ft_t_flow);
-
- if (segment == zft_deblock_segment) {
- TRACE(ft_t_data_flow,
- "re-using segment %d already in deblock buffer",
- segment);
- seg_sz = zft_get_seg_sz(segment);
- if (start > seg_sz) {
- TRACE_ABORT(-EINVAL, ft_t_bug,
- "trying to read beyond end of segment:\n"
- KERN_INFO "seg_sz : %d\n"
- KERN_INFO "start : %d\n"
- KERN_INFO "segment: %d",
- seg_sz, start, segment);
- }
- if ((start + size) > seg_sz) {
- TRACE_EXIT seg_sz - start;
- }
- TRACE_EXIT size;
- }
- seg_sz = ftape_read_segment_fraction(segment, buffer, read_mode,
- start, size);
- TRACE(ft_t_data_flow, "segment %d, result %d", segment, seg_sz);
- if ((int)seg_sz >= 0 && start == 0 && size == FT_SEGMENT_SIZE) {
- /* this implicitly assumes that we are always called with
- * buffer == zft_deblock_buf
- */
- zft_deblock_segment = segment;
- } else {
- zft_deblock_segment = -1;
- }
- TRACE_EXIT seg_sz;
-}
-
-/*
- * out:
- *
- * int *read_cnt: the number of bytes we removed from the
- * zft_deblock_buf (result)
- *
- * int *to_do : the remaining size of the read-request. Is changed.
- *
- * in:
- *
- * char *buff : buff is the address of the upper part of the user
- * buffer, that hasn't been filled with data yet.
- * int buf_pos_read: copy of buf_pos_rd
- * int buf_len_read: copy of buf_len_rd
- * char *zft_deblock_buf: ftape_zft_deblock_buf
- *
- * returns the amount of data actually copied to the user-buffer
- *
- * to_do MUST NOT SHRINK except to indicate an EOT. In this case to_do
- * has to be set to 0. We cannot return -ENOSPC, because we return the
- * amount of data actually * copied to the user-buffer
- */
-static int zft_simple_read (int *read_cnt,
- __u8 __user *dst_buf,
- const int to_do,
- const __u8 *src_buf,
- const int seg_sz,
- const zft_position *pos,
- const zft_volinfo *volume)
-{
- TRACE_FUN(ft_t_flow);
-
- if (seg_sz - pos->seg_byte_pos < to_do) {
- *read_cnt = seg_sz - pos->seg_byte_pos;
- } else {
- *read_cnt = to_do;
- }
- if (copy_to_user(dst_buf,
- src_buf + pos->seg_byte_pos, *read_cnt) != 0) {
- TRACE_EXIT -EFAULT;
- }
- TRACE(ft_t_noise, "nr bytes just read: %d", *read_cnt);
- TRACE_EXIT *read_cnt;
-}
-
-/* req_len: gets clipped due to EOT of EOF.
- * req_clipped: is a flag indicating whether req_len was clipped or not
- * volume: contains information on current volume (blk_sz etc.)
- */
-static int check_read_access(int *req_len,
- const zft_volinfo **volume,
- int *req_clipped,
- const zft_position *pos)
-{
- static __s64 remaining;
- static int eod;
- TRACE_FUN(ft_t_flow);
-
- if (zft_io_state != zft_reading) {
- if (zft_offline) { /* offline includes no_tape */
- TRACE_ABORT(-ENXIO, ft_t_warn,
- "tape is offline or no cartridge");
- }
- if (!ft_formatted) {
- TRACE_ABORT(-EACCES,
- ft_t_warn, "tape is not formatted");
- }
- /* now enter defined state, read header segment if not
- * already done and flush write buffers
- */
- TRACE_CATCH(zft_def_idle_state(),);
- zft_io_state = zft_reading;
- if (zft_tape_at_eod(pos)) {
- eod = 1;
- TRACE_EXIT 1;
- }
- eod = 0;
- *volume = zft_find_volume(pos->seg_pos);
- /* get the space left until EOF */
- remaining = zft_check_for_eof(*volume, pos);
- buf_len_rd = 0;
- TRACE(ft_t_noise, "remaining: " LL_X ", vol_no: %d",
- LL(remaining), (*volume)->count);
- } else if (zft_tape_at_eod(pos)) {
- if (++eod > 2) {
- TRACE_EXIT -EIO; /* st.c also returns -EIO */
- } else {
- TRACE_EXIT 1;
- }
- }
- if ((*req_len % (*volume)->blk_sz) != 0) {
- /* this message is informational only. The user gets the
- * proper return value
- */
- TRACE_ABORT(-EINVAL, ft_t_info,
- "req_len %d not a multiple of block size %d",
- *req_len, (*volume)->blk_sz);
- }
- /* As GNU tar doesn't accept partial read counts when the
- * multiple volume flag is set, we make sure to return the
- * requested amount of data. Except, of course, at the end of
- * the tape or file mark.
- */
- remaining -= *req_len;
- if (remaining <= 0) {
- TRACE(ft_t_noise,
- "clipped request from %d to %d.",
- *req_len, (int)(*req_len + remaining));
- *req_len += remaining;
- *req_clipped = 1;
- } else {
- *req_clipped = 0;
- }
- TRACE_EXIT 0;
-}
-
-/* this_segs_size: the current segment's size.
- * buff: the USER-SPACE buffer provided by the calling function.
- * req_len: how much data should be read at most.
- * volume: contains information on current volume (blk_sz etc.)
- */
-static int empty_deblock_buf(__u8 __user *usr_buf, const int req_len,
- const __u8 *src_buf, const int seg_sz,
- zft_position *pos,
- const zft_volinfo *volume)
-{
- int cnt;
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_data_flow, "this_segs_size: %d", seg_sz);
- if (zft_use_compression && volume->use_compression) {
- TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
- TRACE_CATCH(result= (*zft_cmpr_ops->read)(&cnt,
- usr_buf, req_len,
- src_buf, seg_sz,
- pos, volume),);
- } else {
- TRACE_CATCH(result= zft_simple_read (&cnt,
- usr_buf, req_len,
- src_buf, seg_sz,
- pos, volume),);
- }
- pos->volume_pos += result;
- pos->tape_pos += cnt;
- pos->seg_byte_pos += cnt;
- buf_len_rd -= cnt; /* remaining bytes in buffer */
- TRACE(ft_t_data_flow, "buf_len_rd: %d, cnt: %d", buf_len_rd, cnt);
- if(pos->seg_byte_pos >= seg_sz) {
- pos->seg_pos++;
- pos->seg_byte_pos = 0;
- }
- TRACE(ft_t_data_flow, "bytes moved out of deblock-buffer: %d", cnt);
- TRACE_EXIT result;
-}
-
-
-/* note: we store the segment id of the segment that is inside the
- * deblock buffer. This spares a lot of ftape_read_segment()s when we
- * use small block-sizes. The block-size may be 1kb (SECTOR_SIZE). In
- * this case a MTFSR 28 maybe still inside the same segment.
- */
-int _zft_read(char __user *buff, int req_len)
-{
- int req_clipped;
- int result = 0;
- int bytes_read = 0;
- static unsigned int seg_sz = 0;
- static const zft_volinfo *volume = NULL;
- TRACE_FUN(ft_t_flow);
-
- zft_resid = req_len;
- result = check_read_access(&req_len, &volume,
- &req_clipped, &zft_pos);
- switch(result) {
- case 0:
- break; /* nothing special */
- case 1:
- TRACE(ft_t_noise, "EOD reached");
- TRACE_EXIT 0; /* EOD */
- default:
- TRACE_ABORT(result, ft_t_noise,
- "check_read_access() failed with result %d",
- result);
- TRACE_EXIT result;
- }
- while (req_len > 0) {
- /* Allow escape from this loop on signal !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- /* buf_len_rd == 0 means that we need to read a new
- * segment.
- */
- if (buf_len_rd == 0) {
- while((result = zft_fetch_segment(zft_pos.seg_pos,
- zft_deblock_buf,
- FT_RD_AHEAD)) == 0) {
- zft_pos.seg_pos ++;
- zft_pos.seg_byte_pos = 0;
- }
- if (result < 0) {
- zft_resid -= bytes_read;
- TRACE_ABORT(result, ft_t_noise,
- "zft_fetch_segment(): %d",
- result);
- }
- seg_sz = result;
- buf_len_rd = seg_sz - zft_pos.seg_byte_pos;
- }
- TRACE_CATCH(result = empty_deblock_buf(buff,
- req_len,
- zft_deblock_buf,
- seg_sz,
- &zft_pos,
- volume),
- zft_resid -= bytes_read);
- TRACE(ft_t_data_flow, "bytes just read: %d", result);
- bytes_read += result; /* what we got so far */
- buff += result; /* index in user-buffer */
- req_len -= result; /* what's left from req_len */
- } /* while (req_len > 0) */
- if (req_clipped) {
- TRACE(ft_t_data_flow,
- "maybe partial count because of eof mark");
- if (zft_just_before_eof && bytes_read == 0) {
- /* req_len was > 0, but user didn't get
- * anything the user has read in the eof-mark
- */
- zft_move_past_eof(&zft_pos);
- ftape_abort_operation();
- } else {
- /* don't skip to the next file before the user
- * tried to read a second time past EOF Just
- * mark that we are at EOF and maybe decrement
- * zft_seg_pos to stay in the same volume;
- */
- zft_just_before_eof = 1;
- zft_position_before_eof(&zft_pos, volume);
- TRACE(ft_t_noise, "just before eof");
- }
- }
- zft_resid -= result; /* for MTSTATUS */
- TRACE_EXIT bytes_read;
-}
diff --git a/drivers/char/ftape/zftape/zftape-read.h b/drivers/char/ftape/zftape/zftape-read.h
deleted file mode 100644
index 42941de0c23a..000000000000
--- a/drivers/char/ftape/zftape/zftape-read.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _ZFTAPE_READ_H
-#define _ZFTAPE_READ_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-read.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:07 $
- *
- * This file contains the definitions for the read functions
- * for the zftape driver for Linux.
- *
- */
-
-#include "../lowlevel/ftape-read.h"
-
-/* ftape-read.c defined global vars.
- */
-extern int zft_just_before_eof;
-
-/* ftape-read.c defined global functions.
- */
-extern void zft_zap_read_buffers(void);
-extern int zft_read_header_segments(void);
-extern int zft_fetch_segment_fraction(const unsigned int segment,
- void *buffer,
- const ft_read_mode_t read_mode,
- const unsigned int start,
- const unsigned int size);
-#define zft_fetch_segment(segment, address, read_mode) \
- zft_fetch_segment_fraction(segment, address, read_mode, \
- 0, FT_SEGMENT_SIZE)
-/* hook for the VFS interface
- */
-extern int _zft_read(char __user *buff, int req_len);
-
-#endif /* _ZFTAPE_READ_H */
diff --git a/drivers/char/ftape/zftape/zftape-rw.c b/drivers/char/ftape/zftape/zftape-rw.c
deleted file mode 100644
index dab634686885..000000000000
--- a/drivers/char/ftape/zftape/zftape-rw.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.c,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:08 $
- *
- * This file contains some common code for the r/w code for
- * zftape.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/* Global vars.
- */
-
-__u8 *zft_deblock_buf;
-__u8 *zft_hseg_buf;
-int zft_deblock_segment = -1;
-zft_status_enum zft_io_state = zft_idle;
-int zft_header_changed;
-int zft_qic113; /* conform to old specs. and old zftape */
-int zft_use_compression;
-zft_position zft_pos = {
- -1, /* seg_pos */
- 0, /* seg_byte_pos */
- 0, /* tape_pos */
- 0 /* volume_pos */
-};
-unsigned int zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ;
-__s64 zft_capacity;
-
-unsigned int zft_written_segments;
-int zft_label_changed;
-
-/* Local vars.
- */
-
-unsigned int zft_get_seg_sz(unsigned int segment)
-{
- int size;
- TRACE_FUN(ft_t_any);
-
- size = FT_SEGMENT_SIZE -
- count_ones(ftape_get_bad_sector_entry(segment))*FT_SECTOR_SIZE;
- if (size > 0) {
- TRACE_EXIT (unsigned)size;
- } else {
- TRACE_EXIT 0;
- }
-}
-
-/* ftape_set_flags(). Claus-Justus Heine, 1994/1995
- */
-void zft_set_flags(unsigned minor_unit)
-{
- TRACE_FUN(ft_t_flow);
-
- zft_use_compression = zft_qic_mode = 0;
- switch (minor_unit & ZFT_MINOR_OP_MASK) {
- case (ZFT_Q80_MODE | ZFT_ZIP_MODE):
- case ZFT_ZIP_MODE:
- zft_use_compression = 1;
- case 0:
- case ZFT_Q80_MODE:
- zft_qic_mode = 1;
- if (zft_mt_compression) { /* override the default */
- zft_use_compression = 1;
- }
- break;
- case ZFT_RAW_MODE:
- TRACE(ft_t_noise, "switching to raw mode");
- break;
- default:
- TRACE(ft_t_warn, "Warning:\n"
- KERN_INFO "Wrong combination of minor device bits.\n"
- KERN_INFO "Switching to raw read-only mode.");
- zft_write_protected = 1;
- break;
- }
- TRACE_EXIT;
-}
-
-/* computes the segment and byte offset inside the segment
- * corresponding to tape_pos.
- *
- * tape_pos gives the offset in bytes from the beginning of the
- * ft_first_data_segment *seg_byte_pos is the offset in the current
- * segment in bytes
- *
- * Of, if this routine was called often one should cache the last data
- * pos it was called with, but actually this is only needed in
- * ftape_seek_block(), that is, almost never.
- */
-int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos)
-{
- int segment;
- int seg_sz;
- TRACE_FUN(ft_t_flow);
-
- if (tape_pos == 0) {
- *seg_byte_pos = 0;
- segment = ft_first_data_segment;
- } else {
- seg_sz = 0;
-
- for (segment = ft_first_data_segment;
- ((tape_pos > 0) && (segment <= ft_last_data_segment));
- segment++) {
- seg_sz = zft_get_seg_sz(segment);
- tape_pos -= seg_sz;
- }
- if(tape_pos >= 0) {
- /* the case tape_pos > != 0 means that the
- * argument tape_pos lies beyond the EOT.
- */
- *seg_byte_pos= 0;
- } else { /* tape_pos < 0 */
- segment--;
- *seg_byte_pos= tape_pos + seg_sz;
- }
- }
- TRACE_EXIT(segment);
-}
-
-/* ftape_calc_tape_pos().
- *
- * computes the offset in bytes from the beginning of the
- * ft_first_data_segment inverse to ftape_calc_seg_byte_coord
- *
- * We should do some caching. But how:
- *
- * Each time the header segments are read in, this routine is called
- * with ft_tracks_per_tape*segments_per_track argumnet. So this should be
- * the time to reset the cache.
- *
- * Also, it might be in the future that the bad sector map gets
- * changed. -> reset the cache
- */
-static int seg_pos;
-static __s64 tape_pos;
-
-__s64 zft_get_capacity(void)
-{
- seg_pos = ft_first_data_segment;
- tape_pos = 0;
-
- while (seg_pos <= ft_last_data_segment) {
- tape_pos += zft_get_seg_sz(seg_pos ++);
- }
- return tape_pos;
-}
-
-__s64 zft_calc_tape_pos(int segment)
-{
- int d1, d2, d3;
- TRACE_FUN(ft_t_any);
-
- if (segment > ft_last_data_segment) {
- TRACE_EXIT zft_capacity;
- }
- if (segment < ft_first_data_segment) {
- TRACE_EXIT 0;
- }
- d2 = segment - seg_pos;
- if (-d2 > 10) {
- d1 = segment - ft_first_data_segment;
- if (-d2 > d1) {
- tape_pos = 0;
- seg_pos = ft_first_data_segment;
- d2 = d1;
- }
- }
- if (d2 > 10) {
- d3 = ft_last_data_segment - segment;
- if (d2 > d3) {
- tape_pos = zft_capacity;
- seg_pos = ft_last_data_segment + 1;
- d2 = -d3;
- }
- }
- if (d2 > 0) {
- while (seg_pos < segment) {
- tape_pos += zft_get_seg_sz(seg_pos++);
- }
- } else {
- while (seg_pos > segment) {
- tape_pos -= zft_get_seg_sz(--seg_pos);
- }
- }
- TRACE(ft_t_noise, "new cached pos: %d", seg_pos);
-
- TRACE_EXIT tape_pos;
-}
-
-/* copy Z-label string to buffer, keeps track of the correct offset in
- * `buffer'
- */
-void zft_update_label(__u8 *buffer)
-{
- TRACE_FUN(ft_t_flow);
-
- if (strncmp(&buffer[FT_LABEL], ZFTAPE_LABEL,
- sizeof(ZFTAPE_LABEL)-1) != 0) {
- TRACE(ft_t_info, "updating label from \"%s\" to \"%s\"",
- &buffer[FT_LABEL], ZFTAPE_LABEL);
- strcpy(&buffer[FT_LABEL], ZFTAPE_LABEL);
- memset(&buffer[FT_LABEL] + sizeof(ZFTAPE_LABEL) - 1, ' ',
- FT_LABEL_SZ - sizeof(ZFTAPE_LABEL + 1));
- PUT4(buffer, FT_LABEL_DATE, 0);
- zft_label_changed = zft_header_changed = 1; /* changed */
- }
- TRACE_EXIT;
-}
-
-int zft_verify_write_segments(unsigned int segment,
- __u8 *data, size_t size,
- __u8 *buffer)
-{
- int result;
- __u8 *write_buf;
- __u8 *src_buf;
- int single;
- int seg_pos;
- int seg_sz;
- int remaining;
- ft_write_mode_t write_mode;
- TRACE_FUN(ft_t_flow);
-
- seg_pos = segment;
- seg_sz = zft_get_seg_sz(seg_pos);
- src_buf = data;
- single = size <= seg_sz;
- remaining = size;
- do {
- TRACE(ft_t_noise, "\n"
- KERN_INFO "remaining: %d\n"
- KERN_INFO "seg_sz : %d\n"
- KERN_INFO "segment : %d",
- remaining, seg_sz, seg_pos);
- if (remaining == seg_sz) {
- write_buf = src_buf;
- write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI;
- remaining = 0;
- } else if (remaining > seg_sz) {
- write_buf = src_buf;
- write_mode = FT_WR_ASYNC; /* don't start tape */
- remaining -= seg_sz;
- } else { /* remaining < seg_sz */
- write_buf = buffer;
- memcpy(write_buf, src_buf, remaining);
- memset(&write_buf[remaining],'\0',seg_sz-remaining);
- write_mode = single ? FT_WR_SINGLE : FT_WR_MULTI;
- remaining = 0;
- }
- if ((result = ftape_write_segment(seg_pos,
- write_buf,
- write_mode)) != seg_sz) {
- TRACE(ft_t_err, "Error: "
- "Couldn't write segment %d", seg_pos);
- TRACE_EXIT result < 0 ? result : -EIO; /* bail out */
- }
- zft_written_segments ++;
- seg_sz = zft_get_seg_sz(++seg_pos);
- src_buf += result;
- } while (remaining > 0);
- if (ftape_get_status()->fti_state == writing) {
- TRACE_CATCH(ftape_loop_until_writes_done(),);
- TRACE_CATCH(ftape_abort_operation(),);
- zft_prevent_flush();
- }
- seg_pos = segment;
- src_buf = data;
- remaining = size;
- do {
- TRACE_CATCH(result = ftape_read_segment(seg_pos, buffer,
- single ? FT_RD_SINGLE
- : FT_RD_AHEAD),);
- if (memcmp(src_buf, buffer,
- remaining > result ? result : remaining) != 0) {
- TRACE_ABORT(-EIO, ft_t_err,
- "Failed to verify written segment %d",
- seg_pos);
- }
- remaining -= result;
- TRACE(ft_t_noise, "verify successful:\n"
- KERN_INFO "segment : %d\n"
- KERN_INFO "segsize : %d\n"
- KERN_INFO "remaining: %d",
- seg_pos, result, remaining);
- src_buf += seg_sz;
- seg_pos++;
- } while (remaining > 0);
- TRACE_EXIT size;
-}
-
-
-/* zft_erase(). implemented compression-handling
- *
- * calculate the first data-segment when using/not using compression.
- *
- * update header-segment and compression-map-segment.
- */
-int zft_erase(void)
-{
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- if (!zft_header_read) {
- TRACE_CATCH(zft_vmalloc_once((void **)&zft_hseg_buf,
- FT_SEGMENT_SIZE),);
- /* no need to read the vtbl and compression map */
- TRACE_CATCH(ftape_read_header_segment(zft_hseg_buf),);
- if ((zft_old_ftape =
- zft_ftape_validate_label(&zft_hseg_buf[FT_LABEL]))) {
- zft_ftape_extract_file_marks(zft_hseg_buf);
- }
- TRACE(ft_t_noise,
- "ft_first_data_segment: %d, ft_last_data_segment: %d",
- ft_first_data_segment, ft_last_data_segment);
- zft_qic113 = (ft_format_code != fmt_normal &&
- ft_format_code != fmt_1100ft &&
- ft_format_code != fmt_425ft);
- }
- if (zft_old_ftape) {
- zft_clear_ftape_file_marks();
- zft_old_ftape = 0; /* no longer old ftape */
- }
- PUT2(zft_hseg_buf, FT_CMAP_START, 0);
- zft_volume_table_changed = 1;
- zft_capacity = zft_get_capacity();
- zft_init_vtbl();
- /* the rest must be done in ftape_update_header_segments
- */
- zft_header_read = 1;
- zft_header_changed = 1; /* force update of timestamp */
- result = zft_update_header_segments();
-
- ftape_abort_operation();
-
- zft_reset_position(&zft_pos);
- zft_set_flags (zft_unit);
- TRACE_EXIT result;
-}
-
-unsigned int zft_get_time(void)
-{
- unsigned int date = FT_TIME_STAMP(2097, 11, 30, 23, 59, 59); /* fun */
- return date;
-}
diff --git a/drivers/char/ftape/zftape/zftape-rw.h b/drivers/char/ftape/zftape/zftape-rw.h
deleted file mode 100644
index 1ceec22b60bd..000000000000
--- a/drivers/char/ftape/zftape/zftape-rw.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef _ZFTAPE_RW_H
-#define _ZFTAPE_RW_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-rw.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:09 $
- *
- * This file contains the definitions for the read and write
- * functions for the QIC-117 floppy-tape driver for Linux.
- *
- */
-
-#include "../zftape/zftape-buffers.h"
-
-#define SEGMENTS_PER_TAPE (ft_segments_per_track * ft_tracks_per_tape)
-
-/* QIC-113 Rev. G says that `a maximum of 63488 raw bytes may be
- * compressed into a single frame'.
- * Maybe we should stick to 32kb to make it more `beautiful'
- */
-#define ZFT_MAX_BLK_SZ (62*1024) /* bytes */
-#if !defined(CONFIG_ZFT_DFLT_BLK_SZ)
-# define CONFIG_ZFT_DFLT_BLK_SZ (10*1024) /* bytes, default of gnu tar */
-#elif CONFIG_ZFT_DFLT_BLK_SZ == 0
-# undef CONFIG_ZFT_DFLT_BLK_SZ
-# define CONFIG_ZFT_DFLT_BLK_SZ 1
-#elif (CONFIG_ZFT_DFLT_BLK_SZ % 1024) != 0
-# error CONFIG_ZFT_DFLT_BLK_SZ must be 1 or a multiple of 1024
-#endif
-/* The *optional* compression routines need some overhead per tape
- * block for their purposes. Instead of asking the actual compression
- * implementation how much it needs, we restrict this overhead to be
- * maximal of ZFT_CMPT_OVERHEAD size. We need this for EOT
- * conditions. The tape is assumed to be logical at EOT when the
- * distance from the physical EOT is less than
- * one tape block + ZFT_CMPR_OVERHEAD
- */
-#define ZFT_CMPR_OVERHEAD 16 /* bytes */
-
-typedef enum
-{
- zft_idle = 0,
- zft_reading,
- zft_writing,
-} zft_status_enum;
-
-typedef struct /* all values measured in bytes */
-{
- int seg_pos; /* segment currently positioned at */
- int seg_byte_pos; /* offset in current segment */
- __s64 tape_pos; /* real offset from BOT */
- __s64 volume_pos; /* pos. in uncompressed data stream in
- * current volume
- */
-} zft_position;
-
-extern zft_position zft_pos;
-extern __u8 *zft_deblock_buf;
-extern __u8 *zft_hseg_buf;
-extern int zft_deblock_segment;
-extern zft_status_enum zft_io_state;
-extern int zft_header_changed;
-extern int zft_qic113; /* conform to old specs. and old zftape */
-extern int zft_use_compression;
-extern unsigned int zft_blk_sz;
-extern __s64 zft_capacity;
-extern unsigned int zft_written_segments;
-extern int zft_label_changed;
-
-/* zftape-rw.c exported functions
- */
-extern unsigned int zft_get_seg_sz(unsigned int segment);
-extern void zft_set_flags(unsigned int minor_unit);
-extern int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos);
-extern __s64 zft_calc_tape_pos(int segment);
-extern __s64 zft_get_capacity(void);
-extern void zft_update_label(__u8 *buffer);
-extern int zft_erase(void);
-extern int zft_verify_write_segments(unsigned int segment,
- __u8 *data, size_t size, __u8 *buffer);
-extern unsigned int zft_get_time(void);
-#endif /* _ZFTAPE_RW_H */
-
diff --git a/drivers/char/ftape/zftape/zftape-vtbl.c b/drivers/char/ftape/zftape/zftape-vtbl.c
deleted file mode 100644
index ad7f8be6340b..000000000000
--- a/drivers/char/ftape/zftape/zftape-vtbl.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * Copyright (c) 1995-1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.c,v $
- * $Revision: 1.7.6.1 $
- * $Date: 1997/11/24 13:48:31 $
- *
- * This file defines a volume table as defined in various QIC
- * standards.
- *
- * This is a minimal implementation, just allowing ordinary DOS
- * :( prgrams to identify the cartridge as used.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include <linux/zftape.h>
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-#define ZFT_CMAP_HACK /* leave this defined to hide the compression map */
-
-/*
- * global variables
- */
-int zft_qic_mode = 1; /* use the vtbl */
-int zft_old_ftape; /* prevents old ftaped tapes to be overwritten */
-int zft_volume_table_changed; /* for write_header_segments() */
-
-/*
- * private variables (only exported for inline functions)
- */
-LIST_HEAD(zft_vtbl);
-
-/* We could also allocate these dynamically when extracting the volume table
- * sizeof(zft_volinfo) is about 32 or something close to that
- */
-static zft_volinfo tape_vtbl;
-static zft_volinfo eot_vtbl;
-static zft_volinfo *cur_vtbl;
-
-static inline void zft_new_vtbl_entry(void)
-{
- struct list_head *tmp = &zft_last_vtbl->node;
- zft_volinfo *new = zft_kmalloc(sizeof(zft_volinfo));
-
- list_add(&new->node, tmp);
- new->count = zft_eom_vtbl->count ++;
-}
-
-void zft_free_vtbl(void)
-{
- for (;;) {
- struct list_head *tmp = zft_vtbl.prev;
- zft_volinfo *vtbl;
-
- if (tmp == &zft_vtbl)
- break;
- list_del(tmp);
- vtbl = list_entry(tmp, zft_volinfo, node);
- zft_kfree(vtbl, sizeof(zft_volinfo));
- }
- INIT_LIST_HEAD(&zft_vtbl);
- cur_vtbl = NULL;
-}
-
-/* initialize vtbl, called by ftape_new_cartridge()
- */
-void zft_init_vtbl(void)
-{
- zft_volinfo *new;
-
- zft_free_vtbl();
-
- /* Create the two dummy vtbl entries
- */
- new = zft_kmalloc(sizeof(zft_volinfo));
- list_add(&new->node, &zft_vtbl);
- new = zft_kmalloc(sizeof(zft_volinfo));
- list_add(&new->node, &zft_vtbl);
- zft_head_vtbl->end_seg = ft_first_data_segment;
- zft_head_vtbl->blk_sz = zft_blk_sz;
- zft_head_vtbl->count = -1;
- zft_eom_vtbl->start_seg = ft_first_data_segment + 1;
- zft_eom_vtbl->end_seg = ft_last_data_segment + 1;
- zft_eom_vtbl->blk_sz = zft_blk_sz;
- zft_eom_vtbl->count = 0;
-
- /* Reset the pointer for zft_find_volume()
- */
- cur_vtbl = zft_eom_vtbl;
-
- /* initialize the dummy vtbl entries for zft_qic_mode == 0
- */
- eot_vtbl.start_seg = ft_last_data_segment + 1;
- eot_vtbl.end_seg = ft_last_data_segment + 1;
- eot_vtbl.blk_sz = zft_blk_sz;
- eot_vtbl.count = -1;
- tape_vtbl.start_seg = ft_first_data_segment;
- tape_vtbl.end_seg = ft_last_data_segment;
- tape_vtbl.blk_sz = zft_blk_sz;
- tape_vtbl.size = zft_capacity;
- tape_vtbl.count = 0;
-}
-
-/* check for a valid VTBL signature.
- */
-static int vtbl_signature_valid(__u8 signature[4])
-{
- const char *vtbl_ids[] = VTBL_IDS; /* valid signatures */
- int j;
-
- for (j = 0;
- (j < NR_ITEMS(vtbl_ids)) && (memcmp(signature, vtbl_ids[j], 4) != 0);
- j++);
- return j < NR_ITEMS(vtbl_ids);
-}
-
-/* We used to store the block-size of the volume in the volume-label,
- * using the keyword "blocksize". The blocksize written to the
- * volume-label is in bytes.
- *
- * We use this now only for compatibility with old zftape version. We
- * store the blocksize directly as binary number in the vendor
- * extension part of the volume entry.
- */
-static int check_volume_label(const char *label, int *blk_sz)
-{
- int valid_format;
- char *blocksize;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "called with \"%s\" / \"%s\"", label, ZFT_VOL_NAME);
- if (strncmp(label, ZFT_VOL_NAME, strlen(ZFT_VOL_NAME)) != 0) {
- *blk_sz = 1; /* smallest block size that we allow */
- valid_format = 0;
- } else {
- TRACE(ft_t_noise, "got old style zftape vtbl entry");
- /* get the default blocksize */
- /* use the kernel strstr() */
- blocksize= strstr(label, " blocksize ");
- if (blocksize) {
- blocksize += strlen(" blocksize ");
- for(*blk_sz= 0;
- *blocksize >= '0' && *blocksize <= '9';
- blocksize++) {
- *blk_sz *= 10;
- *blk_sz += *blocksize - '0';
- }
- if (*blk_sz > ZFT_MAX_BLK_SZ) {
- *blk_sz= 1;
- valid_format= 0;
- } else {
- valid_format = 1;
- }
- } else {
- *blk_sz= 1;
- valid_format= 0;
- }
- }
- TRACE_EXIT valid_format;
-}
-
-/* check for a zftape volume
- */
-static int check_volume(__u8 *entry, zft_volinfo *volume)
-{
- TRACE_FUN(ft_t_flow);
-
- if(strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
- strlen(ZFTAPE_SIG)) == 0) {
- TRACE(ft_t_noise, "got new style zftape vtbl entry");
- volume->blk_sz = GET2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ);
- volume->qic113 = entry[VTBL_EXT+EXT_ZFTAPE_QIC113];
- TRACE_EXIT 1;
- } else {
- TRACE_EXIT check_volume_label(&entry[VTBL_DESC], &volume->blk_sz);
- }
-}
-
-
-/* create zftape specific vtbl entry, the volume bounds are inserted
- * in the calling function, zft_create_volume_headers()
- */
-static void create_zft_volume(__u8 *entry, zft_volinfo *vtbl)
-{
- TRACE_FUN(ft_t_flow);
-
- memset(entry, 0, VTBL_SIZE);
- memcpy(&entry[VTBL_SIG], VTBL_ID, 4);
- sprintf(&entry[VTBL_DESC], ZFT_VOL_NAME" %03d", vtbl->count);
- entry[VTBL_FLAGS] = (VTBL_FL_NOT_VERIFIED | VTBL_FL_SEG_SPANNING);
- entry[VTBL_M_NO] = 1; /* multi_cartridge_count */
- strcpy(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG);
- PUT2(entry, VTBL_EXT+EXT_ZFTAPE_BLKSZ, vtbl->blk_sz);
- if (zft_qic113) {
- PUT8(entry, VTBL_DATA_SIZE, vtbl->size);
- entry[VTBL_CMPR] = VTBL_CMPR_UNREG;
- if (vtbl->use_compression) { /* use compression: */
- entry[VTBL_CMPR] |= VTBL_CMPR_USED;
- }
- entry[VTBL_EXT+EXT_ZFTAPE_QIC113] = 1;
- } else {
- PUT4(entry, VTBL_DATA_SIZE, vtbl->size);
- entry[VTBL_K_CMPR] = VTBL_CMPR_UNREG;
- if (vtbl->use_compression) { /* use compression: */
- entry[VTBL_K_CMPR] |= VTBL_CMPR_USED;
- }
- }
- if (ft_format_code == fmt_big) {
- /* SCSI like vtbl, store the number of used
- * segments as 4 byte value
- */
- PUT4(entry, VTBL_SCSI_SEGS, vtbl->end_seg-vtbl->start_seg + 1);
- } else {
- /* normal, QIC-80MC like vtbl
- */
- PUT2(entry, VTBL_START, vtbl->start_seg);
- PUT2(entry, VTBL_END, vtbl->end_seg);
- }
- TRACE_EXIT;
-}
-
-/* this one creates the volume headers for each volume. It is assumed
- * that buffer already contains the old volume-table, so that vtbl
- * entries without the zft_volume flag set can savely be ignored.
- */
-static void zft_create_volume_headers(__u8 *buffer)
-{
- __u8 *entry;
- struct list_head *tmp;
- zft_volinfo *vtbl;
- TRACE_FUN(ft_t_flow);
-
-#ifdef ZFT_CMAP_HACK
- if((strncmp(&buffer[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
- strlen(ZFTAPE_SIG)) == 0) &&
- buffer[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) {
- TRACE(ft_t_noise, "deleting cmap volume");
- memmove(buffer, buffer + VTBL_SIZE,
- FT_SEGMENT_SIZE - VTBL_SIZE);
- }
-#endif
- entry = buffer;
- for (tmp = zft_head_vtbl->node.next;
- tmp != &zft_eom_vtbl->node;
- tmp = tmp->next) {
- vtbl = list_entry(tmp, zft_volinfo, node);
- /* we now fill in the values only for newly created volumes.
- */
- if (vtbl->new_volume) {
- create_zft_volume(entry, vtbl);
- vtbl->new_volume = 0; /* clear the flag */
- }
-
- DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], vtbl);
- entry += VTBL_SIZE;
- }
- memset(entry, 0, FT_SEGMENT_SIZE - zft_eom_vtbl->count * VTBL_SIZE);
- TRACE_EXIT;
-}
-
-/* write volume table to tape. Calls zft_create_volume_headers()
- */
-int zft_update_volume_table(unsigned int segment)
-{
- int result = 0;
- __u8 *verify_buf = NULL;
- TRACE_FUN(ft_t_flow);
-
- TRACE_CATCH(result = ftape_read_segment(ft_first_data_segment,
- zft_deblock_buf,
- FT_RD_SINGLE),);
- zft_create_volume_headers(zft_deblock_buf);
- TRACE(ft_t_noise, "writing volume table segment %d", segment);
- if (zft_vmalloc_once(&verify_buf, FT_SEGMENT_SIZE) == 0) {
- TRACE_CATCH(zft_verify_write_segments(segment,
- zft_deblock_buf, result,
- verify_buf),
- zft_vfree(&verify_buf, FT_SEGMENT_SIZE));
- zft_vfree(&verify_buf, FT_SEGMENT_SIZE);
- } else {
- TRACE_CATCH(ftape_write_segment(segment, zft_deblock_buf,
- FT_WR_SINGLE),);
- }
- TRACE_EXIT 0;
-}
-
-/* non zftape volumes are handled in raw mode. Thus we need to
- * calculate the raw amount of data contained in those segments.
- */
-static void extract_alien_volume(__u8 *entry, zft_volinfo *vtbl)
-{
- TRACE_FUN(ft_t_flow);
-
- vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1) -
- zft_calc_tape_pos(zft_last_vtbl->start_seg));
- vtbl->use_compression = 0;
- vtbl->qic113 = zft_qic113;
- if (vtbl->qic113) {
- TRACE(ft_t_noise,
- "Fake alien volume's size from " LL_X " to " LL_X,
- LL(GET8(entry, VTBL_DATA_SIZE)), LL(vtbl->size));
- } else {
- TRACE(ft_t_noise,
- "Fake alien volume's size from %d to " LL_X,
- (int)GET4(entry, VTBL_DATA_SIZE), LL(vtbl->size));
- }
- TRACE_EXIT;
-}
-
-
-/* extract an zftape specific volume
- */
-static void extract_zft_volume(__u8 *entry, zft_volinfo *vtbl)
-{
- TRACE_FUN(ft_t_flow);
-
- if (vtbl->qic113) {
- vtbl->size = GET8(entry, VTBL_DATA_SIZE);
- vtbl->use_compression =
- (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0;
- } else {
- vtbl->size = GET4(entry, VTBL_DATA_SIZE);
- if (entry[VTBL_K_CMPR] & VTBL_CMPR_UNREG) {
- vtbl->use_compression =
- (entry[VTBL_K_CMPR] & VTBL_CMPR_USED) != 0;
- } else if (entry[VTBL_CMPR] & VTBL_CMPR_UNREG) {
- vtbl->use_compression =
- (entry[VTBL_CMPR] & VTBL_CMPR_USED) != 0;
- } else {
- TRACE(ft_t_warn, "Geeh! There is something wrong:\n"
- KERN_INFO "QIC compression (Rev = K): %x\n"
- KERN_INFO "QIC compression (Rev > K): %x",
- entry[VTBL_K_CMPR], entry[VTBL_CMPR]);
- }
- }
- TRACE_EXIT;
-}
-
-/* extract the volume table from buffer. "buffer" must already contain
- * the vtbl-segment
- */
-int zft_extract_volume_headers(__u8 *buffer)
-{
- __u8 *entry;
- TRACE_FUN(ft_t_flow);
-
- zft_init_vtbl();
- entry = buffer;
-#ifdef ZFT_CMAP_HACK
- if ((strncmp(&entry[VTBL_EXT+EXT_ZFTAPE_SIG], ZFTAPE_SIG,
- strlen(ZFTAPE_SIG)) == 0) &&
- entry[VTBL_EXT+EXT_ZFTAPE_CMAP] != 0) {
- TRACE(ft_t_noise, "ignoring cmap volume");
- entry += VTBL_SIZE;
- }
-#endif
- /* the end of the vtbl is indicated by an invalid signature
- */
- while (vtbl_signature_valid(&entry[VTBL_SIG]) &&
- (entry - buffer) < FT_SEGMENT_SIZE) {
- zft_new_vtbl_entry();
- if (ft_format_code == fmt_big) {
- /* SCSI like vtbl, stores only the number of
- * segments used
- */
- unsigned int num_segments= GET4(entry, VTBL_SCSI_SEGS);
- zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
- zft_last_vtbl->end_seg =
- zft_last_vtbl->start_seg + num_segments - 1;
- } else {
- /* `normal', QIC-80 like vtbl
- */
- zft_last_vtbl->start_seg = GET2(entry, VTBL_START);
- zft_last_vtbl->end_seg = GET2(entry, VTBL_END);
- }
- zft_eom_vtbl->start_seg = zft_last_vtbl->end_seg + 1;
- /* check if we created this volume and get the
- * blk_sz
- */
- zft_last_vtbl->zft_volume = check_volume(entry, zft_last_vtbl);
- if (zft_last_vtbl->zft_volume == 0) {
- extract_alien_volume(entry, zft_last_vtbl);
- } else {
- extract_zft_volume(entry, zft_last_vtbl);
- }
- DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], zft_last_vtbl);
- entry +=VTBL_SIZE;
- }
-#if 0
-/*
- * undefine to test end of tape handling
- */
- zft_new_vtbl_entry();
- zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
- zft_last_vtbl->end_seg = ft_last_data_segment - 10;
- zft_last_vtbl->blk_sz = zft_blk_sz;
- zft_last_vtbl->zft_volume = 1;
- zft_last_vtbl->qic113 = zft_qic113;
- zft_last_vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1)
- - zft_calc_tape_pos(zft_last_vtbl->start_seg));
-#endif
- TRACE_EXIT 0;
-}
-
-/* this functions translates the failed_sector_log, misused as
- * EOF-marker list, into a virtual volume table. The table mustn't be
- * written to tape, because this would occupy the first data segment,
- * which should be the volume table, but is actually the first segment
- * that is filled with data (when using standard ftape). We assume,
- * that we get a non-empty failed_sector_log.
- */
-int zft_fake_volume_headers (eof_mark_union *eof_map, int num_failed_sectors)
-{
- unsigned int segment, sector;
- int have_eom = 0;
- int vol_no;
- TRACE_FUN(ft_t_flow);
-
- if ((num_failed_sectors >= 2) &&
- (GET2(&eof_map[num_failed_sectors - 1].mark.segment, 0)
- ==
- GET2(&eof_map[num_failed_sectors - 2].mark.segment, 0) + 1) &&
- (GET2(&eof_map[num_failed_sectors - 1].mark.date, 0) == 1)) {
- /* this should be eom. We keep the remainder of the
- * tape as another volume.
- */
- have_eom = 1;
- }
- zft_init_vtbl();
- zft_eom_vtbl->start_seg = ft_first_data_segment;
- for(vol_no = 0; vol_no < num_failed_sectors - have_eom; vol_no ++) {
- zft_new_vtbl_entry();
-
- segment = GET2(&eof_map[vol_no].mark.segment, 0);
- sector = GET2(&eof_map[vol_no].mark.date, 0);
-
- zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
- zft_last_vtbl->end_seg = segment;
- zft_eom_vtbl->start_seg = segment + 1;
- zft_last_vtbl->blk_sz = 1;
- zft_last_vtbl->size =
- (zft_calc_tape_pos(zft_last_vtbl->end_seg)
- - zft_calc_tape_pos(zft_last_vtbl->start_seg)
- + (sector-1) * FT_SECTOR_SIZE);
- TRACE(ft_t_noise,
- "failed sector log: segment: %d, sector: %d",
- segment, sector);
- DUMP_VOLINFO(ft_t_noise, "Faked volume", zft_last_vtbl);
- }
- if (!have_eom) {
- zft_new_vtbl_entry();
- zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;
- zft_last_vtbl->end_seg = ft_last_data_segment;
- zft_eom_vtbl->start_seg = ft_last_data_segment + 1;
- zft_last_vtbl->size = zft_capacity;
- zft_last_vtbl->size -= zft_calc_tape_pos(zft_last_vtbl->start_seg);
- zft_last_vtbl->blk_sz = 1;
- DUMP_VOLINFO(ft_t_noise, "Faked volume",zft_last_vtbl);
- }
- TRACE_EXIT 0;
-}
-
-/* update the internal volume table
- *
- * if before start of last volume: erase all following volumes if
- * inside a volume: set end of volume to infinity
- *
- * this function is intended to be called every time _ftape_write() is
- * called
- *
- * return: 0 if no new volume was created, 1 if a new volume was
- * created
- *
- * NOTE: we don't need to check for zft_mode as ftape_write() does
- * that already. This function gets never called without accessing
- * zftape via the *qft* devices
- */
-
-int zft_open_volume(zft_position *pos, int blk_sz, int use_compression)
-{
- TRACE_FUN(ft_t_flow);
-
- if (!zft_qic_mode) {
- TRACE_EXIT 0;
- }
- if (zft_tape_at_lbot(pos)) {
- zft_init_vtbl();
- if(zft_old_ftape) {
- /* clear old ftape's eof marks */
- zft_clear_ftape_file_marks();
- zft_old_ftape = 0; /* no longer old ftape */
- }
- zft_reset_position(pos);
- }
- if (pos->seg_pos != zft_last_vtbl->end_seg + 1) {
- TRACE_ABORT(-EIO, ft_t_bug,
- "BUG: seg_pos: %d, zft_last_vtbl->end_seg: %d",
- pos->seg_pos, zft_last_vtbl->end_seg);
- }
- TRACE(ft_t_noise, "create new volume");
- if (zft_eom_vtbl->count >= ZFT_MAX_VOLUMES) {
- TRACE_ABORT(-ENOSPC, ft_t_err,
- "Error: maxmimal number of volumes exhausted "
- "(maxmimum is %d)", ZFT_MAX_VOLUMES);
- }
- zft_new_vtbl_entry();
- pos->volume_pos = pos->seg_byte_pos = 0;
- zft_last_vtbl->start_seg = pos->seg_pos;
- zft_last_vtbl->end_seg = ft_last_data_segment; /* infinity */
- zft_last_vtbl->blk_sz = blk_sz;
- zft_last_vtbl->size = zft_capacity;
- zft_last_vtbl->zft_volume = 1;
- zft_last_vtbl->use_compression = use_compression;
- zft_last_vtbl->qic113 = zft_qic113;
- zft_last_vtbl->new_volume = 1;
- zft_last_vtbl->open = 1;
- zft_volume_table_changed = 1;
- zft_eom_vtbl->start_seg = ft_last_data_segment + 1;
- TRACE_EXIT 0;
-}
-
-/* perform mtfsf, mtbsf, not allowed without zft_qic_mode
- */
-int zft_skip_volumes(int count, zft_position *pos)
-{
- const zft_volinfo *vtbl;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "count: %d", count);
-
- vtbl= zft_find_volume(pos->seg_pos);
- while (count > 0 && vtbl != zft_eom_vtbl) {
- vtbl = list_entry(vtbl->node.next, zft_volinfo, node);
- count --;
- }
- while (count < 0 && vtbl != zft_first_vtbl) {
- vtbl = list_entry(vtbl->node.prev, zft_volinfo, node);
- count ++;
- }
- pos->seg_pos = vtbl->start_seg;
- pos->seg_byte_pos = 0;
- pos->volume_pos = 0;
- pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
- zft_just_before_eof = vtbl->size == 0;
- if (zft_cmpr_ops) {
- (*zft_cmpr_ops->reset)();
- }
- zft_deblock_segment = -1; /* no need to keep cache */
- TRACE(ft_t_noise, "repositioning to:\n"
- KERN_INFO "zft_seg_pos : %d\n"
- KERN_INFO "zft_seg_byte_pos : %d\n"
- KERN_INFO "zft_tape_pos : " LL_X "\n"
- KERN_INFO "zft_volume_pos : " LL_X "\n"
- KERN_INFO "file number : %d",
- pos->seg_pos, pos->seg_byte_pos,
- LL(pos->tape_pos), LL(pos->volume_pos), vtbl->count);
- zft_resid = count < 0 ? -count : count;
- TRACE_EXIT zft_resid ? -EINVAL : 0;
-}
-
-/* the following simply returns the raw data position of the EOM
- * marker, MTIOCSIZE ioctl
- */
-__s64 zft_get_eom_pos(void)
-{
- if (zft_qic_mode) {
- return zft_calc_tape_pos(zft_eom_vtbl->start_seg);
- } else {
- /* there is only one volume in raw mode */
- return zft_capacity;
- }
-}
-
-/* skip to eom, used for MTEOM
- */
-void zft_skip_to_eom(zft_position *pos)
-{
- TRACE_FUN(ft_t_flow);
- pos->seg_pos = zft_eom_vtbl->start_seg;
- pos->seg_byte_pos =
- pos->volume_pos =
- zft_just_before_eof = 0;
- pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);
- TRACE(ft_t_noise, "ftape positioned to segment %d, data pos " LL_X,
- pos->seg_pos, LL(pos->tape_pos));
- TRACE_EXIT;
-}
-
-/* write an EOF-marker by setting zft_last_vtbl->end_seg to seg_pos.
- * NOTE: this function assumes that zft_last_vtbl points to a valid
- * vtbl entry
- *
- * NOTE: this routine always positions before the EOF marker
- */
-int zft_close_volume(zft_position *pos)
-{
- TRACE_FUN(ft_t_any);
-
- if (zft_vtbl_empty || !zft_last_vtbl->open) { /* should not happen */
- TRACE(ft_t_noise, "There are no volumes to finish");
- TRACE_EXIT -EIO;
- }
- if (pos->seg_byte_pos == 0 &&
- pos->seg_pos != zft_last_vtbl->start_seg) {
- pos->seg_pos --;
- pos->seg_byte_pos = zft_get_seg_sz(pos->seg_pos);
- }
- zft_last_vtbl->end_seg = pos->seg_pos;
- zft_last_vtbl->size = pos->volume_pos;
- zft_volume_table_changed = 1;
- zft_just_before_eof = 1;
- zft_eom_vtbl->start_seg = zft_last_vtbl->end_seg + 1;
- zft_last_vtbl->open = 0; /* closed */
- TRACE_EXIT 0;
-}
-
-/* write count file-marks at current position.
- *
- * The tape is positioned after the eof-marker, that is at byte 0 of
- * the segment following the eof-marker
- *
- * this function is only allowed in zft_qic_mode
- *
- * Only allowed when tape is at BOT or EOD.
- */
-int zft_weof(unsigned int count, zft_position *pos)
-{
-
- TRACE_FUN(ft_t_flow);
-
- if (!count) { /* write zero EOF marks should be a real no-op */
- TRACE_EXIT 0;
- }
- zft_volume_table_changed = 1;
- if (zft_tape_at_lbot(pos)) {
- zft_init_vtbl();
- if(zft_old_ftape) {
- /* clear old ftape's eof marks */
- zft_clear_ftape_file_marks();
- zft_old_ftape = 0; /* no longer old ftape */
- }
- }
- if (zft_last_vtbl->open) {
- zft_close_volume(pos);
- zft_move_past_eof(pos);
- count --;
- }
- /* now it's easy, just append eof-marks, that is empty
- * volumes, to the end of the already recorded media.
- */
- while (count > 0 &&
- pos->seg_pos <= ft_last_data_segment &&
- zft_eom_vtbl->count < ZFT_MAX_VOLUMES) {
- TRACE(ft_t_noise,
- "Writing zero sized file at segment %d", pos->seg_pos);
- zft_new_vtbl_entry();
- zft_last_vtbl->start_seg = pos->seg_pos;
- zft_last_vtbl->end_seg = pos->seg_pos;
- zft_last_vtbl->size = 0;
- zft_last_vtbl->blk_sz = zft_blk_sz;
- zft_last_vtbl->zft_volume = 1;
- zft_last_vtbl->use_compression = 0;
- pos->tape_pos += zft_get_seg_sz(pos->seg_pos);
- zft_eom_vtbl->start_seg = ++ pos->seg_pos;
- count --;
- }
- if (count > 0) {
- /* there are two possibilities: end of tape, or the
- * maximum number of files is exhausted.
- */
- zft_resid = count;
- TRACE(ft_t_noise,"Number of marks NOT written: %d", zft_resid);
- if (zft_eom_vtbl->count == ZFT_MAX_VOLUMES) {
- TRACE_ABORT(-EINVAL, ft_t_warn,
- "maximum allowed number of files "
- "exhausted: %d", ZFT_MAX_VOLUMES);
- } else {
- TRACE_ABORT(-ENOSPC,
- ft_t_noise, "reached end of tape");
- }
- }
- TRACE_EXIT 0;
-}
-
-const zft_volinfo *zft_find_volume(unsigned int seg_pos)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_any, "called with seg_pos %d",seg_pos);
- if (!zft_qic_mode) {
- if (seg_pos > ft_last_data_segment) {
- TRACE_EXIT &eot_vtbl;
- }
- tape_vtbl.blk_sz = zft_blk_sz;
- TRACE_EXIT &tape_vtbl;
- }
- if (seg_pos < zft_first_vtbl->start_seg) {
- TRACE_EXIT (cur_vtbl = zft_first_vtbl);
- }
- while (seg_pos > cur_vtbl->end_seg) {
- cur_vtbl = list_entry(cur_vtbl->node.next, zft_volinfo, node);
- TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);
- }
- while (seg_pos < cur_vtbl->start_seg) {
- cur_vtbl = list_entry(cur_vtbl->node.prev, zft_volinfo, node);
- TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);
- }
- if (seg_pos > cur_vtbl->end_seg || seg_pos < cur_vtbl->start_seg) {
- TRACE(ft_t_bug, "This cannot happen");
- }
- DUMP_VOLINFO(ft_t_noise, "", cur_vtbl);
- TRACE_EXIT cur_vtbl;
-}
-
-/* this function really assumes that we are just before eof
- */
-void zft_move_past_eof(zft_position *pos)
-{
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_noise, "old seg. pos: %d", pos->seg_pos);
- pos->tape_pos += zft_get_seg_sz(pos->seg_pos++) - pos->seg_byte_pos;
- pos->seg_byte_pos = 0;
- pos->volume_pos = 0;
- if (zft_cmpr_ops) {
- (*zft_cmpr_ops->reset)();
- }
- zft_just_before_eof = 0;
- zft_deblock_segment = -1; /* no need to cache it anymore */
- TRACE(ft_t_noise, "new seg. pos: %d", pos->seg_pos);
- TRACE_EXIT;
-}
diff --git a/drivers/char/ftape/zftape/zftape-vtbl.h b/drivers/char/ftape/zftape/zftape-vtbl.h
deleted file mode 100644
index f31d196d1759..000000000000
--- a/drivers/char/ftape/zftape/zftape-vtbl.h
+++ /dev/null
@@ -1,227 +0,0 @@
-#ifndef _ZFTAPE_VTBL_H
-#define _ZFTAPE_VTBL_H
-
-/*
- * Copyright (c) 1995-1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
- USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-vtbl.h,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/28 14:30:09 $
- *
- * This file defines a volume table as defined in the QIC-80
- * development standards.
- */
-
-#include <linux/list.h>
-
-#include "../lowlevel/ftape-tracing.h"
-
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-rw.h"
-
-#define VTBL_SIZE 128 /* bytes */
-
-/* The following are offsets in the vtbl. */
-#define VTBL_SIG 0
-#define VTBL_START 4
-#define VTBL_END 6
-#define VTBL_DESC 8
-#define VTBL_DATE 52
-#define VTBL_FLAGS 56
-#define VTBL_FL_VENDOR_SPECIFIC (1<<0)
-#define VTBL_FL_MUTLI_CARTRIDGE (1<<1)
-#define VTBL_FL_NOT_VERIFIED (1<<2)
-#define VTBL_FL_REDIR_INHIBIT (1<<3)
-#define VTBL_FL_SEG_SPANNING (1<<4)
-#define VTBL_FL_DIRECTORY_LAST (1<<5)
-#define VTBL_FL_RESERVED_6 (1<<6)
-#define VTBL_FL_RESERVED_7 (1<<7)
-#define VTBL_M_NO 57
-#define VTBL_EXT 58
-#define EXT_ZFTAPE_SIG 0
-#define EXT_ZFTAPE_BLKSZ 10
-#define EXT_ZFTAPE_CMAP 12
-#define EXT_ZFTAPE_QIC113 13
-#define VTBL_PWD 84
-#define VTBL_DIR_SIZE 92
-#define VTBL_DATA_SIZE 96
-#define VTBL_OS_VERSION 104
-#define VTBL_SRC_DRIVE 106
-#define VTBL_DEV 122
-#define VTBL_RESERVED_1 123
-#define VTBL_CMPR 124
-#define VTBL_CMPR_UNREG 0x3f
-#define VTBL_CMPR_USED 0x80
-#define VTBL_FMT 125
-#define VTBL_RESERVED_2 126
-#define VTBL_RESERVED_3 127
-/* compatibility with pre revision K */
-#define VTBL_K_CMPR 120
-
-/* the next is used by QIC-3020 tapes with format code 6 (>2^16
- * segments) It is specified in QIC-113, Rev. G, Section 5 (SCSI
- * volume table). The difference is simply, that we only store the
- * number of segments used, not the starting segment.
- */
-#define VTBL_SCSI_SEGS 4 /* is a 4 byte value */
-
-/* one vtbl is 128 bytes, that results in a maximum number of
- * 29*1024/128 = 232 volumes.
- */
-#define ZFT_MAX_VOLUMES (FT_SEGMENT_SIZE/VTBL_SIZE)
-#define VTBL_ID "VTBL"
-#define VTBL_IDS { VTBL_ID, "XTBL", "UTID", "EXVT" } /* other valid ids */
-#define ZFT_VOL_NAME "zftape volume" /* volume label used by me */
-#define ZFTAPE_SIG "LINUX ZFT"
-
-/* global variables
- */
-typedef struct zft_internal_vtbl
-{
- struct list_head node;
- int count;
- unsigned int start_seg; /* 32 bits are enough for now */
- unsigned int end_seg; /* 32 bits are enough for now */
- __s64 size; /* uncompressed size */
- unsigned int blk_sz; /* block size for this volume */
- unsigned int zft_volume :1; /* zftape created this volume */
- unsigned int use_compression:1; /* compressed volume */
- unsigned int qic113 :1; /* layout of compressed block
- * info and vtbl conforms to
- * QIC-113, Rev. G
- */
- unsigned int new_volume :1; /* it was created by us, this
- * run. this allows the
- * fields that aren't really
- * used by zftape to be filled
- * in by some user level
- * program.
- */
- unsigned int open :1; /* just in progress of being
- * written
- */
-} zft_volinfo;
-
-extern struct list_head zft_vtbl;
-#define zft_head_vtbl list_entry(zft_vtbl.next, zft_volinfo, node)
-#define zft_eom_vtbl list_entry(zft_vtbl.prev, zft_volinfo, node)
-#define zft_last_vtbl list_entry(zft_eom_vtbl->node.prev, zft_volinfo, node)
-#define zft_first_vtbl list_entry(zft_head_vtbl->node.next, zft_volinfo, node)
-#define zft_vtbl_empty (zft_eom_vtbl->node.prev == &zft_head_vtbl->node)
-
-#define DUMP_VOLINFO(level, desc, info) \
-{ \
- char tmp[21]; \
- strlcpy(tmp, desc, sizeof(tmp)); \
- TRACE(level, "Volume %d:\n" \
- KERN_INFO "description : %s\n" \
- KERN_INFO "first segment: %d\n" \
- KERN_INFO "last segment: %d\n" \
- KERN_INFO "size : " LL_X "\n" \
- KERN_INFO "block size : %d\n" \
- KERN_INFO "compression : %d\n" \
- KERN_INFO "zftape volume: %d\n" \
- KERN_INFO "QIC-113 conf.: %d", \
- (info)->count, tmp, (info)->start_seg, (info)->end_seg, \
- LL((info)->size), (info)->blk_sz, \
- (info)->use_compression != 0, (info)->zft_volume != 0, \
- (info)->qic113 != 0); \
-}
-
-extern int zft_qic_mode;
-extern int zft_old_ftape;
-extern int zft_volume_table_changed;
-
-/* exported functions */
-extern void zft_init_vtbl (void);
-extern void zft_free_vtbl (void);
-extern int zft_extract_volume_headers(__u8 *buffer);
-extern int zft_update_volume_table (unsigned int segment);
-extern int zft_open_volume (zft_position *pos,
- int blk_sz, int use_compression);
-extern int zft_close_volume (zft_position *pos);
-extern const zft_volinfo *zft_find_volume(unsigned int seg_pos);
-extern int zft_skip_volumes (int count, zft_position *pos);
-extern __s64 zft_get_eom_pos (void);
-extern void zft_skip_to_eom (zft_position *pos);
-extern int zft_fake_volume_headers (eof_mark_union *eof_map,
- int num_failed_sectors);
-extern int zft_weof (unsigned int count, zft_position *pos);
-extern void zft_move_past_eof (zft_position *pos);
-
-static inline int zft_tape_at_eod (const zft_position *pos);
-static inline int zft_tape_at_lbot (const zft_position *pos);
-static inline void zft_position_before_eof (zft_position *pos,
- const zft_volinfo *volume);
-static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
- const zft_position *pos);
-
-/* this function decrements the zft_seg_pos counter if we are right
- * at the beginning of a segment. This is to handle fsfm/bsfm -- we
- * need to position before the eof mark. NOTE: zft_tape_pos is not
- * changed
- */
-static inline void zft_position_before_eof(zft_position *pos,
- const zft_volinfo *volume)
-{
- TRACE_FUN(ft_t_flow);
-
- if (pos->seg_pos == volume->end_seg + 1 && pos->seg_byte_pos == 0) {
- pos->seg_pos --;
- pos->seg_byte_pos = zft_get_seg_sz(pos->seg_pos);
- }
- TRACE_EXIT;
-}
-
-/* Mmmh. Is the position at the end of the last volume, that is right
- * before the last EOF mark also logical an EOD condition?
- */
-static inline int zft_tape_at_eod(const zft_position *pos)
-{
- TRACE_FUN(ft_t_any);
-
- if (zft_qic_mode) {
- TRACE_EXIT (pos->seg_pos >= zft_eom_vtbl->start_seg ||
- zft_last_vtbl->open);
- } else {
- TRACE_EXIT pos->seg_pos > ft_last_data_segment;
- }
-}
-
-static inline int zft_tape_at_lbot(const zft_position *pos)
-{
- if (zft_qic_mode) {
- return (pos->seg_pos <= zft_first_vtbl->start_seg &&
- pos->volume_pos == 0);
- } else {
- return (pos->seg_pos <= ft_first_data_segment &&
- pos->volume_pos == 0);
- }
-}
-
-/* This one checks for EOF. return remaing space (may be negative)
- */
-static inline __s64 zft_check_for_eof(const zft_volinfo *vtbl,
- const zft_position *pos)
-{
- return (__s64)(vtbl->size - pos->volume_pos);
-}
-
-#endif /* _ZFTAPE_VTBL_H */
diff --git a/drivers/char/ftape/zftape/zftape-write.c b/drivers/char/ftape/zftape/zftape-write.c
deleted file mode 100644
index 94327b8c97b9..000000000000
--- a/drivers/char/ftape/zftape/zftape-write.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 Claus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/11/06 00:50:29 $
- *
- * This file contains the writing code
- * for the QIC-117 floppy-tape driver for Linux.
- */
-
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <linux/zftape.h>
-
-#include <asm/uaccess.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-eof.h"
-#include "../zftape/zftape-ctl.h"
-#include "../zftape/zftape-write.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-rw.h"
-#include "../zftape/zftape-vtbl.h"
-
-/* Global vars.
- */
-
-/* Local vars.
- */
-static int last_write_failed;
-static int need_flush;
-
-void zft_prevent_flush(void)
-{
- need_flush = 0;
-}
-
-static int zft_write_header_segments(__u8* buffer)
-{
- int header_1_ok = 0;
- int header_2_ok = 0;
- unsigned int time_stamp;
- TRACE_FUN(ft_t_noise);
-
- TRACE_CATCH(ftape_abort_operation(),);
- ftape_seek_to_bot(); /* prevents extra rewind */
- if (GET4(buffer, 0) != FT_HSEG_MAGIC) {
- TRACE_ABORT(-EIO, ft_t_err,
- "wrong header signature found, aborting");
- }
- /* Be optimistic: */
- PUT4(buffer, FT_SEG_CNT,
- zft_written_segments + GET4(buffer, FT_SEG_CNT) + 2);
- if ((time_stamp = zft_get_time()) != 0) {
- PUT4(buffer, FT_WR_DATE, time_stamp);
- if (zft_label_changed) {
- PUT4(buffer, FT_LABEL_DATE, time_stamp);
- }
- }
- TRACE(ft_t_noise,
- "writing first header segment %d", ft_header_segment_1);
- header_1_ok = zft_verify_write_segments(ft_header_segment_1,
- buffer, FT_SEGMENT_SIZE,
- zft_deblock_buf) >= 0;
- TRACE(ft_t_noise,
- "writing second header segment %d", ft_header_segment_2);
- header_2_ok = zft_verify_write_segments(ft_header_segment_2,
- buffer, FT_SEGMENT_SIZE,
- zft_deblock_buf) >= 0;
- if (!header_1_ok) {
- TRACE(ft_t_warn, "Warning: "
- "update of first header segment failed");
- }
- if (!header_2_ok) {
- TRACE(ft_t_warn, "Warning: "
- "update of second header segment failed");
- }
- if (!header_1_ok && !header_2_ok) {
- TRACE_ABORT(-EIO, ft_t_err, "Error: "
- "update of both header segments failed.");
- }
- TRACE_EXIT 0;
-}
-
-int zft_update_header_segments(void)
-{
- TRACE_FUN(ft_t_noise);
-
- /* must NOT use zft_write_protected, as it also includes the
- * file access mode. But we also want to update when soft
- * write protection is enabled (O_RDONLY)
- */
- if (ft_write_protected || zft_old_ftape) {
- TRACE_ABORT(0, ft_t_noise, "Tape set read-only: no update");
- }
- if (!zft_header_read) {
- TRACE_ABORT(0, ft_t_noise, "Nothing to update");
- }
- if (!zft_header_changed) {
- zft_header_changed = zft_written_segments > 0;
- }
- if (!zft_header_changed && !zft_volume_table_changed) {
- TRACE_ABORT(0, ft_t_noise, "Nothing to update");
- }
- TRACE(ft_t_noise, "Updating header segments");
- if (ftape_get_status()->fti_state == writing) {
- TRACE_CATCH(ftape_loop_until_writes_done(),);
- }
- TRACE_CATCH(ftape_abort_operation(),);
-
- zft_deblock_segment = -1; /* invalidate the cache */
- if (zft_header_changed) {
- TRACE_CATCH(zft_write_header_segments(zft_hseg_buf),);
- }
- if (zft_volume_table_changed) {
- TRACE_CATCH(zft_update_volume_table(ft_first_data_segment),);
- }
- zft_header_changed =
- zft_volume_table_changed =
- zft_label_changed =
- zft_written_segments = 0;
- TRACE_CATCH(ftape_abort_operation(),);
- ftape_seek_to_bot();
- TRACE_EXIT 0;
-}
-
-static int read_merge_buffer(int seg_pos, __u8 *buffer, int offset, int seg_sz)
-{
- int result = 0;
- const ft_trace_t old_tracing = TRACE_LEVEL;
- TRACE_FUN(ft_t_flow);
-
- if (zft_qic_mode) {
- /* writing in the middle of a volume is NOT allowed
- *
- */
- TRACE(ft_t_noise, "No need to read a segment");
- memset(buffer + offset, 0, seg_sz - offset);
- TRACE_EXIT 0;
- }
- TRACE(ft_t_any, "waiting");
- ftape_start_writing(FT_WR_MULTI);
- TRACE_CATCH(ftape_loop_until_writes_done(),);
-
- TRACE(ft_t_noise, "trying to read segment %d from offset %d",
- seg_pos, offset);
- SET_TRACE_LEVEL(ft_t_bug);
- result = zft_fetch_segment_fraction(seg_pos, buffer,
- FT_RD_SINGLE,
- offset, seg_sz - offset);
- SET_TRACE_LEVEL(old_tracing);
- if (result != (seg_sz - offset)) {
- TRACE(ft_t_noise, "Ignore error: read_segment() result: %d",
- result);
- memset(buffer + offset, 0, seg_sz - offset);
- }
- TRACE_EXIT 0;
-}
-
-/* flush the write buffer to tape and write an eof-marker at the
- * current position if not in raw mode. This function always
- * positions the tape before the eof-marker. _ftape_close() should
- * then advance to the next segment.
- *
- * the parameter "finish_volume" describes whether to position before
- * or after the possibly created file-mark. We always position after
- * the file-mark when called from ftape_close() and a flush was needed
- * (that is ftape_write() was the last tape operation before calling
- * ftape_flush) But we always position before the file-mark when this
- * function get's called from outside ftape_close()
- */
-int zft_flush_buffers(void)
-{
- int result;
- int data_remaining;
- int this_segs_size;
- TRACE_FUN(ft_t_flow);
-
- TRACE(ft_t_data_flow,
- "entered, ftape_state = %d", ftape_get_status()->fti_state);
- if (ftape_get_status()->fti_state != writing && !need_flush) {
- TRACE_ABORT(0, ft_t_noise, "no need for flush");
- }
- zft_io_state = zft_idle; /* triggers some initializations for the
- * read and write routines
- */
- if (last_write_failed) {
- ftape_abort_operation();
- TRACE_EXIT -EIO;
- }
- TRACE(ft_t_noise, "flushing write buffers");
- this_segs_size = zft_get_seg_sz(zft_pos.seg_pos);
- if (this_segs_size == zft_pos.seg_byte_pos) {
- zft_pos.seg_pos ++;
- data_remaining = zft_pos.seg_byte_pos = 0;
- } else {
- data_remaining = zft_pos.seg_byte_pos;
- }
- /* If there is any data not written to tape yet, append zero's
- * up to the end of the sector (if using compression) or merge
- * it with the data existing on the tape Then write the
- * segment(s) to tape.
- */
- TRACE(ft_t_noise, "Position:\n"
- KERN_INFO "seg_pos : %d\n"
- KERN_INFO "byte pos : %d\n"
- KERN_INFO "remaining: %d",
- zft_pos.seg_pos, zft_pos.seg_byte_pos, data_remaining);
- if (data_remaining > 0) {
- do {
- this_segs_size = zft_get_seg_sz(zft_pos.seg_pos);
- if (this_segs_size > data_remaining) {
- TRACE_CATCH(read_merge_buffer(zft_pos.seg_pos,
- zft_deblock_buf,
- data_remaining,
- this_segs_size),
- last_write_failed = 1);
- }
- result = ftape_write_segment(zft_pos.seg_pos,
- zft_deblock_buf,
- FT_WR_MULTI);
- if (result != this_segs_size) {
- TRACE(ft_t_err, "flush buffers failed");
- zft_pos.tape_pos -= zft_pos.seg_byte_pos;
- zft_pos.seg_byte_pos = 0;
-
- last_write_failed = 1;
- TRACE_EXIT result;
- }
- zft_written_segments ++;
- TRACE(ft_t_data_flow,
- "flush, moved out buffer: %d", result);
- /* need next segment for more data (empty segments?)
- */
- if (result < data_remaining) {
- if (result > 0) {
- /* move remainder to buffer beginning
- */
- memmove(zft_deblock_buf,
- zft_deblock_buf + result,
- FT_SEGMENT_SIZE - result);
- }
- }
- data_remaining -= result;
- zft_pos.seg_pos ++;
- } while (data_remaining > 0);
- TRACE(ft_t_any, "result: %d", result);
- zft_deblock_segment = --zft_pos.seg_pos;
- if (data_remaining == 0) { /* first byte next segment */
- zft_pos.seg_byte_pos = this_segs_size;
- } else { /* after data previous segment, data_remaining < 0 */
- zft_pos.seg_byte_pos = data_remaining + result;
- }
- } else {
- TRACE(ft_t_noise, "zft_deblock_buf empty");
- zft_pos.seg_pos --;
- zft_pos.seg_byte_pos = zft_get_seg_sz (zft_pos.seg_pos);
- ftape_start_writing(FT_WR_MULTI);
- }
- TRACE(ft_t_any, "waiting");
- if ((result = ftape_loop_until_writes_done()) < 0) {
- /* that's really bad. What to to with zft_tape_pos?
- */
- TRACE(ft_t_err, "flush buffers failed");
- }
- TRACE(ft_t_any, "zft_seg_pos: %d, zft_seg_byte_pos: %d",
- zft_pos.seg_pos, zft_pos.seg_byte_pos);
- last_write_failed =
- need_flush = 0;
- TRACE_EXIT result;
-}
-
-/* return-value: the number of bytes removed from the user-buffer
- *
- * out:
- * int *write_cnt: how much actually has been moved to the
- * zft_deblock_buf
- * int req_len : MUST NOT BE CHANGED, except at EOT, in
- * which case it may be adjusted
- * in :
- * char *buff : the user buffer
- * int buf_pos_write : copy of buf_len_wr int
- * this_segs_size : the size in bytes of the actual segment
- * char
- * *zft_deblock_buf : zft_deblock_buf
- */
-static int zft_simple_write(int *cnt,
- __u8 *dst_buf, const int seg_sz,
- const __u8 __user *src_buf, const int req_len,
- const zft_position *pos,const zft_volinfo *volume)
-{
- int space_left;
- TRACE_FUN(ft_t_flow);
-
- /* volume->size holds the tape capacity while volume is open */
- if (pos->tape_pos + volume->blk_sz > volume->size) {
- TRACE_EXIT -ENOSPC;
- }
- /* remaining space in this segment, NOT zft_deblock_buf
- */
- space_left = seg_sz - pos->seg_byte_pos;
- *cnt = req_len < space_left ? req_len : space_left;
- if (copy_from_user(dst_buf + pos->seg_byte_pos, src_buf, *cnt) != 0) {
- TRACE_EXIT -EFAULT;
- }
- TRACE_EXIT *cnt;
-}
-
-static int check_write_access(int req_len,
- const zft_volinfo **volume,
- zft_position *pos,
- const unsigned int blk_sz)
-{
- int result;
- TRACE_FUN(ft_t_flow);
-
- if ((req_len % zft_blk_sz) != 0) {
- TRACE_ABORT(-EINVAL, ft_t_info,
- "write-count %d must be multiple of block-size %d",
- req_len, blk_sz);
- }
- if (zft_io_state == zft_writing) {
- /* all other error conditions have been checked earlier
- */
- TRACE_EXIT 0;
- }
- zft_io_state = zft_idle;
- TRACE_CATCH(zft_check_write_access(pos),);
- /* If we haven't read the header segment yet, do it now.
- * This will verify the configuration, get the bad sector
- * table and read the volume table segment
- */
- if (!zft_header_read) {
- TRACE_CATCH(zft_read_header_segments(),);
- }
- /* fine. Now the tape is either at BOT or at EOD,
- * Write start of volume now
- */
- TRACE_CATCH(zft_open_volume(pos, blk_sz, zft_use_compression),);
- *volume = zft_find_volume(pos->seg_pos);
- DUMP_VOLINFO(ft_t_noise, "", *volume);
- zft_just_before_eof = 0;
- /* now merge with old data if necessary */
- if (!zft_qic_mode && pos->seg_byte_pos != 0){
- result = zft_fetch_segment(pos->seg_pos,
- zft_deblock_buf,
- FT_RD_SINGLE);
- if (result < 0) {
- if (result == -EINTR || result == -ENOSPC) {
- TRACE_EXIT result;
- }
- TRACE(ft_t_noise,
- "ftape_read_segment() result: %d. "
- "This might be normal when using "
- "a newly\nformatted tape", result);
- memset(zft_deblock_buf, '\0', pos->seg_byte_pos);
- }
- }
- zft_io_state = zft_writing;
- TRACE_EXIT 0;
-}
-
-static int fill_deblock_buf(__u8 *dst_buf, const int seg_sz,
- zft_position *pos, const zft_volinfo *volume,
- const char __user *usr_buf, const int req_len)
-{
- int cnt = 0;
- int result = 0;
- TRACE_FUN(ft_t_flow);
-
- if (seg_sz == 0) {
- TRACE_ABORT(0, ft_t_data_flow, "empty segment");
- }
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "remaining req_len: %d\n"
- KERN_INFO " buf_pos: %d",
- req_len, pos->seg_byte_pos);
- /* zft_deblock_buf will not contain a valid segment any longer */
- zft_deblock_segment = -1;
- if (zft_use_compression) {
- TRACE_CATCH(zft_cmpr_lock(1 /* try to load */),);
- TRACE_CATCH(result= (*zft_cmpr_ops->write)(&cnt,
- dst_buf, seg_sz,
- usr_buf, req_len,
- pos, volume),);
- } else {
- TRACE_CATCH(result= zft_simple_write(&cnt,
- dst_buf, seg_sz,
- usr_buf, req_len,
- pos, volume),);
- }
- pos->volume_pos += result;
- pos->seg_byte_pos += cnt;
- pos->tape_pos += cnt;
- TRACE(ft_t_data_flow, "\n"
- KERN_INFO "removed from user-buffer : %d bytes.\n"
- KERN_INFO "copied to zft_deblock_buf: %d bytes.\n"
- KERN_INFO "zft_tape_pos : " LL_X " bytes.",
- result, cnt, LL(pos->tape_pos));
- TRACE_EXIT result;
-}
-
-
-/* called by the kernel-interface routine "zft_write()"
- */
-int _zft_write(const char __user *buff, int req_len)
-{
- int result = 0;
- int written = 0;
- int write_cnt;
- int seg_sz;
- static const zft_volinfo *volume = NULL;
- TRACE_FUN(ft_t_flow);
-
- zft_resid = req_len;
- last_write_failed = 1; /* reset to 0 when successful */
- /* check if write is allowed
- */
- TRACE_CATCH(check_write_access(req_len, &volume,&zft_pos,zft_blk_sz),);
- while (req_len > 0) {
- /* Allow us to escape from this loop with a signal !
- */
- FT_SIGNAL_EXIT(_DONT_BLOCK);
- seg_sz = zft_get_seg_sz(zft_pos.seg_pos);
- if ((write_cnt = fill_deblock_buf(zft_deblock_buf,
- seg_sz,
- &zft_pos,
- volume,
- buff,
- req_len)) < 0) {
- zft_resid -= written;
- if (write_cnt == -ENOSPC) {
- /* leave the remainder to flush_buffers()
- */
- TRACE(ft_t_info, "No space left on device");
- last_write_failed = 0;
- if (!need_flush) {
- need_flush = written > 0;
- }
- TRACE_EXIT written > 0 ? written : -ENOSPC;
- } else {
- TRACE_EXIT result;
- }
- }
- if (zft_pos.seg_byte_pos == seg_sz) {
- TRACE_CATCH(ftape_write_segment(zft_pos.seg_pos,
- zft_deblock_buf,
- FT_WR_ASYNC),
- zft_resid -= written);
- zft_written_segments ++;
- zft_pos.seg_byte_pos = 0;
- zft_deblock_segment = zft_pos.seg_pos;
- ++zft_pos.seg_pos;
- }
- written += write_cnt;
- buff += write_cnt;
- req_len -= write_cnt;
- } /* while (req_len > 0) */
- TRACE(ft_t_data_flow, "remaining in blocking buffer: %d",
- zft_pos.seg_byte_pos);
- TRACE(ft_t_data_flow, "just written bytes: %d", written);
- last_write_failed = 0;
- zft_resid -= written;
- need_flush = need_flush || written > 0;
- TRACE_EXIT written; /* bytes written */
-}
diff --git a/drivers/char/ftape/zftape/zftape-write.h b/drivers/char/ftape/zftape/zftape-write.h
deleted file mode 100644
index ea887015b493..000000000000
--- a/drivers/char/ftape/zftape/zftape-write.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _ZFTAPE_WRITE_H
-#define _ZFTAPE_WRITE_H
-
-/*
- * Copyright (C) 1996, 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-write.h,v $
- * $Revision: 1.2 $
- * $Date: 1997/10/05 19:19:13 $
- *
- * This file contains the definitions for the write functions
- * for the zftape driver for Linux.
- *
- */
-
-extern int zft_flush_buffers(void);
-extern int zft_update_header_segments(void);
-extern void zft_prevent_flush(void);
-
-/* hook for the VFS interface
- */
-extern int _zft_write(const char __user *buff, int req_len);
-#endif /* _ZFTAPE_WRITE_H */
diff --git a/drivers/char/ftape/zftape/zftape_syms.c b/drivers/char/ftape/zftape/zftape_syms.c
deleted file mode 100644
index 2db1401682df..000000000000
--- a/drivers/char/ftape/zftape/zftape_syms.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 1997 Claus-Justus Heine
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- *
- * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape_syms.c,v $
- * $Revision: 1.3 $
- * $Date: 1997/10/05 19:19:14 $
- *
- * This file contains the symbols that the zftape frontend to
- * the ftape floppy tape driver exports
- */
-
-#include <linux/module.h>
-
-#include <linux/zftape.h>
-
-#include "../zftape/zftape-init.h"
-#include "../zftape/zftape-read.h"
-#include "../zftape/zftape-buffers.h"
-#include "../zftape/zftape-ctl.h"
-
-/* zftape-init.c */
-EXPORT_SYMBOL(zft_cmpr_register);
-/* zftape-read.c */
-EXPORT_SYMBOL(zft_fetch_segment_fraction);
-/* zftape-buffers.c */
-EXPORT_SYMBOL(zft_vmalloc_once);
-EXPORT_SYMBOL(zft_vmalloc_always);
-EXPORT_SYMBOL(zft_vfree);
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 817dc409ac20..23b25ada65ea 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -102,7 +102,7 @@ static void gen_rtc_interrupt(unsigned long arg);
* Routine to poll RTC seconds field for change as often as possible,
* after first RTC_UIE use timer to reduce polling
*/
-static void genrtc_troutine(void *data)
+static void genrtc_troutine(struct work_struct *work)
{
unsigned int tmp = get_rtc_ss();
@@ -255,7 +255,7 @@ static inline int gen_set_rtc_irq_bit(unsigned char bit)
irq_active = 1;
stop_rtc_timers = 0;
lostint = 0;
- INIT_WORK(&genrtc_task, genrtc_troutine, NULL);
+ INIT_WORK(&genrtc_task, genrtc_troutine);
oldsecs = get_rtc_ss();
init_timer(&timer_task);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 091a11cd878c..20dc3be5ecfc 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -21,6 +21,7 @@
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
+#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/sysctl.h>
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 2cf63e7305a3..82a41d5b4ed0 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -69,7 +69,7 @@
#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
struct hvsi_struct {
- struct work_struct writer;
+ struct delayed_work writer;
struct work_struct handshaker;
wait_queue_head_t emptyq; /* woken when outbuf is emptied */
wait_queue_head_t stateq; /* woken when HVSI state changes */
@@ -744,9 +744,10 @@ static int hvsi_handshake(struct hvsi_struct *hp)
return 0;
}
-static void hvsi_handshaker(void *arg)
+static void hvsi_handshaker(struct work_struct *work)
{
- struct hvsi_struct *hp = (struct hvsi_struct *)arg;
+ struct hvsi_struct *hp =
+ container_of(work, struct hvsi_struct, handshaker);
if (hvsi_handshake(hp) >= 0)
return;
@@ -951,9 +952,10 @@ static void hvsi_push(struct hvsi_struct *hp)
}
/* hvsi_write_worker will keep rescheduling itself until outbuf is empty */
-static void hvsi_write_worker(void *arg)
+static void hvsi_write_worker(struct work_struct *work)
{
- struct hvsi_struct *hp = (struct hvsi_struct *)arg;
+ struct hvsi_struct *hp =
+ container_of(work, struct hvsi_struct, writer.work);
unsigned long flags;
#ifdef DEBUG
static long start_j = 0;
@@ -1287,8 +1289,8 @@ static int __init hvsi_console_init(void)
}
hp = &hvsi_ports[hvsi_count];
- INIT_WORK(&hp->writer, hvsi_write_worker, hp);
- INIT_WORK(&hp->handshaker, hvsi_handshaker, hp);
+ INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker);
+ INIT_WORK(&hp->handshaker, hvsi_handshaker);
init_waitqueue_head(&hp->emptyq);
init_waitqueue_head(&hp->stateq);
spin_lock_init(&hp->lock);
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index ebace201bec6..26a860adcb38 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -36,6 +36,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/sched.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 54d93f0345e8..c213fdbdb2b0 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -84,8 +84,8 @@ static void iiSendPendingMail(i2eBordStrPtr);
static void serviceOutgoingFifo(i2eBordStrPtr);
// Functions defined in ip2.c as part of interrupt handling
-static void do_input(void *);
-static void do_status(void *);
+static void do_input(struct work_struct *);
+static void do_status(struct work_struct *);
//***************
//* Debug Data *
@@ -331,8 +331,8 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
pCh->ClosingWaitTime = 30*HZ;
// Initialize task queue objects
- INIT_WORK(&pCh->tqueue_input, do_input, pCh);
- INIT_WORK(&pCh->tqueue_status, do_status, pCh);
+ INIT_WORK(&pCh->tqueue_input, do_input);
+ INIT_WORK(&pCh->tqueue_status, do_status);
#ifdef IP2DEBUG_TRACE
pCh->trace = ip2trace;
@@ -1573,7 +1573,7 @@ i2StripFifo(i2eBordStrPtr pB)
#ifdef USE_IQ
schedule_work(&pCh->tqueue_input);
#else
- do_input(pCh);
+ do_input(&pCh->tqueue_input);
#endif
// Note we do not need to maintain any flow-control credits at this
@@ -1810,7 +1810,7 @@ i2StripFifo(i2eBordStrPtr pB)
#ifdef USE_IQ
schedule_work(&pCh->tqueue_status);
#else
- do_status(pCh);
+ do_status(&pCh->tqueue_status);
#endif
}
}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index a3f32d46d2f8..cda2459c1d60 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -189,12 +189,12 @@ static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void set_irq(int, int);
-static void ip2_interrupt_bh(i2eBordStrPtr pB);
+static void ip2_interrupt_bh(struct work_struct *work);
static irqreturn_t ip2_interrupt(int irq, void *dev_id);
static void ip2_poll(unsigned long arg);
static inline void service_all_boards(void);
-static void do_input(void *p);
-static void do_status(void *p);
+static void do_input(struct work_struct *);
+static void do_status(struct work_struct *);
static void ip2_wait_until_sent(PTTY,int);
@@ -918,7 +918,7 @@ ip2_init_board( int boardnum )
pCh++;
}
ex_exit:
- INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
+ INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
return;
err_release_region:
@@ -1125,8 +1125,8 @@ service_all_boards(void)
/******************************************************************************/
-/* Function: ip2_interrupt_bh(pB) */
-/* Parameters: pB - pointer to the board structure */
+/* Function: ip2_interrupt_bh(work) */
+/* Parameters: work - pointer to the board structure */
/* Returns: Nothing */
/* */
/* Description: */
@@ -1135,8 +1135,9 @@ service_all_boards(void)
/* */
/******************************************************************************/
static void
-ip2_interrupt_bh(i2eBordStrPtr pB)
+ip2_interrupt_bh(struct work_struct *work)
{
+ i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
// pB better well be set or we have a problem! We can only get
// here from the IMMEDIATE queue. Here, we process the boards.
// Checking pB doesn't cost much and it saves us from the sanity checkers.
@@ -1245,9 +1246,9 @@ ip2_poll(unsigned long arg)
ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
}
-static void do_input(void *p)
+static void do_input(struct work_struct *work)
{
- i2ChanStrPtr pCh = p;
+ i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
unsigned long flags;
ip2trace(CHANN, ITRC_INPUT, 21, 0 );
@@ -1279,9 +1280,9 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
}
}
-static void do_status(void *p)
+static void do_status(struct work_struct *work)
{
- i2ChanStrPtr pCh = p;
+ i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
int status;
status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 58c955e390b3..1637c1d9a4ba 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -530,9 +530,9 @@ sched_again:
/* Interrupt handlers */
-static void isicom_bottomhalf(void *data)
+static void isicom_bottomhalf(struct work_struct *work)
{
- struct isi_port *port = (struct isi_port *) data;
+ struct isi_port *port = container_of(work, struct isi_port, bh_tqueue);
struct tty_struct *tty = port->tty;
if (!tty)
@@ -1474,9 +1474,9 @@ static void isicom_start(struct tty_struct *tty)
}
/* hangup et all */
-static void do_isicom_hangup(void *data)
+static void do_isicom_hangup(struct work_struct *work)
{
- struct isi_port *port = data;
+ struct isi_port *port = container_of(work, struct isi_port, hangup_tq);
struct tty_struct *tty;
tty = port->tty;
@@ -1966,8 +1966,8 @@ static int __devinit isicom_setup(void)
port->channel = channel;
port->close_delay = 50 * HZ/100;
port->closing_wait = 3000 * HZ/100;
- INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
- INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
+ INIT_WORK(&port->hangup_tq, do_isicom_hangup);
+ INIT_WORK(&port->bh_tqueue, isicom_bottomhalf);
port->status = 0;
init_waitqueue_head(&port->open_wait);
init_waitqueue_head(&port->close_wait);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index ffdf9df1a67a..bd9195e17956 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -663,7 +663,7 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);
static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp);
-static void stli_dohangup(void *arg);
+static void stli_dohangup(struct work_struct *);
static int stli_setport(stliport_t *portp);
static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
@@ -1990,9 +1990,9 @@ static void stli_start(struct tty_struct *tty)
* aren't that time critical).
*/
-static void stli_dohangup(void *arg)
+static void stli_dohangup(struct work_struct *ugly_api)
{
- stliport_t *portp = (stliport_t *) arg;
+ stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup);
if (portp->tty != NULL) {
tty_hangup(portp->tty);
}
@@ -2898,7 +2898,7 @@ static int stli_initports(stlibrd_t *brdp)
portp->baud_base = STL_BAUDBASE;
portp->close_delay = STL_CLOSEDELAY;
portp->closing_wait = 30 * HZ;
- INIT_WORK(&portp->tqhangup, stli_dohangup, portp);
+ INIT_WORK(&portp->tqhangup, stli_dohangup);
init_waitqueue_head(&portp->open_wait);
init_waitqueue_head(&portp->close_wait);
init_waitqueue_head(&portp->raw_wait);
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 96cb1f07332b..2d025a9fd14d 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -222,7 +222,7 @@ static struct semaphore moxaBuffSem;
/*
* static functions:
*/
-static void do_moxa_softint(void *);
+static void do_moxa_softint(struct work_struct *);
static int moxa_open(struct tty_struct *, struct file *);
static void moxa_close(struct tty_struct *, struct file *);
static int moxa_write(struct tty_struct *, const unsigned char *, int);
@@ -363,7 +363,7 @@ static int __init moxa_init(void)
for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
ch->type = PORT_16550A;
ch->port = i;
- INIT_WORK(&ch->tqueue, do_moxa_softint, ch);
+ INIT_WORK(&ch->tqueue, do_moxa_softint);
ch->tty = NULL;
ch->close_delay = 5 * HZ / 10;
ch->closing_wait = 30 * HZ;
@@ -509,9 +509,9 @@ static void __exit moxa_exit(void)
module_init(moxa_init);
module_exit(moxa_exit);
-static void do_moxa_softint(void *private_)
+static void do_moxa_softint(struct work_struct *work)
{
- struct moxa_str *ch = (struct moxa_str *) private_;
+ struct moxa_str *ch = container_of(work, struct moxa_str, tqueue);
struct tty_struct *tty;
if (ch && (tty = ch->tty)) {
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 048d91142c17..5ed2486b7581 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -389,7 +389,7 @@ static int mxser_init(void);
/* static void mxser_poll(unsigned long); */
static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
-static void mxser_do_softint(void *);
+static void mxser_do_softint(struct work_struct *);
static int mxser_open(struct tty_struct *, struct file *);
static void mxser_close(struct tty_struct *, struct file *);
static int mxser_write(struct tty_struct *, const unsigned char *, int);
@@ -590,7 +590,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
info->custom_divisor = hwconf->baud_base[i] * 16;
info->close_delay = 5 * HZ / 10;
info->closing_wait = 30 * HZ;
- INIT_WORK(&info->tqueue, mxser_do_softint, info);
+ INIT_WORK(&info->tqueue, mxser_do_softint);
info->normal_termios = mxvar_sdriver->init_termios;
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
@@ -917,9 +917,10 @@ static int mxser_init(void)
return 0;
}
-static void mxser_do_softint(void *private_)
+static void mxser_do_softint(struct work_struct *work)
{
- struct mxser_struct *info = private_;
+ struct mxser_struct *info =
+ container_of(work, struct mxser_struct, tqueue);
struct tty_struct *tty;
tty = info->tty;
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 50d20aafeb18..211c93fda6fc 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1764,29 +1764,11 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
int rc;
/* read the config-tuples */
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) {
- fail_fn = GetFirstTuple;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) {
- fail_fn = GetTupleData;
- goto cs_failed;
- }
- if ((fail_rc =
- pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) {
- fail_fn = ParseTuple;
- goto cs_failed;
- }
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
@@ -1841,8 +1823,6 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
return 0;
-cs_failed:
- cs_error(link, fail_fn, fail_rc);
cs_release:
cm4000_release(link);
return -ENODEV;
@@ -1973,14 +1953,14 @@ static int __init cmm_init(void)
printk(KERN_INFO "%s\n", version);
cmm_class = class_create(THIS_MODULE, "cardman_4000");
- if (!cmm_class)
- return -1;
+ if (IS_ERR(cmm_class))
+ return PTR_ERR(cmm_class);
major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
": could not get major number\n");
- return -1;
+ return major;
}
rc = pcmcia_register_driver(&cm4000_driver);
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 55cf4be42976..9b1ff7e8f896 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -523,29 +523,11 @@ static int reader_config(struct pcmcia_device *link, int devno)
int fail_fn, fail_rc;
int rc;
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) {
- fail_fn = GetFirstTuple;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) {
- fail_fn = GetTupleData;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse))
- != CS_SUCCESS) {
- fail_fn = ParseTuple;
- goto cs_failed;
- }
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
@@ -609,8 +591,6 @@ static int reader_config(struct pcmcia_device *link, int devno)
return 0;
-cs_failed:
- cs_error(link, fail_fn, fail_rc);
cs_release:
reader_release(link);
return -ENODEV;
@@ -721,14 +701,14 @@ static int __init cm4040_init(void)
printk(KERN_INFO "%s\n", version);
cmx_class = class_create(THIS_MODULE, "cardman_4040");
- if (!cmx_class)
- return -1;
+ if (IS_ERR(cmx_class))
+ return PTR_ERR(cmx_class);
major = register_chrdev(0, DEVICE_NAME, &reader_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
": could not get major number\n");
- return -1;
+ return major;
}
rc = pcmcia_register_driver(&reader_driver);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 1a0bc30b79d1..1bd12296dca5 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -421,7 +421,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id);
/*
* Bottom half interrupt handlers
*/
-static void bh_handler(void* Context);
+static void bh_handler(struct work_struct *work);
static void bh_transmit(MGSLPC_INFO *info);
static void bh_status(MGSLPC_INFO *info);
@@ -547,7 +547,7 @@ static int mgslpc_probe(struct pcmcia_device *link)
memset(info, 0, sizeof(MGSLPC_INFO));
info->magic = MGSLPC_MAGIC;
- INIT_WORK(&info->task, bh_handler, info);
+ INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
info->close_delay = 5*HZ/10;
info->closing_wait = 30*HZ;
@@ -604,17 +604,10 @@ static int mgslpc_config(struct pcmcia_device *link)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link);
- /* read CONFIG tuple to find its configuration registers */
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
/* get CIS configuration entry */
@@ -842,9 +835,9 @@ static int bh_action(MGSLPC_INFO *info)
return rc;
}
-static void bh_handler(void* Context)
+static void bh_handler(struct work_struct *work)
{
- MGSLPC_INFO *info = (MGSLPC_INFO*)Context;
+ MGSLPC_INFO *info = container_of(work, MGSLPC_INFO, task);
int action;
if (!info)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index eb6b13f4211a..4c6782a1ecdb 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1422,9 +1422,9 @@ static struct keydata {
static unsigned int ip_cnt;
-static void rekey_seq_generator(void *private_);
+static void rekey_seq_generator(struct work_struct *work);
-static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL);
+static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator);
/*
* Lock avoidance:
@@ -1438,7 +1438,7 @@ static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL);
* happen, and even if that happens only a not perfectly compliant
* ISN is generated, nothing fatal.
*/
-static void rekey_seq_generator(void *private_)
+static void rekey_seq_generator(struct work_struct *work)
{
struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)];
@@ -1466,8 +1466,8 @@ static __init int seqgen_init(void)
late_initcall(seqgen_init);
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-__u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
- __u16 sport, __u16 dport)
+__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
+ __be16 sport, __be16 dport)
{
struct timeval tv;
__u32 seq;
@@ -1479,10 +1479,10 @@ __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
*/
memcpy(hash, saddr, 16);
- hash[4]=(sport << 16) + dport;
+ hash[4]=((__force u16)sport << 16) + (__force u16)dport;
memcpy(&hash[5],keyptr->secret,sizeof(__u32) * 7);
- seq = twothirdsMD4Transform(daddr, hash) & HASH_MASK;
+ seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK;
seq += keyptr->count;
do_gettimeofday(&tv);
@@ -1496,7 +1496,7 @@ EXPORT_SYMBOL(secure_tcpv6_sequence_number);
/* The code below is shamelessly stolen from secure_tcp_sequence_number().
* All blames to Andrey V. Savochkin <saw@msu.ru>.
*/
-__u32 secure_ip_id(__u32 daddr)
+__u32 secure_ip_id(__be32 daddr)
{
struct keydata *keyptr;
__u32 hash[4];
@@ -1508,7 +1508,7 @@ __u32 secure_ip_id(__u32 daddr)
* The dest ip address is placed in the starting vector,
* which is then hashed with random data.
*/
- hash[0] = daddr;
+ hash[0] = (__force __u32)daddr;
hash[1] = keyptr->secret[9];
hash[2] = keyptr->secret[10];
hash[3] = keyptr->secret[11];
@@ -1518,8 +1518,8 @@ __u32 secure_ip_id(__u32 daddr)
#ifdef CONFIG_INET
-__u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
- __u16 sport, __u16 dport)
+__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport)
{
struct timeval tv;
__u32 seq;
@@ -1532,9 +1532,9 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
* Note that the words are placed into the starting vector, which is
* then mixed with a partial MD4 over random data.
*/
- hash[0]=saddr;
- hash[1]=daddr;
- hash[2]=(sport << 16) + dport;
+ hash[0]=(__force u32)saddr;
+ hash[1]=(__force u32)daddr;
+ hash[2]=((__force u16)sport << 16) + (__force u16)dport;
hash[3]=keyptr->secret[11];
seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK;
@@ -1559,7 +1559,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
EXPORT_SYMBOL(secure_tcp_sequence_number);
/* Generate secure starting point for ephemeral IPV4 transport port search */
-u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
{
struct keydata *keyptr = get_keyptr();
u32 hash[4];
@@ -1568,25 +1568,25 @@ u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
* Pick a unique starting offset for each ephemeral port search
* (saddr, daddr, dport) and 48bits of random data.
*/
- hash[0] = saddr;
- hash[1] = daddr;
- hash[2] = dport ^ keyptr->secret[10];
+ hash[0] = (__force u32)saddr;
+ hash[1] = (__force u32)daddr;
+ hash[2] = (__force u32)dport ^ keyptr->secret[10];
hash[3] = keyptr->secret[11];
return half_md4_transform(hash, keyptr->secret);
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
+u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport)
{
struct keydata *keyptr = get_keyptr();
u32 hash[12];
memcpy(hash, saddr, 16);
- hash[4] = dport;
+ hash[4] = (__force u32)dport;
memcpy(&hash[5],keyptr->secret,sizeof(__u32) * 7);
- return twothirdsMD4Transform(daddr, hash);
+ return twothirdsMD4Transform((const __u32 *)daddr, hash);
}
#endif
@@ -1595,17 +1595,17 @@ u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dpo
* bit's 32-47 increase every key exchange
* 0-31 hash(source, dest)
*/
-u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
- __u16 sport, __u16 dport)
+u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport)
{
struct timeval tv;
u64 seq;
__u32 hash[4];
struct keydata *keyptr = get_keyptr();
- hash[0] = saddr;
- hash[1] = daddr;
- hash[2] = (sport << 16) + dport;
+ hash[0] = (__force u32)saddr;
+ hash[1] = (__force u32)daddr;
+ hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
hash[3] = keyptr->secret[11];
seq = half_md4_transform(hash, keyptr->secret);
@@ -1641,7 +1641,7 @@ unsigned int get_random_int(void)
* drain on it), and uses halfMD4Transform within the second. We
* also mix it with jiffies and the PID:
*/
- return secure_ip_id(current->pid + jiffies);
+ return secure_ip_id((__force __be32)(current->pid + jiffies));
}
/*
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 5ab32b38f45a..722dd3e74185 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1516,9 +1516,9 @@ static void rc_start(struct tty_struct * tty)
* do_rc_hangup() -> tty->hangup() -> rc_hangup()
*
*/
-static void do_rc_hangup(void *private_)
+static void do_rc_hangup(struct work_struct *ugly_api)
{
- struct riscom_port *port = (struct riscom_port *) private_;
+ struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue_hangup);
struct tty_struct *tty;
tty = port->tty;
@@ -1567,9 +1567,9 @@ static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios
}
}
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *ugly_api)
{
- struct riscom_port *port = (struct riscom_port *) private_;
+ struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue);
struct tty_struct *tty;
if(!(tty = port->tty))
@@ -1632,8 +1632,8 @@ static inline int rc_init_drivers(void)
memset(rc_port, 0, sizeof(rc_port));
for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
rc_port[i].magic = RISCOM8_MAGIC;
- INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]);
- INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]);
+ INIT_WORK(&rc_port[i].tqueue, do_softint);
+ INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup);
rc_port[i].close_delay = 50 * HZ/100;
rc_port[i].closing_wait = 3000 * HZ/100;
init_waitqueue_head(&rc_port[i].open_wait);
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 3af7f0958c5d..9ba13af234be 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -706,9 +706,9 @@ cd2401_rx_interrupt(int irq, void *dev_id)
* had to poll every port to see if that port needed servicing.
*/
static void
-do_softint(void *private_)
+do_softint(struct work_struct *ugly_api)
{
- struct cyclades_port *info = (struct cyclades_port *) private_;
+ struct cyclades_port *info = container_of(ugly_api, struct cyclades_port, tqueue);
struct tty_struct *tty;
tty = info->tty;
@@ -2273,7 +2273,7 @@ scrn[1] = '\0';
info->blocked_open = 0;
info->default_threshold = 0;
info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
+ INIT_WORK(&info->tqueue, do_softint);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
/* info->session */
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index c084149153de..fc87070f1866 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -765,7 +765,7 @@ static void sonypi_setbluetoothpower(u8 state)
sonypi_device.bluetooth_power = state;
}
-static void input_keyrelease(void *data)
+static void input_keyrelease(struct work_struct *work)
{
struct sonypi_keypress kp;
@@ -1412,7 +1412,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
goto err_inpdev_unregister;
}
- INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL);
+ INIT_WORK(&sonypi_device.input_work, input_keyrelease);
}
sonypi_enable(0);
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 7e1bd9562c2a..99137ab66b62 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2261,9 +2261,10 @@ static void sx_start(struct tty_struct * tty)
* do_sx_hangup() -> tty->hangup() -> sx_hangup()
*
*/
-static void do_sx_hangup(void *private_)
+static void do_sx_hangup(struct work_struct *work)
{
- struct specialix_port *port = (struct specialix_port *) private_;
+ struct specialix_port *port =
+ container_of(work, struct specialix_port, tqueue_hangup);
struct tty_struct *tty;
func_enter();
@@ -2336,9 +2337,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios
}
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *work)
{
- struct specialix_port *port = (struct specialix_port *) private_;
+ struct specialix_port *port =
+ container_of(work, struct specialix_port, tqueue);
struct tty_struct *tty;
func_enter();
@@ -2411,8 +2413,8 @@ static int sx_init_drivers(void)
memset(sx_port, 0, sizeof(sx_port));
for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
sx_port[i].magic = SPECIALIX_MAGIC;
- INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
- INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
+ INIT_WORK(&sx_port[i].tqueue, do_softint);
+ INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup);
sx_port[i].close_delay = 50 * HZ/100;
sx_port[i].closing_wait = 3000 * HZ/100;
init_waitqueue_head(&sx_port[i].open_wait);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 522e88e395cc..5e2de62bce70 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -500,7 +500,7 @@ static int stl_echatintr(stlbrd_t *brdp);
static int stl_echmcaintr(stlbrd_t *brdp);
static int stl_echpciintr(stlbrd_t *brdp);
static int stl_echpci64intr(stlbrd_t *brdp);
-static void stl_offintr(void *private);
+static void stl_offintr(struct work_struct *);
static stlbrd_t *stl_allocbrd(void);
static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
@@ -2081,14 +2081,12 @@ static int stl_echpci64intr(stlbrd_t *brdp)
/*
* Service an off-level request for some channel.
*/
-static void stl_offintr(void *private)
+static void stl_offintr(struct work_struct *work)
{
- stlport_t *portp;
+ stlport_t *portp = container_of(work, stlport_t, tqueue);
struct tty_struct *tty;
unsigned int oldsigs;
- portp = private;
-
#ifdef DEBUG
printk("stl_offintr(portp=%x)\n", (int) portp);
#endif
@@ -2156,7 +2154,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
portp->baud_base = STL_BAUDBASE;
portp->close_delay = STL_CLOSEDELAY;
portp->closing_wait = 30 * HZ;
- INIT_WORK(&portp->tqueue, stl_offintr, portp);
+ INIT_WORK(&portp->tqueue, stl_offintr);
init_waitqueue_head(&portp->open_wait);
init_waitqueue_head(&portp->close_wait);
portp->stats.brd = portp->brdnr;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 06784adcc35c..147c30da81ea 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -802,7 +802,7 @@ static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, u
/*
* Bottom half interrupt handlers
*/
-static void mgsl_bh_handler(void* Context);
+static void mgsl_bh_handler(struct work_struct *work);
static void mgsl_bh_receive(struct mgsl_struct *info);
static void mgsl_bh_transmit(struct mgsl_struct *info);
static void mgsl_bh_status(struct mgsl_struct *info);
@@ -1071,9 +1071,10 @@ static int mgsl_bh_action(struct mgsl_struct *info)
/*
* Perform bottom half processing of work items queued by ISR.
*/
-static void mgsl_bh_handler(void* Context)
+static void mgsl_bh_handler(struct work_struct *work)
{
- struct mgsl_struct *info = (struct mgsl_struct*)Context;
+ struct mgsl_struct *info =
+ container_of(work, struct mgsl_struct, task);
int action;
if (!info)
@@ -4337,7 +4338,7 @@ static struct mgsl_struct* mgsl_allocate_device(void)
} else {
memset(info, 0, sizeof(struct mgsl_struct));
info->magic = MGSL_MAGIC;
- INIT_WORK(&info->task, mgsl_bh_handler, info);
+ INIT_WORK(&info->task, mgsl_bh_handler);
info->max_frame_size = 4096;
info->close_delay = 5*HZ/10;
info->closing_wait = 30*HZ;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index d4334c79f8d4..07f34d43dc7f 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -485,7 +485,7 @@ static void enable_loopback(struct slgt_info *info);
static void set_rate(struct slgt_info *info, u32 data_rate);
static int bh_action(struct slgt_info *info);
-static void bh_handler(void* context);
+static void bh_handler(struct work_struct *work);
static void bh_transmit(struct slgt_info *info);
static void isr_serial(struct slgt_info *info);
static void isr_rdma(struct slgt_info *info);
@@ -1878,9 +1878,9 @@ static int bh_action(struct slgt_info *info)
/*
* perform bottom half processing
*/
-static void bh_handler(void* context)
+static void bh_handler(struct work_struct *work)
{
- struct slgt_info *info = context;
+ struct slgt_info *info = container_of(work, struct slgt_info, task);
int action;
if (!info)
@@ -3326,7 +3326,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
} else {
memset(info, 0, sizeof(struct slgt_info));
info->magic = MGSL_MAGIC;
- INIT_WORK(&info->task, bh_handler, info);
+ INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
info->raw_rx_size = DMABUFSIZE;
info->close_delay = 5*HZ/10;
@@ -4799,6 +4799,6 @@ static void rx_timeout(unsigned long context)
spin_lock_irqsave(&info->lock, flags);
info->pending_bh |= BH_RECEIVE;
spin_unlock_irqrestore(&info->lock, flags);
- bh_handler(info);
+ bh_handler(&info->task);
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 3e932b681371..13a57245cf2e 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -602,7 +602,7 @@ static void enable_loopback(SLMP_INFO *info, int enable);
static void set_rate(SLMP_INFO *info, u32 data_rate);
static int bh_action(SLMP_INFO *info);
-static void bh_handler(void* Context);
+static void bh_handler(struct work_struct *work);
static void bh_receive(SLMP_INFO *info);
static void bh_transmit(SLMP_INFO *info);
static void bh_status(SLMP_INFO *info);
@@ -2063,9 +2063,9 @@ int bh_action(SLMP_INFO *info)
/* Perform bottom half processing of work items queued by ISR.
*/
-void bh_handler(void* Context)
+void bh_handler(struct work_struct *work)
{
- SLMP_INFO *info = (SLMP_INFO*)Context;
+ SLMP_INFO *info = container_of(work, SLMP_INFO, task);
int action;
if (!info)
@@ -3805,7 +3805,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
} else {
memset(info, 0, sizeof(SLMP_INFO));
info->magic = MGSL_MAGIC;
- INIT_WORK(&info->task, bh_handler, info);
+ INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
info->close_delay = 5*HZ/10;
info->closing_wait = 30*HZ;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 5f49280779fb..c64f5bcff947 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -219,13 +219,13 @@ static struct sysrq_key_op sysrq_term_op = {
.enable_mask = SYSRQ_ENABLE_SIGNAL,
};
-static void moom_callback(void *ignored)
+static void moom_callback(struct work_struct *ignored)
{
out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL],
GFP_KERNEL, 0);
}
-static DECLARE_WORK(moom_work, moom_callback, NULL);
+static DECLARE_WORK(moom_work, moom_callback);
static void sysrq_handle_moom(int key, struct tty_struct *tty)
{
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 6e1329d404d2..774fa861169a 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -325,9 +325,9 @@ static void user_reader_timeout(unsigned long ptr)
schedule_work(&chip->work);
}
-static void timeout_work(void *ptr)
+static void timeout_work(struct work_struct *work)
{
- struct tpm_chip *chip = ptr;
+ struct tpm_chip *chip = container_of(work, struct tpm_chip, work);
down(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
@@ -1105,7 +1105,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
- INIT_WORK(&chip->work, timeout_work, chip);
+ INIT_WORK(&chip->work, timeout_work);
init_timer(&chip->user_read_timer);
chip->user_read_timer.function = user_reader_timeout;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 050ced247f68..bb9a43c6cf3d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -22,6 +22,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/fs.h>
+#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/io.h>
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 50dc49205a23..b3cfc8bc613c 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1254,7 +1254,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
/**
* do_tty_hangup - actual handler for hangup events
- * @data: tty device
+ * @work: tty device
*
* This can be called by the "eventd" kernel thread. That is process
* synchronous but doesn't hold any locks, so we need to make sure we
@@ -1274,9 +1274,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
* tasklist_lock to walk task list for hangup event
*
*/
-static void do_tty_hangup(void *data)
+static void do_tty_hangup(struct work_struct *work)
{
- struct tty_struct *tty = (struct tty_struct *) data;
+ struct tty_struct *tty =
+ container_of(work, struct tty_struct, hangup_work);
struct file * cons_filp = NULL;
struct file *filp, *f = NULL;
struct task_struct *p;
@@ -1433,7 +1434,7 @@ void tty_vhangup(struct tty_struct * tty)
printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
#endif
- do_tty_hangup((void *) tty);
+ do_tty_hangup(&tty->hangup_work);
}
EXPORT_SYMBOL(tty_vhangup);
@@ -3304,12 +3305,13 @@ int tty_ioctl(struct inode * inode, struct file * file,
* Nasty bug: do_SAK is being called in interrupt context. This can
* deadlock. We punt it up to process context. AKPM - 16Mar2001
*/
-static void __do_SAK(void *arg)
+static void __do_SAK(struct work_struct *work)
{
+ struct tty_struct *tty =
+ container_of(work, struct tty_struct, SAK_work);
#ifdef TTY_SOFT_SAK
tty_hangup(tty);
#else
- struct tty_struct *tty = arg;
struct task_struct *g, *p;
int session;
int i;
@@ -3388,7 +3390,7 @@ void do_SAK(struct tty_struct *tty)
{
if (!tty)
return;
- PREPARE_WORK(&tty->SAK_work, __do_SAK, tty);
+ PREPARE_WORK(&tty->SAK_work, __do_SAK);
schedule_work(&tty->SAK_work);
}
@@ -3396,7 +3398,7 @@ EXPORT_SYMBOL(do_SAK);
/**
* flush_to_ldisc
- * @private_: tty structure passed from work queue.
+ * @work: tty structure passed from work queue.
*
* This routine is called out of the software interrupt to flush data
* from the buffer chain to the line discipline.
@@ -3406,9 +3408,10 @@ EXPORT_SYMBOL(do_SAK);
* receive_buf method is single threaded for each tty instance.
*/
-static void flush_to_ldisc(void *private_)
+static void flush_to_ldisc(struct work_struct *work)
{
- struct tty_struct *tty = (struct tty_struct *) private_;
+ struct tty_struct *tty =
+ container_of(work, struct tty_struct, buf.work.work);
unsigned long flags;
struct tty_ldisc *disc;
struct tty_buffer *tbuf, *head;
@@ -3553,7 +3556,7 @@ void tty_flip_buffer_push(struct tty_struct *tty)
spin_unlock_irqrestore(&tty->buf.lock, flags);
if (tty->low_latency)
- flush_to_ldisc((void *) tty);
+ flush_to_ldisc(&tty->buf.work.work);
else
schedule_delayed_work(&tty->buf.work, 1);
}
@@ -3580,17 +3583,17 @@ static void initialize_tty_struct(struct tty_struct *tty)
tty->overrun_time = jiffies;
tty->buf.head = tty->buf.tail = NULL;
tty_buffer_init(tty);
- INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
+ INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
init_MUTEX(&tty->buf.pty_sem);
mutex_init(&tty->termios_mutex);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
- INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
+ INIT_WORK(&tty->hangup_work, do_tty_hangup);
mutex_init(&tty->atomic_read_lock);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->read_lock);
INIT_LIST_HEAD(&tty->tty_files);
- INIT_WORK(&tty->SAK_work, NULL, NULL);
+ INIT_WORK(&tty->SAK_work, NULL);
}
/*
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 87587b4385ab..75ff0286e1ad 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -155,7 +155,7 @@ static void con_flush_chars(struct tty_struct *tty);
static void set_vesa_blanking(char __user *p);
static void set_cursor(struct vc_data *vc);
static void hide_cursor(struct vc_data *vc);
-static void console_callback(void *ignored);
+static void console_callback(struct work_struct *ignored);
static void blank_screen_t(unsigned long dummy);
static void set_palette(struct vc_data *vc);
@@ -174,7 +174,7 @@ static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
static int blankinterval = 10*60*HZ;
static int vesa_off_interval;
-static DECLARE_WORK(console_work, console_callback, NULL);
+static DECLARE_WORK(console_work, console_callback);
/*
* fg_console is the current virtual console,
@@ -2154,7 +2154,7 @@ out:
* with other console code and prevention of re-entrancy is
* ensured with console_sem.
*/
-static void console_callback(void *ignored)
+static void console_callback(struct work_struct *ignored)
{
acquire_console_sem();
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 05f8ce2cfb4a..b418b16e910e 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -31,9 +31,11 @@
#include <linux/connector.h>
#include <linux/delay.h>
-void cn_queue_wrapper(void *data)
+void cn_queue_wrapper(struct work_struct *work)
{
- struct cn_callback_data *d = data;
+ struct cn_callback_entry *cbq =
+ container_of(work, struct cn_callback_entry, work.work);
+ struct cn_callback_data *d = &cbq->data;
d->callback(d->callback_priv);
@@ -57,7 +59,7 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;
- INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data);
+ INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper);
return cbq;
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index b49bacfd8de8..5e7cd45d10ee 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -135,40 +135,39 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
spin_lock_bh(&dev->cbdev->queue_lock);
list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
- if (likely(!test_bit(0, &__cbq->work.pending) &&
+ if (likely(!test_bit(WORK_STRUCT_PENDING,
+ &__cbq->work.work.management) &&
__cbq->data.ddata == NULL)) {
__cbq->data.callback_priv = msg;
__cbq->data.ddata = data;
__cbq->data.destruct_data = destruct_data;
- if (queue_work(dev->cbdev->cn_queue,
- &__cbq->work))
+ if (queue_delayed_work(
+ dev->cbdev->cn_queue,
+ &__cbq->work, 0))
err = 0;
} else {
- struct work_struct *w;
struct cn_callback_data *d;
- w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC);
- if (w) {
- d = (struct cn_callback_data *)(w+1);
-
+ __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC);
+ if (__cbq) {
+ d = &__cbq->data;
d->callback_priv = msg;
d->callback = __cbq->data.callback;
d->ddata = data;
d->destruct_data = destruct_data;
- d->free = w;
+ d->free = __cbq;
- INIT_LIST_HEAD(&w->entry);
- w->pending = 0;
- w->func = &cn_queue_wrapper;
- w->data = d;
- init_timer(&w->timer);
+ INIT_DELAYED_WORK(&__cbq->work,
+ &cn_queue_wrapper);
- if (queue_work(dev->cbdev->cn_queue, w))
+ if (queue_delayed_work(
+ dev->cbdev->cn_queue,
+ &__cbq->work, 0))
err = 0;
else {
- kfree(w);
+ kfree(__cbq);
err = -EINVAL;
}
} else
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index dd0c2623e27b..7a7c6e6dfe4f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -42,7 +42,7 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
/* internal prototypes */
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
-static void handle_update(void *data);
+static void handle_update(struct work_struct *work);
/**
* Two notifier lists: the "policy" list is involved in the
@@ -665,7 +665,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
mutex_init(&policy->lock);
mutex_lock(&policy->lock);
init_completion(&policy->kobj_unregister);
- INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
+ INIT_WORK(&policy->update, handle_update);
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
@@ -895,9 +895,11 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
}
-static void handle_update(void *data)
+static void handle_update(struct work_struct *work)
{
- unsigned int cpu = (unsigned int)(long)data;
+ struct cpufreq_policy *policy =
+ container_of(work, struct cpufreq_policy, update);
+ unsigned int cpu = policy->cpu;
dprintk("handle_update for cpu %u called\n", cpu);
cpufreq_update_policy(cpu);
}
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index c4c578defabf..5ef5ede5b884 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -59,7 +59,7 @@ static unsigned int def_sampling_rate;
#define MAX_SAMPLING_DOWN_FACTOR (10)
#define TRANSITION_LATENCY_LIMIT (10 * 1000)
-static void do_dbs_timer(void *data);
+static void do_dbs_timer(struct work_struct *work);
struct cpu_dbs_info_s {
struct cpufreq_policy *cur_policy;
@@ -82,7 +82,7 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
* is recursive for the same process. -Venki
*/
static DEFINE_MUTEX (dbs_mutex);
-static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
+static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer);
struct dbs_tuners {
unsigned int sampling_rate;
@@ -420,7 +420,7 @@ static void dbs_check_cpu(int cpu)
}
}
-static void do_dbs_timer(void *data)
+static void do_dbs_timer(struct work_struct *work)
{
int i;
lock_cpu_hotplug();
@@ -435,7 +435,6 @@ static void do_dbs_timer(void *data)
static inline void dbs_timer_init(void)
{
- INIT_WORK(&dbs_work, do_dbs_timer, NULL);
schedule_delayed_work(&dbs_work,
usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
return;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index bf8aa45d4f01..e1cc5113c2ae 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -47,13 +47,17 @@ static unsigned int def_sampling_rate;
#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
#define TRANSITION_LATENCY_LIMIT (10 * 1000)
-static void do_dbs_timer(void *data);
+static void do_dbs_timer(struct work_struct *work);
+
+/* Sampling types */
+enum dbs_sample {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
struct cpu_dbs_info_s {
cputime64_t prev_cpu_idle;
cputime64_t prev_cpu_wall;
struct cpufreq_policy *cur_policy;
- struct work_struct work;
+ struct delayed_work work;
+ enum dbs_sample sample_type;
unsigned int enable;
struct cpufreq_frequency_table *freq_table;
unsigned int freq_lo;
@@ -407,30 +411,31 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
}
}
-/* Sampling types */
-enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
-
-static void do_dbs_timer(void *data)
+static void do_dbs_timer(struct work_struct *work)
{
unsigned int cpu = smp_processor_id();
struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
+ enum dbs_sample sample_type = dbs_info->sample_type;
/* We want all CPUs to do sampling nearly on same jiffy */
int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+ /* Permit rescheduling of this work item */
+ work_release(work);
+
delay -= jiffies % delay;
if (!dbs_info->enable)
return;
/* Common NORMAL_SAMPLE setup */
- INIT_WORK(&dbs_info->work, do_dbs_timer, (void *)DBS_NORMAL_SAMPLE);
+ dbs_info->sample_type = DBS_NORMAL_SAMPLE;
if (!dbs_tuners_ins.powersave_bias ||
- (unsigned long) data == DBS_NORMAL_SAMPLE) {
+ sample_type == DBS_NORMAL_SAMPLE) {
lock_cpu_hotplug();
dbs_check_cpu(dbs_info);
unlock_cpu_hotplug();
if (dbs_info->freq_lo) {
/* Setup timer for SUB_SAMPLE */
- INIT_WORK(&dbs_info->work, do_dbs_timer,
- (void *)DBS_SUB_SAMPLE);
+ dbs_info->sample_type = DBS_SUB_SAMPLE;
delay = dbs_info->freq_hi_jiffies;
}
} else {
@@ -449,7 +454,8 @@ static inline void dbs_timer_init(unsigned int cpu)
delay -= jiffies % delay;
ondemand_powersave_bias_init();
- INIT_WORK(&dbs_info->work, do_dbs_timer, NULL);
+ INIT_DELAYED_WORK_NAR(&dbs_info->work, do_dbs_timer);
+ dbs_info->sample_type = DBS_NORMAL_SAMPLE;
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
}
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index e5cb0fdab9b1..b1dc63e4ac7b 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -21,6 +21,7 @@
etc voltage & frequency control is not supported!
*/
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 26be4ea8a38a..e8ef62b83d6b 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
index 4630f1969a09..15edf40828b4 100644
--- a/drivers/i2c/chips/ds1374.c
+++ b/drivers/i2c/chips/ds1374.c
@@ -140,12 +140,14 @@ ulong ds1374_get_rtc_time(void)
return t1;
}
-static void ds1374_set_work(void *arg)
+static ulong new_time;
+
+static void ds1374_set_work(struct work_struct *work)
{
ulong t1, t2;
int limit = 10; /* arbitrary retry limit */
- t1 = *(ulong *) arg;
+ t1 = new_time;
mutex_lock(&ds1374_mutex);
@@ -167,11 +169,9 @@ static void ds1374_set_work(void *arg)
"can't confirm time set from rtc chip\n");
}
-static ulong new_time;
-
static struct workqueue_struct *ds1374_workqueue;
-static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time);
+static DECLARE_WORK(ds1374_work, ds1374_set_work);
int ds1374_set_rtc_time(ulong nowtime)
{
@@ -180,7 +180,7 @@ int ds1374_set_rtc_time(ulong nowtime)
if (in_interrupt())
queue_work(ds1374_workqueue, &ds1374_work);
else
- ds1374_set_work(&new_time);
+ ds1374_set_work(NULL);
return 0;
}
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index 2dd0a34d9472..420377c86422 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -215,8 +215,15 @@ m41t00_set(void *arg)
}
static ulong new_time;
+/* well, isn't this API just _lovely_? */
+static void
+m41t00_barf(struct work_struct *unusable)
+{
+ m41t00_set(&new_time);
+}
+
static struct workqueue_struct *m41t00_wq;
-static DECLARE_WORK(m41t00_work, m41t00_set, &new_time);
+static DECLARE_WORK(m41t00_work, m41t00_barf);
int
m41t00_set_rtc_time(ulong nowtime)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index bef4759f70e5..7efd28ac21ed 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -192,20 +192,10 @@ static int ide_config(struct pcmcia_device *link)
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
- link->conf.ConfigBase = stk->parse.config.base;
- link->conf.Present = stk->parse.config.rmask[0];
-
- tuple.DesiredTuple = CISTPL_MANFID;
- if (!pcmcia_get_first_tuple(link, &tuple) &&
- !pcmcia_get_tuple_data(link, &tuple) &&
- !pcmcia_parse_tuple(link, &tuple, &stk->parse))
- is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
- ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
- (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
+
+ is_kme = ((link->manf_id == MANFID_KME) &&
+ ((link->card_id == PRODID_KME_KXLC005_A) ||
+ (link->card_id == PRODID_KME_KXLC005_B)));
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
@@ -408,8 +398,10 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
+ PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 2af634d7acf4..eb7ab112c050 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -35,7 +35,7 @@
#include <linux/ide.h>
#include <asm/io.h>
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#ifdef CONFIG_PPC_CHRP
#include <asm/processor.h>
#endif
@@ -442,7 +442,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->speedproc = &via_set_drive;
-#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
+#ifdef CONFIG_PPC_CHRP
if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
hwif->irq = hwif->channel ? 15 : 14;
}
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index d90a3a1898c0..8f4378a1631c 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -31,9 +31,10 @@
#include "config_roms.h"
-static void delayed_reset_bus(void * __reset_info)
+static void delayed_reset_bus(struct work_struct *work)
{
- struct hpsb_host *host = (struct hpsb_host*)__reset_info;
+ struct hpsb_host *host =
+ container_of(work, struct hpsb_host, delayed_reset.work);
int generation = host->csr.generation + 1;
/* The generation field rolls over to 2 rather than 0 per IEEE
@@ -145,7 +146,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
atomic_set(&h->generation, 0);
- INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
+ INIT_DELAYED_WORK(&h->delayed_reset, delayed_reset_bus);
init_timer(&h->timeout);
h->timeout.data = (unsigned long) h;
@@ -234,7 +235,7 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
* Config ROM in the near future. */
reset_delay = HZ;
- PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host);
+ PREPARE_DELAYED_WORK(&host->delayed_reset, delayed_reset_bus);
schedule_delayed_work(&host->delayed_reset, reset_delay);
return 0;
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index bc6dbfadb891..d553e38c9543 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -62,7 +62,7 @@ struct hpsb_host {
struct class_device class_dev;
int update_config_rom;
- struct work_struct delayed_reset;
+ struct delayed_work delayed_reset;
unsigned int config_roms;
struct list_head addr_space;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 6986ac188281..cd156d4e779e 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -493,20 +493,25 @@ static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id,
scsi_unblock_requests(scsi_id->scsi_host);
}
-static void sbp2util_write_orb_pointer(void *p)
+static void sbp2util_write_orb_pointer(struct work_struct *work)
{
+ struct scsi_id_instance_data *scsi_id =
+ container_of(work, struct scsi_id_instance_data,
+ protocol_work.work);
quadlet_t data[2];
- data[0] = ORB_SET_NODE_ID(
- ((struct scsi_id_instance_data *)p)->hi->host->node_id);
- data[1] = ((struct scsi_id_instance_data *)p)->last_orb_dma;
+ data[0] = ORB_SET_NODE_ID(scsi_id->hi->host->node_id);
+ data[1] = scsi_id->last_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);
- sbp2util_notify_fetch_agent(p, SBP2_ORB_POINTER_OFFSET, data, 8);
+ sbp2util_notify_fetch_agent(scsi_id, SBP2_ORB_POINTER_OFFSET, data, 8);
}
-static void sbp2util_write_doorbell(void *p)
+static void sbp2util_write_doorbell(struct work_struct *work)
{
- sbp2util_notify_fetch_agent(p, SBP2_DOORBELL_OFFSET, NULL, 4);
+ struct scsi_id_instance_data *scsi_id =
+ container_of(work, struct scsi_id_instance_data,
+ protocol_work.work);
+ sbp2util_notify_fetch_agent(scsi_id, SBP2_DOORBELL_OFFSET, NULL, 4);
}
/*
@@ -843,7 +848,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
INIT_LIST_HEAD(&scsi_id->scsi_list);
spin_lock_init(&scsi_id->sbp2_command_orb_lock);
atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
- INIT_WORK(&scsi_id->protocol_work, NULL, NULL);
+ INIT_DELAYED_WORK(&scsi_id->protocol_work, NULL);
ud->device.driver_data = scsi_id;
@@ -2047,11 +2052,10 @@ static void sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
* We do not accept new commands until the job is over.
*/
scsi_block_requests(scsi_id->scsi_host);
- PREPARE_WORK(&scsi_id->protocol_work,
+ PREPARE_DELAYED_WORK(&scsi_id->protocol_work,
last_orb ? sbp2util_write_doorbell:
- sbp2util_write_orb_pointer,
- scsi_id);
- schedule_work(&scsi_id->protocol_work);
+ sbp2util_write_orb_pointer);
+ schedule_delayed_work(&scsi_id->protocol_work, 0);
}
}
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index abbe48e646c3..1b16d6b9cf11 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -348,7 +348,7 @@ struct scsi_id_instance_data {
unsigned workarounds;
atomic_t state;
- struct work_struct protocol_work;
+ struct delayed_work protocol_work;
};
/* For use in scsi_id_instance_data.state */
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 7767a11b6890..af939796750d 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -55,11 +55,11 @@ struct addr_req {
int status;
};
-static void process_req(void *data);
+static void process_req(struct work_struct *work);
static DEFINE_MUTEX(lock);
static LIST_HEAD(req_list);
-static DECLARE_WORK(work, process_req, NULL);
+static DECLARE_DELAYED_WORK(work, process_req);
static struct workqueue_struct *addr_wq;
void rdma_addr_register_client(struct rdma_addr_client *client)
@@ -215,7 +215,7 @@ out:
return ret;
}
-static void process_req(void *data)
+static void process_req(struct work_struct *work)
{
struct addr_req *req, *temp_req;
struct sockaddr_in *src_in, *dst_in;
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 20e9f64e67a6..98272fbbfb31 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -285,9 +285,10 @@ err:
kfree(tprops);
}
-static void ib_cache_task(void *work_ptr)
+static void ib_cache_task(struct work_struct *_work)
{
- struct ib_update_work *work = work_ptr;
+ struct ib_update_work *work =
+ container_of(_work, struct ib_update_work, work);
ib_cache_update(work->device, work->port_num);
kfree(work);
@@ -306,7 +307,7 @@ static void ib_cache_event(struct ib_event_handler *handler,
event->event == IB_EVENT_CLIENT_REREGISTER) {
work = kmalloc(sizeof *work, GFP_ATOMIC);
if (work) {
- INIT_WORK(&work->work, ib_cache_task, work);
+ INIT_WORK(&work->work, ib_cache_task);
work->device = event->device;
work->port_num = event->element.port_num;
schedule_work(&work->work);
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index e5dc4530808a..79c937bf6962 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -101,7 +101,7 @@ struct cm_av {
};
struct cm_work {
- struct work_struct work;
+ struct delayed_work work;
struct list_head list;
struct cm_port *port;
struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */
@@ -161,7 +161,7 @@ struct cm_id_private {
atomic_t work_count;
};
-static void cm_work_handler(void *data);
+static void cm_work_handler(struct work_struct *work);
static inline void cm_deref_id(struct cm_id_private *cm_id_priv)
{
@@ -668,8 +668,7 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
return ERR_PTR(-ENOMEM);
timewait_info->work.local_id = local_id;
- INIT_WORK(&timewait_info->work.work, cm_work_handler,
- &timewait_info->work);
+ INIT_DELAYED_WORK(&timewait_info->work.work, cm_work_handler);
timewait_info->work.cm_event.event = IB_CM_TIMEWAIT_EXIT;
return timewait_info;
}
@@ -2995,9 +2994,9 @@ static void cm_send_handler(struct ib_mad_agent *mad_agent,
}
}
-static void cm_work_handler(void *data)
+static void cm_work_handler(struct work_struct *_work)
{
- struct cm_work *work = data;
+ struct cm_work *work = container_of(_work, struct cm_work, work.work);
int ret;
switch (work->cm_event.event) {
@@ -3087,12 +3086,12 @@ static int cm_establish(struct ib_cm_id *cm_id)
* we need to find the cm_id once we're in the context of the
* worker thread, rather than holding a reference on it.
*/
- INIT_WORK(&work->work, cm_work_handler, work);
+ INIT_DELAYED_WORK(&work->work, cm_work_handler);
work->local_id = cm_id->local_id;
work->remote_id = cm_id->remote_id;
work->mad_recv_wc = NULL;
work->cm_event.event = IB_CM_USER_ESTABLISHED;
- queue_work(cm.wq, &work->work);
+ queue_delayed_work(cm.wq, &work->work, 0);
out:
return ret;
}
@@ -3191,11 +3190,11 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent,
return;
}
- INIT_WORK(&work->work, cm_work_handler, work);
+ INIT_DELAYED_WORK(&work->work, cm_work_handler);
work->cm_event.event = event;
work->mad_recv_wc = mad_recv_wc;
work->port = (struct cm_port *)mad_agent->context;
- queue_work(cm.wq, &work->work);
+ queue_delayed_work(cm.wq, &work->work, 0);
}
static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv,
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index cf48f2697434..985a6b564d8f 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1340,9 +1340,9 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
return (id_priv->query_id < 0) ? id_priv->query_id : 0;
}
-static void cma_work_handler(void *data)
+static void cma_work_handler(struct work_struct *_work)
{
- struct cma_work *work = data;
+ struct cma_work *work = container_of(_work, struct cma_work, work);
struct rdma_id_private *id_priv = work->id;
int destroy = 0;
@@ -1373,7 +1373,7 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms)
return -ENOMEM;
work->id = id_priv;
- INIT_WORK(&work->work, cma_work_handler, work);
+ INIT_WORK(&work->work, cma_work_handler);
work->old_state = CMA_ROUTE_QUERY;
work->new_state = CMA_ROUTE_RESOLVED;
work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
@@ -1430,7 +1430,7 @@ static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms)
return -ENOMEM;
work->id = id_priv;
- INIT_WORK(&work->work, cma_work_handler, work);
+ INIT_WORK(&work->work, cma_work_handler);
work->old_state = CMA_ROUTE_QUERY;
work->new_state = CMA_ROUTE_RESOLVED;
work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
@@ -1583,7 +1583,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
}
work->id = id_priv;
- INIT_WORK(&work->work, cma_work_handler, work);
+ INIT_WORK(&work->work, cma_work_handler);
work->old_state = CMA_ADDR_QUERY;
work->new_state = CMA_ADDR_RESOLVED;
work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index cf797d7aea09..1039ad57d53b 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -828,9 +828,9 @@ static int process_event(struct iwcm_id_private *cm_id_priv,
* thread asleep on the destroy_comp list vs. an object destroyed
* here synchronously when the last reference is removed.
*/
-static void cm_work_handler(void *arg)
+static void cm_work_handler(struct work_struct *_work)
{
- struct iwcm_work *work = arg;
+ struct iwcm_work *work = container_of(_work, struct iwcm_work, work);
struct iw_cm_event levent;
struct iwcm_id_private *cm_id_priv = work->cm_id;
unsigned long flags;
@@ -900,7 +900,7 @@ static int cm_event_handler(struct iw_cm_id *cm_id,
goto out;
}
- INIT_WORK(&work->work, cm_work_handler, work);
+ INIT_WORK(&work->work, cm_work_handler);
work->cm_id = cm_id_priv;
work->event = *iw_event;
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 3f9c16232c4d..15f38d94b3a8 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -65,8 +65,8 @@ static struct ib_mad_agent_private *find_mad_agent(
static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
struct ib_mad_private *mad);
static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
-static void timeout_sends(void *data);
-static void local_completions(void *data);
+static void timeout_sends(struct work_struct *work);
+static void local_completions(struct work_struct *work);
static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
struct ib_mad_agent_private *agent_priv,
u8 mgmt_class);
@@ -356,10 +356,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
INIT_LIST_HEAD(&mad_agent_priv->wait_list);
INIT_LIST_HEAD(&mad_agent_priv->done_list);
INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
- INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv);
+ INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
INIT_LIST_HEAD(&mad_agent_priv->local_list);
- INIT_WORK(&mad_agent_priv->local_work, local_completions,
- mad_agent_priv);
+ INIT_WORK(&mad_agent_priv->local_work, local_completions);
atomic_set(&mad_agent_priv->refcount, 1);
init_completion(&mad_agent_priv->comp);
@@ -2198,12 +2197,12 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv,
/*
* IB MAD completion callback
*/
-static void ib_mad_completion_handler(void *data)
+static void ib_mad_completion_handler(struct work_struct *work)
{
struct ib_mad_port_private *port_priv;
struct ib_wc wc;
- port_priv = (struct ib_mad_port_private *)data;
+ port_priv = container_of(work, struct ib_mad_port_private, work);
ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
@@ -2324,7 +2323,7 @@ void ib_cancel_mad(struct ib_mad_agent *mad_agent,
}
EXPORT_SYMBOL(ib_cancel_mad);
-static void local_completions(void *data)
+static void local_completions(struct work_struct *work)
{
struct ib_mad_agent_private *mad_agent_priv;
struct ib_mad_local_private *local;
@@ -2334,7 +2333,8 @@ static void local_completions(void *data)
struct ib_wc wc;
struct ib_mad_send_wc mad_send_wc;
- mad_agent_priv = (struct ib_mad_agent_private *)data;
+ mad_agent_priv =
+ container_of(work, struct ib_mad_agent_private, local_work);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
while (!list_empty(&mad_agent_priv->local_list)) {
@@ -2434,14 +2434,15 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
return ret;
}
-static void timeout_sends(void *data)
+static void timeout_sends(struct work_struct *work)
{
struct ib_mad_agent_private *mad_agent_priv;
struct ib_mad_send_wr_private *mad_send_wr;
struct ib_mad_send_wc mad_send_wc;
unsigned long flags, delay;
- mad_agent_priv = (struct ib_mad_agent_private *)data;
+ mad_agent_priv = container_of(work, struct ib_mad_agent_private,
+ timed_work.work);
mad_send_wc.vendor_err = 0;
spin_lock_irqsave(&mad_agent_priv->lock, flags);
@@ -2799,7 +2800,7 @@ static int ib_mad_port_open(struct ib_device *device,
ret = -ENOMEM;
goto error8;
}
- INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv);
+ INIT_WORK(&port_priv->work, ib_mad_completion_handler);
spin_lock_irqsave(&ib_mad_port_list_lock, flags);
list_add_tail(&port_priv->port_list, &ib_mad_port_list);
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index d06b59083f6e..d5548e73e068 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -102,7 +102,7 @@ struct ib_mad_agent_private {
struct list_head send_list;
struct list_head wait_list;
struct list_head done_list;
- struct work_struct timed_work;
+ struct delayed_work timed_work;
unsigned long timeout;
struct list_head local_list;
struct work_struct local_work;
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 1ef79d015a1e..3663fd7022be 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -45,8 +45,8 @@ enum rmpp_state {
struct mad_rmpp_recv {
struct ib_mad_agent_private *agent;
struct list_head list;
- struct work_struct timeout_work;
- struct work_struct cleanup_work;
+ struct delayed_work timeout_work;
+ struct delayed_work cleanup_work;
struct completion comp;
enum rmpp_state state;
spinlock_t lock;
@@ -233,9 +233,10 @@ static void nack_recv(struct ib_mad_agent_private *agent,
}
}
-static void recv_timeout_handler(void *data)
+static void recv_timeout_handler(struct work_struct *work)
{
- struct mad_rmpp_recv *rmpp_recv = data;
+ struct mad_rmpp_recv *rmpp_recv =
+ container_of(work, struct mad_rmpp_recv, timeout_work.work);
struct ib_mad_recv_wc *rmpp_wc;
unsigned long flags;
@@ -254,9 +255,10 @@ static void recv_timeout_handler(void *data)
ib_free_recv_mad(rmpp_wc);
}
-static void recv_cleanup_handler(void *data)
+static void recv_cleanup_handler(struct work_struct *work)
{
- struct mad_rmpp_recv *rmpp_recv = data;
+ struct mad_rmpp_recv *rmpp_recv =
+ container_of(work, struct mad_rmpp_recv, cleanup_work.work);
unsigned long flags;
spin_lock_irqsave(&rmpp_recv->agent->lock, flags);
@@ -285,8 +287,8 @@ create_rmpp_recv(struct ib_mad_agent_private *agent,
rmpp_recv->agent = agent;
init_completion(&rmpp_recv->comp);
- INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv);
- INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv);
+ INIT_DELAYED_WORK(&rmpp_recv->timeout_work, recv_timeout_handler);
+ INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler);
spin_lock_init(&rmpp_recv->lock);
rmpp_recv->state = RMPP_STATE_ACTIVE;
atomic_set(&rmpp_recv->refcount, 1);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 1706d3c7e95e..e45afba75341 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -360,9 +360,10 @@ static void free_sm_ah(struct kref *kref)
kfree(sm_ah);
}
-static void update_sm_ah(void *port_ptr)
+static void update_sm_ah(struct work_struct *work)
{
- struct ib_sa_port *port = port_ptr;
+ struct ib_sa_port *port =
+ container_of(work, struct ib_sa_port, update_task);
struct ib_sa_sm_ah *new_ah, *old_ah;
struct ib_port_attr port_attr;
struct ib_ah_attr ah_attr;
@@ -992,8 +993,7 @@ static void ib_sa_add_one(struct ib_device *device)
if (IS_ERR(sa_dev->port[i].agent))
goto err;
- INIT_WORK(&sa_dev->port[i].update_task,
- update_sm_ah, &sa_dev->port[i]);
+ INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
}
ib_set_client_data(device, &sa_client, sa_dev);
@@ -1010,7 +1010,7 @@ static void ib_sa_add_one(struct ib_device *device)
goto err;
for (i = 0; i <= e - s; ++i)
- update_sm_ah(&sa_dev->port[i]);
+ update_sm_ah(&sa_dev->port[i].update_task);
return;
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c
index efe147dbeb42..db12cc0841df 100644
--- a/drivers/infiniband/core/uverbs_mem.c
+++ b/drivers/infiniband/core/uverbs_mem.c
@@ -179,9 +179,10 @@ void ib_umem_release(struct ib_device *dev, struct ib_umem *umem)
up_write(&current->mm->mmap_sem);
}
-static void ib_umem_account(void *work_ptr)
+static void ib_umem_account(struct work_struct *_work)
{
- struct ib_umem_account_work *work = work_ptr;
+ struct ib_umem_account_work *work =
+ container_of(_work, struct ib_umem_account_work, work);
down_write(&work->mm->mmap_sem);
work->mm->locked_vm -= work->diff;
@@ -216,7 +217,7 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem)
return;
}
- INIT_WORK(&work->work, ib_umem_account, work);
+ INIT_WORK(&work->work, ib_umem_account);
work->mm = mm;
work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 413754b1d8a2..8536aeb96af8 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -214,9 +214,10 @@ struct ipath_user_pages_work {
unsigned long num_pages;
};
-static void user_pages_account(void *ptr)
+static void user_pages_account(struct work_struct *_work)
{
- struct ipath_user_pages_work *work = ptr;
+ struct ipath_user_pages_work *work =
+ container_of(_work, struct ipath_user_pages_work, work);
down_write(&work->mm->mmap_sem);
work->mm->locked_vm -= work->num_pages;
@@ -242,7 +243,7 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages)
goto bail;
- INIT_WORK(&work->work, user_pages_account, work);
+ INIT_WORK(&work->work, user_pages_account);
work->mm = mm;
work->num_pages = num_pages;
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index cd044ea2dfa4..e948158a28d9 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -57,7 +57,7 @@ static int catas_reset_disable;
module_param_named(catas_reset_disable, catas_reset_disable, int, 0644);
MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero");
-static void catas_reset(void *work_ptr)
+static void catas_reset(struct work_struct *work)
{
struct mthca_dev *dev, *tmpdev;
LIST_HEAD(tlist);
@@ -203,7 +203,7 @@ void mthca_stop_catas_poll(struct mthca_dev *dev)
int __init mthca_catas_init(void)
{
- INIT_WORK(&catas_work, catas_reset, NULL);
+ INIT_WORK(&catas_work, catas_reset);
catas_wq = create_singlethread_workqueue("mthca_catas");
if (!catas_wq)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index f2b61851a49c..99547996aba2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -136,11 +136,11 @@ struct ipoib_dev_priv {
struct list_head multicast_list;
struct rb_root multicast_tree;
- struct work_struct pkey_task;
- struct work_struct mcast_task;
+ struct delayed_work pkey_task;
+ struct delayed_work mcast_task;
struct work_struct flush_task;
struct work_struct restart_task;
- struct work_struct ah_reap_task;
+ struct delayed_work ah_reap_task;
struct ib_device *ca;
u8 port;
@@ -254,13 +254,13 @@ int ipoib_add_pkey_attr(struct net_device *dev);
void ipoib_send(struct net_device *dev, struct sk_buff *skb,
struct ipoib_ah *address, u32 qpn);
-void ipoib_reap_ah(void *dev_ptr);
+void ipoib_reap_ah(struct work_struct *work);
void ipoib_flush_paths(struct net_device *dev);
struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
-void ipoib_ib_dev_flush(void *dev);
+void ipoib_ib_dev_flush(struct work_struct *work);
void ipoib_ib_dev_cleanup(struct net_device *dev);
int ipoib_ib_dev_open(struct net_device *dev);
@@ -271,10 +271,10 @@ int ipoib_ib_dev_stop(struct net_device *dev);
int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
void ipoib_dev_cleanup(struct net_device *dev);
-void ipoib_mcast_join_task(void *dev_ptr);
+void ipoib_mcast_join_task(struct work_struct *work);
void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
-void ipoib_mcast_restart_task(void *dev_ptr);
+void ipoib_mcast_restart_task(struct work_struct *work);
int ipoib_mcast_start_thread(struct net_device *dev);
int ipoib_mcast_stop_thread(struct net_device *dev, int flush);
@@ -312,7 +312,7 @@ void ipoib_event(struct ib_event_handler *handler,
int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey);
int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
-void ipoib_pkey_poll(void *dev);
+void ipoib_pkey_poll(struct work_struct *work);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8bf5e9ec7c95..f10fba5d3265 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -400,10 +400,11 @@ static void __ipoib_reap_ah(struct net_device *dev)
spin_unlock_irq(&priv->tx_lock);
}
-void ipoib_reap_ah(void *dev_ptr)
+void ipoib_reap_ah(struct work_struct *work)
{
- struct net_device *dev = dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
+ struct ipoib_dev_priv *priv =
+ container_of(work, struct ipoib_dev_priv, ah_reap_task.work);
+ struct net_device *dev = priv->dev;
__ipoib_reap_ah(dev);
@@ -613,10 +614,11 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
return 0;
}
-void ipoib_ib_dev_flush(void *_dev)
+void ipoib_ib_dev_flush(struct work_struct *work)
{
- struct net_device *dev = (struct net_device *)_dev;
- struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv;
+ struct ipoib_dev_priv *cpriv, *priv =
+ container_of(work, struct ipoib_dev_priv, flush_task);
+ struct net_device *dev = priv->dev;
if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) {
ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
@@ -638,14 +640,14 @@ void ipoib_ib_dev_flush(void *_dev)
*/
if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {
ipoib_ib_dev_up(dev);
- ipoib_mcast_restart_task(dev);
+ ipoib_mcast_restart_task(&priv->restart_task);
}
mutex_lock(&priv->vlan_mutex);
/* Flush any child interfaces too */
list_for_each_entry(cpriv, &priv->child_intfs, list)
- ipoib_ib_dev_flush(cpriv->dev);
+ ipoib_ib_dev_flush(&cpriv->flush_task);
mutex_unlock(&priv->vlan_mutex);
}
@@ -672,10 +674,11 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
* change async notification is available.
*/
-void ipoib_pkey_poll(void *dev_ptr)
+void ipoib_pkey_poll(struct work_struct *work)
{
- struct net_device *dev = dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
+ struct ipoib_dev_priv *priv =
+ container_of(work, struct ipoib_dev_priv, pkey_task.work);
+ struct net_device *dev = priv->dev;
ipoib_pkey_dev_check_presence(dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 5ba3154320b4..c09280243726 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -940,11 +940,11 @@ static void ipoib_setup(struct net_device *dev)
INIT_LIST_HEAD(&priv->dead_ahs);
INIT_LIST_HEAD(&priv->multicast_list);
- INIT_WORK(&priv->pkey_task, ipoib_pkey_poll, priv->dev);
- INIT_WORK(&priv->mcast_task, ipoib_mcast_join_task, priv->dev);
- INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush, priv->dev);
- INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task, priv->dev);
- INIT_WORK(&priv->ah_reap_task, ipoib_reap_ah, priv->dev);
+ INIT_DELAYED_WORK(&priv->pkey_task, ipoib_pkey_poll);
+ INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task);
+ INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush);
+ INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task);
+ INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah);
}
struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index d282d65e3ee0..b04b72ca32ed 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -399,7 +399,8 @@ static void ipoib_mcast_join_complete(int status,
mcast->backoff = 1;
mutex_lock(&mcast_mutex);
if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
- queue_work(ipoib_workqueue, &priv->mcast_task);
+ queue_delayed_work(ipoib_workqueue,
+ &priv->mcast_task, 0);
mutex_unlock(&mcast_mutex);
complete(&mcast->done);
return;
@@ -435,7 +436,8 @@ static void ipoib_mcast_join_complete(int status,
if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
if (status == -ETIMEDOUT)
- queue_work(ipoib_workqueue, &priv->mcast_task);
+ queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
+ 0);
else
queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
mcast->backoff * HZ);
@@ -517,10 +519,11 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
mcast->query_id = ret;
}
-void ipoib_mcast_join_task(void *dev_ptr)
+void ipoib_mcast_join_task(struct work_struct *work)
{
- struct net_device *dev = dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
+ struct ipoib_dev_priv *priv =
+ container_of(work, struct ipoib_dev_priv, mcast_task.work);
+ struct net_device *dev = priv->dev;
if (!test_bit(IPOIB_MCAST_RUN, &priv->flags))
return;
@@ -610,7 +613,7 @@ int ipoib_mcast_start_thread(struct net_device *dev)
mutex_lock(&mcast_mutex);
if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags))
- queue_work(ipoib_workqueue, &priv->mcast_task);
+ queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0);
mutex_unlock(&mcast_mutex);
spin_lock_irq(&priv->lock);
@@ -818,10 +821,11 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
}
}
-void ipoib_mcast_restart_task(void *dev_ptr)
+void ipoib_mcast_restart_task(struct work_struct *work)
{
- struct net_device *dev = dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
+ struct ipoib_dev_priv *priv =
+ container_of(work, struct ipoib_dev_priv, restart_task);
+ struct net_device *dev = priv->dev;
struct dev_mc_list *mclist;
struct ipoib_mcast *mcast, *tmcast;
LIST_HEAD(remove_list);
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 0606744c3f84..5e122501fd80 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -35,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <asm/io.h>
#include <asm/scatterlist.h>
#include <linux/scatterlist.h>
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 18a000034996..693b77002897 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -48,7 +48,7 @@
static void iser_cq_tasklet_fn(unsigned long data);
static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
-static void iser_comp_error_worker(void *data);
+static void iser_comp_error_worker(struct work_struct *work);
static void iser_cq_event_callback(struct ib_event *cause, void *context)
{
@@ -480,8 +480,7 @@ int iser_conn_init(struct iser_conn **ibconn)
init_waitqueue_head(&ib_conn->wait);
atomic_set(&ib_conn->post_recv_buf_count, 0);
atomic_set(&ib_conn->post_send_buf_count, 0);
- INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker,
- ib_conn);
+ INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker);
INIT_LIST_HEAD(&ib_conn->conn_list);
spin_lock_init(&ib_conn->lock);
@@ -754,9 +753,10 @@ int iser_post_send(struct iser_desc *tx_desc)
return ret_val;
}
-static void iser_comp_error_worker(void *data)
+static void iser_comp_error_worker(struct work_struct *work)
{
- struct iser_conn *ib_conn = data;
+ struct iser_conn *ib_conn =
+ container_of(work, struct iser_conn, comperror_work);
/* getting here when the state is UP means that the conn is being *
* terminated asynchronously from the iSCSI layer's perspective. */
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 64ab5fc7cca3..a6289595557b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -390,9 +390,10 @@ static void srp_disconnect_target(struct srp_target_port *target)
wait_for_completion(&target->done);
}
-static void srp_remove_work(void *target_ptr)
+static void srp_remove_work(struct work_struct *work)
{
- struct srp_target_port *target = target_ptr;
+ struct srp_target_port *target =
+ container_of(work, struct srp_target_port, work);
spin_lock_irq(target->scsi_host->host_lock);
if (target->state != SRP_TARGET_DEAD) {
@@ -575,7 +576,7 @@ err:
spin_lock_irq(target->scsi_host->host_lock);
if (target->state == SRP_TARGET_CONNECTING) {
target->state = SRP_TARGET_DEAD;
- INIT_WORK(&target->work, srp_remove_work, target);
+ INIT_WORK(&target->work, srp_remove_work);
schedule_work(&target->work);
}
spin_unlock_irq(target->scsi_host->host_lock);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index cbb93669d1ce..8451b29a3db5 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -567,9 +567,9 @@ static int atkbd_set_leds(struct atkbd *atkbd)
* interrupt context.
*/
-static void atkbd_event_work(void *data)
+static void atkbd_event_work(struct work_struct *work)
{
- struct atkbd *atkbd = data;
+ struct atkbd *atkbd = container_of(work, struct atkbd, event_work);
mutex_lock(&atkbd->event_mutex);
@@ -943,7 +943,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->dev = dev;
ps2_init(&atkbd->ps2dev, serio);
- INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
+ INIT_WORK(&atkbd->event_work, atkbd_event_work);
mutex_init(&atkbd->event_mutex);
switch (serio->id.type) {
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 979b93e33da7..b7f049b45b6b 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -572,9 +572,9 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
* were in.
*/
static void
-lkkbd_reinit (void *data)
+lkkbd_reinit (struct work_struct *work)
{
- struct lkkbd *lk = data;
+ struct lkkbd *lk = container_of(work, struct lkkbd, tq);
int division;
unsigned char leds_on = 0;
unsigned char leds_off = 0;
@@ -651,7 +651,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
lk->serio = serio;
lk->dev = input_dev;
- INIT_WORK (&lk->tq, lkkbd_reinit, lk);
+ INIT_WORK (&lk->tq, lkkbd_reinit);
lk->bell_volume = bell_volume;
lk->keyclick_volume = keyclick_volume;
lk->ctrlclick_volume = ctrlclick_volume;
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index cac4781103c3..6cd887c5eb0a 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -208,9 +208,9 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
* were in.
*/
-static void sunkbd_reinit(void *data)
+static void sunkbd_reinit(struct work_struct *work)
{
- struct sunkbd *sunkbd = data;
+ struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
@@ -248,7 +248,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
sunkbd->serio = serio;
sunkbd->dev = input_dev;
init_waitqueue_head(&sunkbd->wait);
- INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
+ INIT_WORK(&sunkbd->tq, sunkbd_reinit);
snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, sunkbd);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 6f9b2c7cc9c2..52bb2226ce2f 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -888,9 +888,10 @@ static int psmouse_poll(struct psmouse *psmouse)
* psmouse_resync() attempts to re-validate current protocol.
*/
-static void psmouse_resync(void *p)
+static void psmouse_resync(struct work_struct *work)
{
- struct psmouse *psmouse = p, *parent = NULL;
+ struct psmouse *parent = NULL, *psmouse =
+ container_of(work, struct psmouse, resync_work);
struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
int failed = 0, enabled = 0;
@@ -1121,7 +1122,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
goto out;
ps2_init(&psmouse->ps2dev, serio);
- INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
+ INIT_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index e5b1b60757bb..b3e84d3bb7f7 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -251,9 +251,9 @@ EXPORT_SYMBOL(ps2_command);
* ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
*/
-static void ps2_execute_scheduled_command(void *data)
+static void ps2_execute_scheduled_command(struct work_struct *work)
{
- struct ps2work *ps2work = data;
+ struct ps2work *ps2work = container_of(work, struct ps2work, work);
ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
kfree(ps2work);
@@ -278,7 +278,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
ps2work->ps2dev = ps2dev;
ps2work->command = command;
memcpy(ps2work->param, param, send);
- INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work);
+ INIT_WORK(&ps2work->work, ps2_execute_scheduled_command);
if (!schedule_work(&ps2work->work)) {
kfree(ps2work);
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index 6ae6eb322111..946c38cf6f8a 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -627,8 +627,10 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
}
void
-actcapi_dispatch(act2000_card *card)
+actcapi_dispatch(struct work_struct *work)
{
+ struct act2000_card *card =
+ container_of(work, struct act2000_card, rcv_tq);
struct sk_buff *skb;
actcapi_msg *msg;
__u16 ccmd;
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
index 49f453c53c64..e55f6a931f66 100644
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -356,7 +356,7 @@ extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int
extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *);
extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *);
extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8);
-extern void actcapi_dispatch(act2000_card *);
+extern void actcapi_dispatch(struct work_struct *);
#ifdef DEBUG_MSG
extern void actcapi_debug_msg(struct sk_buff *skb, int);
#else
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index d89dcde4eade..90593e2ef872 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -192,8 +192,11 @@ act2000_set_msn(act2000_card *card, char *eazmsn)
}
static void
-act2000_transmit(struct act2000_card *card)
+act2000_transmit(struct work_struct *work)
{
+ struct act2000_card *card =
+ container_of(work, struct act2000_card, snd_tq);
+
switch (card->bus) {
case ACT2000_BUS_ISA:
act2000_isa_send(card);
@@ -207,8 +210,11 @@ act2000_transmit(struct act2000_card *card)
}
static void
-act2000_receive(struct act2000_card *card)
+act2000_receive(struct work_struct *work)
{
+ struct act2000_card *card =
+ container_of(work, struct act2000_card, poll_tq);
+
switch (card->bus) {
case ACT2000_BUS_ISA:
act2000_isa_receive(card);
@@ -227,7 +233,7 @@ act2000_poll(unsigned long data)
act2000_card * card = (act2000_card *)data;
unsigned long flags;
- act2000_receive(card);
+ act2000_receive(&card->poll_tq);
spin_lock_irqsave(&card->lock, flags);
mod_timer(&card->ptimer, jiffies+3);
spin_unlock_irqrestore(&card->lock, flags);
@@ -578,9 +584,9 @@ act2000_alloccard(int bus, int port, int irq, char *id)
skb_queue_head_init(&card->sndq);
skb_queue_head_init(&card->rcvq);
skb_queue_head_init(&card->ackq);
- INIT_WORK(&card->snd_tq, (void *) (void *) act2000_transmit, card);
- INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card);
- INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card);
+ INIT_WORK(&card->snd_tq, act2000_transmit);
+ INIT_WORK(&card->rcv_tq, actcapi_dispatch);
+ INIT_WORK(&card->poll_tq, act2000_receive);
init_timer(&card->ptimer);
card->interface.owner = THIS_MODULE;
card->interface.channels = ACT2000_BCH;
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 8c4fcb9027b3..783a25526315 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -208,9 +208,10 @@ static void notify_down(u32 contr)
}
}
-static void notify_handler(void *data)
+static void notify_handler(struct work_struct *work)
{
- struct capi_notifier *np = data;
+ struct capi_notifier *np =
+ container_of(work, struct capi_notifier, work);
switch (np->cmd) {
case KCI_CONTRUP:
@@ -235,7 +236,7 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci)
if (!np)
return -ENOMEM;
- INIT_WORK(&np->work, notify_handler, np);
+ INIT_WORK(&np->work, notify_handler);
np->cmd = cmd;
np->controller = controller;
np->applid = applid;
@@ -248,10 +249,11 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci)
/* -------- Receiver ------------------------------------------ */
-static void recv_handler(void *_ap)
+static void recv_handler(struct work_struct *work)
{
struct sk_buff *skb;
- struct capi20_appl *ap = (struct capi20_appl *) _ap;
+ struct capi20_appl *ap =
+ container_of(work, struct capi20_appl, recv_work);
if ((!ap) || (ap->release_in_progress))
return;
@@ -527,7 +529,7 @@ u16 capi20_register(struct capi20_appl *ap)
ap->callback = NULL;
init_MUTEX(&ap->recv_sem);
skb_queue_head_init(&ap->recv_queue);
- INIT_WORK(&ap->recv_work, recv_handler, (void *)ap);
+ INIT_WORK(&ap->recv_work, recv_handler);
ap->release_in_progress = 0;
write_unlock_irqrestore(&application_lock, flags);
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 1f5ebe9ee72c..03319ea5aa0c 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -10,6 +10,8 @@
*/
#include <linux/proc_fs.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
#include "isdn_divert.h"
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 7bbfd85ab793..fd5d7364a487 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -194,41 +194,11 @@ static int avmcs_config(struct pcmcia_device *link)
dev = link->priv;
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
do {
- tuple.DesiredTuple = CISTPL_CONFIG;
- i = pcmcia_get_first_tuple(link, &tuple);
- if (i != CS_SUCCESS) break;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- i = pcmcia_get_tuple_data(link, &tuple);
- if (i != CS_SUCCESS) break;
- i = pcmcia_parse_tuple(link, &tuple, &parse);
- if (i != CS_SUCCESS) break;
- link->conf.ConfigBase = parse.config.base;
- } while (0);
- if (i != CS_SUCCESS) {
- cs_error(link, ParseTuple, i);
- return -ENODEV;
- }
-
- do {
-
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 254;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
-
devname[0] = 0;
- if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
- strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
- sizeof(devname));
- }
+ if (link->prod_id[1])
+ strlcpy(devname, link->prod_id[1], sizeof(devname));
+
/*
* find IO port
*/
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index bec59010bc66..3b19caeba258 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -232,9 +232,10 @@ Amd7930_new_ph(struct IsdnCardState *cs)
static void
-Amd7930_bh(struct IsdnCardState *cs)
+Amd7930_bh(struct work_struct *work)
{
-
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
if (!cs)
@@ -789,7 +790,7 @@ Amd7930_init(struct IsdnCardState *cs)
void __devinit
setup_Amd7930(struct IsdnCardState *cs)
{
- INIT_WORK(&cs->tqueue, (void *)(void *) Amd7930_bh, cs);
+ INIT_WORK(&cs->tqueue, Amd7930_bh);
cs->dbusytimer.function = (void *) dbusy_timer_handler;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index ac28e3278ad9..876fec6c6be8 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -216,41 +216,11 @@ static int avma1cs_config(struct pcmcia_device *link)
DEBUG(0, "avma1cs_config(0x%p)\n", link);
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
do {
- tuple.DesiredTuple = CISTPL_CONFIG;
- i = pcmcia_get_first_tuple(link, &tuple);
- if (i != CS_SUCCESS) break;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- i = pcmcia_get_tuple_data(link, &tuple);
- if (i != CS_SUCCESS) break;
- i = pcmcia_parse_tuple(link, &tuple, &parse);
- if (i != CS_SUCCESS) break;
- link->conf.ConfigBase = parse.config.base;
- } while (0);
- if (i != CS_SUCCESS) {
- cs_error(link, ParseTuple, i);
- return -ENODEV;
- }
-
- do {
-
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 254;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
-
devname[0] = 0;
- if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
- strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
- sizeof(devname));
- }
+ if (link->prod_id[1])
+ strlcpy(devname, link->prod_id[1], sizeof(devname));
+
/*
* find IO port
*/
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 785b08554fca..cede72cdbb31 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1137,7 +1137,6 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
cs->tx_skb = NULL;
cs->tx_cnt = 0;
cs->event = 0;
- cs->tqueue.data = cs;
skb_queue_head_init(&cs->rq);
skb_queue_head_init(&cs->sq);
@@ -1554,7 +1553,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg);
static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg);
static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs);
static void hisax_bc_close(struct BCState *bcs);
-static void hisax_bh(struct IsdnCardState *cs);
+static void hisax_bh(struct work_struct *work);
static void EChannel_proc_rcv(struct hisax_d_if *d_if);
int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
@@ -1586,7 +1585,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
hisax_d_if->cs = cs;
cs->hw.hisax_d_if = hisax_d_if;
cs->cardmsg = hisax_cardmsg;
- INIT_WORK(&cs->tqueue, (void *)(void *)hisax_bh, cs);
+ INIT_WORK(&cs->tqueue, hisax_bh);
cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1;
for (i = 0; i < 2; i++) {
cs->bcs[i].BC_SetStack = hisax_bc_setstack;
@@ -1618,8 +1617,10 @@ static void hisax_sched_event(struct IsdnCardState *cs, int event)
schedule_work(&cs->tqueue);
}
-static void hisax_bh(struct IsdnCardState *cs)
+static void hisax_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
struct PStack *st;
int pr;
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index e18e75be8ed3..4e180d210faa 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -242,23 +242,6 @@ static int elsa_cs_config(struct pcmcia_device *link)
DEBUG(0, "elsa_config(0x%p)\n", link);
dev = link->priv;
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 255;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- i = first_tuple(link, &tuple, &parse);
- if (i != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index d852c9d998b2..de9b1a4d6bac 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1083,8 +1083,9 @@ tx_b_frame(struct hfc4s8s_btype *bch)
/* bottom half handler for interrupt */
/*************************************/
static void
-hfc4s8s_bh(hfc4s8s_hw * hw)
+hfc4s8s_bh(struct work_struct *work)
{
+ hfc4s8s_hw *hw = container_of(work, hfc4s8s_hw, tqueue);
u_char b;
struct hfc4s8s_l1 *l1p;
volatile u_char *fifo_stat;
@@ -1550,7 +1551,7 @@ setup_instance(hfc4s8s_hw * hw)
goto out;
}
- INIT_WORK(&hw->tqueue, (void *) (void *) hfc4s8s_bh, hw);
+ INIT_WORK(&hw->tqueue, hfc4s8s_bh);
if (request_irq
(hw->irq, hfc4s8s_interrupt, IRQF_SHARED, hw->card_name, hw)) {
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 6360e8214720..8d9864453a23 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -549,10 +549,11 @@ setstack_2b(struct PStack *st, struct BCState *bcs)
}
static void
-hfcd_bh(struct IsdnCardState *cs)
+hfcd_bh(struct work_struct *work)
{
- if (!cs)
- return;
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
+
if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
switch (cs->dc.hfcd.ph_state) {
case (0):
@@ -1072,5 +1073,5 @@ set_cs_func(struct IsdnCardState *cs)
cs->dbusytimer.function = (void *) hfc_dbusy_timer;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
- INIT_WORK(&cs->tqueue, (void *)(void *) hfcd_bh, cs);
+ INIT_WORK(&cs->tqueue, hfcd_bh);
}
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 93f60b563515..5db0a85b827f 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1506,8 +1506,10 @@ setstack_2b(struct PStack *st, struct BCState *bcs)
/* handle L1 state changes */
/***************************/
static void
-hfcpci_bh(struct IsdnCardState *cs)
+hfcpci_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
u_long flags;
// struct PStack *stptr;
@@ -1722,7 +1724,7 @@ setup_hfcpci(struct IsdnCard *card)
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
/* At this point the needed PCI config is done */
/* fifos are still not enabled */
- INIT_WORK(&cs->tqueue, (void *)(void *) hfcpci_bh, cs);
+ INIT_WORK(&cs->tqueue, hfcpci_bh);
cs->setstack_d = setstack_hfcpci;
cs->BC_Send_Data = &hfcpci_send_data;
cs->readisac = NULL;
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 954d1536db1f..4fd09d21a27f 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -1251,8 +1251,10 @@ setstack_2b(struct PStack *st, struct BCState *bcs)
/* handle L1 state changes */
/***************************/
static void
-hfcsx_bh(struct IsdnCardState *cs)
+hfcsx_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
u_long flags;
if (!cs)
@@ -1499,7 +1501,7 @@ setup_hfcsx(struct IsdnCard *card)
cs->dbusytimer.function = (void *) hfcsx_dbusy_timer;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
- INIT_WORK(&cs->tqueue, (void *)(void *) hfcsx_bh, cs);
+ INIT_WORK(&cs->tqueue, hfcsx_bh);
cs->readisac = NULL;
cs->writeisac = NULL;
cs->readisacfifo = NULL;
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index da706925d54d..682cac32f259 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -77,8 +77,10 @@ icc_new_ph(struct IsdnCardState *cs)
}
static void
-icc_bh(struct IsdnCardState *cs)
+icc_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
if (!cs)
@@ -674,7 +676,7 @@ clear_pending_icc_ints(struct IsdnCardState *cs)
void __devinit
setup_icc(struct IsdnCardState *cs)
{
- INIT_WORK(&cs->tqueue, (void *)(void *) icc_bh, cs);
+ INIT_WORK(&cs->tqueue, icc_bh);
cs->dbusytimer.function = (void *) dbusy_timer_handler;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 282f349408bc..4e9f23803dae 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -81,8 +81,10 @@ isac_new_ph(struct IsdnCardState *cs)
}
static void
-isac_bh(struct IsdnCardState *cs)
+isac_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
if (!cs)
@@ -674,7 +676,7 @@ clear_pending_isac_ints(struct IsdnCardState *cs)
void __devinit
setup_isac(struct IsdnCardState *cs)
{
- INIT_WORK(&cs->tqueue, (void *)(void *) isac_bh, cs);
+ INIT_WORK(&cs->tqueue, isac_bh);
cs->dbusytimer.function = (void *) dbusy_timer_handler;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 674af673ff96..6f1a6583b17d 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -437,8 +437,10 @@ extern void BChannel_bh(struct BCState *);
#define B_LL_OK 10
static void
-isar_bh(struct BCState *bcs)
+isar_bh(struct work_struct *work)
{
+ struct BCState *bcs = container_of(work, struct BCState, tqueue);
+
BChannel_bh(bcs);
if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event))
ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR);
@@ -1580,7 +1582,7 @@ isar_setup(struct IsdnCardState *cs)
cs->bcs[i].mode = 0;
cs->bcs[i].hw.isar.dpath = i + 1;
modeisar(&cs->bcs[i], 0, 0);
- INIT_WORK(&cs->bcs[i].tqueue, (void *)(void *) isar_bh, &cs->bcs[i]);
+ INIT_WORK(&cs->bcs[i].tqueue, isar_bh);
}
}
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index bab356886483..a14204ec88ee 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -315,8 +315,10 @@ BChannel_proc_ack(struct BCState *bcs)
}
void
-BChannel_bh(struct BCState *bcs)
+BChannel_bh(struct work_struct *work)
{
+ struct BCState *bcs = container_of(work, struct BCState, tqueue);
+
if (!bcs)
return;
if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event))
@@ -362,7 +364,7 @@ init_bcstate(struct IsdnCardState *cs, int bc)
bcs->cs = cs;
bcs->channel = bc;
- INIT_WORK(&bcs->tqueue, (void *)(void *) BChannel_bh, bcs);
+ INIT_WORK(&bcs->tqueue, BChannel_bh);
spin_lock_init(&bcs->aclock);
bcs->BC_SetStack = NULL;
bcs->BC_Close = NULL;
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index f9c14a2970bc..46ed65334c51 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -233,20 +233,10 @@ static int sedlbauer_config(struct pcmcia_device *link)
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index afcc2aeadb34..6b754f183796 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -232,23 +232,6 @@ static int teles_cs_config(struct pcmcia_device *link)
DEBUG(0, "teles_config(0x%p)\n", link);
dev = link->priv;
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 255;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- i = first_tuple(link, &tuple, &parse);
- if (i != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 1655341797a9..3aeceaf9769e 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -101,8 +101,10 @@ W6692_new_ph(struct IsdnCardState *cs)
}
static void
-W6692_bh(struct IsdnCardState *cs)
+W6692_bh(struct work_struct *work)
{
+ struct IsdnCardState *cs =
+ container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
if (!cs)
@@ -1070,7 +1072,7 @@ setup_w6692(struct IsdnCard *card)
id_list[cs->subtyp].card_name, cs->irq,
cs->hw.w6692.iobase);
- INIT_WORK(&cs->tqueue, (void *)(void *) W6692_bh, cs);
+ INIT_WORK(&cs->tqueue, W6692_bh);
cs->readW6692 = &ReadW6692;
cs->writeW6692 = &WriteW6692;
cs->readisacfifo = &ReadISACfifo;
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 82e42a80dc4b..a1206498a1cf 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -71,8 +71,9 @@ ergo_interrupt(int intno, void *dev_id)
/* may be queued from everywhere (interrupts included). */
/******************************************************************************/
static void
-ergo_irq_bh(hysdn_card * card)
+ergo_irq_bh(struct work_struct *ugli_api)
{
+ hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue);
tErgDpram *dpr;
int again;
unsigned long flags;
@@ -442,7 +443,7 @@ ergo_inithardware(hysdn_card * card)
card->writebootseq = ergo_writebootseq;
card->waitpofready = ergo_waitpofready;
card->set_errlog_state = ergo_set_errlog_state;
- INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card);
+ INIT_WORK(&card->irq_queue, ergo_irq_bh);
card->hysdn_lock = SPIN_LOCK_UNLOCKED;
return (0);
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 1f8d6ae66b41..2e4daebfb7e0 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -984,9 +984,9 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
/*
* called from tq_immediate
*/
-static void isdn_net_softint(void *private)
+static void isdn_net_softint(struct work_struct *work)
{
- isdn_net_local *lp = private;
+ isdn_net_local *lp = container_of(work, isdn_net_local, tqueue);
struct sk_buff *skb;
spin_lock_bh(&lp->xmit_lock);
@@ -2596,7 +2596,7 @@ isdn_net_new(char *name, struct net_device *master)
netdev->local->netdev = netdev;
netdev->local->next = netdev->local;
- INIT_WORK(&netdev->local->tqueue, (void *)(void *) isdn_net_softint, netdev->local);
+ INIT_WORK(&netdev->local->tqueue, isdn_net_softint);
spin_lock_init(&netdev->local->xmit_lock);
netdev->local->isdn_device = -1;
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 6ead5e1508b7..1966f3410a13 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -68,8 +68,6 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list);
static int pcbit_check_msn(struct pcbit_dev *dev, char *msn);
-extern void pcbit_deliver(void * data);
-
int pcbit_init_dev(int board, int mem_base, int irq)
{
struct pcbit_dev *dev;
@@ -129,7 +127,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
memset(dev->b2, 0, sizeof(struct pcbit_chan));
dev->b2->id = 1;
- INIT_WORK(&dev->qdelivery, pcbit_deliver, dev);
+ INIT_WORK(&dev->qdelivery, pcbit_deliver);
/*
* interrupts
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 937fd2120381..0c9f6df873fc 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -67,7 +67,6 @@ extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
* Prototypes
*/
-void pcbit_deliver(void *data);
static void pcbit_transmit(struct pcbit_dev *dev);
static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);
@@ -299,11 +298,12 @@ pcbit_transmit(struct pcbit_dev *dev)
*/
void
-pcbit_deliver(void *data)
+pcbit_deliver(struct work_struct *work)
{
struct frame_buf *frame;
unsigned long flags, msg;
- struct pcbit_dev *dev = (struct pcbit_dev *) data;
+ struct pcbit_dev *dev =
+ container_of(work, struct pcbit_dev, qdelivery);
spin_lock_irqsave(&dev->lock, flags);
diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h
index 388bacefd23a..19c18e88ff16 100644
--- a/drivers/isdn/pcbit/pcbit.h
+++ b/drivers/isdn/pcbit/pcbit.h
@@ -166,4 +166,6 @@ struct pcbit_ioctl {
#define L2_RUNNING 5
#define L2_ERROR 6
+extern void pcbit_deliver(struct work_struct *work);
+
#endif
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index fa651886ab4f..54b155c7026f 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 29a8818a32ec..d756bdb01c59 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 7f8477d3a661..92ccee85e2a2 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -228,4 +228,11 @@ config ANSLCD
tristate "Support for ANS LCD display"
depends on ADB_CUDA && PPC_PMAC
+config PMAC_RACKMETER
+ tristate "Support for Apple XServe front panel LEDs"
+ depends on PPC_PMAC
+ help
+ This driver procides some support to control the front panel
+ blue LEDs "vu-meter" of the XServer macs.
+
endmenu
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index b53d45f87b0b..2dfc3f4eaf42 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \
windfarm_smu_sensors.o \
windfarm_max6690_sensor.o \
windfarm_lm75_sensor.o windfarm_pid.o
+obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index be0bd34ff6f9..d43ea81d6df9 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -267,12 +267,12 @@ adb_probe_task(void *x)
}
static void
-__adb_probe_task(void *data)
+__adb_probe_task(struct work_struct *bullshit)
{
adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL);
}
-static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL);
+static DECLARE_WORK(adb_reset_work, __adb_probe_task);
int
adb_reset_bus(void)
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
new file mode 100644
index 000000000000..5ed41fe84e57
--- /dev/null
+++ b/drivers/macintosh/rack-meter.c
@@ -0,0 +1,616 @@
+/*
+ * RackMac vu-meter driver
+ *
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ * Support the CPU-meter LEDs of the Xserve G5
+ *
+ * TODO: Implement PWM to do variable intensity and provide userland
+ * interface for fun. Also, the CPU-meter could be made nicer by being
+ * a bit less "immediate" but giving instead a more average load over
+ * time. Patches welcome :-)
+ *
+ */
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+#include <asm/dbdma.h>
+#include <asm/macio.h>
+#include <asm/keylargo.h>
+
+/* Number of samples in a sample buffer */
+#define SAMPLE_COUNT 256
+
+/* CPU meter sampling rate in ms */
+#define CPU_SAMPLING_RATE 250
+
+struct rackmeter_dma {
+ struct dbdma_cmd cmd[4] ____cacheline_aligned;
+ u32 mark ____cacheline_aligned;
+ u32 buf1[SAMPLE_COUNT] ____cacheline_aligned;
+ u32 buf2[SAMPLE_COUNT] ____cacheline_aligned;
+} ____cacheline_aligned;
+
+struct rackmeter_cpu {
+ struct delayed_work sniffer;
+ struct rackmeter *rm;
+ cputime64_t prev_wall;
+ cputime64_t prev_idle;
+ int zero;
+} ____cacheline_aligned;
+
+struct rackmeter {
+ struct macio_dev *mdev;
+ unsigned int irq;
+ struct device_node *i2s;
+ u8 *ubuf;
+ struct dbdma_regs __iomem *dma_regs;
+ void __iomem *i2s_regs;
+ dma_addr_t dma_buf_p;
+ struct rackmeter_dma *dma_buf_v;
+ int stale_irq;
+ struct rackmeter_cpu cpu[2];
+ int paused;
+ struct mutex sem;
+};
+
+/* To be set as a tunable */
+static int rackmeter_ignore_nice;
+
+/* This GPIO is whacked by the OS X driver when initializing */
+#define RACKMETER_MAGIC_GPIO 0x78
+
+/* This is copied from cpufreq_ondemand, maybe we should put it in
+ * a common header somewhere
+ */
+static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
+{
+ cputime64_t retval;
+
+ retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
+ kstat_cpu(cpu).cpustat.iowait);
+
+ if (rackmeter_ignore_nice)
+ retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
+
+ return retval;
+}
+
+static void rackmeter_setup_i2s(struct rackmeter *rm)
+{
+ struct macio_chip *macio = rm->mdev->bus->chip;
+
+ /* First whack magic GPIO */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, RACKMETER_MAGIC_GPIO, 5);
+
+
+ /* Call feature code to enable the sound channel and the proper
+ * clock sources
+ */
+ pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, rm->i2s, 0, 1);
+
+ /* Power i2s and stop i2s clock. We whack MacIO FCRs directly for now.
+ * This is a bit racy, thus we should add new platform functions to
+ * handle that. snd-aoa needs that too
+ */
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
+ MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ udelay(10);
+
+ /* Then setup i2s. For now, we use the same magic value that
+ * the OS X driver seems to use. We might want to play around
+ * with the clock divisors later
+ */
+ out_le32(rm->i2s_regs + 0x10, 0x01fa0000);
+ (void)in_le32(rm->i2s_regs + 0x10);
+ udelay(10);
+
+ /* Fully restart i2s*/
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE |
+ KL1_I2S0_CLK_ENABLE_BIT);
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ udelay(10);
+}
+
+static void rackmeter_set_default_pattern(struct rackmeter *rm)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ if (i < 8)
+ rm->ubuf[i] = (i & 1) * 255;
+ else
+ rm->ubuf[i] = ((~i) & 1) * 255;
+ }
+}
+
+static void rackmeter_do_pause(struct rackmeter *rm, int pause)
+{
+ struct rackmeter_dma *rdma = rm->dma_buf_v;
+
+ pr_debug("rackmeter: %s\n", pause ? "paused" : "started");
+
+ rm->paused = pause;
+ if (pause) {
+ DBDMA_DO_STOP(rm->dma_regs);
+ return;
+ }
+ memset(rdma->buf1, 0, SAMPLE_COUNT & sizeof(u32));
+ memset(rdma->buf2, 0, SAMPLE_COUNT & sizeof(u32));
+
+ rm->dma_buf_v->mark = 0;
+
+ mb();
+ out_le32(&rm->dma_regs->cmdptr_hi, 0);
+ out_le32(&rm->dma_regs->cmdptr, rm->dma_buf_p);
+ out_le32(&rm->dma_regs->control, (RUN << 16) | RUN);
+}
+
+static void rackmeter_setup_dbdma(struct rackmeter *rm)
+{
+ struct rackmeter_dma *db = rm->dma_buf_v;
+ struct dbdma_cmd *cmd = db->cmd;
+
+ /* Make sure dbdma is reset */
+ DBDMA_DO_RESET(rm->dma_regs);
+
+ pr_debug("rackmeter: mark offset=0x%lx\n",
+ offsetof(struct rackmeter_dma, mark));
+ pr_debug("rackmeter: buf1 offset=0x%lx\n",
+ offsetof(struct rackmeter_dma, buf1));
+ pr_debug("rackmeter: buf2 offset=0x%lx\n",
+ offsetof(struct rackmeter_dma, buf2));
+
+ /* Prepare 4 dbdma commands for the 2 buffers */
+ memset(cmd, 0, 4 * sizeof(struct dbdma_cmd));
+ st_le16(&cmd->req_count, 4);
+ st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
+ st_le32(&cmd->phy_addr, rm->dma_buf_p +
+ offsetof(struct rackmeter_dma, mark));
+ st_le32(&cmd->cmd_dep, 0x02000000);
+ cmd++;
+
+ st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
+ st_le16(&cmd->command, OUTPUT_MORE);
+ st_le32(&cmd->phy_addr, rm->dma_buf_p +
+ offsetof(struct rackmeter_dma, buf1));
+ cmd++;
+
+ st_le16(&cmd->req_count, 4);
+ st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
+ st_le32(&cmd->phy_addr, rm->dma_buf_p +
+ offsetof(struct rackmeter_dma, mark));
+ st_le32(&cmd->cmd_dep, 0x01000000);
+ cmd++;
+
+ st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
+ st_le16(&cmd->command, OUTPUT_MORE | BR_ALWAYS);
+ st_le32(&cmd->phy_addr, rm->dma_buf_p +
+ offsetof(struct rackmeter_dma, buf2));
+ st_le32(&cmd->cmd_dep, rm->dma_buf_p);
+
+ rackmeter_do_pause(rm, 0);
+}
+
+static void rackmeter_do_timer(struct work_struct *work)
+{
+ struct rackmeter_cpu *rcpu =
+ container_of(work, struct rackmeter_cpu, sniffer.work);
+ struct rackmeter *rm = rcpu->rm;
+ unsigned int cpu = smp_processor_id();
+ cputime64_t cur_jiffies, total_idle_ticks;
+ unsigned int total_ticks, idle_ticks;
+ int i, offset, load, cumm, pause;
+
+ cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
+ total_ticks = (unsigned int)cputime64_sub(cur_jiffies,
+ rcpu->prev_wall);
+ rcpu->prev_wall = cur_jiffies;
+
+ total_idle_ticks = get_cpu_idle_time(cpu);
+ idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
+ rcpu->prev_idle);
+ rcpu->prev_idle = total_idle_ticks;
+
+ /* We do a very dumb calculation to update the LEDs for now,
+ * we'll do better once we have actual PWM implemented
+ */
+ load = (9 * (total_ticks - idle_ticks)) / total_ticks;
+
+ offset = cpu << 3;
+ cumm = 0;
+ for (i = 0; i < 8; i++) {
+ u8 ub = (load > i) ? 0xff : 0;
+ rm->ubuf[i + offset] = ub;
+ cumm |= ub;
+ }
+ rcpu->zero = (cumm == 0);
+
+ /* Now check if LEDs are all 0, we can stop DMA */
+ pause = (rm->cpu[0].zero && rm->cpu[1].zero);
+ if (pause != rm->paused) {
+ mutex_lock(&rm->sem);
+ pause = (rm->cpu[0].zero && rm->cpu[1].zero);
+ rackmeter_do_pause(rm, pause);
+ mutex_unlock(&rm->sem);
+ }
+ schedule_delayed_work_on(cpu, &rcpu->sniffer,
+ msecs_to_jiffies(CPU_SAMPLING_RATE));
+}
+
+static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
+{
+ unsigned int cpu;
+
+ /* This driver works only with 1 or 2 CPUs numbered 0 and 1,
+ * but that's really all we have on Apple Xserve. It doesn't
+ * play very nice with CPU hotplug neither but we don't do that
+ * on those machines yet
+ */
+
+ rm->cpu[0].rm = rm;
+ INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer);
+ rm->cpu[1].rm = rm;
+ INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer);
+
+ for_each_online_cpu(cpu) {
+ struct rackmeter_cpu *rcpu;
+
+ if (cpu > 1)
+ continue;
+ rcpu = &rm->cpu[cpu];;
+ rcpu->prev_idle = get_cpu_idle_time(cpu);
+ rcpu->prev_wall = jiffies64_to_cputime64(get_jiffies_64());
+ schedule_delayed_work_on(cpu, &rm->cpu[cpu].sniffer,
+ msecs_to_jiffies(CPU_SAMPLING_RATE));
+ }
+}
+
+static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
+{
+ cancel_rearming_delayed_work(&rm->cpu[0].sniffer);
+ cancel_rearming_delayed_work(&rm->cpu[1].sniffer);
+}
+
+static int rackmeter_setup(struct rackmeter *rm)
+{
+ pr_debug("rackmeter: setting up i2s..\n");
+ rackmeter_setup_i2s(rm);
+
+ pr_debug("rackmeter: setting up default pattern..\n");
+ rackmeter_set_default_pattern(rm);
+
+ pr_debug("rackmeter: setting up dbdma..\n");
+ rackmeter_setup_dbdma(rm);
+
+ pr_debug("rackmeter: start CPU measurements..\n");
+ rackmeter_init_cpu_sniffer(rm);
+
+ printk(KERN_INFO "RackMeter initialized\n");
+
+ return 0;
+}
+
+/* XXX FIXME: No PWM yet, this is 0/1 */
+static u32 rackmeter_calc_sample(struct rackmeter *rm, unsigned int index)
+{
+ int led;
+ u32 sample = 0;
+
+ for (led = 0; led < 16; led++) {
+ sample >>= 1;
+ sample |= ((rm->ubuf[led] >= 0x80) << 15);
+ }
+ return (sample << 17) | (sample >> 15);
+}
+
+static irqreturn_t rackmeter_irq(int irq, void *arg)
+{
+ struct rackmeter *rm = arg;
+ struct rackmeter_dma *db = rm->dma_buf_v;
+ unsigned int mark, i;
+ u32 *buf;
+
+ /* Flush PCI buffers with an MMIO read. Maybe we could actually
+ * check the status one day ... in case things go wrong, though
+ * this never happened to me
+ */
+ (void)in_le32(&rm->dma_regs->status);
+
+ /* Make sure the CPU gets us in order */
+ rmb();
+
+ /* Read mark */
+ mark = db->mark;
+ if (mark != 1 && mark != 2) {
+ printk(KERN_WARNING "rackmeter: Incorrect DMA mark 0x%08x\n",
+ mark);
+ /* We allow for 3 errors like that (stale DBDMA irqs) */
+ if (++rm->stale_irq > 3) {
+ printk(KERN_ERR "rackmeter: Too many errors,"
+ " stopping DMA\n");
+ DBDMA_DO_RESET(rm->dma_regs);
+ }
+ return IRQ_HANDLED;
+ }
+
+ /* Next buffer we need to fill is mark value */
+ buf = mark == 1 ? db->buf1 : db->buf2;
+
+ /* Fill it now. This routine converts the 8 bits depth sample array
+ * into the PWM bitmap for each LED.
+ */
+ for (i = 0; i < SAMPLE_COUNT; i++)
+ buf[i] = rackmeter_calc_sample(rm, i);
+
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit rackmeter_probe(struct macio_dev* mdev,
+ const struct of_device_id *match)
+{
+ struct device_node *i2s = NULL, *np = NULL;
+ struct rackmeter *rm = NULL;
+ struct resource ri2s, rdma;
+ int rc = -ENODEV;
+
+ pr_debug("rackmeter_probe()\n");
+
+ /* Get i2s-a node */
+ while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL)
+ if (strcmp(i2s->name, "i2s-a") == 0)
+ break;
+ if (i2s == NULL) {
+ pr_debug(" i2s-a child not found\n");
+ goto bail;
+ }
+ /* Get lightshow or virtual sound */
+ while ((np = of_get_next_child(i2s, np)) != NULL) {
+ if (strcmp(np->name, "lightshow") == 0)
+ break;
+ if ((strcmp(np->name, "sound") == 0) &&
+ get_property(np, "virtual", NULL) != NULL)
+ break;
+ }
+ if (np == NULL) {
+ pr_debug(" lightshow or sound+virtual child not found\n");
+ goto bail;
+ }
+
+ /* Create and initialize our instance data */
+ rm = kzalloc(sizeof(struct rackmeter), GFP_KERNEL);
+ if (rm == NULL) {
+ printk(KERN_ERR "rackmeter: failed to allocate memory !\n");
+ rc = -ENOMEM;
+ goto bail_release;
+ }
+ rm->mdev = mdev;
+ rm->i2s = i2s;
+ mutex_init(&rm->sem);
+ dev_set_drvdata(&mdev->ofdev.dev, rm);
+ /* Check resources availability. We need at least resource 0 and 1 */
+#if 0 /* Use that when i2s-a is finally an mdev per-se */
+ if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) {
+ printk(KERN_ERR
+ "rackmeter: found match but lacks resources: %s"
+ " (%d resources, %d interrupts)\n",
+ mdev->ofdev.node->full_name);
+ rc = -ENXIO;
+ goto bail_free;
+ }
+ if (macio_request_resources(mdev, "rackmeter")) {
+ printk(KERN_ERR
+ "rackmeter: failed to request resources: %s\n",
+ mdev->ofdev.node->full_name);
+ rc = -EBUSY;
+ goto bail_free;
+ }
+ rm->irq = macio_irq(mdev, 1);
+#else
+ rm->irq = irq_of_parse_and_map(i2s, 1);
+ if (rm->irq == NO_IRQ ||
+ of_address_to_resource(i2s, 0, &ri2s) ||
+ of_address_to_resource(i2s, 1, &rdma)) {
+ printk(KERN_ERR
+ "rackmeter: found match but lacks resources: %s",
+ mdev->ofdev.node->full_name);
+ rc = -ENXIO;
+ goto bail_free;
+ }
+#endif
+
+ pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start);
+ pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start);
+ pr_debug(" irq %d\n", rm->irq);
+
+ rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL);
+ if (rm->ubuf == NULL) {
+ printk(KERN_ERR
+ "rackmeter: failed to allocate samples page !\n");
+ rc = -ENOMEM;
+ goto bail_release;
+ }
+
+ rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev,
+ sizeof(struct rackmeter_dma),
+ &rm->dma_buf_p, GFP_KERNEL);
+ if (rm->dma_buf_v == NULL) {
+ printk(KERN_ERR
+ "rackmeter: failed to allocate dma buffer !\n");
+ rc = -ENOMEM;
+ goto bail_free_samples;
+ }
+#if 0
+ rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000);
+#else
+ rm->i2s_regs = ioremap(ri2s.start, 0x1000);
+#endif
+ if (rm->i2s_regs == NULL) {
+ printk(KERN_ERR
+ "rackmeter: failed to map i2s registers !\n");
+ rc = -ENXIO;
+ goto bail_free_dma;
+ }
+#if 0
+ rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100);
+#else
+ rm->dma_regs = ioremap(rdma.start, 0x100);
+#endif
+ if (rm->dma_regs == NULL) {
+ printk(KERN_ERR
+ "rackmeter: failed to map dma registers !\n");
+ rc = -ENXIO;
+ goto bail_unmap_i2s;
+ }
+
+ rc = rackmeter_setup(rm);
+ if (rc) {
+ printk(KERN_ERR
+ "rackmeter: failed to initialize !\n");
+ rc = -ENXIO;
+ goto bail_unmap_dma;
+ }
+
+ rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm);
+ if (rc != 0) {
+ printk(KERN_ERR
+ "rackmeter: failed to request interrupt !\n");
+ goto bail_stop_dma;
+ }
+ of_node_put(np);
+ return 0;
+
+ bail_stop_dma:
+ DBDMA_DO_RESET(rm->dma_regs);
+ bail_unmap_dma:
+ iounmap(rm->dma_regs);
+ bail_unmap_i2s:
+ iounmap(rm->i2s_regs);
+ bail_free_dma:
+ dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
+ sizeof(struct rackmeter_dma),
+ rm->dma_buf_v, rm->dma_buf_p);
+ bail_free_samples:
+ free_page((unsigned long)rm->ubuf);
+ bail_release:
+#if 0
+ macio_release_resources(mdev);
+#endif
+ bail_free:
+ kfree(rm);
+ bail:
+ of_node_put(i2s);
+ of_node_put(np);
+ dev_set_drvdata(&mdev->ofdev.dev, NULL);
+ return rc;
+}
+
+static int __devexit rackmeter_remove(struct macio_dev* mdev)
+{
+ struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
+
+ /* Stop CPU sniffer timer & work queues */
+ rackmeter_stop_cpu_sniffer(rm);
+
+ /* Clear reference to private data */
+ dev_set_drvdata(&mdev->ofdev.dev, NULL);
+
+ /* Stop/reset dbdma */
+ DBDMA_DO_RESET(rm->dma_regs);
+
+ /* Release the IRQ */
+ free_irq(rm->irq, rm);
+
+ /* Unmap registers */
+ iounmap(rm->dma_regs);
+ iounmap(rm->i2s_regs);
+
+ /* Free DMA */
+ dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
+ sizeof(struct rackmeter_dma),
+ rm->dma_buf_v, rm->dma_buf_p);
+
+ /* Free samples */
+ free_page((unsigned long)rm->ubuf);
+
+#if 0
+ /* Release resources */
+ macio_release_resources(mdev);
+#endif
+
+ /* Get rid of me */
+ kfree(rm);
+
+ return 0;
+}
+
+static int rackmeter_shutdown(struct macio_dev* mdev)
+{
+ struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
+
+ if (rm == NULL)
+ return -ENODEV;
+
+ /* Stop CPU sniffer timer & work queues */
+ rackmeter_stop_cpu_sniffer(rm);
+
+ /* Stop/reset dbdma */
+ DBDMA_DO_RESET(rm->dma_regs);
+
+ return 0;
+}
+
+static struct of_device_id rackmeter_match[] = {
+ { .name = "i2s" },
+ { }
+};
+
+static struct macio_driver rackmeter_drv = {
+ .name = "rackmeter",
+ .owner = THIS_MODULE,
+ .match_table = rackmeter_match,
+ .probe = rackmeter_probe,
+ .remove = rackmeter_remove,
+ .shutdown = rackmeter_shutdown,
+};
+
+
+static int __init rackmeter_init(void)
+{
+ pr_debug("rackmeter_init()\n");
+
+ return macio_register_driver(&rackmeter_drv);
+}
+
+static void __exit rackmeter_exit(void)
+{
+ pr_debug("rackmeter_exit()\n");
+
+ macio_unregister_driver(&rackmeter_drv);
+}
+
+module_init(rackmeter_init);
+module_exit(rackmeter_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("RackMeter: Support vu-meter on XServe front panel");
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index ade25b3fbb35..6dde27ab79a8 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -46,6 +46,7 @@
#include <asm/abs_addr.h>
#include <asm/uaccess.h>
#include <asm/of_device.h>
+#include <asm/of_platform.h>
#define VERSION "0.7"
#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
@@ -600,7 +601,7 @@ core_initcall(smu_late_init);
* sysfs visibility
*/
-static void smu_expose_childs(void *unused)
+static void smu_expose_childs(struct work_struct *unused)
{
struct device_node *np;
@@ -610,7 +611,7 @@ static void smu_expose_childs(void *unused)
&smu->of_dev->dev);
}
-static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL);
+static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs);
static int smu_platform_probe(struct of_device* dev,
const struct of_device_id *match)
@@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void)
* I'm a bit too far from figuring out how that works with those
* new chipsets, but that will come back and bite us
*/
- of_register_driver(&smu_of_platform_driver);
+ of_register_platform_driver(&smu_of_platform_driver);
return 0;
}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index a0f30d0853ea..13b953ae8ebc 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -30,7 +30,7 @@
#include <asm/io.h>
#include <asm/system.h>
#include <asm/sections.h>
-#include <asm/of_device.h>
+#include <asm/of_platform.h>
#undef DEBUG
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index d00c0c37a12e..2e4ad44a8636 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -129,6 +129,7 @@
#include <asm/sections.h>
#include <asm/of_device.h>
#include <asm/macio.h>
+#include <asm/of_platform.h>
#include "therm_pm72.h"
@@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void)
return -ENODEV;
}
- of_register_driver(&fcu_of_platform_driver);
+ of_register_platform_driver(&fcu_of_platform_driver);
return 0;
}
static void __exit therm_pm72_exit(void)
{
- of_unregister_driver(&fcu_of_platform_driver);
+ of_unregister_platform_driver(&fcu_of_platform_driver);
if (of_dev)
of_device_unregister(of_dev);
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 738faab1b22c..a1d3a987cb3a 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,12 +36,13 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/init.h>
+
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/sections.h>
-#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include <asm/macio.h>
#define LOG_TEMP 0 /* continously log temperature */
@@ -511,14 +512,14 @@ g4fan_init( void )
return -ENODEV;
}
- of_register_driver( &therm_of_driver );
+ of_register_platform_driver( &therm_of_driver );
return 0;
}
static void __exit
g4fan_exit( void )
{
- of_unregister_driver( &therm_of_driver );
+ of_unregister_platform_driver( &therm_of_driver );
if( x.of_dev )
of_device_unregister( x.of_dev );
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 08a40f4e4f60..ed2d4ef27fd8 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -458,11 +458,11 @@ static void dec_pending(struct crypt_io *io, int error)
* interrupt context.
*/
static struct workqueue_struct *_kcryptd_workqueue;
-static void kcryptd_do_work(void *data);
+static void kcryptd_do_work(struct work_struct *work);
static void kcryptd_queue_io(struct crypt_io *io)
{
- INIT_WORK(&io->work, kcryptd_do_work, io);
+ INIT_WORK(&io->work, kcryptd_do_work);
queue_work(_kcryptd_workqueue, &io->work);
}
@@ -618,9 +618,9 @@ static void process_read_endio(struct crypt_io *io)
dec_pending(io, crypt_convert(cc, &ctx));
}
-static void kcryptd_do_work(void *data)
+static void kcryptd_do_work(struct work_struct *work)
{
- struct crypt_io *io = data;
+ struct crypt_io *io = container_of(work, struct crypt_io, work);
if (io->post_process)
process_read_endio(io);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index d754e0bc6e90..e77ee6fd1044 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -104,8 +104,8 @@ typedef int (*action_fn) (struct pgpath *pgpath);
static kmem_cache_t *_mpio_cache;
struct workqueue_struct *kmultipathd;
-static void process_queued_ios(void *data);
-static void trigger_event(void *data);
+static void process_queued_ios(struct work_struct *work);
+static void trigger_event(struct work_struct *work);
/*-----------------------------------------------
@@ -173,8 +173,8 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
INIT_LIST_HEAD(&m->priority_groups);
spin_lock_init(&m->lock);
m->queue_io = 1;
- INIT_WORK(&m->process_queued_ios, process_queued_ios, m);
- INIT_WORK(&m->trigger_event, trigger_event, m);
+ INIT_WORK(&m->process_queued_ios, process_queued_ios);
+ INIT_WORK(&m->trigger_event, trigger_event);
m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
if (!m->mpio_pool) {
kfree(m);
@@ -379,9 +379,10 @@ static void dispatch_queued_ios(struct multipath *m)
}
}
-static void process_queued_ios(void *data)
+static void process_queued_ios(struct work_struct *work)
{
- struct multipath *m = (struct multipath *) data;
+ struct multipath *m =
+ container_of(work, struct multipath, process_queued_ios);
struct hw_handler *hwh = &m->hw_handler;
struct pgpath *pgpath = NULL;
unsigned init_required = 0, must_queue = 1;
@@ -421,9 +422,10 @@ out:
* An event is triggered whenever a path is taken out of use.
* Includes path failure and PG bypass.
*/
-static void trigger_event(void *data)
+static void trigger_event(struct work_struct *work)
{
- struct multipath *m = (struct multipath *) data;
+ struct multipath *m =
+ container_of(work, struct multipath, trigger_event);
dm_table_event(m->ti->table);
}
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 48a653b3f518..fc8cbb168e3e 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -883,7 +883,7 @@ static void do_mirror(struct mirror_set *ms)
do_writes(ms, &writes);
}
-static void do_work(void *ignored)
+static void do_work(struct work_struct *ignored)
{
struct mirror_set *ms;
@@ -1269,7 +1269,7 @@ static int __init dm_mirror_init(void)
dm_dirty_log_exit();
return r;
}
- INIT_WORK(&_kmirrord_work, do_work, NULL);
+ INIT_WORK(&_kmirrord_work, do_work);
r = dm_register_target(&mirror_target);
if (r < 0) {
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 5281e0094072..91c7aa1fed0e 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -40,7 +40,7 @@
#define SNAPSHOT_PAGES 256
struct workqueue_struct *ksnapd;
-static void flush_queued_bios(void *data);
+static void flush_queued_bios(struct work_struct *work);
struct pending_exception {
struct exception e;
@@ -528,7 +528,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
bio_list_init(&s->queued_bios);
- INIT_WORK(&s->queued_bios_work, flush_queued_bios, s);
+ INIT_WORK(&s->queued_bios_work, flush_queued_bios);
/* Add snapshot to the list of snapshots for this origin */
/* Exceptions aren't triggered till snapshot_resume() is called */
@@ -603,9 +603,10 @@ static void flush_bios(struct bio *bio)
}
}
-static void flush_queued_bios(void *data)
+static void flush_queued_bios(struct work_struct *work)
{
- struct dm_snapshot *s = (struct dm_snapshot *) data;
+ struct dm_snapshot *s =
+ container_of(work, struct dm_snapshot, queued_bios_work);
struct bio *queued_bios;
unsigned long flags;
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index f1db6eff4857..b3c01496c737 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -417,7 +417,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *))
/*
* kcopyd does this every time it's woken up.
*/
-static void do_work(void *ignored)
+static void do_work(struct work_struct *ignored)
{
/*
* The order that these are called is *very* important.
@@ -628,7 +628,7 @@ static int kcopyd_init(void)
}
kcopyd_clients++;
- INIT_WORK(&_kcopyd_work, do_work, NULL);
+ INIT_WORK(&_kcopyd_work, do_work);
mutex_unlock(&kcopyd_init_lock);
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 06893243f3d4..6e166801505d 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -63,7 +63,7 @@ struct flexcop_pci {
unsigned long last_irq;
- struct work_struct irq_check_work;
+ struct delayed_work irq_check_work;
struct flexcop_device *fc_dev;
};
@@ -97,9 +97,10 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi
return 0;
}
-static void flexcop_pci_irq_check_work(void *data)
+static void flexcop_pci_irq_check_work(struct work_struct *work)
{
- struct flexcop_pci *fc_pci = data;
+ struct flexcop_pci *fc_pci =
+ container_of(work, struct flexcop_pci, irq_check_work.work);
struct flexcop_device *fc = fc_pci->fc_dev;
flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
@@ -371,7 +372,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
- INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
+ INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
return ret;
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 55bc891768c2..206c13e47a06 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -30,6 +30,7 @@
#include <linux/input.h>
#include <linux/dvb/frontend.h>
#include <linux/mutex.h>
+#include <linux/mm.h>
#include "dmxdev.h"
#include "dvb_demux.h"
@@ -127,7 +128,7 @@ struct cinergyt2 {
struct dvbt_set_parameters_msg param;
struct dvbt_get_status_msg status;
- struct work_struct query_work;
+ struct delayed_work query_work;
wait_queue_head_t poll_wq;
int pending_fe_events;
@@ -141,7 +142,7 @@ struct cinergyt2 {
#ifdef ENABLE_RC
struct input_dev *rc_input_dev;
char phys[64];
- struct work_struct rc_query_work;
+ struct delayed_work rc_query_work;
int rc_input_event;
u32 rc_last_code;
unsigned long last_event_jiffies;
@@ -722,9 +723,10 @@ static struct dvb_device cinergyt2_fe_template = {
#ifdef ENABLE_RC
-static void cinergyt2_query_rc (void *data)
+static void cinergyt2_query_rc (struct work_struct *work)
{
- struct cinergyt2 *cinergyt2 = data;
+ struct cinergyt2 *cinergyt2 =
+ container_of(work, struct cinergyt2, rc_query_work.work);
char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
struct cinergyt2_rc_event rc_events[12];
int n, len, i;
@@ -805,7 +807,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
cinergyt2->rc_input_event = KEY_MAX;
cinergyt2->rc_last_code = ~0;
- INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+ INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc);
input_dev->name = DRIVER_NAME " remote control";
input_dev->phys = cinergyt2->phys;
@@ -846,9 +848,10 @@ static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
#endif /* ENABLE_RC */
-static void cinergyt2_query (void *data)
+static void cinergyt2_query (struct work_struct *work)
{
- struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
+ struct cinergyt2 *cinergyt2 =
+ container_of(work, struct cinergyt2, query_work.work);
char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS };
struct dvbt_get_status_msg *s = &cinergyt2->status;
uint8_t lock_bits;
@@ -892,7 +895,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
mutex_init(&cinergyt2->sem);
init_waitqueue_head (&cinergyt2->poll_wq);
- INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
+ INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query);
cinergyt2->udev = interface_to_usbdev(intf);
cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 8859ab74f0fe..ebf4dc5190f6 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -127,6 +127,7 @@ struct dvb_net_priv {
int in_use;
struct net_device_stats stats;
u16 pid;
+ struct net_device *net;
struct dvb_net *host;
struct dmx_demux *demux;
struct dmx_section_feed *secfeed;
@@ -1123,10 +1124,11 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
}
-static void wq_set_multicast_list (void *data)
+static void wq_set_multicast_list (struct work_struct *work)
{
- struct net_device *dev = data;
- struct dvb_net_priv *priv = dev->priv;
+ struct dvb_net_priv *priv =
+ container_of(work, struct dvb_net_priv, set_multicast_list_wq);
+ struct net_device *dev = priv->net;
dvb_net_feed_stop(dev);
priv->rx_mode = RX_MODE_UNI;
@@ -1167,9 +1169,11 @@ static void dvb_net_set_multicast_list (struct net_device *dev)
}
-static void wq_restart_net_feed (void *data)
+static void wq_restart_net_feed (struct work_struct *work)
{
- struct net_device *dev = data;
+ struct dvb_net_priv *priv =
+ container_of(work, struct dvb_net_priv, restart_net_feed_wq);
+ struct net_device *dev = priv->net;
if (netif_running(dev)) {
dvb_net_feed_stop(dev);
@@ -1276,6 +1280,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
dvbnet->device[if_num] = net;
priv = net->priv;
+ priv->net = net;
priv->demux = dvbnet->demux;
priv->pid = pid;
priv->rx_mode = RX_MODE_UNI;
@@ -1284,8 +1289,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
priv->feedtype = feedtype;
reset_ule(priv);
- INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
- INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
+ INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list);
+ INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed);
mutex_init(&priv->mutex);
net->base_addr = pid;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 0a3a0b6c2350..794e4471561c 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -13,9 +13,10 @@
*
* TODO: Fix the repeat rate of the input device.
*/
-static void dvb_usb_read_remote_control(void *data)
+static void dvb_usb_read_remote_control(struct work_struct *work)
{
- struct dvb_usb_device *d = data;
+ struct dvb_usb_device *d =
+ container_of(work, struct dvb_usb_device, rc_query_work.work);
u32 event;
int state;
@@ -128,7 +129,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
input_register_device(d->rc_input_dev);
- INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
+ INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
info("schedule remote query interval to %d msecs.", d->props.rc_interval);
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 376c45a8e779..0d721731a524 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -369,7 +369,7 @@ struct dvb_usb_device {
/* remote control */
struct input_dev *rc_input_dev;
char rc_phys[64];
- struct work_struct rc_query_work;
+ struct delayed_work rc_query_work;
u32 last_event;
int last_state;
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 41f4b8d17559..b12cec94f4cc 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -82,6 +82,8 @@ struct pp_cam_entry {
struct pardevice *pdev;
struct parport *port;
struct work_struct cb_task;
+ void (*cb_func)(void *cbdata);
+ void *cb_data;
int open_count;
wait_queue_head_t wq_stream;
/* image state flags */
@@ -130,6 +132,20 @@ static void cpia_parport_disable_irq( struct parport *port ) {
#define PARPORT_CHUNK_SIZE PAGE_SIZE
+static void cpia_pp_run_callback(struct work_struct *work)
+{
+ void (*cb_func)(void *cbdata);
+ void *cb_data;
+ struct pp_cam_entry *cam;
+
+ cam = container_of(work, struct pp_cam_entry, cb_task);
+ cb_func = cam->cb_func;
+ cb_data = cam->cb_data;
+ work_release(work);
+
+ cb_func(cb_data);
+}
+
/****************************************************************************
*
* CPiA-specific low-level parport functions for nibble uploads
@@ -664,7 +680,9 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo
int retval = 0;
if(cam->port->irq != PARPORT_IRQ_NONE) {
- INIT_WORK(&cam->cb_task, cb, cbdata);
+ cam->cb_func = cb;
+ cam->cb_data = cbdata;
+ INIT_WORK_NAR(&cam->cb_task, cpia_pp_run_callback);
} else {
retval = -1;
}
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 57e1c024a547..e60a0a52e4b2 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -145,9 +145,9 @@ static void ir_timer(unsigned long data)
schedule_work(&ir->work);
}
-static void cx88_ir_work(void *data)
+static void cx88_ir_work(struct work_struct *work)
{
- struct cx88_IR *ir = data;
+ struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
unsigned long timeout;
cx88_ir_handle_key(ir);
@@ -308,7 +308,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
core->ir = ir;
if (ir->polling) {
- INIT_WORK(&ir->work, cx88_ir_work, ir);
+ INIT_WORK(&ir->work, cx88_ir_work);
init_timer(&ir->timer);
ir->timer.function = ir_timer;
ir->timer.data = (unsigned long)ir;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 1457b1602221..ab87e7bfe84f 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -268,9 +268,9 @@ static void ir_timer(unsigned long data)
schedule_work(&ir->work);
}
-static void ir_work(void *data)
+static void ir_work(struct work_struct *work)
{
- struct IR_i2c *ir = data;
+ struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
ir_key_poll(ir);
mod_timer(&ir->timer, jiffies+HZ/10);
}
@@ -400,7 +400,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir->input->name,ir->input->phys,adap->name);
/* start polling via eventd */
- INIT_WORK(&ir->work, ir_work, ir);
+ INIT_WORK(&ir->work, ir_work);
init_timer(&ir->timer);
ir->timer.function = ir_timer;
ir->timer.data = (unsigned long)ir;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
index f129f316d20e..cf129746205d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -45,16 +45,21 @@ static void pvr2_context_trigger_poll(struct pvr2_context *mp)
}
-static void pvr2_context_poll(struct pvr2_context *mp)
+static void pvr2_context_poll(struct work_struct *work)
{
+ struct pvr2_context *mp =
+ container_of(work, struct pvr2_context, workpoll);
pvr2_context_enter(mp); do {
pvr2_hdw_poll(mp->hdw);
} while (0); pvr2_context_exit(mp);
}
-static void pvr2_context_setup(struct pvr2_context *mp)
+static void pvr2_context_setup(struct work_struct *work)
{
+ struct pvr2_context *mp =
+ container_of(work, struct pvr2_context, workinit);
+
pvr2_context_enter(mp); do {
if (!pvr2_hdw_dev_ok(mp->hdw)) break;
pvr2_hdw_setup(mp->hdw);
@@ -92,8 +97,8 @@ struct pvr2_context *pvr2_context_create(
}
mp->workqueue = create_singlethread_workqueue("pvrusb2");
- INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp);
- INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp);
+ INIT_WORK(&mp->workinit, pvr2_context_setup);
+ INIT_WORK(&mp->workpoll, pvr2_context_poll);
queue_work(mp->workqueue,&mp->workinit);
done:
return mp;
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 7b9859c33018..92eabf88a09b 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -324,9 +324,9 @@ static void saa6588_timer(unsigned long data)
schedule_work(&s->work);
}
-static void saa6588_work(void *data)
+static void saa6588_work(struct work_struct *work)
{
- struct saa6588 *s = (struct saa6588 *)data;
+ struct saa6588 *s = container_of(work, struct saa6588, work);
saa6588_i2c_poll(s);
mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
@@ -419,7 +419,7 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
saa6588_configure(s);
/* start polling via eventd */
- INIT_WORK(&s->work, saa6588_work, s);
+ INIT_WORK(&s->work, saa6588_work);
init_timer(&s->timer);
s->timer.function = saa6588_timer;
s->timer.data = (unsigned long)s;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 65d044086ce9..daaae870a2c4 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -343,9 +343,10 @@ static struct video_device saa7134_empress_template =
.minor = -1,
};
-static void empress_signal_update(void* data)
+static void empress_signal_update(struct work_struct *work)
{
- struct saa7134_dev* dev = (struct saa7134_dev*) data;
+ struct saa7134_dev* dev =
+ container_of(work, struct saa7134_dev, empress_workqueue);
if (dev->nosignal) {
dprintk("no video signal\n");
@@ -378,7 +379,7 @@ static int empress_init(struct saa7134_dev *dev)
"%s empress (%s)", dev->name,
saa7134_boards[dev->board].name);
- INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
+ INIT_WORK(&dev->empress_workqueue, empress_signal_update);
err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
empress_nr[dev->nr]);
@@ -399,7 +400,7 @@ static int empress_init(struct saa7134_dev *dev)
sizeof(struct saa7134_buf),
dev);
- empress_signal_update(dev);
+ empress_signal_update(&dev->empress_workqueue);
return 0;
}
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 1dd491773150..ef2b55e19910 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1018,9 +1018,10 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
}
static void
-mptfc_setup_reset(void *arg)
+mptfc_setup_reset(struct work_struct *work)
{
- MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+ MPT_ADAPTER *ioc =
+ container_of(work, MPT_ADAPTER, fc_setup_reset_work);
u64 pn;
struct mptfc_rport_info *ri;
@@ -1043,9 +1044,10 @@ mptfc_setup_reset(void *arg)
}
static void
-mptfc_rescan_devices(void *arg)
+mptfc_rescan_devices(struct work_struct *work)
{
- MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+ MPT_ADAPTER *ioc =
+ container_of(work, MPT_ADAPTER, fc_rescan_work);
int ii;
u64 pn;
struct mptfc_rport_info *ri;
@@ -1154,8 +1156,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
spin_lock_init(&ioc->fc_rescan_work_lock);
- INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
- INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc);
+ INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
+ INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
spin_lock_irqsave(&ioc->FreeQlock, flags);
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 314c3a27585d..b7c4407c5e3f 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -111,7 +111,8 @@ struct mpt_lan_priv {
u32 total_received;
struct net_device_stats stats; /* Per device statistics */
- struct work_struct post_buckets_task;
+ struct delayed_work post_buckets_task;
+ struct net_device *dev;
unsigned long post_buckets_active;
};
@@ -132,7 +133,7 @@ static int lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
static int mpt_lan_open(struct net_device *dev);
static int mpt_lan_reset(struct net_device *dev);
static int mpt_lan_close(struct net_device *dev);
-static void mpt_lan_post_receive_buckets(void *dev_id);
+static void mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv);
static void mpt_lan_wake_post_buckets_task(struct net_device *dev,
int priority);
static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg);
@@ -345,7 +346,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
} else {
- mpt_lan_post_receive_buckets(dev);
+ mpt_lan_post_receive_buckets(priv);
netif_wake_queue(dev);
}
@@ -441,7 +442,7 @@ mpt_lan_open(struct net_device *dev)
dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
- mpt_lan_post_receive_buckets(dev);
+ mpt_lan_post_receive_buckets(priv);
printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n",
IOC_AND_NETDEV_NAMES_s_s(dev));
@@ -854,7 +855,7 @@ mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
if (priority) {
- schedule_work(&priv->post_buckets_task);
+ schedule_delayed_work(&priv->post_buckets_task, 0);
} else {
schedule_delayed_work(&priv->post_buckets_task, 1);
dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
@@ -1188,10 +1189,9 @@ mpt_lan_receive_post_reply(struct net_device *dev,
/* Simple SGE's only at the moment */
static void
-mpt_lan_post_receive_buckets(void *dev_id)
+mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
{
- struct net_device *dev = dev_id;
- struct mpt_lan_priv *priv = dev->priv;
+ struct net_device *dev = priv->dev;
MPT_ADAPTER *mpt_dev = priv->mpt_dev;
MPT_FRAME_HDR *mf;
LANReceivePostRequest_t *pRecvReq;
@@ -1335,6 +1335,13 @@ out:
clear_bit(0, &priv->post_buckets_active);
}
+static void
+mpt_lan_post_receive_buckets_work(struct work_struct *work)
+{
+ mpt_lan_post_receive_buckets(container_of(work, struct mpt_lan_priv,
+ post_buckets_task.work));
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static struct net_device *
mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
@@ -1350,11 +1357,13 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
priv = netdev_priv(dev);
+ priv->dev = dev;
priv->mpt_dev = mpt_dev;
priv->pnum = pnum;
- memset(&priv->post_buckets_task, 0, sizeof(struct work_struct));
- INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
+ memset(&priv->post_buckets_task, 0, sizeof(priv->post_buckets_task));
+ INIT_DELAYED_WORK(&priv->post_buckets_task,
+ mpt_lan_post_receive_buckets_work);
priv->post_buckets_active = 0;
dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index b752a479f6db..4f0c530e47b0 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2006,9 +2006,10 @@ __mptsas_discovery_work(MPT_ADAPTER *ioc)
*(Mutex LOCKED)
*/
static void
-mptsas_discovery_work(void * arg)
+mptsas_discovery_work(struct work_struct *work)
{
- struct mptsas_discovery_event *ev = arg;
+ struct mptsas_discovery_event *ev =
+ container_of(work, struct mptsas_discovery_event, work);
MPT_ADAPTER *ioc = ev->ioc;
mutex_lock(&ioc->sas_discovery_mutex);
@@ -2068,9 +2069,9 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
* Work queue thread to clear the persitency table
*/
static void
-mptsas_persist_clear_table(void * arg)
+mptsas_persist_clear_table(struct work_struct *work)
{
- MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+ MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
}
@@ -2093,9 +2094,10 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
* Work queue thread to handle SAS hotplug events
*/
static void
-mptsas_hotplug_work(void *arg)
+mptsas_hotplug_work(struct work_struct *work)
{
- struct mptsas_hotplug_event *ev = arg;
+ struct mptsas_hotplug_event *ev =
+ container_of(work, struct mptsas_hotplug_event, work);
MPT_ADAPTER *ioc = ev->ioc;
struct mptsas_phyinfo *phy_info;
struct sas_rphy *rphy;
@@ -2341,7 +2343,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
break;
}
- INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
+ INIT_WORK(&ev->work, mptsas_hotplug_work);
ev->ioc = ioc;
ev->handle = le16_to_cpu(sas_event_data->DevHandle);
ev->parent_handle =
@@ -2366,7 +2368,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
* Persistent table is full.
*/
INIT_WORK(&ioc->sas_persist_task,
- mptsas_persist_clear_table, (void *)ioc);
+ mptsas_persist_clear_table);
schedule_work(&ioc->sas_persist_task);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
@@ -2395,7 +2397,7 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc,
return;
}
- INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
+ INIT_WORK(&ev->work, mptsas_hotplug_work);
ev->ioc = ioc;
ev->id = raid_event_data->VolumeID;
ev->event_type = MPTSAS_IGNORE_EVENT;
@@ -2474,7 +2476,7 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc,
ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev)
return;
- INIT_WORK(&ev->work, mptsas_discovery_work, ev);
+ INIT_WORK(&ev->work, mptsas_discovery_work);
ev->ioc = ioc;
schedule_work(&ev->work);
};
@@ -2511,8 +2513,7 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
break;
case MPI_EVENT_PERSISTENT_TABLE_FULL:
INIT_WORK(&ioc->sas_persist_task,
- mptsas_persist_clear_table,
- (void *)ioc);
+ mptsas_persist_clear_table);
schedule_work(&ioc->sas_persist_task);
break;
case MPI_EVENT_SAS_DISCOVERY:
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index e4cc3dd5fc9f..f422c0d0621c 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -646,9 +646,10 @@ struct work_queue_wrapper {
int disk;
};
-static void mpt_work_wrapper(void *data)
+static void mpt_work_wrapper(struct work_struct *work)
{
- struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+ struct work_queue_wrapper *wqw =
+ container_of(work, struct work_queue_wrapper, work);
struct _MPT_SCSI_HOST *hd = wqw->hd;
struct Scsi_Host *shost = hd->ioc->sh;
struct scsi_device *sdev;
@@ -695,7 +696,7 @@ static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
disk);
return;
}
- INIT_WORK(&wqw->work, mpt_work_wrapper, wqw);
+ INIT_WORK(&wqw->work, mpt_work_wrapper);
wqw->hd = hd;
wqw->disk = disk;
@@ -784,9 +785,10 @@ MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
* renegotiate for a given target
*/
static void
-mptspi_dv_renegotiate_work(void *data)
+mptspi_dv_renegotiate_work(struct work_struct *work)
{
- struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+ struct work_queue_wrapper *wqw =
+ container_of(work, struct work_queue_wrapper, work);
struct _MPT_SCSI_HOST *hd = wqw->hd;
struct scsi_device *sdev;
@@ -804,7 +806,7 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
if (!wqw)
return;
- INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw);
+ INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work);
wqw->hd = hd;
schedule_work(&wqw->work);
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 64130227574f..7fc7399bd2ec 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -232,7 +232,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
break;
}
- INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
+ INIT_WORK(&evt->work, drv->event);
queue_work(drv->event_queue, &evt->work);
return 1;
}
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index a2350640384b..9e529d8dd5cb 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -371,8 +371,10 @@ static int i2o_exec_remove(struct device *dev)
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
* again, otherwise send LCT NOTIFY to get informed on next LCT change.
*/
-static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work)
+static void i2o_exec_lct_modified(struct work_struct *_work)
{
+ struct i2o_exec_lct_notify_work *work =
+ container_of(_work, struct i2o_exec_lct_notify_work, work);
u32 change_ind = 0;
struct i2o_controller *c = work->c;
@@ -439,8 +441,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
work->c = c;
- INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified,
- work);
+ INIT_WORK(&work->work, i2o_exec_lct_modified);
queue_work(i2o_exec_driver.event_queue, &work->work);
return 1;
}
@@ -460,13 +461,15 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
/**
* i2o_exec_event - Event handling function
- * @evt: Event which occurs
+ * @work: Work item in occurring event
*
* Handles events send by the Executive device. At the moment does not do
* anything useful.
*/
-static void i2o_exec_event(struct i2o_event *evt)
+static void i2o_exec_event(struct work_struct *work)
{
+ struct i2o_event *evt = container_of(work, struct i2o_event, work);
+
if (likely(evt->i2o_dev))
osm_debug("Event received from device: %d\n",
evt->i2o_dev->lct_data.tid);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index eaba81bf2eca..70ae00253321 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -419,16 +419,18 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
/**
* i2o_block_delayed_request_fn - delayed request queue function
- * delayed_request: the delayed request with the queue to start
+ * @work: the delayed request with the queue to start
*
* If the request queue is stopped for a disk, and there is no open
* request, a new event is created, which calls this function to start
* the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never
* be started again.
*/
-static void i2o_block_delayed_request_fn(void *delayed_request)
+static void i2o_block_delayed_request_fn(struct work_struct *work)
{
- struct i2o_block_delayed_request *dreq = delayed_request;
+ struct i2o_block_delayed_request *dreq =
+ container_of(work, struct i2o_block_delayed_request,
+ work.work);
struct request_queue *q = dreq->queue;
unsigned long flags;
@@ -538,8 +540,9 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
return 1;
};
-static void i2o_block_event(struct i2o_event *evt)
+static void i2o_block_event(struct work_struct *work)
{
+ struct i2o_event *evt = container_of(work, struct i2o_event, work);
osm_debug("event received\n");
kfree(evt);
};
@@ -938,8 +941,8 @@ static void i2o_block_request_fn(struct request_queue *q)
continue;
dreq->queue = q;
- INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
- dreq);
+ INIT_DELAYED_WORK(&dreq->work,
+ i2o_block_delayed_request_fn);
if (!queue_delayed_work(i2o_block_driver.event_queue,
&dreq->work,
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
index 4fdaa5bda412..d9fdc95b440d 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/message/i2o/i2o_block.h
@@ -96,7 +96,7 @@ struct i2o_block_request {
/* I2O Block device delayed request */
struct i2o_block_delayed_request {
- struct work_struct work;
+ struct delayed_work work;
struct request_queue *queue;
};
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index 1ba8754e9383..2ab7add78f94 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -33,9 +33,10 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
spin_unlock_irqrestore(&fm->lock, flags);
}
-static void tifm_7xx1_remove_media(void *adapter)
+static void tifm_7xx1_remove_media(struct work_struct *work)
{
- struct tifm_adapter *fm = adapter;
+ struct tifm_adapter *fm =
+ container_of(work, struct tifm_adapter, media_remover);
unsigned long flags;
int cnt;
struct tifm_dev *sock;
@@ -169,9 +170,10 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
return base_addr + ((sock_num + 1) << 10);
}
-static void tifm_7xx1_insert_media(void *adapter)
+static void tifm_7xx1_insert_media(struct work_struct *work)
{
- struct tifm_adapter *fm = adapter;
+ struct tifm_adapter *fm =
+ container_of(work, struct tifm_adapter, media_inserter);
unsigned long flags;
tifm_media_id media_id;
char *card_name = "xx";
@@ -261,7 +263,7 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
spin_unlock_irqrestore(&fm->lock, flags);
flush_workqueue(fm->wq);
- tifm_7xx1_remove_media(fm);
+ tifm_7xx1_remove_media(&fm->media_remover);
pci_set_power_state(dev, PCI_D3hot);
pci_disable_device(dev);
@@ -328,8 +330,8 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
if (!fm->sockets)
goto err_out_free;
- INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm);
- INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm);
+ INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media);
+ INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media);
fm->eject = tifm_7xx1_eject;
pci_set_drvdata(dev, fm);
@@ -384,7 +386,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
flush_workqueue(fm->wq);
- tifm_7xx1_remove_media(fm);
+ tifm_7xx1_remove_media(&fm->media_remover);
writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
free_irq(dev->irq, fm);
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index ea41852ec8cd..f4f8ccaf5455 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -40,7 +40,7 @@ config MMC_ARMMMCI
If unsure, say N.
config MMC_PXA
- tristate "Intel PXA255 Multimedia Card Interface support"
+ tristate "Intel PXA25x/26x/27x Multimedia Card Interface support"
depends on ARCH_PXA && MMC
help
This selects the Intel(R) PXA(R) Multimedia card Interface.
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index 494b23fb0a01..6495cd8a9306 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -793,7 +793,7 @@ int at91_mci_get_ro(struct mmc_host *mmc)
return read_only;
}
-static struct mmc_host_ops at91_mci_ops = {
+static const struct mmc_host_ops at91_mci_ops = {
.request = at91_mci_request,
.set_ios = at91_mci_set_ios,
.get_ro = at91_mci_get_ro,
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 53ffcbb14a97..447fba5825fd 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -875,7 +875,7 @@ static void au1xmmc_init_dma(struct au1xmmc_host *host)
host->rx_chan = rxchan;
}
-struct mmc_host_ops au1xmmc_ops = {
+struct const mmc_host_ops au1xmmc_ops = {
.request = au1xmmc_request,
.set_ios = au1xmmc_set_ios,
};
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index 659d4a822cc5..06e7fcd19221 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -877,7 +877,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
}
}
-static struct mmc_host_ops imxmci_ops = {
+static const struct mmc_host_ops imxmci_ops = {
.request = imxmci_request,
.set_ios = imxmci_set_ios,
};
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 766bc54406e5..6f2a282e2b97 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -4,6 +4,7 @@
* Copyright (C) 2003-2004 Russell King, All Rights Reserved.
* SD support Copyright (C) 2004 Ian Molton, All Rights Reserved.
* SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved.
+ * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
*
* 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
@@ -396,23 +397,23 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
return err;
/*
- * Default bus width is 1 bit.
- */
- host->ios.bus_width = MMC_BUS_WIDTH_1;
-
- /*
- * We can only change the bus width of the selected
- * card so therefore we have to put the handling
+ * We can only change the bus width of SD cards when
+ * they are selected so we have to put the handling
* here.
+ *
+ * The card is in 1 bit mode by default so
+ * we only need to change if it supports the
+ * wider version.
*/
- if (host->caps & MMC_CAP_4_BIT_DATA) {
+ if (mmc_card_sd(card) &&
+ (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+
/*
- * The card is in 1 bit mode by default so
- * we only need to change if it supports the
- * wider version.
- */
- if (mmc_card_sd(card) &&
- (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+ * Default bus width is 1 bit.
+ */
+ host->ios.bus_width = MMC_BUS_WIDTH_1;
+
+ if (host->caps & MMC_CAP_4_BIT_DATA) {
struct mmc_command cmd;
cmd.opcode = SD_APP_SET_BUS_WIDTH;
cmd.arg = SD_BUS_WIDTH_4;
@@ -453,11 +454,11 @@ static void mmc_deselect_cards(struct mmc_host *host)
static inline void mmc_delay(unsigned int ms)
{
- if (ms < HZ / 1000) {
- yield();
+ if (ms < 1000 / HZ) {
+ cond_resched();
mdelay(ms);
} else {
- msleep_interruptible (ms);
+ msleep(ms);
}
}
@@ -953,6 +954,137 @@ static void mmc_read_csds(struct mmc_host *host)
}
}
+static void mmc_process_ext_csds(struct mmc_host *host)
+{
+ int err;
+ struct mmc_card *card;
+
+ struct mmc_request mrq;
+ struct mmc_command cmd;
+ struct mmc_data data;
+
+ struct scatterlist sg;
+
+ /*
+ * As the ext_csd is so large and mostly unused, we don't store the
+ * raw block in mmc_card.
+ */
+ u8 *ext_csd;
+ ext_csd = kmalloc(512, GFP_KERNEL);
+ if (!ext_csd) {
+ printk("%s: could not allocate a buffer to receive the ext_csd."
+ "mmc v4 cards will be treated as v3.\n",
+ mmc_hostname(host));
+ return;
+ }
+
+ list_for_each_entry(card, &host->cards, node) {
+ if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
+ continue;
+ if (mmc_card_sd(card))
+ continue;
+ if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
+ continue;
+
+ err = mmc_select_card(host, card);
+ if (err != MMC_ERR_NONE) {
+ mmc_card_set_dead(card);
+ continue;
+ }
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+
+ cmd.opcode = MMC_SEND_EXT_CSD;
+ cmd.arg = 0;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ memset(&data, 0, sizeof(struct mmc_data));
+
+ mmc_set_data_timeout(&data, card, 0);
+
+ data.blksz = 512;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+ data.sg = &sg;
+ data.sg_len = 1;
+
+ memset(&mrq, 0, sizeof(struct mmc_request));
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ sg_init_one(&sg, ext_csd, 512);
+
+ mmc_wait_for_req(host, &mrq);
+
+ if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+ mmc_card_set_dead(card);
+ continue;
+ }
+
+ switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+ case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ break;
+ case EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 26000000;
+ break;
+ default:
+ /* MMC v4 spec says this cannot happen */
+ printk("%s: card is mmc v4 but doesn't support "
+ "any high-speed modes.\n",
+ mmc_hostname(card->host));
+ mmc_card_set_bad(card);
+ continue;
+ }
+
+ /* Activate highspeed support. */
+ cmd.opcode = MMC_SWITCH;
+ cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_HS_TIMING << 16) |
+ (1 << 8) |
+ EXT_CSD_CMD_SET_NORMAL;
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+
+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+ if (err != MMC_ERR_NONE) {
+ printk("%s: failed to switch card to mmc v4 "
+ "high-speed mode.\n",
+ mmc_hostname(card->host));
+ continue;
+ }
+
+ mmc_card_set_highspeed(card);
+
+ /* Check for host support for wide-bus modes. */
+ if (!(host->caps & MMC_CAP_4_BIT_DATA)) {
+ continue;
+ }
+
+ /* Activate 4-bit support. */
+ cmd.opcode = MMC_SWITCH;
+ cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_BUS_WIDTH << 16) |
+ (EXT_CSD_BUS_WIDTH_4 << 8) |
+ EXT_CSD_CMD_SET_NORMAL;
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+
+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+ if (err != MMC_ERR_NONE) {
+ printk("%s: failed to switch card to "
+ "mmc v4 4-bit bus mode.\n",
+ mmc_hostname(card->host));
+ continue;
+ }
+
+ host->ios.bus_width = MMC_BUS_WIDTH_4;
+ }
+
+ kfree(ext_csd);
+
+ mmc_deselect_cards(host);
+}
+
static void mmc_read_scrs(struct mmc_host *host)
{
int err;
@@ -1025,14 +1157,133 @@ static void mmc_read_scrs(struct mmc_host *host)
mmc_deselect_cards(host);
}
+static void mmc_read_switch_caps(struct mmc_host *host)
+{
+ int err;
+ struct mmc_card *card;
+ struct mmc_request mrq;
+ struct mmc_command cmd;
+ struct mmc_data data;
+ unsigned char *status;
+ struct scatterlist sg;
+
+ status = kmalloc(64, GFP_KERNEL);
+ if (!status) {
+ printk(KERN_WARNING "%s: Unable to allocate buffer for "
+ "reading switch capabilities.\n",
+ mmc_hostname(host));
+ return;
+ }
+
+ list_for_each_entry(card, &host->cards, node) {
+ if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
+ continue;
+ if (!mmc_card_sd(card))
+ continue;
+ if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+ continue;
+
+ err = mmc_select_card(host, card);
+ if (err != MMC_ERR_NONE) {
+ mmc_card_set_dead(card);
+ continue;
+ }
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+
+ cmd.opcode = SD_SWITCH;
+ cmd.arg = 0x00FFFFF1;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ memset(&data, 0, sizeof(struct mmc_data));
+
+ mmc_set_data_timeout(&data, card, 0);
+
+ data.blksz = 64;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+ data.sg = &sg;
+ data.sg_len = 1;
+
+ memset(&mrq, 0, sizeof(struct mmc_request));
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ sg_init_one(&sg, status, 64);
+
+ mmc_wait_for_req(host, &mrq);
+
+ if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+ mmc_card_set_dead(card);
+ continue;
+ }
+
+ if (status[13] & 0x02)
+ card->sw_caps.hs_max_dtr = 50000000;
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+
+ cmd.opcode = SD_SWITCH;
+ cmd.arg = 0x80FFFFF1;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ memset(&data, 0, sizeof(struct mmc_data));
+
+ mmc_set_data_timeout(&data, card, 0);
+
+ data.blksz = 64;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+ data.sg = &sg;
+ data.sg_len = 1;
+
+ memset(&mrq, 0, sizeof(struct mmc_request));
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ sg_init_one(&sg, status, 64);
+
+ mmc_wait_for_req(host, &mrq);
+
+ if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+ mmc_card_set_dead(card);
+ continue;
+ }
+
+ if ((status[16] & 0xF) != 1) {
+ printk(KERN_WARNING "%s: Problem switching card "
+ "into high-speed mode!\n",
+ mmc_hostname(host));
+ continue;
+ }
+
+ mmc_card_set_highspeed(card);
+ }
+
+ kfree(status);
+
+ mmc_deselect_cards(host);
+}
+
static unsigned int mmc_calculate_clock(struct mmc_host *host)
{
struct mmc_card *card;
unsigned int max_dtr = host->f_max;
list_for_each_entry(card, &host->cards, node)
- if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
- max_dtr = card->csd.max_dtr;
+ if (!mmc_card_dead(card)) {
+ if (mmc_card_highspeed(card) && mmc_card_sd(card)) {
+ if (max_dtr > card->sw_caps.hs_max_dtr)
+ max_dtr = card->sw_caps.hs_max_dtr;
+ } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) {
+ if (max_dtr > card->ext_csd.hs_max_dtr)
+ max_dtr = card->ext_csd.hs_max_dtr;
+ } else if (max_dtr > card->csd.max_dtr) {
+ max_dtr = card->csd.max_dtr;
+ }
+ }
pr_debug("%s: selected %d.%03dMHz transfer rate\n",
mmc_hostname(host),
@@ -1150,8 +1401,11 @@ static void mmc_setup(struct mmc_host *host)
mmc_read_csds(host);
- if (host->mode == MMC_MODE_SD)
+ if (host->mode == MMC_MODE_SD) {
mmc_read_scrs(host);
+ mmc_read_switch_caps(host);
+ } else
+ mmc_process_ext_csds(host);
}
@@ -1165,18 +1419,16 @@ static void mmc_setup(struct mmc_host *host)
*/
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
- if (delay)
- mmc_schedule_delayed_work(&host->detect, delay);
- else
- mmc_schedule_work(&host->detect);
+ mmc_schedule_delayed_work(&host->detect, delay);
}
EXPORT_SYMBOL(mmc_detect_change);
-static void mmc_rescan(void *data)
+static void mmc_rescan(struct work_struct *work)
{
- struct mmc_host *host = data;
+ struct mmc_host *host =
+ container_of(work, struct mmc_host, detect.work);
struct list_head *l, *n;
unsigned char power_mode;
@@ -1259,7 +1511,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
spin_lock_init(&host->lock);
init_waitqueue_head(&host->wq);
INIT_LIST_HEAD(&host->cards);
- INIT_WORK(&host->detect, mmc_rescan, host);
+ INIT_DELAYED_WORK(&host->detect, mmc_rescan);
/*
* By default, hosts do not support SGIO or large requests.
@@ -1357,7 +1609,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
*/
int mmc_resume_host(struct mmc_host *host)
{
- mmc_rescan(host);
+ mmc_rescan(&host->detect.work);
return 0;
}
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h
index cd5e0ab3d84b..149affe0b686 100644
--- a/drivers/mmc/mmc.h
+++ b/drivers/mmc/mmc.h
@@ -20,6 +20,6 @@ void mmc_remove_host_sysfs(struct mmc_host *host);
void mmc_free_host_sysfs(struct mmc_host *host);
int mmc_schedule_work(struct work_struct *work);
-int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay);
+int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay);
void mmc_flush_scheduled_work(void);
#endif
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index f9027c8db792..87713572293f 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -83,7 +83,6 @@ static void mmc_blk_put(struct mmc_blk_data *md)
md->usage--;
if (md->usage == 0) {
put_disk(md->disk);
- mmc_cleanup_queue(&md->queue);
kfree(md);
}
mutex_unlock(&open_lock);
@@ -225,10 +224,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
struct mmc_blk_request brq;
- int ret;
+ int ret = 1;
if (mmc_card_claim_host(card))
- goto cmd_err;
+ goto flush_queue;
do {
struct mmc_command cmd;
@@ -345,8 +344,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
return 1;
cmd_err:
- ret = 1;
-
/*
* If this is an SD card and we're writing, we can first
* mark the known good sectors as ok.
@@ -380,6 +377,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
mmc_card_release_host(card);
+flush_queue:
spin_lock_irq(&md->lock);
while (ret) {
ret = end_that_request_chunk(req, 0,
@@ -553,12 +551,11 @@ static void mmc_blk_remove(struct mmc_card *card)
if (md) {
int devidx;
+ /* Stop new requests from getting into the queue */
del_gendisk(md->disk);
- /*
- * I think this is needed.
- */
- md->disk->queue = NULL;
+ /* Then flush out any already in there */
+ mmc_cleanup_queue(&md->queue);
devidx = md->disk->first_minor >> MMC_SHIFT;
__clear_bit(devidx, dev_use);
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 61a1de85cb23..a17423a4ed8f 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -10,13 +10,13 @@
*/
#include <linux/module.h>
#include <linux/blkdev.h>
+#include <linux/kthread.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include "mmc_queue.h"
-#define MMC_QUEUE_EXIT (1 << 0)
-#define MMC_QUEUE_SUSPENDED (1 << 1)
+#define MMC_QUEUE_SUSPENDED (1 << 0)
/*
* Prepare a MMC request. Essentially, this means passing the
@@ -59,7 +59,6 @@ static int mmc_queue_thread(void *d)
{
struct mmc_queue *mq = d;
struct request_queue *q = mq->queue;
- DECLARE_WAITQUEUE(wait, current);
/*
* Set iothread to ensure that we aren't put to sleep by
@@ -67,12 +66,7 @@ static int mmc_queue_thread(void *d)
*/
current->flags |= PF_MEMALLOC|PF_NOFREEZE;
- daemonize("mmcqd");
-
- complete(&mq->thread_complete);
-
down(&mq->thread_sem);
- add_wait_queue(&mq->thread_wq, &wait);
do {
struct request *req = NULL;
@@ -84,7 +78,7 @@ static int mmc_queue_thread(void *d)
spin_unlock_irq(q->queue_lock);
if (!req) {
- if (mq->flags & MMC_QUEUE_EXIT)
+ if (kthread_should_stop())
break;
up(&mq->thread_sem);
schedule();
@@ -95,10 +89,8 @@ static int mmc_queue_thread(void *d)
mq->issue_fn(mq, req);
} while (1);
- remove_wait_queue(&mq->thread_wq, &wait);
up(&mq->thread_sem);
- complete_and_exit(&mq->thread_complete, 0);
return 0;
}
@@ -111,9 +103,22 @@ static int mmc_queue_thread(void *d)
static void mmc_request(request_queue_t *q)
{
struct mmc_queue *mq = q->queuedata;
+ struct request *req;
+ int ret;
+
+ if (!mq) {
+ printk(KERN_ERR "MMC: killing requests for dead queue\n");
+ while ((req = elv_next_request(q)) != NULL) {
+ do {
+ ret = end_that_request_chunk(req, 0,
+ req->current_nr_sectors << 9);
+ } while (ret);
+ }
+ return;
+ }
if (!mq->req)
- wake_up(&mq->thread_wq);
+ wake_up_process(mq->thread);
}
/**
@@ -152,36 +157,40 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
- goto cleanup;
+ goto cleanup_queue;
}
- init_completion(&mq->thread_complete);
- init_waitqueue_head(&mq->thread_wq);
init_MUTEX(&mq->thread_sem);
- ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL);
- if (ret >= 0) {
- wait_for_completion(&mq->thread_complete);
- init_completion(&mq->thread_complete);
- ret = 0;
- goto out;
+ mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");
+ if (IS_ERR(mq->thread)) {
+ ret = PTR_ERR(mq->thread);
+ goto free_sg;
}
- cleanup:
+ return 0;
+
+ free_sg:
kfree(mq->sg);
mq->sg = NULL;
-
+ cleanup_queue:
blk_cleanup_queue(mq->queue);
- out:
return ret;
}
EXPORT_SYMBOL(mmc_init_queue);
void mmc_cleanup_queue(struct mmc_queue *mq)
{
- mq->flags |= MMC_QUEUE_EXIT;
- wake_up(&mq->thread_wq);
- wait_for_completion(&mq->thread_complete);
+ request_queue_t *q = mq->queue;
+ unsigned long flags;
+
+ /* Mark that we should start throwing out stragglers */
+ spin_lock_irqsave(q->queue_lock, flags);
+ q->queuedata = NULL;
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ /* Then terminate our worker thread */
+ kthread_stop(mq->thread);
kfree(mq->sg);
mq->sg = NULL;
diff --git a/drivers/mmc/mmc_queue.h b/drivers/mmc/mmc_queue.h
index 7182d2f69b4e..c9f139e764f6 100644
--- a/drivers/mmc/mmc_queue.h
+++ b/drivers/mmc/mmc_queue.h
@@ -6,8 +6,7 @@ struct task_struct;
struct mmc_queue {
struct mmc_card *card;
- struct completion thread_complete;
- wait_queue_head_t thread_wq;
+ struct task_struct *thread;
struct semaphore thread_sem;
unsigned int flags;
struct request *req;
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index ac5329636045..e334acd045bc 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -321,17 +321,9 @@ void mmc_free_host_sysfs(struct mmc_host *host)
static struct workqueue_struct *workqueue;
/*
- * Internal function. Schedule work in the MMC work queue.
- */
-int mmc_schedule_work(struct work_struct *work)
-{
- return queue_work(workqueue, work);
-}
-
-/*
* Internal function. Schedule delayed work in the MMC work queue.
*/
-int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay)
+int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay)
{
return queue_delayed_work(workqueue, work, delay);
}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 828503c4ee62..e9b80e920266 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -443,7 +443,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
}
}
-static struct mmc_host_ops mmci_ops = {
+static const struct mmc_host_ops mmci_ops = {
.request = mmci_request,
.set_ios = mmci_set_ios,
};
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
index d593ef342e75..435d331e772a 100644
--- a/drivers/mmc/omap.c
+++ b/drivers/mmc/omap.c
@@ -38,7 +38,57 @@
#include <asm/arch/fpga.h>
#include <asm/arch/tps65010.h>
-#include "omap.h"
+#define OMAP_MMC_REG_CMD 0x00
+#define OMAP_MMC_REG_ARGL 0x04
+#define OMAP_MMC_REG_ARGH 0x08
+#define OMAP_MMC_REG_CON 0x0c
+#define OMAP_MMC_REG_STAT 0x10
+#define OMAP_MMC_REG_IE 0x14
+#define OMAP_MMC_REG_CTO 0x18
+#define OMAP_MMC_REG_DTO 0x1c
+#define OMAP_MMC_REG_DATA 0x20
+#define OMAP_MMC_REG_BLEN 0x24
+#define OMAP_MMC_REG_NBLK 0x28
+#define OMAP_MMC_REG_BUF 0x2c
+#define OMAP_MMC_REG_SDIO 0x34
+#define OMAP_MMC_REG_REV 0x3c
+#define OMAP_MMC_REG_RSP0 0x40
+#define OMAP_MMC_REG_RSP1 0x44
+#define OMAP_MMC_REG_RSP2 0x48
+#define OMAP_MMC_REG_RSP3 0x4c
+#define OMAP_MMC_REG_RSP4 0x50
+#define OMAP_MMC_REG_RSP5 0x54
+#define OMAP_MMC_REG_RSP6 0x58
+#define OMAP_MMC_REG_RSP7 0x5c
+#define OMAP_MMC_REG_IOSR 0x60
+#define OMAP_MMC_REG_SYSC 0x64
+#define OMAP_MMC_REG_SYSS 0x68
+
+#define OMAP_MMC_STAT_CARD_ERR (1 << 14)
+#define OMAP_MMC_STAT_CARD_IRQ (1 << 13)
+#define OMAP_MMC_STAT_OCR_BUSY (1 << 12)
+#define OMAP_MMC_STAT_A_EMPTY (1 << 11)
+#define OMAP_MMC_STAT_A_FULL (1 << 10)
+#define OMAP_MMC_STAT_CMD_CRC (1 << 8)
+#define OMAP_MMC_STAT_CMD_TOUT (1 << 7)
+#define OMAP_MMC_STAT_DATA_CRC (1 << 6)
+#define OMAP_MMC_STAT_DATA_TOUT (1 << 5)
+#define OMAP_MMC_STAT_END_BUSY (1 << 4)
+#define OMAP_MMC_STAT_END_OF_DATA (1 << 3)
+#define OMAP_MMC_STAT_CARD_BUSY (1 << 2)
+#define OMAP_MMC_STAT_END_OF_CMD (1 << 0)
+
+#define OMAP_MMC_READ(host, reg) __raw_readw((host)->virt_base + OMAP_MMC_REG_##reg)
+#define OMAP_MMC_WRITE(host, reg, val) __raw_writew((val), (host)->virt_base + OMAP_MMC_REG_##reg)
+
+/*
+ * Command types
+ */
+#define OMAP_MMC_CMDTYPE_BC 0
+#define OMAP_MMC_CMDTYPE_BCR 1
+#define OMAP_MMC_CMDTYPE_AC 2
+#define OMAP_MMC_CMDTYPE_ADTC 3
+
#define DRIVER_NAME "mmci-omap"
#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
@@ -60,8 +110,9 @@ struct mmc_omap_host {
unsigned char id; /* 16xx chips have 2 MMC blocks */
struct clk * iclk;
struct clk * fclk;
- struct resource *res;
- void __iomem *base;
+ struct resource *mem_res;
+ void __iomem *virt_base;
+ unsigned int phys_base;
int irq;
unsigned char bus_mode;
unsigned char hw_bus_mode;
@@ -191,16 +242,16 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
clk_enable(host->fclk);
- OMAP_MMC_WRITE(host->base, CTO, 200);
- OMAP_MMC_WRITE(host->base, ARGL, cmd->arg & 0xffff);
- OMAP_MMC_WRITE(host->base, ARGH, cmd->arg >> 16);
- OMAP_MMC_WRITE(host->base, IE,
+ OMAP_MMC_WRITE(host, CTO, 200);
+ OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff);
+ OMAP_MMC_WRITE(host, ARGH, cmd->arg >> 16);
+ OMAP_MMC_WRITE(host, IE,
OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL |
OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT |
OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT |
OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR |
OMAP_MMC_STAT_END_OF_DATA);
- OMAP_MMC_WRITE(host->base, CMD, cmdreg);
+ OMAP_MMC_WRITE(host, CMD, cmdreg);
}
static void
@@ -296,22 +347,22 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
if (cmd->flags & MMC_RSP_136) {
/* response type 2 */
cmd->resp[3] =
- OMAP_MMC_READ(host->base, RSP0) |
- (OMAP_MMC_READ(host->base, RSP1) << 16);
+ OMAP_MMC_READ(host, RSP0) |
+ (OMAP_MMC_READ(host, RSP1) << 16);
cmd->resp[2] =
- OMAP_MMC_READ(host->base, RSP2) |
- (OMAP_MMC_READ(host->base, RSP3) << 16);
+ OMAP_MMC_READ(host, RSP2) |
+ (OMAP_MMC_READ(host, RSP3) << 16);
cmd->resp[1] =
- OMAP_MMC_READ(host->base, RSP4) |
- (OMAP_MMC_READ(host->base, RSP5) << 16);
+ OMAP_MMC_READ(host, RSP4) |
+ (OMAP_MMC_READ(host, RSP5) << 16);
cmd->resp[0] =
- OMAP_MMC_READ(host->base, RSP6) |
- (OMAP_MMC_READ(host->base, RSP7) << 16);
+ OMAP_MMC_READ(host, RSP6) |
+ (OMAP_MMC_READ(host, RSP7) << 16);
} else {
/* response types 1, 1b, 3, 4, 5, 6 */
cmd->resp[0] =
- OMAP_MMC_READ(host->base, RSP6) |
- (OMAP_MMC_READ(host->base, RSP7) << 16);
+ OMAP_MMC_READ(host, RSP6) |
+ (OMAP_MMC_READ(host, RSP7) << 16);
}
}
@@ -354,9 +405,9 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
host->data->bytes_xfered += n;
if (write) {
- __raw_writesw(host->base + OMAP_MMC_REG_DATA, host->buffer, n);
+ __raw_writesw(host->virt_base + OMAP_MMC_REG_DATA, host->buffer, n);
} else {
- __raw_readsw(host->base + OMAP_MMC_REG_DATA, host->buffer, n);
+ __raw_readsw(host->virt_base + OMAP_MMC_REG_DATA, host->buffer, n);
}
}
@@ -386,11 +437,11 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
int transfer_error;
if (host->cmd == NULL && host->data == NULL) {
- status = OMAP_MMC_READ(host->base, STAT);
+ status = OMAP_MMC_READ(host, STAT);
dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
if (status != 0) {
- OMAP_MMC_WRITE(host->base, STAT, status);
- OMAP_MMC_WRITE(host->base, IE, 0);
+ OMAP_MMC_WRITE(host, STAT, status);
+ OMAP_MMC_WRITE(host, IE, 0);
}
return IRQ_HANDLED;
}
@@ -399,8 +450,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
end_transfer = 0;
transfer_error = 0;
- while ((status = OMAP_MMC_READ(host->base, STAT)) != 0) {
- OMAP_MMC_WRITE(host->base, STAT, status);
+ while ((status = OMAP_MMC_READ(host, STAT)) != 0) {
+ OMAP_MMC_WRITE(host, STAT, status);
#ifdef CONFIG_MMC_DEBUG
dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
status, host->cmd != NULL ? host->cmd->opcode : -1);
@@ -470,8 +521,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
if (status & OMAP_MMC_STAT_CARD_ERR) {
if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) {
- u32 response = OMAP_MMC_READ(host->base, RSP6)
- | (OMAP_MMC_READ(host->base, RSP7) << 16);
+ u32 response = OMAP_MMC_READ(host, RSP6)
+ | (OMAP_MMC_READ(host, RSP7) << 16);
/* STOP sometimes sets must-ignore bits */
if (!(response & (R1_CC_ERROR
| R1_ILLEGAL_COMMAND
@@ -530,12 +581,6 @@ static void mmc_omap_switch_timer(unsigned long arg)
schedule_work(&host->switch_work);
}
-/* FIXME: Handle card insertion and removal properly. Maybe use a mask
- * for MMC state? */
-static void mmc_omap_switch_callback(unsigned long data, u8 mmc_mask)
-{
-}
-
static void mmc_omap_switch_handler(void *data)
{
struct mmc_omap_host *host = (struct mmc_omap_host *) data;
@@ -581,7 +626,7 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
int dst_port = 0;
int sync_dev = 0;
- data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA;
+ data_addr = host->phys_base + OMAP_MMC_REG_DATA;
frame = data->blksz;
count = sg_dma_len(sg);
@@ -642,7 +687,7 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
/* Max limit for DMA frame count is 0xffff */
BUG_ON(count > 0xffff);
- OMAP_MMC_WRITE(host->base, BUF, buf);
+ OMAP_MMC_WRITE(host, BUF, buf);
omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
frame, count, OMAP_DMA_SYNC_FRAME,
sync_dev, 0);
@@ -727,11 +772,11 @@ static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_reques
{
u16 reg;
- reg = OMAP_MMC_READ(host->base, SDIO);
+ reg = OMAP_MMC_READ(host, SDIO);
reg &= ~(1 << 5);
- OMAP_MMC_WRITE(host->base, SDIO, reg);
+ OMAP_MMC_WRITE(host, SDIO, reg);
/* Set maximum timeout */
- OMAP_MMC_WRITE(host->base, CTO, 0xff);
+ OMAP_MMC_WRITE(host, CTO, 0xff);
}
static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
@@ -745,14 +790,14 @@ static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_reque
timeout = req->data->timeout_clks + req->data->timeout_ns / 500;
/* Check if we need to use timeout multiplier register */
- reg = OMAP_MMC_READ(host->base, SDIO);
+ reg = OMAP_MMC_READ(host, SDIO);
if (timeout > 0xffff) {
reg |= (1 << 5);
timeout /= 1024;
} else
reg &= ~(1 << 5);
- OMAP_MMC_WRITE(host->base, SDIO, reg);
- OMAP_MMC_WRITE(host->base, DTO, timeout);
+ OMAP_MMC_WRITE(host, SDIO, reg);
+ OMAP_MMC_WRITE(host, DTO, timeout);
}
static void
@@ -764,19 +809,18 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
host->data = data;
if (data == NULL) {
- OMAP_MMC_WRITE(host->base, BLEN, 0);
- OMAP_MMC_WRITE(host->base, NBLK, 0);
- OMAP_MMC_WRITE(host->base, BUF, 0);
+ OMAP_MMC_WRITE(host, BLEN, 0);
+ OMAP_MMC_WRITE(host, NBLK, 0);
+ OMAP_MMC_WRITE(host, BUF, 0);
host->dma_in_use = 0;
set_cmd_timeout(host, req);
return;
}
-
block_size = data->blksz;
- OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1);
- OMAP_MMC_WRITE(host->base, BLEN, block_size - 1);
+ OMAP_MMC_WRITE(host, NBLK, data->blocks - 1);
+ OMAP_MMC_WRITE(host, BLEN, block_size - 1);
set_data_timeout(host, req);
/* cope with calling layer confusion; it issues "single
@@ -818,7 +862,7 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
/* Revert to PIO? */
if (!use_dma) {
- OMAP_MMC_WRITE(host->base, BUF, 0x1f1f);
+ OMAP_MMC_WRITE(host, BUF, 0x1f1f);
host->total_bytes_left = data->blocks * block_size;
host->sg_len = sg_len;
mmc_omap_sg_to_buf(host);
@@ -844,7 +888,6 @@ static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
static void innovator_fpga_socket_power(int on)
{
#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
-
if (on) {
fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
OMAP1510_FPGA_POWER);
@@ -870,8 +913,8 @@ static void mmc_omap_power(struct mmc_omap_host *host, int on)
/* GPIO 4 of TPS65010 sends SD_EN signal */
tps65010_set_gpio_out_value(GPIO4, HIGH);
else if (cpu_is_omap24xx()) {
- u16 reg = OMAP_MMC_READ(host->base, CON);
- OMAP_MMC_WRITE(host->base, CON, reg | (1 << 11));
+ u16 reg = OMAP_MMC_READ(host, CON);
+ OMAP_MMC_WRITE(host, CON, reg | (1 << 11));
} else
if (host->power_pin >= 0)
omap_set_gpio_dataout(host->power_pin, 1);
@@ -883,8 +926,8 @@ static void mmc_omap_power(struct mmc_omap_host *host, int on)
else if (machine_is_omap_h3())
tps65010_set_gpio_out_value(GPIO4, LOW);
else if (cpu_is_omap24xx()) {
- u16 reg = OMAP_MMC_READ(host->base, CON);
- OMAP_MMC_WRITE(host->base, CON, reg & ~(1 << 11));
+ u16 reg = OMAP_MMC_READ(host, CON);
+ OMAP_MMC_WRITE(host, CON, reg & ~(1 << 11));
} else
if (host->power_pin >= 0)
omap_set_gpio_dataout(host->power_pin, 0);
@@ -926,7 +969,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_UP:
case MMC_POWER_ON:
mmc_omap_power(host, 1);
- dsor |= 1<<11;
+ dsor |= 1 << 11;
break;
}
@@ -940,14 +983,14 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* which results in the while loop below getting stuck.
* Writing to the CON register twice seems to do the trick. */
for (i = 0; i < 2; i++)
- OMAP_MMC_WRITE(host->base, CON, dsor);
+ OMAP_MMC_WRITE(host, CON, dsor);
if (ios->power_mode == MMC_POWER_UP) {
/* Send clock cycles, poll completion */
- OMAP_MMC_WRITE(host->base, IE, 0);
- OMAP_MMC_WRITE(host->base, STAT, 0xffff);
- OMAP_MMC_WRITE(host->base, CMD, 1<<7);
- while (0 == (OMAP_MMC_READ(host->base, STAT) & 1));
- OMAP_MMC_WRITE(host->base, STAT, 1);
+ OMAP_MMC_WRITE(host, IE, 0);
+ OMAP_MMC_WRITE(host, STAT, 0xffff);
+ OMAP_MMC_WRITE(host, CMD, 1 << 7);
+ while ((OMAP_MMC_READ(host, STAT) & 1) == 0);
+ OMAP_MMC_WRITE(host, STAT, 1);
}
clk_disable(host->fclk);
}
@@ -959,7 +1002,7 @@ static int mmc_omap_get_ro(struct mmc_host *mmc)
return host->wp_pin && omap_get_gpio_datain(host->wp_pin);
}
-static struct mmc_host_ops mmc_omap_ops = {
+static const struct mmc_host_ops mmc_omap_ops = {
.request = mmc_omap_request,
.set_ios = mmc_omap_set_ios,
.get_ro = mmc_omap_get_ro,
@@ -970,25 +1013,29 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
struct omap_mmc_conf *minfo = pdev->dev.platform_data;
struct mmc_host *mmc;
struct mmc_omap_host *host = NULL;
- struct resource *r;
+ struct resource *res;
int ret = 0;
int irq;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (minfo == NULL) {
+ dev_err(&pdev->dev, "platform data missing\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- if (!r || irq < 0)
+ if (res == NULL || irq < 0)
return -ENXIO;
- r = request_mem_region(pdev->resource[0].start,
- pdev->resource[0].end - pdev->resource[0].start + 1,
- pdev->name);
- if (!r)
+ res = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (res == NULL)
return -EBUSY;
mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev);
- if (!mmc) {
+ if (mmc == NULL) {
ret = -ENOMEM;
- goto out;
+ goto err_free_mem_region;
}
host = mmc_priv(mmc);
@@ -1000,13 +1047,13 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->dma_timer.data = (unsigned long) host;
host->id = pdev->id;
- host->res = r;
+ host->mem_res = res;
host->irq = irq;
if (cpu_is_omap24xx()) {
host->iclk = clk_get(&pdev->dev, "mmc_ick");
if (IS_ERR(host->iclk))
- goto out;
+ goto err_free_mmc_host;
clk_enable(host->iclk);
}
@@ -1017,7 +1064,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
- goto out;
+ goto err_free_iclk;
}
/* REVISIT:
@@ -1030,14 +1077,15 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->use_dma = 1;
host->dma_ch = -1;
- host->irq = pdev->resource[1].start;
- host->base = (void __iomem*)IO_ADDRESS(r->start);
+ host->irq = irq;
+ host->phys_base = host->mem_res->start;
+ host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
mmc->ops = &mmc_omap_ops;
mmc->f_min = 400000;
mmc->f_max = 24000000;
- mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
- mmc->caps = MMC_CAP_BYTEBLOCK;
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
if (minfo->wire4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
@@ -1055,20 +1103,18 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
if ((ret = omap_request_gpio(host->power_pin)) != 0) {
dev_err(mmc_dev(host->mmc),
"Unable to get GPIO pin for MMC power\n");
- goto out;
+ goto err_free_fclk;
}
omap_set_gpio_direction(host->power_pin, 0);
}
ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
if (ret)
- goto out;
+ goto err_free_power_gpio;
host->dev = &pdev->dev;
platform_set_drvdata(pdev, host);
- mmc_add_host(mmc);
-
if (host->switch_pin >= 0) {
INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host);
init_timer(&host->switch_timer);
@@ -1106,10 +1152,11 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
schedule_work(&host->switch_work);
}
-no_switch:
+ mmc_add_host(mmc);
+
return 0;
-out:
+no_switch:
/* FIXME: Free other resources too. */
if (host) {
if (host->iclk && !IS_ERR(host->iclk))
@@ -1118,6 +1165,20 @@ out:
clk_put(host->fclk);
mmc_free_host(host->mmc);
}
+err_free_power_gpio:
+ if (host->power_pin >= 0)
+ omap_free_gpio(host->power_pin);
+err_free_fclk:
+ clk_put(host->fclk);
+err_free_iclk:
+ if (host->iclk != NULL) {
+ clk_disable(host->iclk);
+ clk_put(host->iclk);
+ }
+err_free_mmc_host:
+ mmc_free_host(host->mmc);
+err_free_mem_region:
+ release_mem_region(res->start, res->end - res->start + 1);
return ret;
}
@@ -1127,30 +1188,31 @@ static int mmc_omap_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
- if (host) {
- mmc_remove_host(host->mmc);
- free_irq(host->irq, host);
-
- if (host->power_pin >= 0)
- omap_free_gpio(host->power_pin);
- if (host->switch_pin >= 0) {
- device_remove_file(&pdev->dev, &dev_attr_enable_poll);
- device_remove_file(&pdev->dev, &dev_attr_cover_switch);
- free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
- omap_free_gpio(host->switch_pin);
- host->switch_pin = -1;
- del_timer_sync(&host->switch_timer);
- flush_scheduled_work();
- }
- if (host->iclk && !IS_ERR(host->iclk))
- clk_put(host->iclk);
- if (host->fclk && !IS_ERR(host->fclk))
- clk_put(host->fclk);
- mmc_free_host(host->mmc);
+ BUG_ON(host == NULL);
+
+ mmc_remove_host(host->mmc);
+ free_irq(host->irq, host);
+
+ if (host->power_pin >= 0)
+ omap_free_gpio(host->power_pin);
+ if (host->switch_pin >= 0) {
+ device_remove_file(&pdev->dev, &dev_attr_enable_poll);
+ device_remove_file(&pdev->dev, &dev_attr_cover_switch);
+ free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
+ omap_free_gpio(host->switch_pin);
+ host->switch_pin = -1;
+ del_timer_sync(&host->switch_timer);
+ flush_scheduled_work();
}
+ if (host->iclk && !IS_ERR(host->iclk))
+ clk_put(host->iclk);
+ if (host->fclk && !IS_ERR(host->fclk))
+ clk_put(host->fclk);
release_mem_region(pdev->resource[0].start,
- pdev->resource[0].end - pdev->resource[0].start + 1);
+ pdev->resource[0].end - pdev->resource[0].start + 1);
+
+ mmc_free_host(host->mmc);
return 0;
}
diff --git a/drivers/mmc/omap.h b/drivers/mmc/omap.h
deleted file mode 100644
index c954d355a5e3..000000000000
--- a/drivers/mmc/omap.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef DRIVERS_MEDIA_MMC_OMAP_H
-#define DRIVERS_MEDIA_MMC_OMAP_H
-
-#define OMAP_MMC_REG_CMD 0x00
-#define OMAP_MMC_REG_ARGL 0x04
-#define OMAP_MMC_REG_ARGH 0x08
-#define OMAP_MMC_REG_CON 0x0c
-#define OMAP_MMC_REG_STAT 0x10
-#define OMAP_MMC_REG_IE 0x14
-#define OMAP_MMC_REG_CTO 0x18
-#define OMAP_MMC_REG_DTO 0x1c
-#define OMAP_MMC_REG_DATA 0x20
-#define OMAP_MMC_REG_BLEN 0x24
-#define OMAP_MMC_REG_NBLK 0x28
-#define OMAP_MMC_REG_BUF 0x2c
-#define OMAP_MMC_REG_SDIO 0x34
-#define OMAP_MMC_REG_REV 0x3c
-#define OMAP_MMC_REG_RSP0 0x40
-#define OMAP_MMC_REG_RSP1 0x44
-#define OMAP_MMC_REG_RSP2 0x48
-#define OMAP_MMC_REG_RSP3 0x4c
-#define OMAP_MMC_REG_RSP4 0x50
-#define OMAP_MMC_REG_RSP5 0x54
-#define OMAP_MMC_REG_RSP6 0x58
-#define OMAP_MMC_REG_RSP7 0x5c
-#define OMAP_MMC_REG_IOSR 0x60
-#define OMAP_MMC_REG_SYSC 0x64
-#define OMAP_MMC_REG_SYSS 0x68
-
-#define OMAP_MMC_STAT_CARD_ERR (1 << 14)
-#define OMAP_MMC_STAT_CARD_IRQ (1 << 13)
-#define OMAP_MMC_STAT_OCR_BUSY (1 << 12)
-#define OMAP_MMC_STAT_A_EMPTY (1 << 11)
-#define OMAP_MMC_STAT_A_FULL (1 << 10)
-#define OMAP_MMC_STAT_CMD_CRC (1 << 8)
-#define OMAP_MMC_STAT_CMD_TOUT (1 << 7)
-#define OMAP_MMC_STAT_DATA_CRC (1 << 6)
-#define OMAP_MMC_STAT_DATA_TOUT (1 << 5)
-#define OMAP_MMC_STAT_END_BUSY (1 << 4)
-#define OMAP_MMC_STAT_END_OF_DATA (1 << 3)
-#define OMAP_MMC_STAT_CARD_BUSY (1 << 2)
-#define OMAP_MMC_STAT_END_OF_CMD (1 << 0)
-
-#define OMAP_MMC_READ(base, reg) __raw_readw((base) + OMAP_MMC_REG_##reg)
-#define OMAP_MMC_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MMC_REG_##reg)
-
-/*
- * Command types
- */
-#define OMAP_MMC_CMDTYPE_BC 0
-#define OMAP_MMC_CMDTYPE_BCR 1
-#define OMAP_MMC_CMDTYPE_AC 2
-#define OMAP_MMC_CMDTYPE_ADTC 3
-
-#endif
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index a526698b8c91..471e9f4e0530 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -393,7 +393,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->clkrt, host->cmdat);
}
-static struct mmc_host_ops pxamci_ops = {
+static const struct mmc_host_ops pxamci_ops = {
.request = pxamci_request,
.get_ro = pxamci_get_ro,
.set_ios = pxamci_set_ios,
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 9a7d39b7cdbf..cd98117632d3 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -616,6 +616,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
int div;
+ u8 ctrl;
u16 clk;
unsigned long timeout;
@@ -624,6 +625,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ if (clock > 25000000)
+ ctrl |= SDHCI_CTRL_HISPD;
+ else
+ ctrl &= ~SDHCI_CTRL_HISPD;
+ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+
if (clock == 0)
goto out;
@@ -784,7 +792,7 @@ static int sdhci_get_ro(struct mmc_host *mmc)
return !(present & SDHCI_WRITE_PROTECT);
}
-static struct mmc_host_ops sdhci_ops = {
+static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.set_ios = sdhci_set_ios,
.get_ro = sdhci_get_ro,
@@ -1291,6 +1299,13 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
else if (caps & SDHCI_CAN_VDD_180)
mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
+ if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) {
+ printk(KERN_ERR "%s: Controller reports > 25 MHz base clock,"
+ " but no high speed support.\n",
+ host->slot_descr);
+ mmc->f_max = 25000000;
+ }
+
if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
"support voltages.\n", host->slot_descr);
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index 72a67937afe0..f9d1a0a6f03a 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -71,6 +71,7 @@
#define SDHCI_HOST_CONTROL 0x28
#define SDHCI_CTRL_LED 0x01
#define SDHCI_CTRL_4BITBUS 0x02
+#define SDHCI_CTRL_HISPD 0x04
#define SDHCI_POWER_CONTROL 0x29
#define SDHCI_POWER_ON 0x01
@@ -138,6 +139,7 @@
#define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_MAX_BLOCK_MASK 0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16
+#define SDHCI_CAN_DO_HISPD 0x00200000
#define SDHCI_CAN_DO_DMA 0x00400000
#define SDHCI_CAN_VDD_330 0x01000000
#define SDHCI_CAN_VDD_300 0x02000000
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index 0fdc55b08a6d..e846499a004c 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -99,7 +99,7 @@ struct tifm_sd {
struct mmc_request *req;
struct work_struct cmd_handler;
- struct work_struct abort_handler;
+ struct delayed_work abort_handler;
wait_queue_head_t can_eject;
size_t written_blocks;
@@ -496,9 +496,9 @@ err_out:
mmc_request_done(mmc, mrq);
}
-static void tifm_sd_end_cmd(void *data)
+static void tifm_sd_end_cmd(struct work_struct *work)
{
- struct tifm_sd *host = data;
+ struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler);
struct tifm_dev *sock = host->dev;
struct mmc_host *mmc = tifm_get_drvdata(sock);
struct mmc_request *mrq;
@@ -608,9 +608,9 @@ err_out:
mmc_request_done(mmc, mrq);
}
-static void tifm_sd_end_cmd_nodma(void *data)
+static void tifm_sd_end_cmd_nodma(struct work_struct *work)
{
- struct tifm_sd *host = (struct tifm_sd*)data;
+ struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler);
struct tifm_dev *sock = host->dev;
struct mmc_host *mmc = tifm_get_drvdata(sock);
struct mmc_request *mrq;
@@ -661,11 +661,14 @@ static void tifm_sd_end_cmd_nodma(void *data)
mmc_request_done(mmc, mrq);
}
-static void tifm_sd_abort(void *data)
+static void tifm_sd_abort(struct work_struct *work)
{
+ struct tifm_sd *host =
+ container_of(work, struct tifm_sd, abort_handler.work);
+
printk(KERN_ERR DRIVER_NAME
": card failed to respond for a long period of time");
- tifm_eject(((struct tifm_sd*)data)->dev);
+ tifm_eject(host->dev);
}
static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -762,9 +765,9 @@ static struct mmc_host_ops tifm_sd_ops = {
.get_ro = tifm_sd_ro
};
-static void tifm_sd_register_host(void *data)
+static void tifm_sd_register_host(struct work_struct *work)
{
- struct tifm_sd *host = (struct tifm_sd*)data;
+ struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler);
struct tifm_dev *sock = host->dev;
struct mmc_host *mmc = tifm_get_drvdata(sock);
unsigned long flags;
@@ -772,8 +775,7 @@ static void tifm_sd_register_host(void *data)
spin_lock_irqsave(&sock->lock, flags);
host->flags |= HOST_REG;
PREPARE_WORK(&host->cmd_handler,
- no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
- data);
+ no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd);
spin_unlock_irqrestore(&sock->lock, flags);
dev_dbg(&sock->dev, "adding host\n");
mmc_add_host(mmc);
@@ -799,8 +801,8 @@ static int tifm_sd_probe(struct tifm_dev *sock)
host->dev = sock;
host->clk_div = 61;
init_waitqueue_head(&host->can_eject);
- INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host);
- INIT_WORK(&host->abort_handler, tifm_sd_abort, host);
+ INIT_WORK(&host->cmd_handler, tifm_sd_register_host);
+ INIT_DELAYED_WORK(&host->abort_handler, tifm_sd_abort);
tifm_set_drvdata(sock, mmc);
sock->signal_irq = tifm_sd_signal_irq;
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 682e62b0b09d..7a282672f8e9 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1021,7 +1021,7 @@ static int wbsd_get_ro(struct mmc_host *mmc)
return csr & WBSD_WRPT;
}
-static struct mmc_host_ops wbsd_ops = {
+static const struct mmc_host_ops wbsd_ops = {
.request = wbsd_request,
.set_ios = wbsd_set_ios,
.get_ro = wbsd_get_ro,
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 11d170afa9c3..06e33786078d 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -922,7 +922,7 @@ int __init init_module(void)
* and then free up the resources we took when the card was found.
*/
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
struct net_device *dev = dev_3c501;
unregister_netdev(dev);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index a34b2206132d..7e34c4f07b70 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -726,7 +726,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index 458cb9cbe915..702bfb2a5e99 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -1670,7 +1670,7 @@ int __init init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index aa43563610ae..54e1d5aebed3 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -940,7 +940,7 @@ int __init init_module(void)
return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
}
-void
+void __exit
cleanup_module(void)
{
struct net_device *dev = dev_3c507;
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index 91849469b4f4..17d61eb0a7e5 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -1302,7 +1302,7 @@ int __init init_module(void)
} else return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index f4aca5386add..6c7437e60bd2 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -1659,7 +1659,7 @@ int __init init_module(void)
* transmit operations are allowed to start scribbling into memory.
*/
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(this_device);
cleanup_card(this_device);
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index d02ed51abfcc..931028f672de 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -594,7 +594,7 @@ struct rtl8139_private {
u32 rx_config;
struct rtl_extra_stats xstats;
- struct work_struct thread;
+ struct delayed_work thread;
struct mii_if_info mii;
unsigned int regs_len;
@@ -636,8 +636,8 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
-static void rtl8139_thread (void *_data);
-static void rtl8139_tx_timeout_task(void *_data);
+static void rtl8139_thread (struct work_struct *work);
+static void rtl8139_tx_timeout_task(struct work_struct *work);
static const struct ethtool_ops rtl8139_ethtool_ops;
/* write MMIO register, with flush */
@@ -1010,7 +1010,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
spin_lock_init (&tp->lock);
spin_lock_init (&tp->rx_lock);
- INIT_WORK(&tp->thread, rtl8139_thread, dev);
+ INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
tp->mii.dev = dev;
tp->mii.mdio_read = mdio_read;
tp->mii.mdio_write = mdio_write;
@@ -1596,15 +1596,16 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
RTL_R8 (Config1));
}
-static void rtl8139_thread (void *_data)
+static void rtl8139_thread (struct work_struct *work)
{
- struct net_device *dev = _data;
- struct rtl8139_private *tp = netdev_priv(dev);
+ struct rtl8139_private *tp =
+ container_of(work, struct rtl8139_private, thread.work);
+ struct net_device *dev = tp->mii.dev;
unsigned long thr_delay = next_tick;
if (tp->watchdog_fired) {
tp->watchdog_fired = 0;
- rtl8139_tx_timeout_task(_data);
+ rtl8139_tx_timeout_task(work);
} else if (rtnl_trylock()) {
rtl8139_thread_iter (dev, tp, tp->mmio_addr);
rtnl_unlock ();
@@ -1646,10 +1647,11 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
}
-static void rtl8139_tx_timeout_task (void *_data)
+static void rtl8139_tx_timeout_task (struct work_struct *work)
{
- struct net_device *dev = _data;
- struct rtl8139_private *tp = netdev_priv(dev);
+ struct rtl8139_private *tp =
+ container_of(work, struct rtl8139_private, thread.work);
+ struct net_device *dev = tp->mii.dev;
void __iomem *ioaddr = tp->mmio_addr;
int i;
u8 tmp8;
@@ -1695,7 +1697,7 @@ static void rtl8139_tx_timeout (struct net_device *dev)
struct rtl8139_private *tp = netdev_priv(dev);
if (!tp->have_thread) {
- INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
+ INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
schedule_delayed_work(&tp->thread, next_tick);
} else
tp->watchdog_fired = 1;
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index a67f5efc983f..602ed31a5dd9 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -33,7 +33,6 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netlink.h>
-#include <linux/divert.h>
/* A unified ethernet device probe. This is the easiest way to have every
ethernet adaptor have the name "eth[0123...]".
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 0dca8bb9d2c7..c01f87f5bed7 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -405,7 +405,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index 9164d8cd670e..d4e408169073 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -568,7 +568,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
#ifdef MODULE
static struct net_device *apne_dev;
-int init_module(void)
+int __init init_module(void)
{
apne_dev = apne_probe(-1);
if (IS_ERR(apne_dev))
@@ -576,7 +576,7 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(apne_dev);
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index cc1a27ed197f..dba5e5165452 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -1041,7 +1041,7 @@ int __init init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(cops_dev);
cleanup_card(cops_dev);
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index b54b857e357e..fada15d959de 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -41,9 +41,6 @@
#define DRV_NAME "at91_ether"
#define DRV_VERSION "1.0"
-static struct net_device *at91_dev;
-
-static struct timer_list check_timer;
#define LINK_POLL_INTERVAL (HZ)
/* ..................................................................... */
@@ -146,7 +143,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int
*/
static void update_linkspeed(struct net_device *dev, int silent)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned int bmsr, bmcr, lpa, mac_cfg;
unsigned int speed, duplex;
@@ -199,7 +196,7 @@ static void update_linkspeed(struct net_device *dev, int silent)
static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned int phy;
/*
@@ -242,7 +239,7 @@ done:
*/
static void enable_phyirq(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned int dsintr, irq_number;
int status;
@@ -252,8 +249,7 @@ static void enable_phyirq(struct net_device *dev)
* PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
* or board does not have it connected.
*/
- check_timer.expires = jiffies + LINK_POLL_INTERVAL;
- add_timer(&check_timer);
+ mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
return;
}
@@ -294,13 +290,13 @@ static void enable_phyirq(struct net_device *dev)
*/
static void disable_phyirq(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned int dsintr;
unsigned int irq_number;
irq_number = lp->board_data.phy_irq_pin;
if (!irq_number) {
- del_timer_sync(&check_timer);
+ del_timer_sync(&lp->check_timer);
return;
}
@@ -340,7 +336,7 @@ static void disable_phyirq(struct net_device *dev)
#if 0
static void reset_phy(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned int bmcr;
spin_lock_irq(&lp->lock);
@@ -362,13 +358,13 @@ static void reset_phy(struct net_device *dev)
static void at91ether_check_link(unsigned long dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
+ struct at91_private *lp = netdev_priv(dev);
enable_mdi();
update_linkspeed(dev, 1);
disable_mdi();
- check_timer.expires = jiffies + LINK_POLL_INTERVAL;
- add_timer(&check_timer);
+ mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
}
/* ......................... ADDRESS MANAGEMENT ........................ */
@@ -590,7 +586,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
int ret;
spin_lock_irq(&lp->lock);
@@ -611,7 +607,7 @@ static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cm
static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
int ret;
spin_lock_irq(&lp->lock);
@@ -627,7 +623,7 @@ static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cm
static int at91ether_nwayreset(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
int ret;
spin_lock_irq(&lp->lock);
@@ -658,7 +654,7 @@ static const struct ethtool_ops at91ether_ethtool_ops = {
static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
int res;
if (!netif_running(dev))
@@ -680,7 +676,7 @@ static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
*/
static void at91ether_start(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
struct recv_desc_bufs *dlist, *dlist_phys;
int i;
unsigned long ctl;
@@ -712,7 +708,7 @@ static void at91ether_start(struct net_device *dev)
*/
static int at91ether_open(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned long ctl;
if (!is_valid_ether_addr(dev->dev_addr))
@@ -752,7 +748,7 @@ static int at91ether_open(struct net_device *dev)
*/
static int at91ether_close(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned long ctl;
/* Disable Receiver and Transmitter */
@@ -779,7 +775,7 @@ static int at91ether_close(struct net_device *dev)
*/
static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) {
netif_stop_queue(dev);
@@ -811,7 +807,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
*/
static struct net_device_stats *at91ether_stats(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
int ale, lenerr, seqe, lcol, ecol;
if (netif_running(dev)) {
@@ -847,7 +843,7 @@ static struct net_device_stats *at91ether_stats(struct net_device *dev)
*/
static void at91ether_rx(struct net_device *dev)
{
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
struct recv_desc_bufs *dlist;
unsigned char *p_recv;
struct sk_buff *skb;
@@ -857,14 +853,13 @@ static void at91ether_rx(struct net_device *dev)
while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
p_recv = dlist->recv_buf[lp->rxBuffIndex];
pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */
- skb = alloc_skb(pktlen + 2, GFP_ATOMIC);
+ skb = dev_alloc_skb(pktlen + 2);
if (skb != NULL) {
skb_reserve(skb, 2);
memcpy(skb_put(skb, pktlen), p_recv, pktlen);
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
- skb->len = pktlen;
dev->last_rx = jiffies;
lp->stats.rx_bytes += pktlen;
netif_rx(skb);
@@ -891,7 +886,7 @@ static void at91ether_rx(struct net_device *dev)
static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct at91_private *lp = (struct at91_private *) dev->priv;
+ struct at91_private *lp = netdev_priv(dev);
unsigned long intstatus, ctl;
/* MAC Interrupt Status register indicates what interrupts are pending.
@@ -927,6 +922,17 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void at91ether_poll_controller(struct net_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ at91ether_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
+}
+#endif
+
/*
* Initialize the ethernet interface
*/
@@ -939,9 +945,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
unsigned int val;
int res;
- if (at91_dev) /* already initialized */
- return 0;
-
dev = alloc_etherdev(sizeof(struct at91_private));
if (!dev)
return -ENOMEM;
@@ -957,7 +960,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
}
/* Allocate memory for DMA Receive descriptors */
- lp = (struct at91_private *)dev->priv;
+ lp = netdev_priv(dev);
lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL);
if (lp->dlist == NULL) {
free_irq(dev->irq, dev);
@@ -979,6 +982,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
dev->set_mac_address = set_mac_address;
dev->ethtool_ops = &at91ether_ethtool_ops;
dev->do_ioctl = at91ether_ioctl;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = at91ether_poll_controller;
+#endif
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -1024,7 +1030,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
return res;
}
- at91_dev = dev;
/* Determine current link speed */
spin_lock_irq(&lp->lock);
@@ -1036,9 +1041,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
/* If board has no PHY IRQ, use a timer to poll the PHY */
if (!lp->board_data.phy_irq_pin) {
- init_timer(&check_timer);
- check_timer.data = (unsigned long)dev;
- check_timer.function = at91ether_check_link;
+ init_timer(&lp->check_timer);
+ lp->check_timer.data = (unsigned long)dev;
+ lp->check_timer.function = at91ether_check_link;
}
/* Display ethernet banner */
@@ -1115,15 +1120,16 @@ static int __init at91ether_probe(struct platform_device *pdev)
static int __devexit at91ether_remove(struct platform_device *pdev)
{
- struct at91_private *lp = (struct at91_private *) at91_dev->priv;
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct at91_private *lp = netdev_priv(dev);
- unregister_netdev(at91_dev);
- free_irq(at91_dev->irq, at91_dev);
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
clk_put(lp->ether_clk);
- free_netdev(at91_dev);
- at91_dev = NULL;
+ platform_set_drvdata(pdev, NULL);
+ free_netdev(dev);
return 0;
}
@@ -1131,8 +1137,8 @@ static int __devexit at91ether_remove(struct platform_device *pdev)
static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
{
- struct at91_private *lp = (struct at91_private *) at91_dev->priv;
struct net_device *net_dev = platform_get_drvdata(pdev);
+ struct at91_private *lp = netdev_priv(net_dev);
int phy_irq = lp->board_data.phy_irq_pin;
if (netif_running(net_dev)) {
@@ -1149,8 +1155,8 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
static int at91ether_resume(struct platform_device *pdev)
{
- struct at91_private *lp = (struct at91_private *) at91_dev->priv;
struct net_device *net_dev = platform_get_drvdata(pdev);
+ struct at91_private *lp = netdev_priv(net_dev);
int phy_irq = lp->board_data.phy_irq_pin;
if (netif_running(net_dev)) {
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
index d1e72e02be3a..b6b665de2ea0 100644
--- a/drivers/net/arm/at91_ether.h
+++ b/drivers/net/arm/at91_ether.h
@@ -87,6 +87,7 @@ struct at91_private
spinlock_t lock; /* lock for MDI interface */
short phy_media; /* media interface type */
unsigned short phy_address; /* 5-bit MDI address of PHY (0..31) */
+ struct timer_list check_timer; /* Poll link status */
/* Transmit */
struct sk_buff *skb; /* holds skb until xmit interrupt completes */
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index f3478a30e778..d6da3ce9ad79 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -254,7 +254,7 @@ ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsig
} while (thislen);
}
-static int __init
+static int __devinit
ether1_ramtest(struct net_device *dev, unsigned char byte)
{
unsigned char *buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
@@ -308,7 +308,7 @@ ether1_reset (struct net_device *dev)
return BUS_16;
}
-static int __init
+static int __devinit
ether1_init_2(struct net_device *dev)
{
int i;
@@ -986,7 +986,7 @@ ether1_setmulticastlist (struct net_device *dev)
/* ------------------------------------------------------------------------- */
-static void __init ether1_banner(void)
+static void __devinit ether1_banner(void)
{
static unsigned int version_printed = 0;
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 84686c8a5bc2..4fc234785d56 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -198,7 +198,7 @@ static inline void ether3_ledon(struct net_device *dev)
* Read the ethernet address string from the on board rom.
* This is an ascii string!!!
*/
-static int __init
+static int __devinit
ether3_addr(char *addr, struct expansion_card *ec)
{
struct in_chunk_dir cd;
@@ -223,7 +223,7 @@ ether3_addr(char *addr, struct expansion_card *ec)
/* --------------------------------------------------------------------------- */
-static int __init
+static int __devinit
ether3_ramtest(struct net_device *dev, unsigned char byte)
{
unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL);
@@ -272,7 +272,7 @@ ether3_ramtest(struct net_device *dev, unsigned char byte)
/* ------------------------------------------------------------------------------- */
-static int __init ether3_init_2(struct net_device *dev)
+static int __devinit ether3_init_2(struct net_device *dev)
{
int i;
@@ -765,7 +765,7 @@ static void ether3_tx(struct net_device *dev)
}
}
-static void __init ether3_banner(void)
+static void __devinit ether3_banner(void)
{
static unsigned version_printed = 0;
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 8620a5b470f5..56ae8babd919 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -908,7 +908,7 @@ int __init init_module(void)
return 0;
}
-void
+void __exit
cleanup_module(void)
{
unregister_netdev(dev_at1700);
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index d79489e46249..7e37ac86a69a 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -1179,7 +1179,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
#ifdef MODULE
static struct net_device *atarilance_dev;
-int init_module(void)
+int __init init_module(void)
{
atarilance_dev = atarilance_probe(-1);
if (IS_ERR(atarilance_dev))
@@ -1187,7 +1187,7 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(atarilance_dev);
free_irq(atarilance_dev->irq, atarilance_dev);
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 01b76d3aa42f..5bacb7587df4 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -53,11 +53,12 @@
#include "bnx2.h"
#include "bnx2_fw.h"
+#include "bnx2_fw2.h"
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.4.45"
-#define DRV_MODULE_RELDATE "September 29, 2006"
+#define DRV_MODULE_VERSION "1.5.1"
+#define DRV_MODULE_RELDATE "November 15, 2006"
#define RUN_AT(x) (jiffies + (x))
@@ -85,6 +86,7 @@ typedef enum {
NC370F,
BCM5708,
BCM5708S,
+ BCM5709,
} board_t;
/* indexed by board_t, above */
@@ -98,6 +100,7 @@ static const struct {
{ "HP NC370F Multifunction Gigabit Server Adapter" },
{ "Broadcom NetXtreme II BCM5708 1000Base-T" },
{ "Broadcom NetXtreme II BCM5708 1000Base-SX" },
+ { "Broadcom NetXtreme II BCM5709 1000Base-T" },
};
static struct pci_device_id bnx2_pci_tbl[] = {
@@ -115,6 +118,8 @@ static struct pci_device_id bnx2_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709 },
{ 0, }
};
@@ -236,8 +241,23 @@ static void
bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
{
offset += cid_addr;
- REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
- REG_WR(bp, BNX2_CTX_DATA, val);
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ int i;
+
+ REG_WR(bp, BNX2_CTX_CTX_DATA, val);
+ REG_WR(bp, BNX2_CTX_CTX_CTRL,
+ offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
+ for (i = 0; i < 5; i++) {
+ u32 val;
+ val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
+ if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
+ break;
+ udelay(5);
+ }
+ } else {
+ REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
+ REG_WR(bp, BNX2_CTX_DATA, val);
+ }
}
static int
@@ -403,6 +423,14 @@ bnx2_free_mem(struct bnx2 *bp)
{
int i;
+ for (i = 0; i < bp->ctx_pages; i++) {
+ if (bp->ctx_blk[i]) {
+ pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
+ bp->ctx_blk[i],
+ bp->ctx_blk_mapping[i]);
+ bp->ctx_blk[i] = NULL;
+ }
+ }
if (bp->status_blk) {
pci_free_consistent(bp->pdev, bp->status_stats_size,
bp->status_blk, bp->status_blk_mapping);
@@ -481,6 +509,18 @@ bnx2_alloc_mem(struct bnx2 *bp)
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ bp->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
+ if (bp->ctx_pages == 0)
+ bp->ctx_pages = 1;
+ for (i = 0; i < bp->ctx_pages; i++) {
+ bp->ctx_blk[i] = pci_alloc_consistent(bp->pdev,
+ BCM_PAGE_SIZE,
+ &bp->ctx_blk_mapping[i]);
+ if (bp->ctx_blk[i] == NULL)
+ goto alloc_mem_err;
+ }
+ }
return 0;
alloc_mem_err:
@@ -803,13 +843,13 @@ bnx2_set_mac_link(struct bnx2 *bp)
val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
- BNX2_EMAC_MODE_25G);
+ BNX2_EMAC_MODE_25G_MODE);
if (bp->link_up) {
switch (bp->line_speed) {
case SPEED_10:
- if (CHIP_NUM(bp) == CHIP_NUM_5708) {
- val |= BNX2_EMAC_MODE_PORT_MII_10;
+ if (CHIP_NUM(bp) != CHIP_NUM_5706) {
+ val |= BNX2_EMAC_MODE_PORT_MII_10M;
break;
}
/* fall through */
@@ -817,7 +857,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
val |= BNX2_EMAC_MODE_PORT_MII;
break;
case SPEED_2500:
- val |= BNX2_EMAC_MODE_25G;
+ val |= BNX2_EMAC_MODE_25G_MODE;
/* fall through */
case SPEED_1000:
val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -860,7 +900,7 @@ bnx2_set_link(struct bnx2 *bp)
u32 bmsr;
u8 link_up;
- if (bp->loopback == MAC_LOOPBACK) {
+ if (bp->loopback == MAC_LOOPBACK || bp->loopback == PHY_LOOPBACK) {
bp->link_up = 1;
return 0;
}
@@ -902,6 +942,7 @@ bnx2_set_link(struct bnx2 *bp)
u32 bmcr;
bnx2_read_phy(bp, MII_BMCR, &bmcr);
+ bmcr &= ~BCM5708S_BMCR_FORCE_2500;
if (!(bmcr & BMCR_ANENABLE)) {
bnx2_write_phy(bp, MII_BMCR, bmcr |
BMCR_ANENABLE);
@@ -988,7 +1029,21 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
u32 new_bmcr;
int force_link_down = 0;
- if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+ adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
+
+ bnx2_read_phy(bp, MII_BMCR, &bmcr);
+ new_bmcr = bmcr & ~(BMCR_ANENABLE | BCM5708S_BMCR_FORCE_2500);
+ new_bmcr |= BMCR_SPEED1000;
+ if (bp->req_line_speed == SPEED_2500) {
+ new_bmcr |= BCM5708S_BMCR_FORCE_2500;
+ bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+ if (!(up1 & BCM5708S_UP1_2G5)) {
+ up1 |= BCM5708S_UP1_2G5;
+ bnx2_write_phy(bp, BCM5708S_UP1, up1);
+ force_link_down = 1;
+ }
+ } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
bnx2_read_phy(bp, BCM5708S_UP1, &up1);
if (up1 & BCM5708S_UP1_2G5) {
up1 &= ~BCM5708S_UP1_2G5;
@@ -997,12 +1052,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
}
}
- bnx2_read_phy(bp, MII_ADVERTISE, &adv);
- adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
-
- bnx2_read_phy(bp, MII_BMCR, &bmcr);
- new_bmcr = bmcr & ~BMCR_ANENABLE;
- new_bmcr |= BMCR_SPEED1000;
if (bp->req_duplex == DUPLEX_FULL) {
adv |= ADVERTISE_1000XFULL;
new_bmcr |= BMCR_FULLDPLX;
@@ -1023,6 +1072,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
bp->link_up = 0;
netif_carrier_off(bp->dev);
bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+ bnx2_report_link(bp);
}
bnx2_write_phy(bp, MII_ADVERTISE, adv);
bnx2_write_phy(bp, MII_BMCR, new_bmcr);
@@ -1048,30 +1098,26 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) {
/* Force a link down visible on the other side */
if (bp->link_up) {
- int i;
-
bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
- for (i = 0; i < 110; i++) {
- udelay(100);
- }
+ spin_unlock_bh(&bp->phy_lock);
+ msleep(20);
+ spin_lock_bh(&bp->phy_lock);
}
bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
BMCR_ANENABLE);
- if (CHIP_NUM(bp) == CHIP_NUM_5706) {
- /* Speed up link-up time when the link partner
- * does not autonegotiate which is very common
- * in blade servers. Some blade servers use
- * IPMI for kerboard input and it's important
- * to minimize link disruptions. Autoneg. involves
- * exchanging base pages plus 3 next pages and
- * normally completes in about 120 msec.
- */
- bp->current_interval = SERDES_AN_TIMEOUT;
- bp->serdes_an_pending = 1;
- mod_timer(&bp->timer, jiffies + bp->current_interval);
- }
+ /* Speed up link-up time when the link partner
+ * does not autonegotiate which is very common
+ * in blade servers. Some blade servers use
+ * IPMI for kerboard input and it's important
+ * to minimize link disruptions. Autoneg. involves
+ * exchanging base pages plus 3 next pages and
+ * normally completes in about 120 msec.
+ */
+ bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->serdes_an_pending = 1;
+ mod_timer(&bp->timer, jiffies + bp->current_interval);
}
return 0;
@@ -1153,7 +1199,6 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
}
if (new_bmcr != bmcr) {
u32 bmsr;
- int i = 0;
bnx2_read_phy(bp, MII_BMSR, &bmsr);
bnx2_read_phy(bp, MII_BMSR, &bmsr);
@@ -1161,12 +1206,12 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
if (bmsr & BMSR_LSTATUS) {
/* Force link down */
bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
- do {
- udelay(100);
- bnx2_read_phy(bp, MII_BMSR, &bmsr);
- bnx2_read_phy(bp, MII_BMSR, &bmsr);
- i++;
- } while ((bmsr & BMSR_LSTATUS) && (i < 620));
+ spin_unlock_bh(&bp->phy_lock);
+ msleep(50);
+ spin_lock_bh(&bp->phy_lock);
+
+ bnx2_read_phy(bp, MII_BMSR, &bmsr);
+ bnx2_read_phy(bp, MII_BMSR, &bmsr);
}
bnx2_write_phy(bp, MII_BMCR, new_bmcr);
@@ -1258,9 +1303,8 @@ bnx2_init_5706s_phy(struct bnx2 *bp)
{
bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
- if (CHIP_NUM(bp) == CHIP_NUM_5706) {
- REG_WR(bp, BNX2_MISC_UNUSED0, 0x300);
- }
+ if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
if (bp->dev->mtu > 1500) {
u32 val;
@@ -1397,13 +1441,13 @@ bnx2_set_phy_loopback(struct bnx2 *bp)
for (i = 0; i < 10; i++) {
if (bnx2_test_link(bp) == 0)
break;
- udelay(10);
+ msleep(100);
}
mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
- BNX2_EMAC_MODE_25G);
+ BNX2_EMAC_MODE_25G_MODE);
mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
@@ -1454,6 +1498,40 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
return 0;
}
+static int
+bnx2_init_5709_context(struct bnx2 *bp)
+{
+ int i, ret = 0;
+ u32 val;
+
+ val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
+ val |= (BCM_PAGE_BITS - 8) << 16;
+ REG_WR(bp, BNX2_CTX_COMMAND, val);
+ for (i = 0; i < bp->ctx_pages; i++) {
+ int j;
+
+ REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0,
+ (bp->ctx_blk_mapping[i] & 0xffffffff) |
+ BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID);
+ REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1,
+ (u64) bp->ctx_blk_mapping[i] >> 32);
+ REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i |
+ BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
+ for (j = 0; j < 10; j++) {
+
+ val = REG_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL);
+ if (!(val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ))
+ break;
+ udelay(5);
+ }
+ if (val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) {
+ ret = -EBUSY;
+ break;
+ }
+ }
+ return ret;
+}
+
static void
bnx2_init_context(struct bnx2 *bp)
{
@@ -1576,9 +1654,8 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
return -ENOMEM;
}
- if (unlikely((align = (unsigned long) skb->data & 0x7))) {
- skb_reserve(skb, 8 - align);
- }
+ if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1))))
+ skb_reserve(skb, BNX2_RX_ALIGN - align);
mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
@@ -2040,7 +2117,8 @@ bnx2_set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
/* Promiscuous mode. */
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
- sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN;
+ sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
+ BNX2_RPM_SORT_USER0_PROM_VLAN;
}
else if (dev->flags & IFF_ALLMULTI) {
for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
@@ -2208,11 +2286,12 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
}
}
-static void
+static int
load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
{
u32 offset;
u32 val;
+ int rc;
/* Halt the CPU. */
val = REG_RD_IND(bp, cpu_reg->mode);
@@ -2222,7 +2301,18 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
/* Load the Text area. */
offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
- if (fw->text) {
+ if (fw->gz_text) {
+ u32 text_len;
+ void *text;
+
+ rc = bnx2_gunzip(bp, fw->gz_text, fw->gz_text_len, &text,
+ &text_len);
+ if (rc)
+ return rc;
+
+ fw->text = text;
+ }
+ if (fw->gz_text) {
int j;
for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
@@ -2280,13 +2370,15 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
val &= ~cpu_reg->mode_value_halt;
REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
REG_WR_IND(bp, cpu_reg->mode, val);
+
+ return 0;
}
static int
bnx2_init_cpus(struct bnx2 *bp)
{
struct cpu_reg cpu_reg;
- struct fw_info fw;
+ struct fw_info *fw;
int rc = 0;
void *text;
u32 text_len;
@@ -2323,44 +2415,15 @@ bnx2_init_cpus(struct bnx2 *bp)
cpu_reg.spad_base = BNX2_RXP_SCRATCH;
cpu_reg.mips_view_base = 0x8000000;
- fw.ver_major = bnx2_RXP_b06FwReleaseMajor;
- fw.ver_minor = bnx2_RXP_b06FwReleaseMinor;
- fw.ver_fix = bnx2_RXP_b06FwReleaseFix;
- fw.start_addr = bnx2_RXP_b06FwStartAddr;
-
- fw.text_addr = bnx2_RXP_b06FwTextAddr;
- fw.text_len = bnx2_RXP_b06FwTextLen;
- fw.text_index = 0;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ fw = &bnx2_rxp_fw_09;
+ else
+ fw = &bnx2_rxp_fw_06;
- rc = bnx2_gunzip(bp, bnx2_RXP_b06FwText, sizeof(bnx2_RXP_b06FwText),
- &text, &text_len);
+ rc = load_cpu_fw(bp, &cpu_reg, fw);
if (rc)
goto init_cpu_err;
- fw.text = text;
-
- fw.data_addr = bnx2_RXP_b06FwDataAddr;
- fw.data_len = bnx2_RXP_b06FwDataLen;
- fw.data_index = 0;
- fw.data = bnx2_RXP_b06FwData;
-
- fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
- fw.sbss_len = bnx2_RXP_b06FwSbssLen;
- fw.sbss_index = 0;
- fw.sbss = bnx2_RXP_b06FwSbss;
-
- fw.bss_addr = bnx2_RXP_b06FwBssAddr;
- fw.bss_len = bnx2_RXP_b06FwBssLen;
- fw.bss_index = 0;
- fw.bss = bnx2_RXP_b06FwBss;
-
- fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
- fw.rodata_len = bnx2_RXP_b06FwRodataLen;
- fw.rodata_index = 0;
- fw.rodata = bnx2_RXP_b06FwRodata;
-
- load_cpu_fw(bp, &cpu_reg, &fw);
-
/* Initialize the TX Processor. */
cpu_reg.mode = BNX2_TXP_CPU_MODE;
cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT;
@@ -2375,44 +2438,15 @@ bnx2_init_cpus(struct bnx2 *bp)
cpu_reg.spad_base = BNX2_TXP_SCRATCH;
cpu_reg.mips_view_base = 0x8000000;
- fw.ver_major = bnx2_TXP_b06FwReleaseMajor;
- fw.ver_minor = bnx2_TXP_b06FwReleaseMinor;
- fw.ver_fix = bnx2_TXP_b06FwReleaseFix;
- fw.start_addr = bnx2_TXP_b06FwStartAddr;
-
- fw.text_addr = bnx2_TXP_b06FwTextAddr;
- fw.text_len = bnx2_TXP_b06FwTextLen;
- fw.text_index = 0;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ fw = &bnx2_txp_fw_09;
+ else
+ fw = &bnx2_txp_fw_06;
- rc = bnx2_gunzip(bp, bnx2_TXP_b06FwText, sizeof(bnx2_TXP_b06FwText),
- &text, &text_len);
+ rc = load_cpu_fw(bp, &cpu_reg, fw);
if (rc)
goto init_cpu_err;
- fw.text = text;
-
- fw.data_addr = bnx2_TXP_b06FwDataAddr;
- fw.data_len = bnx2_TXP_b06FwDataLen;
- fw.data_index = 0;
- fw.data = bnx2_TXP_b06FwData;
-
- fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
- fw.sbss_len = bnx2_TXP_b06FwSbssLen;
- fw.sbss_index = 0;
- fw.sbss = bnx2_TXP_b06FwSbss;
-
- fw.bss_addr = bnx2_TXP_b06FwBssAddr;
- fw.bss_len = bnx2_TXP_b06FwBssLen;
- fw.bss_index = 0;
- fw.bss = bnx2_TXP_b06FwBss;
-
- fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
- fw.rodata_len = bnx2_TXP_b06FwRodataLen;
- fw.rodata_index = 0;
- fw.rodata = bnx2_TXP_b06FwRodata;
-
- load_cpu_fw(bp, &cpu_reg, &fw);
-
/* Initialize the TX Patch-up Processor. */
cpu_reg.mode = BNX2_TPAT_CPU_MODE;
cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT;
@@ -2427,44 +2461,15 @@ bnx2_init_cpus(struct bnx2 *bp)
cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
cpu_reg.mips_view_base = 0x8000000;
- fw.ver_major = bnx2_TPAT_b06FwReleaseMajor;
- fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor;
- fw.ver_fix = bnx2_TPAT_b06FwReleaseFix;
- fw.start_addr = bnx2_TPAT_b06FwStartAddr;
-
- fw.text_addr = bnx2_TPAT_b06FwTextAddr;
- fw.text_len = bnx2_TPAT_b06FwTextLen;
- fw.text_index = 0;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ fw = &bnx2_tpat_fw_09;
+ else
+ fw = &bnx2_tpat_fw_06;
- rc = bnx2_gunzip(bp, bnx2_TPAT_b06FwText, sizeof(bnx2_TPAT_b06FwText),
- &text, &text_len);
+ rc = load_cpu_fw(bp, &cpu_reg, fw);
if (rc)
goto init_cpu_err;
- fw.text = text;
-
- fw.data_addr = bnx2_TPAT_b06FwDataAddr;
- fw.data_len = bnx2_TPAT_b06FwDataLen;
- fw.data_index = 0;
- fw.data = bnx2_TPAT_b06FwData;
-
- fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
- fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
- fw.sbss_index = 0;
- fw.sbss = bnx2_TPAT_b06FwSbss;
-
- fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
- fw.bss_len = bnx2_TPAT_b06FwBssLen;
- fw.bss_index = 0;
- fw.bss = bnx2_TPAT_b06FwBss;
-
- fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
- fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
- fw.rodata_index = 0;
- fw.rodata = bnx2_TPAT_b06FwRodata;
-
- load_cpu_fw(bp, &cpu_reg, &fw);
-
/* Initialize the Completion Processor. */
cpu_reg.mode = BNX2_COM_CPU_MODE;
cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT;
@@ -2479,44 +2484,36 @@ bnx2_init_cpus(struct bnx2 *bp)
cpu_reg.spad_base = BNX2_COM_SCRATCH;
cpu_reg.mips_view_base = 0x8000000;
- fw.ver_major = bnx2_COM_b06FwReleaseMajor;
- fw.ver_minor = bnx2_COM_b06FwReleaseMinor;
- fw.ver_fix = bnx2_COM_b06FwReleaseFix;
- fw.start_addr = bnx2_COM_b06FwStartAddr;
-
- fw.text_addr = bnx2_COM_b06FwTextAddr;
- fw.text_len = bnx2_COM_b06FwTextLen;
- fw.text_index = 0;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ fw = &bnx2_com_fw_09;
+ else
+ fw = &bnx2_com_fw_06;
- rc = bnx2_gunzip(bp, bnx2_COM_b06FwText, sizeof(bnx2_COM_b06FwText),
- &text, &text_len);
+ rc = load_cpu_fw(bp, &cpu_reg, fw);
if (rc)
goto init_cpu_err;
- fw.text = text;
-
- fw.data_addr = bnx2_COM_b06FwDataAddr;
- fw.data_len = bnx2_COM_b06FwDataLen;
- fw.data_index = 0;
- fw.data = bnx2_COM_b06FwData;
-
- fw.sbss_addr = bnx2_COM_b06FwSbssAddr;
- fw.sbss_len = bnx2_COM_b06FwSbssLen;
- fw.sbss_index = 0;
- fw.sbss = bnx2_COM_b06FwSbss;
-
- fw.bss_addr = bnx2_COM_b06FwBssAddr;
- fw.bss_len = bnx2_COM_b06FwBssLen;
- fw.bss_index = 0;
- fw.bss = bnx2_COM_b06FwBss;
-
- fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
- fw.rodata_len = bnx2_COM_b06FwRodataLen;
- fw.rodata_index = 0;
- fw.rodata = bnx2_COM_b06FwRodata;
+ /* Initialize the Command Processor. */
+ cpu_reg.mode = BNX2_CP_CPU_MODE;
+ cpu_reg.mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT;
+ cpu_reg.mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA;
+ cpu_reg.state = BNX2_CP_CPU_STATE;
+ cpu_reg.state_value_clear = 0xffffff;
+ cpu_reg.gpr0 = BNX2_CP_CPU_REG_FILE;
+ cpu_reg.evmask = BNX2_CP_CPU_EVENT_MASK;
+ cpu_reg.pc = BNX2_CP_CPU_PROGRAM_COUNTER;
+ cpu_reg.inst = BNX2_CP_CPU_INSTRUCTION;
+ cpu_reg.bp = BNX2_CP_CPU_HW_BREAKPOINT;
+ cpu_reg.spad_base = BNX2_CP_SCRATCH;
+ cpu_reg.mips_view_base = 0x8000000;
- load_cpu_fw(bp, &cpu_reg, &fw);
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ fw = &bnx2_cp_fw_09;
+ load_cpu_fw(bp, &cpu_reg, fw);
+ if (rc)
+ goto init_cpu_err;
+ }
init_cpu_err:
bnx2_gunzip_end(bp);
return rc;
@@ -3288,31 +3285,44 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
* before we issue a reset. */
val = REG_RD(bp, BNX2_MISC_ID);
- val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
- BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
- BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ REG_WR(bp, BNX2_MISC_COMMAND, BNX2_MISC_COMMAND_SW_RESET);
+ REG_RD(bp, BNX2_MISC_COMMAND);
+ udelay(5);
- /* Chip reset. */
- REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
+ val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
- if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5706_A1))
- msleep(15);
+ pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
- /* Reset takes approximate 30 usec */
- for (i = 0; i < 10; i++) {
- val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
- if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
- BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
- break;
+ } else {
+ val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+ BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
+
+ /* Chip reset. */
+ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
+
+ if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+ (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(HZ / 50);
}
- udelay(10);
- }
- if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
- BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
- printk(KERN_ERR PFX "Chip reset did not complete\n");
- return -EBUSY;
+ /* Reset takes approximate 30 usec */
+ for (i = 0; i < 10; i++) {
+ val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
+ if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+ BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
+ break;
+ udelay(10);
+ }
+
+ if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+ BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
+ printk(KERN_ERR PFX "Chip reset did not complete\n");
+ return -EBUSY;
+ }
}
/* Make sure byte swapping is properly configured. */
@@ -3390,7 +3400,10 @@ bnx2_init_chip(struct bnx2 *bp)
/* Initialize context mapping and zero out the quick contexts. The
* context block must have already been enabled. */
- bnx2_init_context(bp);
+ if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ bnx2_init_5709_context(bp);
+ else
+ bnx2_init_context(bp);
if ((rc = bnx2_init_cpus(bp)) != 0)
return rc;
@@ -3501,12 +3514,40 @@ bnx2_init_chip(struct bnx2 *bp)
return rc;
}
+static void
+bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
+{
+ u32 val, offset0, offset1, offset2, offset3;
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ offset0 = BNX2_L2CTX_TYPE_XI;
+ offset1 = BNX2_L2CTX_CMD_TYPE_XI;
+ offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
+ offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI;
+ } else {
+ offset0 = BNX2_L2CTX_TYPE;
+ offset1 = BNX2_L2CTX_CMD_TYPE;
+ offset2 = BNX2_L2CTX_TBDR_BHADDR_HI;
+ offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
+ }
+ val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
+ CTX_WR(bp, GET_CID_ADDR(cid), offset0, val);
+
+ val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
+ CTX_WR(bp, GET_CID_ADDR(cid), offset1, val);
+
+ val = (u64) bp->tx_desc_mapping >> 32;
+ CTX_WR(bp, GET_CID_ADDR(cid), offset2, val);
+
+ val = (u64) bp->tx_desc_mapping & 0xffffffff;
+ CTX_WR(bp, GET_CID_ADDR(cid), offset3, val);
+}
static void
bnx2_init_tx_ring(struct bnx2 *bp)
{
struct tx_bd *txbd;
- u32 val;
+ u32 cid;
bp->tx_wake_thresh = bp->tx_ring_size / 2;
@@ -3520,19 +3561,11 @@ bnx2_init_tx_ring(struct bnx2 *bp)
bp->hw_tx_cons = 0;
bp->tx_prod_bseq = 0;
- val = BNX2_L2CTX_TYPE_TYPE_L2;
- val |= BNX2_L2CTX_TYPE_SIZE_L2;
- CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val);
+ cid = TX_CID;
+ bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
+ bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
- val = BNX2_L2CTX_CMD_TYPE_TYPE_L2;
- val |= 8 << 16;
- CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);
-
- val = (u64) bp->tx_desc_mapping >> 32;
- CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val);
-
- val = (u64) bp->tx_desc_mapping & 0xffffffff;
- CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
+ bnx2_init_tx_context(bp, cid);
}
static void
@@ -3545,8 +3578,8 @@ bnx2_init_rx_ring(struct bnx2 *bp)
/* 8 for CRC and VLAN */
bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
- /* 8 for alignment */
- bp->rx_buf_size = bp->rx_buf_use_size + 8;
+ /* hw alignment */
+ bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
ring_prod = prod = bp->rx_prod = 0;
bp->rx_cons = 0;
@@ -3712,7 +3745,9 @@ bnx2_init_nic(struct bnx2 *bp)
if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
return rc;
+ spin_lock_bh(&bp->phy_lock);
bnx2_init_phy(bp);
+ spin_unlock_bh(&bp->phy_lock);
bnx2_set_link(bp);
return 0;
}
@@ -3952,7 +3987,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
bnx2_set_mac_loopback(bp);
}
else if (loopback_mode == BNX2_PHY_LOOPBACK) {
- bp->loopback = 0;
+ bp->loopback = PHY_LOOPBACK;
bnx2_set_phy_loopback(bp);
}
else
@@ -3992,8 +4027,8 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
bp->tx_prod = NEXT_TX_BD(bp->tx_prod);
bp->tx_prod_bseq += pkt_size;
- REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod);
- REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
+ REG_WR16(bp, bp->tx_bidx_addr, bp->tx_prod);
+ REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
udelay(100);
@@ -4162,80 +4197,117 @@ bnx2_test_intr(struct bnx2 *bp)
}
static void
-bnx2_timer(unsigned long data)
+bnx2_5706_serdes_timer(struct bnx2 *bp)
{
- struct bnx2 *bp = (struct bnx2 *) data;
- u32 msg;
+ spin_lock(&bp->phy_lock);
+ if (bp->serdes_an_pending)
+ bp->serdes_an_pending--;
+ else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
+ u32 bmcr;
- if (!netif_running(bp->dev))
- return;
+ bp->current_interval = bp->timer_interval;
- if (atomic_read(&bp->intr_sem) != 0)
- goto bnx2_restart_timer;
+ bnx2_read_phy(bp, MII_BMCR, &bmcr);
- msg = (u32) ++bp->fw_drv_pulse_wr_seq;
- REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
+ if (bmcr & BMCR_ANENABLE) {
+ u32 phy1, phy2;
- bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
+ bnx2_write_phy(bp, 0x1c, 0x7c00);
+ bnx2_read_phy(bp, 0x1c, &phy1);
- if ((bp->phy_flags & PHY_SERDES_FLAG) &&
- (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+ bnx2_write_phy(bp, 0x17, 0x0f01);
+ bnx2_read_phy(bp, 0x15, &phy2);
+ bnx2_write_phy(bp, 0x17, 0x0f01);
+ bnx2_read_phy(bp, 0x15, &phy2);
- spin_lock(&bp->phy_lock);
- if (bp->serdes_an_pending) {
- bp->serdes_an_pending--;
+ if ((phy1 & 0x10) && /* SIGNAL DETECT */
+ !(phy2 & 0x20)) { /* no CONFIG */
+
+ bmcr &= ~BMCR_ANENABLE;
+ bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
+ bnx2_write_phy(bp, MII_BMCR, bmcr);
+ bp->phy_flags |= PHY_PARALLEL_DETECT_FLAG;
+ }
}
- else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
- u32 bmcr;
+ }
+ else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
+ (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
+ u32 phy2;
- bp->current_interval = bp->timer_interval;
+ bnx2_write_phy(bp, 0x17, 0x0f01);
+ bnx2_read_phy(bp, 0x15, &phy2);
+ if (phy2 & 0x20) {
+ u32 bmcr;
bnx2_read_phy(bp, MII_BMCR, &bmcr);
+ bmcr |= BMCR_ANENABLE;
+ bnx2_write_phy(bp, MII_BMCR, bmcr);
- if (bmcr & BMCR_ANENABLE) {
- u32 phy1, phy2;
+ bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+ }
+ } else
+ bp->current_interval = bp->timer_interval;
- bnx2_write_phy(bp, 0x1c, 0x7c00);
- bnx2_read_phy(bp, 0x1c, &phy1);
+ spin_unlock(&bp->phy_lock);
+}
- bnx2_write_phy(bp, 0x17, 0x0f01);
- bnx2_read_phy(bp, 0x15, &phy2);
- bnx2_write_phy(bp, 0x17, 0x0f01);
- bnx2_read_phy(bp, 0x15, &phy2);
+static void
+bnx2_5708_serdes_timer(struct bnx2 *bp)
+{
+ if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
+ bp->serdes_an_pending = 0;
+ return;
+ }
- if ((phy1 & 0x10) && /* SIGNAL DETECT */
- !(phy2 & 0x20)) { /* no CONFIG */
+ spin_lock(&bp->phy_lock);
+ if (bp->serdes_an_pending)
+ bp->serdes_an_pending--;
+ else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
+ u32 bmcr;
- bmcr &= ~BMCR_ANENABLE;
- bmcr |= BMCR_SPEED1000 |
- BMCR_FULLDPLX;
- bnx2_write_phy(bp, MII_BMCR, bmcr);
- bp->phy_flags |=
- PHY_PARALLEL_DETECT_FLAG;
- }
- }
+ bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+ if (bmcr & BMCR_ANENABLE) {
+ bmcr &= ~BMCR_ANENABLE;
+ bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500;
+ bnx2_write_phy(bp, MII_BMCR, bmcr);
+ bp->current_interval = SERDES_FORCED_TIMEOUT;
+ } else {
+ bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500);
+ bmcr |= BMCR_ANENABLE;
+ bnx2_write_phy(bp, MII_BMCR, bmcr);
+ bp->serdes_an_pending = 2;
+ bp->current_interval = bp->timer_interval;
}
- else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
- (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
- u32 phy2;
- bnx2_write_phy(bp, 0x17, 0x0f01);
- bnx2_read_phy(bp, 0x15, &phy2);
- if (phy2 & 0x20) {
- u32 bmcr;
+ } else
+ bp->current_interval = bp->timer_interval;
- bnx2_read_phy(bp, MII_BMCR, &bmcr);
- bmcr |= BMCR_ANENABLE;
- bnx2_write_phy(bp, MII_BMCR, bmcr);
+ spin_unlock(&bp->phy_lock);
+}
+
+static void
+bnx2_timer(unsigned long data)
+{
+ struct bnx2 *bp = (struct bnx2 *) data;
+ u32 msg;
- bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+ if (!netif_running(bp->dev))
+ return;
- }
- }
- else
- bp->current_interval = bp->timer_interval;
+ if (atomic_read(&bp->intr_sem) != 0)
+ goto bnx2_restart_timer;
- spin_unlock(&bp->phy_lock);
+ msg = (u32) ++bp->fw_drv_pulse_wr_seq;
+ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
+
+ bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
+
+ if (bp->phy_flags & PHY_SERDES_FLAG) {
+ if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ bnx2_5706_serdes_timer(bp);
+ else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ bnx2_5708_serdes_timer(bp);
}
bnx2_restart_timer:
@@ -4339,9 +4411,9 @@ bnx2_open(struct net_device *dev)
}
static void
-bnx2_reset_task(void *data)
+bnx2_reset_task(struct work_struct *work)
{
- struct bnx2 *bp = data;
+ struct bnx2 *bp = container_of(work, struct bnx2, reset_task);
if (!netif_running(bp->dev))
return;
@@ -4508,8 +4580,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
prod = NEXT_TX_BD(prod);
bp->tx_prod_bseq += skb->len;
- REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
- REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
+ REG_WR16(bp, bp->tx_bidx_addr, prod);
+ REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
mmiowb();
@@ -4743,10 +4815,14 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
else {
if (bp->phy_flags & PHY_SERDES_FLAG) {
- if ((cmd->speed != SPEED_1000) ||
- (cmd->duplex != DUPLEX_FULL)) {
+ if ((cmd->speed != SPEED_1000 &&
+ cmd->speed != SPEED_2500) ||
+ (cmd->duplex != DUPLEX_FULL))
+ return -EINVAL;
+
+ if (cmd->speed == SPEED_2500 &&
+ !(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
return -EINVAL;
- }
}
else if (cmd->speed == SPEED_1000) {
return -EINVAL;
@@ -4903,11 +4979,10 @@ bnx2_nway_reset(struct net_device *dev)
msleep(20);
spin_lock_bh(&bp->phy_lock);
- if (CHIP_NUM(bp) == CHIP_NUM_5706) {
- bp->current_interval = SERDES_AN_TIMEOUT;
- bp->serdes_an_pending = 1;
- mod_timer(&bp->timer, jiffies + bp->current_interval);
- }
+
+ bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->serdes_an_pending = 1;
+ mod_timer(&bp->timer, jiffies + bp->current_interval);
}
bnx2_read_phy(bp, MII_BMCR, &bmcr);
@@ -5288,6 +5363,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
if (etest->flags & ETH_TEST_FL_OFFLINE) {
+ int i;
+
bnx2_netif_stop(bp);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
bnx2_free_skbs(bp);
@@ -5312,9 +5389,11 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
}
/* wait for link up */
- msleep_interruptible(3000);
- if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG))
- msleep_interruptible(4000);
+ for (i = 0; i < 7; i++) {
+ if (bp->link_up)
+ break;
+ msleep_interruptible(1000);
+ }
}
if (bnx2_test_nvram(bp) != 0) {
@@ -5604,13 +5683,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_release;
}
- bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
- if (bp->pcix_cap == 0) {
- dev_err(&pdev->dev, "Cannot find PCIX capability, aborting.\n");
- rc = -EIO;
- goto err_out_release;
- }
-
if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
bp->flags |= USING_DAC_FLAG;
if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
@@ -5630,10 +5702,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->pdev = pdev;
spin_lock_init(&bp->phy_lock);
- INIT_WORK(&bp->reset_task, bnx2_reset_task, bp);
+ INIT_WORK(&bp->reset_task, bnx2_reset_task);
dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
- mem_len = MB_GET_CID_ADDR(17);
+ mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1);
dev->mem_end = dev->mem_start + mem_len;
dev->irq = pdev->irq;
@@ -5657,6 +5729,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
+ if (CHIP_NUM(bp) != CHIP_NUM_5709) {
+ bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
+ if (bp->pcix_cap == 0) {
+ dev_err(&pdev->dev,
+ "Cannot find PCIX capability, aborting.\n");
+ rc = -EIO;
+ goto err_out_unmap;
+ }
+ }
+
/* Get bus information. */
reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5776,10 +5858,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->phy_addr = 1;
/* Disable WOL support if we are running on a SERDES chip. */
- if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (CHIP_BOND_ID(bp) != BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C)
+ bp->phy_flags |= PHY_SERDES_FLAG;
+ } else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
bp->phy_flags |= PHY_SERDES_FLAG;
+
+ if (bp->phy_flags & PHY_SERDES_FLAG) {
bp->flags |= NO_WOL_FLAG;
- if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ if (CHIP_NUM(bp) != CHIP_NUM_5706) {
bp->phy_addr = 2;
reg = REG_RD_IND(bp, bp->shmem_base +
BNX2_SHARED_HW_CFG_CONFIG);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index ca31904893ea..13b6f9b11e01 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -56,6 +56,7 @@ struct rx_bd {
};
+#define BNX2_RX_ALIGN 16
/*
* status_block definition
@@ -90,6 +91,7 @@ struct status_block {
#define STATUS_ATTN_BITS_DMAE_ABORT (1L<<25)
#define STATUS_ATTN_BITS_FLSH_ABORT (1L<<26)
#define STATUS_ATTN_BITS_GRC_ABORT (1L<<27)
+ #define STATUS_ATTN_BITS_EPB_ERROR (1L<<30)
#define STATUS_ATTN_BITS_PARITY_ERROR (1L<<31)
u32 status_attn_bits_ack;
@@ -117,7 +119,8 @@ struct status_block {
u16 status_completion_producer_index;
u16 status_cmd_consumer_index;
u16 status_idx;
- u16 status_unused;
+ u8 status_unused;
+ u8 status_blk_num;
#elif defined(__LITTLE_ENDIAN)
u16 status_tx_quick_consumer_index1;
u16 status_tx_quick_consumer_index0;
@@ -141,7 +144,8 @@ struct status_block {
u16 status_rx_quick_consumer_index14;
u16 status_cmd_consumer_index;
u16 status_completion_producer_index;
- u16 status_unused;
+ u8 status_blk_num;
+ u8 status_unused;
u16 status_idx;
#endif
};
@@ -301,6 +305,10 @@ struct l2_fhdr {
#define BNX2_L2CTX_TXP_BIDX 0x000000a8
#define BNX2_L2CTX_TXP_BSEQ 0x000000ac
+#define BNX2_L2CTX_TYPE_XI 0x00000080
+#define BNX2_L2CTX_CMD_TYPE_XI 0x00000240
+#define BNX2_L2CTX_TBDR_BHADDR_HI_XI 0x00000258
+#define BNX2_L2CTX_TBDR_BHADDR_LO_XI 0x0000025c
/*
* l2_bd_chain_context definition
@@ -328,11 +336,15 @@ struct l2_fhdr {
#define BNX2_PCICFG_MISC_CONFIG 0x00000068
#define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2)
#define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3)
+#define BNX2_PCICFG_MISC_CONFIG_RESERVED1 (1L<<4)
#define BNX2_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA (1L<<5)
#define BNX2_PCICFG_MISC_CONFIG_TARGET_GRC_WORD_SWAP (1L<<6)
#define BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA (1L<<7)
#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ (1L<<8)
#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY (1L<<9)
+#define BNX2_PCICFG_MISC_CONFIG_GRC_WIN1_SWAP_EN (1L<<10)
+#define BNX2_PCICFG_MISC_CONFIG_GRC_WIN2_SWAP_EN (1L<<11)
+#define BNX2_PCICFG_MISC_CONFIG_GRC_WIN3_SWAP_EN (1L<<12)
#define BNX2_PCICFG_MISC_CONFIG_ASIC_METAL_REV (0xffL<<16)
#define BNX2_PCICFG_MISC_CONFIG_ASIC_BASE_REV (0xfL<<24)
#define BNX2_PCICFG_MISC_CONFIG_ASIC_ID (0xfL<<28)
@@ -347,6 +359,7 @@ struct l2_fhdr {
#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_100 (1L<<4)
#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_133 (2L<<4)
#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_PCI_MODE (3L<<4)
+#define BNX2_PCICFG_MISC_STATUS_BAD_MEM_WRITE_BE (1L<<8)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS 0x00000070
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0)
@@ -366,7 +379,7 @@ struct l2_fhdr {
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8)
-#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_MIN_POWER (1L<<11)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12)
@@ -374,18 +387,21 @@ struct l2_fhdr {
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16)
-#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_17 (1L<<17)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18)
-#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_19 (1L<<19)
#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20)
#define BNX2_PCICFG_REG_WINDOW_ADDRESS 0x00000078
+#define BNX2_PCICFG_REG_WINDOW_ADDRESS_VAL (0xfffffL<<2)
+
#define BNX2_PCICFG_REG_WINDOW 0x00000080
#define BNX2_PCICFG_INT_ACK_CMD 0x00000084
#define BNX2_PCICFG_INT_ACK_CMD_INDEX (0xffffL<<0)
#define BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID (1L<<16)
#define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17)
#define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18)
+#define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM (0xfL<<24)
#define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088
#define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c
@@ -398,9 +414,11 @@ struct l2_fhdr {
* offset: 0x400
*/
#define BNX2_PCI_GRC_WINDOW_ADDR 0x00000400
-#define BNX2_PCI_GRC_WINDOW_ADDR_PCI_GRC_WINDOW_ADDR_VALUE (0x3ffffL<<8)
+#define BNX2_PCI_GRC_WINDOW_ADDR_VALUE (0x1ffL<<13)
+#define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN (1L<<31)
#define BNX2_PCI_CONFIG_1 0x00000404
+#define BNX2_PCI_CONFIG_1_RESERVED0 (0xffL<<0)
#define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8)
#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_OFF (0L<<8)
#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_16 (1L<<8)
@@ -419,6 +437,7 @@ struct l2_fhdr {
#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_256 (5L<<11)
#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_512 (6L<<11)
#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_1024 (7L<<11)
+#define BNX2_PCI_CONFIG_1_RESERVED1 (0x3ffffL<<14)
#define BNX2_PCI_CONFIG_2 0x00000408
#define BNX2_PCI_CONFIG_2_BAR1_SIZE (0xfL<<0)
@@ -468,9 +487,13 @@ struct l2_fhdr {
#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_MSTR (1L<<23)
#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_TGT (1L<<24)
#define BNX2_PCI_CONFIG_2_KEEP_REQ_ASSERT (1L<<25)
+#define BNX2_PCI_CONFIG_2_RESERVED0 (0x3fL<<26)
+#define BNX2_PCI_CONFIG_2_BAR_PREFETCH_XI (1L<<16)
+#define BNX2_PCI_CONFIG_2_RESERVED0_XI (0x7fffL<<17)
#define BNX2_PCI_CONFIG_3 0x0000040c
#define BNX2_PCI_CONFIG_3_STICKY_BYTE (0xffL<<0)
+#define BNX2_PCI_CONFIG_3_REG_STICKY_BYTE (0xffL<<8)
#define BNX2_PCI_CONFIG_3_FORCE_PME (1L<<24)
#define BNX2_PCI_CONFIG_3_PME_STATUS (1L<<25)
#define BNX2_PCI_CONFIG_3_PME_ENABLE (1L<<26)
@@ -501,8 +524,10 @@ struct l2_fhdr {
#define BNX2_PCI_VPD_INTF_INTF_REQ (1L<<0)
#define BNX2_PCI_VPD_ADDR_FLAG 0x0000042c
-#define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS (0x1fff<<2)
-#define BNX2_PCI_VPD_ADDR_FLAG_WR (1<<15)
+#define BNX2_PCI_VPD_ADDR_FLAG_MSK 0x0000ffff
+#define BNX2_PCI_VPD_ADDR_FLAG_SL 0L
+#define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS (0x1fffL<<2)
+#define BNX2_PCI_VPD_ADDR_FLAG_WR (1L<<15)
#define BNX2_PCI_VPD_DATA 0x00000430
#define BNX2_PCI_ID_VAL1 0x00000434
@@ -535,19 +560,26 @@ struct l2_fhdr {
#define BNX2_PCI_ID_VAL4_CAP_ENA_13 (13L<<0)
#define BNX2_PCI_ID_VAL4_CAP_ENA_14 (14L<<0)
#define BNX2_PCI_ID_VAL4_CAP_ENA_15 (15L<<0)
+#define BNX2_PCI_ID_VAL4_RESERVED0 (0x3L<<4)
#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG (0x3L<<6)
#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_0 (0L<<6)
#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_1 (1L<<6)
#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_2 (2L<<6)
#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_3 (3L<<6)
+#define BNX2_PCI_ID_VAL4_MSI_PV_MASK_CAP (1L<<8)
#define BNX2_PCI_ID_VAL4_MSI_LIMIT (0x7L<<9)
-#define BNX2_PCI_ID_VAL4_MSI_ADVERTIZE (0x7L<<12)
+#define BNX2_PCI_ID_VAL4_MULTI_MSG_CAP (0x7L<<12)
#define BNX2_PCI_ID_VAL4_MSI_ENABLE (1L<<15)
#define BNX2_PCI_ID_VAL4_MAX_64_ADVERTIZE (1L<<16)
#define BNX2_PCI_ID_VAL4_MAX_133_ADVERTIZE (1L<<17)
-#define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE (0x3L<<21)
-#define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE (0x7L<<23)
-#define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE (0x7L<<26)
+#define BNX2_PCI_ID_VAL4_RESERVED2 (0x7L<<18)
+#define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE_B21 (0x3L<<21)
+#define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE_B21 (0x3L<<23)
+#define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE_B0 (1L<<25)
+#define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE_B10 (0x3L<<26)
+#define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE_B0 (1L<<28)
+#define BNX2_PCI_ID_VAL4_RESERVED3 (0x7L<<29)
+#define BNX2_PCI_ID_VAL4_RESERVED3_XI (0xffffL<<16)
#define BNX2_PCI_ID_VAL5 0x00000444
#define BNX2_PCI_ID_VAL5_D1_SUPPORT (1L<<0)
@@ -556,6 +588,10 @@ struct l2_fhdr {
#define BNX2_PCI_ID_VAL5_PME_IN_D1 (1L<<3)
#define BNX2_PCI_ID_VAL5_PME_IN_D2 (1L<<4)
#define BNX2_PCI_ID_VAL5_PME_IN_D3_HOT (1L<<5)
+#define BNX2_PCI_ID_VAL5_RESERVED0_TE (0x3ffffffL<<6)
+#define BNX2_PCI_ID_VAL5_PM_VERSION_XI (0x7L<<6)
+#define BNX2_PCI_ID_VAL5_NO_SOFT_RESET_XI (1L<<9)
+#define BNX2_PCI_ID_VAL5_RESERVED0_XI (0x3fffffL<<10)
#define BNX2_PCI_PCIX_EXTENDED_STATUS 0x00000448
#define BNX2_PCI_PCIX_EXTENDED_STATUS_NO_SNOOP (1L<<8)
@@ -567,12 +603,91 @@ struct l2_fhdr {
#define BNX2_PCI_ID_VAL6_MAX_LAT (0xffL<<0)
#define BNX2_PCI_ID_VAL6_MIN_GNT (0xffL<<8)
#define BNX2_PCI_ID_VAL6_BIST (0xffL<<16)
+#define BNX2_PCI_ID_VAL6_RESERVED0 (0xffL<<24)
#define BNX2_PCI_MSI_DATA 0x00000450
-#define BNX2_PCI_MSI_DATA_PCI_MSI_DATA (0xffffL<<0)
+#define BNX2_PCI_MSI_DATA_MSI_DATA (0xffffL<<0)
#define BNX2_PCI_MSI_ADDR_H 0x00000454
#define BNX2_PCI_MSI_ADDR_L 0x00000458
+#define BNX2_PCI_MSI_ADDR_L_VAL (0x3fffffffL<<2)
+
+#define BNX2_PCI_CFG_ACCESS_CMD 0x0000045c
+#define BNX2_PCI_CFG_ACCESS_CMD_ADR (0x3fL<<2)
+#define BNX2_PCI_CFG_ACCESS_CMD_RD_REQ (1L<<27)
+#define BNX2_PCI_CFG_ACCESS_CMD_WR_REQ (0xfL<<28)
+
+#define BNX2_PCI_CFG_ACCESS_DATA 0x00000460
+#define BNX2_PCI_MSI_MASK 0x00000464
+#define BNX2_PCI_MSI_MASK_MSI_MASK (0xffffffffL<<0)
+
+#define BNX2_PCI_MSI_PEND 0x00000468
+#define BNX2_PCI_MSI_PEND_MSI_PEND (0xffffffffL<<0)
+
+#define BNX2_PCI_PM_DATA_C 0x0000046c
+#define BNX2_PCI_PM_DATA_C_PM_DATA_8_PRG (0xffL<<0)
+#define BNX2_PCI_PM_DATA_C_RESERVED0 (0xffffffL<<8)
+
+#define BNX2_PCI_MSIX_CONTROL 0x000004c0
+#define BNX2_PCI_MSIX_CONTROL_MSIX_TBL_SIZ (0x7ffL<<0)
+#define BNX2_PCI_MSIX_CONTROL_RESERVED0 (0x1fffffL<<11)
+
+#define BNX2_PCI_MSIX_TBL_OFF_BIR 0x000004c4
+#define BNX2_PCI_MSIX_TBL_OFF_BIR_MSIX_TBL_BIR (0x7L<<0)
+#define BNX2_PCI_MSIX_TBL_OFF_BIR_MSIX_TBL_OFF (0x1fffffffL<<3)
+
+#define BNX2_PCI_MSIX_PBA_OFF_BIT 0x000004c8
+#define BNX2_PCI_MSIX_PBA_OFF_BIT_MSIX_PBA_BIR (0x7L<<0)
+#define BNX2_PCI_MSIX_PBA_OFF_BIT_MSIX_PBA_OFF (0x1fffffffL<<3)
+
+#define BNX2_PCI_PCIE_CAPABILITY 0x000004d0
+#define BNX2_PCI_PCIE_CAPABILITY_INTERRUPT_MSG_NUM (0x1fL<<0)
+#define BNX2_PCI_PCIE_CAPABILITY_COMPLY_PCIE_1_1 (1L<<5)
+
+#define BNX2_PCI_DEVICE_CAPABILITY 0x000004d4
+#define BNX2_PCI_DEVICE_CAPABILITY_MAX_PL_SIZ_SUPPORTED (0x7L<<0)
+#define BNX2_PCI_DEVICE_CAPABILITY_EXTENDED_TAG_SUPPORT (1L<<5)
+#define BNX2_PCI_DEVICE_CAPABILITY_L0S_ACCEPTABLE_LATENCY (0x7L<<6)
+#define BNX2_PCI_DEVICE_CAPABILITY_L1_ACCEPTABLE_LATENCY (0x7L<<9)
+#define BNX2_PCI_DEVICE_CAPABILITY_ROLE_BASED_ERR_RPT (1L<<15)
+
+#define BNX2_PCI_LINK_CAPABILITY 0x000004dc
+#define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED (0xfL<<0)
+#define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED_0001 (1L<<0)
+#define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED_0010 (1L<<0)
+#define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_WIDTH (0x1fL<<4)
+#define BNX2_PCI_LINK_CAPABILITY_CLK_POWER_MGMT (1L<<9)
+#define BNX2_PCI_LINK_CAPABILITY_ASPM_SUPPORT (0x3L<<10)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT (0x7L<<12)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT_101 (5L<<12)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT_110 (6L<<12)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT (0x7L<<15)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT_001 (1L<<15)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT_010 (2L<<15)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT (0x7L<<18)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT_101 (5L<<18)
+#define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT_110 (6L<<18)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT (0x7L<<21)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT_001 (1L<<21)
+#define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT_010 (2L<<21)
+#define BNX2_PCI_LINK_CAPABILITY_PORT_NUM (0xffL<<24)
+
+#define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2 0x000004e4
+#define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_CMPL_TO_RANGE_SUPP (0xfL<<0)
+#define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_CMPL_TO_DISABL_SUPP (1L<<4)
+#define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_RESERVED (0x7ffffffL<<5)
+
+#define BNX2_PCI_PCIE_LINK_CAPABILITY_2 0x000004e8
+#define BNX2_PCI_PCIE_LINK_CAPABILITY_2_RESERVED (0xffffffffL<<0)
+
+#define BNX2_PCI_GRC_WINDOW1_ADDR 0x00000610
+#define BNX2_PCI_GRC_WINDOW1_ADDR_VALUE (0x1ffL<<13)
+
+#define BNX2_PCI_GRC_WINDOW2_ADDR 0x00000614
+#define BNX2_PCI_GRC_WINDOW2_ADDR_VALUE (0x1ffL<<13)
+
+#define BNX2_PCI_GRC_WINDOW3_ADDR 0x00000618
+#define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE (0x1ffL<<13)
/*
@@ -582,13 +697,23 @@ struct l2_fhdr {
#define BNX2_MISC_COMMAND 0x00000800
#define BNX2_MISC_COMMAND_ENABLE_ALL (1L<<0)
#define BNX2_MISC_COMMAND_DISABLE_ALL (1L<<1)
-#define BNX2_MISC_COMMAND_CORE_RESET (1L<<4)
-#define BNX2_MISC_COMMAND_HARD_RESET (1L<<5)
+#define BNX2_MISC_COMMAND_SW_RESET (1L<<4)
+#define BNX2_MISC_COMMAND_POR_RESET (1L<<5)
+#define BNX2_MISC_COMMAND_HD_RESET (1L<<6)
+#define BNX2_MISC_COMMAND_CMN_SW_RESET (1L<<7)
#define BNX2_MISC_COMMAND_PAR_ERROR (1L<<8)
+#define BNX2_MISC_COMMAND_CS16_ERR (1L<<9)
+#define BNX2_MISC_COMMAND_CS16_ERR_LOC (0xfL<<12)
#define BNX2_MISC_COMMAND_PAR_ERR_RAM (0x7fL<<16)
+#define BNX2_MISC_COMMAND_POWERDOWN_EVENT (1L<<23)
+#define BNX2_MISC_COMMAND_SW_SHUTDOWN (1L<<24)
+#define BNX2_MISC_COMMAND_SHUTDOWN_EN (1L<<25)
+#define BNX2_MISC_COMMAND_DINTEG_ATTN_EN (1L<<26)
+#define BNX2_MISC_COMMAND_PCIE_LINK_IN_L23 (1L<<27)
+#define BNX2_MISC_COMMAND_PCIE_DIS (1L<<28)
#define BNX2_MISC_CFG 0x00000804
-#define BNX2_MISC_CFG_PCI_GRC_TMOUT (1L<<0)
+#define BNX2_MISC_CFG_GRC_TMOUT (1L<<0)
#define BNX2_MISC_CFG_NVM_WR_EN (0x3L<<1)
#define BNX2_MISC_CFG_NVM_WR_EN_PROTECT (0L<<1)
#define BNX2_MISC_CFG_NVM_WR_EN_PCI (1L<<1)
@@ -596,16 +721,45 @@ struct l2_fhdr {
#define BNX2_MISC_CFG_NVM_WR_EN_ALLOW2 (3L<<1)
#define BNX2_MISC_CFG_BIST_EN (1L<<3)
#define BNX2_MISC_CFG_CK25_OUT_ALT_SRC (1L<<4)
-#define BNX2_MISC_CFG_BYPASS_BSCAN (1L<<5)
-#define BNX2_MISC_CFG_BYPASS_EJTAG (1L<<6)
+#define BNX2_MISC_CFG_RESERVED5_TE (1L<<5)
+#define BNX2_MISC_CFG_RESERVED6_TE (1L<<6)
#define BNX2_MISC_CFG_CLK_CTL_OVERRIDE (1L<<7)
-#define BNX2_MISC_CFG_LEDMODE (0x3L<<8)
+#define BNX2_MISC_CFG_LEDMODE (0x7L<<8)
#define BNX2_MISC_CFG_LEDMODE_MAC (0L<<8)
-#define BNX2_MISC_CFG_LEDMODE_GPHY1 (1L<<8)
-#define BNX2_MISC_CFG_LEDMODE_GPHY2 (2L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY1_TE (1L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY2_TE (2L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY3_TE (3L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY4_TE (4L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY5_TE (5L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY6_TE (6L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY7_TE (7L<<8)
+#define BNX2_MISC_CFG_MCP_GRC_TMOUT_TE (1L<<11)
+#define BNX2_MISC_CFG_DBU_GRC_TMOUT_TE (1L<<12)
+#define BNX2_MISC_CFG_LEDMODE_XI (0xfL<<8)
+#define BNX2_MISC_CFG_LEDMODE_MAC_XI (0L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY1_XI (1L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY2_XI (2L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY3_XI (3L<<8)
+#define BNX2_MISC_CFG_LEDMODE_MAC2_XI (4L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY4_XI (5L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY5_XI (6L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY6_XI (7L<<8)
+#define BNX2_MISC_CFG_LEDMODE_MAC3_XI (8L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY7_XI (9L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY8_XI (10L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY9_XI (11L<<8)
+#define BNX2_MISC_CFG_LEDMODE_MAC4_XI (12L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY10_XI (13L<<8)
+#define BNX2_MISC_CFG_LEDMODE_PHY11_XI (14L<<8)
+#define BNX2_MISC_CFG_LEDMODE_UNUSED_XI (15L<<8)
+#define BNX2_MISC_CFG_PORT_SELECT_XI (1L<<13)
+#define BNX2_MISC_CFG_PARITY_MODE_XI (1L<<14)
#define BNX2_MISC_ID 0x00000808
#define BNX2_MISC_ID_BOND_ID (0xfL<<0)
+#define BNX2_MISC_ID_BOND_ID_X (0L<<0)
+#define BNX2_MISC_ID_BOND_ID_C (3L<<0)
+#define BNX2_MISC_ID_BOND_ID_S (12L<<0)
#define BNX2_MISC_ID_CHIP_METAL (0xffL<<4)
#define BNX2_MISC_ID_CHIP_REV (0xfL<<12)
#define BNX2_MISC_ID_CHIP_NUM (0xffffL<<16)
@@ -639,6 +793,8 @@ struct l2_fhdr {
#define BNX2_MISC_ENABLE_STATUS_BITS_TIMER_ENABLE (1L<<25)
#define BNX2_MISC_ENABLE_STATUS_BITS_DMA_ENGINE_ENABLE (1L<<26)
#define BNX2_MISC_ENABLE_STATUS_BITS_UMP_ENABLE (1L<<27)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
#define BNX2_MISC_ENABLE_SET_BITS 0x00000810
#define BNX2_MISC_ENABLE_SET_BITS_TX_SCHEDULER_ENABLE (1L<<0)
@@ -669,6 +825,8 @@ struct l2_fhdr {
#define BNX2_MISC_ENABLE_SET_BITS_TIMER_ENABLE (1L<<25)
#define BNX2_MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE (1L<<26)
#define BNX2_MISC_ENABLE_SET_BITS_UMP_ENABLE (1L<<27)
+#define BNX2_MISC_ENABLE_SET_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
+#define BNX2_MISC_ENABLE_SET_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
#define BNX2_MISC_ENABLE_CLR_BITS 0x00000814
#define BNX2_MISC_ENABLE_CLR_BITS_TX_SCHEDULER_ENABLE (1L<<0)
@@ -699,6 +857,8 @@ struct l2_fhdr {
#define BNX2_MISC_ENABLE_CLR_BITS_TIMER_ENABLE (1L<<25)
#define BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE (1L<<26)
#define BNX2_MISC_ENABLE_CLR_BITS_UMP_ENABLE (1L<<27)
+#define BNX2_MISC_ENABLE_CLR_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
+#define BNX2_MISC_ENABLE_CLR_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
#define BNX2_MISC_CLOCK_CONTROL_BITS 0x00000818
#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0)
@@ -718,30 +878,41 @@ struct l2_fhdr {
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8)
-#define BNX2_MISC_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED0_XI (0x7L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_MIN_POWER (1L<<11)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50 (2L<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED1_XI (0xfL<<12)
#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16)
-#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17)
-#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18)
-#define BNX2_MISC_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19)
-#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20)
-
-#define BNX2_MISC_GPIO 0x0000081c
-#define BNX2_MISC_GPIO_VALUE (0xffL<<0)
-#define BNX2_MISC_GPIO_SET (0xffL<<8)
-#define BNX2_MISC_GPIO_CLR (0xffL<<16)
-#define BNX2_MISC_GPIO_FLOAT (0xffL<<24)
-
-#define BNX2_MISC_GPIO_INT 0x00000820
-#define BNX2_MISC_GPIO_INT_INT_STATE (0xfL<<0)
-#define BNX2_MISC_GPIO_INT_OLD_VALUE (0xfL<<8)
-#define BNX2_MISC_GPIO_INT_OLD_SET (0xfL<<16)
-#define BNX2_MISC_GPIO_INT_OLD_CLR (0xfL<<24)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_17_TE (1L<<17)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18_TE (1L<<18)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_19_TE (1L<<19)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_TE (0xfffL<<20)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_MGMT_XI (1L<<17)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED2_XI (0x3fL<<18)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_VCO_XI (0x7L<<24)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED3_XI (1L<<27)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_XI (0xfL<<28)
+
+#define BNX2_MISC_SPIO 0x0000081c
+#define BNX2_MISC_SPIO_VALUE (0xffL<<0)
+#define BNX2_MISC_SPIO_SET (0xffL<<8)
+#define BNX2_MISC_SPIO_CLR (0xffL<<16)
+#define BNX2_MISC_SPIO_FLOAT (0xffL<<24)
+
+#define BNX2_MISC_SPIO_INT 0x00000820
+#define BNX2_MISC_SPIO_INT_INT_STATE_TE (0xfL<<0)
+#define BNX2_MISC_SPIO_INT_OLD_VALUE_TE (0xfL<<8)
+#define BNX2_MISC_SPIO_INT_OLD_SET_TE (0xfL<<16)
+#define BNX2_MISC_SPIO_INT_OLD_CLR_TE (0xfL<<24)
+#define BNX2_MISC_SPIO_INT_INT_STATE_XI (0xffL<<0)
+#define BNX2_MISC_SPIO_INT_OLD_VALUE_XI (0xffL<<8)
+#define BNX2_MISC_SPIO_INT_OLD_SET_XI (0xffL<<16)
+#define BNX2_MISC_SPIO_INT_OLD_CLR_XI (0xffL<<24)
#define BNX2_MISC_CONFIG_LFSR 0x00000824
#define BNX2_MISC_CONFIG_LFSR_DIV (0xffffL<<0)
@@ -775,6 +946,8 @@ struct l2_fhdr {
#define BNX2_MISC_LFSR_MASK_BITS_TIMER_ENABLE (1L<<25)
#define BNX2_MISC_LFSR_MASK_BITS_DMA_ENGINE_ENABLE (1L<<26)
#define BNX2_MISC_LFSR_MASK_BITS_UMP_ENABLE (1L<<27)
+#define BNX2_MISC_LFSR_MASK_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
+#define BNX2_MISC_LFSR_MASK_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
#define BNX2_MISC_ARB_REQ0 0x0000082c
#define BNX2_MISC_ARB_REQ1 0x00000830
@@ -831,22 +1004,12 @@ struct l2_fhdr {
#define BNX2_MISC_ARB_GNT3_30 (0x7L<<24)
#define BNX2_MISC_ARB_GNT3_31 (0x7L<<28)
-#define BNX2_MISC_PRBS_CONTROL 0x00000878
-#define BNX2_MISC_PRBS_CONTROL_EN (1L<<0)
-#define BNX2_MISC_PRBS_CONTROL_RSTB (1L<<1)
-#define BNX2_MISC_PRBS_CONTROL_INV (1L<<2)
-#define BNX2_MISC_PRBS_CONTROL_ERR_CLR (1L<<3)
-#define BNX2_MISC_PRBS_CONTROL_ORDER (0x3L<<4)
-#define BNX2_MISC_PRBS_CONTROL_ORDER_7TH (0L<<4)
-#define BNX2_MISC_PRBS_CONTROL_ORDER_15TH (1L<<4)
-#define BNX2_MISC_PRBS_CONTROL_ORDER_23RD (2L<<4)
-#define BNX2_MISC_PRBS_CONTROL_ORDER_31ST (3L<<4)
-
-#define BNX2_MISC_PRBS_STATUS 0x0000087c
-#define BNX2_MISC_PRBS_STATUS_LOCK (1L<<0)
-#define BNX2_MISC_PRBS_STATUS_STKY (1L<<1)
-#define BNX2_MISC_PRBS_STATUS_ERRORS (0x3fffL<<2)
-#define BNX2_MISC_PRBS_STATUS_STATE (0xfL<<16)
+#define BNX2_MISC_RESERVED1 0x00000878
+#define BNX2_MISC_RESERVED1_MISC_RESERVED1_VALUE (0x3fL<<0)
+
+#define BNX2_MISC_RESERVED2 0x0000087c
+#define BNX2_MISC_RESERVED2_PCIE_DIS (1L<<0)
+#define BNX2_MISC_RESERVED2_LINK_IN_L23 (1L<<1)
#define BNX2_MISC_SM_ASF_CONTROL 0x00000880
#define BNX2_MISC_SM_ASF_CONTROL_ASF_RST (1L<<0)
@@ -857,13 +1020,15 @@ struct l2_fhdr {
#define BNX2_MISC_SM_ASF_CONTROL_PL_TO (1L<<5)
#define BNX2_MISC_SM_ASF_CONTROL_RT_TO (1L<<6)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_EVENT (1L<<7)
-#define BNX2_MISC_SM_ASF_CONTROL_RES (0xfL<<8)
+#define BNX2_MISC_SM_ASF_CONTROL_STRETCH_EN (1L<<8)
+#define BNX2_MISC_SM_ASF_CONTROL_STRETCH_PULSE (1L<<9)
+#define BNX2_MISC_SM_ASF_CONTROL_RES (0x3L<<10)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_EN (1L<<12)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_BB_EN (1L<<13)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_NO_ADDR_FILT (1L<<14)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_AUTOREAD (1L<<15)
-#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1 (0x3fL<<16)
-#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2 (0x3fL<<24)
+#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1 (0x7fL<<16)
+#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2 (0x7fL<<23)
#define BNX2_MISC_SM_ASF_CONTROL_EN_NIC_SMB_ADDR_0 (1L<<30)
#define BNX2_MISC_SM_ASF_CONTROL_SMB_EARLY_ATTN (1L<<31)
@@ -891,13 +1056,13 @@ struct l2_fhdr {
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS (0xfL<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_OK (0L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_NACK (1L<<20)
-#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK (9L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_UFLOW (2L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_STOP (3L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_TIMEOUT (4L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_LOST (5L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK (6L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK (9L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_LOST (0xdL<<20)
-#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK (0x6L<<20)
#define BNX2_MISC_SMB_OUT_SMB_OUT_SLAVEMODE (1L<<24)
#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_EN (1L<<25)
#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_IN (1L<<26)
@@ -955,6 +1120,38 @@ struct l2_fhdr {
#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPC (1L<<29)
#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPM (1L<<30)
#define BNX2_MISC_PERR_ENA0_RV2P_MISC_CB0REGS (1L<<31)
+#define BNX2_MISC_PERR_ENA0_COM_DMAE_PERR_EN_XI (1L<<0)
+#define BNX2_MISC_PERR_ENA0_CP_DMAE_PERR_EN_XI (1L<<1)
+#define BNX2_MISC_PERR_ENA0_RPM_ACPIBEMEM_PERR_EN_XI (1L<<2)
+#define BNX2_MISC_PERR_ENA0_CTX_USAGE_CNT_PERR_EN_XI (1L<<3)
+#define BNX2_MISC_PERR_ENA0_CTX_PGTBL_PERR_EN_XI (1L<<4)
+#define BNX2_MISC_PERR_ENA0_CTX_CACHE_PERR_EN_XI (1L<<5)
+#define BNX2_MISC_PERR_ENA0_CTX_MIRROR_PERR_EN_XI (1L<<6)
+#define BNX2_MISC_PERR_ENA0_COM_CTXC_PERR_EN_XI (1L<<7)
+#define BNX2_MISC_PERR_ENA0_COM_SCPAD_PERR_EN_XI (1L<<8)
+#define BNX2_MISC_PERR_ENA0_CP_CTXC_PERR_EN_XI (1L<<9)
+#define BNX2_MISC_PERR_ENA0_CP_SCPAD_PERR_EN_XI (1L<<10)
+#define BNX2_MISC_PERR_ENA0_RXP_RBUFC_PERR_EN_XI (1L<<11)
+#define BNX2_MISC_PERR_ENA0_RXP_CTXC_PERR_EN_XI (1L<<12)
+#define BNX2_MISC_PERR_ENA0_RXP_SCPAD_PERR_EN_XI (1L<<13)
+#define BNX2_MISC_PERR_ENA0_TPAT_SCPAD_PERR_EN_XI (1L<<14)
+#define BNX2_MISC_PERR_ENA0_TXP_CTXC_PERR_EN_XI (1L<<15)
+#define BNX2_MISC_PERR_ENA0_TXP_SCPAD_PERR_EN_XI (1L<<16)
+#define BNX2_MISC_PERR_ENA0_CS_TMEM_PERR_EN_XI (1L<<17)
+#define BNX2_MISC_PERR_ENA0_MQ_CTX_PERR_EN_XI (1L<<18)
+#define BNX2_MISC_PERR_ENA0_RPM_DFIFOMEM_PERR_EN_XI (1L<<19)
+#define BNX2_MISC_PERR_ENA0_RPC_DFIFOMEM_PERR_EN_XI (1L<<20)
+#define BNX2_MISC_PERR_ENA0_RBUF_PTRMEM_PERR_EN_XI (1L<<21)
+#define BNX2_MISC_PERR_ENA0_RBUF_DATAMEM_PERR_EN_XI (1L<<22)
+#define BNX2_MISC_PERR_ENA0_RV2P_P2IRAM_PERR_EN_XI (1L<<23)
+#define BNX2_MISC_PERR_ENA0_RV2P_P1IRAM_PERR_EN_XI (1L<<24)
+#define BNX2_MISC_PERR_ENA0_RV2P_CB1REGS_PERR_EN_XI (1L<<25)
+#define BNX2_MISC_PERR_ENA0_RV2P_CB0REGS_PERR_EN_XI (1L<<26)
+#define BNX2_MISC_PERR_ENA0_TPBUF_PERR_EN_XI (1L<<27)
+#define BNX2_MISC_PERR_ENA0_THBUF_PERR_EN_XI (1L<<28)
+#define BNX2_MISC_PERR_ENA0_TDMA_PERR_EN_XI (1L<<29)
+#define BNX2_MISC_PERR_ENA0_TBDC_PERR_EN_XI (1L<<30)
+#define BNX2_MISC_PERR_ENA0_TSCH_LR_PERR_EN_XI (1L<<31)
#define BNX2_MISC_PERR_ENA1 0x000008a8
#define BNX2_MISC_PERR_ENA1_RV2P_MISC_CB1REGS (1L<<0)
@@ -989,6 +1186,35 @@ struct l2_fhdr {
#define BNX2_MISC_PERR_ENA1_RXPQ_MISC (1L<<29)
#define BNX2_MISC_PERR_ENA1_RXPCQ_MISC (1L<<30)
#define BNX2_MISC_PERR_ENA1_RLUPQ_MISC (1L<<31)
+#define BNX2_MISC_PERR_ENA1_RBDC_PERR_EN_XI (1L<<0)
+#define BNX2_MISC_PERR_ENA1_RDMA_DFIFO_PERR_EN_XI (1L<<2)
+#define BNX2_MISC_PERR_ENA1_HC_STATS_PERR_EN_XI (1L<<3)
+#define BNX2_MISC_PERR_ENA1_HC_MSIX_PERR_EN_XI (1L<<4)
+#define BNX2_MISC_PERR_ENA1_HC_PRODUCSTB_PERR_EN_XI (1L<<5)
+#define BNX2_MISC_PERR_ENA1_HC_CONSUMSTB_PERR_EN_XI (1L<<6)
+#define BNX2_MISC_PERR_ENA1_TPATQ_PERR_EN_XI (1L<<7)
+#define BNX2_MISC_PERR_ENA1_MCPQ_PERR_EN_XI (1L<<8)
+#define BNX2_MISC_PERR_ENA1_TDMAQ_PERR_EN_XI (1L<<9)
+#define BNX2_MISC_PERR_ENA1_TXPQ_PERR_EN_XI (1L<<10)
+#define BNX2_MISC_PERR_ENA1_COMTQ_PERR_EN_XI (1L<<11)
+#define BNX2_MISC_PERR_ENA1_COMQ_PERR_EN_XI (1L<<12)
+#define BNX2_MISC_PERR_ENA1_RLUPQ_PERR_EN_XI (1L<<13)
+#define BNX2_MISC_PERR_ENA1_RXPQ_PERR_EN_XI (1L<<14)
+#define BNX2_MISC_PERR_ENA1_RV2PPQ_PERR_EN_XI (1L<<15)
+#define BNX2_MISC_PERR_ENA1_RDMAQ_PERR_EN_XI (1L<<16)
+#define BNX2_MISC_PERR_ENA1_TASQ_PERR_EN_XI (1L<<17)
+#define BNX2_MISC_PERR_ENA1_TBDRQ_PERR_EN_XI (1L<<18)
+#define BNX2_MISC_PERR_ENA1_TSCHQ_PERR_EN_XI (1L<<19)
+#define BNX2_MISC_PERR_ENA1_COMXQ_PERR_EN_XI (1L<<20)
+#define BNX2_MISC_PERR_ENA1_RXPCQ_PERR_EN_XI (1L<<21)
+#define BNX2_MISC_PERR_ENA1_RV2PTQ_PERR_EN_XI (1L<<22)
+#define BNX2_MISC_PERR_ENA1_RV2PMQ_PERR_EN_XI (1L<<23)
+#define BNX2_MISC_PERR_ENA1_CPQ_PERR_EN_XI (1L<<24)
+#define BNX2_MISC_PERR_ENA1_CSQ_PERR_EN_XI (1L<<25)
+#define BNX2_MISC_PERR_ENA1_RLUP_CID_PERR_EN_XI (1L<<26)
+#define BNX2_MISC_PERR_ENA1_RV2PCS_TMEM_PERR_EN_XI (1L<<27)
+#define BNX2_MISC_PERR_ENA1_RV2PCSQ_PERR_EN_XI (1L<<28)
+#define BNX2_MISC_PERR_ENA1_MQ_IDX_PERR_EN_XI (1L<<29)
#define BNX2_MISC_PERR_ENA2 0x000008ac
#define BNX2_MISC_PERR_ENA2_COMQ_MISC (1L<<0)
@@ -1000,19 +1226,498 @@ struct l2_fhdr {
#define BNX2_MISC_PERR_ENA2_TDMAQ_MISC (1L<<6)
#define BNX2_MISC_PERR_ENA2_TPATQ_MISC (1L<<7)
#define BNX2_MISC_PERR_ENA2_TASQ_MISC (1L<<8)
+#define BNX2_MISC_PERR_ENA2_TGT_FIFO_PERR_EN_XI (1L<<0)
+#define BNX2_MISC_PERR_ENA2_UMP_TX_PERR_EN_XI (1L<<1)
+#define BNX2_MISC_PERR_ENA2_UMP_RX_PERR_EN_XI (1L<<2)
+#define BNX2_MISC_PERR_ENA2_MCP_ROM_PERR_EN_XI (1L<<3)
+#define BNX2_MISC_PERR_ENA2_MCP_SCPAD_PERR_EN_XI (1L<<4)
+#define BNX2_MISC_PERR_ENA2_HB_MEM_PERR_EN_XI (1L<<5)
+#define BNX2_MISC_PERR_ENA2_PCIE_REPLAY_PERR_EN_XI (1L<<6)
#define BNX2_MISC_DEBUG_VECTOR_SEL 0x000008b0
#define BNX2_MISC_DEBUG_VECTOR_SEL_0 (0xfffL<<0)
#define BNX2_MISC_DEBUG_VECTOR_SEL_1 (0xfffL<<12)
+#define BNX2_MISC_DEBUG_VECTOR_SEL_1_XI (0xfffL<<15)
#define BNX2_MISC_VREG_CONTROL 0x000008b4
#define BNX2_MISC_VREG_CONTROL_1_2 (0xfL<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_XI (0xfL<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS14_XI (0L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS12_XI (1L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS10_XI (2L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS8_XI (3L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS6_XI (4L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS4_XI (5L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS2_XI (6L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_NOM_XI (7L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS2_XI (8L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS4_XI (9L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS6_XI (10L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS8_XI (11L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS10_XI (12L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS12_XI (13L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS14_XI (14L<<0)
+#define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS16_XI (15L<<0)
#define BNX2_MISC_VREG_CONTROL_2_5 (0xfL<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS14 (0L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS12 (1L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS10 (2L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS8 (3L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS6 (4L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS4 (5L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_PLUS2 (6L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_NOM (7L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS2 (8L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS4 (9L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS6 (10L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS8 (11L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS10 (12L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS12 (13L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS14 (14L<<4)
+#define BNX2_MISC_VREG_CONTROL_2_5_MINUS16 (15L<<4)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT (0xfL<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS14 (0L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS12 (1L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS10 (2L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS8 (3L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS6 (4L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS4 (5L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS2 (6L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_NOM (7L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS2 (8L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS4 (9L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS6 (10L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS8 (11L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS10 (12L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS12 (13L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS14 (14L<<8)
+#define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS16 (15L<<8)
#define BNX2_MISC_FINAL_CLK_CTL_VAL 0x000008b8
#define BNX2_MISC_FINAL_CLK_CTL_VAL_MISC_FINAL_CLK_CTL_VAL (0x3ffffffL<<6)
-#define BNX2_MISC_UNUSED0 0x000008bc
+#define BNX2_MISC_GP_HW_CTL0 0x000008bc
+#define BNX2_MISC_GP_HW_CTL0_TX_DRIVE (1L<<0)
+#define BNX2_MISC_GP_HW_CTL0_RMII_MODE (1L<<1)
+#define BNX2_MISC_GP_HW_CTL0_RMII_CRSDV_SEL (1L<<2)
+#define BNX2_MISC_GP_HW_CTL0_RVMII_MODE (1L<<3)
+#define BNX2_MISC_GP_HW_CTL0_FLASH_SAMP_SCLK_NEGEDGE_TE (1L<<4)
+#define BNX2_MISC_GP_HW_CTL0_HIDDEN_REVISION_ID_TE (1L<<5)
+#define BNX2_MISC_GP_HW_CTL0_HC_CNTL_TMOUT_CTR_RST_TE (1L<<6)
+#define BNX2_MISC_GP_HW_CTL0_RESERVED1_XI (0x7L<<4)
+#define BNX2_MISC_GP_HW_CTL0_ENA_CORE_RST_ON_MAIN_PWR_GOING_AWAY (1L<<7)
+#define BNX2_MISC_GP_HW_CTL0_ENA_SEL_VAUX_B_IN_L2_TE (1L<<8)
+#define BNX2_MISC_GP_HW_CTL0_GRC_BNK_FREE_FIX_TE (1L<<9)
+#define BNX2_MISC_GP_HW_CTL0_LED_ACT_SEL_TE (1L<<10)
+#define BNX2_MISC_GP_HW_CTL0_RESERVED2_XI (0x7L<<8)
+#define BNX2_MISC_GP_HW_CTL0_UP1_DEF0 (1L<<11)
+#define BNX2_MISC_GP_HW_CTL0_FIBER_MODE_DIS_DEF (1L<<12)
+#define BNX2_MISC_GP_HW_CTL0_FORCE2500_DEF (1L<<13)
+#define BNX2_MISC_GP_HW_CTL0_AUTODETECT_DIS_DEF (1L<<14)
+#define BNX2_MISC_GP_HW_CTL0_PARALLEL_DETECT_DEF (1L<<15)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI (0xfL<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_3MA (0L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_2P5MA (1L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_2P0MA (3L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_1P5MA (5L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_1P0MA (7L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_PWRDN (15L<<16)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PRE2DIS (1L<<20)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PRE1DIS (1L<<21)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT (0x3L<<22)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_M6P (0L<<22)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_M0P (1L<<22)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_P0P (2L<<22)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_P6P (3L<<22)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT (0x3L<<24)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_M6P (0L<<24)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_M0P (1L<<24)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_P0P (2L<<24)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_P6P (3L<<24)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ (0x3L<<26)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_240UA (0L<<26)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_160UA (1L<<26)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_400UA (2L<<26)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_320UA (3L<<26)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ (0x3L<<28)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_240UA (0L<<28)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_160UA (1L<<28)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_400UA (2L<<28)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_320UA (3L<<28)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ (0x3L<<30)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P57 (0L<<30)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P45 (1L<<30)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P62 (2L<<30)
+#define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P66 (3L<<30)
+
+#define BNX2_MISC_GP_HW_CTL1 0x000008c0
+#define BNX2_MISC_GP_HW_CTL1_1_ATTN_BTN_PRSNT_TE (1L<<0)
+#define BNX2_MISC_GP_HW_CTL1_1_ATTN_IND_PRSNT_TE (1L<<1)
+#define BNX2_MISC_GP_HW_CTL1_1_PWR_IND_PRSNT_TE (1L<<2)
+#define BNX2_MISC_GP_HW_CTL1_0_PCIE_LOOPBACK_TE (1L<<3)
+#define BNX2_MISC_GP_HW_CTL1_RESERVED_SOFT_XI (0xffffL<<0)
+#define BNX2_MISC_GP_HW_CTL1_RESERVED_HARD_XI (0xffffL<<16)
+
+#define BNX2_MISC_NEW_HW_CTL 0x000008c4
+#define BNX2_MISC_NEW_HW_CTL_MAIN_POR_BYPASS (1L<<0)
+#define BNX2_MISC_NEW_HW_CTL_RINGOSC_ENABLE (1L<<1)
+#define BNX2_MISC_NEW_HW_CTL_RINGOSC_SEL0 (1L<<2)
+#define BNX2_MISC_NEW_HW_CTL_RINGOSC_SEL1 (1L<<3)
+#define BNX2_MISC_NEW_HW_CTL_RESERVED_SHARED (0xfffL<<4)
+#define BNX2_MISC_NEW_HW_CTL_RESERVED_SPLIT (0xffffL<<16)
+
+#define BNX2_MISC_NEW_CORE_CTL 0x000008c8
+#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0)
+#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1)
+#define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2)
+#define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16)
+
+#define BNX2_MISC_ECO_HW_CTL 0x000008cc
+#define BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN (1L<<0)
+#define BNX2_MISC_ECO_HW_CTL_RESERVED_SOFT (0x7fffL<<1)
+#define BNX2_MISC_ECO_HW_CTL_RESERVED_HARD (0xffffL<<16)
+
+#define BNX2_MISC_ECO_CORE_CTL 0x000008d0
+#define BNX2_MISC_ECO_CORE_CTL_RESERVED_SOFT (0xffffL<<0)
+#define BNX2_MISC_ECO_CORE_CTL_RESERVED_HARD (0xffffL<<16)
+
+#define BNX2_MISC_PPIO 0x000008d4
+#define BNX2_MISC_PPIO_VALUE (0xfL<<0)
+#define BNX2_MISC_PPIO_SET (0xfL<<8)
+#define BNX2_MISC_PPIO_CLR (0xfL<<16)
+#define BNX2_MISC_PPIO_FLOAT (0xfL<<24)
+
+#define BNX2_MISC_PPIO_INT 0x000008d8
+#define BNX2_MISC_PPIO_INT_INT_STATE (0xfL<<0)
+#define BNX2_MISC_PPIO_INT_OLD_VALUE (0xfL<<8)
+#define BNX2_MISC_PPIO_INT_OLD_SET (0xfL<<16)
+#define BNX2_MISC_PPIO_INT_OLD_CLR (0xfL<<24)
+
+#define BNX2_MISC_RESET_NUMS 0x000008dc
+#define BNX2_MISC_RESET_NUMS_NUM_HARD_RESETS (0x7L<<0)
+#define BNX2_MISC_RESET_NUMS_NUM_PCIE_RESETS (0x7L<<4)
+#define BNX2_MISC_RESET_NUMS_NUM_PERSTB_RESETS (0x7L<<8)
+#define BNX2_MISC_RESET_NUMS_NUM_CMN_RESETS (0x7L<<12)
+#define BNX2_MISC_RESET_NUMS_NUM_PORT_RESETS (0x7L<<16)
+
+#define BNX2_MISC_CS16_ERR 0x000008e0
+#define BNX2_MISC_CS16_ERR_ENA_PCI (1L<<0)
+#define BNX2_MISC_CS16_ERR_ENA_RDMA (1L<<1)
+#define BNX2_MISC_CS16_ERR_ENA_TDMA (1L<<2)
+#define BNX2_MISC_CS16_ERR_ENA_EMAC (1L<<3)
+#define BNX2_MISC_CS16_ERR_ENA_CTX (1L<<4)
+#define BNX2_MISC_CS16_ERR_ENA_TBDR (1L<<5)
+#define BNX2_MISC_CS16_ERR_ENA_RBDC (1L<<6)
+#define BNX2_MISC_CS16_ERR_ENA_COM (1L<<7)
+#define BNX2_MISC_CS16_ERR_ENA_CP (1L<<8)
+#define BNX2_MISC_CS16_ERR_STA_PCI (1L<<16)
+#define BNX2_MISC_CS16_ERR_STA_RDMA (1L<<17)
+#define BNX2_MISC_CS16_ERR_STA_TDMA (1L<<18)
+#define BNX2_MISC_CS16_ERR_STA_EMAC (1L<<19)
+#define BNX2_MISC_CS16_ERR_STA_CTX (1L<<20)
+#define BNX2_MISC_CS16_ERR_STA_TBDR (1L<<21)
+#define BNX2_MISC_CS16_ERR_STA_RBDC (1L<<22)
+#define BNX2_MISC_CS16_ERR_STA_COM (1L<<23)
+#define BNX2_MISC_CS16_ERR_STA_CP (1L<<24)
+
+#define BNX2_MISC_SPIO_EVENT 0x000008e4
+#define BNX2_MISC_SPIO_EVENT_ENABLE (0xffL<<0)
+
+#define BNX2_MISC_PPIO_EVENT 0x000008e8
+#define BNX2_MISC_PPIO_EVENT_ENABLE (0xfL<<0)
+
+#define BNX2_MISC_DUAL_MEDIA_CTRL 0x000008ec
+#define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID (0xffL<<0)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_X (0L<<0)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C (3L<<0)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S (12L<<0)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP (0x7L<<8)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PORT_SWAP_PIN (1L<<11)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES1_SIGDET (1L<<12)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES0_SIGDET (1L<<13)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY1_SIGDET (1L<<14)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY0_SIGDET (1L<<15)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_LCPLL_RST (1L<<16)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES1_RST (1L<<17)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES0_RST (1L<<18)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY1_RST (1L<<19)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY0_RST (1L<<20)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL (0x7L<<21)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PORT_SWAP (1L<<24)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE (1L<<25)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ (0xfL<<26)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_SER1_IDDQ (1L<<26)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_SER0_IDDQ (2L<<26)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_PHY1_IDDQ (4L<<26)
+#define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_PHY0_IDDQ (8L<<26)
+
+#define BNX2_MISC_OTP_CMD1 0x000008f0
+#define BNX2_MISC_OTP_CMD1_FMODE (0x7L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_IDLE (0L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_WRITE (1L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_INIT (2L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_SET (3L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_RST (4L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_VERIFY (5L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_RESERVED0 (6L<<0)
+#define BNX2_MISC_OTP_CMD1_FMODE_RESERVED1 (7L<<0)
+#define BNX2_MISC_OTP_CMD1_USEPINS (1L<<8)
+#define BNX2_MISC_OTP_CMD1_PROGSEL (1L<<9)
+#define BNX2_MISC_OTP_CMD1_PROGSTART (1L<<10)
+#define BNX2_MISC_OTP_CMD1_PCOUNT (0x7L<<16)
+#define BNX2_MISC_OTP_CMD1_PBYP (1L<<19)
+#define BNX2_MISC_OTP_CMD1_VSEL (0xfL<<20)
+#define BNX2_MISC_OTP_CMD1_TM (0x7L<<27)
+#define BNX2_MISC_OTP_CMD1_SADBYP (1L<<30)
+#define BNX2_MISC_OTP_CMD1_DEBUG (1L<<31)
+
+#define BNX2_MISC_OTP_CMD2 0x000008f4
+#define BNX2_MISC_OTP_CMD2_OTP_ROM_ADDR (0x3ffL<<0)
+#define BNX2_MISC_OTP_CMD2_DOSEL (0x7fL<<16)
+#define BNX2_MISC_OTP_CMD2_DOSEL_0 (0L<<16)
+#define BNX2_MISC_OTP_CMD2_DOSEL_1 (1L<<16)
+#define BNX2_MISC_OTP_CMD2_DOSEL_127 (127L<<16)
+
+#define BNX2_MISC_OTP_STATUS 0x000008f8
+#define BNX2_MISC_OTP_STATUS_DATA (0xffL<<0)
+#define BNX2_MISC_OTP_STATUS_VALID (1L<<8)
+#define BNX2_MISC_OTP_STATUS_BUSY (1L<<9)
+#define BNX2_MISC_OTP_STATUS_BUSYSM (1L<<10)
+#define BNX2_MISC_OTP_STATUS_DONE (1L<<11)
+
+#define BNX2_MISC_OTP_SHIFT1_CMD 0x000008fc
+#define BNX2_MISC_OTP_SHIFT1_CMD_RESET_MODE_N (1L<<0)
+#define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_DONE (1L<<1)
+#define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_START (1L<<2)
+#define BNX2_MISC_OTP_SHIFT1_CMD_LOAD_DATA (1L<<3)
+#define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_SELECT (0x1fL<<8)
+
+#define BNX2_MISC_OTP_SHIFT1_DATA 0x00000900
+#define BNX2_MISC_OTP_SHIFT2_CMD 0x00000904
+#define BNX2_MISC_OTP_SHIFT2_CMD_RESET_MODE_N (1L<<0)
+#define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_DONE (1L<<1)
+#define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_START (1L<<2)
+#define BNX2_MISC_OTP_SHIFT2_CMD_LOAD_DATA (1L<<3)
+#define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_SELECT (0x1fL<<8)
+
+#define BNX2_MISC_OTP_SHIFT2_DATA 0x00000908
+#define BNX2_MISC_BIST_CS0 0x0000090c
+#define BNX2_MISC_BIST_CS0_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS0_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS0_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS0_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS0_MBIST_GO (1L<<9)
+#define BNX2_MISC_BIST_CS0_BIST_OVERRIDE (1L<<31)
+
+#define BNX2_MISC_BIST_MEMSTATUS0 0x00000910
+#define BNX2_MISC_BIST_CS1 0x00000914
+#define BNX2_MISC_BIST_CS1_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS1_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS1_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS1_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS1_MBIST_GO (1L<<9)
+
+#define BNX2_MISC_BIST_MEMSTATUS1 0x00000918
+#define BNX2_MISC_BIST_CS2 0x0000091c
+#define BNX2_MISC_BIST_CS2_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS2_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS2_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS2_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS2_MBIST_GO (1L<<9)
+
+#define BNX2_MISC_BIST_MEMSTATUS2 0x00000920
+#define BNX2_MISC_BIST_CS3 0x00000924
+#define BNX2_MISC_BIST_CS3_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS3_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS3_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS3_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS3_MBIST_GO (1L<<9)
+
+#define BNX2_MISC_BIST_MEMSTATUS3 0x00000928
+#define BNX2_MISC_BIST_CS4 0x0000092c
+#define BNX2_MISC_BIST_CS4_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS4_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS4_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS4_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS4_MBIST_GO (1L<<9)
+
+#define BNX2_MISC_BIST_MEMSTATUS4 0x00000930
+#define BNX2_MISC_BIST_CS5 0x00000934
+#define BNX2_MISC_BIST_CS5_MBIST_EN (1L<<0)
+#define BNX2_MISC_BIST_CS5_BIST_SETUP (0x3L<<1)
+#define BNX2_MISC_BIST_CS5_MBIST_ASYNC_RESET (1L<<3)
+#define BNX2_MISC_BIST_CS5_MBIST_DONE (1L<<8)
+#define BNX2_MISC_BIST_CS5_MBIST_GO (1L<<9)
+
+#define BNX2_MISC_BIST_MEMSTATUS5 0x00000938
+#define BNX2_MISC_MEM_TM0 0x0000093c
+#define BNX2_MISC_MEM_TM0_PCIE_REPLAY_TM (0xfL<<0)
+#define BNX2_MISC_MEM_TM0_MCP_SCPAD (0xfL<<8)
+#define BNX2_MISC_MEM_TM0_UMP_TM (0xffL<<16)
+#define BNX2_MISC_MEM_TM0_HB_MEM_TM (0xfL<<24)
+
+#define BNX2_MISC_USPLL_CTRL 0x00000940
+#define BNX2_MISC_USPLL_CTRL_PH_DET_DIS (1L<<0)
+#define BNX2_MISC_USPLL_CTRL_FREQ_DET_DIS (1L<<1)
+#define BNX2_MISC_USPLL_CTRL_LCPX (0x3fL<<2)
+#define BNX2_MISC_USPLL_CTRL_RX (0x3L<<8)
+#define BNX2_MISC_USPLL_CTRL_VC_EN (1L<<10)
+#define BNX2_MISC_USPLL_CTRL_VCO_MG (0x3L<<11)
+#define BNX2_MISC_USPLL_CTRL_KVCO_XF (0x7L<<13)
+#define BNX2_MISC_USPLL_CTRL_KVCO_XS (0x7L<<16)
+#define BNX2_MISC_USPLL_CTRL_TESTD_EN (1L<<19)
+#define BNX2_MISC_USPLL_CTRL_TESTD_SEL (0x7L<<20)
+#define BNX2_MISC_USPLL_CTRL_TESTA_EN (1L<<23)
+#define BNX2_MISC_USPLL_CTRL_TESTA_SEL (0x3L<<24)
+#define BNX2_MISC_USPLL_CTRL_ATTEN_FREF (1L<<26)
+#define BNX2_MISC_USPLL_CTRL_DIGITAL_RST (1L<<27)
+#define BNX2_MISC_USPLL_CTRL_ANALOG_RST (1L<<28)
+#define BNX2_MISC_USPLL_CTRL_LOCK (1L<<29)
+
+#define BNX2_MISC_PERR_STATUS0 0x00000944
+#define BNX2_MISC_PERR_STATUS0_COM_DMAE_PERR (1L<<0)
+#define BNX2_MISC_PERR_STATUS0_CP_DMAE_PERR (1L<<1)
+#define BNX2_MISC_PERR_STATUS0_RPM_ACPIBEMEM_PERR (1L<<2)
+#define BNX2_MISC_PERR_STATUS0_CTX_USAGE_CNT_PERR (1L<<3)
+#define BNX2_MISC_PERR_STATUS0_CTX_PGTBL_PERR (1L<<4)
+#define BNX2_MISC_PERR_STATUS0_CTX_CACHE_PERR (1L<<5)
+#define BNX2_MISC_PERR_STATUS0_CTX_MIRROR_PERR (1L<<6)
+#define BNX2_MISC_PERR_STATUS0_COM_CTXC_PERR (1L<<7)
+#define BNX2_MISC_PERR_STATUS0_COM_SCPAD_PERR (1L<<8)
+#define BNX2_MISC_PERR_STATUS0_CP_CTXC_PERR (1L<<9)
+#define BNX2_MISC_PERR_STATUS0_CP_SCPAD_PERR (1L<<10)
+#define BNX2_MISC_PERR_STATUS0_RXP_RBUFC_PERR (1L<<11)
+#define BNX2_MISC_PERR_STATUS0_RXP_CTXC_PERR (1L<<12)
+#define BNX2_MISC_PERR_STATUS0_RXP_SCPAD_PERR (1L<<13)
+#define BNX2_MISC_PERR_STATUS0_TPAT_SCPAD_PERR (1L<<14)
+#define BNX2_MISC_PERR_STATUS0_TXP_CTXC_PERR (1L<<15)
+#define BNX2_MISC_PERR_STATUS0_TXP_SCPAD_PERR (1L<<16)
+#define BNX2_MISC_PERR_STATUS0_CS_TMEM_PERR (1L<<17)
+#define BNX2_MISC_PERR_STATUS0_MQ_CTX_PERR (1L<<18)
+#define BNX2_MISC_PERR_STATUS0_RPM_DFIFOMEM_PERR (1L<<19)
+#define BNX2_MISC_PERR_STATUS0_RPC_DFIFOMEM_PERR (1L<<20)
+#define BNX2_MISC_PERR_STATUS0_RBUF_PTRMEM_PERR (1L<<21)
+#define BNX2_MISC_PERR_STATUS0_RBUF_DATAMEM_PERR (1L<<22)
+#define BNX2_MISC_PERR_STATUS0_RV2P_P2IRAM_PERR (1L<<23)
+#define BNX2_MISC_PERR_STATUS0_RV2P_P1IRAM_PERR (1L<<24)
+#define BNX2_MISC_PERR_STATUS0_RV2P_CB1REGS_PERR (1L<<25)
+#define BNX2_MISC_PERR_STATUS0_RV2P_CB0REGS_PERR (1L<<26)
+#define BNX2_MISC_PERR_STATUS0_TPBUF_PERR (1L<<27)
+#define BNX2_MISC_PERR_STATUS0_THBUF_PERR (1L<<28)
+#define BNX2_MISC_PERR_STATUS0_TDMA_PERR (1L<<29)
+#define BNX2_MISC_PERR_STATUS0_TBDC_PERR (1L<<30)
+#define BNX2_MISC_PERR_STATUS0_TSCH_LR_PERR (1L<<31)
+
+#define BNX2_MISC_PERR_STATUS1 0x00000948
+#define BNX2_MISC_PERR_STATUS1_RBDC_PERR (1L<<0)
+#define BNX2_MISC_PERR_STATUS1_RDMA_DFIFO_PERR (1L<<2)
+#define BNX2_MISC_PERR_STATUS1_HC_STATS_PERR (1L<<3)
+#define BNX2_MISC_PERR_STATUS1_HC_MSIX_PERR (1L<<4)
+#define BNX2_MISC_PERR_STATUS1_HC_PRODUCSTB_PERR (1L<<5)
+#define BNX2_MISC_PERR_STATUS1_HC_CONSUMSTB_PERR (1L<<6)
+#define BNX2_MISC_PERR_STATUS1_TPATQ_PERR (1L<<7)
+#define BNX2_MISC_PERR_STATUS1_MCPQ_PERR (1L<<8)
+#define BNX2_MISC_PERR_STATUS1_TDMAQ_PERR (1L<<9)
+#define BNX2_MISC_PERR_STATUS1_TXPQ_PERR (1L<<10)
+#define BNX2_MISC_PERR_STATUS1_COMTQ_PERR (1L<<11)
+#define BNX2_MISC_PERR_STATUS1_COMQ_PERR (1L<<12)
+#define BNX2_MISC_PERR_STATUS1_RLUPQ_PERR (1L<<13)
+#define BNX2_MISC_PERR_STATUS1_RXPQ_PERR (1L<<14)
+#define BNX2_MISC_PERR_STATUS1_RV2PPQ_PERR (1L<<15)
+#define BNX2_MISC_PERR_STATUS1_RDMAQ_PERR (1L<<16)
+#define BNX2_MISC_PERR_STATUS1_TASQ_PERR (1L<<17)
+#define BNX2_MISC_PERR_STATUS1_TBDRQ_PERR (1L<<18)
+#define BNX2_MISC_PERR_STATUS1_TSCHQ_PERR (1L<<19)
+#define BNX2_MISC_PERR_STATUS1_COMXQ_PERR (1L<<20)
+#define BNX2_MISC_PERR_STATUS1_RXPCQ_PERR (1L<<21)
+#define BNX2_MISC_PERR_STATUS1_RV2PTQ_PERR (1L<<22)
+#define BNX2_MISC_PERR_STATUS1_RV2PMQ_PERR (1L<<23)
+#define BNX2_MISC_PERR_STATUS1_CPQ_PERR (1L<<24)
+#define BNX2_MISC_PERR_STATUS1_CSQ_PERR (1L<<25)
+#define BNX2_MISC_PERR_STATUS1_RLUP_CID_PERR (1L<<26)
+#define BNX2_MISC_PERR_STATUS1_RV2PCS_TMEM_PERR (1L<<27)
+#define BNX2_MISC_PERR_STATUS1_RV2PCSQ_PERR (1L<<28)
+#define BNX2_MISC_PERR_STATUS1_MQ_IDX_PERR (1L<<29)
+
+#define BNX2_MISC_PERR_STATUS2 0x0000094c
+#define BNX2_MISC_PERR_STATUS2_TGT_FIFO_PERR (1L<<0)
+#define BNX2_MISC_PERR_STATUS2_UMP_TX_PERR (1L<<1)
+#define BNX2_MISC_PERR_STATUS2_UMP_RX_PERR (1L<<2)
+#define BNX2_MISC_PERR_STATUS2_MCP_ROM_PERR (1L<<3)
+#define BNX2_MISC_PERR_STATUS2_MCP_SCPAD_PERR (1L<<4)
+#define BNX2_MISC_PERR_STATUS2_HB_MEM_PERR (1L<<5)
+#define BNX2_MISC_PERR_STATUS2_PCIE_REPLAY_PERR (1L<<6)
+
+#define BNX2_MISC_LCPLL_CTRL0 0x00000950
+#define BNX2_MISC_LCPLL_CTRL0_OAC (0x7L<<0)
+#define BNX2_MISC_LCPLL_CTRL0_OAC_NEGTWENTY (0L<<0)
+#define BNX2_MISC_LCPLL_CTRL0_OAC_ZERO (1L<<0)
+#define BNX2_MISC_LCPLL_CTRL0_OAC_TWENTY (3L<<0)
+#define BNX2_MISC_LCPLL_CTRL0_OAC_FORTY (7L<<0)
+#define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL (0x7L<<3)
+#define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_360 (0L<<3)
+#define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_480 (1L<<3)
+#define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_600 (3L<<3)
+#define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_720 (7L<<3)
+#define BNX2_MISC_LCPLL_CTRL0_BIAS_CTRL (0x3L<<6)
+#define BNX2_MISC_LCPLL_CTRL0_PLL_OBSERVE (0x7L<<8)
+#define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL (0x3L<<11)
+#define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_0 (0L<<11)
+#define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_1 (1L<<11)
+#define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_2 (2L<<11)
+#define BNX2_MISC_LCPLL_CTRL0_PLLSEQSTART (1L<<13)
+#define BNX2_MISC_LCPLL_CTRL0_RESERVED (1L<<14)
+#define BNX2_MISC_LCPLL_CTRL0_CAPRETRY_EN (1L<<15)
+#define BNX2_MISC_LCPLL_CTRL0_FREQMONITOR_EN (1L<<16)
+#define BNX2_MISC_LCPLL_CTRL0_FREQDETRESTART_EN (1L<<17)
+#define BNX2_MISC_LCPLL_CTRL0_FREQDETRETRY_EN (1L<<18)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFDONE_EN (1L<<19)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFDONE (1L<<20)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFPASS (1L<<21)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPDONE_EN (1L<<22)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPDONE (1L<<23)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPPASS_EN (1L<<24)
+#define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPPASS (1L<<25)
+#define BNX2_MISC_LCPLL_CTRL0_CAPRESTART (1L<<26)
+#define BNX2_MISC_LCPLL_CTRL0_CAPSELECTM_EN (1L<<27)
+
+#define BNX2_MISC_LCPLL_CTRL1 0x00000954
+#define BNX2_MISC_LCPLL_CTRL1_CAPSELECTM (0x1fL<<0)
+#define BNX2_MISC_LCPLL_CTRL1_CAPFORCESLOWDOWN_EN (1L<<5)
+#define BNX2_MISC_LCPLL_CTRL1_CAPFORCESLOWDOWN (1L<<6)
+#define BNX2_MISC_LCPLL_CTRL1_SLOWDN_XOR (1L<<7)
+
+#define BNX2_MISC_LCPLL_STATUS 0x00000958
+#define BNX2_MISC_LCPLL_STATUS_FREQDONE_SM (1L<<0)
+#define BNX2_MISC_LCPLL_STATUS_FREQPASS_SM (1L<<1)
+#define BNX2_MISC_LCPLL_STATUS_PLLSEQDONE (1L<<2)
+#define BNX2_MISC_LCPLL_STATUS_PLLSEQPASS (1L<<3)
+#define BNX2_MISC_LCPLL_STATUS_PLLSTATE (0x7L<<4)
+#define BNX2_MISC_LCPLL_STATUS_CAPSTATE (0x7L<<7)
+#define BNX2_MISC_LCPLL_STATUS_CAPSELECT (0x1fL<<10)
+#define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR (1L<<15)
+#define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR_0 (0L<<15)
+#define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR_1 (1L<<15)
+
+#define BNX2_MISC_OSCFUNDS_CTRL 0x0000095c
+#define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON (1L<<5)
+#define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON_OFF (0L<<5)
+#define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON_ON (1L<<5)
+#define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM (0x3L<<6)
+#define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_0 (0L<<6)
+#define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_1 (1L<<6)
+#define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_2 (2L<<6)
+#define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_3 (3L<<6)
+#define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ (0x3L<<8)
+#define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_0 (0L<<8)
+#define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_1 (1L<<8)
+#define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_2 (2L<<8)
+#define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_3 (3L<<8)
+#define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ (0x3L<<10)
+#define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_0 (0L<<10)
+#define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_1 (1L<<10)
+#define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_2 (2L<<10)
+#define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_3 (3L<<10)
/*
@@ -1031,11 +1736,35 @@ struct l2_fhdr {
#define BNX2_NVM_COMMAND_WRDI (1L<<17)
#define BNX2_NVM_COMMAND_EWSR (1L<<18)
#define BNX2_NVM_COMMAND_WRSR (1L<<19)
+#define BNX2_NVM_COMMAND_RD_ID (1L<<20)
+#define BNX2_NVM_COMMAND_RD_STATUS (1L<<21)
+#define BNX2_NVM_COMMAND_MODE_256 (1L<<22)
#define BNX2_NVM_STATUS 0x00006404
#define BNX2_NVM_STATUS_PI_FSM_STATE (0xfL<<0)
#define BNX2_NVM_STATUS_EE_FSM_STATE (0xfL<<4)
#define BNX2_NVM_STATUS_EQ_FSM_STATE (0xfL<<8)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_XI (0x1fL<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_IDLE_XI (0L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD0_XI (1L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD1_XI (2L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD_FINISH0_XI (3L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD_FINISH1_XI (4L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_ADDR0_XI (5L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA0_XI (6L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA1_XI (7L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA2_XI (8L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA0_XI (9L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA1_XI (10L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA2_XI (11L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID0_XI (12L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID1_XI (13L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID2_XI (14L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID3_XI (15L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID4_XI (16L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CHECK_BUSY0_XI (17L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_ST_WREN_XI (18L<<0)
+#define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WAIT_XI (19L<<0)
#define BNX2_NVM_WRITE 0x00006408
#define BNX2_NVM_WRITE_NVM_WRITE_VALUE (0xffffffffL<<0)
@@ -1046,6 +1775,10 @@ struct l2_fhdr {
#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B (8L<<0)
#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO (16L<<0)
#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI (32L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI_XI (1L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO_XI (2L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B_XI (4L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK_XI (8L<<0)
#define BNX2_NVM_ADDR 0x0000640c
#define BNX2_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0)
@@ -1056,6 +1789,10 @@ struct l2_fhdr {
#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B (8L<<0)
#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO (16L<<0)
#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI (32L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI_XI (1L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO_XI (2L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B_XI (4L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK_XI (8L<<0)
#define BNX2_NVM_READ 0x00006410
#define BNX2_NVM_READ_NVM_READ_VALUE (0xffffffffL<<0)
@@ -1066,6 +1803,10 @@ struct l2_fhdr {
#define BNX2_NVM_READ_NVM_READ_VALUE_CS_B (8L<<0)
#define BNX2_NVM_READ_NVM_READ_VALUE_SO (16L<<0)
#define BNX2_NVM_READ_NVM_READ_VALUE_SI (32L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SI_XI (1L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SO_XI (2L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_CS_B_XI (4L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SCLK_XI (8L<<0)
#define BNX2_NVM_CFG1 0x00006414
#define BNX2_NVM_CFG1_FLASH_MODE (1L<<0)
@@ -1077,14 +1818,21 @@ struct l2_fhdr {
#define BNX2_NVM_CFG1_STATUS_BIT_BUFFER_RDY (7L<<4)
#define BNX2_NVM_CFG1_SPI_CLK_DIV (0xfL<<7)
#define BNX2_NVM_CFG1_SEE_CLK_DIV (0x7ffL<<11)
+#define BNX2_NVM_CFG1_STRAP_CONTROL_0 (1L<<23)
#define BNX2_NVM_CFG1_PROTECT_MODE (1L<<24)
#define BNX2_NVM_CFG1_FLASH_SIZE (1L<<25)
+#define BNX2_NVM_CFG1_FW_USTRAP_1 (1L<<26)
+#define BNX2_NVM_CFG1_FW_USTRAP_0 (1L<<27)
+#define BNX2_NVM_CFG1_FW_USTRAP_2 (1L<<28)
+#define BNX2_NVM_CFG1_FW_USTRAP_3 (1L<<29)
+#define BNX2_NVM_CFG1_FW_FLASH_TYPE_EN (1L<<30)
#define BNX2_NVM_CFG1_COMPAT_BYPASSS (1L<<31)
#define BNX2_NVM_CFG2 0x00006418
#define BNX2_NVM_CFG2_ERASE_CMD (0xffL<<0)
#define BNX2_NVM_CFG2_DUMMY (0xffL<<8)
#define BNX2_NVM_CFG2_STATUS_CMD (0xffL<<16)
+#define BNX2_NVM_CFG2_READ_ID (0xffL<<24)
#define BNX2_NVM_CFG3 0x0000641c
#define BNX2_NVM_CFG3_BUFFER_RD_CMD (0xffL<<0)
@@ -1119,6 +1867,35 @@ struct l2_fhdr {
#define BNX2_NVM_WRITE1_WRDI_CMD (0xffL<<8)
#define BNX2_NVM_WRITE1_SR_DATA (0xffL<<16)
+#define BNX2_NVM_CFG4 0x0000642c
+#define BNX2_NVM_CFG4_FLASH_SIZE (0x7L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_1MBIT (0L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_2MBIT (1L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_4MBIT (2L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_8MBIT (3L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_16MBIT (4L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_32MBIT (5L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_64MBIT (6L<<0)
+#define BNX2_NVM_CFG4_FLASH_SIZE_128MBIT (7L<<0)
+#define BNX2_NVM_CFG4_FLASH_VENDOR (1L<<3)
+#define BNX2_NVM_CFG4_FLASH_VENDOR_ST (0L<<3)
+#define BNX2_NVM_CFG4_FLASH_VENDOR_ATMEL (1L<<3)
+#define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC (0x3L<<4)
+#define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT8 (0L<<4)
+#define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT9 (1L<<4)
+#define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT10 (2L<<4)
+#define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT11 (3L<<4)
+#define BNX2_NVM_CFG4_STATUS_BIT_POLARITY (1L<<6)
+#define BNX2_NVM_CFG4_RESERVED (0x1ffffffL<<7)
+
+#define BNX2_NVM_RECONFIG 0x00006430
+#define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE (0xfL<<0)
+#define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE_ST (0L<<0)
+#define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE_ATMEL (1L<<0)
+#define BNX2_NVM_RECONFIG_RECONFIG_STRAP_VALUE (0xfL<<4)
+#define BNX2_NVM_RECONFIG_RESERVED (0x7fffffL<<8)
+#define BNX2_NVM_RECONFIG_RECONFIG_DONE (1L<<31)
+
/*
@@ -1140,6 +1917,8 @@ struct l2_fhdr {
#define BNX2_DMA_STATUS_BIG_WRITE_TRANSFERS_STAT (1L<<23)
#define BNX2_DMA_STATUS_BIG_WRITE_DELAY_PCI_CLKS_STAT (1L<<24)
#define BNX2_DMA_STATUS_BIG_WRITE_RETRY_AFTER_DATA_STAT (1L<<25)
+#define BNX2_DMA_STATUS_GLOBAL_ERR_XI (1L<<0)
+#define BNX2_DMA_STATUS_BME_XI (1L<<4)
#define BNX2_DMA_CONFIG 0x00000c08
#define BNX2_DMA_CONFIG_DATA_BYTE_SWAP (1L<<0)
@@ -1161,85 +1940,315 @@ struct l2_fhdr {
#define BNX2_DMA_CONFIG_BIG_SIZE_128 (0x2L<<24)
#define BNX2_DMA_CONFIG_BIG_SIZE_256 (0x4L<<24)
#define BNX2_DMA_CONFIG_BIG_SIZE_512 (0x8L<<24)
+#define BNX2_DMA_CONFIG_DAT_WBSWAP_MODE_XI (0x3L<<0)
+#define BNX2_DMA_CONFIG_CTL_WBSWAP_MODE_XI (0x3L<<4)
+#define BNX2_DMA_CONFIG_MAX_PL_XI (0x7L<<12)
+#define BNX2_DMA_CONFIG_MAX_PL_128B_XI (0L<<12)
+#define BNX2_DMA_CONFIG_MAX_PL_256B_XI (1L<<12)
+#define BNX2_DMA_CONFIG_MAX_PL_512B_XI (2L<<12)
+#define BNX2_DMA_CONFIG_MAX_PL_EN_XI (1L<<15)
+#define BNX2_DMA_CONFIG_MAX_RRS_XI (0x7L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_128B_XI (0L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_256B_XI (1L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_512B_XI (2L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_1024B_XI (3L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_2048B_XI (4L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_4096B_XI (5L<<16)
+#define BNX2_DMA_CONFIG_MAX_RRS_EN_XI (1L<<19)
+#define BNX2_DMA_CONFIG_NO_64SWAP_EN_XI (1L<<31)
#define BNX2_DMA_BLACKOUT 0x00000c0c
#define BNX2_DMA_BLACKOUT_RD_RETRY_BLACKOUT (0xffL<<0)
#define BNX2_DMA_BLACKOUT_2ND_RD_RETRY_BLACKOUT (0xffL<<8)
#define BNX2_DMA_BLACKOUT_WR_RETRY_BLACKOUT (0xffL<<16)
-#define BNX2_DMA_RCHAN_STAT 0x00000c30
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_0 (0x7L<<0)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_0 (1L<<3)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_1 (0x7L<<4)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_1 (1L<<7)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_2 (0x7L<<8)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_2 (1L<<11)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_3 (0x7L<<12)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_3 (1L<<15)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_4 (0x7L<<16)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_4 (1L<<19)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_5 (0x7L<<20)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_5 (1L<<23)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_6 (0x7L<<24)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_6 (1L<<27)
-#define BNX2_DMA_RCHAN_STAT_COMP_CODE_7 (0x7L<<28)
-#define BNX2_DMA_RCHAN_STAT_PAR_ERR_7 (1L<<31)
-
-#define BNX2_DMA_WCHAN_STAT 0x00000c34
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_0 (0x7L<<0)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_0 (1L<<3)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_1 (0x7L<<4)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_1 (1L<<7)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_2 (0x7L<<8)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_2 (1L<<11)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_3 (0x7L<<12)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_3 (1L<<15)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_4 (0x7L<<16)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_4 (1L<<19)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_5 (0x7L<<20)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_5 (1L<<23)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_6 (0x7L<<24)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_6 (1L<<27)
-#define BNX2_DMA_WCHAN_STAT_COMP_CODE_7 (0x7L<<28)
-#define BNX2_DMA_WCHAN_STAT_PAR_ERR_7 (1L<<31)
-
-#define BNX2_DMA_RCHAN_ASSIGNMENT 0x00000c38
-#define BNX2_DMA_RCHAN_ASSIGNMENT_0 (0xfL<<0)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_1 (0xfL<<4)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_2 (0xfL<<8)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_3 (0xfL<<12)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_4 (0xfL<<16)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_5 (0xfL<<20)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_6 (0xfL<<24)
-#define BNX2_DMA_RCHAN_ASSIGNMENT_7 (0xfL<<28)
-
-#define BNX2_DMA_WCHAN_ASSIGNMENT 0x00000c3c
-#define BNX2_DMA_WCHAN_ASSIGNMENT_0 (0xfL<<0)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_1 (0xfL<<4)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_2 (0xfL<<8)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_3 (0xfL<<12)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_4 (0xfL<<16)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_5 (0xfL<<20)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_6 (0xfL<<24)
-#define BNX2_DMA_WCHAN_ASSIGNMENT_7 (0xfL<<28)
-
-#define BNX2_DMA_RCHAN_STAT_00 0x00000c40
-#define BNX2_DMA_RCHAN_STAT_00_RCHAN_STA_HOST_ADDR_LOW (0xffffffffL<<0)
-
-#define BNX2_DMA_RCHAN_STAT_01 0x00000c44
-#define BNX2_DMA_RCHAN_STAT_01_RCHAN_STA_HOST_ADDR_HIGH (0xffffffffL<<0)
-
-#define BNX2_DMA_RCHAN_STAT_02 0x00000c48
-#define BNX2_DMA_RCHAN_STAT_02_LENGTH (0xffffL<<0)
-#define BNX2_DMA_RCHAN_STAT_02_WORD_SWAP (1L<<16)
-#define BNX2_DMA_RCHAN_STAT_02_BYTE_SWAP (1L<<17)
-#define BNX2_DMA_RCHAN_STAT_02_PRIORITY_LVL (1L<<18)
-
-#define BNX2_DMA_RCHAN_STAT_10 0x00000c4c
-#define BNX2_DMA_RCHAN_STAT_11 0x00000c50
-#define BNX2_DMA_RCHAN_STAT_12 0x00000c54
-#define BNX2_DMA_RCHAN_STAT_20 0x00000c58
-#define BNX2_DMA_RCHAN_STAT_21 0x00000c5c
+#define BNX2_DMA_READ_MASTER_SETTING_0 0x00000c10
+#define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_NO_SNOOP (1L<<0)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_RELAX_ORDER (1L<<1)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_PRIORITY (1L<<2)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_TRAFFIC_CLASS (0x7L<<4)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_PARAM_EN (1L<<7)
+#define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_NO_SNOOP (1L<<8)
+#define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_RELAX_ORDER (1L<<9)
+#define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_PRIORITY (1L<<10)
+#define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_TRAFFIC_CLASS (0x7L<<12)
+#define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_PARAM_EN (1L<<15)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_NO_SNOOP (1L<<16)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_RELAX_ORDER (1L<<17)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_PRIORITY (1L<<18)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_TRAFFIC_CLASS (0x7L<<20)
+#define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_PARAM_EN (1L<<23)
+#define BNX2_DMA_READ_MASTER_SETTING_0_CTX_NO_SNOOP (1L<<24)
+#define BNX2_DMA_READ_MASTER_SETTING_0_CTX_RELAX_ORDER (1L<<25)
+#define BNX2_DMA_READ_MASTER_SETTING_0_CTX_PRIORITY (1L<<26)
+#define BNX2_DMA_READ_MASTER_SETTING_0_CTX_TRAFFIC_CLASS (0x7L<<28)
+#define BNX2_DMA_READ_MASTER_SETTING_0_CTX_PARAM_EN (1L<<31)
+
+#define BNX2_DMA_READ_MASTER_SETTING_1 0x00000c14
+#define BNX2_DMA_READ_MASTER_SETTING_1_COM_NO_SNOOP (1L<<0)
+#define BNX2_DMA_READ_MASTER_SETTING_1_COM_RELAX_ORDER (1L<<1)
+#define BNX2_DMA_READ_MASTER_SETTING_1_COM_PRIORITY (1L<<2)
+#define BNX2_DMA_READ_MASTER_SETTING_1_COM_TRAFFIC_CLASS (0x7L<<4)
+#define BNX2_DMA_READ_MASTER_SETTING_1_COM_PARAM_EN (1L<<7)
+#define BNX2_DMA_READ_MASTER_SETTING_1_CP_NO_SNOOP (1L<<8)
+#define BNX2_DMA_READ_MASTER_SETTING_1_CP_RELAX_ORDER (1L<<9)
+#define BNX2_DMA_READ_MASTER_SETTING_1_CP_PRIORITY (1L<<10)
+#define BNX2_DMA_READ_MASTER_SETTING_1_CP_TRAFFIC_CLASS (0x7L<<12)
+#define BNX2_DMA_READ_MASTER_SETTING_1_CP_PARAM_EN (1L<<15)
+
+#define BNX2_DMA_WRITE_MASTER_SETTING_0 0x00000c18
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_NO_SNOOP (1L<<0)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_RELAX_ORDER (1L<<1)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_PRIORITY (1L<<2)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_CS_VLD (1L<<3)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_TRAFFIC_CLASS (0x7L<<4)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_PARAM_EN (1L<<7)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_NO_SNOOP (1L<<8)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_RELAX_ORDER (1L<<9)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_PRIORITY (1L<<10)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_CS_VLD (1L<<11)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_TRAFFIC_CLASS (0x7L<<12)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_PARAM_EN (1L<<15)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_NO_SNOOP (1L<<24)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_RELAX_ORDER (1L<<25)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_PRIORITY (1L<<26)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_CS_VLD (1L<<27)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_TRAFFIC_CLASS (0x7L<<28)
+#define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_PARAM_EN (1L<<31)
+
+#define BNX2_DMA_WRITE_MASTER_SETTING_1 0x00000c1c
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_NO_SNOOP (1L<<0)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_RELAX_ORDER (1L<<1)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_PRIORITY (1L<<2)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_CS_VLD (1L<<3)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_TRAFFIC_CLASS (0x7L<<4)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_PARAM_EN (1L<<7)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_NO_SNOOP (1L<<8)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_RELAX_ORDER (1L<<9)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_PRIORITY (1L<<10)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_CS_VLD (1L<<11)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_TRAFFIC_CLASS (0x7L<<12)
+#define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_PARAM_EN (1L<<15)
+
+#define BNX2_DMA_ARBITER 0x00000c20
+#define BNX2_DMA_ARBITER_NUM_READS (0x7L<<0)
+#define BNX2_DMA_ARBITER_WR_ARB_MODE (1L<<4)
+#define BNX2_DMA_ARBITER_WR_ARB_MODE_STRICT (0L<<4)
+#define BNX2_DMA_ARBITER_WR_ARB_MODE_RND_RBN (1L<<4)
+#define BNX2_DMA_ARBITER_RD_ARB_MODE (0x3L<<5)
+#define BNX2_DMA_ARBITER_RD_ARB_MODE_STRICT (0L<<5)
+#define BNX2_DMA_ARBITER_RD_ARB_MODE_RND_RBN (1L<<5)
+#define BNX2_DMA_ARBITER_RD_ARB_MODE_WGT_RND_RBN (2L<<5)
+#define BNX2_DMA_ARBITER_ALT_MODE_EN (1L<<8)
+#define BNX2_DMA_ARBITER_RR_MODE (1L<<9)
+#define BNX2_DMA_ARBITER_TIMER_MODE (1L<<10)
+#define BNX2_DMA_ARBITER_OUSTD_READ_REQ (0xfL<<12)
+
+#define BNX2_DMA_ARB_TIMERS 0x00000c24
+#define BNX2_DMA_ARB_TIMERS_RD_DRR_WAIT_TIME (0xffL<<0)
+#define BNX2_DMA_ARB_TIMERS_TM_MIN_TIMEOUT (0xffL<<12)
+#define BNX2_DMA_ARB_TIMERS_TM_MAX_TIMEOUT (0xfffL<<20)
+
+#define BNX2_DMA_DEBUG_VECT_PEEK 0x00000c2c
+#define BNX2_DMA_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0)
+#define BNX2_DMA_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11)
+#define BNX2_DMA_DEBUG_VECT_PEEK_1_SEL (0xfL<<12)
+#define BNX2_DMA_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16)
+#define BNX2_DMA_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27)
+#define BNX2_DMA_DEBUG_VECT_PEEK_2_SEL (0xfL<<28)
+
+#define BNX2_DMA_TAG_RAM_00 0x00000c30
+#define BNX2_DMA_TAG_RAM_00_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_00_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_00_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_00_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_00_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_00_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_00_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_00_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_00_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_01 0x00000c34
+#define BNX2_DMA_TAG_RAM_01_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_01_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_01_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_01_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_01_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_01_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_01_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_01_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_01_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_02 0x00000c38
+#define BNX2_DMA_TAG_RAM_02_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_02_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_02_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_02_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_02_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_02_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_02_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_02_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_02_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_03 0x00000c3c
+#define BNX2_DMA_TAG_RAM_03_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_03_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_03_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_03_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_03_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_03_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_03_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_03_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_03_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_04 0x00000c40
+#define BNX2_DMA_TAG_RAM_04_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_04_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_04_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_04_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_04_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_04_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_04_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_04_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_04_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_05 0x00000c44
+#define BNX2_DMA_TAG_RAM_05_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_05_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_05_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_05_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_05_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_05_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_05_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_05_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_05_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_06 0x00000c48
+#define BNX2_DMA_TAG_RAM_06_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_06_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_06_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_06_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_06_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_06_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_06_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_06_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_06_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_07 0x00000c4c
+#define BNX2_DMA_TAG_RAM_07_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_07_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_07_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_07_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_07_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_07_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_07_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_07_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_07_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_08 0x00000c50
+#define BNX2_DMA_TAG_RAM_08_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_08_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_08_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_08_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_08_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_08_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_08_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_08_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_08_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_09 0x00000c54
+#define BNX2_DMA_TAG_RAM_09_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_09_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_09_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_09_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_09_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_09_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_09_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_09_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_09_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_10 0x00000c58
+#define BNX2_DMA_TAG_RAM_10_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_10_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_10_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_10_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_10_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_10_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_10_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_10_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_10_VALID (1L<<10)
+
+#define BNX2_DMA_TAG_RAM_11 0x00000c5c
+#define BNX2_DMA_TAG_RAM_11_CHANNEL (0xfL<<0)
+#define BNX2_DMA_TAG_RAM_11_MASTER (0x7L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_CTX (0L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_RBDC (1L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_TBDC (2L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_COM (3L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_CP (4L<<4)
+#define BNX2_DMA_TAG_RAM_11_MASTER_TDMA (5L<<4)
+#define BNX2_DMA_TAG_RAM_11_SWAP (0x3L<<7)
+#define BNX2_DMA_TAG_RAM_11_SWAP_CONFIG (0L<<7)
+#define BNX2_DMA_TAG_RAM_11_SWAP_DATA (1L<<7)
+#define BNX2_DMA_TAG_RAM_11_SWAP_CONTROL (2L<<7)
+#define BNX2_DMA_TAG_RAM_11_FUNCTION (1L<<9)
+#define BNX2_DMA_TAG_RAM_11_VALID (1L<<10)
+
#define BNX2_DMA_RCHAN_STAT_22 0x00000c60
#define BNX2_DMA_RCHAN_STAT_30 0x00000c64
#define BNX2_DMA_RCHAN_STAT_31 0x00000c68
@@ -1336,6 +2345,25 @@ struct l2_fhdr {
*/
#define BNX2_CTX_COMMAND 0x00001000
#define BNX2_CTX_COMMAND_ENABLED (1L<<0)
+#define BNX2_CTX_COMMAND_DISABLE_USAGE_CNT (1L<<1)
+#define BNX2_CTX_COMMAND_DISABLE_PLRU (1L<<2)
+#define BNX2_CTX_COMMAND_DISABLE_COMBINE_READ (1L<<3)
+#define BNX2_CTX_COMMAND_FLUSH_AHEAD (0x1fL<<8)
+#define BNX2_CTX_COMMAND_MEM_INIT (1L<<13)
+#define BNX2_CTX_COMMAND_PAGE_SIZE (0xfL<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_256 (0L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_512 (1L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_1K (2L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_2K (3L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_4K (4L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_8K (5L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_16K (6L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_32K (7L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_64K (8L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_128K (9L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_256K (10L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_512K (11L<<16)
+#define BNX2_CTX_COMMAND_PAGE_SIZE_1M (12L<<16)
#define BNX2_CTX_STATUS 0x00001004
#define BNX2_CTX_STATUS_LOCK_WAIT (1L<<0)
@@ -1343,6 +2371,13 @@ struct l2_fhdr {
#define BNX2_CTX_STATUS_WRITE_STAT (1L<<17)
#define BNX2_CTX_STATUS_ACC_STALL_STAT (1L<<18)
#define BNX2_CTX_STATUS_LOCK_STALL_STAT (1L<<19)
+#define BNX2_CTX_STATUS_EXT_READ_STAT (1L<<20)
+#define BNX2_CTX_STATUS_EXT_WRITE_STAT (1L<<21)
+#define BNX2_CTX_STATUS_MISS_STAT (1L<<22)
+#define BNX2_CTX_STATUS_HIT_STAT (1L<<23)
+#define BNX2_CTX_STATUS_DEAD_LOCK (1L<<24)
+#define BNX2_CTX_STATUS_USAGE_CNT_ERR (1L<<25)
+#define BNX2_CTX_STATUS_INVALID_PAGE (1L<<26)
#define BNX2_CTX_VIRT_ADDR 0x00001008
#define BNX2_CTX_VIRT_ADDR_VIRT_ADDR (0x7fffL<<6)
@@ -1357,10 +2392,15 @@ struct l2_fhdr {
#define BNX2_CTX_LOCK 0x00001018
#define BNX2_CTX_LOCK_TYPE (0x7L<<0)
#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_VOID (0x0L<<0)
-#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE (0x7L<<0)
#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_PROTOCOL (0x1L<<0)
#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TX (0x2L<<0)
#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TIMER (0x4L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE (0x7L<<0)
+#define BNX2_CTX_LOCK_TYPE_VOID_XI (0L<<0)
+#define BNX2_CTX_LOCK_TYPE_PROTOCOL_XI (1L<<0)
+#define BNX2_CTX_LOCK_TYPE_TX_XI (2L<<0)
+#define BNX2_CTX_LOCK_TYPE_TIMER_XI (4L<<0)
+#define BNX2_CTX_LOCK_TYPE_COMPLETE_XI (7L<<0)
#define BNX2_CTX_LOCK_CID_VALUE (0x3fffL<<7)
#define BNX2_CTX_LOCK_GRANTED (1L<<26)
#define BNX2_CTX_LOCK_MODE (0x7L<<27)
@@ -1370,21 +2410,89 @@ struct l2_fhdr {
#define BNX2_CTX_LOCK_STATUS (1L<<30)
#define BNX2_CTX_LOCK_REQ (1L<<31)
+#define BNX2_CTX_CTX_CTRL 0x0000101c
+#define BNX2_CTX_CTX_CTRL_CTX_ADDR (0x7ffffL<<2)
+#define BNX2_CTX_CTX_CTRL_MOD_USAGE_CNT (0x3L<<21)
+#define BNX2_CTX_CTX_CTRL_NO_RAM_ACC (1L<<23)
+#define BNX2_CTX_CTX_CTRL_PREFETCH_SIZE (0x3L<<24)
+#define BNX2_CTX_CTX_CTRL_ATTR (1L<<26)
+#define BNX2_CTX_CTX_CTRL_WRITE_REQ (1L<<30)
+#define BNX2_CTX_CTX_CTRL_READ_REQ (1L<<31)
+
+#define BNX2_CTX_CTX_DATA 0x00001020
#define BNX2_CTX_ACCESS_STATUS 0x00001040
#define BNX2_CTX_ACCESS_STATUS_MASTERENCODED (0xfL<<0)
#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYSM (0x3L<<10)
#define BNX2_CTX_ACCESS_STATUS_PAGETABLEINITSM (0x3L<<12)
#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYINITSM (0x3L<<14)
#define BNX2_CTX_ACCESS_STATUS_QUALIFIED_REQUEST (0x7ffL<<17)
+#define BNX2_CTX_ACCESS_STATUS_CAMMASTERENCODED_XI (0x1fL<<0)
+#define BNX2_CTX_ACCESS_STATUS_CACHEMASTERENCODED_XI (0x1fL<<5)
+#define BNX2_CTX_ACCESS_STATUS_REQUEST_XI (0x3fffffL<<10)
#define BNX2_CTX_DBG_LOCK_STATUS 0x00001044
#define BNX2_CTX_DBG_LOCK_STATUS_SM (0x3ffL<<0)
#define BNX2_CTX_DBG_LOCK_STATUS_MATCH (0x3ffL<<22)
+#define BNX2_CTX_CACHE_CTRL_STATUS 0x00001048
+#define BNX2_CTX_CACHE_CTRL_STATUS_RFIFO_OVERFLOW (1L<<0)
+#define BNX2_CTX_CACHE_CTRL_STATUS_INVALID_READ_COMP (1L<<1)
+#define BNX2_CTX_CACHE_CTRL_STATUS_FLUSH_START (1L<<6)
+#define BNX2_CTX_CACHE_CTRL_STATUS_FREE_ENTRY_CNT (0x3fL<<7)
+#define BNX2_CTX_CACHE_CTRL_STATUS_CACHE_ENTRY_NEEDED (0x3fL<<13)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN0_ACTIVE (1L<<19)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN1_ACTIVE (1L<<20)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN2_ACTIVE (1L<<21)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN3_ACTIVE (1L<<22)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN4_ACTIVE (1L<<23)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN5_ACTIVE (1L<<24)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN6_ACTIVE (1L<<25)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN7_ACTIVE (1L<<26)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN8_ACTIVE (1L<<27)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN9_ACTIVE (1L<<28)
+#define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN10_ACTIVE (1L<<29)
+
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS 0x0000104c
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_DWC (0x7L<<0)
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_WFIFOC (0x7L<<3)
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_RTAGC (0x7L<<6)
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_RFIFOC (0x7L<<9)
+#define BNX2_CTX_CACHE_CTRL_SM_STATUS_INVALID_BLK_ADDR (0x7fffL<<16)
+
+#define BNX2_CTX_CACHE_STATUS 0x00001050
+#define BNX2_CTX_CACHE_STATUS_HELD_ENTRIES (0x3ffL<<0)
+#define BNX2_CTX_CACHE_STATUS_MAX_HELD_ENTRIES (0x3ffL<<16)
+
+#define BNX2_CTX_DMA_STATUS 0x00001054
+#define BNX2_CTX_DMA_STATUS_RD_CHAN0_STATUS (0x3L<<0)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN1_STATUS (0x3L<<2)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN2_STATUS (0x3L<<4)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN3_STATUS (0x3L<<6)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN4_STATUS (0x3L<<8)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN5_STATUS (0x3L<<10)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN6_STATUS (0x3L<<12)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN7_STATUS (0x3L<<14)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN8_STATUS (0x3L<<16)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN9_STATUS (0x3L<<18)
+#define BNX2_CTX_DMA_STATUS_RD_CHAN10_STATUS (0x3L<<20)
+
+#define BNX2_CTX_REP_STATUS 0x00001058
+#define BNX2_CTX_REP_STATUS_ERROR_ENTRY (0x3ffL<<0)
+#define BNX2_CTX_REP_STATUS_ERROR_CLIENT_ID (0x1fL<<10)
+#define BNX2_CTX_REP_STATUS_USAGE_CNT_MAX_ERR (1L<<16)
+#define BNX2_CTX_REP_STATUS_USAGE_CNT_MIN_ERR (1L<<17)
+#define BNX2_CTX_REP_STATUS_USAGE_CNT_MISS_ERR (1L<<18)
+
+#define BNX2_CTX_CKSUM_ERROR_STATUS 0x0000105c
+#define BNX2_CTX_CKSUM_ERROR_STATUS_CALCULATED (0xffffL<<0)
+#define BNX2_CTX_CKSUM_ERROR_STATUS_EXPECTED (0xffffL<<16)
+
#define BNX2_CTX_CHNL_LOCK_STATUS_0 0x00001080
#define BNX2_CTX_CHNL_LOCK_STATUS_0_CID (0x3fffL<<0)
#define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE (0x3L<<14)
#define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE (1L<<16)
+#define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE_XI (1L<<14)
+#define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE_XI (0x7L<<15)
#define BNX2_CTX_CHNL_LOCK_STATUS_1 0x00001084
#define BNX2_CTX_CHNL_LOCK_STATUS_2 0x00001088
@@ -1394,6 +2502,26 @@ struct l2_fhdr {
#define BNX2_CTX_CHNL_LOCK_STATUS_6 0x00001098
#define BNX2_CTX_CHNL_LOCK_STATUS_7 0x0000109c
#define BNX2_CTX_CHNL_LOCK_STATUS_8 0x000010a0
+#define BNX2_CTX_CHNL_LOCK_STATUS_9 0x000010a4
+
+#define BNX2_CTX_CACHE_DATA 0x000010c4
+#define BNX2_CTX_HOST_PAGE_TBL_CTRL 0x000010c8
+#define BNX2_CTX_HOST_PAGE_TBL_CTRL_PAGE_TBL_ADDR (0x1ffL<<0)
+#define BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ (1L<<30)
+#define BNX2_CTX_HOST_PAGE_TBL_CTRL_READ_REQ (1L<<31)
+
+#define BNX2_CTX_HOST_PAGE_TBL_DATA0 0x000010cc
+#define BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID (1L<<0)
+#define BNX2_CTX_HOST_PAGE_TBL_DATA0_VALUE (0xffffffL<<8)
+
+#define BNX2_CTX_HOST_PAGE_TBL_DATA1 0x000010d0
+#define BNX2_CTX_CAM_CTRL 0x000010d4
+#define BNX2_CTX_CAM_CTRL_CAM_ADDR (0x3ffL<<0)
+#define BNX2_CTX_CAM_CTRL_RESET (1L<<27)
+#define BNX2_CTX_CAM_CTRL_INVALIDATE (1L<<28)
+#define BNX2_CTX_CAM_CTRL_SEARCH (1L<<29)
+#define BNX2_CTX_CAM_CTRL_WRITE_REQ (1L<<30)
+#define BNX2_CTX_CAM_CTRL_READ_REQ (1L<<31)
/*
@@ -1407,14 +2535,16 @@ struct l2_fhdr {
#define BNX2_EMAC_MODE_PORT_NONE (0L<<2)
#define BNX2_EMAC_MODE_PORT_MII (1L<<2)
#define BNX2_EMAC_MODE_PORT_GMII (2L<<2)
-#define BNX2_EMAC_MODE_PORT_MII_10 (3L<<2)
+#define BNX2_EMAC_MODE_PORT_MII_10M (3L<<2)
#define BNX2_EMAC_MODE_MAC_LOOP (1L<<4)
-#define BNX2_EMAC_MODE_25G (1L<<5)
+#define BNX2_EMAC_MODE_25G_MODE (1L<<5)
#define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7)
#define BNX2_EMAC_MODE_TX_BURST (1L<<8)
#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9)
#define BNX2_EMAC_MODE_EXT_LINK_POL (1L<<10)
#define BNX2_EMAC_MODE_FORCE_LINK (1L<<11)
+#define BNX2_EMAC_MODE_SERDES_MODE (1L<<12)
+#define BNX2_EMAC_MODE_BOND_OVRD (1L<<13)
#define BNX2_EMAC_MODE_MPKT (1L<<18)
#define BNX2_EMAC_MODE_MPKT_RCVD (1L<<19)
#define BNX2_EMAC_MODE_ACPI_RCVD (1L<<20)
@@ -1422,6 +2552,11 @@ struct l2_fhdr {
#define BNX2_EMAC_STATUS 0x00001404
#define BNX2_EMAC_STATUS_LINK (1L<<11)
#define BNX2_EMAC_STATUS_LINK_CHANGE (1L<<12)
+#define BNX2_EMAC_STATUS_SERDES_AUTONEG_COMPLETE (1L<<13)
+#define BNX2_EMAC_STATUS_SERDES_AUTONEG_CHANGE (1L<<14)
+#define BNX2_EMAC_STATUS_SERDES_NXT_PG_CHANGE (1L<<16)
+#define BNX2_EMAC_STATUS_SERDES_RX_CONFIG_IS_0 (1L<<17)
+#define BNX2_EMAC_STATUS_SERDES_RX_CONFIG_IS_0_CHANGE (1L<<18)
#define BNX2_EMAC_STATUS_MI_COMPLETE (1L<<22)
#define BNX2_EMAC_STATUS_MI_INT (1L<<23)
#define BNX2_EMAC_STATUS_AP_ERROR (1L<<24)
@@ -1429,6 +2564,9 @@ struct l2_fhdr {
#define BNX2_EMAC_ATTENTION_ENA 0x00001408
#define BNX2_EMAC_ATTENTION_ENA_LINK (1L<<11)
+#define BNX2_EMAC_ATTENTION_ENA_AUTONEG_CHANGE (1L<<14)
+#define BNX2_EMAC_ATTENTION_ENA_NXT_PG_CHANGE (1L<<16)
+#define BNX2_EMAC_ATTENTION_ENA_SERDES_RX_CONFIG_IS_0_CHANGE (1L<<18)
#define BNX2_EMAC_ATTENTION_ENA_MI_COMPLETE (1L<<22)
#define BNX2_EMAC_ATTENTION_ENA_MI_INT (1L<<23)
#define BNX2_EMAC_ATTENTION_ENA_AP_ERROR (1L<<24)
@@ -1445,6 +2583,13 @@ struct l2_fhdr {
#define BNX2_EMAC_LED_100MB (1L<<8)
#define BNX2_EMAC_LED_10MB (1L<<9)
#define BNX2_EMAC_LED_TRAFFIC_STAT (1L<<10)
+#define BNX2_EMAC_LED_2500MB (1L<<11)
+#define BNX2_EMAC_LED_2500MB_OVERRIDE (1L<<12)
+#define BNX2_EMAC_LED_ACTIVITY_SEL (0x3L<<17)
+#define BNX2_EMAC_LED_ACTIVITY_SEL_0 (0L<<17)
+#define BNX2_EMAC_LED_ACTIVITY_SEL_1 (1L<<17)
+#define BNX2_EMAC_LED_ACTIVITY_SEL_2 (2L<<17)
+#define BNX2_EMAC_LED_ACTIVITY_SEL_3 (3L<<17)
#define BNX2_EMAC_LED_BLNK_RATE (0xfffL<<19)
#define BNX2_EMAC_LED_BLNK_RATE_ENA (1L<<31)
@@ -1515,9 +2660,15 @@ struct l2_fhdr {
#define BNX2_EMAC_MDIO_COMM_PHY_ADDR (0x1fL<<21)
#define BNX2_EMAC_MDIO_COMM_COMMAND (0x3L<<26)
#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_0 (0L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26)
#define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE (1L<<26)
#define BNX2_EMAC_MDIO_COMM_COMMAND_READ (2L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE_22_XI (1L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE_45_XI (1L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_READ_22_XI (2L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_READ_INC_45_XI (2L<<26)
#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_3 (3L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26)
#define BNX2_EMAC_MDIO_COMM_FAIL (1L<<28)
#define BNX2_EMAC_MDIO_COMM_START_BUSY (1L<<29)
#define BNX2_EMAC_MDIO_COMM_DISEXT (1L<<30)
@@ -1534,13 +2685,17 @@ struct l2_fhdr {
#define BNX2_EMAC_MDIO_MODE_MDIO_OE (1L<<10)
#define BNX2_EMAC_MDIO_MODE_MDC (1L<<11)
#define BNX2_EMAC_MDIO_MODE_MDINT (1L<<12)
+#define BNX2_EMAC_MDIO_MODE_EXT_MDINT (1L<<13)
#define BNX2_EMAC_MDIO_MODE_CLOCK_CNT (0x1fL<<16)
+#define BNX2_EMAC_MDIO_MODE_CLOCK_CNT_XI (0x3fL<<16)
+#define BNX2_EMAC_MDIO_MODE_CLAUSE_45_XI (1L<<31)
#define BNX2_EMAC_MDIO_AUTO_STATUS 0x000014b8
#define BNX2_EMAC_MDIO_AUTO_STATUS_AUTO_ERR (1L<<0)
#define BNX2_EMAC_TX_MODE 0x000014bc
#define BNX2_EMAC_TX_MODE_RESET (1L<<0)
+#define BNX2_EMAC_TX_MODE_CS16_TEST (1L<<2)
#define BNX2_EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
#define BNX2_EMAC_TX_MODE_FLOW_EN (1L<<4)
#define BNX2_EMAC_TX_MODE_BIG_BACKOFF (1L<<5)
@@ -1553,6 +2708,7 @@ struct l2_fhdr {
#define BNX2_EMAC_TX_STATUS_XON_SENT (1L<<2)
#define BNX2_EMAC_TX_STATUS_LINK_UP (1L<<3)
#define BNX2_EMAC_TX_STATUS_UNDERRUN (1L<<4)
+#define BNX2_EMAC_TX_STATUS_CS16_ERROR (1L<<5)
#define BNX2_EMAC_TX_LENGTHS 0x000014c4
#define BNX2_EMAC_TX_LENGTHS_SLOT (0xffL<<0)
@@ -1586,6 +2742,10 @@ struct l2_fhdr {
#define BNX2_EMAC_MULTICAST_HASH5 0x000014e4
#define BNX2_EMAC_MULTICAST_HASH6 0x000014e8
#define BNX2_EMAC_MULTICAST_HASH7 0x000014ec
+#define BNX2_EMAC_CKSUM_ERROR_STATUS 0x000014f0
+#define BNX2_EMAC_CKSUM_ERROR_STATUS_CALCULATED (0xffffL<<0)
+#define BNX2_EMAC_CKSUM_ERROR_STATUS_EXPECTED (0xffffL<<16)
+
#define BNX2_EMAC_RX_STAT_IFHCINOCTETS 0x00001500
#define BNX2_EMAC_RX_STAT_IFHCINBADOCTETS 0x00001504
#define BNX2_EMAC_RX_STAT_ETHERSTATSFRAGMENTS 0x00001508
@@ -1608,7 +2768,7 @@ struct l2_fhdr {
#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x0000154c
#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001550
#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x00001554
-#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001558
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTSOVER1522OCTETS 0x00001558
#define BNX2_EMAC_RXMAC_DEBUG0 0x0000155c
#define BNX2_EMAC_RXMAC_DEBUG1 0x00001560
#define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_NE_BYTE_COUNT (1L<<0)
@@ -1661,9 +2821,9 @@ struct l2_fhdr {
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC2 (0x1L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC3 (0x2L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UNI (0x3L<<16)
-#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2 (0x7L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC3 (0x5L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA1 (0x6L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2 (0x7L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA2 (0x7L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA3 (0x8L<<16)
#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC2 (0x9L<<16)
@@ -1701,7 +2861,7 @@ struct l2_fhdr {
#define BNX2_EMAC_RXMAC_DEBUG4_SLOT_FILLED (1L<<23)
#define BNX2_EMAC_RXMAC_DEBUG4_FALSE_CARRIER (1L<<24)
#define BNX2_EMAC_RXMAC_DEBUG4_LAST_DATA (1L<<25)
-#define BNX2_EMAC_RXMAC_DEBUG4_sfd_FOUND (1L<<26)
+#define BNX2_EMAC_RXMAC_DEBUG4_SFD_FOUND (1L<<26)
#define BNX2_EMAC_RXMAC_DEBUG4_ADVANCE (1L<<27)
#define BNX2_EMAC_RXMAC_DEBUG4_START (1L<<28)
@@ -1733,6 +2893,7 @@ struct l2_fhdr {
#define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_ACCEPT (1L<<19)
#define BNX2_EMAC_RXMAC_DEBUG5_FMLEN (0xfffL<<20)
+#define BNX2_EMAC_RX_STAT_FALSECARRIERERRORS 0x00001574
#define BNX2_EMAC_RX_STAT_AC0 0x00001580
#define BNX2_EMAC_RX_STAT_AC1 0x00001584
#define BNX2_EMAC_RX_STAT_AC2 0x00001588
@@ -1757,6 +2918,7 @@ struct l2_fhdr {
#define BNX2_EMAC_RX_STAT_AC21 0x000015d4
#define BNX2_EMAC_RX_STAT_AC22 0x000015d8
#define BNX2_EMAC_RXMAC_SUC_DBG_OVERRUNVEC 0x000015dc
+#define BNX2_EMAC_RX_STAT_AC_28 0x000015f4
#define BNX2_EMAC_TX_STAT_IFHCOUTOCTETS 0x00001600
#define BNX2_EMAC_TX_STAT_IFHCOUTBADOCTETS 0x00001604
#define BNX2_EMAC_TX_STAT_ETHERSTATSCOLLISIONS 0x00001608
@@ -1777,7 +2939,7 @@ struct l2_fhdr {
#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x00001644
#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001648
#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x0000164c
-#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001650
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTSOVER1522OCTETS 0x00001650
#define BNX2_EMAC_TX_STAT_DOT3STATSINTERNALMACTRANSMITERRORS 0x00001654
#define BNX2_EMAC_TXMAC_DEBUG0 0x00001658
#define BNX2_EMAC_TXMAC_DEBUG1 0x0000165c
@@ -1843,16 +3005,16 @@ struct l2_fhdr {
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_IDLE (0x0L<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA1 (0x2L<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA2 (0x3L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3 (0x4L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2 (0x5L<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA3 (0x6L<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC1 (0x7L<<16)
-#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2 (0x5L<<16)
-#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3 (0x4L<<16)
-#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE (0xcL<<16)
-#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD (0xeL<<16)
-#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME (0xaL<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC1 (0x8L<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC2 (0x9L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME (0xaL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE (0xcL<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_WAIT (0xdL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD (0xeL<<16)
#define BNX2_EMAC_TXMAC_DEBUG4_STATS0_VALID (1L<<20)
#define BNX2_EMAC_TXMAC_DEBUG4_APPEND_CRC (1L<<21)
#define BNX2_EMAC_TXMAC_DEBUG4_SLOT_FILLED (1L<<22)
@@ -1887,8 +3049,11 @@ struct l2_fhdr {
#define BNX2_EMAC_TX_STAT_AC18 0x000016c8
#define BNX2_EMAC_TX_STAT_AC19 0x000016cc
#define BNX2_EMAC_TX_STAT_AC20 0x000016d0
-#define BNX2_EMAC_TX_STAT_AC21 0x000016d4
#define BNX2_EMAC_TXMAC_SUC_DBG_OVERRUNVEC 0x000016d8
+#define BNX2_EMAC_TX_RATE_LIMIT_CTRL 0x000016fc
+#define BNX2_EMAC_TX_RATE_LIMIT_CTRL_TX_THROTTLE_INC (0x7fL<<0)
+#define BNX2_EMAC_TX_RATE_LIMIT_CTRL_TX_THROTTLE_NUM (0x7fL<<16)
+#define BNX2_EMAC_TX_RATE_LIMIT_CTRL_RATE_LIMITER_EN (1L<<31)
/*
@@ -1909,8 +3074,15 @@ struct l2_fhdr {
#define BNX2_RPM_CONFIG_ACPI_KEEP (1L<<2)
#define BNX2_RPM_CONFIG_MP_KEEP (1L<<3)
#define BNX2_RPM_CONFIG_SORT_VECT_VAL (0xfL<<4)
+#define BNX2_RPM_CONFIG_DISABLE_WOL_ASSERT (1L<<30)
#define BNX2_RPM_CONFIG_IGNORE_VLAN (1L<<31)
+#define BNX2_RPM_MGMT_PKT_CTRL 0x0000180c
+#define BNX2_RPM_MGMT_PKT_CTRL_MGMT_SORT (0xfL<<0)
+#define BNX2_RPM_MGMT_PKT_CTRL_MGMT_RULE (0xfL<<4)
+#define BNX2_RPM_MGMT_PKT_CTRL_MGMT_DISCARD_EN (1L<<30)
+#define BNX2_RPM_MGMT_PKT_CTRL_MGMT_EN (1L<<31)
+
#define BNX2_RPM_VLAN_MATCH0 0x00001810
#define BNX2_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE (0xfffL<<0)
@@ -1931,6 +3103,7 @@ struct l2_fhdr {
#define BNX2_RPM_SORT_USER0_PROM_EN (1L<<19)
#define BNX2_RPM_SORT_USER0_VLAN_EN (0xfL<<20)
#define BNX2_RPM_SORT_USER0_PROM_VLAN (1L<<24)
+#define BNX2_RPM_SORT_USER0_VLAN_NOTMATCH (1L<<25)
#define BNX2_RPM_SORT_USER0_ENA (1L<<31)
#define BNX2_RPM_SORT_USER1 0x00001824
@@ -1968,11 +3141,187 @@ struct l2_fhdr {
#define BNX2_RPM_STAT_IFINFTQDISCARDS 0x00001848
#define BNX2_RPM_STAT_IFINMBUFDISCARD 0x0000184c
#define BNX2_RPM_STAT_RULE_CHECKER_P4_HIT 0x00001850
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0 0x00001854
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1 0x00001858
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2 0x0000185c
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3 0x00001860
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4 0x00001864
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5 0x00001868
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6 0x0000186c
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_EN (1L<<31)
+
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7 0x00001870
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_LEN (0xffL<<0)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER (0xffL<<16)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_LEN_TYPE (1L<<30)
+#define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_EN (1L<<31)
+
#define BNX2_RPM_STAT_AC0 0x00001880
#define BNX2_RPM_STAT_AC1 0x00001884
#define BNX2_RPM_STAT_AC2 0x00001888
#define BNX2_RPM_STAT_AC3 0x0000188c
#define BNX2_RPM_STAT_AC4 0x00001890
+#define BNX2_RPM_RC_CNTL_16 0x000018e0
+#define BNX2_RPM_RC_CNTL_16_OFFSET (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_16_CLASS (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_16_PRIORITY (1L<<11)
+#define BNX2_RPM_RC_CNTL_16_P4 (1L<<12)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_START (0L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_IP (1L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_TCP (2L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_UDP (3L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_DATA (4L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_TCP_UDP (5L<<13)
+#define BNX2_RPM_RC_CNTL_16_HDR_TYPE_ICMPV6 (6L<<13)
+#define BNX2_RPM_RC_CNTL_16_COMP (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_16_COMP_EQUAL (0L<<16)
+#define BNX2_RPM_RC_CNTL_16_COMP_NEQUAL (1L<<16)
+#define BNX2_RPM_RC_CNTL_16_COMP_GREATER (2L<<16)
+#define BNX2_RPM_RC_CNTL_16_COMP_LESS (3L<<16)
+#define BNX2_RPM_RC_CNTL_16_MAP (1L<<18)
+#define BNX2_RPM_RC_CNTL_16_SBIT (1L<<19)
+#define BNX2_RPM_RC_CNTL_16_CMDSEL (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_16_DISCARD (1L<<25)
+#define BNX2_RPM_RC_CNTL_16_MASK (1L<<26)
+#define BNX2_RPM_RC_CNTL_16_P1 (1L<<27)
+#define BNX2_RPM_RC_CNTL_16_P2 (1L<<28)
+#define BNX2_RPM_RC_CNTL_16_P3 (1L<<29)
+#define BNX2_RPM_RC_CNTL_16_NBIT (1L<<30)
+
+#define BNX2_RPM_RC_VALUE_MASK_16 0x000018e4
+#define BNX2_RPM_RC_VALUE_MASK_16_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_16_MASK (0xffffL<<16)
+
+#define BNX2_RPM_RC_CNTL_17 0x000018e8
+#define BNX2_RPM_RC_CNTL_17_OFFSET (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_17_CLASS (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_17_PRIORITY (1L<<11)
+#define BNX2_RPM_RC_CNTL_17_P4 (1L<<12)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_START (0L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_IP (1L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_TCP (2L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_UDP (3L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_DATA (4L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_TCP_UDP (5L<<13)
+#define BNX2_RPM_RC_CNTL_17_HDR_TYPE_ICMPV6 (6L<<13)
+#define BNX2_RPM_RC_CNTL_17_COMP (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_17_COMP_EQUAL (0L<<16)
+#define BNX2_RPM_RC_CNTL_17_COMP_NEQUAL (1L<<16)
+#define BNX2_RPM_RC_CNTL_17_COMP_GREATER (2L<<16)
+#define BNX2_RPM_RC_CNTL_17_COMP_LESS (3L<<16)
+#define BNX2_RPM_RC_CNTL_17_MAP (1L<<18)
+#define BNX2_RPM_RC_CNTL_17_SBIT (1L<<19)
+#define BNX2_RPM_RC_CNTL_17_CMDSEL (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_17_DISCARD (1L<<25)
+#define BNX2_RPM_RC_CNTL_17_MASK (1L<<26)
+#define BNX2_RPM_RC_CNTL_17_P1 (1L<<27)
+#define BNX2_RPM_RC_CNTL_17_P2 (1L<<28)
+#define BNX2_RPM_RC_CNTL_17_P3 (1L<<29)
+#define BNX2_RPM_RC_CNTL_17_NBIT (1L<<30)
+
+#define BNX2_RPM_RC_VALUE_MASK_17 0x000018ec
+#define BNX2_RPM_RC_VALUE_MASK_17_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_17_MASK (0xffffL<<16)
+
+#define BNX2_RPM_RC_CNTL_18 0x000018f0
+#define BNX2_RPM_RC_CNTL_18_OFFSET (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_18_CLASS (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_18_PRIORITY (1L<<11)
+#define BNX2_RPM_RC_CNTL_18_P4 (1L<<12)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_START (0L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_IP (1L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_TCP (2L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_UDP (3L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_DATA (4L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_TCP_UDP (5L<<13)
+#define BNX2_RPM_RC_CNTL_18_HDR_TYPE_ICMPV6 (6L<<13)
+#define BNX2_RPM_RC_CNTL_18_COMP (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_18_COMP_EQUAL (0L<<16)
+#define BNX2_RPM_RC_CNTL_18_COMP_NEQUAL (1L<<16)
+#define BNX2_RPM_RC_CNTL_18_COMP_GREATER (2L<<16)
+#define BNX2_RPM_RC_CNTL_18_COMP_LESS (3L<<16)
+#define BNX2_RPM_RC_CNTL_18_MAP (1L<<18)
+#define BNX2_RPM_RC_CNTL_18_SBIT (1L<<19)
+#define BNX2_RPM_RC_CNTL_18_CMDSEL (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_18_DISCARD (1L<<25)
+#define BNX2_RPM_RC_CNTL_18_MASK (1L<<26)
+#define BNX2_RPM_RC_CNTL_18_P1 (1L<<27)
+#define BNX2_RPM_RC_CNTL_18_P2 (1L<<28)
+#define BNX2_RPM_RC_CNTL_18_P3 (1L<<29)
+#define BNX2_RPM_RC_CNTL_18_NBIT (1L<<30)
+
+#define BNX2_RPM_RC_VALUE_MASK_18 0x000018f4
+#define BNX2_RPM_RC_VALUE_MASK_18_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_18_MASK (0xffffL<<16)
+
+#define BNX2_RPM_RC_CNTL_19 0x000018f8
+#define BNX2_RPM_RC_CNTL_19_OFFSET (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_19_CLASS (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_19_PRIORITY (1L<<11)
+#define BNX2_RPM_RC_CNTL_19_P4 (1L<<12)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_START (0L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_IP (1L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_TCP (2L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_UDP (3L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_DATA (4L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_TCP_UDP (5L<<13)
+#define BNX2_RPM_RC_CNTL_19_HDR_TYPE_ICMPV6 (6L<<13)
+#define BNX2_RPM_RC_CNTL_19_COMP (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_19_COMP_EQUAL (0L<<16)
+#define BNX2_RPM_RC_CNTL_19_COMP_NEQUAL (1L<<16)
+#define BNX2_RPM_RC_CNTL_19_COMP_GREATER (2L<<16)
+#define BNX2_RPM_RC_CNTL_19_COMP_LESS (3L<<16)
+#define BNX2_RPM_RC_CNTL_19_MAP (1L<<18)
+#define BNX2_RPM_RC_CNTL_19_SBIT (1L<<19)
+#define BNX2_RPM_RC_CNTL_19_CMDSEL (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_19_DISCARD (1L<<25)
+#define BNX2_RPM_RC_CNTL_19_MASK (1L<<26)
+#define BNX2_RPM_RC_CNTL_19_P1 (1L<<27)
+#define BNX2_RPM_RC_CNTL_19_P2 (1L<<28)
+#define BNX2_RPM_RC_CNTL_19_P3 (1L<<29)
+#define BNX2_RPM_RC_CNTL_19_NBIT (1L<<30)
+
+#define BNX2_RPM_RC_VALUE_MASK_19 0x000018fc
+#define BNX2_RPM_RC_VALUE_MASK_19_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_19_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_0 0x00001900
#define BNX2_RPM_RC_CNTL_0_OFFSET (0xffL<<0)
#define BNX2_RPM_RC_CNTL_0_CLASS (0x7L<<8)
@@ -1984,14 +3333,18 @@ struct l2_fhdr {
#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP (2L<<13)
#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_UDP (3L<<13)
#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_DATA (4L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP_UDP (5L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_ICMPV6 (6L<<13)
#define BNX2_RPM_RC_CNTL_0_COMP (0x3L<<16)
#define BNX2_RPM_RC_CNTL_0_COMP_EQUAL (0L<<16)
#define BNX2_RPM_RC_CNTL_0_COMP_NEQUAL (1L<<16)
#define BNX2_RPM_RC_CNTL_0_COMP_GREATER (2L<<16)
#define BNX2_RPM_RC_CNTL_0_COMP_LESS (3L<<16)
+#define BNX2_RPM_RC_CNTL_0_MAP_XI (1L<<18)
#define BNX2_RPM_RC_CNTL_0_SBIT (1L<<19)
#define BNX2_RPM_RC_CNTL_0_CMDSEL (0xfL<<20)
#define BNX2_RPM_RC_CNTL_0_MAP (1L<<24)
+#define BNX2_RPM_RC_CNTL_0_CMDSEL_XI (0x1fL<<20)
#define BNX2_RPM_RC_CNTL_0_DISCARD (1L<<25)
#define BNX2_RPM_RC_CNTL_0_MASK (1L<<26)
#define BNX2_RPM_RC_CNTL_0_P1 (1L<<27)
@@ -2006,81 +3359,518 @@ struct l2_fhdr {
#define BNX2_RPM_RC_CNTL_1 0x00001908
#define BNX2_RPM_RC_CNTL_1_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_1_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_1_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_1_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_1_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_1_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_1_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_1_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_1_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_1_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_1_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_1_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_1_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_1_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_1_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_1_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_1_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_1_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_1_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_1_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_1_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_1 0x0000190c
+#define BNX2_RPM_RC_VALUE_MASK_1_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_1_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_2 0x00001910
#define BNX2_RPM_RC_CNTL_2_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_2_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_2_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_2_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_2_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_2_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_2_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_2_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_2_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_2_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_2_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_2_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_2_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_2_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_2_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_2_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_2_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_2_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_2_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_2_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_2_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_2 0x00001914
+#define BNX2_RPM_RC_VALUE_MASK_2_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_2_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_3 0x00001918
#define BNX2_RPM_RC_CNTL_3_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_3_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_3_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_3_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_3_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_3_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_3_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_3_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_3_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_3_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_3_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_3_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_3_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_3_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_3_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_3_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_3_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_3_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_3_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_3_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_3_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_3 0x0000191c
+#define BNX2_RPM_RC_VALUE_MASK_3_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_3_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_4 0x00001920
#define BNX2_RPM_RC_CNTL_4_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_4_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_4_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_4_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_4_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_4_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_4_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_4_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_4_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_4_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_4_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_4_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_4_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_4_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_4_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_4_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_4_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_4_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_4_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_4_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_4_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_4 0x00001924
+#define BNX2_RPM_RC_VALUE_MASK_4_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_4_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_5 0x00001928
#define BNX2_RPM_RC_CNTL_5_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_5_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_5_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_5_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_5_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_5_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_5_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_5_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_5_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_5_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_5_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_5_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_5_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_5_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_5_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_5_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_5_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_5_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_5_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_5_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_5_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_5 0x0000192c
+#define BNX2_RPM_RC_VALUE_MASK_5_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_5_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_6 0x00001930
#define BNX2_RPM_RC_CNTL_6_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_6_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_6_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_6_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_6_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_6_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_6_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_6_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_6_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_6_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_6_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_6_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_6_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_6_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_6_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_6_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_6_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_6_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_6_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_6_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_6_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_6 0x00001934
+#define BNX2_RPM_RC_VALUE_MASK_6_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_6_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_7 0x00001938
#define BNX2_RPM_RC_CNTL_7_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_7_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_7_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_7_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_7_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_7_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_7_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_7_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_7_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_7_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_7_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_7_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_7_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_7_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_7_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_7_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_7_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_7_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_7_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_7_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_7_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_7 0x0000193c
+#define BNX2_RPM_RC_VALUE_MASK_7_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_7_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_8 0x00001940
#define BNX2_RPM_RC_CNTL_8_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_8_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_8_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_8_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_8_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_8_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_8_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_8_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_8_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_8_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_8_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_8_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_8_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_8_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_8_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_8_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_8_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_8_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_8_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_8_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_8_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_8 0x00001944
+#define BNX2_RPM_RC_VALUE_MASK_8_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_8_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_9 0x00001948
#define BNX2_RPM_RC_CNTL_9_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_9_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_9_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_9_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_9_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_9_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_9_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_9_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_9_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_9_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_9_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_9_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_9_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_9_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_9_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_9_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_9_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_9_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_9_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_9_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_9_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_9 0x0000194c
+#define BNX2_RPM_RC_VALUE_MASK_9_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_9_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_10 0x00001950
#define BNX2_RPM_RC_CNTL_10_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_10_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_10_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_10_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_10_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_10_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_10_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_10_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_10_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_10_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_10_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_10_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_10_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_10_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_10_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_10_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_10_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_10_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_10_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_10_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_10_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_10 0x00001954
+#define BNX2_RPM_RC_VALUE_MASK_10_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_10_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_11 0x00001958
#define BNX2_RPM_RC_CNTL_11_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_11_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_11_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_11_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_11_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_11_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_11_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_11_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_11_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_11_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_11_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_11_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_11_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_11_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_11_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_11_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_11_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_11_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_11_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_11_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_11_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_11 0x0000195c
+#define BNX2_RPM_RC_VALUE_MASK_11_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_11_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_12 0x00001960
#define BNX2_RPM_RC_CNTL_12_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_12_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_12_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_12_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_12_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_12_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_12_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_12_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_12_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_12_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_12_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_12_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_12_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_12_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_12_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_12_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_12_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_12_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_12_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_12_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_12_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_12 0x00001964
+#define BNX2_RPM_RC_VALUE_MASK_12_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_12_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_13 0x00001968
#define BNX2_RPM_RC_CNTL_13_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_13_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_13_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_13_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_13_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_13_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_13_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_13_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_13_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_13_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_13_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_13_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_13_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_13_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_13_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_13_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_13_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_13_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_13_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_13_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_13_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_13 0x0000196c
+#define BNX2_RPM_RC_VALUE_MASK_13_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_13_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_14 0x00001970
#define BNX2_RPM_RC_CNTL_14_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_14_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_14_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_14_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_14_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_14_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_14_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_14_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_14_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_14_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_14_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_14_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_14_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_14_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_14_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_14_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_14_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_14_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_14_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_14_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_14_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_14 0x00001974
+#define BNX2_RPM_RC_VALUE_MASK_14_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_14_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CNTL_15 0x00001978
#define BNX2_RPM_RC_CNTL_15_A (0x3ffffL<<0)
#define BNX2_RPM_RC_CNTL_15_B (0xfffL<<19)
+#define BNX2_RPM_RC_CNTL_15_OFFSET_XI (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_15_CLASS_XI (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_15_PRIORITY_XI (1L<<11)
+#define BNX2_RPM_RC_CNTL_15_P4_XI (1L<<12)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_XI (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_START_XI (0L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_IP_XI (1L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_TCP_XI (2L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_UDP_XI (3L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_DATA_XI (4L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_TCP_UDP_XI (5L<<13)
+#define BNX2_RPM_RC_CNTL_15_HDR_TYPE_ICMPV6_XI (6L<<13)
+#define BNX2_RPM_RC_CNTL_15_COMP_XI (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_15_COMP_EQUAL_XI (0L<<16)
+#define BNX2_RPM_RC_CNTL_15_COMP_NEQUAL_XI (1L<<16)
+#define BNX2_RPM_RC_CNTL_15_COMP_GREATER_XI (2L<<16)
+#define BNX2_RPM_RC_CNTL_15_COMP_LESS_XI (3L<<16)
+#define BNX2_RPM_RC_CNTL_15_MAP_XI (1L<<18)
+#define BNX2_RPM_RC_CNTL_15_SBIT_XI (1L<<19)
+#define BNX2_RPM_RC_CNTL_15_CMDSEL_XI (0x1fL<<20)
+#define BNX2_RPM_RC_CNTL_15_DISCARD_XI (1L<<25)
+#define BNX2_RPM_RC_CNTL_15_MASK_XI (1L<<26)
+#define BNX2_RPM_RC_CNTL_15_P1_XI (1L<<27)
+#define BNX2_RPM_RC_CNTL_15_P2_XI (1L<<28)
+#define BNX2_RPM_RC_CNTL_15_P3_XI (1L<<29)
+#define BNX2_RPM_RC_CNTL_15_NBIT_XI (1L<<30)
#define BNX2_RPM_RC_VALUE_MASK_15 0x0000197c
+#define BNX2_RPM_RC_VALUE_MASK_15_VALUE (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_15_MASK (0xffffL<<16)
+
#define BNX2_RPM_RC_CONFIG 0x00001980
#define BNX2_RPM_RC_CONFIG_RULE_ENABLE (0xffffL<<0)
+#define BNX2_RPM_RC_CONFIG_RULE_ENABLE_XI (0xfffffL<<0)
#define BNX2_RPM_RC_CONFIG_DEF_CLASS (0x7L<<24)
+#define BNX2_RPM_RC_CONFIG_KNUM_OVERWRITE (1L<<31)
#define BNX2_RPM_DEBUG0 0x00001984
#define BNX2_RPM_DEBUG0_FM_BCNT (0xffffL<<0)
@@ -2236,6 +4026,16 @@ struct l2_fhdr {
#define BNX2_RPM_DEBUG9_INFIFO_OVERRUN_OCCURRED (1L<<29)
#define BNX2_RPM_DEBUG9_ACPI_MATCH_INT (1L<<30)
#define BNX2_RPM_DEBUG9_ACPI_ENABLE_SYN (1L<<31)
+#define BNX2_RPM_DEBUG9_BEMEM_R_XI (0x1fL<<0)
+#define BNX2_RPM_DEBUG9_EO_XI (1L<<5)
+#define BNX2_RPM_DEBUG9_AEOF_DE_XI (1L<<6)
+#define BNX2_RPM_DEBUG9_SO_XI (1L<<7)
+#define BNX2_RPM_DEBUG9_WD64_CT_XI (0x1fL<<8)
+#define BNX2_RPM_DEBUG9_EOF_VLDBYTE_XI (0x7L<<13)
+#define BNX2_RPM_DEBUG9_ACPI_RDE_PAT_ID_XI (0xfL<<16)
+#define BNX2_RPM_DEBUG9_CALCRC_RESULT_XI (0x3ffL<<20)
+#define BNX2_RPM_DEBUG9_DATA_IN_VL_XI (1L<<30)
+#define BNX2_RPM_DEBUG9_CALCRC_BUFFER_VLD_XI (1L<<31)
#define BNX2_RPM_ACPI_DBG_BUF_W00 0x000019c0
#define BNX2_RPM_ACPI_DBG_BUF_W01 0x000019c4
@@ -2253,6 +4053,56 @@ struct l2_fhdr {
#define BNX2_RPM_ACPI_DBG_BUF_W31 0x000019f4
#define BNX2_RPM_ACPI_DBG_BUF_W32 0x000019f8
#define BNX2_RPM_ACPI_DBG_BUF_W33 0x000019fc
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL 0x00001a00
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_BYTE_ADDRESS (0xffffL<<0)
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_DEBUGRD (1L<<28)
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_MODE (1L<<29)
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_INIT (1L<<30)
+#define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_WR (1L<<31)
+
+#define BNX2_RPM_ACPI_PATTERN_CTRL 0x00001a04
+#define BNX2_RPM_ACPI_PATTERN_CTRL_PATTERN_ID (0xfL<<0)
+#define BNX2_RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR (1L<<30)
+#define BNX2_RPM_ACPI_PATTERN_CTRL_WR (1L<<31)
+
+#define BNX2_RPM_ACPI_DATA 0x00001a08
+#define BNX2_RPM_ACPI_DATA_PATTERN_BE (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_LEN0 0x00001a0c
+#define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN3 (0xffL<<0)
+#define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN2 (0xffL<<8)
+#define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN1 (0xffL<<16)
+#define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN0 (0xffL<<24)
+
+#define BNX2_RPM_ACPI_PATTERN_LEN1 0x00001a10
+#define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN7 (0xffL<<0)
+#define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN6 (0xffL<<8)
+#define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN5 (0xffL<<16)
+#define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN4 (0xffL<<24)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC0 0x00001a18
+#define BNX2_RPM_ACPI_PATTERN_CRC0_PATTERN_CRC0 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC1 0x00001a1c
+#define BNX2_RPM_ACPI_PATTERN_CRC1_PATTERN_CRC1 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC2 0x00001a20
+#define BNX2_RPM_ACPI_PATTERN_CRC2_PATTERN_CRC2 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC3 0x00001a24
+#define BNX2_RPM_ACPI_PATTERN_CRC3_PATTERN_CRC3 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC4 0x00001a28
+#define BNX2_RPM_ACPI_PATTERN_CRC4_PATTERN_CRC4 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC5 0x00001a2c
+#define BNX2_RPM_ACPI_PATTERN_CRC5_PATTERN_CRC5 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC6 0x00001a30
+#define BNX2_RPM_ACPI_PATTERN_CRC6_PATTERN_CRC6 (0xffffffffL<<0)
+
+#define BNX2_RPM_ACPI_PATTERN_CRC7 0x00001a34
+#define BNX2_RPM_ACPI_PATTERN_CRC7_PATTERN_CRC7 (0xffffffffL<<0)
/*
@@ -2263,15 +4113,20 @@ struct l2_fhdr {
#define BNX2_RBUF_COMMAND_ENABLED (1L<<0)
#define BNX2_RBUF_COMMAND_FREE_INIT (1L<<1)
#define BNX2_RBUF_COMMAND_RAM_INIT (1L<<2)
+#define BNX2_RBUF_COMMAND_PKT_OFFSET_OVFL (1L<<3)
#define BNX2_RBUF_COMMAND_OVER_FREE (1L<<4)
#define BNX2_RBUF_COMMAND_ALLOC_REQ (1L<<5)
+#define BNX2_RBUF_COMMAND_EN_PRI_CHNGE_TE (1L<<6)
+#define BNX2_RBUF_COMMAND_CU_ISOLATE_XI (1L<<5)
+#define BNX2_RBUF_COMMAND_EN_PRI_CHANGE_XI (1L<<6)
+#define BNX2_RBUF_COMMAND_GRC_ENDIAN_CONV_DIS_XI (1L<<7)
#define BNX2_RBUF_STATUS1 0x00200004
#define BNX2_RBUF_STATUS1_FREE_COUNT (0x3ffL<<0)
#define BNX2_RBUF_STATUS2 0x00200008
-#define BNX2_RBUF_STATUS2_FREE_TAIL (0x3ffL<<0)
-#define BNX2_RBUF_STATUS2_FREE_HEAD (0x3ffL<<16)
+#define BNX2_RBUF_STATUS2_FREE_TAIL (0x1ffL<<0)
+#define BNX2_RBUF_STATUS2_FREE_HEAD (0x1ffL<<16)
#define BNX2_RBUF_CONFIG 0x0020000c
#define BNX2_RBUF_CONFIG_XOFF_TRIP (0x3ffL<<0)
@@ -2279,16 +4134,21 @@ struct l2_fhdr {
#define BNX2_RBUF_FW_BUF_ALLOC 0x00200010
#define BNX2_RBUF_FW_BUF_ALLOC_VALUE (0x1ffL<<7)
+#define BNX2_RBUF_FW_BUF_ALLOC_TYPE (1L<<16)
+#define BNX2_RBUF_FW_BUF_ALLOC_ALLOC_REQ (1L<<31)
#define BNX2_RBUF_FW_BUF_FREE 0x00200014
#define BNX2_RBUF_FW_BUF_FREE_COUNT (0x7fL<<0)
#define BNX2_RBUF_FW_BUF_FREE_TAIL (0x1ffL<<7)
#define BNX2_RBUF_FW_BUF_FREE_HEAD (0x1ffL<<16)
+#define BNX2_RBUF_FW_BUF_FREE_TYPE (1L<<25)
+#define BNX2_RBUF_FW_BUF_FREE_FREE_REQ (1L<<31)
#define BNX2_RBUF_FW_BUF_SEL 0x00200018
#define BNX2_RBUF_FW_BUF_SEL_COUNT (0x7fL<<0)
#define BNX2_RBUF_FW_BUF_SEL_TAIL (0x1ffL<<7)
#define BNX2_RBUF_FW_BUF_SEL_HEAD (0x1ffL<<16)
+#define BNX2_RBUF_FW_BUF_SEL_SEL_REQ (1L<<31)
#define BNX2_RBUF_CONFIG2 0x0020001c
#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP (0x3ffL<<0)
@@ -2376,6 +4236,8 @@ struct l2_fhdr {
#define BNX2_RV2P_INSTR_HIGH_HIGH (0x1fL<<0)
#define BNX2_RV2P_INSTR_LOW 0x00002834
+#define BNX2_RV2P_INSTR_LOW_LOW (0xffffffffL<<0)
+
#define BNX2_RV2P_PROC1_ADDR_CMD 0x00002838
#define BNX2_RV2P_PROC1_ADDR_CMD_ADD (0x3ffL<<0)
#define BNX2_RV2P_PROC1_ADDR_CMD_RDWR (1L<<31)
@@ -2395,7 +4257,29 @@ struct l2_fhdr {
#define BNX2_RV2P_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27)
#define BNX2_RV2P_DEBUG_VECT_PEEK_2_SEL (0xfL<<28)
-#define BNX2_RV2P_PFTQ_DATA 0x00002b40
+#define BNX2_RV2P_MPFE_PFE_CTL 0x00002afc
+#define BNX2_RV2P_MPFE_PFE_CTL_INC_USAGE_CNT (1L<<0)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE (0xfL<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_0 (0L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_1 (1L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_2 (2L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_3 (3L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_4 (4L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_5 (5L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_6 (6L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_7 (7L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_8 (8L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_9 (9L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_10 (10L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_11 (11L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_12 (12L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_13 (13L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_14 (14L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_15 (15L<<4)
+#define BNX2_RV2P_MPFE_PFE_CTL_PFE_COUNT (0xfL<<12)
+#define BNX2_RV2P_MPFE_PFE_CTL_OFFSET (0x1ffL<<16)
+
+#define BNX2_RV2P_RV2PPQ 0x00002b40
#define BNX2_RV2P_PFTQ_CMD 0x00002b78
#define BNX2_RV2P_PFTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_RV2P_PFTQ_CMD_WR_TOP (1L<<10)
@@ -2416,7 +4300,7 @@ struct l2_fhdr {
#define BNX2_RV2P_PFTQ_CTL_MAX_DEPTH (0x3ffL<<12)
#define BNX2_RV2P_PFTQ_CTL_CUR_DEPTH (0x3ffL<<22)
-#define BNX2_RV2P_TFTQ_DATA 0x00002b80
+#define BNX2_RV2P_RV2PTQ 0x00002b80
#define BNX2_RV2P_TFTQ_CMD 0x00002bb8
#define BNX2_RV2P_TFTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_RV2P_TFTQ_CMD_WR_TOP (1L<<10)
@@ -2437,7 +4321,7 @@ struct l2_fhdr {
#define BNX2_RV2P_TFTQ_CTL_MAX_DEPTH (0x3ffL<<12)
#define BNX2_RV2P_TFTQ_CTL_CUR_DEPTH (0x3ffL<<22)
-#define BNX2_RV2P_MFTQ_DATA 0x00002bc0
+#define BNX2_RV2P_RV2PMQ 0x00002bc0
#define BNX2_RV2P_MFTQ_CMD 0x00002bf8
#define BNX2_RV2P_MFTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_RV2P_MFTQ_CMD_WR_TOP (1L<<10)
@@ -2466,18 +4350,26 @@ struct l2_fhdr {
*/
#define BNX2_MQ_COMMAND 0x00003c00
#define BNX2_MQ_COMMAND_ENABLED (1L<<0)
+#define BNX2_MQ_COMMAND_INIT (1L<<1)
#define BNX2_MQ_COMMAND_OVERFLOW (1L<<4)
#define BNX2_MQ_COMMAND_WR_ERROR (1L<<5)
#define BNX2_MQ_COMMAND_RD_ERROR (1L<<6)
+#define BNX2_MQ_COMMAND_IDB_CFG_ERROR (1L<<7)
+#define BNX2_MQ_COMMAND_IDB_OVERFLOW (1L<<10)
+#define BNX2_MQ_COMMAND_NO_BIN_ERROR (1L<<11)
+#define BNX2_MQ_COMMAND_NO_MAP_ERROR (1L<<12)
#define BNX2_MQ_STATUS 0x00003c04
#define BNX2_MQ_STATUS_CTX_ACCESS_STAT (1L<<16)
#define BNX2_MQ_STATUS_CTX_ACCESS64_STAT (1L<<17)
#define BNX2_MQ_STATUS_PCI_STALL_STAT (1L<<18)
+#define BNX2_MQ_STATUS_IDB_OFLOW_STAT (1L<<19)
#define BNX2_MQ_CONFIG 0x00003c08
#define BNX2_MQ_CONFIG_TX_HIGH_PRI (1L<<0)
#define BNX2_MQ_CONFIG_HALT_DIS (1L<<1)
+#define BNX2_MQ_CONFIG_BIN_MQ_MODE (1L<<2)
+#define BNX2_MQ_CONFIG_DIS_IDB_DROP (1L<<3)
#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE (0x7L<<4)
#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256 (0L<<4)
#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_512 (1L<<4)
@@ -2533,6 +4425,7 @@ struct l2_fhdr {
#define BNX2_MQ_MEM_WR_DATA2 0x00003c80
#define BNX2_MQ_MEM_WR_DATA2_VALUE (0x3fffffffL<<0)
+#define BNX2_MQ_MEM_WR_DATA2_VALUE_XI (0x7fffffffL<<0)
#define BNX2_MQ_MEM_RD_ADDR 0x00003c84
#define BNX2_MQ_MEM_RD_ADDR_VALUE (0x3fL<<0)
@@ -2545,6 +4438,16 @@ struct l2_fhdr {
#define BNX2_MQ_MEM_RD_DATA2 0x00003c90
#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0)
+#define BNX2_MQ_MEM_RD_DATA2_VALUE_XI (0x7fffffffL<<0)
+
+
+/*
+ * tsch_reg definition
+ * offset: 0x4c00
+ */
+#define BNX2_TSCH_TSS_CFG 0x00004c1c
+#define BNX2_TSCH_TSS_CFG_TSS_START_CID (0x7ffL<<8)
+#define BNX2_TSCH_TSS_CFG_NUM_OF_TSS_CON (0xfL<<24)
@@ -2594,7 +4497,11 @@ struct l2_fhdr {
#define BNX2_TBDR_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27)
#define BNX2_TBDR_DEBUG_VECT_PEEK_2_SEL (0xfL<<28)
-#define BNX2_TBDR_FTQ_DATA 0x000053c0
+#define BNX2_TBDR_CKSUM_ERROR_STATUS 0x00005010
+#define BNX2_TBDR_CKSUM_ERROR_STATUS_CALCULATED (0xffffL<<0)
+#define BNX2_TBDR_CKSUM_ERROR_STATUS_EXPECTED (0xffffL<<16)
+
+#define BNX2_TBDR_TBDRQ 0x000053c0
#define BNX2_TBDR_FTQ_CMD 0x000053f8
#define BNX2_TBDR_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_TBDR_FTQ_CMD_WR_TOP (1L<<10)
@@ -2624,7 +4531,15 @@ struct l2_fhdr {
#define BNX2_TDMA_COMMAND 0x00005c00
#define BNX2_TDMA_COMMAND_ENABLED (1L<<0)
#define BNX2_TDMA_COMMAND_MASTER_ABORT (1L<<4)
+#define BNX2_TDMA_COMMAND_CS16_ERR (1L<<5)
#define BNX2_TDMA_COMMAND_BAD_L2_LENGTH_ABORT (1L<<7)
+#define BNX2_TDMA_COMMAND_MASK_CS1 (1L<<20)
+#define BNX2_TDMA_COMMAND_MASK_CS2 (1L<<21)
+#define BNX2_TDMA_COMMAND_MASK_CS3 (1L<<22)
+#define BNX2_TDMA_COMMAND_MASK_CS4 (1L<<23)
+#define BNX2_TDMA_COMMAND_FORCE_ILOCK_CKERR (1L<<24)
+#define BNX2_TDMA_COMMAND_OFIFO_CLR (1L<<30)
+#define BNX2_TDMA_COMMAND_IFIFO_CLR (1L<<31)
#define BNX2_TDMA_STATUS 0x00005c04
#define BNX2_TDMA_STATUS_DMA_WAIT (1L<<0)
@@ -2633,10 +4548,18 @@ struct l2_fhdr {
#define BNX2_TDMA_STATUS_LOCK_WAIT (1L<<3)
#define BNX2_TDMA_STATUS_FTQ_ENTRY_CNT (1L<<16)
#define BNX2_TDMA_STATUS_BURST_CNT (1L<<17)
+#define BNX2_TDMA_STATUS_MAX_IFIFO_DEPTH (0x3fL<<20)
+#define BNX2_TDMA_STATUS_OFIFO_OVERFLOW (1L<<30)
+#define BNX2_TDMA_STATUS_IFIFO_OVERFLOW (1L<<31)
#define BNX2_TDMA_CONFIG 0x00005c08
#define BNX2_TDMA_CONFIG_ONE_DMA (1L<<0)
#define BNX2_TDMA_CONFIG_ONE_RECORD (1L<<1)
+#define BNX2_TDMA_CONFIG_NUM_DMA_CHAN (0x3L<<2)
+#define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_0 (0L<<2)
+#define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_1 (1L<<2)
+#define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_2 (2L<<2)
+#define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_3 (3L<<2)
#define BNX2_TDMA_CONFIG_LIMIT_SZ (0xfL<<4)
#define BNX2_TDMA_CONFIG_LIMIT_SZ_64 (0L<<4)
#define BNX2_TDMA_CONFIG_LIMIT_SZ_128 (0x4L<<4)
@@ -2649,7 +4572,35 @@ struct l2_fhdr {
#define BNX2_TDMA_CONFIG_LINE_SZ_512 (8L<<8)
#define BNX2_TDMA_CONFIG_ALIGN_ENA (1L<<15)
#define BNX2_TDMA_CONFIG_CHK_L2_BD (1L<<16)
+#define BNX2_TDMA_CONFIG_CMPL_ENTRY (1L<<17)
+#define BNX2_TDMA_CONFIG_OFIFO_CMP (1L<<19)
+#define BNX2_TDMA_CONFIG_OFIFO_CMP_3 (0L<<19)
+#define BNX2_TDMA_CONFIG_OFIFO_CMP_2 (1L<<19)
#define BNX2_TDMA_CONFIG_FIFO_CMP (0xfL<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_XI (0x7L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_0_XI (0L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_4_XI (1L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_8_XI (2L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_16_XI (3L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_32_XI (4L<<20)
+#define BNX2_TDMA_CONFIG_IFIFO_DEPTH_64_XI (5L<<20)
+#define BNX2_TDMA_CONFIG_FIFO_CMP_EN_XI (1L<<23)
+#define BNX2_TDMA_CONFIG_BYTES_OST_XI (0x7L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_512_XI (0L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_1024_XI (1L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_2048_XI (2L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_4096_XI (3L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_8192_XI (4L<<24)
+#define BNX2_TDMA_CONFIG_BYTES_OST_16384_XI (5L<<24)
+#define BNX2_TDMA_CONFIG_HC_BYPASS_XI (1L<<27)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_XI (0x7L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_128_XI (0L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_256_XI (1L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_512_XI (2L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_1024_XI (3L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_2048_XI (4L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_4096_XI (5L<<28)
+#define BNX2_TDMA_CONFIG_LCL_MRRS_EN_XI (1L<<31)
#define BNX2_TDMA_PAYLOAD_PROD 0x00005c0c
#define BNX2_TDMA_PAYLOAD_PROD_VALUE (0x1fffL<<3)
@@ -2685,7 +4636,22 @@ struct l2_fhdr {
#define BNX2_TDMA_DR_INTF_STATUS_NXT_PNTR (0xfL<<12)
#define BNX2_TDMA_DR_INTF_STATUS_BYTE_COUNT (0x7L<<16)
-#define BNX2_TDMA_FTQ_DATA 0x00005fc0
+#define BNX2_TDMA_PUSH_FSM 0x00005c90
+#define BNX2_TDMA_BD_IF_DEBUG 0x00005c94
+#define BNX2_TDMA_DMAD_IF_DEBUG 0x00005c98
+#define BNX2_TDMA_CTX_IF_DEBUG 0x00005c9c
+#define BNX2_TDMA_TPBUF_IF_DEBUG 0x00005ca0
+#define BNX2_TDMA_DR_IF_DEBUG 0x00005ca4
+#define BNX2_TDMA_TPATQ_IF_DEBUG 0x00005ca8
+#define BNX2_TDMA_TDMA_ILOCK_CKSUM 0x00005cac
+#define BNX2_TDMA_TDMA_ILOCK_CKSUM_CALCULATED (0xffffL<<0)
+#define BNX2_TDMA_TDMA_ILOCK_CKSUM_EXPECTED (0xffffL<<16)
+
+#define BNX2_TDMA_TDMA_PCIE_CKSUM 0x00005cb0
+#define BNX2_TDMA_TDMA_PCIE_CKSUM_CALCULATED (0xffffL<<0)
+#define BNX2_TDMA_TDMA_PCIE_CKSUM_EXPECTED (0xffffL<<16)
+
+#define BNX2_TDMA_TDMAQ 0x00005fc0
#define BNX2_TDMA_FTQ_CMD 0x00005ff8
#define BNX2_TDMA_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_TDMA_FTQ_CMD_WR_TOP (1L<<10)
@@ -2724,6 +4690,8 @@ struct l2_fhdr {
#define BNX2_HC_COMMAND_FORCE_INT_LOW (2L<<19)
#define BNX2_HC_COMMAND_FORCE_INT_FREE (3L<<19)
#define BNX2_HC_COMMAND_CLR_STAT_NOW (1L<<21)
+#define BNX2_HC_COMMAND_MAIN_PWR_INT (1L<<22)
+#define BNX2_HC_COMMAND_COAL_ON_NEXT_EVENT (1L<<27)
#define BNX2_HC_STATUS 0x00006804
#define BNX2_HC_STATUS_MASTER_ABORT (1L<<0)
@@ -2746,6 +4714,23 @@ struct l2_fhdr {
#define BNX2_HC_CONFIG_STATISTIC_PRIORITY (1L<<5)
#define BNX2_HC_CONFIG_STATUS_PRIORITY (1L<<6)
#define BNX2_HC_CONFIG_STAT_MEM_ADDR (0xffL<<8)
+#define BNX2_HC_CONFIG_PER_MODE (1L<<16)
+#define BNX2_HC_CONFIG_ONE_SHOT (1L<<17)
+#define BNX2_HC_CONFIG_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_CONFIG_SET_MASK_AT_RD (1L<<19)
+#define BNX2_HC_CONFIG_PER_COLLECT_LIMIT (0xfL<<20)
+#define BNX2_HC_CONFIG_SB_ADDR_INC (0x7L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_64B (0L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_128B (1L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_256B (2L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_512B (3L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_1024B (4L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_2048B (5L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_4096B (6L<<24)
+#define BNX2_HC_CONFIG_SB_ADDR_INC_8192B (7L<<24)
+#define BNX2_HC_CONFIG_GEN_STAT_AVG_INTR (1L<<29)
+#define BNX2_HC_CONFIG_UNMASK_ALL (1L<<30)
+#define BNX2_HC_CONFIG_TX_SEL (1L<<31)
#define BNX2_HC_ATTN_BITS_ENABLE 0x0000680c
#define BNX2_HC_STATUS_ADDR_L 0x00006810
@@ -2782,6 +4767,7 @@ struct l2_fhdr {
#define BNX2_HC_PERIODIC_TICKS 0x0000683c
#define BNX2_HC_PERIODIC_TICKS_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_HC_INT_PERIODIC_TICKS (0xffffL<<16)
#define BNX2_HC_STAT_COLLECT_TICKS 0x00006840
#define BNX2_HC_STAT_COLLECT_TICKS_HC_STAT_COLL_TICKS (0xffL<<4)
@@ -2789,6 +4775,10 @@ struct l2_fhdr {
#define BNX2_HC_STATS_TICKS 0x00006844
#define BNX2_HC_STATS_TICKS_HC_STAT_TICKS (0xffffL<<8)
+#define BNX2_HC_STATS_INTERRUPT_STATUS 0x00006848
+#define BNX2_HC_STATS_INTERRUPT_STATUS_SB_STATUS (0x1ffL<<0)
+#define BNX2_HC_STATS_INTERRUPT_STATUS_INT_STATUS (0x1ffL<<16)
+
#define BNX2_HC_STAT_MEM_DATA 0x0000684c
#define BNX2_HC_STAT_GEN_SEL_0 0x00006850
#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0 (0x7fL<<0)
@@ -2917,24 +4907,108 @@ struct l2_fhdr {
#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1 (0x7fL<<8)
#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2 (0x7fL<<16)
#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3 (0x7fL<<24)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_XI (0xffL<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UMP_RX_FRAME_DROP_XI (52L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S0_XI (57L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S1_XI (58L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S2_XI (85L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S3_XI (86L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S4_XI (87L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S5_XI (88L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S6_XI (89L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S7_XI (90L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S8_XI (91L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S9_XI (92L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S10_XI (93L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MQ_IDB_OFLOW_XI (94L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_BLK_RD_CNT_XI (123L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_BLK_WR_CNT_XI (124L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_HITS_XI (125L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_MISSES_XI (126L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC1_XI (128L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC1_XI (129L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC1_XI (130L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC1_XI (131L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC1_XI (132L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC1_XI (133L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC2_XI (134L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC2_XI (135L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC2_XI (136L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC2_XI (137L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC2_XI (138L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC2_XI (139L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC3_XI (140L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC3_XI (141L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC3_XI (142L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC3_XI (143L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC3_XI (144L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC3_XI (145L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC4_XI (146L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC4_XI (147L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC4_XI (148L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC4_XI (149L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC4_XI (150L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC4_XI (151L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC5_XI (152L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC5_XI (153L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC5_XI (154L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC5_XI (155L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC5_XI (156L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC5_XI (157L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC6_XI (158L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC6_XI (159L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC6_XI (160L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC6_XI (161L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC6_XI (162L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC6_XI (163L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC7_XI (164L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC7_XI (165L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC7_XI (166L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC7_XI (167L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC7_XI (168L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC7_XI (169L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC8_XI (170L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC8_XI (171L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC8_XI (172L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC8_XI (173L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC8_XI (174L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC8_XI (175L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCS_CMD_CNT_XI (176L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCS_SLOT_CNT_XI (177L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI (178L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1_XI (0xffL<<8)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2_XI (0xffL<<16)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3_XI (0xffL<<24)
#define BNX2_HC_STAT_GEN_SEL_1 0x00006854
#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4 (0x7fL<<0)
#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5 (0x7fL<<8)
#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6 (0x7fL<<16)
#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7 (0x7fL<<24)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4_XI (0xffL<<0)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5_XI (0xffL<<8)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6_XI (0xffL<<16)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7_XI (0xffL<<24)
#define BNX2_HC_STAT_GEN_SEL_2 0x00006858
#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8 (0x7fL<<0)
#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9 (0x7fL<<8)
#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10 (0x7fL<<16)
#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11 (0x7fL<<24)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8_XI (0xffL<<0)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9_XI (0xffL<<8)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10_XI (0xffL<<16)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11_XI (0xffL<<24)
#define BNX2_HC_STAT_GEN_SEL_3 0x0000685c
#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12 (0x7fL<<0)
#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13 (0x7fL<<8)
#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14 (0x7fL<<16)
#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15 (0x7fL<<24)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12_XI (0xffL<<0)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13_XI (0xffL<<8)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14_XI (0xffL<<16)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15_XI (0xffL<<24)
#define BNX2_HC_STAT_GEN_STAT0 0x00006888
#define BNX2_HC_STAT_GEN_STAT1 0x0000688c
@@ -2968,6 +5042,7 @@ struct l2_fhdr {
#define BNX2_HC_STAT_GEN_STAT_AC13 0x000068fc
#define BNX2_HC_STAT_GEN_STAT_AC14 0x00006900
#define BNX2_HC_STAT_GEN_STAT_AC15 0x00006904
+#define BNX2_HC_STAT_GEN_STAT_AC 0x000068c8
#define BNX2_HC_VIS 0x00006908
#define BNX2_HC_VIS_STAT_BUILD_STATE (0xfL<<0)
#define BNX2_HC_VIS_STAT_BUILD_STATE_IDLE (0L<<0)
@@ -3038,6 +5113,349 @@ struct l2_fhdr {
#define BNX2_HC_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27)
#define BNX2_HC_DEBUG_VECT_PEEK_2_SEL (0xfL<<28)
+#define BNX2_HC_COALESCE_NOW 0x00006914
+#define BNX2_HC_COALESCE_NOW_COAL_NOW (0x1ffL<<1)
+#define BNX2_HC_COALESCE_NOW_COAL_NOW_WO_INT (0x1ffL<<11)
+#define BNX2_HC_COALESCE_NOW_COAL_ON_NXT_EVENT (0x1ffL<<21)
+
+#define BNX2_HC_MSIX_BIT_VECTOR 0x00006918
+#define BNX2_HC_MSIX_BIT_VECTOR_VAL (0x1ffL<<0)
+
+#define BNX2_HC_SB_CONFIG_1 0x00006a00
+#define BNX2_HC_SB_CONFIG_1_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_1_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_1_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_1_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_1_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_1_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_1_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_1_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_1 0x00006a04
+#define BNX2_HC_TX_QUICK_CONS_TRIP_1_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_1_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_1 0x00006a08
+#define BNX2_HC_COMP_PROD_TRIP_1_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_1_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_1 0x00006a0c
+#define BNX2_HC_RX_QUICK_CONS_TRIP_1_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_1_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_1 0x00006a10
+#define BNX2_HC_RX_TICKS_1_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_1_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_1 0x00006a14
+#define BNX2_HC_TX_TICKS_1_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_1_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_1 0x00006a18
+#define BNX2_HC_COM_TICKS_1_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_1_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_1 0x00006a1c
+#define BNX2_HC_CMD_TICKS_1_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_1_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_1 0x00006a20
+#define BNX2_HC_PERIODIC_TICKS_1_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_1_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_2 0x00006a24
+#define BNX2_HC_SB_CONFIG_2_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_2_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_2_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_2_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_2_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_2_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_2_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_2_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_2 0x00006a28
+#define BNX2_HC_TX_QUICK_CONS_TRIP_2_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_2_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_2 0x00006a2c
+#define BNX2_HC_COMP_PROD_TRIP_2_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_2_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_2 0x00006a30
+#define BNX2_HC_RX_QUICK_CONS_TRIP_2_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_2_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_2 0x00006a34
+#define BNX2_HC_RX_TICKS_2_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_2_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_2 0x00006a38
+#define BNX2_HC_TX_TICKS_2_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_2_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_2 0x00006a3c
+#define BNX2_HC_COM_TICKS_2_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_2_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_2 0x00006a40
+#define BNX2_HC_CMD_TICKS_2_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_2_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_2 0x00006a44
+#define BNX2_HC_PERIODIC_TICKS_2_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_2_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_3 0x00006a48
+#define BNX2_HC_SB_CONFIG_3_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_3_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_3_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_3_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_3_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_3_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_3_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_3_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_3 0x00006a4c
+#define BNX2_HC_TX_QUICK_CONS_TRIP_3_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_3_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_3 0x00006a50
+#define BNX2_HC_COMP_PROD_TRIP_3_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_3_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_3 0x00006a54
+#define BNX2_HC_RX_QUICK_CONS_TRIP_3_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_3_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_3 0x00006a58
+#define BNX2_HC_RX_TICKS_3_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_3_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_3 0x00006a5c
+#define BNX2_HC_TX_TICKS_3_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_3_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_3 0x00006a60
+#define BNX2_HC_COM_TICKS_3_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_3_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_3 0x00006a64
+#define BNX2_HC_CMD_TICKS_3_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_3_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_3 0x00006a68
+#define BNX2_HC_PERIODIC_TICKS_3_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_3_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_4 0x00006a6c
+#define BNX2_HC_SB_CONFIG_4_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_4_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_4_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_4_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_4_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_4_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_4_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_4_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_4 0x00006a70
+#define BNX2_HC_TX_QUICK_CONS_TRIP_4_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_4_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_4 0x00006a74
+#define BNX2_HC_COMP_PROD_TRIP_4_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_4_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_4 0x00006a78
+#define BNX2_HC_RX_QUICK_CONS_TRIP_4_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_4_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_4 0x00006a7c
+#define BNX2_HC_RX_TICKS_4_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_4_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_4 0x00006a80
+#define BNX2_HC_TX_TICKS_4_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_4_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_4 0x00006a84
+#define BNX2_HC_COM_TICKS_4_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_4_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_4 0x00006a88
+#define BNX2_HC_CMD_TICKS_4_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_4_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_4 0x00006a8c
+#define BNX2_HC_PERIODIC_TICKS_4_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_4_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_5 0x00006a90
+#define BNX2_HC_SB_CONFIG_5_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_5_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_5_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_5_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_5_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_5_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_5_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_5_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_5 0x00006a94
+#define BNX2_HC_TX_QUICK_CONS_TRIP_5_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_5_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_5 0x00006a98
+#define BNX2_HC_COMP_PROD_TRIP_5_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_5_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_5 0x00006a9c
+#define BNX2_HC_RX_QUICK_CONS_TRIP_5_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_5_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_5 0x00006aa0
+#define BNX2_HC_RX_TICKS_5_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_5_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_5 0x00006aa4
+#define BNX2_HC_TX_TICKS_5_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_5_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_5 0x00006aa8
+#define BNX2_HC_COM_TICKS_5_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_5_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_5 0x00006aac
+#define BNX2_HC_CMD_TICKS_5_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_5_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_5 0x00006ab0
+#define BNX2_HC_PERIODIC_TICKS_5_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_5_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_6 0x00006ab4
+#define BNX2_HC_SB_CONFIG_6_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_6_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_6_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_6_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_6_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_6_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_6_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_6_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_6 0x00006ab8
+#define BNX2_HC_TX_QUICK_CONS_TRIP_6_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_6_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_6 0x00006abc
+#define BNX2_HC_COMP_PROD_TRIP_6_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_6_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_6 0x00006ac0
+#define BNX2_HC_RX_QUICK_CONS_TRIP_6_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_6_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_6 0x00006ac4
+#define BNX2_HC_RX_TICKS_6_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_6_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_6 0x00006ac8
+#define BNX2_HC_TX_TICKS_6_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_6_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_6 0x00006acc
+#define BNX2_HC_COM_TICKS_6_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_6_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_6 0x00006ad0
+#define BNX2_HC_CMD_TICKS_6_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_6_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_6 0x00006ad4
+#define BNX2_HC_PERIODIC_TICKS_6_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_6_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_7 0x00006ad8
+#define BNX2_HC_SB_CONFIG_7_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_7_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_7_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_7_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_7_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_7_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_7_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_7_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_7 0x00006adc
+#define BNX2_HC_TX_QUICK_CONS_TRIP_7_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_7_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_7 0x00006ae0
+#define BNX2_HC_COMP_PROD_TRIP_7_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_7_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_7 0x00006ae4
+#define BNX2_HC_RX_QUICK_CONS_TRIP_7_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_7_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_7 0x00006ae8
+#define BNX2_HC_RX_TICKS_7_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_7_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_7 0x00006aec
+#define BNX2_HC_TX_TICKS_7_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_7_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_7 0x00006af0
+#define BNX2_HC_COM_TICKS_7_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_7_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_7 0x00006af4
+#define BNX2_HC_CMD_TICKS_7_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_7_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_7 0x00006af8
+#define BNX2_HC_PERIODIC_TICKS_7_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_7_HC_INT_PERIODIC_TICKS (0xffffL<<16)
+
+#define BNX2_HC_SB_CONFIG_8 0x00006afc
+#define BNX2_HC_SB_CONFIG_8_RX_TMR_MODE (1L<<1)
+#define BNX2_HC_SB_CONFIG_8_TX_TMR_MODE (1L<<2)
+#define BNX2_HC_SB_CONFIG_8_COM_TMR_MODE (1L<<3)
+#define BNX2_HC_SB_CONFIG_8_CMD_TMR_MODE (1L<<4)
+#define BNX2_HC_SB_CONFIG_8_PER_MODE (1L<<16)
+#define BNX2_HC_SB_CONFIG_8_ONE_SHOT (1L<<17)
+#define BNX2_HC_SB_CONFIG_8_USE_INT_PARAM (1L<<18)
+#define BNX2_HC_SB_CONFIG_8_PER_COLLECT_LIMIT (0xfL<<20)
+
+#define BNX2_HC_TX_QUICK_CONS_TRIP_8 0x00006b00
+#define BNX2_HC_TX_QUICK_CONS_TRIP_8_VALUE (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_8_INT (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP_8 0x00006b04
+#define BNX2_HC_COMP_PROD_TRIP_8_VALUE (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_8_INT (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP_8 0x00006b08
+#define BNX2_HC_RX_QUICK_CONS_TRIP_8_VALUE (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_8_INT (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS_8 0x00006b0c
+#define BNX2_HC_RX_TICKS_8_VALUE (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_8_INT (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS_8 0x00006b10
+#define BNX2_HC_TX_TICKS_8_VALUE (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_8_INT (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS_8 0x00006b14
+#define BNX2_HC_COM_TICKS_8_VALUE (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_8_INT (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS_8 0x00006b18
+#define BNX2_HC_CMD_TICKS_8_VALUE (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_8_INT (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS_8 0x00006b1c
+#define BNX2_HC_PERIODIC_TICKS_8_HC_PERIODIC_TICKS (0xffffL<<0)
+#define BNX2_HC_PERIODIC_TICKS_8_HC_INT_PERIODIC_TICKS (0xffffL<<16)
/*
@@ -3063,7 +5481,7 @@ struct l2_fhdr {
#define BNX2_TXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_TXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_TXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_TXP_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_TXP_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_TXP_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_TXP_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3111,7 +5529,7 @@ struct l2_fhdr {
#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_TXP_CPU_REG_FILE 0x00045200
-#define BNX2_TXP_FTQ_DATA 0x000453c0
+#define BNX2_TXP_TXPQ 0x000453c0
#define BNX2_TXP_FTQ_CMD 0x000453f8
#define BNX2_TXP_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_TXP_FTQ_CMD_WR_TOP (1L<<10)
@@ -3158,7 +5576,7 @@ struct l2_fhdr {
#define BNX2_TPAT_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_TPAT_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_TPAT_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_TPAT_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_TPAT_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_TPAT_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_TPAT_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3206,7 +5624,7 @@ struct l2_fhdr {
#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_TPAT_CPU_REG_FILE 0x00085200
-#define BNX2_TPAT_FTQ_DATA 0x000853c0
+#define BNX2_TPAT_TPATQ 0x000853c0
#define BNX2_TPAT_FTQ_CMD 0x000853f8
#define BNX2_TPAT_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_TPAT_FTQ_CMD_WR_TOP (1L<<10)
@@ -3253,7 +5671,7 @@ struct l2_fhdr {
#define BNX2_RXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_RXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_RXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_RXP_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_RXP_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_RXP_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_RXP_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3301,7 +5719,29 @@ struct l2_fhdr {
#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_RXP_CPU_REG_FILE 0x000c5200
-#define BNX2_RXP_CFTQ_DATA 0x000c5380
+#define BNX2_RXP_PFE_PFE_CTL 0x000c537c
+#define BNX2_RXP_PFE_PFE_CTL_INC_USAGE_CNT (1L<<0)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE (0xfL<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_0 (0L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_1 (1L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_2 (2L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_3 (3L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_4 (4L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_5 (5L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_6 (6L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_7 (7L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_8 (8L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_9 (9L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_10 (10L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_11 (11L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_12 (12L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_13 (13L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_14 (14L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_15 (15L<<4)
+#define BNX2_RXP_PFE_PFE_CTL_PFE_COUNT (0xfL<<12)
+#define BNX2_RXP_PFE_PFE_CTL_OFFSET (0x1ffL<<16)
+
+#define BNX2_RXP_RXPCQ 0x000c5380
#define BNX2_RXP_CFTQ_CMD 0x000c53b8
#define BNX2_RXP_CFTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_RXP_CFTQ_CMD_WR_TOP (1L<<10)
@@ -3322,7 +5762,7 @@ struct l2_fhdr {
#define BNX2_RXP_CFTQ_CTL_MAX_DEPTH (0x3ffL<<12)
#define BNX2_RXP_CFTQ_CTL_CUR_DEPTH (0x3ffL<<22)
-#define BNX2_RXP_FTQ_DATA 0x000c53c0
+#define BNX2_RXP_RXPQ 0x000c53c0
#define BNX2_RXP_FTQ_CMD 0x000c53f8
#define BNX2_RXP_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_RXP_FTQ_CMD_WR_TOP (1L<<10)
@@ -3350,6 +5790,10 @@ struct l2_fhdr {
* com_reg definition
* offset: 0x100000
*/
+#define BNX2_COM_CKSUM_ERROR_STATUS 0x00100000
+#define BNX2_COM_CKSUM_ERROR_STATUS_CALCULATED (0xffffL<<0)
+#define BNX2_COM_CKSUM_ERROR_STATUS_EXPECTED (0xffffL<<16)
+
#define BNX2_COM_CPU_MODE 0x00105000
#define BNX2_COM_CPU_MODE_LOCAL_RST (1L<<0)
#define BNX2_COM_CPU_MODE_STEP_ENA (1L<<1)
@@ -3369,7 +5813,7 @@ struct l2_fhdr {
#define BNX2_COM_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_COM_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_COM_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_COM_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_COM_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_COM_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_COM_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3417,7 +5861,29 @@ struct l2_fhdr {
#define BNX2_COM_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_COM_CPU_REG_FILE 0x00105200
-#define BNX2_COM_COMXQ_FTQ_DATA 0x00105340
+#define BNX2_COM_COMTQ_PFE_PFE_CTL 0x001052bc
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_INC_USAGE_CNT (1L<<0)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE (0xfL<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_0 (0L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_1 (1L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_2 (2L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_3 (3L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_4 (4L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_5 (5L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_6 (6L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_7 (7L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_8 (8L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_9 (9L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_10 (10L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_11 (11L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_12 (12L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_13 (13L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_14 (14L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_15 (15L<<4)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_COUNT (0xfL<<12)
+#define BNX2_COM_COMTQ_PFE_PFE_CTL_OFFSET (0x1ffL<<16)
+
+#define BNX2_COM_COMXQ 0x00105340
#define BNX2_COM_COMXQ_FTQ_CMD 0x00105378
#define BNX2_COM_COMXQ_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP (1L<<10)
@@ -3438,7 +5904,7 @@ struct l2_fhdr {
#define BNX2_COM_COMXQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12)
#define BNX2_COM_COMXQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22)
-#define BNX2_COM_COMTQ_FTQ_DATA 0x00105380
+#define BNX2_COM_COMTQ 0x00105380
#define BNX2_COM_COMTQ_FTQ_CMD 0x001053b8
#define BNX2_COM_COMTQ_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP (1L<<10)
@@ -3459,7 +5925,7 @@ struct l2_fhdr {
#define BNX2_COM_COMTQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12)
#define BNX2_COM_COMTQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22)
-#define BNX2_COM_COMQ_FTQ_DATA 0x001053c0
+#define BNX2_COM_COMQ 0x001053c0
#define BNX2_COM_COMQ_FTQ_CMD 0x001053f8
#define BNX2_COM_COMQ_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP (1L<<10)
@@ -3489,6 +5955,10 @@ struct l2_fhdr {
* cp_reg definition
* offset: 0x180000
*/
+#define BNX2_CP_CKSUM_ERROR_STATUS 0x00180000
+#define BNX2_CP_CKSUM_ERROR_STATUS_CALCULATED (0xffffL<<0)
+#define BNX2_CP_CKSUM_ERROR_STATUS_EXPECTED (0xffffL<<16)
+
#define BNX2_CP_CPU_MODE 0x00185000
#define BNX2_CP_CPU_MODE_LOCAL_RST (1L<<0)
#define BNX2_CP_CPU_MODE_STEP_ENA (1L<<1)
@@ -3508,7 +5978,7 @@ struct l2_fhdr {
#define BNX2_CP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_CP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_CP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_CP_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_CP_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_CP_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_CP_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3556,7 +6026,29 @@ struct l2_fhdr {
#define BNX2_CP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_CP_CPU_REG_FILE 0x00185200
-#define BNX2_CP_CPQ_FTQ_DATA 0x001853c0
+#define BNX2_CP_CPQ_PFE_PFE_CTL 0x001853bc
+#define BNX2_CP_CPQ_PFE_PFE_CTL_INC_USAGE_CNT (1L<<0)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE (0xfL<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_0 (0L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_1 (1L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_2 (2L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_3 (3L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_4 (4L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_5 (5L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_6 (6L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_7 (7L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_8 (8L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_9 (9L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_10 (10L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_11 (11L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_12 (12L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_13 (13L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_14 (14L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_15 (15L<<4)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_COUNT (0xfL<<12)
+#define BNX2_CP_CPQ_PFE_PFE_CTL_OFFSET (0x1ffL<<16)
+
+#define BNX2_CP_CPQ 0x001853c0
#define BNX2_CP_CPQ_FTQ_CMD 0x001853f8
#define BNX2_CP_CPQ_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP (1L<<10)
@@ -3584,6 +6076,59 @@ struct l2_fhdr {
* mcp_reg definition
* offset: 0x140000
*/
+#define BNX2_MCP_MCP_CONTROL 0x00140080
+#define BNX2_MCP_MCP_CONTROL_SMBUS_SEL (1L<<30)
+#define BNX2_MCP_MCP_CONTROL_MCP_ISOLATE (1L<<31)
+
+#define BNX2_MCP_MCP_ATTENTION_STATUS 0x00140084
+#define BNX2_MCP_MCP_ATTENTION_STATUS_DRV_DOORBELL (1L<<29)
+#define BNX2_MCP_MCP_ATTENTION_STATUS_WATCHDOG_TIMEOUT (1L<<30)
+#define BNX2_MCP_MCP_ATTENTION_STATUS_CPU_EVENT (1L<<31)
+
+#define BNX2_MCP_MCP_HEARTBEAT_CONTROL 0x00140088
+#define BNX2_MCP_MCP_HEARTBEAT_CONTROL_MCP_HEARTBEAT_ENABLE (1L<<31)
+
+#define BNX2_MCP_MCP_HEARTBEAT_STATUS 0x0014008c
+#define BNX2_MCP_MCP_HEARTBEAT_STATUS_MCP_HEARTBEAT_PERIOD (0x7ffL<<0)
+#define BNX2_MCP_MCP_HEARTBEAT_STATUS_VALID (1L<<31)
+
+#define BNX2_MCP_MCP_HEARTBEAT 0x00140090
+#define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_COUNT (0x3fffffffL<<0)
+#define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_INC (1L<<30)
+#define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_RESET (1L<<31)
+
+#define BNX2_MCP_WATCHDOG_RESET 0x00140094
+#define BNX2_MCP_WATCHDOG_RESET_WATCHDOG_RESET (1L<<31)
+
+#define BNX2_MCP_WATCHDOG_CONTROL 0x00140098
+#define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_TIMEOUT (0xfffffffL<<0)
+#define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_ATTN (1L<<29)
+#define BNX2_MCP_WATCHDOG_CONTROL_MCP_RST_ENABLE (1L<<30)
+#define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_ENABLE (1L<<31)
+
+#define BNX2_MCP_ACCESS_LOCK 0x0014009c
+#define BNX2_MCP_ACCESS_LOCK_LOCK (1L<<31)
+
+#define BNX2_MCP_TOE_ID 0x001400a0
+#define BNX2_MCP_TOE_ID_FUNCTION_ID (1L<<31)
+
+#define BNX2_MCP_MAILBOX_CFG 0x001400a4
+#define BNX2_MCP_MAILBOX_CFG_MAILBOX_OFFSET (0x3fffL<<0)
+#define BNX2_MCP_MAILBOX_CFG_MAILBOX_SIZE (0xfffL<<20)
+
+#define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC 0x001400a8
+#define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC_MAILBOX_OFFSET (0x3fffL<<0)
+#define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC_MAILBOX_SIZE (0xfffL<<20)
+
+#define BNX2_MCP_MCP_DOORBELL 0x001400ac
+#define BNX2_MCP_MCP_DOORBELL_MCP_DOORBELL (1L<<31)
+
+#define BNX2_MCP_DRIVER_DOORBELL 0x001400b0
+#define BNX2_MCP_DRIVER_DOORBELL_DRIVER_DOORBELL (1L<<31)
+
+#define BNX2_MCP_DRIVER_DOORBELL_OTHER_FUNC 0x001400b4
+#define BNX2_MCP_DRIVER_DOORBELL_OTHER_FUNC_DRIVER_DOORBELL (1L<<31)
+
#define BNX2_MCP_CPU_MODE 0x00145000
#define BNX2_MCP_CPU_MODE_LOCAL_RST (1L<<0)
#define BNX2_MCP_CPU_MODE_STEP_ENA (1L<<1)
@@ -3603,7 +6148,7 @@ struct l2_fhdr {
#define BNX2_MCP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3)
#define BNX2_MCP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4)
#define BNX2_MCP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5)
-#define BNX2_MCP_CPU_STATE_BAD_pc_HALTED (1L<<6)
+#define BNX2_MCP_CPU_STATE_BAD_PC_HALTED (1L<<6)
#define BNX2_MCP_CPU_STATE_ALIGN_HALTED (1L<<7)
#define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_MCP_CPU_STATE_SOFT_HALTED (1L<<10)
@@ -3651,7 +6196,7 @@ struct l2_fhdr {
#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2)
#define BNX2_MCP_CPU_REG_FILE 0x00145200
-#define BNX2_MCP_MCPQ_FTQ_DATA 0x001453c0
+#define BNX2_MCP_MCPQ 0x001453c0
#define BNX2_MCP_MCPQ_FTQ_CMD 0x001453f8
#define BNX2_MCP_MCPQ_FTQ_CMD_OFFSET (0x3ffL<<0)
#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP (1L<<10)
@@ -3696,6 +6241,8 @@ struct l2_fhdr {
/* 5708 Serdes PHY registers */
+#define BCM5708S_BMCR_FORCE_2500 0x20
+
#define BCM5708S_UP1 0xb
#define BCM5708S_UP1_2G5 0x1
@@ -3804,6 +6351,7 @@ struct l2_fhdr {
#define INVALID_CID_ADDR 0xffffffff
#define TX_CID 16
+#define TX_TSS_CID 32
#define RX_CID 0
#define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID)
@@ -3889,6 +6437,8 @@ struct bnx2 {
u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES)));
u16 tx_prod;
+ u32 tx_bidx_addr;
+ u32 tx_bseq_addr;
u16 tx_cons __attribute__((aligned(L1_CACHE_BYTES)));
u16 hw_tx_cons;
@@ -3945,6 +6495,7 @@ struct bnx2 {
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
#define CHIP_NUM_5706 0x57060000
#define CHIP_NUM_5708 0x57080000
+#define CHIP_NUM_5709 0x57090000
#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
@@ -4007,6 +6558,10 @@ struct bnx2 {
struct statistics_block *stats_blk;
dma_addr_t stats_blk_mapping;
+ int ctx_pages;
+ void *ctx_blk[4];
+ dma_addr_t ctx_blk_mapping[4];
+
u32 hc_cmd;
u32 rx_mode;
@@ -4038,6 +6593,7 @@ struct bnx2 {
u8 serdes_an_pending;
#define SERDES_AN_TIMEOUT (HZ / 3)
+#define SERDES_FORCED_TIMEOUT (HZ / 10)
u8 mac_addr[8];
@@ -4104,41 +6660,43 @@ struct cpu_reg {
};
struct fw_info {
- u32 ver_major;
- u32 ver_minor;
- u32 ver_fix;
+ const u32 ver_major;
+ const u32 ver_minor;
+ const u32 ver_fix;
- u32 start_addr;
+ const u32 start_addr;
/* Text section. */
- u32 text_addr;
- u32 text_len;
- u32 text_index;
+ const u32 text_addr;
+ const u32 text_len;
+ const u32 text_index;
u32 *text;
+ u8 *gz_text;
+ const u32 gz_text_len;
/* Data section. */
- u32 data_addr;
- u32 data_len;
- u32 data_index;
- u32 *data;
+ const u32 data_addr;
+ const u32 data_len;
+ const u32 data_index;
+ const u32 *data;
/* SBSS section. */
- u32 sbss_addr;
- u32 sbss_len;
- u32 sbss_index;
- u32 *sbss;
+ const u32 sbss_addr;
+ const u32 sbss_len;
+ const u32 sbss_index;
+ const u32 *sbss;
/* BSS section. */
- u32 bss_addr;
- u32 bss_len;
- u32 bss_index;
- u32 *bss;
+ const u32 bss_addr;
+ const u32 bss_len;
+ const u32 bss_index;
+ const u32 *bss;
/* Read-only section. */
- u32 rodata_addr;
- u32 rodata_len;
- u32 rodata_index;
- u32 *rodata;
+ const u32 rodata_addr;
+ const u32 rodata_len;
+ const u32 rodata_index;
+ const u32 *rodata;
};
#define RV2P_PROC1 0
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 2d753dca0d75..21d368ff424d 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -14,20 +14,6 @@
* accompanying it.
*/
-static const int bnx2_COM_b06FwReleaseMajor = 0x1;
-static const int bnx2_COM_b06FwReleaseMinor = 0x0;
-static const int bnx2_COM_b06FwReleaseFix = 0x0;
-static const u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
-static const u32 bnx2_COM_b06FwTextAddr = 0x08000000;
-static const int bnx2_COM_b06FwTextLen = 0x57bc;
-static const u32 bnx2_COM_b06FwDataAddr = 0x08005840;
-static const int bnx2_COM_b06FwDataLen = 0x0;
-static const u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
-static const int bnx2_COM_b06FwRodataLen = 0x58;
-static const u32 bnx2_COM_b06FwBssAddr = 0x08005860;
-static const int bnx2_COM_b06FwBssLen = 0x88;
-static const u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
-static const int bnx2_COM_b06FwSbssLen = 0x1c;
static u8 bnx2_COM_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0x09, 0x83, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5b, 0x7d, 0x6c,
@@ -673,389 +659,752 @@ static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = {
static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 };
static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
-static int bnx2_RXP_b06FwReleaseMajor = 0x1;
-static int bnx2_RXP_b06FwReleaseMinor = 0x0;
-static int bnx2_RXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_RXP_b06FwStartAddr = 0x08003184;
-static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
-static int bnx2_RXP_b06FwTextLen = 0x588c;
-static u32 bnx2_RXP_b06FwDataAddr = 0x080058e0;
-static int bnx2_RXP_b06FwDataLen = 0x0;
-static u32 bnx2_RXP_b06FwRodataAddr = 0x08005890;
-static int bnx2_RXP_b06FwRodataLen = 0x28;
-static u32 bnx2_RXP_b06FwBssAddr = 0x08005900;
-static int bnx2_RXP_b06FwBssLen = 0x13a4;
-static u32 bnx2_RXP_b06FwSbssAddr = 0x080058e0;
-static int bnx2_RXP_b06FwSbssLen = 0x1c;
+static struct fw_info bnx2_com_fw_06 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x080008b4,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x57bc,
+ .text_index = 0x0,
+ .gz_text = bnx2_COM_b06FwText,
+ .gz_text_len = sizeof(bnx2_COM_b06FwText),
+
+ .data_addr = 0x08005840,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_COM_b06FwData,
+
+ .sbss_addr = 0x08005840,
+ .sbss_len = 0x1c,
+ .sbss_index = 0x0,
+ .sbss = bnx2_COM_b06FwSbss,
+
+ .bss_addr = 0x08005860,
+ .bss_len = 0x88,
+ .bss_index = 0x0,
+ .bss = bnx2_COM_b06FwBss,
+
+ .rodata_addr = 0x080057c0,
+ .rodata_len = 0x58,
+ .rodata_index = 0x0,
+ .rodata = bnx2_COM_b06FwRodata,
+};
+
static u8 bnx2_RXP_b06FwText[] = {
- 0x1f, 0x8b, 0x08, 0x08, 0x07, 0x87, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
- 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xed, 0x5c, 0x5d, 0x6c,
- 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x71, 0x49, 0x91, 0xd4, 0x70, 0xb9,
- 0x62, 0x57, 0x12, 0x65, 0xed, 0x8a, 0x43, 0x71, 0x6d, 0x31, 0xce, 0x50,
- 0x58, 0xdb, 0x82, 0xb1, 0x48, 0xc7, 0xb3, 0xa4, 0xc8, 0x24, 0x02, 0x42,
- 0x1b, 0x42, 0xab, 0xa4, 0xa9, 0xc1, 0x90, 0x72, 0x91, 0x22, 0x2c, 0xa0,
- 0x1a, 0x79, 0xf0, 0x43, 0x10, 0x2f, 0x56, 0x3f, 0xa6, 0xd1, 0x8d, 0x96,
- 0xb6, 0x1c, 0x53, 0x08, 0x82, 0x82, 0xe5, 0x52, 0x52, 0x0b, 0x2c, 0xb4,
- 0x96, 0xed, 0x36, 0x7e, 0xa8, 0x23, 0x9a, 0x92, 0x8d, 0xa6, 0x68, 0x81,
- 0x22, 0xad, 0xd1, 0xf4, 0x4d, 0x95, 0x9a, 0x4a, 0x75, 0x5f, 0xd4, 0xa2,
- 0x48, 0xda, 0x46, 0xcd, 0xf4, 0xfb, 0xee, 0xcc, 0x88, 0xd4, 0x9a, 0xb2,
- 0x2c, 0x3b, 0x0d, 0x62, 0x74, 0x0e, 0x30, 0xd8, 0xb9, 0x7f, 0xe7, 0xef,
- 0x9e, 0x73, 0xee, 0x39, 0x77, 0x28, 0x7d, 0xa5, 0x43, 0xda, 0x25, 0x84,
- 0x4e, 0x3c, 0x99, 0xc3, 0xcf, 0x3c, 0xfd, 0xe0, 0xc3, 0x0f, 0xee, 0xc1,
- 0xeb, 0xb0, 0xa1, 0x6d, 0xd0, 0xa3, 0xfe, 0x18, 0x62, 0x88, 0x21, 0x86,
- 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62,
- 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21,
- 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18,
- 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0x18, 0x62, 0x88,
- 0x21, 0x86, 0x18, 0x62, 0x88, 0x21, 0x86, 0xff, 0xef, 0x60, 0x88, 0x58,
- 0xfc, 0xed, 0x0c, 0x1f, 0x49, 0xe8, 0x85, 0xcb, 0x07, 0x3d, 0x5b, 0x12,
- 0x46, 0x61, 0x69, 0x66, 0xda, 0x16, 0x71, 0xeb, 0xbb, 0x33, 0x45, 0xf9,
- 0x1f, 0xbf, 0x94, 0x32, 0x85, 0xfd, 0xdb, 0x0b, 0x37, 0x9f, 0x7d, 0xf3,
- 0x91, 0xec, 0x8d, 0x05, 0x43, 0x12, 0x56, 0xe1, 0xe8, 0xb0, 0xb5, 0x4b,
- 0x12, 0x7d, 0x58, 0xf3, 0xdd, 0xc1, 0xcf, 0x59, 0xd2, 0x15, 0xe1, 0xba,
- 0xee, 0xbf, 0x39, 0x68, 0xc9, 0x2b, 0x8d, 0x94, 0x5c, 0x68, 0x6c, 0xdf,
- 0x24, 0x5d, 0xd9, 0x52, 0x09, 0xfd, 0x6e, 0x8a, 0xe3, 0x96, 0x94, 0xab,
- 0x2d, 0xe2, 0x2a, 0xba, 0x7d, 0x5a, 0x71, 0xfe, 0x3e, 0xcd, 0x9b, 0x7f,
- 0x9e, 0xff, 0x1e, 0x24, 0xa5, 0xcb, 0x7d, 0x68, 0xf7, 0xa1, 0xcd, 0xf7,
- 0x81, 0xf4, 0x94, 0x98, 0x72, 0xa4, 0x91, 0x90, 0xa3, 0xd5, 0x8c, 0xe8,
- 0x05, 0x71, 0xbd, 0xbc, 0x9d, 0x2e, 0xa3, 0x6f, 0xea, 0x00, 0xdb, 0x29,
- 0xe0, 0xf9, 0x0e, 0xd7, 0x59, 0x5e, 0x5e, 0x4a, 0xb7, 0xc6, 0x14, 0x0d,
- 0x8e, 0xb1, 0x0f, 0xbf, 0x58, 0x5f, 0xae, 0x76, 0x00, 0x6f, 0xd6, 0x71,
- 0x41, 0xdc, 0x73, 0x2c, 0xd0, 0xf6, 0xfd, 0xdf, 0x75, 0x32, 0xb2, 0xe2,
- 0x74, 0x81, 0xa7, 0x16, 0x69, 0xb5, 0xc5, 0xd2, 0x0b, 0xb6, 0xb5, 0x22,
- 0x6d, 0x1c, 0xeb, 0x34, 0x0a, 0xbe, 0x3f, 0x9d, 0x97, 0xae, 0xa0, 0x6f,
- 0xb7, 0xe2, 0x63, 0x72, 0x42, 0xc3, 0xbc, 0x57, 0x49, 0x0f, 0x3a, 0xe2,
- 0x3b, 0x7f, 0xf3, 0x52, 0xac, 0x6c, 0x97, 0xc9, 0x54, 0xf6, 0xa0, 0x1b,
- 0xd0, 0x74, 0x3d, 0x67, 0x2b, 0x70, 0x6a, 0xe0, 0x4f, 0xdb, 0x81, 0xf5,
- 0xee, 0x0a, 0x68, 0x1a, 0x85, 0xcd, 0x62, 0x6c, 0x66, 0x9f, 0xe8, 0x3b,
- 0x87, 0x93, 0xe1, 0x78, 0x97, 0x36, 0x32, 0x6f, 0x88, 0x6e, 0xff, 0x81,
- 0xe6, 0xd5, 0x7a, 0xe5, 0xd8, 0xbc, 0x8e, 0x77, 0x5d, 0xae, 0xe6, 0x4b,
- 0x9a, 0xdb, 0xa8, 0x68, 0xde, 0xd9, 0x59, 0xad, 0x78, 0xd6, 0x94, 0xa3,
- 0xb6, 0x7f, 0xe1, 0xb4, 0x73, 0x42, 0x1b, 0x39, 0x7b, 0x46, 0x1b, 0x3d,
- 0xfb, 0x86, 0x36, 0xde, 0xd8, 0xb2, 0x49, 0xda, 0xb3, 0xd0, 0x1e, 0x71,
- 0x90, 0xbf, 0x4f, 0x87, 0xba, 0xec, 0xa2, 0xde, 0x4a, 0xe4, 0x7d, 0x9f,
- 0xf3, 0x86, 0xe6, 0x55, 0x6d, 0x8b, 0xfb, 0xe6, 0xa6, 0x22, 0x1a, 0xed,
- 0x72, 0x74, 0xde, 0x94, 0x63, 0xd5, 0x94, 0x3c, 0x57, 0x2d, 0x29, 0x5a,
- 0x86, 0x5d, 0xd2, 0xbc, 0x06, 0xc7, 0x2b, 0xa0, 0x75, 0x42, 0xdb, 0x07,
- 0x9a, 0xde, 0x59, 0x29, 0x5d, 0x71, 0xe6, 0x40, 0xaf, 0x03, 0x78, 0xff,
- 0x58, 0x1b, 0x6d, 0xf4, 0x6a, 0xde, 0xc9, 0x9b, 0xe2, 0x39, 0x59, 0xeb,
- 0x4b, 0x62, 0xba, 0xb0, 0x01, 0xc8, 0x0c, 0xfd, 0x38, 0xd0, 0x49, 0xca,
- 0xf7, 0xf5, 0x82, 0xff, 0x2c, 0x74, 0x6f, 0x5d, 0xa1, 0xfc, 0x8d, 0x5e,
- 0x29, 0xcf, 0x53, 0xd7, 0xa6, 0x36, 0x52, 0xf5, 0x2f, 0x78, 0x8e, 0xf4,
- 0x19, 0xe2, 0xfb, 0x47, 0x9d, 0x81, 0xf4, 0x21, 0x39, 0x03, 0xdc, 0x75,
- 0xad, 0xd8, 0xa0, 0xae, 0xc1, 0xdf, 0x2d, 0x39, 0x02, 0xbd, 0x15, 0x9d,
- 0x5e, 0x99, 0xb4, 0xb2, 0x2e, 0xf6, 0x68, 0x53, 0x20, 0x57, 0x32, 0xb4,
- 0x17, 0xd2, 0xe7, 0xde, 0x67, 0xd3, 0x9e, 0xa1, 0xcb, 0x53, 0x2f, 0x3d,
- 0xdf, 0xb3, 0x38, 0xb4, 0x91, 0x32, 0x43, 0xff, 0xf2, 0x45, 0xcf, 0xf6,
- 0xb6, 0xb4, 0x48, 0x29, 0x6d, 0x48, 0x16, 0xfb, 0xb4, 0x43, 0x4e, 0x3b,
- 0x22, 0x87, 0x2a, 0xd0, 0x8d, 0x6d, 0x5a, 0x8b, 0x62, 0x67, 0xca, 0x32,
- 0x50, 0x32, 0x75, 0x74, 0x26, 0x49, 0x97, 0x3a, 0xd2, 0xe5, 0x7a, 0x9e,
- 0x7a, 0xa2, 0x3d, 0x7f, 0x28, 0x5d, 0x69, 0xab, 0xba, 0x5a, 0xd5, 0xd3,
- 0xf8, 0x2f, 0x5d, 0x4f, 0xd4, 0xc9, 0x72, 0x28, 0xb7, 0x03, 0xdc, 0x8f,
- 0x40, 0x5f, 0xe2, 0xea, 0xc3, 0x0f, 0xb1, 0x6f, 0x93, 0x51, 0xb0, 0xd3,
- 0x17, 0x61, 0x14, 0x7a, 0x61, 0x37, 0x64, 0x19, 0xa6, 0xee, 0xe0, 0xc3,
- 0x1f, 0x49, 0x5e, 0xf9, 0xd5, 0x90, 0x97, 0xfc, 0xdb, 0x32, 0x55, 0x49,
- 0x80, 0x06, 0x65, 0xd4, 0xe5, 0xbd, 0x7c, 0x64, 0x1b, 0x7b, 0x20, 0x5f,
- 0x5e, 0xa6, 0xbe, 0x45, 0x7f, 0xa2, 0xfd, 0xf3, 0x9d, 0xb2, 0xfe, 0xcc,
- 0xbf, 0xee, 0x7c, 0x92, 0xf6, 0x96, 0x7c, 0x27, 0xe4, 0x78, 0x35, 0xc9,
- 0x3d, 0xd4, 0x56, 0x54, 0x6c, 0x8a, 0x64, 0x14, 0xdd, 0x28, 0x74, 0x48,
- 0x51, 0xed, 0xf7, 0x5e, 0xd0, 0x43, 0x2c, 0xa8, 0xf2, 0xbd, 0xa0, 0x64,
- 0x9b, 0xb6, 0xed, 0xcc, 0x11, 0xc9, 0xc2, 0xbe, 0x45, 0x8e, 0xcc, 0x99,
- 0x32, 0x6d, 0xff, 0x63, 0xa7, 0xb4, 0x2f, 0xdf, 0x6f, 0xa8, 0xb8, 0xae,
- 0xf7, 0x6e, 0x90, 0x4d, 0xe0, 0x77, 0xf9, 0x7e, 0x5d, 0xe4, 0xa6, 0x59,
- 0xc8, 0x5a, 0x23, 0x08, 0xf6, 0x46, 0x81, 0xb1, 0x4c, 0x43, 0x2c, 0x93,
- 0x44, 0x8b, 0x4d, 0x7d, 0xf9, 0xfe, 0xf8, 0xf0, 0xdd, 0xf5, 0x75, 0x64,
- 0x9e, 0xb4, 0xa9, 0x2f, 0xc6, 0xa8, 0x12, 0xf4, 0xc1, 0xf8, 0x74, 0xbb,
- 0xae, 0x8a, 0xa1, 0xae, 0x46, 0xfe, 0xef, 0xed, 0xc2, 0xf5, 0xaa, 0xa2,
- 0x79, 0xce, 0xbb, 0xa1, 0x2f, 0xd8, 0x32, 0x02, 0x7f, 0x37, 0xec, 0x4f,
- 0xcb, 0x91, 0x54, 0x76, 0xc2, 0x95, 0xc0, 0xe6, 0xaf, 0xad, 0xb1, 0xf9,
- 0xd1, 0xbb, 0xc8, 0x75, 0x3c, 0x94, 0xcb, 0x0d, 0xe5, 0x1a, 0x85, 0x5c,
- 0x63, 0x90, 0x6b, 0xe5, 0x23, 0xc8, 0xb5, 0xf2, 0x91, 0xe5, 0xd2, 0xa4,
- 0xec, 0x3c, 0x08, 0x5a, 0xa6, 0xfc, 0xab, 0x13, 0xd8, 0xf2, 0xbf, 0x38,
- 0x9f, 0x14, 0x19, 0x7c, 0x7f, 0x70, 0xd8, 0x16, 0xef, 0x5b, 0xe0, 0xd5,
- 0x71, 0x40, 0x8b, 0xef, 0xef, 0x97, 0xe1, 0x6e, 0xfe, 0x38, 0x8b, 0x7d,
- 0x5d, 0xcf, 0x1f, 0x29, 0x87, 0x3e, 0x7c, 0xef, 0xfe, 0xa8, 0x6b, 0x1f,
- 0x55, 0x0e, 0xc6, 0x9c, 0x4f, 0x35, 0x9d, 0xab, 0x1f, 0x56, 0x86, 0xf5,
- 0x63, 0xca, 0x2f, 0x4f, 0x86, 0xc7, 0x64, 0x72, 0x33, 0xed, 0xa9, 0xa4,
- 0x8d, 0x0c, 0x92, 0xef, 0xb5, 0xfc, 0x4a, 0x26, 0xe0, 0x0d, 0x39, 0xd1,
- 0xd2, 0x46, 0x39, 0xb2, 0x60, 0x49, 0x69, 0xe9, 0x4e, 0x71, 0x57, 0x03,
- 0x6f, 0xb4, 0x47, 0xf6, 0x7d, 0xd2, 0x7c, 0x2a, 0xc8, 0x2b, 0x2e, 0x54,
- 0x91, 0x83, 0x56, 0x13, 0x72, 0xd9, 0x48, 0xcb, 0x9b, 0x83, 0x87, 0xe5,
- 0xf3, 0xd5, 0x24, 0xe8, 0x31, 0x9f, 0x2c, 0xe7, 0x10, 0x17, 0xb5, 0xb2,
- 0x63, 0x08, 0x79, 0xaf, 0xd9, 0x9c, 0x13, 0xc4, 0x96, 0x72, 0x10, 0x83,
- 0x5d, 0x6f, 0x50, 0xe5, 0x14, 0x90, 0x4f, 0x64, 0x0c, 0xb1, 0xb7, 0x66,
- 0xb3, 0xcd, 0xfe, 0xa0, 0xef, 0xb3, 0x95, 0x5e, 0xad, 0xc8, 0xbc, 0x64,
- 0xf0, 0xa6, 0x4c, 0x3b, 0x41, 0xdf, 0xe7, 0x2a, 0xa3, 0x9b, 0x98, 0x1f,
- 0x1a, 0x05, 0xc9, 0x94, 0x9d, 0xf7, 0x7c, 0xd7, 0xba, 0x7d, 0xcd, 0xfa,
- 0x78, 0xb2, 0x13, 0x81, 0xce, 0x45, 0xfb, 0xaa, 0xad, 0xf7, 0xb6, 0x4a,
- 0x09, 0x27, 0x5d, 0xd6, 0x1a, 0x47, 0xe7, 0xbe, 0x4a, 0x79, 0x5b, 0xab,
- 0xdc, 0x34, 0x80, 0x3f, 0x6d, 0x68, 0x62, 0x1e, 0xaa, 0x94, 0xbb, 0xd9,
- 0xa6, 0xbe, 0x74, 0x4d, 0x12, 0xa3, 0x15, 0x5f, 0xae, 0x3a, 0x41, 0xee,
- 0x63, 0x68, 0x7a, 0x6f, 0x5b, 0xb8, 0x56, 0xd7, 0x76, 0x39, 0x97, 0x44,
- 0x3a, 0x0e, 0x55, 0xc4, 0x2a, 0x56, 0x76, 0x39, 0x6f, 0x4b, 0xb9, 0xa7,
- 0x6d, 0x75, 0x5d, 0x8a, 0xeb, 0x76, 0x0e, 0xaf, 0x9d, 0xbb, 0xcb, 0xb9,
- 0x28, 0xe5, 0x2d, 0x6d, 0xab, 0xb4, 0xd2, 0x58, 0xdb, 0x17, 0xac, 0xe5,
- 0xf8, 0x66, 0x71, 0xbb, 0x39, 0x47, 0xef, 0x6d, 0xbf, 0x45, 0x43, 0x32,
- 0xc5, 0x4a, 0xb9, 0xa7, 0x7d, 0x15, 0xaf, 0x4d, 0xbc, 0xde, 0x1a, 0xbc,
- 0xc4, 0xd9, 0xbe, 0x8a, 0x33, 0x07, 0x9c, 0x43, 0xab, 0x38, 0x39, 0x7e,
- 0x58, 0x8a, 0x38, 0xd3, 0x5a, 0x0a, 0x32, 0xbc, 0x54, 0xc9, 0x48, 0x79,
- 0x28, 0x01, 0xdd, 0xf7, 0x1f, 0xfc, 0x9a, 0xaa, 0x43, 0xcc, 0x61, 0x0f,
- 0xba, 0x32, 0x55, 0x5e, 0x87, 0xd8, 0x08, 0xdb, 0xf8, 0x5a, 0x5d, 0x86,
- 0x17, 0xeb, 0xa6, 0x1c, 0x6f, 0x70, 0xbf, 0x98, 0xe3, 0x05, 0x75, 0xc6,
- 0x85, 0x46, 0x4e, 0xdb, 0x87, 0xbd, 0x66, 0x9d, 0xb0, 0xaf, 0x61, 0x6a,
- 0xa3, 0x3c, 0x1f, 0x80, 0x97, 0x76, 0x7e, 0xac, 0x41, 0xdb, 0x79, 0x03,
- 0xb6, 0x41, 0xce, 0xa3, 0x9c, 0xbd, 0x95, 0xb9, 0x53, 0x66, 0xd1, 0x51,
- 0x75, 0x88, 0x56, 0xcb, 0x77, 0x20, 0x07, 0x4d, 0xa0, 0xd6, 0x80, 0xcd,
- 0xdb, 0x78, 0x6f, 0x70, 0xde, 0x32, 0xe6, 0x6d, 0xe0, 0x3c, 0xec, 0xcd,
- 0x25, 0xe5, 0x0f, 0xa6, 0xcd, 0xf1, 0x77, 0xb1, 0xc7, 0x68, 0xd7, 0x59,
- 0x57, 0x58, 0x02, 0x5f, 0xc1, 0x3e, 0xa2, 0x6e, 0x48, 0xed, 0x60, 0x7e,
- 0x8f, 0xb9, 0x19, 0xcc, 0xcd, 0x66, 0x18, 0xcf, 0x3d, 0xfb, 0x99, 0x0e,
- 0xe9, 0x42, 0xbb, 0xce, 0x35, 0xd9, 0x0c, 0x72, 0x5b, 0xdf, 0xcb, 0xb7,
- 0xc9, 0x4a, 0xca, 0xbf, 0x60, 0xd8, 0xd1, 0xdc, 0x08, 0x6f, 0xf3, 0x5c,
- 0xe6, 0xc5, 0xc4, 0xbd, 0x21, 0xcc, 0x83, 0xc7, 0xc5, 0x6d, 0xfc, 0x49,
- 0xb7, 0x74, 0xb9, 0xf8, 0x8d, 0xe6, 0x4c, 0x6f, 0x0e, 0x6a, 0x2e, 0xbe,
- 0xb7, 0x50, 0x3e, 0x17, 0xe7, 0xa1, 0x56, 0xac, 0x66, 0x26, 0x59, 0x1f,
- 0x15, 0xeb, 0x6c, 0xef, 0x85, 0x3f, 0x04, 0x75, 0xd7, 0x85, 0x5b, 0xbe,
- 0x70, 0x19, 0x7a, 0x4b, 0x43, 0x6f, 0x29, 0x39, 0xdf, 0x60, 0x9d, 0xe6,
- 0x42, 0x5f, 0x19, 0xf1, 0x1a, 0xe3, 0x58, 0x2b, 0x87, 0x81, 0x03, 0x3a,
- 0x17, 0x47, 0x2f, 0x64, 0x65, 0xca, 0xda, 0x1d, 0xf1, 0x00, 0x5c, 0x88,
- 0x1f, 0x85, 0x36, 0xf4, 0xf1, 0x1d, 0x9a, 0x53, 0xff, 0x86, 0x7f, 0x94,
- 0xed, 0x09, 0xbd, 0x30, 0xd6, 0xd4, 0xbf, 0x6e, 0xfc, 0xa1, 0x1c, 0x68,
- 0x33, 0x06, 0x31, 0xfe, 0xe8, 0xa8, 0xf3, 0x18, 0x8b, 0x48, 0xd7, 0x92,
- 0x23, 0x4b, 0x23, 0xdc, 0x37, 0x8b, 0xf1, 0xa7, 0x5c, 0xe7, 0x9e, 0x29,
- 0x5c, 0xc0, 0x19, 0xad, 0xf1, 0xfd, 0x11, 0x87, 0x6b, 0x7c, 0x99, 0x70,
- 0x3a, 0xc4, 0x48, 0x96, 0xb4, 0xc7, 0x07, 0x11, 0x7b, 0x1e, 0xe0, 0x3e,
- 0x32, 0x06, 0x6d, 0x17, 0xb0, 0xea, 0xb4, 0x3c, 0x3c, 0xc8, 0x75, 0xa0,
- 0xdd, 0x2a, 0x7a, 0x92, 0x34, 0xf3, 0x21, 0x4f, 0x43, 0xdd, 0x81, 0xbe,
- 0x06, 0xac, 0x40, 0x7f, 0x9f, 0xe9, 0x5e, 0xd5, 0x1f, 0xd7, 0x35, 0xf3,
- 0xcb, 0x18, 0x96, 0x90, 0x81, 0x33, 0x1b, 0x65, 0xe7, 0xa2, 0x25, 0xf6,
- 0x99, 0x55, 0xfe, 0x76, 0x9e, 0x5b, 0xcb, 0x5f, 0xf4, 0x7f, 0x15, 0x5c,
- 0xd0, 0xc5, 0x8e, 0xfa, 0x1e, 0x4b, 0x05, 0xb8, 0xa3, 0xf6, 0x7b, 0xe1,
- 0x5e, 0xf1, 0xfd, 0x99, 0x70, 0x4f, 0xb0, 0x07, 0x88, 0x95, 0xe7, 0x6f,
- 0xc5, 0xa9, 0x0c, 0xf6, 0x06, 0xb6, 0xa7, 0xe2, 0x11, 0xe3, 0x18, 0xed,
- 0xbb, 0x63, 0xd2, 0x2c, 0xb0, 0x8e, 0xe6, 0x3e, 0xc9, 0x44, 0xb9, 0x22,
- 0xa5, 0xad, 0x85, 0x67, 0x7d, 0xd8, 0xcf, 0xa4, 0xa5, 0x6c, 0xaf, 0x63,
- 0xaf, 0x97, 0x37, 0xa0, 0x1b, 0x8c, 0xc1, 0x26, 0xf5, 0x42, 0x42, 0x8a,
- 0x8d, 0x44, 0xc2, 0x3c, 0x31, 0xf0, 0x23, 0xcf, 0x48, 0x24, 0xf4, 0x13,
- 0x81, 0x9d, 0x4d, 0xd6, 0x6f, 0x20, 0x56, 0x6a, 0x72, 0x74, 0xe8, 0x86,
- 0xcf, 0x1a, 0xd8, 0xdb, 0x0b, 0x9b, 0x1b, 0x82, 0xcf, 0x80, 0x8f, 0x72,
- 0xa3, 0xa3, 0x37, 0xe0, 0xed, 0x2b, 0x11, 0x8f, 0xa6, 0x8e, 0xdc, 0xd3,
- 0xcb, 0xfb, 0xbe, 0x51, 0xd8, 0x90, 0x98, 0xce, 0x8f, 0x6f, 0xd1, 0xcf,
- 0xed, 0xdf, 0x62, 0x9c, 0x2b, 0x6d, 0x01, 0x3e, 0xdd, 0xcb, 0xe3, 0xf7,
- 0x9c, 0xc8, 0x44, 0x15, 0x3a, 0xdf, 0x03, 0x3d, 0x59, 0xf0, 0xc5, 0x3d,
- 0xa6, 0xca, 0xd1, 0xf5, 0x3d, 0x2f, 0x6e, 0x0a, 0x70, 0xf0, 0xfd, 0x27,
- 0x7e, 0x70, 0x86, 0x5e, 0x0e, 0xfb, 0x7e, 0x3f, 0xdc, 0x87, 0x5f, 0x45,
- 0xb9, 0x78, 0x5e, 0x44, 0xb2, 0xad, 0x3d, 0x37, 0xb2, 0xe3, 0x25, 0x9c,
- 0x33, 0xa7, 0x1d, 0xdf, 0x7f, 0x07, 0xcf, 0x35, 0xa7, 0xd9, 0x46, 0xde,
- 0x7f, 0xf6, 0x31, 0x07, 0xf8, 0x2c, 0xce, 0xbd, 0xd1, 0xa6, 0xb3, 0xff,
- 0x5e, 0xcf, 0xbd, 0x7b, 0x3f, 0xfb, 0xc9, 0xf3, 0x1d, 0x7d, 0xef, 0x03,
- 0xce, 0xfe, 0x0f, 0x5c, 0x77, 0x0f, 0x3e, 0x1b, 0xd8, 0x6d, 0xb1, 0xd1,
- 0x1c, 0x5f, 0xee, 0xd5, 0x7f, 0x7f, 0xad, 0xfb, 0x76, 0xff, 0xb5, 0xbb,
- 0x6f, 0xf7, 0xdf, 0xcd, 0xdd, 0xbf, 0x18, 0xff, 0xcd, 0x01, 0x0f, 0x7d,
- 0x70, 0xad, 0xff, 0xae, 0xe7, 0x93, 0xd4, 0xf7, 0xf3, 0x3d, 0xe5, 0xa1,
- 0xce, 0x30, 0x1f, 0x52, 0xe7, 0xf5, 0x17, 0xa7, 0x6d, 0xef, 0x7e, 0x53,
- 0x4a, 0xb9, 0x16, 0xc9, 0xe6, 0x6a, 0xb2, 0x43, 0x8e, 0x3b, 0x22, 0x4b,
- 0xaa, 0x16, 0x31, 0x51, 0x8b, 0x0f, 0xa0, 0x3e, 0x0b, 0xf4, 0xba, 0xa4,
- 0xf4, 0xf2, 0x02, 0x78, 0x89, 0xf0, 0x74, 0xdd, 0x05, 0x0f, 0x71, 0x10,
- 0x17, 0xf1, 0x0c, 0xe2, 0x7c, 0xb7, 0xd7, 0xc1, 0x85, 0x73, 0xea, 0x25,
- 0xd4, 0x64, 0xb6, 0xde, 0xa3, 0x07, 0x67, 0xb2, 0x5b, 0x96, 0xdd, 0xe9,
- 0xeb, 0xf2, 0x05, 0x9e, 0x59, 0x0a, 0xae, 0xce, 0x21, 0x56, 0x0f, 0x8d,
- 0x85, 0x75, 0xd2, 0xdc, 0x41, 0xcf, 0x8e, 0xee, 0x49, 0x78, 0x47, 0x92,
- 0x90, 0x92, 0x9a, 0xb5, 0x04, 0x1d, 0x68, 0x72, 0x0d, 0x67, 0xd0, 0xd5,
- 0xb9, 0x76, 0xe0, 0x45, 0xee, 0x77, 0x20, 0xbb, 0x57, 0xb4, 0x7e, 0xab,
- 0x55, 0x6b, 0x87, 0x2f, 0x65, 0xc4, 0x55, 0x6d, 0x9e, 0xd3, 0xa7, 0x66,
- 0x16, 0x2b, 0xc8, 0x03, 0x6d, 0x9c, 0xaf, 0x79, 0xbc, 0xd7, 0x49, 0x43,
- 0x93, 0x2b, 0x73, 0xba, 0xfc, 0xd3, 0x9c, 0x21, 0xff, 0x8c, 0x3a, 0xf4,
- 0x9a, 0x7d, 0x6a, 0xe6, 0xb4, 0x2d, 0xf7, 0x81, 0xd5, 0xf0, 0x0e, 0x4f,
- 0x76, 0x9a, 0x42, 0x5b, 0x1d, 0x48, 0xff, 0x8e, 0x20, 0xff, 0xc1, 0x9a,
- 0x2b, 0x73, 0xa4, 0xb5, 0x76, 0x8d, 0xf4, 0x22, 0x1f, 0x83, 0x5d, 0x0f,
- 0x30, 0x27, 0xe2, 0x7c, 0xd4, 0xab, 0x03, 0xd6, 0x3e, 0xc5, 0x5b, 0x42,
- 0x16, 0xeb, 0x9c, 0x6f, 0x82, 0xb7, 0x2e, 0x9c, 0x31, 0x59, 0x6b, 0x52,
- 0xfe, 0xb0, 0x5b, 0xe5, 0xaa, 0x1a, 0xfb, 0x0d, 0xb5, 0xc7, 0xef, 0xef,
- 0xe7, 0xde, 0x1b, 0x32, 0x95, 0x62, 0x9b, 0x63, 0x59, 0xd4, 0x9c, 0xc4,
- 0x97, 0xdd, 0xeb, 0x0a, 0x79, 0x0e, 0xde, 0xaf, 0x08, 0x65, 0xdb, 0x6d,
- 0x5d, 0x97, 0xd7, 0x7d, 0xf7, 0x00, 0xe5, 0x89, 0x72, 0x8b, 0x39, 0x9f,
- 0xb1, 0xd8, 0x28, 0xcc, 0xc0, 0x8e, 0xbf, 0x2a, 0xdf, 0x6f, 0x1c, 0x92,
- 0xef, 0x35, 0x26, 0xe5, 0xcf, 0x1a, 0x5f, 0x96, 0x3f, 0x6d, 0x1c, 0x94,
- 0xd7, 0x1b, 0x07, 0xe4, 0xb5, 0xc6, 0x84, 0xbc, 0xda, 0xd8, 0x0f, 0x1b,
- 0x1f, 0x87, 0x8d, 0x9f, 0x9a, 0x99, 0xac, 0xf7, 0xcb, 0xd4, 0x49, 0xc4,
- 0x20, 0xe7, 0x1b, 0xba, 0xba, 0xe3, 0xb3, 0xe9, 0xe7, 0x2d, 0x32, 0xad,
- 0xee, 0xaf, 0x34, 0xe4, 0x89, 0x2d, 0xbc, 0x2b, 0x7c, 0xc5, 0x33, 0x2e,
- 0x87, 0xf1, 0xe8, 0xe1, 0x94, 0xb4, 0x03, 0xbf, 0xca, 0x4b, 0x4d, 0x9e,
- 0xdb, 0x62, 0x86, 0xf7, 0x9c, 0x87, 0x24, 0xc9, 0xfb, 0xb0, 0x9c, 0x67,
- 0xa0, 0xde, 0x5e, 0xd7, 0x27, 0x73, 0xb4, 0x65, 0xe8, 0xc6, 0x95, 0x43,
- 0xb0, 0x53, 0xc3, 0x7e, 0xcb, 0xa5, 0x1e, 0x16, 0x97, 0x28, 0xf7, 0x46,
- 0x59, 0x5c, 0xa0, 0x6f, 0xff, 0x1b, 0x64, 0x6c, 0x97, 0xda, 0x82, 0x89,
- 0xb9, 0x6e, 0x98, 0xab, 0x6c, 0xa7, 0x3d, 0x00, 0x1f, 0xf1, 0x7e, 0x10,
- 0x4e, 0xab, 0x09, 0x27, 0xf1, 0x24, 0x54, 0x0c, 0x08, 0x70, 0x5b, 0x52,
- 0x5b, 0x4a, 0xca, 0xc2, 0x42, 0x0f, 0x9e, 0x94, 0x2c, 0xd4, 0x6d, 0x3c,
- 0x39, 0x3c, 0x43, 0x78, 0xd2, 0xb0, 0x53, 0xca, 0xc8, 0xd8, 0x12, 0xc9,
- 0x88, 0x78, 0x5c, 0xed, 0x0d, 0x6b, 0x2a, 0xf2, 0xa3, 0x85, 0xfc, 0x74,
- 0x87, 0x7d, 0x1d, 0x52, 0xab, 0x38, 0x32, 0x55, 0xfd, 0x94, 0x3e, 0xa5,
- 0x74, 0x07, 0xfc, 0x95, 0x21, 0xb4, 0xef, 0x0f, 0xdb, 0x8f, 0xca, 0xf4,
- 0xbc, 0xc8, 0xca, 0xcb, 0x03, 0x7a, 0x51, 0xb5, 0xf7, 0xa2, 0xad, 0xa3,
- 0x9d, 0x0d, 0xdb, 0xcc, 0x8f, 0x0e, 0xe0, 0x71, 0xd5, 0xf3, 0xf5, 0xea,
- 0xb8, 0x3c, 0x55, 0xed, 0x77, 0x5e, 0x87, 0xcd, 0xbd, 0x65, 0x46, 0xf7,
- 0xd2, 0x04, 0x24, 0x79, 0xf6, 0x56, 0x75, 0xf7, 0xf1, 0x04, 0xe2, 0xad,
- 0x9b, 0x34, 0xe5, 0x6f, 0x4f, 0x64, 0xad, 0xa7, 0xf5, 0x5c, 0x52, 0xda,
- 0x7d, 0xff, 0x71, 0x3b, 0x3b, 0x3b, 0xa9, 0x77, 0xca, 0xdf, 0xbf, 0x98,
- 0x91, 0x85, 0xb3, 0x5b, 0x65, 0xa1, 0x06, 0x99, 0x1a, 0xbf, 0x8e, 0x7d,
- 0x35, 0xe5, 0xea, 0x9e, 0x47, 0xb1, 0x27, 0x8c, 0x5d, 0x49, 0xe4, 0x6c,
- 0x1b, 0xc4, 0xec, 0x25, 0x5d, 0x49, 0x98, 0x85, 0x9c, 0x1c, 0x81, 0xdf,
- 0x4f, 0xdb, 0xb9, 0x1e, 0x69, 0xc7, 0x7b, 0x7d, 0x04, 0x7c, 0x5b, 0x32,
- 0xd5, 0x6b, 0xc9, 0x99, 0xc1, 0x68, 0xff, 0xb6, 0x62, 0x6e, 0x46, 0x16,
- 0xcf, 0x66, 0xf0, 0x9b, 0x83, 0xfd, 0xec, 0x94, 0x57, 0x6a, 0xfd, 0xb2,
- 0x54, 0xdb, 0x2a, 0x8b, 0xb5, 0xe6, 0x7d, 0xe8, 0xec, 0x09, 0xe2, 0x1d,
- 0xf1, 0xf4, 0x5b, 0x53, 0xfa, 0x56, 0x71, 0xcd, 0x7e, 0xeb, 0x29, 0xfd,
- 0x1f, 0xe4, 0x31, 0x33, 0xa0, 0xa9, 0x17, 0x7e, 0xa4, 0xee, 0x84, 0x26,
- 0x79, 0xf6, 0x2a, 0xbc, 0x4f, 0x26, 0x49, 0xfb, 0xf5, 0xc6, 0x07, 0xd1,
- 0x59, 0xcb, 0xcf, 0x9d, 0x68, 0x52, 0x06, 0xe2, 0xec, 0xbf, 0x71, 0x52,
- 0xef, 0x95, 0xe5, 0x6d, 0x0f, 0x58, 0x4f, 0xea, 0xad, 0x88, 0x01, 0x3f,
- 0x97, 0x9f, 0xee, 0xd9, 0x24, 0x3f, 0xfc, 0xcd, 0xec, 0xa9, 0x6f, 0x22,
- 0xd9, 0xbf, 0xb2, 0xa7, 0x83, 0x71, 0x01, 0xef, 0xec, 0xcf, 0xde, 0x70,
- 0x75, 0xea, 0xe1, 0x2f, 0xa0, 0x87, 0xec, 0x9c, 0xba, 0x9b, 0x56, 0x3c,
- 0x90, 0x3e, 0xf5, 0x52, 0x06, 0x6f, 0x18, 0xab, 0xf7, 0x03, 0x57, 0x59,
- 0xe9, 0xf9, 0x09, 0x27, 0x7b, 0x03, 0xe9, 0xb0, 0xbf, 0x68, 0xf7, 0xa7,
- 0x77, 0xea, 0x3b, 0x64, 0x32, 0xfd, 0x80, 0xf5, 0xb4, 0x6c, 0x21, 0xce,
- 0xd9, 0x05, 0xc1, 0xda, 0x79, 0xe2, 0xfb, 0x2b, 0xe0, 0x0b, 0x70, 0x28,
- 0xff, 0x51, 0x38, 0x77, 0x59, 0x5f, 0xd7, 0x79, 0xc6, 0x63, 0x0c, 0x71,
- 0xe1, 0xe2, 0x10, 0x65, 0x40, 0x82, 0x95, 0xca, 0xa6, 0x5d, 0xfd, 0xc3,
- 0xc8, 0x47, 0xfc, 0xfd, 0x56, 0x51, 0x27, 0x0f, 0xe7, 0xc0, 0xcb, 0x4f,
- 0xc0, 0x7f, 0x3f, 0x70, 0xa2, 0xf6, 0x48, 0x47, 0x74, 0xff, 0x4e, 0xd1,
- 0x7d, 0xad, 0x21, 0xe6, 0x2a, 0x5d, 0xf4, 0xd5, 0x75, 0xc8, 0xdd, 0x07,
- 0x7b, 0xb5, 0xf0, 0xcb, 0xbd, 0xe9, 0x0c, 0xf7, 0x98, 0xeb, 0x22, 0xba,
- 0x11, 0xbf, 0x5c, 0x73, 0x27, 0x1e, 0xee, 0x75, 0x3e, 0xea, 0xd4, 0x03,
- 0x09, 0x79, 0xf7, 0x44, 0xb4, 0x37, 0x07, 0x64, 0xba, 0x0a, 0xdd, 0xed,
- 0xea, 0x0f, 0xfc, 0x27, 0x1d, 0xf1, 0x40, 0xde, 0xff, 0x06, 0xbc, 0x07,
- 0xb8, 0x5b, 0x0b, 0xcd, 0xba, 0xc3, 0x58, 0x3d, 0xa0, 0x31, 0xb6, 0x0e,
- 0x4f, 0x57, 0xf6, 0x44, 0xbe, 0x98, 0x84, 0x5f, 0xed, 0xb6, 0x9e, 0x10,
- 0xd6, 0x63, 0xc4, 0x9b, 0x94, 0x1f, 0xbe, 0x0c, 0x1e, 0x92, 0xf4, 0x93,
- 0x7f, 0x5f, 0xe3, 0x27, 0x1c, 0xdb, 0x2a, 0x35, 0xd4, 0xd4, 0x5e, 0xde,
- 0x94, 0x69, 0x25, 0x03, 0xda, 0x35, 0xfa, 0x77, 0x29, 0xf4, 0xef, 0x47,
- 0x80, 0xa3, 0x5d, 0x8c, 0x47, 0x1f, 0xc7, 0x59, 0x9d, 0xcd, 0x2c, 0xeb,
- 0xcc, 0x03, 0x76, 0x4b, 0x51, 0xdd, 0x4f, 0xdf, 0x8b, 0xee, 0xa2, 0xd8,
- 0x94, 0x96, 0x8b, 0x95, 0x28, 0x2e, 0xa5, 0x71, 0x9e, 0xb4, 0xcb, 0xa5,
- 0xb9, 0x28, 0xe6, 0xb5, 0xcb, 0x12, 0xf2, 0x9a, 0x95, 0x97, 0x2c, 0x8c,
- 0x25, 0xe5, 0xe2, 0x5c, 0x12, 0x31, 0xab, 0x47, 0x56, 0xe6, 0x7a, 0x30,
- 0x96, 0xc2, 0xba, 0x14, 0xe6, 0xdb, 0xb2, 0x52, 0xb1, 0x81, 0x27, 0x87,
- 0x76, 0x0e, 0xed, 0x21, 0xb9, 0xa4, 0xbe, 0x17, 0x30, 0x2f, 0x18, 0x42,
- 0xdc, 0x62, 0x5e, 0x30, 0x82, 0x18, 0x32, 0x81, 0x27, 0x8a, 0x5d, 0xa7,
- 0x66, 0xa6, 0x2a, 0xbc, 0x73, 0x84, 0x0e, 0xac, 0x53, 0x33, 0xd3, 0xb6,
- 0x89, 0xba, 0xed, 0x1b, 0xda, 0x54, 0x83, 0x72, 0x41, 0xb7, 0x43, 0x1d,
- 0xa2, 0x3f, 0x4a, 0x9b, 0xe4, 0x79, 0x67, 0x20, 0xc6, 0x77, 0x01, 0x9f,
- 0x23, 0xfa, 0x6f, 0xd0, 0x17, 0xa0, 0xc3, 0x27, 0xba, 0xe4, 0xd2, 0xcb,
- 0x8c, 0x35, 0xae, 0xbc, 0x7a, 0x96, 0x3a, 0x2c, 0xf6, 0xac, 0xea, 0x90,
- 0x63, 0x0f, 0xe1, 0x8c, 0xd8, 0x0f, 0x7b, 0x32, 0x33, 0x87, 0x90, 0xcb,
- 0x7c, 0x1b, 0xf6, 0x59, 0x66, 0xcd, 0x9d, 0x0e, 0x6a, 0x84, 0x20, 0x06,
- 0xa0, 0xdd, 0x47, 0x5d, 0xb1, 0xdd, 0x07, 0xbb, 0xe3, 0x58, 0x9f, 0x1a,
- 0x5b, 0x04, 0x8e, 0x60, 0x8c, 0xed, 0xcd, 0xb2, 0xa8, 0xc6, 0x0e, 0xaa,
- 0xb1, 0xb2, 0xb2, 0x0f, 0x8e, 0x1d, 0x52, 0xb1, 0xe9, 0x7c, 0x23, 0xea,
- 0xdf, 0x88, 0x58, 0xc2, 0x7e, 0xf6, 0xe5, 0x61, 0xeb, 0x7b, 0x71, 0xae,
- 0x15, 0x64, 0xa9, 0x81, 0x3a, 0x30, 0xff, 0x7b, 0x98, 0xcb, 0x3d, 0xc8,
- 0x9e, 0x2a, 0xe9, 0xe4, 0xf1, 0x20, 0xce, 0x83, 0xfd, 0x21, 0xad, 0xb6,
- 0x90, 0xaf, 0x03, 0x61, 0xbb, 0x25, 0xa4, 0x4d, 0x3c, 0x36, 0x70, 0x1c,
- 0xc3, 0x5a, 0x17, 0x38, 0x18, 0x63, 0x11, 0x23, 0x52, 0x29, 0xe8, 0x82,
- 0x34, 0xdb, 0xa4, 0xac, 0xde, 0xf7, 0xc3, 0x76, 0xb9, 0x16, 0x3a, 0xb4,
- 0xa2, 0x75, 0xa5, 0x70, 0xcf, 0x53, 0xea, 0x9c, 0xd1, 0x93, 0x9b, 0xc3,
- 0x9c, 0x10, 0x7a, 0x45, 0x9c, 0xd5, 0x93, 0x8c, 0x37, 0xef, 0x84, 0x76,
- 0xda, 0x8b, 0xbe, 0x87, 0x44, 0xef, 0x65, 0xdf, 0x51, 0xe0, 0x61, 0xed,
- 0x3c, 0x0c, 0x99, 0xd9, 0xe6, 0xfa, 0x6c, 0xd3, 0xfa, 0xc4, 0x3a, 0xeb,
- 0x3b, 0x9a, 0xfa, 0x32, 0x52, 0x9b, 0xef, 0x52, 0xf1, 0xf2, 0x7c, 0x18,
- 0x2f, 0x17, 0x6b, 0x94, 0x05, 0x7e, 0x96, 0x7f, 0x5b, 0xe9, 0xa2, 0x76,
- 0x36, 0xb0, 0xf5, 0xa5, 0x93, 0x3c, 0x17, 0x57, 0xe7, 0xd5, 0xd4, 0xbc,
- 0xdf, 0x06, 0xff, 0xba, 0x1c, 0x55, 0x32, 0x70, 0x3e, 0xe6, 0xd5, 0x02,
- 0xbf, 0x31, 0x6c, 0xce, 0xa1, 0x8f, 0x44, 0x6b, 0x38, 0xff, 0xe7, 0xa8,
- 0x55, 0xbe, 0xac, 0xd6, 0xac, 0xfa, 0x0c, 0xf9, 0x71, 0x42, 0x9e, 0x7b,
- 0xc0, 0x5f, 0x67, 0x28, 0x43, 0x7b, 0x28, 0x03, 0xf1, 0xfd, 0x27, 0x70,
- 0xb7, 0x61, 0x1e, 0x79, 0xdd, 0x86, 0x3e, 0xbe, 0xff, 0x17, 0xfa, 0x76,
- 0x23, 0xff, 0x23, 0x6f, 0x89, 0x26, 0xde, 0xfe, 0x03, 0x63, 0x3d, 0x4a,
- 0xb7, 0x35, 0xd4, 0x26, 0x53, 0xbc, 0xef, 0x48, 0xe1, 0x1c, 0x38, 0xb9,
- 0x4d, 0xd1, 0xad, 0x9d, 0xbd, 0x86, 0xf1, 0x5e, 0xac, 0x89, 0xda, 0xcd,
- 0xb2, 0xe9, 0x58, 0xfb, 0x53, 0x25, 0xcf, 0x62, 0xed, 0x4e, 0xf2, 0x6f,
- 0x5b, 0x23, 0x3b, 0xe5, 0x26, 0x4f, 0xe4, 0xa7, 0x1f, 0x4f, 0x2b, 0x72,
- 0x21, 0xd8, 0x6d, 0xd2, 0x90, 0xd1, 0x7c, 0x9a, 0xdf, 0xf9, 0x12, 0xbc,
- 0x17, 0x1d, 0x19, 0xe4, 0x9e, 0xa1, 0xdd, 0x60, 0x4e, 0x47, 0x7f, 0x4b,
- 0xc8, 0x31, 0xd4, 0x24, 0xe5, 0x85, 0x8c, 0x56, 0x3c, 0x99, 0x45, 0x16,
- 0xad, 0xbe, 0xd5, 0xc9, 0x8b, 0x4b, 0xb6, 0x7c, 0x1b, 0x7e, 0x7a, 0xb2,
- 0x9e, 0x4d, 0x7f, 0x13, 0xf9, 0xc1, 0x91, 0x25, 0xe6, 0x13, 0x3d, 0x29,
- 0x65, 0x9b, 0xf3, 0x9a, 0x6c, 0x60, 0x4c, 0x9b, 0x47, 0x7e, 0x6a, 0xdd,
- 0x2d, 0x47, 0x82, 0x9f, 0x57, 0xd7, 0xc6, 0x0c, 0xca, 0xb1, 0x36, 0x66,
- 0x10, 0x0f, 0x63, 0xc6, 0x4e, 0xec, 0x13, 0x63, 0x06, 0xf6, 0xff, 0x24,
- 0x63, 0x86, 0x8d, 0x75, 0x8c, 0x19, 0x79, 0x59, 0xac, 0x32, 0x66, 0xec,
- 0x45, 0x9b, 0x31, 0xa3, 0x80, 0x76, 0x10, 0x2f, 0x16, 0x55, 0xbc, 0xc8,
- 0x5a, 0xcb, 0xc2, 0x38, 0x81, 0x3c, 0xb1, 0x8a, 0x3c, 0xb1, 0x8a, 0x3c,
- 0xb1, 0x8a, 0x3c, 0xb1, 0x8a, 0x3c, 0x11, 0xb6, 0xfe, 0x5a, 0x15, 0x79,
- 0x22, 0xfc, 0xe7, 0x3c, 0x72, 0x92, 0xa0, 0xa6, 0x38, 0x8c, 0x9a, 0xc2,
- 0xd5, 0xc6, 0xaa, 0xe3, 0xda, 0xbe, 0x2a, 0x6a, 0x43, 0xf5, 0x9d, 0x58,
- 0x1f, 0xda, 0x80, 0xba, 0xa8, 0xe6, 0x6c, 0x01, 0x5f, 0xd7, 0xe0, 0x1b,
- 0xd4, 0xd3, 0x56, 0x99, 0xca, 0xed, 0x80, 0x7c, 0xd8, 0x7f, 0xfb, 0xfb,
- 0xe8, 0x43, 0x3e, 0x9f, 0x63, 0x0d, 0xc2, 0x78, 0xb5, 0x0f, 0x6d, 0x1d,
- 0x6d, 0xec, 0xe9, 0x04, 0x7c, 0xc4, 0x7e, 0x90, 0xf9, 0x62, 0x7a, 0x41,
- 0x9e, 0xdc, 0x1c, 0xd8, 0xf4, 0x6f, 0x31, 0x27, 0x5e, 0xd3, 0xde, 0x88,
- 0x39, 0xf0, 0x17, 0xd8, 0x97, 0x5a, 0x03, 0x5c, 0xba, 0xfd, 0xe7, 0xc4,
- 0xd1, 0xb7, 0xe1, 0xd6, 0x1c, 0xda, 0xd5, 0xf7, 0x9a, 0xfa, 0xb2, 0x98,
- 0xcf, 0xef, 0xe2, 0x3b, 0xf0, 0xfb, 0x16, 0x7e, 0x61, 0x77, 0xf6, 0x05,
- 0xcc, 0xe9, 0xc3, 0xef, 0x77, 0x9a, 0xe6, 0x42, 0x0a, 0xfb, 0x2f, 0xd1,
- 0x77, 0x31, 0xa4, 0xc1, 0x6f, 0x89, 0x5f, 0x6a, 0xe2, 0xe3, 0x07, 0xe8,
- 0xfb, 0x6b, 0xf4, 0xf9, 0xfe, 0xdb, 0x4e, 0xd4, 0x27, 0xa5, 0x96, 0x70,
- 0xef, 0x46, 0xd5, 0xde, 0x69, 0xca, 0xe6, 0x8f, 0x2c, 0xe9, 0xaa, 0x0e,
- 0x7a, 0xae, 0x8e, 0xea, 0x08, 0x71, 0xbe, 0xbc, 0x10, 0xd4, 0xad, 0xc7,
- 0x51, 0x73, 0x16, 0xab, 0xb4, 0x91, 0x1c, 0xfa, 0x6d, 0x9c, 0x69, 0x32,
- 0x69, 0xdc, 0xaa, 0x63, 0x13, 0x89, 0xc9, 0x7a, 0x9b, 0x48, 0x37, 0x69,
- 0x32, 0x4f, 0x22, 0x8e, 0xd9, 0x99, 0xe2, 0xc2, 0xec, 0x8c, 0x07, 0x9c,
- 0x63, 0x75, 0xae, 0xe5, 0x3c, 0x93, 0xf7, 0x63, 0x4d, 0x74, 0x69, 0x13,
- 0x60, 0x06, 0xf4, 0x9e, 0xab, 0x93, 0x7e, 0x40, 0xb3, 0xac, 0x68, 0xda,
- 0xe8, 0x8f, 0xea, 0xc7, 0x1c, 0x6a, 0x5d, 0x99, 0x64, 0xed, 0x5c, 0x0c,
- 0x69, 0xba, 0x75, 0x49, 0x24, 0x0a, 0xcd, 0xf8, 0x82, 0x8c, 0xf3, 0xb9,
- 0xfa, 0xec, 0x8c, 0xfe, 0x42, 0x36, 0xc7, 0x3b, 0x11, 0xd7, 0x9a, 0x9d,
- 0x69, 0x1d, 0x48, 0xc8, 0x8f, 0x91, 0xbb, 0x1d, 0x53, 0x34, 0x66, 0x67,
- 0x8c, 0x17, 0x02, 0x5b, 0x0c, 0xe8, 0xe0, 0x3c, 0xc9, 0xb7, 0x43, 0x4e,
- 0xd2, 0x62, 0x4d, 0x1d, 0x8c, 0x4f, 0xaa, 0x7a, 0xd1, 0x94, 0x2b, 0x15,
- 0x45, 0x3b, 0xac, 0xdb, 0xc9, 0xc3, 0xec, 0x8c, 0xfc, 0xd1, 0x2d, 0x1e,
- 0xd6, 0x91, 0x87, 0x78, 0x49, 0x27, 0xd0, 0x5b, 0xc0, 0x7f, 0x12, 0xf5,
- 0x7b, 0x54, 0xab, 0xfb, 0xfe, 0x8a, 0x93, 0x43, 0x5c, 0xe0, 0x3e, 0xb6,
- 0xa8, 0x3c, 0xd7, 0x73, 0x32, 0xbc, 0xef, 0x9b, 0xe3, 0xdf, 0x39, 0x78,
- 0xf9, 0x01, 0xd4, 0x4d, 0xbc, 0x1b, 0xa4, 0x7f, 0xe1, 0xf7, 0x36, 0xff,
- 0xe2, 0x7c, 0xf6, 0x93, 0xe7, 0x81, 0xf4, 0x55, 0xf0, 0xe7, 0xe5, 0xd1,
- 0x87, 0x58, 0x51, 0x6c, 0x44, 0xb8, 0x78, 0xc7, 0xce, 0x39, 0x2a, 0xff,
- 0x6e, 0xf2, 0xd1, 0x96, 0xf0, 0xdc, 0xa5, 0x8e, 0xc8, 0x27, 0xf9, 0xe9,
- 0x84, 0x4d, 0x90, 0x17, 0xce, 0x8f, 0xee, 0x25, 0xd8, 0xfe, 0xb8, 0x36,
- 0x12, 0xdd, 0xa9, 0x7d, 0x9c, 0x3d, 0x8f, 0x74, 0x76, 0x37, 0x7e, 0x88,
- 0x83, 0xb4, 0x23, 0xbe, 0x22, 0x9e, 0x88, 0x8f, 0xfc, 0x44, 0xbc, 0x28,
- 0x1b, 0x5d, 0x97, 0x9f, 0x60, 0x5d, 0xc0, 0x4f, 0x69, 0x21, 0x0d, 0x9d,
- 0x90, 0xa7, 0x11, 0x6d, 0xa4, 0xba, 0xde, 0x1d, 0xc7, 0x0f, 0x5c, 0xc6,
- 0xd5, 0xb1, 0x06, 0xef, 0xa1, 0x48, 0x97, 0x7f, 0x3b, 0xb2, 0xa4, 0x8d,
- 0x34, 0xf8, 0x9d, 0xa9, 0xae, 0xb9, 0x8d, 0x88, 0xde, 0x5a, 0x9d, 0x46,
- 0xbf, 0xbc, 0x2b, 0xff, 0x0c, 0xf6, 0xa9, 0x3b, 0xf8, 0xbb, 0x14, 0x55,
- 0x47, 0xb1, 0x6f, 0xb9, 0xd5, 0x73, 0xa2, 0xbf, 0xd3, 0xd9, 0x1f, 0xe6,
- 0x43, 0x51, 0x6d, 0x1c, 0xd5, 0x59, 0xea, 0x9e, 0x7d, 0xaf, 0xe7, 0x68,
- 0xc8, 0x4f, 0x99, 0x33, 0x05, 0x3a, 0x08, 0xf1, 0xde, 0x91, 0xcf, 0x91,
- 0x26, 0x3e, 0x47, 0xc1, 0xe7, 0x3e, 0xf0, 0x39, 0x76, 0x8b, 0xcf, 0x5b,
- 0xb6, 0x97, 0x29, 0xc3, 0xf6, 0x46, 0xd6, 0xb5, 0xbd, 0x55, 0x3a, 0xab,
- 0x73, 0x83, 0xfb, 0x9a, 0x91, 0x86, 0x2f, 0xc7, 0x9d, 0x8f, 0x53, 0x37,
- 0xb7, 0xcb, 0x99, 0x85, 0xbb, 0xd5, 0xb7, 0x11, 0xaf, 0x2a, 0x77, 0x94,
- 0x4b, 0xf5, 0x80, 0x9f, 0x1f, 0x2f, 0xb1, 0x3d, 0x12, 0xea, 0x8a, 0x3a,
- 0xcb, 0x3a, 0x25, 0xb9, 0x1b, 0x2f, 0xbf, 0xf8, 0x9c, 0x76, 0xa5, 0x12,
- 0x9d, 0x4f, 0x5a, 0x78, 0xc6, 0xae, 0xe5, 0x29, 0xfa, 0x6e, 0x32, 0x66,
- 0x45, 0xf7, 0x67, 0x22, 0xfc, 0xfe, 0xc0, 0xef, 0x75, 0x6b, 0xbf, 0x13,
- 0xf0, 0x7c, 0x8a, 0x78, 0xd7, 0x53, 0x3c, 0x9f, 0xc6, 0x9c, 0x66, 0x19,
- 0x5c, 0xd8, 0xa4, 0x9e, 0xe4, 0x98, 0xe7, 0xd0, 0x2f, 0x4c, 0xd0, 0x0c,
- 0xee, 0xdd, 0x6a, 0x4b, 0xbe, 0x5c, 0x74, 0x36, 0x06, 0xe7, 0x28, 0x64,
- 0xba, 0x6c, 0xf1, 0xfe, 0x0a, 0x31, 0x8c, 0x67, 0x83, 0xb2, 0xb5, 0x16,
- 0xf5, 0x5c, 0x39, 0xd0, 0x0e, 0x1d, 0xb3, 0xdd, 0xd6, 0xcb, 0xfb, 0x0a,
- 0xca, 0xbc, 0xa0, 0xf6, 0x21, 0xd2, 0x71, 0xf4, 0x7d, 0xae, 0x55, 0x96,
- 0xc3, 0xbb, 0xad, 0xc5, 0x8a, 0xef, 0xbf, 0x83, 0x3c, 0xfc, 0x34, 0x74,
- 0x5f, 0xae, 0xff, 0xcc, 0x5f, 0x4e, 0xf1, 0x6f, 0xa5, 0x22, 0x9b, 0xd8,
- 0xd1, 0xcb, 0x7b, 0x20, 0xf8, 0x96, 0x1c, 0xaf, 0x87, 0x65, 0xbf, 0x70,
- 0x9c, 0x7d, 0xff, 0x0d, 0xbe, 0x7d, 0xff, 0xf4, 0xaa, 0x9d, 0x02, 0xfe,
- 0x17, 0x33, 0xe1, 0x9b, 0xdd, 0x90, 0x58, 0x00, 0x00, 0x00 };
+ 0x1f, 0x8b, 0x08, 0x08, 0xcb, 0xa3, 0x46, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5c, 0x6f, 0x6c,
+ 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x4e, 0xd4, 0x91, 0x5c, 0x1e,
+ 0x4f, 0xf4, 0x49, 0x66, 0x94, 0x5d, 0x71, 0x25, 0x5e, 0x2d, 0xc6, 0x5d,
+ 0x31, 0x57, 0x9b, 0x08, 0xce, 0xf1, 0x79, 0xef, 0x64, 0xb1, 0x86, 0x0a,
+ 0x51, 0x0d, 0x1d, 0x1b, 0x85, 0x6b, 0xb0, 0x47, 0x39, 0xae, 0xdb, 0x7e,
+ 0x90, 0x65, 0x1b, 0x30, 0xda, 0x10, 0xbe, 0x1c, 0xe9, 0x46, 0x75, 0x2f,
+ 0xdc, 0x8b, 0xc4, 0x98, 0x06, 0xfa, 0x07, 0x57, 0x92, 0xfa, 0x83, 0xe0,
+ 0xa0, 0x93, 0xe2, 0x26, 0xf5, 0x17, 0x57, 0x84, 0x2a, 0xc7, 0xf9, 0xe0,
+ 0x02, 0x4e, 0x63, 0x20, 0x06, 0xea, 0x16, 0xaa, 0xec, 0xd8, 0x46, 0x81,
+ 0xa2, 0x42, 0x1c, 0xd8, 0x46, 0xfc, 0x67, 0xfb, 0x7b, 0x33, 0xbb, 0xd4,
+ 0x91, 0x96, 0x6d, 0xa0, 0x1f, 0xfa, 0xa5, 0x3b, 0xc0, 0x61, 0x67, 0x66,
+ 0xe7, 0xbd, 0x79, 0xf3, 0xfe, 0xbf, 0x59, 0x4a, 0x7f, 0x90, 0xa4, 0x2e,
+ 0x0a, 0x5b, 0x37, 0x7e, 0xd6, 0x91, 0xc7, 0x8f, 0xde, 0x3c, 0x76, 0xf3,
+ 0x28, 0xd1, 0x97, 0x47, 0xf5, 0x1b, 0x12, 0x22, 0x9a, 0x8f, 0x5b, 0xdc,
+ 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2,
+ 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16,
+ 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7,
+ 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8,
+ 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5,
+ 0x2d, 0x6e, 0x71, 0xfb, 0xff, 0xde, 0x74, 0x22, 0x93, 0x9f, 0xdd, 0xe1,
+ 0x8f, 0x12, 0x22, 0xbf, 0xfa, 0x90, 0xe7, 0x50, 0x42, 0xcf, 0xbf, 0x34,
+ 0x33, 0xed, 0x10, 0x15, 0x9a, 0x7b, 0xac, 0x22, 0x7d, 0x14, 0x54, 0xd2,
+ 0x06, 0xf1, 0xfc, 0x17, 0xf2, 0x1f, 0x3e, 0xf1, 0xfc, 0xad, 0xf6, 0xd5,
+ 0x86, 0x4e, 0x09, 0x33, 0x3f, 0xb7, 0xd7, 0xdc, 0x4d, 0x89, 0x41, 0xc0,
+ 0xfc, 0xf5, 0xf0, 0x7f, 0xf4, 0x50, 0x0f, 0x5d, 0xc3, 0xe3, 0x24, 0xe8,
+ 0xb2, 0xfe, 0x9c, 0xe6, 0xb5, 0x82, 0xe0, 0xa4, 0x1b, 0x04, 0x3f, 0xc6,
+ 0xef, 0x2d, 0x17, 0x63, 0xff, 0xe3, 0xa0, 0x60, 0xe8, 0x24, 0x9c, 0xbf,
+ 0xd4, 0xbc, 0xe5, 0x2e, 0xaa, 0x2e, 0x1a, 0x34, 0xeb, 0xa7, 0xe9, 0x98,
+ 0x5f, 0xd1, 0x4a, 0xad, 0x9a, 0xb6, 0xef, 0xf4, 0xbc, 0x76, 0xe7, 0xe9,
+ 0x63, 0xda, 0xfe, 0xd3, 0x75, 0xcd, 0x3b, 0x4d, 0x15, 0xb1, 0x37, 0x49,
+ 0x05, 0xf3, 0x8c, 0x56, 0x6c, 0x0d, 0x68, 0xde, 0x89, 0x0f, 0xc9, 0x73,
+ 0x6d, 0xf3, 0xf7, 0xc8, 0x28, 0x80, 0x16, 0xf2, 0x6a, 0x41, 0xe0, 0xb9,
+ 0x06, 0x15, 0xd2, 0x41, 0x20, 0xf2, 0xc1, 0x13, 0x5e, 0xce, 0x31, 0x85,
+ 0x96, 0xa6, 0x6a, 0x6b, 0x00, 0x78, 0x93, 0x5a, 0x71, 0xd1, 0xd0, 0x4a,
+ 0x7e, 0x70, 0xc1, 0x73, 0x69, 0x50, 0xa7, 0x20, 0x98, 0x73, 0x77, 0x65,
+ 0x0e, 0xd3, 0x29, 0xe0, 0x6d, 0x02, 0x1f, 0x99, 0x22, 0xcf, 0xf4, 0x31,
+ 0x9d, 0x4c, 0x72, 0x45, 0x2b, 0x0e, 0x47, 0xf4, 0x91, 0xc5, 0xf4, 0x97,
+ 0x57, 0x04, 0xe8, 0xdc, 0x42, 0xe5, 0x86, 0x49, 0x53, 0x2b, 0x1b, 0xd7,
+ 0x5f, 0x0e, 0x9e, 0x1f, 0x36, 0xe9, 0x5c, 0xcb, 0xae, 0x54, 0x28, 0x41,
+ 0x73, 0xbe, 0x45, 0x22, 0x4f, 0x05, 0x2f, 0x37, 0x48, 0x17, 0x5a, 0x19,
+ 0xfa, 0x41, 0xcb, 0xc9, 0x54, 0x69, 0x13, 0x95, 0xd3, 0x69, 0x3a, 0xdf,
+ 0x4a, 0xe3, 0x8c, 0xc1, 0x05, 0xe1, 0x38, 0x66, 0x15, 0x6b, 0xab, 0xad,
+ 0x97, 0xf8, 0xdf, 0xbf, 0x98, 0xd3, 0x39, 0x09, 0x53, 0x01, 0xdd, 0xe1,
+ 0x5a, 0x3e, 0x87, 0x5c, 0x2b, 0xcf, 0xa2, 0xd6, 0x52, 0x65, 0x3a, 0x87,
+ 0xb9, 0xd6, 0x1d, 0x6b, 0xfc, 0x2d, 0xa4, 0xf9, 0x69, 0x52, 0xd5, 0xef,
+ 0x00, 0x6f, 0xb8, 0x3f, 0x88, 0xb3, 0xee, 0xd0, 0xbc, 0xc5, 0x7f, 0x65,
+ 0xbc, 0x69, 0x41, 0x3b, 0x30, 0x1e, 0xc4, 0x98, 0xfb, 0xbb, 0x32, 0x65,
+ 0x02, 0x8f, 0x5b, 0x49, 0x8c, 0x99, 0xce, 0x20, 0xd8, 0xef, 0x92, 0x59,
+ 0x75, 0x7b, 0x01, 0x6b, 0x51, 0xd5, 0xed, 0x01, 0xbe, 0x0e, 0xea, 0x73,
+ 0xf8, 0x7c, 0xbc, 0xe7, 0x66, 0xcc, 0x07, 0xdd, 0x7a, 0x3e, 0x08, 0xa6,
+ 0x73, 0xd4, 0xa3, 0xe6, 0xf6, 0x48, 0x1c, 0x53, 0x13, 0x1a, 0xd6, 0xbd,
+ 0xc3, 0x7b, 0x24, 0x52, 0x79, 0xee, 0xf3, 0x33, 0x47, 0xde, 0xfc, 0x8e,
+ 0x90, 0xa6, 0x0c, 0x68, 0xba, 0x31, 0xec, 0x43, 0x0e, 0x3e, 0xf8, 0xe1,
+ 0xde, 0x80, 0xb1, 0xf6, 0x45, 0xe0, 0xc9, 0x56, 0x89, 0xf7, 0xe8, 0xa7,
+ 0xa5, 0x34, 0x89, 0x2b, 0x6e, 0x5f, 0xb8, 0xae, 0x07, 0xb4, 0x46, 0xfa,
+ 0x30, 0x40, 0x73, 0x8b, 0xcc, 0xf3, 0x1a, 0x64, 0x24, 0x68, 0xe7, 0x2d,
+ 0x15, 0xad, 0xd0, 0x3a, 0x86, 0xbe, 0x41, 0xd3, 0x4e, 0x70, 0x61, 0xce,
+ 0x9d, 0xd7, 0x8a, 0xa7, 0x4f, 0x69, 0xa5, 0xd3, 0xcf, 0x69, 0xfb, 0x5a,
+ 0x2f, 0x76, 0x53, 0x97, 0x8d, 0xd3, 0x27, 0xe8, 0x49, 0x5f, 0x23, 0xa6,
+ 0x73, 0x09, 0x3c, 0x2c, 0x98, 0x15, 0x32, 0x9c, 0x1e, 0xed, 0x4e, 0xe0,
+ 0xe9, 0x70, 0xfe, 0x2c, 0x49, 0x3d, 0x3a, 0x6d, 0x72, 0xa2, 0xb5, 0x69,
+ 0xfa, 0x73, 0xd0, 0x74, 0xd1, 0xdd, 0xca, 0x7c, 0xeb, 0x55, 0x30, 0xa9,
+ 0x90, 0x0e, 0xd6, 0x2f, 0x96, 0x9f, 0x6d, 0x7a, 0xba, 0xa0, 0xd2, 0xc2,
+ 0x5f, 0xf4, 0x57, 0x47, 0xb6, 0xf0, 0x3a, 0xd8, 0xc2, 0xd5, 0x87, 0xa6,
+ 0x1d, 0xaf, 0xcf, 0xa0, 0x8a, 0x29, 0xc8, 0x36, 0x8b, 0xf4, 0x45, 0x9a,
+ 0x73, 0x89, 0x8a, 0x35, 0xec, 0xeb, 0x18, 0xe0, 0x8f, 0x03, 0xfe, 0xec,
+ 0xaa, 0xe8, 0xe2, 0x1e, 0xa0, 0xa9, 0x68, 0x46, 0xc8, 0xcb, 0x25, 0xba,
+ 0x4b, 0xc2, 0x8b, 0xbc, 0x0b, 0x5d, 0xed, 0xe2, 0x3e, 0xf6, 0x4e, 0xc8,
+ 0xbd, 0xf5, 0xbc, 0x93, 0x59, 0x26, 0xd2, 0x44, 0x7e, 0x0f, 0xf0, 0xb1,
+ 0x0e, 0xf3, 0xba, 0x79, 0xd0, 0xc9, 0xf4, 0x73, 0xdf, 0x01, 0x4c, 0x02,
+ 0xfa, 0xde, 0xdd, 0x46, 0x2b, 0xe8, 0x49, 0x33, 0xbf, 0x99, 0x7f, 0xf2,
+ 0xac, 0xda, 0xb5, 0xb3, 0x7e, 0x10, 0x0c, 0x8f, 0x1a, 0xf4, 0x63, 0x79,
+ 0x66, 0xb6, 0x37, 0x5e, 0x97, 0x0e, 0xf5, 0x23, 0x01, 0x9d, 0x22, 0xad,
+ 0xec, 0x9a, 0x6b, 0xb8, 0xca, 0x44, 0x42, 0xcf, 0x27, 0xa9, 0x28, 0xe9,
+ 0x1b, 0xc3, 0x5e, 0x6c, 0x87, 0xb0, 0x27, 0x87, 0xcf, 0xc2, 0x73, 0x79,
+ 0xd8, 0xbb, 0xcd, 0x7d, 0x2a, 0xd7, 0xd9, 0xf6, 0x99, 0xb6, 0x55, 0x5b,
+ 0xfe, 0xd3, 0x2c, 0x89, 0x4f, 0x0c, 0xe8, 0xd4, 0x4b, 0x13, 0xee, 0x87,
+ 0x81, 0xd8, 0x8d, 0xf7, 0x23, 0x19, 0xd0, 0x66, 0x5b, 0xb0, 0xca, 0x94,
+ 0x4e, 0x1a, 0xe8, 0xde, 0x93, 0x31, 0xc9, 0xc1, 0xd9, 0xc0, 0xdf, 0x89,
+ 0x55, 0x30, 0xff, 0xd3, 0xe8, 0x54, 0x78, 0x41, 0x66, 0xc1, 0x03, 0x8d,
+ 0x9e, 0xfb, 0x65, 0xc9, 0x33, 0x13, 0xe7, 0xd7, 0xe7, 0x99, 0xbf, 0x5d,
+ 0xb0, 0x0b, 0x8d, 0xca, 0x2e, 0xe3, 0x8e, 0x70, 0x08, 0x1a, 0xbe, 0xa5,
+ 0x1d, 0x47, 0x24, 0x5f, 0xd6, 0x5d, 0x83, 0x46, 0x47, 0x79, 0x2d, 0xaf,
+ 0xe3, 0xf5, 0xf6, 0x98, 0x25, 0x3e, 0x08, 0xf6, 0xae, 0xdb, 0xd3, 0x21,
+ 0x31, 0x0f, 0x9a, 0x95, 0x2c, 0xc0, 0xc3, 0xcf, 0x5b, 0xcb, 0x72, 0xd8,
+ 0xc8, 0x6f, 0x5e, 0xdb, 0xbe, 0x0e, 0xfa, 0x3c, 0xc0, 0x34, 0x9c, 0x4c,
+ 0x2a, 0x3b, 0x8d, 0x68, 0x8a, 0x64, 0xa9, 0x85, 0x38, 0x3e, 0xeb, 0x1c,
+ 0xbc, 0x1e, 0xfe, 0xc3, 0x87, 0xff, 0x80, 0x4f, 0x3c, 0xef, 0xc3, 0xbf,
+ 0xf8, 0xec, 0x6f, 0x2c, 0x7a, 0x7e, 0x18, 0xfe, 0xf1, 0x9a, 0x7f, 0x42,
+ 0x1b, 0x47, 0x5f, 0x90, 0x0e, 0xff, 0x34, 0xdb, 0x10, 0xb0, 0x73, 0xf8,
+ 0x8a, 0x15, 0x9e, 0x83, 0x5f, 0x58, 0x29, 0xe1, 0xe9, 0x50, 0xb5, 0xc9,
+ 0x7a, 0x18, 0xf9, 0x61, 0xf6, 0x57, 0x19, 0xf8, 0x26, 0xf6, 0x47, 0xec,
+ 0xb7, 0x78, 0x6d, 0x10, 0x94, 0x5c, 0x86, 0x0d, 0x20, 0x47, 0xb6, 0xbb,
+ 0x24, 0x89, 0x54, 0x45, 0x3b, 0x34, 0x0c, 0x7b, 0xbc, 0x89, 0x7d, 0x0b,
+ 0xdb, 0xe5, 0x8d, 0x44, 0x9d, 0xbc, 0xdf, 0xaf, 0xbb, 0xd5, 0xbf, 0xd9,
+ 0xdb, 0x84, 0x35, 0xf2, 0xd9, 0xa3, 0xc6, 0x66, 0xe8, 0x97, 0xf8, 0xbd,
+ 0x6d, 0x15, 0x68, 0x57, 0x38, 0xe6, 0xfe, 0x1a, 0xbd, 0xae, 0xb8, 0x25,
+ 0x41, 0x3b, 0x4f, 0x29, 0x7f, 0xba, 0x73, 0x09, 0x9a, 0x71, 0x4a, 0xd1,
+ 0xb8, 0xf3, 0x6c, 0xe4, 0x57, 0x93, 0xc0, 0x07, 0xfa, 0xfc, 0xb5, 0x18,
+ 0x82, 0xf6, 0x9e, 0x06, 0xd3, 0xc2, 0xdc, 0x46, 0x5e, 0xb0, 0x2f, 0x67,
+ 0xfb, 0x34, 0xdb, 0xed, 0x73, 0x2f, 0xec, 0xd3, 0xed, 0x24, 0xdb, 0xfd,
+ 0x27, 0xd8, 0xe7, 0xb7, 0x5d, 0x0d, 0xbc, 0x21, 0xba, 0x54, 0xcb, 0xc0,
+ 0x3f, 0x18, 0x99, 0xd7, 0x69, 0x97, 0x35, 0x0b, 0xbd, 0x3c, 0xc9, 0x73,
+ 0x4d, 0xcc, 0x49, 0x3f, 0xae, 0xfc, 0xc7, 0x65, 0xfd, 0xbb, 0xa0, 0x2b,
+ 0x08, 0x66, 0x81, 0xb3, 0x3c, 0xa2, 0x87, 0xb6, 0x18, 0xcd, 0x5f, 0x45,
+ 0x3c, 0xf4, 0x7e, 0x43, 0xa7, 0x4a, 0xb6, 0x83, 0xec, 0xec, 0x12, 0x70,
+ 0x4f, 0xbb, 0xca, 0xee, 0xd9, 0x36, 0x96, 0x81, 0x7f, 0xce, 0x1f, 0x86,
+ 0x5f, 0x60, 0xbb, 0x01, 0x5d, 0xc0, 0xbf, 0x0c, 0xfc, 0x73, 0xad, 0x0e,
+ 0xfa, 0x96, 0x11, 0xc5, 0xd9, 0xe8, 0x3c, 0xdb, 0xb0, 0x2c, 0xda, 0xf7,
+ 0x08, 0xdd, 0xe5, 0xa7, 0xe0, 0x73, 0xd8, 0x27, 0x57, 0xb3, 0xb0, 0x2b,
+ 0xad, 0xea, 0xf2, 0xde, 0x3a, 0x2d, 0xaf, 0xad, 0xa1, 0x42, 0x55, 0xd9,
+ 0x6c, 0xc1, 0x1b, 0xae, 0x64, 0x74, 0xe9, 0x7b, 0x88, 0xee, 0x84, 0xad,
+ 0x2e, 0x3b, 0x3c, 0xe6, 0x79, 0x35, 0x37, 0x5e, 0x1b, 0xd0, 0x8a, 0xec,
+ 0xbf, 0x86, 0x3f, 0x04, 0x7d, 0x6a, 0xee, 0xb7, 0x6b, 0x0f, 0xb1, 0x8c,
+ 0x70, 0x16, 0xb2, 0xaa, 0xee, 0x7f, 0x06, 0xd0, 0xdf, 0x75, 0x30, 0xd7,
+ 0xc7, 0x63, 0x8f, 0x2b, 0x9d, 0x25, 0x6d, 0xbf, 0x23, 0x06, 0x3a, 0x43,
+ 0x9f, 0xb7, 0x1f, 0x93, 0xfb, 0x6a, 0xd5, 0xfe, 0x4e, 0xfa, 0x50, 0xe7,
+ 0x18, 0x7c, 0x85, 0xc8, 0xf0, 0x6a, 0xbb, 0xc1, 0x8f, 0x6a, 0x5f, 0xdb,
+ 0x5c, 0xa2, 0x54, 0x0b, 0xe8, 0xa2, 0xab, 0x60, 0x30, 0x4e, 0x16, 0x6b,
+ 0x62, 0x20, 0x41, 0x6b, 0x63, 0x93, 0x61, 0x56, 0x68, 0x77, 0x76, 0x99,
+ 0x24, 0x6c, 0x7f, 0xe2, 0x1a, 0x6c, 0xba, 0x54, 0xab, 0xf6, 0xb5, 0x8d,
+ 0x33, 0x45, 0xe0, 0x12, 0x7b, 0xd7, 0x60, 0x07, 0xaf, 0xc1, 0x6e, 0x25,
+ 0xab, 0x8f, 0xe1, 0xc5, 0xc0, 0xe6, 0x6b, 0xb8, 0xad, 0x90, 0x9e, 0xfe,
+ 0xcd, 0xd7, 0x70, 0x38, 0x8c, 0xb3, 0x6d, 0x9c, 0x65, 0x9c, 0x3b, 0xaf,
+ 0xe1, 0x1c, 0x59, 0x4f, 0xcf, 0x11, 0x82, 0x0f, 0x4a, 0x74, 0xe6, 0x69,
+ 0xef, 0xa5, 0xda, 0xd0, 0xc4, 0x5d, 0x84, 0xf8, 0x38, 0xb2, 0x29, 0xf4,
+ 0xe1, 0xc6, 0x5e, 0x0f, 0xbc, 0x32, 0x88, 0x7d, 0xa2, 0x46, 0x55, 0xc8,
+ 0xf9, 0x8f, 0x9a, 0xb4, 0xf7, 0x62, 0xd3, 0x08, 0x75, 0x89, 0x75, 0xe2,
+ 0x6d, 0xd8, 0x58, 0x72, 0xca, 0x40, 0x0c, 0xbf, 0x20, 0x6d, 0x8c, 0x26,
+ 0xaa, 0x35, 0xaa, 0x6c, 0xcf, 0x3f, 0x11, 0x40, 0x17, 0xa7, 0xe0, 0xd3,
+ 0xc0, 0xe3, 0xe4, 0x98, 0x97, 0xc3, 0x7c, 0x93, 0x6d, 0x0b, 0x7e, 0x05,
+ 0xb0, 0xd0, 0xb5, 0x84, 0x3e, 0xbf, 0xeb, 0x55, 0x4f, 0xe7, 0x7d, 0x2c,
+ 0xe4, 0x5c, 0x89, 0x84, 0x98, 0xbf, 0x1a, 0xb0, 0x9e, 0x4d, 0x8f, 0x5c,
+ 0x45, 0x8e, 0x63, 0x92, 0x37, 0x06, 0xff, 0x01, 0x7d, 0x9f, 0x6d, 0x11,
+ 0x72, 0x82, 0x3f, 0xed, 0x55, 0x36, 0xf6, 0x9d, 0xad, 0xea, 0x49, 0x06,
+ 0xfb, 0xf2, 0xe9, 0x1c, 0xe7, 0x0f, 0x9d, 0x09, 0x2f, 0x37, 0xbe, 0x4d,
+ 0x3f, 0x7b, 0x60, 0x9b, 0x38, 0x5b, 0xd9, 0x26, 0x10, 0x03, 0x60, 0x53,
+ 0xc2, 0xcb, 0xa1, 0x7f, 0x36, 0xb2, 0xa1, 0x0c, 0x6c, 0x88, 0x69, 0x65,
+ 0x3a, 0x7f, 0x04, 0x7b, 0x95, 0xb4, 0xd2, 0x84, 0x0f, 0x9a, 0x46, 0x3f,
+ 0x82, 0x9e, 0xe0, 0x2c, 0xf0, 0x81, 0x05, 0x70, 0x49, 0x8c, 0xfe, 0x2a,
+ 0xb4, 0x67, 0xee, 0xbf, 0x1b, 0xa8, 0x78, 0x72, 0x30, 0xdc, 0xff, 0x17,
+ 0xa1, 0x0f, 0x88, 0x70, 0x31, 0x9e, 0xac, 0x36, 0x81, 0x5c, 0x68, 0xa2,
+ 0x65, 0x68, 0xec, 0xcf, 0x8b, 0x3e, 0xe7, 0x30, 0x9c, 0xbf, 0x3c, 0x1e,
+ 0xfa, 0x45, 0xce, 0x5b, 0x92, 0x21, 0x4f, 0x73, 0x51, 0x5c, 0x94, 0xf6,
+ 0x86, 0x18, 0x65, 0x95, 0x5d, 0x99, 0xd3, 0x68, 0xd3, 0xb9, 0x24, 0xd6,
+ 0x61, 0xae, 0x85, 0x73, 0xc3, 0x2f, 0x21, 0x0f, 0xe2, 0xdc, 0x14, 0xeb,
+ 0x3b, 0x43, 0x9b, 0xbf, 0x44, 0x65, 0xf8, 0x54, 0xc3, 0xe1, 0xf7, 0x5e,
+ 0x2f, 0x75, 0x61, 0xdc, 0xc4, 0x5e, 0xf0, 0x13, 0xba, 0xe4, 0x33, 0x62,
+ 0x41, 0xfa, 0x06, 0xce, 0xaf, 0xb0, 0xd6, 0xc2, 0x5a, 0xf6, 0xbb, 0xbc,
+ 0xf6, 0x3c, 0xe8, 0xc0, 0xb8, 0xc9, 0x30, 0xec, 0xa3, 0x82, 0xf7, 0xbc,
+ 0xdc, 0x1e, 0x73, 0x82, 0x12, 0x21, 0x5e, 0xab, 0x0d, 0xef, 0xc6, 0xb5,
+ 0x9c, 0xd3, 0x04, 0x17, 0x74, 0x87, 0xf1, 0x47, 0x79, 0x18, 0xd1, 0xf4,
+ 0x09, 0xe4, 0x71, 0x4e, 0x07, 0xe2, 0x14, 0x8f, 0x86, 0x4c, 0x75, 0xce,
+ 0x08, 0xe6, 0x81, 0xfe, 0xf5, 0xe3, 0xbb, 0x53, 0xd7, 0xfc, 0x23, 0x5b,
+ 0x17, 0x15, 0x10, 0x1f, 0xc0, 0x27, 0x6b, 0x8a, 0x73, 0xbf, 0x62, 0x53,
+ 0xa2, 0xc4, 0xdc, 0x18, 0x7c, 0xa2, 0xca, 0xa3, 0x2e, 0xf8, 0x1b, 0xe5,
+ 0x66, 0x82, 0xd7, 0x05, 0xf0, 0xd7, 0x82, 0xfe, 0x8c, 0x03, 0x96, 0x8e,
+ 0x00, 0x07, 0xc7, 0x6a, 0x57, 0xe4, 0x53, 0x54, 0x36, 0x39, 0xa7, 0xe8,
+ 0x64, 0xfa, 0x0a, 0x6c, 0xfb, 0x22, 0xbf, 0x19, 0x73, 0xdc, 0x7f, 0xac,
+ 0x57, 0xc9, 0xab, 0x9b, 0xc7, 0x13, 0x22, 0xdf, 0xbb, 0x61, 0xfe, 0x9f,
+ 0xbb, 0x15, 0x6d, 0x72, 0x8c, 0xf9, 0x7f, 0xdb, 0x30, 0xfe, 0xe3, 0xd4,
+ 0xfa, 0xf1, 0xdd, 0xdb, 0x42, 0xfd, 0x43, 0xff, 0xf1, 0x90, 0x5e, 0xd0,
+ 0xb6, 0x46, 0x6b, 0x94, 0x2b, 0x53, 0x5d, 0x20, 0x5f, 0xf4, 0x72, 0xbb,
+ 0xac, 0x2a, 0x6c, 0xaa, 0xd4, 0x02, 0xdd, 0x6b, 0x71, 0x6c, 0x6d, 0x4d,
+ 0xe5, 0xda, 0x1a, 0xe5, 0xe7, 0x4b, 0xad, 0x00, 0x79, 0x56, 0x7b, 0xcc,
+ 0xcb, 0xa2, 0x5f, 0xc1, 0x3e, 0x05, 0x9a, 0xf6, 0x2f, 0x16, 0x84, 0x73,
+ 0x4c, 0xe6, 0x89, 0xc2, 0x79, 0x4a, 0x2b, 0x2d, 0x73, 0xfe, 0x08, 0x5b,
+ 0x72, 0x64, 0xdd, 0x80, 0x98, 0x72, 0x5c, 0x2b, 0x9c, 0x5e, 0x40, 0xfe,
+ 0xb8, 0x82, 0xdf, 0x19, 0xfc, 0x9a, 0xf8, 0x45, 0xf9, 0xfb, 0x33, 0xc8,
+ 0xff, 0xa5, 0x7f, 0x45, 0x2c, 0x50, 0xfb, 0xff, 0x62, 0x05, 0x3a, 0xb6,
+ 0x90, 0xa6, 0x6f, 0x3b, 0xa2, 0x5f, 0x28, 0x9f, 0x52, 0x40, 0xde, 0x6b,
+ 0xbe, 0x4d, 0xbf, 0x13, 0xe6, 0x50, 0x44, 0xaf, 0xd7, 0xc1, 0xc7, 0x91,
+ 0xfd, 0xa1, 0xbe, 0x66, 0x1f, 0xf4, 0xa4, 0xef, 0x0c, 0x73, 0x24, 0xe4,
+ 0x6a, 0x05, 0xb9, 0xea, 0xfb, 0xe0, 0x8d, 0x46, 0x6f, 0x41, 0x7f, 0x5e,
+ 0xaf, 0x77, 0x81, 0x1e, 0x87, 0xca, 0x93, 0xf6, 0x18, 0x69, 0x43, 0xe6,
+ 0x26, 0xad, 0x0b, 0x36, 0x0c, 0xfb, 0x96, 0x63, 0x4a, 0x74, 0xe4, 0xcf,
+ 0xcd, 0x2c, 0xd5, 0x04, 0xd6, 0x22, 0xef, 0xc9, 0xa1, 0x0f, 0xd9, 0x5f,
+ 0xa9, 0x33, 0x9c, 0xa0, 0x37, 0xea, 0x3a, 0xbd, 0x89, 0xbc, 0xeb, 0x2d,
+ 0xe7, 0xdc, 0x0c, 0x62, 0xd6, 0x00, 0xe2, 0x03, 0x6a, 0x98, 0x5d, 0xec,
+ 0xa3, 0x77, 0x1a, 0x78, 0x96, 0xf0, 0xbb, 0x13, 0x79, 0xe3, 0xf5, 0x61,
+ 0x3e, 0x6d, 0x3d, 0xd3, 0x96, 0x00, 0x0c, 0xaf, 0x37, 0x40, 0x5b, 0x0f,
+ 0xe4, 0x6f, 0x9b, 0x53, 0xf4, 0xcb, 0x5e, 0x99, 0xab, 0x68, 0x3c, 0xaf,
+ 0xfc, 0xd2, 0x27, 0xe7, 0x99, 0xcf, 0x3a, 0x74, 0x9c, 0xc7, 0xfc, 0x8e,
+ 0xfd, 0x27, 0xe3, 0xb3, 0xc7, 0x0a, 0x38, 0xcc, 0x95, 0xba, 0xea, 0x47,
+ 0x73, 0xa4, 0x45, 0x31, 0x8c, 0xfd, 0x62, 0x89, 0x0a, 0x92, 0xef, 0x13,
+ 0x24, 0x65, 0xb0, 0x4e, 0x9e, 0x94, 0x30, 0xf2, 0xf5, 0x99, 0x39, 0x87,
+ 0xe5, 0x0a, 0xff, 0x56, 0x8b, 0xe4, 0xca, 0x32, 0xea, 0xa4, 0x6a, 0xfd,
+ 0x29, 0xc8, 0x55, 0x84, 0xf5, 0x01, 0xec, 0x7b, 0x81, 0xe5, 0x8b, 0xba,
+ 0xb1, 0x8e, 0xbc, 0xa7, 0x4e, 0x29, 0x55, 0xdf, 0x1c, 0x47, 0x5d, 0x00,
+ 0xf9, 0xd5, 0x16, 0x80, 0x03, 0x36, 0x5a, 0x5b, 0xc1, 0x13, 0xb5, 0x48,
+ 0xed, 0x0c, 0x9e, 0x83, 0x78, 0x36, 0x59, 0x37, 0xc3, 0x3c, 0xe3, 0x13,
+ 0xf4, 0xc0, 0x9e, 0x4a, 0x6c, 0x4f, 0xf4, 0x8f, 0xad, 0x3c, 0xfd, 0x43,
+ 0x6b, 0x8c, 0x7e, 0xd4, 0xca, 0xd1, 0x0f, 0x5b, 0x2e, 0xfd, 0x7d, 0x6b,
+ 0x84, 0x9e, 0x6d, 0x65, 0xb9, 0x96, 0x43, 0xce, 0x64, 0x71, 0xce, 0x44,
+ 0x0f, 0xfa, 0xb7, 0xc3, 0xde, 0x59, 0xfe, 0xe7, 0x66, 0x0a, 0xcd, 0x21,
+ 0x2a, 0x9f, 0x80, 0x6f, 0x76, 0x6f, 0xe3, 0x1a, 0x94, 0x1e, 0x73, 0xb9,
+ 0x86, 0xe8, 0xe0, 0xf7, 0xa8, 0x23, 0xe0, 0xbb, 0xe1, 0xcb, 0xa6, 0xd2,
+ 0xf6, 0x39, 0x4f, 0x1f, 0x08, 0x7d, 0xc0, 0x5d, 0x29, 0xea, 0xc2, 0x5e,
+ 0xf0, 0x7f, 0x17, 0x9f, 0x86, 0x0d, 0xc8, 0x1a, 0x28, 0x01, 0x5f, 0xc3,
+ 0x79, 0x80, 0xc1, 0x76, 0xcc, 0xf5, 0x87, 0xe5, 0xe9, 0x5c, 0x17, 0xb2,
+ 0x3d, 0xeb, 0x08, 0x1a, 0x0c, 0x37, 0x69, 0xb2, 0xdc, 0x0c, 0x87, 0x7d,
+ 0x6a, 0x21, 0xf4, 0x6f, 0x89, 0x50, 0x2f, 0x4d, 0xcc, 0x3f, 0x15, 0xfa,
+ 0xe3, 0x8d, 0xfb, 0x20, 0x56, 0x20, 0x97, 0x54, 0xeb, 0x18, 0x56, 0x0b,
+ 0x61, 0xfb, 0xc3, 0xb9, 0x24, 0xf8, 0xed, 0x52, 0xd9, 0x7f, 0x43, 0xe3,
+ 0x1c, 0x5b, 0x38, 0xcc, 0xff, 0x11, 0x8c, 0x2f, 0x87, 0xe3, 0xaf, 0xd0,
+ 0xf4, 0x22, 0x81, 0xd6, 0xd7, 0xb4, 0xa2, 0x1c, 0x8f, 0x61, 0x2c, 0x30,
+ 0xd6, 0xb9, 0x6e, 0xe0, 0x0c, 0x23, 0xc5, 0xba, 0x2e, 0x9c, 0x71, 0xf0,
+ 0x71, 0x12, 0xbf, 0x82, 0xfc, 0x3d, 0xe2, 0x0f, 0x15, 0xde, 0x41, 0xbc,
+ 0xd0, 0x3a, 0xa2, 0xdc, 0x67, 0x3b, 0x6a, 0xcf, 0x20, 0x38, 0x84, 0x5a,
+ 0xdd, 0x4a, 0x19, 0xf4, 0x2f, 0xf3, 0xb6, 0x79, 0x48, 0xcc, 0xe1, 0x4c,
+ 0x41, 0x30, 0xe1, 0xd8, 0x95, 0x82, 0xe8, 0xa6, 0x9f, 0x1f, 0xe7, 0xb8,
+ 0x5b, 0x9f, 0x79, 0x01, 0xba, 0xd7, 0x58, 0xe9, 0xa4, 0x46, 0xc3, 0xa0,
+ 0x2b, 0xa3, 0x43, 0xa0, 0xd3, 0xa4, 0x46, 0x33, 0x85, 0x5c, 0x6e, 0x33,
+ 0xa1, 0x3c, 0x94, 0x0e, 0x43, 0xcf, 0x67, 0xa5, 0x8f, 0xf6, 0x1c, 0x3c,
+ 0x9b, 0x1f, 0xf4, 0xae, 0x3f, 0x73, 0x09, 0xf4, 0xf7, 0xa0, 0x0a, 0xd9,
+ 0x2e, 0xe5, 0x5c, 0xf6, 0x87, 0x4c, 0x4f, 0x20, 0x6e, 0x19, 0x43, 0xe6,
+ 0x7e, 0xf1, 0xab, 0xe0, 0x0e, 0x83, 0x65, 0xf7, 0xaa, 0xac, 0x77, 0x64,
+ 0x9c, 0xc3, 0x7e, 0x4b, 0x2b, 0xaf, 0x81, 0x16, 0x93, 0x9e, 0x6d, 0x6e,
+ 0x0f, 0xc7, 0x96, 0xe4, 0xc5, 0xb3, 0xcd, 0x2e, 0xfa, 0x61, 0x63, 0x0b,
+ 0x2d, 0x37, 0xf8, 0x7d, 0x27, 0x2d, 0x35, 0x86, 0xae, 0x1e, 0x15, 0x03,
+ 0xb4, 0x7a, 0xe3, 0x4d, 0xe6, 0x57, 0x05, 0xf2, 0x82, 0xc9, 0x8f, 0xe9,
+ 0xbd, 0xd1, 0x5e, 0xfa, 0xe9, 0x3d, 0x76, 0xfd, 0x7e, 0x01, 0x1b, 0x18,
+ 0x4d, 0xb2, 0x6d, 0xa3, 0xcf, 0xf3, 0xf6, 0x55, 0x4b, 0xb0, 0x6e, 0xff,
+ 0x04, 0x3c, 0xb5, 0x8f, 0x29, 0x3b, 0x60, 0xdc, 0x8c, 0x17, 0xba, 0xe1,
+ 0xbc, 0x08, 0x9c, 0x78, 0xd7, 0x1c, 0x02, 0xae, 0x17, 0x25, 0x2f, 0x0e,
+ 0xb9, 0xf6, 0x55, 0x42, 0x0e, 0x79, 0xc5, 0x19, 0xca, 0x0a, 0xb1, 0x9d,
+ 0x1a, 0x99, 0x9b, 0xcc, 0xf3, 0xf0, 0xff, 0xa8, 0xab, 0x2a, 0x97, 0xa9,
+ 0x3e, 0x73, 0xc9, 0x61, 0xfd, 0x67, 0xbf, 0xf1, 0x12, 0xf2, 0x4e, 0x93,
+ 0x4e, 0x34, 0xd9, 0x5f, 0x32, 0x2e, 0xce, 0xfd, 0x77, 0x9b, 0x5f, 0x13,
+ 0x9c, 0x23, 0xe0, 0x1d, 0xe6, 0xf5, 0x2f, 0xb1, 0x9c, 0x3b, 0x18, 0x36,
+ 0x6b, 0x89, 0x60, 0x03, 0x8f, 0x86, 0xcc, 0x5d, 0x82, 0xf7, 0xfb, 0x6f,
+ 0xec, 0xfb, 0x2e, 0x68, 0x1d, 0x02, 0x2c, 0xe2, 0x65, 0xa6, 0x7d, 0x8f,
+ 0x57, 0xe4, 0x1e, 0xc7, 0x9b, 0xc8, 0xf3, 0xd6, 0xf6, 0xc0, 0x5c, 0x53,
+ 0xe0, 0x9c, 0x86, 0x94, 0xcb, 0x95, 0x51, 0xe6, 0xef, 0x6d, 0x7d, 0x9c,
+ 0x63, 0xea, 0xf9, 0xbf, 0x09, 0xa2, 0x5a, 0xf3, 0x95, 0xf9, 0x49, 0xf8,
+ 0xe7, 0x20, 0xa8, 0xee, 0x1e, 0x52, 0x71, 0x68, 0x90, 0xdf, 0x1f, 0x90,
+ 0xb2, 0xa8, 0x8a, 0x4e, 0xba, 0xc3, 0xb0, 0x00, 0xcb, 0x73, 0x2f, 0x87,
+ 0x72, 0x84, 0x11, 0x75, 0xa1, 0xdf, 0x8c, 0xf4, 0x32, 0x05, 0x1d, 0xdb,
+ 0x63, 0x1e, 0x0a, 0x63, 0x32, 0xc7, 0xb4, 0x9f, 0x42, 0xe7, 0xac, 0x14,
+ 0xeb, 0x4d, 0xaa, 0xef, 0x9a, 0xde, 0xf0, 0xbb, 0xfa, 0x8c, 0x07, 0xda,
+ 0x8a, 0x0b, 0x9d, 0x54, 0xaa, 0x27, 0x90, 0x03, 0x19, 0x34, 0x97, 0xc3,
+ 0x18, 0x3a, 0x54, 0x6a, 0xb0, 0xce, 0x57, 0x42, 0x9d, 0x4f, 0x86, 0xb8,
+ 0x4f, 0x82, 0x17, 0xb6, 0xb5, 0x2a, 0xb8, 0x76, 0xda, 0x26, 0xeb, 0x5f,
+ 0x1d, 0xb6, 0x5c, 0xae, 0x71, 0xed, 0x89, 0xfc, 0xdb, 0x3c, 0x37, 0x33,
+ 0xed, 0x18, 0xa0, 0x6b, 0x44, 0x2b, 0xb7, 0x1c, 0xad, 0xec, 0x33, 0x7d,
+ 0xbb, 0x41, 0xb7, 0x26, 0x6b, 0xdc, 0xa5, 0xd6, 0x7b, 0xc1, 0xd2, 0xee,
+ 0x4d, 0xe8, 0x43, 0xe7, 0x27, 0x58, 0xae, 0x5f, 0x60, 0xba, 0xac, 0x82,
+ 0x60, 0x3e, 0xa7, 0xe9, 0xd4, 0xf0, 0xdf, 0xf5, 0x72, 0x3e, 0x75, 0x7a,
+ 0x98, 0xf1, 0x83, 0x8e, 0x74, 0x9a, 0x96, 0x7d, 0xde, 0xa3, 0x3e, 0xc3,
+ 0x3c, 0x2c, 0x2f, 0x98, 0xf4, 0x88, 0x94, 0xdb, 0x6b, 0xd2, 0xa6, 0xcb,
+ 0x2b, 0xb0, 0xa5, 0xd4, 0x90, 0x79, 0x94, 0xec, 0xab, 0x17, 0x75, 0xbb,
+ 0x3e, 0x05, 0x7b, 0x5e, 0x5a, 0xd4, 0x69, 0xa7, 0xac, 0xb1, 0x58, 0x36,
+ 0xf6, 0x31, 0x58, 0x7c, 0x78, 0xf6, 0x43, 0x6d, 0x67, 0xef, 0xa1, 0x4b,
+ 0x4f, 0xff, 0x16, 0x7c, 0x0d, 0xf3, 0xd5, 0xb0, 0x0e, 0x23, 0x9f, 0x58,
+ 0x40, 0xee, 0x51, 0x45, 0x6e, 0x5c, 0xc8, 0x30, 0x6c, 0xc4, 0xef, 0xad,
+ 0x92, 0xff, 0x42, 0xf2, 0x7f, 0x07, 0x55, 0xa5, 0x0d, 0x65, 0xe4, 0x3b,
+ 0x01, 0x1c, 0xea, 0x1d, 0x8f, 0x91, 0x2b, 0xc9, 0x77, 0xf7, 0x2a, 0x38,
+ 0xf6, 0x11, 0x19, 0x7e, 0x77, 0x14, 0x7b, 0x32, 0x8f, 0xa3, 0xf9, 0x6e,
+ 0x52, 0x36, 0x14, 0xf1, 0x1d, 0x89, 0x44, 0x33, 0x4d, 0xbf, 0x8b, 0x9a,
+ 0x67, 0xb2, 0x39, 0x48, 0xa5, 0xa6, 0x05, 0x19, 0xcc, 0xf4, 0xf1, 0xd9,
+ 0x8a, 0x2b, 0x38, 0x8f, 0x60, 0x5a, 0xef, 0xa5, 0xc3, 0x7e, 0x44, 0x4f,
+ 0x32, 0xa4, 0x6f, 0x32, 0x1c, 0x27, 0x42, 0x1a, 0xda, 0xf1, 0x25, 0x81,
+ 0x0b, 0x31, 0x3e, 0xf7, 0x57, 0x21, 0x1e, 0xf6, 0x1f, 0xa0, 0x75, 0x32,
+ 0x43, 0x2b, 0x3e, 0xd3, 0xb1, 0x85, 0xaa, 0x69, 0xee, 0x1f, 0x80, 0x9e,
+ 0x31, 0x9e, 0x4d, 0x9c, 0xc7, 0xac, 0xe3, 0xf1, 0x91, 0x66, 0x05, 0x3c,
+ 0x66, 0xfe, 0xf2, 0xba, 0x24, 0x2d, 0x7d, 0x85, 0xe5, 0xb7, 0x07, 0xf9,
+ 0x3b, 0xeb, 0xc2, 0x96, 0x50, 0xaf, 0xd4, 0x9e, 0xa5, 0x85, 0x1e, 0xc8,
+ 0x8a, 0xf7, 0xed, 0xa2, 0xbb, 0x61, 0xef, 0xc5, 0x06, 0xef, 0x3f, 0x09,
+ 0x3d, 0x7a, 0x59, 0xee, 0x5f, 0x5a, 0x19, 0x08, 0xe1, 0x19, 0xb6, 0x67,
+ 0x03, 0x6c, 0x27, 0xed, 0xab, 0x9b, 0xd7, 0x81, 0xff, 0x7d, 0xc0, 0x0b,
+ 0x3a, 0x99, 0x63, 0x78, 0xc6, 0x83, 0x75, 0x8d, 0xf4, 0x67, 0xe0, 0x49,
+ 0xc9, 0x5a, 0xbe, 0xd8, 0xe8, 0xa4, 0x62, 0x3d, 0xc2, 0xc5, 0x78, 0x3e,
+ 0x46, 0xad, 0x7b, 0x9f, 0xc4, 0x35, 0x2d, 0x71, 0xe1, 0x7d, 0x83, 0x7d,
+ 0xcd, 0xad, 0x80, 0x47, 0xbd, 0xee, 0x80, 0xb6, 0x54, 0x37, 0x2d, 0xc9,
+ 0x7a, 0xbd, 0x4b, 0xf9, 0x98, 0xd4, 0x66, 0xbc, 0xdf, 0x02, 0x5b, 0xdf,
+ 0x83, 0x3c, 0xa6, 0x07, 0x73, 0xd6, 0x86, 0xb9, 0x8d, 0xf4, 0x27, 0x36,
+ 0xd0, 0xdf, 0x89, 0x75, 0xfd, 0xd8, 0x53, 0xad, 0x2b, 0x61, 0xdd, 0xec,
+ 0x02, 0x6c, 0x82, 0x73, 0xf3, 0x34, 0xc7, 0xe4, 0x1b, 0x25, 0x2d, 0xb3,
+ 0x2b, 0xef, 0xe1, 0x5c, 0x03, 0x80, 0x8d, 0xc6, 0x8a, 0x0f, 0x75, 0xe0,
+ 0xf9, 0x5e, 0x43, 0xde, 0x4b, 0x40, 0x06, 0x9b, 0x53, 0x7c, 0xf6, 0x6a,
+ 0xe3, 0xf3, 0x78, 0x76, 0x63, 0x1b, 0xbf, 0x98, 0x57, 0x4c, 0x2f, 0xd3,
+ 0x0a, 0x3d, 0x25, 0xd8, 0x9b, 0x8b, 0x9a, 0x2f, 0xa5, 0x53, 0x29, 0x87,
+ 0x78, 0xee, 0xf3, 0x5d, 0x2d, 0xdb, 0xe5, 0xa0, 0xaa, 0x0b, 0x1c, 0x8e,
+ 0xeb, 0x86, 0x3c, 0xfb, 0xe1, 0x15, 0xbe, 0xaf, 0xb5, 0x10, 0x4f, 0xed,
+ 0x2c, 0xe1, 0xec, 0x0f, 0xaf, 0x38, 0xf4, 0x68, 0x33, 0x4b, 0x47, 0x9b,
+ 0xb6, 0x79, 0x3f, 0x7c, 0x40, 0x79, 0xed, 0x1e, 0x77, 0x57, 0x8a, 0xfd,
+ 0x96, 0x81, 0x9c, 0xb3, 0xc3, 0x51, 0x39, 0x48, 0x95, 0xeb, 0xb1, 0x05,
+ 0x9b, 0xef, 0x68, 0xcc, 0x06, 0x6d, 0xcc, 0x53, 0xfe, 0x2f, 0x73, 0x14,
+ 0xde, 0x9f, 0xfd, 0x34, 0x72, 0x12, 0x1f, 0x39, 0x89, 0x8f, 0x9c, 0xc4,
+ 0x47, 0x4e, 0xe2, 0x23, 0x27, 0xf1, 0x91, 0x93, 0xf8, 0xc8, 0x49, 0x7c,
+ 0xe4, 0x24, 0xc8, 0xff, 0x55, 0x5d, 0x30, 0x8e, 0x5c, 0x1b, 0xfe, 0xcb,
+ 0xff, 0x6a, 0x98, 0x53, 0x44, 0x31, 0x99, 0xe7, 0x56, 0x37, 0x79, 0x6e,
+ 0x74, 0x4f, 0x7c, 0x00, 0x73, 0x13, 0x61, 0xee, 0xc3, 0x6b, 0xa2, 0x98,
+ 0xcd, 0xeb, 0x68, 0xcc, 0x43, 0xbd, 0x59, 0x98, 0xe4, 0xdc, 0x48, 0xc5,
+ 0x2a, 0x95, 0x97, 0xbf, 0x8a, 0xfc, 0xc8, 0x42, 0x7e, 0x34, 0x88, 0x5c,
+ 0x88, 0xef, 0xb5, 0xa3, 0xfb, 0xa3, 0x82, 0x76, 0xc8, 0x1f, 0xd7, 0xbe,
+ 0xe6, 0x73, 0xde, 0xee, 0x58, 0x65, 0x21, 0x16, 0xfa, 0x29, 0xa0, 0xe2,
+ 0xe8, 0xb7, 0x90, 0x23, 0x7f, 0x4f, 0xde, 0x95, 0x4d, 0x0c, 0xb3, 0xcc,
+ 0x27, 0x3e, 0x25, 0x4f, 0x8e, 0xf8, 0xab, 0xee, 0xf8, 0xc4, 0x12, 0xf3,
+ 0x8f, 0xa8, 0xef, 0x2c, 0x18, 0x7e, 0x36, 0x41, 0xa9, 0x53, 0x5b, 0x30,
+ 0x67, 0x52, 0xbf, 0xbc, 0x27, 0x82, 0x28, 0xcf, 0xfe, 0x1a, 0xf2, 0x72,
+ 0x48, 0x9c, 0xe5, 0xdb, 0x04, 0xc6, 0xcb, 0xfe, 0xb5, 0x32, 0x53, 0x6c,
+ 0x54, 0xa4, 0x4e, 0x1d, 0x6a, 0x96, 0x90, 0x3f, 0xf5, 0xf6, 0x53, 0x97,
+ 0x81, 0x1a, 0x2a, 0xc2, 0xcd, 0x38, 0x7f, 0x99, 0x92, 0xb5, 0xcd, 0xd9,
+ 0x35, 0x79, 0x42, 0xd6, 0xbc, 0x4f, 0x65, 0xa6, 0x5a, 0xb7, 0x33, 0x5c,
+ 0xd7, 0x82, 0xd6, 0x99, 0x27, 0x81, 0x63, 0x19, 0x39, 0x81, 0x2e, 0xf7,
+ 0xae, 0xcc, 0xcc, 0xd6, 0xd5, 0x5d, 0x95, 0xa2, 0x01, 0xf1, 0x2f, 0xd7,
+ 0x45, 0xfa, 0x92, 0xba, 0xb3, 0x12, 0x12, 0x96, 0xe1, 0x18, 0xde, 0x00,
+ 0x1c, 0xcb, 0x2d, 0x0b, 0x58, 0x96, 0x1d, 0xd3, 0x50, 0x99, 0xa9, 0x34,
+ 0xda, 0x69, 0x60, 0x3c, 0x8c, 0x37, 0x3a, 0x0f, 0x9f, 0x25, 0x45, 0xe2,
+ 0x54, 0x10, 0x94, 0x47, 0x07, 0xc3, 0x3a, 0x12, 0xf5, 0xe3, 0x09, 0x43,
+ 0xea, 0xb9, 0x1a, 0x7f, 0x53, 0xc6, 0x29, 0x4b, 0xf0, 0x3c, 0x3f, 0xf1,
+ 0x2e, 0xf7, 0x24, 0xe6, 0x30, 0x5e, 0x8e, 0xd6, 0x8a, 0x70, 0x6d, 0x77,
+ 0x1b, 0x3f, 0x3b, 0xc2, 0xfd, 0x98, 0x26, 0x3e, 0xe7, 0x65, 0xec, 0xc5,
+ 0x74, 0xf1, 0x1a, 0x13, 0xb4, 0x41, 0x96, 0xfe, 0xff, 0x96, 0xf7, 0xed,
+ 0x67, 0x62, 0x9e, 0x1a, 0x80, 0xe1, 0xf5, 0x8c, 0x23, 0x82, 0xc1, 0x8b,
+ 0xb3, 0x0a, 0x4e, 0xac, 0xdd, 0xed, 0x7d, 0xd6, 0xbe, 0xed, 0xb4, 0x46,
+ 0xfb, 0x47, 0x78, 0xb2, 0x4a, 0x6e, 0x6b, 0xf0, 0xf2, 0xff, 0x0a, 0xc3,
+ 0x13, 0xba, 0xf8, 0x89, 0x3b, 0xd2, 0x6c, 0x5b, 0x6d, 0x1c, 0xdd, 0x35,
+ 0x70, 0xcd, 0xcf, 0x35, 0x3c, 0x7f, 0x47, 0x68, 0xaf, 0x4b, 0x4b, 0x61,
+ 0x2c, 0x83, 0x2e, 0xaa, 0xbb, 0xd4, 0x70, 0x6c, 0x70, 0x6c, 0x43, 0xe3,
+ 0x1c, 0x3f, 0xb2, 0x91, 0xf6, 0x7b, 0x42, 0x95, 0x9b, 0x9c, 0x59, 0x8c,
+ 0x7c, 0x0e, 0xfc, 0xc1, 0xb0, 0x11, 0xfa, 0xed, 0x24, 0xfc, 0x56, 0x0f,
+ 0xed, 0x83, 0xbf, 0xb9, 0x13, 0xfe, 0x66, 0x3f, 0xea, 0xca, 0xf1, 0x95,
+ 0xf6, 0xfb, 0x57, 0xae, 0x65, 0xab, 0x74, 0x58, 0xca, 0xae, 0x12, 0xe8,
+ 0xce, 0xc7, 0x90, 0xdf, 0x2e, 0x99, 0xa3, 0x29, 0x79, 0xc2, 0x57, 0xba,
+ 0xfc, 0x2d, 0x62, 0xe3, 0x3d, 0x6f, 0x16, 0x7a, 0xdd, 0x55, 0x10, 0x32,
+ 0xff, 0x52, 0x7c, 0xab, 0x36, 0x14, 0xdf, 0xe0, 0x53, 0x81, 0xdf, 0xa0,
+ 0x4a, 0xd3, 0xa4, 0x0a, 0xf6, 0xad, 0x60, 0xdf, 0x0a, 0xea, 0xc1, 0xd9,
+ 0x66, 0xfb, 0x77, 0xaa, 0xee, 0xb0, 0xc6, 0x66, 0xd8, 0xa8, 0x6f, 0x86,
+ 0xe7, 0xd2, 0xda, 0x9e, 0xc7, 0xc0, 0xbb, 0x47, 0xc1, 0xbb, 0x23, 0xa8,
+ 0x83, 0xfe, 0x04, 0x75, 0xd0, 0x1f, 0xa2, 0x0e, 0x3a, 0x8c, 0x3a, 0x68,
+ 0x0a, 0x75, 0xd0, 0x7d, 0xb0, 0xfd, 0x7b, 0x61, 0xfb, 0x93, 0xb0, 0xfd,
+ 0x09, 0x79, 0xc7, 0x73, 0xc8, 0xdf, 0x78, 0xef, 0x11, 0xed, 0xc5, 0xed,
+ 0x4d, 0x22, 0x88, 0xaf, 0x7c, 0x62, 0x9c, 0x1a, 0x2d, 0xae, 0x87, 0x5c,
+ 0x79, 0x7f, 0x35, 0xed, 0x4e, 0x6a, 0x53, 0xc8, 0xb9, 0xef, 0x1f, 0xe1,
+ 0x3a, 0x29, 0xa5, 0xee, 0x2b, 0x73, 0xf6, 0x73, 0x1e, 0xd2, 0x2e, 0xe4,
+ 0x6d, 0x38, 0xb3, 0x7d, 0xa6, 0xa8, 0x47, 0x35, 0x4a, 0xdf, 0x5a, 0x8d,
+ 0xb2, 0x3c, 0xcf, 0x35, 0xca, 0xab, 0x6b, 0x35, 0xca, 0xf2, 0x3c, 0xd7,
+ 0x28, 0xaf, 0xac, 0xab, 0x51, 0xae, 0x3c, 0xfd, 0xf2, 0xba, 0x1a, 0xe5,
+ 0xca, 0xd3, 0x2f, 0x85, 0x63, 0xa6, 0x03, 0x7e, 0xc9, 0x0d, 0x69, 0x35,
+ 0x5d, 0x3c, 0x7b, 0xc3, 0x7c, 0xe1, 0xfb, 0xfd, 0xeb, 0xff, 0x1f, 0x3a,
+ 0x6e, 0x9d, 0x1a, 0x39, 0xdf, 0xd8, 0xaa, 0xea, 0x9a, 0xf6, 0xf9, 0xde,
+ 0xb6, 0xf9, 0x55, 0xf9, 0x6d, 0xb4, 0x5c, 0xdb, 0xfc, 0x3e, 0xbc, 0x27,
+ 0xad, 0x0c, 0xdb, 0xf5, 0x02, 0x7d, 0x1c, 0xf0, 0xf7, 0x3d, 0x4f, 0x74,
+ 0xc9, 0xef, 0x6a, 0x9e, 0xcc, 0x91, 0x61, 0xa3, 0xa3, 0x47, 0xb7, 0x2a,
+ 0x3b, 0xe6, 0x7e, 0x5a, 0x53, 0xbe, 0xf9, 0x41, 0xe0, 0x01, 0xaf, 0x7d,
+ 0x43, 0xde, 0xe1, 0xa8, 0xf3, 0xaa, 0xbb, 0x6c, 0x23, 0xbf, 0x8a, 0x38,
+ 0x03, 0x59, 0x4b, 0xdc, 0x5c, 0xf3, 0x71, 0x9d, 0x18, 0xf9, 0xef, 0x08,
+ 0xd7, 0xcf, 0xd2, 0x8a, 0xee, 0xdb, 0x50, 0xef, 0xf1, 0x9a, 0x68, 0xdc,
+ 0x5e, 0x1f, 0x26, 0xc3, 0xfb, 0xac, 0x55, 0x95, 0x13, 0x49, 0x7c, 0x46,
+ 0x88, 0xef, 0xbf, 0x02, 0xe5, 0x37, 0x18, 0xde, 0x6c, 0x83, 0x1f, 0x47,
+ 0x9e, 0xc6, 0x77, 0x2b, 0x9c, 0x6f, 0x19, 0xf4, 0xee, 0x7c, 0x37, 0xbd,
+ 0x73, 0x1c, 0xf9, 0xa6, 0x6b, 0x67, 0x5f, 0x46, 0xbd, 0x70, 0x8a, 0xf3,
+ 0xe2, 0x51, 0xa6, 0x73, 0xc8, 0x9a, 0x25, 0xab, 0x5f, 0xe5, 0xd1, 0x47,
+ 0xb4, 0x4f, 0xd2, 0x2d, 0xc2, 0x7d, 0x7e, 0xd6, 0xb6, 0x8f, 0xd5, 0xb6,
+ 0x4f, 0x81, 0xed, 0xad, 0xf1, 0x75, 0x9c, 0xb9, 0xb2, 0xfd, 0x26, 0x33,
+ 0x1d, 0xd6, 0x52, 0x8f, 0x8c, 0x6e, 0xa6, 0xfa, 0x80, 0x7d, 0xee, 0x15,
+ 0xe4, 0xda, 0xe5, 0x51, 0xcc, 0xa5, 0x87, 0xf0, 0x8e, 0xe7, 0xed, 0x06,
+ 0x09, 0xfb, 0x5c, 0x83, 0x90, 0x4c, 0x77, 0xd9, 0x15, 0xbe, 0x63, 0x4b,
+ 0x0b, 0xee, 0x4b, 0xda, 0x1a, 0xa1, 0xfd, 0x66, 0x2e, 0xe2, 0xcc, 0x53,
+ 0xa8, 0x99, 0x8e, 0xa8, 0xbb, 0xaf, 0x70, 0x9f, 0x5b, 0xb4, 0x8b, 0x32,
+ 0xaf, 0xcd, 0x69, 0x95, 0xb4, 0x3a, 0xe3, 0x37, 0x60, 0xeb, 0xba, 0x60,
+ 0xd8, 0x77, 0x81, 0x5b, 0xa3, 0xa5, 0xe3, 0xba, 0xbc, 0xeb, 0x2c, 0x8f,
+ 0xb2, 0xac, 0xf9, 0x79, 0x3d, 0xde, 0x45, 0x67, 0xfa, 0xdb, 0xf0, 0x4c,
+ 0x5f, 0x0a, 0x6b, 0xed, 0xe8, 0x4c, 0x09, 0x7a, 0x63, 0xde, 0x04, 0xec,
+ 0x08, 0xf8, 0x51, 0xa2, 0x95, 0x96, 0xf5, 0x39, 0x78, 0x6a, 0x6d, 0xbc,
+ 0x31, 0x36, 0xc8, 0x30, 0xaa, 0x59, 0xc0, 0x83, 0x89, 0x0c, 0xec, 0x70,
+ 0xba, 0x3f, 0xba, 0x83, 0xd5, 0x1d, 0xa1, 0xa9, 0xda, 0x9b, 0xe7, 0x07,
+ 0x61, 0x8b, 0x16, 0xec, 0x93, 0xf3, 0x9d, 0x12, 0xd7, 0x19, 0xe1, 0xf7,
+ 0x4b, 0xdb, 0x9c, 0xa4, 0x2c, 0x6a, 0x15, 0x3e, 0x7f, 0x9e, 0x96, 0x5b,
+ 0x11, 0x0d, 0x39, 0xd8, 0xe3, 0x18, 0x7e, 0x23, 0x78, 0xe7, 0xe2, 0xc7,
+ 0x75, 0x4e, 0x81, 0x1e, 0x93, 0x79, 0x34, 0xf2, 0xe4, 0x61, 0xa6, 0xef,
+ 0x00, 0xd6, 0xb3, 0x3e, 0xb3, 0x9e, 0x1e, 0x20, 0x6f, 0x80, 0x7d, 0x45,
+ 0x06, 0xb8, 0x01, 0xe3, 0xbf, 0x0e, 0x5b, 0x1f, 0xc4, 0xd3, 0x36, 0xcb,
+ 0xcc, 0x5b, 0x89, 0x3f, 0x08, 0xf4, 0x1c, 0x7f, 0x3b, 0x18, 0x0f, 0xc7,
+ 0x43, 0xe6, 0xdd, 0xac, 0x7b, 0x99, 0x1d, 0x74, 0x6e, 0x31, 0x8a, 0x61,
+ 0x33, 0xb0, 0x41, 0xbe, 0x53, 0x1d, 0x07, 0x5f, 0x78, 0xac, 0x85, 0xb1,
+ 0x0c, 0xf3, 0xcb, 0x0b, 0x38, 0x77, 0x9e, 0x4e, 0xa1, 0x66, 0xa7, 0x01,
+ 0x7e, 0x22, 0x57, 0xf5, 0xb7, 0x84, 0xfa, 0xbe, 0x1e, 0x5e, 0x77, 0xb8,
+ 0x3f, 0x0e, 0xfa, 0x8c, 0x36, 0x78, 0x86, 0x51, 0xb5, 0xc5, 0x45, 0x42,
+ 0x2c, 0xcd, 0x04, 0xb7, 0x8b, 0xfc, 0x7d, 0xf4, 0x80, 0x3c, 0x53, 0x9e,
+ 0x0e, 0x2f, 0x06, 0x81, 0x97, 0x1b, 0xca, 0x2e, 0x93, 0x9d, 0x7d, 0x92,
+ 0xf6, 0x98, 0xfb, 0x48, 0x97, 0xdf, 0xe0, 0x50, 0x13, 0xdf, 0xde, 0x91,
+ 0x0f, 0x82, 0x93, 0xa0, 0xfd, 0x05, 0xb9, 0xcf, 0x7d, 0xa0, 0x1f, 0xbc,
+ 0x92, 0xf5, 0x04, 0xd3, 0x0a, 0xde, 0xa4, 0x99, 0xde, 0x24, 0x1d, 0x6e,
+ 0x9d, 0x0f, 0x65, 0xf3, 0x28, 0x79, 0xfe, 0xdb, 0x3a, 0xdf, 0x47, 0x97,
+ 0x5b, 0x4f, 0x86, 0xb4, 0xe5, 0x41, 0x2f, 0xf6, 0x6f, 0xbd, 0x90, 0x66,
+ 0xdf, 0xc0, 0x32, 0xf7, 0x90, 0xf1, 0x79, 0xa3, 0xcf, 0x40, 0x07, 0x3f,
+ 0xcd, 0x0f, 0xa4, 0x68, 0xbd, 0x1f, 0x60, 0xb8, 0xd4, 0x75, 0x74, 0x85,
+ 0xe9, 0x20, 0xe9, 0x3f, 0x85, 0xb3, 0x19, 0xf4, 0x30, 0x3e, 0x7d, 0x83,
+ 0x2f, 0xa8, 0xc8, 0xe7, 0xaa, 0xce, 0xbe, 0x89, 0xe3, 0x14, 0xeb, 0x70,
+ 0x0f, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x5c, 0x5c, 0xe4, 0x3b, 0x85, 0x61,
+ 0xbe, 0x87, 0x3a, 0x53, 0x82, 0x6c, 0x97, 0xf8, 0xbb, 0x60, 0x5a, 0xe5,
+ 0x82, 0xaa, 0x76, 0xb2, 0xd8, 0x17, 0x32, 0xaf, 0xa5, 0x9f, 0x2c, 0xc9,
+ 0xef, 0x80, 0x29, 0xac, 0x09, 0xf0, 0x6c, 0xff, 0x9b, 0x88, 0x9f, 0x14,
+ 0xd4, 0xdf, 0x44, 0x84, 0xdf, 0x64, 0x1b, 0x2a, 0x07, 0x78, 0xb8, 0x69,
+ 0xd0, 0x54, 0x33, 0xfa, 0x1b, 0x09, 0x96, 0x83, 0x83, 0x3a, 0x3e, 0x8a,
+ 0xfb, 0x81, 0x8c, 0x2f, 0xd5, 0x75, 0xb2, 0xfc, 0x66, 0x98, 0xcf, 0x70,
+ 0xfe, 0xce, 0x3c, 0xc4, 0x78, 0x59, 0xc9, 0x6f, 0x49, 0xec, 0x84, 0xfc,
+ 0xc0, 0x73, 0xdf, 0x80, 0x2d, 0x65, 0xc2, 0x98, 0x6c, 0x72, 0x7d, 0x18,
+ 0xd6, 0xac, 0xdb, 0xa9, 0x3a, 0xc9, 0xef, 0x13, 0xf4, 0xfa, 0xfc, 0xa0,
+ 0x7c, 0x5f, 0xa6, 0x44, 0xf8, 0x9e, 0xc7, 0x29, 0x2a, 0xcb, 0xf7, 0xf7,
+ 0x86, 0xf8, 0x50, 0x63, 0xdd, 0x1b, 0x8d, 0x33, 0x90, 0xa3, 0x82, 0x9b,
+ 0x46, 0x2c, 0x7b, 0x0c, 0x71, 0x6c, 0x1a, 0x7c, 0x2f, 0x4e, 0x54, 0x68,
+ 0x87, 0xc3, 0x3a, 0x0e, 0x99, 0xa5, 0x58, 0xc7, 0x58, 0xbf, 0x18, 0xa6,
+ 0x17, 0x79, 0x26, 0xce, 0x3b, 0x4a, 0x53, 0x7a, 0xfe, 0xfd, 0x83, 0xe5,
+ 0x9a, 0x6d, 0x16, 0xe8, 0xa3, 0xc0, 0x33, 0x78, 0xbc, 0x7a, 0xf0, 0x61,
+ 0x75, 0x4f, 0x2f, 0x44, 0xfe, 0xd2, 0xc1, 0xb2, 0xea, 0xe3, 0xcc, 0xef,
+ 0x87, 0x7d, 0x86, 0xd3, 0xe5, 0xf7, 0xd3, 0x7f, 0xbf, 0xd5, 0xa0, 0x8b,
+ 0xb7, 0x06, 0xc1, 0xfd, 0xfc, 0x0d, 0x27, 0xac, 0x41, 0xd5, 0x77, 0x71,
+ 0x8e, 0x13, 0xa8, 0x37, 0x46, 0x2d, 0xad, 0x04, 0xdb, 0x3d, 0xe5, 0xa3,
+ 0x5e, 0x11, 0xf6, 0xd8, 0xaa, 0x30, 0x11, 0x7f, 0xb9, 0x96, 0xff, 0xcd,
+ 0x7e, 0xfe, 0x26, 0x3c, 0xe7, 0xf2, 0x9a, 0x6d, 0xea, 0xae, 0xea, 0xe6,
+ 0xdb, 0xa4, 0xcf, 0x25, 0x0a, 0xe3, 0xd0, 0xcd, 0xed, 0xf6, 0xd1, 0x9e,
+ 0x23, 0xb2, 0x5d, 0xd0, 0x94, 0x01, 0x7a, 0xaa, 0xb5, 0x28, 0xdf, 0xe2,
+ 0xef, 0xfd, 0xab, 0x07, 0xbf, 0xdb, 0xbc, 0x74, 0x70, 0x16, 0xf2, 0xe1,
+ 0x33, 0xcd, 0x36, 0x23, 0xfd, 0x8b, 0x72, 0x7e, 0xee, 0x23, 0xfe, 0xfb,
+ 0x88, 0xff, 0x3e, 0xe2, 0xbf, 0x8f, 0xf8, 0xef, 0x23, 0xfe, 0xfb, 0x88,
+ 0xff, 0xe0, 0xe1, 0x0f, 0xa0, 0x2f, 0xe7, 0xfd, 0x89, 0x30, 0xdf, 0x7a,
+ 0x7c, 0x2d, 0xdf, 0x3a, 0xd7, 0xe2, 0x6f, 0x3f, 0x92, 0x96, 0x4a, 0x85,
+ 0x54, 0xbe, 0x4a, 0x82, 0xf3, 0x9b, 0x28, 0x5f, 0xbd, 0xfe, 0x37, 0x0c,
+ 0x05, 0xc7, 0xb9, 0x1a, 0xc3, 0x55, 0x34, 0xe1, 0x30, 0x9c, 0xca, 0xd7,
+ 0xb8, 0x46, 0x5a, 0x0f, 0xc3, 0xdf, 0xc9, 0xd8, 0xb7, 0xa9, 0x6f, 0x34,
+ 0xea, 0x7b, 0xd0, 0xe3, 0x5f, 0xf7, 0x10, 0x8b, 0xcb, 0x4d, 0x19, 0x8f,
+ 0x31, 0x7e, 0x06, 0x63, 0x83, 0xf5, 0x8f, 0xdf, 0xdd, 0xc3, 0x75, 0x41,
+ 0xb9, 0x89, 0xbc, 0x68, 0x39, 0xca, 0x85, 0x00, 0xe7, 0xbf, 0xa9, 0x95,
+ 0xea, 0x2c, 0x67, 0x41, 0xb3, 0x69, 0x30, 0xc5, 0x69, 0xaf, 0x75, 0x5e,
+ 0x96, 0xb5, 0x8e, 0xfa, 0x9b, 0x9e, 0x11, 0xd0, 0x16, 0xdd, 0xfd, 0x12,
+ 0xe9, 0xf3, 0x69, 0xf9, 0x77, 0x00, 0x29, 0x67, 0x58, 0xfe, 0x3d, 0x42,
+ 0x1f, 0xf6, 0x11, 0xf3, 0x3b, 0xdb, 0xee, 0x56, 0xa9, 0xa0, 0x7c, 0x76,
+ 0xa7, 0xfa, 0x3b, 0x08, 0x91, 0x86, 0xed, 0xde, 0xb6, 0x0d, 0x67, 0x83,
+ 0x5c, 0x5f, 0xdd, 0x2a, 0xf3, 0x67, 0xf8, 0xd1, 0x93, 0xc3, 0x7d, 0x03,
+ 0xd4, 0xb3, 0x9d, 0x4e, 0x0d, 0x73, 0xad, 0xb5, 0x19, 0xf8, 0x78, 0xad,
+ 0x9d, 0x2d, 0x88, 0xed, 0x74, 0x7a, 0x11, 0x7e, 0x76, 0xd1, 0x76, 0x59,
+ 0x97, 0x97, 0x86, 0xd3, 0xf0, 0xcf, 0x63, 0x03, 0x1c, 0x9f, 0x97, 0x5b,
+ 0xac, 0x2b, 0x7d, 0x80, 0x1f, 0x84, 0x5e, 0x6e, 0x82, 0x3d, 0x09, 0xec,
+ 0x1f, 0xe1, 0xfe, 0xb9, 0xc4, 0xdd, 0xe7, 0xec, 0xd9, 0x26, 0x75, 0x43,
+ 0xd8, 0xa6, 0x25, 0x40, 0xfb, 0x27, 0x6a, 0x44, 0x97, 0xf8, 0x6c, 0xb3,
+ 0x7e, 0xfb, 0xb7, 0xba, 0x37, 0xb5, 0x72, 0x9d, 0xff, 0x0e, 0x61, 0x98,
+ 0xf6, 0x41, 0xbf, 0x4c, 0xe7, 0x4d, 0xed, 0x81, 0xc6, 0xff, 0x14, 0x6e,
+ 0x75, 0xb1, 0x71, 0x5c, 0x55, 0xf8, 0xdc, 0x59, 0xaf, 0xed, 0x38, 0x6b,
+ 0x67, 0xe2, 0x6c, 0xec, 0xb5, 0x15, 0xc4, 0xce, 0x7a, 0x12, 0x4f, 0xb5,
+ 0x8e, 0x3a, 0xb6, 0x12, 0xb4, 0x42, 0x96, 0x58, 0xed, 0x7a, 0x5d, 0x87,
+ 0x92, 0xb2, 0x85, 0x50, 0x05, 0x09, 0x55, 0x96, 0x9d, 0xd2, 0x54, 0x80,
+ 0x90, 0xfa, 0x80, 0x78, 0xcb, 0x6a, 0x6d, 0x87, 0xa4, 0xec, 0x76, 0x6d,
+ 0x62, 0xd7, 0x2f, 0x3c, 0x2c, 0xeb, 0x75, 0x6a, 0xbb, 0x9b, 0xac, 0x42,
+ 0xfb, 0x50, 0x9e, 0x62, 0x99, 0x92, 0xc2, 0x4b, 0x85, 0xc4, 0x03, 0x02,
+ 0x54, 0xa9, 0x4a, 0xda, 0x34, 0x0f, 0x25, 0x11, 0xbc, 0x50, 0x0a, 0xd2,
+ 0xf0, 0x7d, 0x77, 0x66, 0x1d, 0x27, 0x50, 0x61, 0x69, 0x35, 0x77, 0xee,
+ 0xdc, 0x3b, 0x73, 0x7f, 0xce, 0xf9, 0xce, 0x77, 0xce, 0x3d, 0x66, 0x1b,
+ 0x1b, 0x65, 0xfa, 0xd3, 0xab, 0x6a, 0xa6, 0xda, 0x2b, 0x0b, 0x90, 0xe3,
+ 0xe2, 0x48, 0x38, 0x88, 0x97, 0x76, 0x05, 0xfa, 0x0c, 0xc7, 0xdf, 0xb7,
+ 0x57, 0x9a, 0x57, 0x16, 0xcd, 0x4e, 0xcd, 0xab, 0x1e, 0x7d, 0x76, 0x0a,
+ 0x63, 0x8a, 0x61, 0x1d, 0xba, 0xfb, 0x34, 0x36, 0x19, 0xbc, 0xef, 0x7f,
+ 0xec, 0xbe, 0xef, 0xb1, 0xfb, 0xc3, 0xff, 0xa3, 0x3d, 0xcb, 0x8f, 0xcb,
+ 0x03, 0xc7, 0x69, 0xa5, 0xf8, 0x95, 0x62, 0xc9, 0x36, 0x66, 0x4b, 0x56,
+ 0x9a, 0xbc, 0x20, 0x2b, 0x9e, 0xca, 0xba, 0xed, 0xc0, 0xbb, 0x76, 0x99,
+ 0x5f, 0x86, 0xcc, 0x63, 0x1e, 0x1d, 0x36, 0xcf, 0xb4, 0x13, 0x7d, 0xd4,
+ 0x99, 0x4e, 0x6c, 0x83, 0x61, 0x0f, 0xc5, 0xd0, 0xce, 0x7b, 0xc9, 0x4d,
+ 0x9a, 0xe7, 0x74, 0x1c, 0x86, 0x7c, 0xc6, 0x53, 0x45, 0x9d, 0x9f, 0xc1,
+ 0x36, 0x6d, 0x72, 0xc7, 0xce, 0xf4, 0x06, 0xf9, 0x3e, 0xf0, 0x5b, 0xc7,
+ 0xfa, 0xc8, 0x35, 0x5e, 0x74, 0x77, 0xeb, 0xcc, 0xdb, 0xc2, 0x3c, 0x2a,
+ 0x08, 0xcd, 0xb3, 0x22, 0xd5, 0xba, 0xc8, 0xeb, 0xf8, 0xfd, 0xae, 0x1e,
+ 0xf8, 0x0a, 0x8a, 0x3e, 0xf3, 0xb8, 0x6c, 0x55, 0xbe, 0x2c, 0x0d, 0xd8,
+ 0x9f, 0x4d, 0xd7, 0xf3, 0xee, 0xb9, 0x71, 0xbd, 0xe6, 0x3f, 0x29, 0x29,
+ 0x49, 0x8c, 0xd2, 0xbe, 0xb5, 0xcb, 0x4f, 0x97, 0xdb, 0x64, 0xdb, 0xb4,
+ 0xcc, 0x7b, 0xc2, 0x5c, 0xb6, 0x98, 0x4c, 0x45, 0x43, 0x9a, 0xa3, 0xca,
+ 0xb7, 0xc0, 0xa0, 0xf1, 0xec, 0xee, 0xf2, 0x33, 0x7d, 0x8c, 0x9d, 0x7c,
+ 0xb4, 0xcc, 0x7b, 0x03, 0x57, 0x43, 0x76, 0xec, 0x10, 0xb8, 0x2c, 0x40,
+ 0xc8, 0xe4, 0xba, 0x73, 0xbe, 0xcf, 0x71, 0x6c, 0xa8, 0xa3, 0x2f, 0xda,
+ 0x2e, 0xc5, 0xa3, 0xc0, 0x44, 0x35, 0xa4, 0x73, 0x8a, 0x76, 0xa2, 0x1a,
+ 0xa3, 0x43, 0x35, 0xe6, 0xc8, 0x99, 0xfb, 0x35, 0x5e, 0x67, 0xae, 0x7d,
+ 0x5f, 0xcf, 0x05, 0xe5, 0x42, 0xcd, 0xa5, 0xac, 0x9a, 0xb2, 0x09, 0x5d,
+ 0xdb, 0x68, 0x2e, 0xf5, 0x73, 0xaf, 0xb6, 0x9a, 0x3f, 0xe8, 0xf3, 0x7d,
+ 0x2d, 0xd6, 0xfd, 0xb0, 0xcf, 0xaf, 0x8b, 0x07, 0xbe, 0x13, 0x7d, 0xac,
+ 0x2a, 0xe6, 0xf6, 0xb2, 0x34, 0x57, 0x7f, 0x2c, 0x6f, 0x57, 0x7e, 0x24,
+ 0xbf, 0x5a, 0x3d, 0x0b, 0xfe, 0x61, 0x55, 0x0b, 0xb0, 0x27, 0x37, 0x9a,
+ 0x9e, 0x77, 0xc3, 0x3d, 0x03, 0x5f, 0xc1, 0xf3, 0xfe, 0xe0, 0x6e, 0x4b,
+ 0x62, 0xec, 0x3b, 0x98, 0x73, 0x1e, 0x3a, 0x44, 0x2c, 0x9c, 0x82, 0xbc,
+ 0x25, 0xfb, 0xa5, 0x2b, 0xa2, 0xe5, 0x64, 0x68, 0x2c, 0x8c, 0x39, 0x18,
+ 0x01, 0x27, 0xe7, 0x5c, 0x46, 0xfa, 0x29, 0x33, 0x46, 0xf3, 0x15, 0x7c,
+ 0x3f, 0x0c, 0xbd, 0xd8, 0x8f, 0x9f, 0x92, 0x7b, 0xa3, 0x18, 0xeb, 0x28,
+ 0x65, 0x2f, 0x2c, 0x89, 0x27, 0x31, 0x8f, 0x7c, 0x9b, 0xdc, 0x2f, 0x5d,
+ 0xe9, 0x63, 0x5c, 0xee, 0x7e, 0x89, 0x65, 0xe3, 0x4b, 0x3d, 0xe2, 0x49,
+ 0x1b, 0x6c, 0xf9, 0xfc, 0x09, 0x9f, 0x37, 0xfd, 0x5a, 0x0d, 0xa3, 0xbd,
+ 0x5d, 0x78, 0x47, 0x91, 0xe7, 0x15, 0xbc, 0x30, 0x78, 0x79, 0x0e, 0x7c,
+ 0x28, 0xd3, 0xbc, 0x20, 0x3b, 0xa3, 0x11, 0xb4, 0x21, 0x5f, 0xd1, 0x58,
+ 0x22, 0xd9, 0x12, 0x73, 0xb0, 0x98, 0x0f, 0x85, 0x31, 0x9e, 0x21, 0x6e,
+ 0x70, 0x8c, 0xed, 0x3c, 0xb7, 0x0b, 0xea, 0x6c, 0xc8, 0x08, 0xeb, 0x28,
+ 0xdf, 0x69, 0xcd, 0xa9, 0x60, 0x43, 0xf1, 0xbe, 0x11, 0xc9, 0xe8, 0x72,
+ 0x0f, 0xde, 0x77, 0x41, 0xe7, 0x25, 0xfa, 0xef, 0x4c, 0xa1, 0x0d, 0x71,
+ 0x26, 0x05, 0x2e, 0xf1, 0xa1, 0x9a, 0x00, 0xbd, 0x99, 0x29, 0xf5, 0xc9,
+ 0x84, 0xb9, 0x6f, 0xcf, 0x1c, 0x0b, 0xda, 0x57, 0x30, 0x8c, 0x91, 0x60,
+ 0x4c, 0x3d, 0x7b, 0xc6, 0xc4, 0xfe, 0xf8, 0xc1, 0xc7, 0xcd, 0x2c, 0x2f,
+ 0x02, 0xa7, 0x16, 0x7f, 0x9b, 0x71, 0x9f, 0x97, 0x6c, 0xb4, 0x5d, 0xfb,
+ 0x36, 0x35, 0xec, 0x4b, 0xb6, 0xc4, 0x78, 0xd4, 0xb7, 0x81, 0x43, 0xfb,
+ 0x82, 0x3a, 0xb6, 0x15, 0x23, 0x83, 0xb5, 0x4f, 0x6b, 0x3d, 0x64, 0xdd,
+ 0x17, 0x25, 0xb3, 0x98, 0x97, 0x49, 0xdd, 0x8f, 0x6b, 0x38, 0xa8, 0x79,
+ 0x08, 0x75, 0x35, 0x71, 0x08, 0x6b, 0x99, 0x0c, 0x07, 0x6d, 0xf7, 0x91,
+ 0xc9, 0xe3, 0xef, 0xd3, 0x40, 0x67, 0xf1, 0xec, 0x10, 0xf7, 0xa8, 0x5d,
+ 0x12, 0xdf, 0x84, 0xbd, 0x2c, 0xb5, 0xea, 0x23, 0xf2, 0x49, 0xe9, 0xb3,
+ 0x3e, 0x9e, 0x93, 0xfc, 0xb5, 0x64, 0xca, 0x47, 0x25, 0x7d, 0x7e, 0x3a,
+ 0x1d, 0x12, 0xeb, 0xbc, 0xef, 0x67, 0x1f, 0x9d, 0x9e, 0x57, 0x7c, 0x7e,
+ 0xf4, 0xfc, 0xba, 0xea, 0x44, 0xdb, 0x08, 0xda, 0x71, 0x1c, 0xa6, 0xe4,
+ 0x4a, 0x7f, 0xf7, 0x66, 0x8e, 0x79, 0xde, 0xa4, 0xce, 0xe1, 0x4a, 0x9a,
+ 0xf3, 0xaa, 0xc5, 0xcf, 0x1d, 0x29, 0x45, 0x3b, 0xf0, 0xad, 0xa4, 0xb9,
+ 0xae, 0x8e, 0x62, 0x3c, 0x2c, 0x1f, 0xa2, 0x4e, 0xc4, 0xb6, 0x85, 0xef,
+ 0xb7, 0xa6, 0xd6, 0x54, 0x32, 0x3e, 0xa4, 0xac, 0x74, 0x11, 0xbf, 0x36,
+ 0xa5, 0xcf, 0x1e, 0x63, 0x71, 0x05, 0xdd, 0xc5, 0x9c, 0xec, 0xe3, 0x9e,
+ 0x37, 0x65, 0xb3, 0x3e, 0x69, 0x46, 0x14, 0xe3, 0x26, 0x5d, 0xfa, 0x8c,
+ 0xf2, 0xd2, 0xe1, 0xa4, 0x79, 0x5c, 0x1d, 0x0c, 0xee, 0x53, 0xc0, 0xcc,
+ 0xdd, 0xf7, 0x9d, 0x5d, 0x53, 0xa6, 0x5c, 0x2e, 0x25, 0xe3, 0xb3, 0xca,
+ 0xca, 0xe3, 0x9d, 0xf9, 0x09, 0x45, 0xdc, 0x48, 0x9a, 0x5d, 0x8a, 0xb1,
+ 0xcd, 0x0e, 0x3d, 0xef, 0x29, 0xf4, 0x4f, 0xaa, 0xb6, 0x60, 0x3c, 0xdc,
+ 0xaf, 0xcb, 0xfd, 0xbe, 0xce, 0x10, 0x73, 0x06, 0x8c, 0x99, 0x45, 0xe6,
+ 0x83, 0xe9, 0x3c, 0x84, 0x74, 0x62, 0x8c, 0xf7, 0x86, 0x3c, 0x38, 0xf9,
+ 0x0f, 0xd4, 0xa1, 0x5c, 0x65, 0x9d, 0x13, 0xe8, 0xdb, 0x31, 0xcd, 0x9f,
+ 0x1f, 0x9c, 0x2c, 0xe8, 0xfc, 0xc4, 0x1d, 0x95, 0x08, 0xe6, 0xbd, 0xbb,
+ 0x67, 0xf1, 0x8c, 0xfb, 0x05, 0xbe, 0x67, 0x31, 0x34, 0xde, 0x21, 0xcc,
+ 0x07, 0xcd, 0x55, 0x5a, 0xb2, 0xc1, 0xd8, 0x00, 0xcf, 0xf7, 0x5b, 0x67,
+ 0xe5, 0x17, 0xc4, 0x18, 0xeb, 0xdc, 0x23, 0x27, 0xe0, 0x9d, 0xe0, 0xab,
+ 0x75, 0xbc, 0xa7, 0xb8, 0x2c, 0x05, 0xbf, 0xbf, 0x74, 0x32, 0xff, 0xb4,
+ 0x58, 0xff, 0xbc, 0x77, 0xf8, 0x36, 0x30, 0x87, 0xfb, 0x07, 0x27, 0x29,
+ 0x9f, 0x5c, 0x9b, 0xb8, 0x9a, 0xbc, 0xc2, 0xf1, 0x0c, 0x4a, 0x6e, 0x19,
+ 0xdc, 0x08, 0xbf, 0xf9, 0x65, 0x7f, 0xdf, 0xd6, 0xc1, 0xb3, 0x73, 0x25,
+ 0x53, 0xeb, 0xeb, 0xac, 0xcb, 0xb3, 0x0f, 0xe8, 0x8a, 0xce, 0x7b, 0x62,
+ 0x5f, 0xe6, 0x0a, 0x1e, 0xa1, 0x7d, 0x74, 0x6a, 0x12, 0x45, 0x5b, 0x72,
+ 0x56, 0xd6, 0x83, 0xbf, 0xc3, 0x66, 0x16, 0x5f, 0x8d, 0x08, 0x30, 0x39,
+ 0x15, 0x0f, 0x1d, 0x90, 0x79, 0xd7, 0x95, 0x46, 0xf3, 0x84, 0x5c, 0x6b,
+ 0x3a, 0xfa, 0x19, 0xed, 0xd9, 0xc2, 0x6b, 0xfa, 0x5c, 0x3a, 0xfe, 0xa1,
+ 0xb2, 0x9c, 0xab, 0xf0, 0x6b, 0xbe, 0x7b, 0x8c, 0x79, 0xc2, 0xe1, 0x81,
+ 0x87, 0x79, 0x70, 0xc0, 0x0e, 0x70, 0x8e, 0xb7, 0xc0, 0x39, 0xde, 0x04,
+ 0xe7, 0xf8, 0x25, 0x38, 0xf6, 0x8d, 0xca, 0x54, 0x80, 0xff, 0xd3, 0xc0,
+ 0x21, 0xda, 0x6a, 0xeb, 0x2c, 0xf6, 0x74, 0xba, 0x00, 0x19, 0xfc, 0x00,
+ 0xfe, 0xc7, 0x56, 0x25, 0x23, 0x1b, 0xab, 0x93, 0xb2, 0xb9, 0xea, 0xe7,
+ 0x1c, 0xbf, 0xcb, 0x3c, 0xad, 0x51, 0xee, 0x93, 0x03, 0x1c, 0xda, 0x27,
+ 0x89, 0xe3, 0xc4, 0x8f, 0x4e, 0x59, 0x2b, 0xaf, 0x69, 0x1c, 0x5a, 0x2b,
+ 0xb3, 0x1c, 0x12, 0x9d, 0xf3, 0x75, 0x66, 0x5b, 0x6a, 0xee, 0x16, 0xea,
+ 0xbb, 0x99, 0xdb, 0x15, 0xc4, 0xd6, 0x89, 0x97, 0x7f, 0x0e, 0xf6, 0x5e,
+ 0xe9, 0x5c, 0xb8, 0x19, 0xf3, 0x00, 0xda, 0xb5, 0xb0, 0x6b, 0xc8, 0x3f,
+ 0x27, 0x57, 0x7f, 0x41, 0x1b, 0x7c, 0x03, 0x9c, 0xf1, 0x2a, 0x6c, 0xc8,
+ 0x8e, 0x73, 0x40, 0x73, 0xbf, 0x1d, 0xe7, 0x88, 0xce, 0xad, 0xe5, 0x7b,
+ 0x8a, 0x65, 0x5b, 0xe6, 0xca, 0x56, 0xbc, 0x00, 0xf9, 0xbb, 0x06, 0xbf,
+ 0x6d, 0x03, 0x7b, 0xb0, 0x89, 0xb5, 0xd8, 0x6a, 0xd2, 0xce, 0xbf, 0xaf,
+ 0xb1, 0x77, 0xad, 0xf9, 0x27, 0xbc, 0xc7, 0x3a, 0x9b, 0x96, 0x3f, 0xf6,
+ 0x13, 0x03, 0x99, 0x8f, 0x97, 0xd5, 0xfd, 0xfd, 0x7e, 0x1b, 0x68, 0xbb,
+ 0xd9, 0x24, 0x1e, 0x8b, 0x5c, 0x2c, 0xd9, 0xb0, 0x25, 0x17, 0x63, 0xe4,
+ 0x00, 0x55, 0xd5, 0xea, 0xe7, 0x05, 0x63, 0xf6, 0xbc, 0xfd, 0x36, 0xc7,
+ 0xe5, 0x04, 0xb8, 0x4d, 0xdb, 0xbf, 0xad, 0xb9, 0x4d, 0xa9, 0xf2, 0xbc,
+ 0x5c, 0x5f, 0x4d, 0x05, 0x1c, 0x27, 0x2f, 0x6f, 0x80, 0xe3, 0x35, 0x2b,
+ 0xad, 0x1c, 0xed, 0x71, 0xac, 0x53, 0x45, 0xcd, 0x2d, 0x75, 0xc9, 0xa5,
+ 0x95, 0xa2, 0xba, 0xbc, 0x52, 0x52, 0xaf, 0x2c, 0x95, 0x55, 0x71, 0xc9,
+ 0xf3, 0xfe, 0xe9, 0xce, 0xc8, 0xdb, 0xab, 0x9e, 0x9c, 0x76, 0x8d, 0x81,
+ 0x90, 0xb4, 0xf2, 0xdf, 0x3c, 0xaf, 0x13, 0xd8, 0xbc, 0x75, 0xd8, 0xf3,
+ 0x9e, 0x18, 0x1d, 0x15, 0xe7, 0x30, 0x39, 0xca, 0x70, 0x8c, 0x39, 0xac,
+ 0xc4, 0x9c, 0x8c, 0x6d, 0x9f, 0xaf, 0x29, 0x05, 0x7c, 0x3b, 0xe0, 0xf3,
+ 0x97, 0x27, 0xbb, 0x83, 0x33, 0x8f, 0xb3, 0x2f, 0x31, 0x26, 0x1c, 0xfb,
+ 0xaf, 0x98, 0xb0, 0x29, 0xe7, 0xca, 0x58, 0x88, 0xae, 0xa8, 0x7c, 0xaf,
+ 0x1c, 0x79, 0xac, 0x6c, 0xe2, 0xea, 0x18, 0xc5, 0xf2, 0x7d, 0x6f, 0x48,
+ 0xc7, 0xfe, 0xc1, 0x49, 0x4c, 0xcf, 0x9b, 0x75, 0xf9, 0xbd, 0x03, 0x8c,
+ 0xc9, 0x98, 0xdd, 0xb0, 0xff, 0xa7, 0xb5, 0x7d, 0xae, 0xaa, 0x8c, 0x4d,
+ 0xfd, 0x8e, 0xca, 0x44, 0x19, 0x36, 0x5e, 0x31, 0x2f, 0x94, 0x5c, 0xc1,
+ 0x8a, 0xcd, 0x02, 0x3b, 0x66, 0x80, 0x37, 0x4f, 0xeb, 0xb3, 0xd1, 0x43,
+ 0x1a, 0x7b, 0xe6, 0x58, 0xce, 0x4b, 0xba, 0xe6, 0xf6, 0xea, 0xf5, 0xbb,
+ 0x7d, 0xad, 0x18, 0xf3, 0xf7, 0x1c, 0x7a, 0x9c, 0xe7, 0xf9, 0x40, 0xaf,
+ 0x64, 0xd7, 0xcf, 0x40, 0x27, 0x62, 0x58, 0xdb, 0xb0, 0xd6, 0x87, 0x1d,
+ 0xd8, 0xef, 0x1d, 0x27, 0x1c, 0x60, 0x6a, 0x27, 0xee, 0xd9, 0x6e, 0x12,
+ 0xfd, 0x3a, 0x24, 0xb3, 0xd4, 0xae, 0x71, 0xf5, 0xd1, 0xba, 0x34, 0x78,
+ 0x48, 0x0e, 0xe5, 0x10, 0xea, 0xe2, 0x41, 0x99, 0xdc, 0x6b, 0x1a, 0xe5,
+ 0x36, 0x5c, 0xd9, 0xe6, 0x28, 0x78, 0x05, 0xae, 0xbf, 0xc0, 0xfb, 0x46,
+ 0x31, 0xe6, 0xbc, 0x29, 0xef, 0x9d, 0xa4, 0x2d, 0x71, 0x0c, 0xe6, 0x1a,
+ 0xcf, 0xda, 0xb8, 0x36, 0xca, 0x2a, 0xbb, 0xc8, 0x32, 0xae, 0x55, 0xff,
+ 0xf9, 0x23, 0x98, 0x84, 0x3e, 0x99, 0x15, 0x1f, 0x93, 0xde, 0xdb, 0xc5,
+ 0x24, 0xd6, 0x75, 0xc8, 0xc4, 0x52, 0x5c, 0x9d, 0xba, 0x62, 0x42, 0xde,
+ 0xba, 0x24, 0xbb, 0x12, 0xd5, 0x7c, 0xb4, 0x06, 0x59, 0x5c, 0x87, 0x5c,
+ 0xad, 0x41, 0xa6, 0x32, 0x65, 0x2b, 0x35, 0xad, 0xe2, 0x3a, 0x2e, 0x30,
+ 0x05, 0x79, 0x0d, 0xbf, 0x4a, 0x2e, 0x4a, 0xfd, 0x75, 0xd0, 0x46, 0x68,
+ 0x47, 0xd3, 0x61, 0x65, 0x43, 0x0e, 0x21, 0x97, 0x65, 0x5f, 0x7f, 0xdf,
+ 0x51, 0x1a, 0x57, 0x53, 0x77, 0x24, 0xe9, 0xdc, 0x11, 0xcb, 0xdd, 0xc1,
+ 0xef, 0x37, 0xe2, 0xca, 0x55, 0xe8, 0xfb, 0xeb, 0xf8, 0x4e, 0xf8, 0x35,
+ 0x43, 0x8e, 0x0d, 0x6b, 0x9d, 0x4e, 0x49, 0xc8, 0x72, 0x36, 0xc5, 0xd7,
+ 0xf1, 0x75, 0xad, 0xe3, 0x90, 0x37, 0x60, 0x90, 0xaf, 0xd3, 0xe9, 0x40,
+ 0x46, 0xbf, 0x01, 0xfd, 0xb5, 0xe0, 0x95, 0xc5, 0x65, 0x1e, 0xfa, 0x7f,
+ 0x15, 0xcf, 0x6f, 0x36, 0x3f, 0x56, 0x73, 0x8b, 0x2a, 0xc8, 0x3f, 0x79,
+ 0x0e, 0x3c, 0xf9, 0xf7, 0x58, 0xbb, 0x1e, 0xcd, 0xdd, 0x13, 0xa3, 0x3c,
+ 0x07, 0xfb, 0xb7, 0xba, 0x64, 0x1f, 0x97, 0xdb, 0x23, 0x27, 0x50, 0xee,
+ 0xc6, 0xd5, 0xc0, 0x3a, 0x44, 0xf4, 0xf9, 0xf5, 0x5a, 0x69, 0xc4, 0x28,
+ 0xea, 0x33, 0xe6, 0x31, 0xf4, 0x25, 0x96, 0x1d, 0xc6, 0x73, 0xc6, 0x65,
+ 0x38, 0x37, 0x70, 0x26, 0x15, 0xd3, 0x39, 0xa1, 0x35, 0x70, 0x89, 0x75,
+ 0xbc, 0xef, 0x16, 0xe3, 0x7a, 0x0d, 0xe8, 0xf0, 0xc8, 0x67, 0x5e, 0x3a,
+ 0xca, 0xbc, 0xf3, 0xf7, 0x63, 0xbe, 0xfd, 0xfb, 0xc4, 0xbb, 0x6d, 0xcf,
+ 0xa5, 0x0c, 0xdc, 0x7c, 0x60, 0x02, 0xef, 0xc8, 0xdb, 0x61, 0x8b, 0xaa,
+ 0x5a, 0x7e, 0xd9, 0xce, 0xef, 0x5b, 0x6c, 0x24, 0xcd, 0x77, 0xc5, 0xef,
+ 0x3b, 0x6f, 0xd3, 0xee, 0x74, 0x00, 0x5f, 0xe2, 0x9a, 0x57, 0xde, 0xb2,
+ 0x0b, 0x40, 0x05, 0x2b, 0x3e, 0x05, 0x19, 0x6d, 0x17, 0xcb, 0xc9, 0xc9,
+ 0xc3, 0xef, 0xce, 0xea, 0xbe, 0x6c, 0xdb, 0xea, 0xdb, 0xfa, 0x2e, 0xc7,
+ 0xcf, 0xb9, 0x70, 0x0e, 0xf0, 0x6d, 0x4c, 0x53, 0xcb, 0xe8, 0x4e, 0xc3,
+ 0x18, 0xf0, 0x65, 0xb4, 0x35, 0x8f, 0xe8, 0xff, 0x99, 0x07, 0xe5, 0x64,
+ 0xc4, 0xf0, 0xcf, 0xdb, 0x71, 0x6d, 0x70, 0x3d, 0x3f, 0x06, 0xbf, 0xdf,
+ 0x2b, 0x3f, 0xad, 0x38, 0xa3, 0x2f, 0x3f, 0x4f, 0xec, 0xca, 0x0f, 0x7d,
+ 0xd4, 0x2e, 0xc9, 0xad, 0xd8, 0x32, 0x59, 0xd6, 0xfb, 0x0d, 0xae, 0xc9,
+ 0xf8, 0xd1, 0x09, 0xc8, 0x0d, 0x65, 0x9d, 0xba, 0x65, 0x4a, 0x15, 0x72,
+ 0x54, 0x05, 0x3e, 0x55, 0x21, 0x53, 0xe4, 0x40, 0x55, 0xe0, 0x5b, 0xb5,
+ 0x69, 0x39, 0x75, 0xcc, 0x99, 0x36, 0x7b, 0x1d, 0x72, 0x74, 0xb5, 0xc9,
+ 0xfd, 0xd7, 0x63, 0x36, 0x69, 0x07, 0x6f, 0xee, 0xee, 0xfd, 0xa7, 0xd8,
+ 0xfb, 0x23, 0x72, 0x0d, 0x7e, 0xcb, 0xf5, 0xca, 0x08, 0x30, 0x49, 0x80,
+ 0x51, 0x2e, 0x64, 0x23, 0x25, 0x1b, 0x95, 0x71, 0xd9, 0x84, 0x7d, 0xda,
+ 0x5a, 0x4d, 0x80, 0x4f, 0x03, 0x47, 0xaf, 0x1c, 0x93, 0x37, 0x56, 0x95,
+ 0xcc, 0xd8, 0xb0, 0x33, 0x6b, 0x8c, 0xc1, 0x43, 0x9e, 0xab, 0x5d, 0xfa,
+ 0xbc, 0x7d, 0xa2, 0xee, 0xc7, 0xe2, 0x73, 0xf5, 0x1e, 0x99, 0xac, 0x9b,
+ 0xf2, 0x54, 0xbd, 0x57, 0xbe, 0x5a, 0x8f, 0xca, 0xe9, 0x46, 0x4c, 0xbe,
+ 0x56, 0x1f, 0x94, 0xa7, 0xeb, 0x47, 0xe4, 0x99, 0x46, 0x5c, 0xbe, 0x0e,
+ 0xbf, 0x30, 0xdf, 0x70, 0x64, 0xaa, 0x31, 0x22, 0xa7, 0x1a, 0x8c, 0xb1,
+ 0xe3, 0x7b, 0xf8, 0x65, 0x77, 0x63, 0x17, 0x1c, 0x57, 0x27, 0xc6, 0xe5,
+ 0xa8, 0x9c, 0x3e, 0x6f, 0x94, 0xbc, 0x1f, 0xff, 0x10, 0x79, 0x01, 0x7d,
+ 0x17, 0xae, 0x28, 0xa9, 0xe9, 0xef, 0xb7, 0xfe, 0x47, 0x24, 0xa2, 0x7d,
+ 0xa3, 0x17, 0xaa, 0x83, 0x68, 0x63, 0xd3, 0x27, 0x09, 0xe2, 0x20, 0xad,
+ 0xf8, 0x7f, 0xcb, 0xf7, 0x32, 0x74, 0x0c, 0xfb, 0x26, 0x7d, 0x2f, 0xbd,
+ 0xf6, 0xc4, 0x0f, 0xfa, 0x39, 0xf4, 0xb5, 0xf6, 0x9e, 0x51, 0xb4, 0xbe,
+ 0xbb, 0x90, 0x7f, 0xf4, 0x7f, 0x51, 0xfc, 0xb3, 0xa6, 0x73, 0x8d, 0x41,
+ 0xfe, 0x4f, 0x0a, 0xc6, 0xf2, 0xf9, 0xf9, 0xdd, 0x93, 0x95, 0x09, 0xf5,
+ 0x54, 0x85, 0x8c, 0xc6, 0x93, 0x85, 0xdd, 0x3c, 0xba, 0xaf, 0xc8, 0x9a,
+ 0x1b, 0xd1, 0x63, 0xf0, 0xe3, 0xf6, 0x69, 0x9d, 0x53, 0x37, 0x31, 0x4c,
+ 0xf9, 0xe3, 0x19, 0x5a, 0x4f, 0x70, 0xb6, 0x00, 0x6e, 0xeb, 0x9a, 0x72,
+ 0xb1, 0xee, 0xc7, 0xaf, 0xe6, 0xb4, 0xbc, 0x5c, 0x87, 0xcc, 0xf1, 0xfc,
+ 0xc1, 0xbf, 0x16, 0xaa, 0x7e, 0xdf, 0xec, 0xb0, 0x43, 0x7f, 0x1c, 0xf3,
+ 0x35, 0x7a, 0xf9, 0x2d, 0xfe, 0x4f, 0x0e, 0xca, 0xc1, 0x78, 0x99, 0x0f,
+ 0x6c, 0x6b, 0x59, 0xf4, 0xcf, 0x67, 0x1d, 0x79, 0x11, 0x7b, 0x51, 0x33,
+ 0x39, 0xfe, 0x4e, 0xa9, 0x39, 0xf4, 0x6d, 0x89, 0xdf, 0xc3, 0x52, 0xc5,
+ 0x77, 0x6a, 0x4e, 0x2b, 0x36, 0xe6, 0xe3, 0x6c, 0xcd, 0x7c, 0xf8, 0xdd,
+ 0xe9, 0xea, 0x41, 0xdc, 0xa3, 0xce, 0x01, 0x67, 0x3a, 0xc3, 0xfb, 0x05,
+ 0x94, 0x19, 0x1b, 0x99, 0xc3, 0x35, 0x16, 0xd4, 0xfd, 0x7c, 0x40, 0x73,
+ 0xf5, 0xf1, 0x87, 0xfd, 0x66, 0xaa, 0x56, 0x21, 0x13, 0xba, 0xab, 0x8c,
+ 0x9f, 0xad, 0x0f, 0x10, 0x73, 0x0f, 0xda, 0xfc, 0x45, 0xe4, 0x6f, 0xa6,
+ 0x8e, 0x29, 0x04, 0xcf, 0xf6, 0xc9, 0xb3, 0x26, 0x73, 0xcd, 0xd3, 0x6a,
+ 0xa2, 0xf2, 0x72, 0x90, 0x57, 0x7b, 0x57, 0x1d, 0xac, 0x35, 0x07, 0xfc,
+ 0xbc, 0x74, 0xbe, 0x7b, 0x6f, 0x2e, 0xfa, 0x5e, 0x39, 0x61, 0x4e, 0x7a,
+ 0x07, 0x78, 0xab, 0x36, 0x62, 0xd0, 0x41, 0xe0, 0x9d, 0xdd, 0xa6, 0xf5,
+ 0xb1, 0xd8, 0xf8, 0x97, 0xb7, 0xad, 0xf5, 0xb9, 0x15, 0x63, 0xb8, 0x35,
+ 0x40, 0xdf, 0x96, 0xb8, 0x71, 0xd1, 0x8f, 0x1b, 0x69, 0x1f, 0x1a, 0x58,
+ 0x81, 0x3a, 0xea, 0x2a, 0xf4, 0x64, 0xb7, 0x2d, 0xff, 0xfe, 0x03, 0x7d,
+ 0xe7, 0x95, 0xf0, 0x2c, 0x67, 0x00, 0x00, 0x00 };
static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = {
- 0x0800468c, 0x0800458c, 0x08004630, 0x08004648, 0x08004660, 0x08004680,
- 0x0800468c, 0x0800468c, 0x08004594, 0x00000000, 0x00000000 };
-static u32 bnx2_RXP_b06FwBss[(0x13a4/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwRodata[(0x278/4) + 1] = {
+ 0x08003fdc, 0x08003edc, 0x08003f80, 0x08003f98, 0x08003fb0, 0x08003fd0,
+ 0x08003fdc, 0x08003fdc, 0x08003ee4, 0x00000000, 0x08004a04, 0x08004a3c,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004a74, 0x08004c38,
+ 0x08004b80, 0x08004bb8, 0x08004c38, 0x08004b08, 0x08004c38, 0x08004c38,
+ 0x08004bb8, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004bf8,
+ 0x08004c38, 0x08004bf8, 0x08004b80, 0x08004c38, 0x08004c38, 0x08004bf8,
+ 0x08004bf8, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
+ 0x08004ae4, 0x00000000, 0x08006018, 0x08006030, 0x08006030, 0x08006030,
+ 0x08006018, 0x08006030, 0x08006030, 0x08006030, 0x08006018, 0x08006030,
+ 0x08006030, 0x08006030, 0x08006018, 0x08006030, 0x08006030, 0x08006030,
+ 0x08006024, 0x00000000, 0x00000000 };
+
+static u32 bnx2_RXP_b06FwBss[(0x13dc/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwSbss[(0x2c/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_rxp_fw_06 = {
+ .ver_major = 0x2,
+ .ver_minor = 0x8,
+ .ver_fix = 0x17,
+
+ .start_addr = 0x08003184,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x6728,
+ .text_index = 0x0,
+ .gz_text = bnx2_RXP_b06FwText,
+ .gz_text_len = sizeof(bnx2_RXP_b06FwText),
+
+ .data_addr = 0x080069c0,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_RXP_b06FwData,
+
+ .sbss_addr = 0x080069c0,
+ .sbss_len = 0x2c,
+ .sbss_index = 0x0,
+ .sbss = bnx2_RXP_b06FwSbss,
+
+ .bss_addr = 0x080069f0,
+ .bss_len = 0x13dc,
+ .bss_index = 0x0,
+ .bss = bnx2_RXP_b06FwBss,
+
+ .rodata_addr = 0x08006728,
+ .rodata_len = 0x278,
+ .rodata_index = 0x0,
+ .rodata = bnx2_RXP_b06FwRodata,
+};
static u8 bnx2_rv2p_proc1[] = {
0x1f, 0x8b, 0x08, 0x08, 0x5e, 0xd0, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
@@ -1316,20 +1665,6 @@ static u8 bnx2_rv2p_proc2[] = {
0x63, 0xd6, 0x11, 0x8f, 0x47, 0xd5, 0x5f, 0x3f, 0x97, 0x8f, 0x31, 0xd8,
0x17, 0x00, 0x00, 0x00 };
-static const int bnx2_TPAT_b06FwReleaseMajor = 0x1;
-static const int bnx2_TPAT_b06FwReleaseMinor = 0x0;
-static const int bnx2_TPAT_b06FwReleaseFix = 0x0;
-static const u32 bnx2_TPAT_b06FwStartAddr = 0x08000860;
-static const u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
-static const int bnx2_TPAT_b06FwTextLen = 0x122c;
-static const u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60;
-static const int bnx2_TPAT_b06FwDataLen = 0x0;
-static const u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
-static const int bnx2_TPAT_b06FwRodataLen = 0x0;
-static const u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0;
-static const int bnx2_TPAT_b06FwBssLen = 0x250;
-static const u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60;
-static const int bnx2_TPAT_b06FwSbssLen = 0x34;
static u8 bnx2_TPAT_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0x47, 0xd2, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x57, 0x4d, 0x68,
@@ -1529,20 +1864,40 @@ static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 };
static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 };
-static const int bnx2_TXP_b06FwReleaseMajor = 0x1;
-static const int bnx2_TXP_b06FwReleaseMinor = 0x0;
-static const int bnx2_TXP_b06FwReleaseFix = 0x0;
-static const u32 bnx2_TXP_b06FwStartAddr = 0x080034b0;
-static const u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
-static const int bnx2_TXP_b06FwTextLen = 0x5748;
-static const u32 bnx2_TXP_b06FwDataAddr = 0x08005760;
-static const int bnx2_TXP_b06FwDataLen = 0x0;
-static const u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
-static const int bnx2_TXP_b06FwRodataLen = 0x0;
-static const u32 bnx2_TXP_b06FwBssAddr = 0x080057a0;
-static const int bnx2_TXP_b06FwBssLen = 0x1c4;
-static const u32 bnx2_TXP_b06FwSbssAddr = 0x08005760;
-static const int bnx2_TXP_b06FwSbssLen = 0x38;
+static struct fw_info bnx2_tpat_fw_06 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x08000860,
+
+ .text_addr = 0x08000800,
+ .text_len = 0x122c,
+ .text_index = 0x0,
+ .gz_text = bnx2_TPAT_b06FwText,
+ .gz_text_len = sizeof(bnx2_TPAT_b06FwText),
+
+ .data_addr = 0x08001a60,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_TPAT_b06FwData,
+
+ .sbss_addr = 0x08001a60,
+ .sbss_len = 0x34,
+ .sbss_index = 0x0,
+ .sbss = bnx2_TPAT_b06FwSbss,
+
+ .bss_addr = 0x08001aa0,
+ .bss_len = 0x250,
+ .bss_index = 0x0,
+ .bss = bnx2_TPAT_b06FwBss,
+
+ .rodata_addr = 0x00000000,
+ .rodata_len = 0x0,
+ .rodata_index = 0x0,
+ .rodata = bnx2_TPAT_b06FwRodata,
+};
+
static u8 bnx2_TXP_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0x21, 0xd3, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xed, 0x5c, 0x6d, 0x6c,
@@ -1964,3 +2319,38 @@ static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_txp_fw_06 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x080034b0,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x5748,
+ .text_index = 0x0,
+ .gz_text = bnx2_TXP_b06FwText,
+ .gz_text_len = sizeof(bnx2_TXP_b06FwText),
+
+ .data_addr = 0x08005760,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_TXP_b06FwData,
+
+ .sbss_addr = 0x08005760,
+ .sbss_len = 0x38,
+ .sbss_index = 0x0,
+ .sbss = bnx2_TXP_b06FwSbss,
+
+ .bss_addr = 0x080057a0,
+ .bss_len = 0x1c4,
+ .bss_index = 0x0,
+ .bss = bnx2_TXP_b06FwBss,
+
+ .rodata_addr = 0x00000000,
+ .rodata_len = 0x0,
+ .rodata_index = 0x0,
+ .rodata = bnx2_TXP_b06FwRodata,
+};
+
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
new file mode 100644
index 000000000000..680c769a3fc0
--- /dev/null
+++ b/drivers/net/bnx2_fw2.h
@@ -0,0 +1,4086 @@
+/* bnx2_fw2.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2006 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, except as noted below.
+ *
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2006 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
+
+static u8 bnx2_COM_b09FwText[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0xac, 0xfb, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xdc, 0x5b, 0x6b, 0x70,
+ 0x1b, 0xd7, 0x75, 0x3e, 0xfb, 0x00, 0x09, 0x91, 0x10, 0xb5, 0xa4, 0x60,
+ 0x1a, 0x96, 0x68, 0x07, 0x20, 0x57, 0x22, 0x6a, 0xb1, 0x29, 0x4c, 0x33,
+ 0x16, 0x9b, 0xc2, 0x12, 0x02, 0x50, 0xae, 0x26, 0xc3, 0x3a, 0x94, 0xcd,
+ 0xd8, 0x4a, 0xaa, 0xc9, 0x30, 0x00, 0xa5, 0xf4, 0x61, 0xb7, 0x92, 0xab,
+ 0xa9, 0x5d, 0xd7, 0xaa, 0x21, 0x92, 0x6a, 0xf5, 0x83, 0xe5, 0x2a, 0x16,
+ 0x43, 0xa9, 0xd3, 0x74, 0xc2, 0x12, 0x56, 0xac, 0x4e, 0x31, 0x85, 0xfc,
+ 0xd6, 0x38, 0xb1, 0xc9, 0x4a, 0x76, 0xeb, 0xf4, 0xe1, 0xa6, 0x33, 0xcd,
+ 0xa3, 0x9d, 0x36, 0xf6, 0xa8, 0x3f, 0xea, 0xe9, 0xd3, 0x33, 0x6e, 0xa7,
+ 0xea, 0xd8, 0x0e, 0xfa, 0x7d, 0x77, 0x77, 0x81, 0x25, 0x48, 0xbd, 0xfc,
+ 0xc8, 0x8f, 0x70, 0x06, 0xb3, 0x7b, 0xef, 0xde, 0xbd, 0xf7, 0xdc, 0xf3,
+ 0xf8, 0xce, 0x63, 0x2f, 0xfb, 0x44, 0x5a, 0xc4, 0xfb, 0x5b, 0x8b, 0x5f,
+ 0xfc, 0xfe, 0x5f, 0x2d, 0x7c, 0x7c, 0xf0, 0xe3, 0xfd, 0x22, 0xb7, 0xdc,
+ 0xa2, 0xb7, 0x86, 0x75, 0xf6, 0x1b, 0xf8, 0x45, 0xf1, 0xeb, 0xf7, 0xee,
+ 0x57, 0xfb, 0xb3, 0xf0, 0x7b, 0x13, 0x0f, 0xc7, 0xfe, 0x55, 0x44, 0xbb,
+ 0xc4, 0x98, 0xe0, 0x5f, 0xb5, 0x7a, 0xf9, 0xe7, 0x5c, 0x38, 0x7e, 0x89,
+ 0x67, 0x86, 0xbb, 0x9c, 0xa2, 0x97, 0x3f, 0x09, 0xeb, 0x69, 0x39, 0x94,
+ 0xb5, 0x25, 0x6c, 0xa4, 0xdf, 0x3c, 0x54, 0xb0, 0x45, 0x32, 0xe5, 0x2d,
+ 0xf1, 0x9c, 0xbc, 0x57, 0x2d, 0x46, 0x4d, 0x61, 0xff, 0x8d, 0xe9, 0x77,
+ 0xbf, 0xf6, 0xe2, 0xd6, 0xc4, 0x5b, 0xf3, 0x86, 0x84, 0xad, 0xf4, 0x19,
+ 0xb1, 0x36, 0x4b, 0xb8, 0x0b, 0xef, 0x7c, 0xb5, 0xf7, 0x3d, 0x91, 0x36,
+ 0x7f, 0xae, 0x37, 0xab, 0x2f, 0xf6, 0x4a, 0x71, 0x43, 0x3a, 0x2c, 0x7a,
+ 0x7a, 0xd3, 0xf7, 0xb3, 0x86, 0x35, 0x66, 0xa4, 0x2d, 0x59, 0xac, 0xc8,
+ 0xc8, 0xde, 0x69, 0x09, 0x87, 0xd3, 0x47, 0x9b, 0x9b, 0x37, 0x49, 0xd8,
+ 0x4c, 0x8f, 0x1d, 0xfa, 0x6d, 0xfb, 0xd1, 0xaa, 0x6e, 0xdb, 0xc9, 0x05,
+ 0x89, 0x0c, 0x9e, 0x1a, 0xc0, 0xf3, 0x72, 0x22, 0x29, 0xb2, 0x55, 0x74,
+ 0xbb, 0x18, 0x31, 0xec, 0xb0, 0x64, 0x2b, 0xb6, 0xe4, 0x2a, 0x22, 0x7f,
+ 0x5e, 0xd6, 0xe4, 0x94, 0xdd, 0x29, 0x0b, 0x7d, 0xef, 0x56, 0x33, 0xa0,
+ 0xe5, 0xcf, 0xec, 0xb1, 0x43, 0x53, 0x36, 0xe9, 0x9d, 0x6d, 0x76, 0xe9,
+ 0x9d, 0x6a, 0x2a, 0xd8, 0xa6, 0x4c, 0x94, 0xd9, 0x37, 0xa2, 0xb3, 0x2f,
+ 0x94, 0x7e, 0x68, 0xcd, 0x29, 0x3b, 0xe2, 0xf5, 0xed, 0xdc, 0x9e, 0xc5,
+ 0x7c, 0x93, 0x65, 0x8e, 0x3d, 0x93, 0x2a, 0xd8, 0x51, 0xaf, 0x3f, 0x79,
+ 0x5b, 0xd6, 0x8e, 0xa1, 0xbf, 0xcb, 0x7b, 0x76, 0xf2, 0xbe, 0x82, 0x6d,
+ 0x7b, 0xcf, 0xbe, 0x8a, 0xb9, 0x93, 0x5e, 0xff, 0x7d, 0xdb, 0x0a, 0x76,
+ 0x9f, 0xd7, 0x3f, 0xbd, 0x2d, 0x6b, 0xa7, 0xbc, 0xfe, 0xe4, 0xee, 0x82,
+ 0x3d, 0xe0, 0xf5, 0x9f, 0xbd, 0x3d, 0x6b, 0x0f, 0x7a, 0xfd, 0x0f, 0x6d,
+ 0x2d, 0xd8, 0x69, 0xf4, 0x1f, 0x6d, 0xd6, 0x37, 0x59, 0x72, 0xa4, 0x1c,
+ 0xc7, 0x2f, 0x83, 0x67, 0x43, 0xe8, 0xdb, 0x89, 0xdf, 0x30, 0x7e, 0xbf,
+ 0xb8, 0x4e, 0xda, 0x46, 0x70, 0xfd, 0xc6, 0x46, 0x97, 0x77, 0xe0, 0x91,
+ 0x13, 0x96, 0x37, 0x8c, 0x98, 0xbc, 0xd8, 0xfb, 0x06, 0x78, 0x68, 0xc9,
+ 0x99, 0x8a, 0x68, 0x23, 0xbd, 0x31, 0xf0, 0x2e, 0x2a, 0x4f, 0x56, 0x5a,
+ 0xc5, 0x78, 0xcc, 0x00, 0x6f, 0x3e, 0x2f, 0xf9, 0x68, 0x58, 0xda, 0xe7,
+ 0x34, 0xe9, 0xee, 0x0f, 0x4b, 0xc6, 0x52, 0x72, 0x13, 0x7d, 0x26, 0x2a,
+ 0xc6, 0x5c, 0x66, 0xbd, 0x2e, 0x9b, 0xac, 0x9c, 0x14, 0xc1, 0xbb, 0xef,
+ 0x51, 0x27, 0xf1, 0x2c, 0x2e, 0xb9, 0xe9, 0x9b, 0x65, 0xcc, 0x22, 0x5d,
+ 0x3b, 0x6f, 0x74, 0xd7, 0x0a, 0x6b, 0xd9, 0x13, 0x23, 0x72, 0xc4, 0x89,
+ 0x68, 0xb9, 0x13, 0xdb, 0x24, 0x9b, 0x92, 0x28, 0xde, 0x8b, 0xe5, 0xf1,
+ 0xa4, 0x54, 0x1e, 0x91, 0x29, 0x47, 0xb4, 0xac, 0x43, 0x7e, 0x76, 0xe2,
+ 0x79, 0x9b, 0x1a, 0x8b, 0xbe, 0x2e, 0x43, 0xcd, 0x1d, 0x46, 0xbf, 0x85,
+ 0xfe, 0x0e, 0x6d, 0x48, 0xcd, 0xa1, 0xfa, 0xe3, 0x93, 0x12, 0x91, 0xc7,
+ 0xcb, 0x51, 0x6f, 0x6c, 0xb5, 0x9a, 0x4d, 0x59, 0x18, 0x37, 0x22, 0x93,
+ 0x4e, 0x54, 0xc6, 0x70, 0x9d, 0x70, 0xb8, 0x7e, 0x0c, 0x3a, 0xf5, 0xda,
+ 0xa1, 0xfc, 0xac, 0x9a, 0x2f, 0x6e, 0xa4, 0x39, 0x5f, 0x17, 0xc6, 0x4d,
+ 0x80, 0x2e, 0x4d, 0x4c, 0x25, 0xcb, 0x8c, 0xe4, 0xa7, 0x35, 0xe8, 0x1b,
+ 0xae, 0x8a, 0xaf, 0x43, 0xa0, 0xdf, 0x14, 0xbb, 0x5f, 0x93, 0x02, 0x64,
+ 0x55, 0xb4, 0xd0, 0x2e, 0x9f, 0xd5, 0xb3, 0x4e, 0xb3, 0xe4, 0xcc, 0xb8,
+ 0x18, 0x33, 0x4a, 0x97, 0x64, 0x12, 0xef, 0xe8, 0x36, 0xc7, 0x5c, 0xc4,
+ 0xbe, 0xc7, 0x94, 0x1c, 0x9a, 0xd2, 0x45, 0x3d, 0x57, 0xe9, 0x14, 0x7d,
+ 0x6e, 0x8f, 0xbc, 0x3c, 0x2d, 0x96, 0x91, 0x7e, 0xb7, 0x9a, 0xb5, 0xa7,
+ 0xf4, 0xec, 0x13, 0xa6, 0x84, 0x66, 0x34, 0x99, 0xb2, 0x13, 0xb0, 0x80,
+ 0xa3, 0xfa, 0x8e, 0xca, 0x59, 0x8c, 0xe3, 0x7b, 0x18, 0x57, 0xd6, 0xc1,
+ 0x57, 0xde, 0x6f, 0xb1, 0x74, 0xa5, 0xcf, 0x1c, 0x03, 0x19, 0x60, 0x1f,
+ 0x4f, 0x3a, 0x90, 0x89, 0x92, 0x51, 0x1c, 0x32, 0x7a, 0x15, 0x32, 0x1a,
+ 0x80, 0x6c, 0x52, 0xf2, 0x52, 0xa5, 0x4f, 0x9e, 0xaf, 0x24, 0xe5, 0x39,
+ 0xe8, 0xeb, 0xb3, 0x95, 0xb8, 0x3c, 0x53, 0xe9, 0x92, 0xa7, 0x2b, 0x31,
+ 0x79, 0x4a, 0xc9, 0x2d, 0x07, 0xdb, 0x50, 0xb2, 0x0c, 0x5f, 0x9f, 0x96,
+ 0x70, 0x27, 0xe4, 0xd1, 0x01, 0xfd, 0x69, 0x87, 0x6e, 0x7e, 0xa5, 0x37,
+ 0x2c, 0xb3, 0xbd, 0x92, 0x59, 0x8f, 0xfe, 0x9b, 0xd2, 0xa6, 0xe2, 0x91,
+ 0x89, 0xe7, 0x93, 0xd3, 0x21, 0xc9, 0x59, 0x8f, 0xcb, 0x85, 0x19, 0x53,
+ 0x26, 0x2b, 0xdb, 0x6f, 0x72, 0x65, 0xc6, 0xf6, 0xbc, 0x9c, 0x9f, 0x69,
+ 0xc2, 0xb3, 0x79, 0x79, 0x79, 0xb3, 0x2e, 0x13, 0xb3, 0x6f, 0x89, 0x09,
+ 0x1e, 0x0e, 0x29, 0x79, 0x3f, 0x2e, 0xff, 0xfc, 0x27, 0x22, 0x23, 0xe0,
+ 0x8b, 0xde, 0xff, 0xef, 0xd5, 0x8c, 0x05, 0x7e, 0xf4, 0xf7, 0x41, 0x3f,
+ 0x74, 0x5c, 0x29, 0xcf, 0x38, 0xc6, 0x98, 0x5a, 0xce, 0x39, 0x0d, 0x9b,
+ 0x6a, 0xd5, 0xb2, 0xc7, 0x45, 0x0a, 0xc7, 0xab, 0x52, 0x48, 0x85, 0xe4,
+ 0x01, 0xab, 0x2a, 0x43, 0xa9, 0x26, 0x39, 0x60, 0x75, 0xca, 0x44, 0xdf,
+ 0xcf, 0x68, 0x3e, 0x96, 0x7d, 0xa5, 0x92, 0xc6, 0x3d, 0xfb, 0x44, 0x66,
+ 0xd5, 0xbd, 0xdb, 0x5f, 0xac, 0x84, 0x24, 0x13, 0x2d, 0xc6, 0x4c, 0xb9,
+ 0xa0, 0xb9, 0xb4, 0xed, 0xf4, 0x9f, 0x41, 0x5e, 0x63, 0xc0, 0x90, 0x84,
+ 0xd2, 0xa5, 0xfc, 0xf4, 0x9a, 0x8b, 0x19, 0xd5, 0x1d, 0x52, 0x7a, 0x6a,
+ 0xa4, 0x4d, 0xd2, 0x31, 0xa6, 0xa5, 0xa3, 0xd2, 0xad, 0xec, 0x64, 0x00,
+ 0x63, 0x06, 0xb5, 0xbb, 0x2b, 0x94, 0x37, 0xee, 0xcb, 0xa4, 0x75, 0x03,
+ 0xc6, 0x9a, 0xb8, 0x66, 0x3c, 0x9a, 0x83, 0x74, 0x72, 0x2e, 0xd2, 0xc9,
+ 0xeb, 0xde, 0x00, 0x9d, 0xfb, 0x6a, 0xf7, 0xb3, 0x81, 0xfb, 0x62, 0xe5,
+ 0xd7, 0x5b, 0x5c, 0xfa, 0xc8, 0xd7, 0x41, 0x99, 0x98, 0x7e, 0xc8, 0x5b,
+ 0x0b, 0xf7, 0x65, 0xae, 0xb1, 0x00, 0x3e, 0xa9, 0x91, 0x57, 0x58, 0xab,
+ 0x18, 0x58, 0xeb, 0x70, 0x60, 0xad, 0xc3, 0x81, 0xb5, 0x8a, 0xe0, 0xad,
+ 0xac, 0xd3, 0x81, 0x33, 0x79, 0xc2, 0xbc, 0x1c, 0xc5, 0x9c, 0x6f, 0x88,
+ 0x91, 0xa6, 0x2d, 0xf8, 0x36, 0xf9, 0x07, 0x18, 0x9f, 0x96, 0x73, 0x0e,
+ 0x78, 0x73, 0x3c, 0x24, 0x77, 0xa9, 0x71, 0xff, 0xb1, 0xc6, 0xa5, 0x31,
+ 0xf8, 0x2c, 0x2c, 0xbb, 0xa2, 0xbc, 0xf7, 0x9f, 0x99, 0xe0, 0x37, 0xdb,
+ 0x93, 0x37, 0xb8, 0x6d, 0xde, 0x9f, 0xf5, 0xf6, 0xd2, 0xee, 0xbe, 0x57,
+ 0x79, 0x53, 0x61, 0xc6, 0x62, 0x85, 0xb6, 0x2d, 0x29, 0xc3, 0x96, 0xfd,
+ 0x43, 0xa9, 0x4e, 0x99, 0xb4, 0xb4, 0xd4, 0x44, 0xb2, 0x99, 0xfc, 0xcf,
+ 0xe8, 0x76, 0x2b, 0xec, 0x47, 0xe2, 0x3a, 0x71, 0x51, 0xed, 0xeb, 0x5b,
+ 0x1e, 0xfd, 0x16, 0xdb, 0x23, 0xba, 0xdd, 0xd1, 0xd0, 0x4f, 0xfd, 0xff,
+ 0x4b, 0xdc, 0xd3, 0x06, 0xfa, 0x75, 0x77, 0xed, 0xbf, 0x42, 0x9b, 0x58,
+ 0x15, 0xf1, 0xda, 0xfe, 0xf3, 0xff, 0x32, 0x96, 0xb7, 0x8f, 0x6d, 0x5c,
+ 0xde, 0xf6, 0x6d, 0x29, 0x88, 0x73, 0xdc, 0x2b, 0x6c, 0xd8, 0xa6, 0xfe,
+ 0x85, 0x40, 0x6b, 0x0a, 0x36, 0xdc, 0xec, 0xd1, 0xf0, 0xba, 0x47, 0x03,
+ 0x68, 0xc5, 0xb8, 0x89, 0x0a, 0xdf, 0x51, 0xa2, 0x6c, 0x68, 0x93, 0xf7,
+ 0xfe, 0xfd, 0x5a, 0xf5, 0xfc, 0x0d, 0x83, 0xeb, 0xf8, 0x57, 0xd1, 0x86,
+ 0x60, 0x67, 0x93, 0xb3, 0xa6, 0xe4, 0x53, 0x31, 0x65, 0x0f, 0xf9, 0x54,
+ 0x1d, 0x3f, 0x26, 0xa7, 0x1b, 0xf1, 0x83, 0xef, 0x11, 0x3f, 0x5c, 0xec,
+ 0x98, 0x98, 0x25, 0x8e, 0xd4, 0x71, 0xe3, 0xc8, 0xb4, 0x8f, 0x25, 0x9c,
+ 0x9b, 0x18, 0xe2, 0xe3, 0x07, 0xdf, 0x23, 0x7e, 0x18, 0x90, 0x15, 0xe7,
+ 0xf4, 0xd7, 0x9f, 0x6a, 0x98, 0x7b, 0x4a, 0x61, 0x93, 0x8b, 0xcb, 0x6f,
+ 0x06, 0x70, 0xbe, 0x0b, 0x18, 0x1d, 0x85, 0xfc, 0x7c, 0x8c, 0x26, 0x76,
+ 0xc6, 0x80, 0xeb, 0xe0, 0x91, 0xc2, 0xe4, 0x08, 0x70, 0xcc, 0xf4, 0x30,
+ 0x35, 0xec, 0x61, 0x6a, 0x04, 0x78, 0xca, 0xb6, 0xe5, 0xb5, 0xa3, 0x5e,
+ 0x3b, 0x86, 0x36, 0xfc, 0xef, 0x1c, 0x6d, 0xec, 0xb5, 0x43, 0xe3, 0xb3,
+ 0x0a, 0xa7, 0x89, 0xf1, 0xc0, 0x0a, 0xe2, 0x2c, 0xf1, 0xb6, 0x4b, 0x16,
+ 0xca, 0x58, 0xaf, 0x86, 0x69, 0x94, 0x47, 0x90, 0x1e, 0xd2, 0xb2, 0x46,
+ 0xf4, 0xc7, 0xdc, 0xfd, 0xe8, 0xe9, 0xcf, 0xeb, 0xd2, 0xc2, 0x7d, 0x90,
+ 0xee, 0x1b, 0x41, 0x2b, 0xf7, 0xf6, 0xa3, 0xa4, 0x95, 0xeb, 0x35, 0xd2,
+ 0x7b, 0x1a, 0xf4, 0x66, 0x80, 0xb7, 0xa2, 0x8d, 0xf6, 0x8e, 0x82, 0xde,
+ 0x11, 0x60, 0xf1, 0x30, 0xb0, 0x78, 0x27, 0xb0, 0x78, 0x08, 0x58, 0x9c,
+ 0x06, 0x0e, 0x0f, 0x02, 0x87, 0x07, 0x80, 0xc3, 0x29, 0xec, 0x2b, 0x2a,
+ 0xf3, 0xc0, 0xe5, 0x79, 0xe0, 0xf3, 0x3c, 0xe4, 0x35, 0x31, 0x27, 0xda,
+ 0x17, 0xb0, 0xfe, 0x63, 0x33, 0x89, 0xd3, 0xd0, 0xcd, 0x58, 0x51, 0x87,
+ 0x3d, 0xa5, 0x06, 0xa1, 0x23, 0x49, 0x29, 0x55, 0x46, 0xa5, 0x40, 0x3f,
+ 0xb6, 0xb9, 0x07, 0xb6, 0x0b, 0xfb, 0x89, 0xf9, 0x71, 0xd3, 0x5a, 0xef,
+ 0xfa, 0xf7, 0x22, 0xf6, 0x1f, 0x83, 0x27, 0x89, 0xb8, 0xc8, 0xb0, 0xe4,
+ 0x9d, 0x1e, 0x2b, 0xab, 0x27, 0x31, 0x8e, 0xed, 0xb8, 0xb6, 0xf7, 0x78,
+ 0x42, 0x1b, 0x3f, 0xce, 0x3d, 0x4d, 0x03, 0xe3, 0xaa, 0x32, 0x95, 0xa2,
+ 0xad, 0x56, 0xe5, 0x54, 0x2a, 0x31, 0x58, 0x94, 0x56, 0x39, 0x12, 0x9d,
+ 0x56, 0xfe, 0xcd, 0x4c, 0x1f, 0x53, 0xfa, 0x51, 0xb0, 0x71, 0x2d, 0x77,
+ 0x6b, 0xf9, 0xe3, 0xf4, 0x3b, 0x3d, 0xf8, 0x85, 0x40, 0x0b, 0xe7, 0x37,
+ 0x65, 0x68, 0x40, 0xb4, 0x7d, 0xbd, 0x45, 0xa0, 0x62, 0xc2, 0x3a, 0x87,
+ 0x95, 0x73, 0xd3, 0x3d, 0xb1, 0x9c, 0x6e, 0xca, 0x98, 0xa9, 0xc9, 0x04,
+ 0xec, 0x65, 0x28, 0xf5, 0x7f, 0xd5, 0x23, 0x51, 0x3e, 0x6f, 0x96, 0xdf,
+ 0x51, 0x38, 0x8b, 0xb5, 0x4b, 0xb3, 0x58, 0x37, 0x04, 0xfe, 0x71, 0x5d,
+ 0xce, 0x83, 0x36, 0x30, 0xcf, 0xb4, 0x13, 0xa7, 0x8b, 0xb2, 0x1d, 0x76,
+ 0xb7, 0x4e, 0xb2, 0x7d, 0x4d, 0x92, 0x19, 0x89, 0xcb, 0xc4, 0xcc, 0x76,
+ 0xe0, 0x1e, 0x64, 0x60, 0xb7, 0x48, 0x7e, 0x34, 0x2e, 0x5f, 0x9e, 0x61,
+ 0x5f, 0x06, 0xfb, 0x4f, 0x1c, 0xcd, 0x08, 0xf7, 0x1f, 0x52, 0xfb, 0x8a,
+ 0xeb, 0x19, 0x39, 0xe0, 0xbc, 0xa4, 0xbb, 0x76, 0xe9, 0xb6, 0xf7, 0x42,
+ 0x1e, 0xa7, 0xc0, 0xef, 0xbc, 0x63, 0xcb, 0x02, 0xfc, 0x4a, 0xee, 0x38,
+ 0x70, 0xd5, 0x6e, 0x03, 0x06, 0x26, 0xce, 0xd2, 0x3e, 0x0c, 0xc4, 0x5a,
+ 0x25, 0xc5, 0xeb, 0x2e, 0x39, 0x3e, 0xa3, 0xcb, 0xb3, 0xb7, 0xc5, 0xd1,
+ 0x06, 0xd6, 0xa6, 0x12, 0x67, 0xc6, 0xf4, 0x2e, 0xb9, 0xb5, 0x23, 0x86,
+ 0xf7, 0x52, 0x5a, 0xde, 0xf9, 0x37, 0xf2, 0xf2, 0x64, 0x5c, 0xe7, 0x58,
+ 0x5d, 0x72, 0x29, 0x03, 0x3a, 0x56, 0xc4, 0xf8, 0x7f, 0x40, 0x7f, 0x97,
+ 0xcc, 0x21, 0xbe, 0x99, 0x03, 0x4d, 0xd9, 0x14, 0xb1, 0x30, 0x71, 0x72,
+ 0x49, 0x07, 0x66, 0xcd, 0x41, 0x37, 0x47, 0x11, 0x3f, 0xcc, 0xfc, 0x37,
+ 0xc6, 0xc4, 0x21, 0xd3, 0x1e, 0x6b, 0x02, 0xf8, 0x92, 0xe9, 0xe2, 0x3d,
+ 0xe7, 0xb4, 0xe5, 0x94, 0x43, 0x1d, 0x8a, 0xcb, 0xe3, 0x15, 0xbe, 0xd7,
+ 0x73, 0xf6, 0x69, 0xb1, 0xe5, 0x41, 0xe7, 0x7f, 0x30, 0xfe, 0x1d, 0xc4,
+ 0x9e, 0x96, 0x94, 0x20, 0xb7, 0x02, 0x78, 0x99, 0x89, 0xb9, 0xed, 0x89,
+ 0xb9, 0xc4, 0xd9, 0x0b, 0x3a, 0xef, 0xed, 0xe2, 0x82, 0x7e, 0xb3, 0x48,
+ 0x07, 0xf9, 0x99, 0x02, 0x2f, 0x6d, 0x4b, 0xd7, 0x37, 0x7b, 0xf1, 0x16,
+ 0x6d, 0xc0, 0x06, 0x7d, 0xa6, 0x2c, 0xf4, 0x07, 0x6d, 0x80, 0x7e, 0xd6,
+ 0xb7, 0x81, 0x44, 0x6c, 0x49, 0xd7, 0xf1, 0xdc, 0x94, 0x63, 0xaa, 0xad,
+ 0x81, 0xd6, 0x44, 0x8c, 0xfb, 0x9b, 0x2c, 0x27, 0xe5, 0x71, 0x87, 0xe3,
+ 0xc1, 0xe7, 0xe9, 0x88, 0x37, 0x1e, 0xf1, 0x8e, 0xc3, 0x98, 0x29, 0x09,
+ 0x9a, 0x5d, 0xbb, 0x58, 0x98, 0x8e, 0xaa, 0x67, 0x47, 0x1c, 0x37, 0x36,
+ 0xd2, 0x11, 0x3f, 0xcd, 0x23, 0x7e, 0xca, 0x29, 0x1b, 0xb1, 0x32, 0x88,
+ 0xaf, 0xe1, 0x67, 0x5d, 0xfb, 0x28, 0x95, 0x49, 0xcb, 0x3d, 0xa0, 0x2f,
+ 0x51, 0x04, 0x31, 0xc7, 0x74, 0xb8, 0xeb, 0xec, 0x80, 0x14, 0x19, 0x63,
+ 0x9d, 0x33, 0x1e, 0x91, 0xb1, 0x12, 0xfd, 0x1b, 0x7e, 0x8e, 0x6d, 0x31,
+ 0xa6, 0xcf, 0x28, 0xdf, 0xd3, 0x03, 0x3d, 0x80, 0x5f, 0x4a, 0xb5, 0x8b,
+ 0xeb, 0x07, 0xf7, 0x40, 0x9e, 0xc3, 0x90, 0x7b, 0x5a, 0xc6, 0x4f, 0x8c,
+ 0x53, 0xa7, 0x93, 0x25, 0x49, 0x24, 0x8f, 0xc8, 0x16, 0x6b, 0x01, 0xbe,
+ 0x30, 0x33, 0x5a, 0xdd, 0xae, 0xa7, 0xf9, 0xce, 0xa3, 0x78, 0x07, 0xd7,
+ 0xd2, 0xb8, 0x3c, 0x50, 0x61, 0xdf, 0x9d, 0x86, 0xb4, 0xc0, 0x56, 0x06,
+ 0xf6, 0x78, 0x76, 0x80, 0xf9, 0x4c, 0x7f, 0xbe, 0x71, 0x6f, 0x3e, 0x8e,
+ 0xe3, 0x18, 0xbe, 0x53, 0x9f, 0x77, 0x07, 0x7d, 0x1b, 0xb0, 0x64, 0x87,
+ 0x5e, 0xdd, 0x1e, 0xc2, 0xf3, 0x53, 0x03, 0xbc, 0xc7, 0x3c, 0xf0, 0x6d,
+ 0x96, 0x3d, 0x8c, 0xb1, 0xa3, 0x98, 0x73, 0x8d, 0x64, 0x3b, 0x7d, 0x7a,
+ 0xa9, 0x03, 0x8c, 0x3f, 0xd8, 0x8e, 0xae, 0x77, 0x79, 0xff, 0x25, 0xc3,
+ 0xd5, 0xc9, 0x11, 0xb4, 0x69, 0x7f, 0x07, 0x25, 0xe7, 0x24, 0xb0, 0x4f,
+ 0xf0, 0xb6, 0x32, 0xe1, 0xed, 0x11, 0xfc, 0x1f, 0x39, 0x0c, 0x3e, 0x48,
+ 0xd1, 0xe5, 0x0d, 0xf9, 0x42, 0x9e, 0xfc, 0x16, 0x74, 0xff, 0x61, 0x8c,
+ 0x81, 0x7f, 0x50, 0x3c, 0x58, 0xea, 0x70, 0x63, 0xd1, 0x44, 0x31, 0xc3,
+ 0xfc, 0xa9, 0x83, 0x98, 0x07, 0xfc, 0xa9, 0x40, 0xb1, 0x30, 0xf7, 0x92,
+ 0xbe, 0x86, 0xf4, 0xc6, 0x97, 0x0c, 0x83, 0xed, 0xe4, 0x12, 0x74, 0xb8,
+ 0x04, 0xf9, 0x64, 0xfb, 0x68, 0xb3, 0x36, 0xe4, 0x31, 0x63, 0x50, 0x5f,
+ 0x4b, 0x88, 0x05, 0xf3, 0xce, 0x16, 0xeb, 0x5e, 0xf2, 0xcd, 0xb2, 0xe4,
+ 0x69, 0x27, 0x88, 0x1d, 0x3b, 0x30, 0x94, 0x7a, 0x18, 0x85, 0x1e, 0x98,
+ 0xf0, 0xc9, 0x31, 0xc8, 0xfc, 0xc5, 0x0e, 0x77, 0x2f, 0xbc, 0x37, 0x65,
+ 0xde, 0xc2, 0x9a, 0xce, 0xef, 0xaf, 0x73, 0xfb, 0x78, 0xcf, 0xb8, 0xc8,
+ 0x97, 0xab, 0x4f, 0x3b, 0xe5, 0xdb, 0x28, 0xd3, 0x43, 0xd8, 0x0b, 0xfb,
+ 0x71, 0x2d, 0x1d, 0x94, 0x71, 0xd0, 0x56, 0x18, 0xd8, 0x14, 0x3b, 0x8f,
+ 0xf1, 0x39, 0xe0, 0x79, 0xd1, 0xe4, 0xb3, 0x8b, 0x5a, 0xfd, 0x1d, 0xc4,
+ 0x5c, 0x36, 0xfd, 0xd9, 0x92, 0xf6, 0x85, 0xca, 0xcb, 0x5a, 0xb6, 0x74,
+ 0x51, 0xcb, 0x41, 0x4f, 0x4a, 0x0e, 0x73, 0x06, 0xda, 0x8f, 0x85, 0xb5,
+ 0x13, 0xb1, 0xb7, 0xf5, 0x9e, 0xf8, 0x02, 0xb0, 0x60, 0x2f, 0x6c, 0x3a,
+ 0x67, 0xee, 0x94, 0x02, 0xb0, 0x35, 0x7f, 0x62, 0x0b, 0xec, 0x2d, 0x1e,
+ 0xa0, 0x8b, 0x78, 0x56, 0xa4, 0x4f, 0xd5, 0x76, 0x38, 0x52, 0x6c, 0x4a,
+ 0x13, 0xd7, 0x36, 0x41, 0x77, 0xd0, 0x57, 0xae, 0xeb, 0xdf, 0x1d, 0x2b,
+ 0x68, 0x45, 0x7e, 0x39, 0xb0, 0x9c, 0xde, 0x92, 0x5c, 0x99, 0xde, 0x1d,
+ 0x35, 0x7a, 0x89, 0x19, 0xc0, 0x7f, 0xd8, 0xcd, 0x4b, 0xd0, 0xdf, 0xe7,
+ 0x1d, 0xe0, 0xbf, 0x03, 0xfc, 0x87, 0x4d, 0x3d, 0x03, 0xdd, 0x7b, 0xda,
+ 0x81, 0x0f, 0x70, 0xe0, 0x03, 0x1c, 0xf8, 0x00, 0x27, 0x0b, 0x39, 0x11,
+ 0xe7, 0xe9, 0x43, 0x76, 0xd7, 0x7c, 0x9e, 0x1b, 0x37, 0xdd, 0xe0, 0xc5,
+ 0x22, 0xa3, 0x88, 0x45, 0x36, 0xc8, 0x44, 0xf2, 0x7a, 0xec, 0xad, 0x05,
+ 0xd7, 0x56, 0x5c, 0xb1, 0x46, 0xf2, 0x76, 0xcf, 0x4e, 0x1e, 0x06, 0x5d,
+ 0x88, 0xbf, 0x93, 0x3f, 0x0d, 0x3d, 0x6c, 0x02, 0x3d, 0x3f, 0xe5, 0xc5,
+ 0x2c, 0x0f, 0x9a, 0xae, 0x1e, 0xb6, 0xa2, 0xef, 0x93, 0xe8, 0x6b, 0xc5,
+ 0x98, 0x03, 0x18, 0xc3, 0x98, 0xa7, 0xcd, 0xeb, 0x0b, 0x8e, 0x63, 0xec,
+ 0xf3, 0x19, 0xac, 0x95, 0xc0, 0xb8, 0x36, 0xcc, 0xdd, 0x85, 0x31, 0xdb,
+ 0x30, 0xe6, 0x46, 0xb4, 0x19, 0x33, 0x6f, 0x44, 0xfb, 0x13, 0x0d, 0xef,
+ 0x7c, 0x0c, 0x7d, 0xb7, 0x37, 0xf4, 0x9d, 0x43, 0x1f, 0xf2, 0x50, 0xeb,
+ 0xbc, 0xf7, 0x5e, 0x11, 0xed, 0xce, 0x86, 0x31, 0xaf, 0xa2, 0x0f, 0x71,
+ 0xaf, 0xf5, 0x2d, 0x5c, 0x91, 0x7f, 0x5a, 0xa4, 0xc9, 0x7f, 0xc6, 0xb8,
+ 0x37, 0x8e, 0xfe, 0x90, 0x17, 0xbb, 0xfe, 0xa6, 0x09, 0xbd, 0xd3, 0x86,
+ 0x9c, 0xdf, 0x30, 0xdd, 0x58, 0xef, 0x4e, 0xcb, 0xd5, 0x43, 0xbf, 0xfd,
+ 0x70, 0x43, 0x9b, 0x63, 0x17, 0x1a, 0xfa, 0xfe, 0xa5, 0xa1, 0xfd, 0xdd,
+ 0xd0, 0xca, 0x77, 0x06, 0xdb, 0x97, 0xf7, 0x15, 0x3a, 0x96, 0xb7, 0xed,
+ 0xa6, 0x95, 0xef, 0xe8, 0xeb, 0x96, 0xf7, 0xdd, 0xb8, 0xbe, 0x61, 0x0c,
+ 0x74, 0x2a, 0x8a, 0x1c, 0xc9, 0x1f, 0x1f, 0xbe, 0xce, 0x7d, 0x4e, 0xfe,
+ 0x36, 0xea, 0x92, 0xda, 0x3a, 0xda, 0x3a, 0xe4, 0xb0, 0xa4, 0xc1, 0x9e,
+ 0x2c, 0x3d, 0xfd, 0xb2, 0x96, 0x83, 0x4e, 0x65, 0x2b, 0xfe, 0x7c, 0xb4,
+ 0xd9, 0xc6, 0xdc, 0xdc, 0xcf, 0xc9, 0x19, 0x2b, 0x45, 0xa0, 0x37, 0xf7,
+ 0xd0, 0x27, 0x1d, 0x2d, 0x4a, 0xdd, 0x3e, 0xbb, 0xf5, 0x4b, 0xd9, 0xe7,
+ 0xed, 0x1e, 0x46, 0x1d, 0x06, 0x9d, 0x55, 0x19, 0x49, 0x35, 0xd3, 0xc7,
+ 0x78, 0xd8, 0x45, 0xdc, 0xa9, 0x56, 0x8d, 0xcd, 0x55, 0xd9, 0x9f, 0x7a,
+ 0xa7, 0x2a, 0x0a, 0xf3, 0x06, 0x15, 0xee, 0xc4, 0xf5, 0x1e, 0xc8, 0xc8,
+ 0x42, 0x6e, 0x82, 0x7c, 0x3a, 0x4a, 0x9f, 0x74, 0x90, 0xf1, 0xc9, 0xa3,
+ 0x2e, 0xa6, 0x12, 0x77, 0xd0, 0x46, 0x5e, 0x96, 0x3f, 0xce, 0xf5, 0x71,
+ 0x2d, 0x11, 0xc7, 0x47, 0x95, 0x4f, 0xc9, 0x5b, 0x9c, 0x77, 0x35, 0x6c,
+ 0x3c, 0x6b, 0x32, 0xa6, 0x33, 0xed, 0xd3, 0xf0, 0x6f, 0x7c, 0xc6, 0x58,
+ 0xe1, 0x34, 0xe3, 0x92, 0x00, 0x56, 0x6d, 0x35, 0xe0, 0x32, 0x8b, 0xcb,
+ 0xf7, 0xb5, 0x81, 0x79, 0xc4, 0x55, 0xec, 0x75, 0x75, 0x2c, 0xea, 0xd1,
+ 0xaf, 0x6c, 0xdb, 0xbb, 0x6a, 0xb6, 0xed, 0xeb, 0xde, 0x6a, 0x39, 0xf8,
+ 0xf7, 0x95, 0x2c, 0x9e, 0xaa, 0x24, 0x8e, 0x15, 0x61, 0x4b, 0x8b, 0x2a,
+ 0xef, 0xf6, 0xe5, 0xc2, 0x18, 0x27, 0x71, 0x72, 0x1e, 0x6f, 0x8e, 0xab,
+ 0x1c, 0x83, 0xf9, 0x45, 0x55, 0x76, 0xa4, 0x5a, 0xa3, 0xe4, 0x43, 0x46,
+ 0xff, 0x76, 0x88, 0x31, 0xc3, 0xa2, 0x43, 0x9e, 0xa5, 0xf0, 0x3c, 0x05,
+ 0x4c, 0xf8, 0x27, 0xc9, 0x45, 0xd9, 0xf7, 0x76, 0x75, 0x01, 0x71, 0x95,
+ 0x8a, 0x8f, 0x94, 0xbf, 0x67, 0x7c, 0xb7, 0x1f, 0xfc, 0x22, 0x4f, 0x47,
+ 0xc0, 0x67, 0x3f, 0x06, 0x78, 0x8d, 0x75, 0x15, 0x59, 0x1e, 0x07, 0x8b,
+ 0x3c, 0x50, 0x7e, 0x19, 0x73, 0xea, 0x6e, 0xac, 0xc2, 0x3c, 0xdc, 0x66,
+ 0x7f, 0x47, 0x88, 0xb1, 0x9c, 0xeb, 0xeb, 0x0d, 0xac, 0x87, 0xdc, 0xbe,
+ 0xfc, 0x8f, 0x2a, 0x6e, 0x2a, 0x28, 0x79, 0x20, 0x86, 0xaa, 0xf0, 0x19,
+ 0xfb, 0xc2, 0x5e, 0xec, 0x1c, 0xf1, 0x62, 0x65, 0xcb, 0x8b, 0x95, 0x49,
+ 0x07, 0x6b, 0x6f, 0x7e, 0x5c, 0x40, 0x99, 0x2d, 0x1d, 0xd2, 0x37, 0x33,
+ 0x2e, 0x68, 0x93, 0xd5, 0xe3, 0x02, 0x9f, 0xa6, 0x6d, 0xa0, 0x89, 0x71,
+ 0x9e, 0xaa, 0xbd, 0x74, 0xb8, 0xf5, 0x1e, 0xd2, 0xe0, 0xfb, 0x47, 0xe5,
+ 0x87, 0x8f, 0xc2, 0xe5, 0x61, 0x6f, 0x69, 0xd0, 0xba, 0x53, 0xb2, 0xd3,
+ 0xdb, 0x3c, 0x7f, 0xcb, 0x1c, 0x80, 0xf1, 0xb7, 0xab, 0xb3, 0xd9, 0xd4,
+ 0x84, 0x3f, 0x4f, 0x27, 0x3c, 0x64, 0xa0, 0x2e, 0xc4, 0xb5, 0x18, 0xc7,
+ 0xf8, 0x31, 0xcd, 0x4e, 0x2f, 0xa6, 0x19, 0x96, 0xfd, 0x8e, 0x1b, 0xf3,
+ 0x8f, 0xa0, 0x3f, 0xef, 0x28, 0xda, 0x63, 0x8c, 0x2d, 0x75, 0xc4, 0xdc,
+ 0x99, 0x3d, 0x09, 0x24, 0x0f, 0xee, 0x5e, 0xba, 0xb1, 0x97, 0x52, 0x6d,
+ 0x2f, 0xad, 0x4b, 0xcb, 0xf7, 0x32, 0xaa, 0xde, 0x9d, 0x5a, 0xf1, 0xae,
+ 0x60, 0x1f, 0xbb, 0x2f, 0xf1, 0x8c, 0x7b, 0x64, 0xdc, 0x60, 0x79, 0x7b,
+ 0xf4, 0xe5, 0x74, 0x00, 0x7b, 0x4c, 0x6a, 0x79, 0x15, 0x6b, 0xed, 0x51,
+ 0x3c, 0xcf, 0x97, 0xc7, 0x70, 0xa5, 0x7d, 0xa8, 0x79, 0x94, 0x8d, 0x4c,
+ 0x28, 0x3e, 0x8f, 0xab, 0x7d, 0x2c, 0x94, 0x7f, 0x41, 0x0a, 0x27, 0x7e,
+ 0x09, 0x7e, 0x2f, 0x58, 0x0f, 0x63, 0x2d, 0x91, 0xfc, 0x28, 0x06, 0xf0,
+ 0x93, 0x7b, 0x65, 0xad, 0xeb, 0x0f, 0x43, 0x6e, 0x7e, 0x10, 0x81, 0x8c,
+ 0x35, 0xf7, 0xb9, 0x5a, 0xdf, 0xe7, 0x6b, 0x53, 0x80, 0x9e, 0x2a, 0x62,
+ 0xce, 0x18, 0x68, 0x08, 0xbe, 0x73, 0x50, 0x86, 0x1c, 0xca, 0xa3, 0x27,
+ 0x36, 0x2e, 0xb6, 0x95, 0x17, 0x3f, 0xce, 0xe0, 0xfa, 0xb4, 0xf9, 0x5c,
+ 0xcc, 0x10, 0xd6, 0x2f, 0x7d, 0xde, 0xf9, 0x7c, 0x8b, 0x2c, 0x35, 0xea,
+ 0xc0, 0x14, 0xe8, 0x29, 0x38, 0xe4, 0x93, 0xaf, 0x9b, 0xfe, 0xda, 0xaf,
+ 0xaa, 0xfd, 0x4c, 0xaa, 0x9a, 0xdd, 0x73, 0x35, 0x1d, 0x9d, 0x40, 0x0c,
+ 0xe2, 0xea, 0xdc, 0x7d, 0x1e, 0x6f, 0x7c, 0xdd, 0x8c, 0x78, 0x72, 0x66,
+ 0x1e, 0x47, 0xdb, 0xf1, 0xf5, 0x60, 0x93, 0x75, 0xb7, 0xe2, 0x05, 0x9f,
+ 0x11, 0x53, 0x5c, 0x59, 0x8e, 0xd5, 0x64, 0xb9, 0xb6, 0x41, 0x2f, 0xbf,
+ 0xb7, 0xce, 0xb5, 0x43, 0xda, 0x1b, 0xec, 0x16, 0xf4, 0x3d, 0xb5, 0xcc,
+ 0xbe, 0x93, 0x97, 0xa8, 0x83, 0x46, 0xc4, 0x98, 0xfb, 0x53, 0xf0, 0xf2,
+ 0x63, 0xc8, 0x55, 0x44, 0xcc, 0x19, 0xe2, 0x10, 0xe3, 0x8d, 0x7a, 0xbc,
+ 0xbb, 0x20, 0xab, 0xc5, 0xba, 0x57, 0x8a, 0x35, 0x7e, 0xf2, 0x2a, 0x63,
+ 0x8d, 0x78, 0x93, 0xb4, 0x10, 0x8b, 0x86, 0x11, 0xdb, 0x6a, 0xd2, 0x64,
+ 0x3f, 0x08, 0x1f, 0x76, 0xc6, 0x6c, 0xb6, 0x7d, 0x4c, 0x88, 0x48, 0xfb,
+ 0xdc, 0x06, 0x85, 0x0b, 0xd6, 0x4c, 0x1d, 0x17, 0x26, 0xc0, 0xfb, 0x11,
+ 0xb7, 0xb6, 0x1a, 0x6d, 0x97, 0xab, 0xcd, 0x8d, 0xeb, 0x71, 0xff, 0x58,
+ 0x2d, 0xee, 0xbf, 0xa1, 0x81, 0x8f, 0xab, 0xe1, 0xe2, 0x19, 0xf0, 0x2d,
+ 0x8d, 0xfc, 0x97, 0x79, 0xed, 0x10, 0xf2, 0x61, 0xe6, 0x62, 0x19, 0xe4,
+ 0xc4, 0x89, 0x33, 0xc0, 0x2a, 0xe4, 0xc8, 0x89, 0xb7, 0xe0, 0x57, 0x90,
+ 0x37, 0x27, 0xe6, 0x99, 0xbb, 0x2e, 0x22, 0x3f, 0x7e, 0x1a, 0xf9, 0xf1,
+ 0x53, 0x95, 0x3e, 0xf0, 0x37, 0xa9, 0xb0, 0x73, 0xef, 0x71, 0xd1, 0xee,
+ 0x52, 0xf5, 0x61, 0xda, 0x73, 0x14, 0x7e, 0xb4, 0x5a, 0x3d, 0x90, 0xea,
+ 0x41, 0x4e, 0x1e, 0x97, 0x4f, 0x99, 0xcc, 0x63, 0x35, 0xb3, 0xbb, 0x7f,
+ 0xc1, 0x08, 0xc6, 0xa4, 0xd9, 0x2b, 0xfa, 0x81, 0x95, 0xbc, 0xcf, 0x29,
+ 0x5f, 0x70, 0xcc, 0xb8, 0x1c, 0xef, 0xef, 0xaa, 0xf1, 0xfe, 0xc2, 0x1a,
+ 0x69, 0x19, 0x56, 0x35, 0x80, 0xee, 0xfe, 0x03, 0xc4, 0xab, 0x14, 0xfc,
+ 0x3a, 0xfc, 0x6f, 0x55, 0xee, 0x48, 0x5d, 0xac, 0x9e, 0xb7, 0xd7, 0x49,
+ 0xbe, 0xef, 0x8b, 0x1e, 0x66, 0x8f, 0x3d, 0x92, 0xb5, 0x8b, 0xb0, 0x0f,
+ 0xb7, 0x16, 0x39, 0x3e, 0x1d, 0x46, 0x14, 0xca, 0xbf, 0x0e, 0x59, 0x18,
+ 0xfc, 0x1b, 0xc8, 0x70, 0xcb, 0x69, 0x16, 0xb0, 0x74, 0xe0, 0xf0, 0x42,
+ 0x34, 0xa2, 0xea, 0x33, 0xd7, 0xd9, 0xec, 0xb7, 0x20, 0xd3, 0x51, 0x59,
+ 0x40, 0xfc, 0x50, 0x1a, 0x04, 0x8d, 0x7d, 0x9d, 0x18, 0x4f, 0xbb, 0x23,
+ 0xcf, 0x47, 0xe1, 0x7b, 0xc9, 0xd3, 0x28, 0xc6, 0xef, 0xc2, 0x98, 0x0e,
+ 0x5c, 0xbf, 0x68, 0x2c, 0x58, 0xcc, 0x9d, 0x7f, 0x0e, 0x6d, 0xce, 0x11,
+ 0xf4, 0x9d, 0x9f, 0x0e, 0x89, 0x9a, 0x93, 0xef, 0x74, 0x2a, 0xfb, 0xaf,
+ 0xaf, 0xc5, 0x75, 0xf8, 0xec, 0xbd, 0xea, 0x2d, 0xfd, 0x83, 0x81, 0xf5,
+ 0xda, 0x02, 0xeb, 0x0d, 0x06, 0xd6, 0x23, 0x9d, 0x1d, 0x01, 0x3a, 0x3b,
+ 0xf0, 0x7e, 0x0e, 0x6b, 0x0f, 0xab, 0x98, 0xa7, 0xbe, 0xe6, 0xfd, 0x81,
+ 0x35, 0xfd, 0xfd, 0x75, 0x06, 0xde, 0x7b, 0x07, 0xeb, 0xb1, 0x2f, 0x1a,
+ 0xe8, 0x23, 0x0d, 0xeb, 0xd1, 0xc7, 0x76, 0x47, 0x80, 0x2e, 0xd2, 0xba,
+ 0x16, 0xfd, 0x2a, 0x7e, 0x02, 0x9f, 0x5b, 0xe0, 0xb7, 0x74, 0xf8, 0x0e,
+ 0xd6, 0xa0, 0x1b, 0xf7, 0xfa, 0x65, 0xac, 0xeb, 0xcf, 0x17, 0xc5, 0x1c,
+ 0x1c, 0xcf, 0xb1, 0x86, 0xf7, 0x3e, 0xfb, 0xf9, 0xfc, 0x1b, 0xd5, 0xaf,
+ 0x2b, 0xbe, 0xad, 0x07, 0xed, 0xaa, 0xee, 0x22, 0xf3, 0x1d, 0x26, 0xe4,
+ 0xc9, 0xfc, 0x58, 0x93, 0x9b, 0x6c, 0x5d, 0xeb, 0xe9, 0xa7, 0xec, 0xd7,
+ 0x79, 0x58, 0xda, 0xa2, 0x65, 0x8f, 0xb3, 0x5e, 0xd0, 0xea, 0xe5, 0x7c,
+ 0xc8, 0x3d, 0x94, 0x8f, 0x31, 0xbd, 0xe7, 0xf4, 0x31, 0x8c, 0x5b, 0xe8,
+ 0x3f, 0x33, 0xde, 0x3d, 0xae, 0xd0, 0xe1, 0x7d, 0xa5, 0x0e, 0x39, 0xaf,
+ 0x78, 0x6a, 0xc9, 0xb9, 0x1a, 0x4f, 0x43, 0xde, 0xb7, 0x90, 0x83, 0xde,
+ 0x77, 0x06, 0x03, 0x71, 0x11, 0xee, 0xcb, 0x19, 0xd0, 0x10, 0x97, 0x9e,
+ 0x7e, 0xe6, 0x6e, 0x45, 0x5c, 0x59, 0xa7, 0xd0, 0x70, 0x75, 0xeb, 0x17,
+ 0x3d, 0xfd, 0xf0, 0x4b, 0xc0, 0xa1, 0x9e, 0xfe, 0xef, 0xa8, 0x7c, 0xae,
+ 0x54, 0xb1, 0xb4, 0x3b, 0x1c, 0xb7, 0x46, 0x74, 0xce, 0xbe, 0x5c, 0x8d,
+ 0x68, 0xa0, 0x99, 0x75, 0x0d, 0xbf, 0x46, 0x74, 0x4e, 0x54, 0x8d, 0xe8,
+ 0xe4, 0x15, 0x6a, 0x44, 0x99, 0xab, 0xaf, 0x11, 0x71, 0x7e, 0x53, 0xee,
+ 0x1e, 0x10, 0xed, 0x4b, 0x5e, 0x8d, 0xe8, 0x82, 0xb8, 0x35, 0xa2, 0xf3,
+ 0xb2, 0x7a, 0x8d, 0xe8, 0x68, 0x43, 0x8d, 0x68, 0xbd, 0xaa, 0x11, 0x71,
+ 0x1e, 0xb7, 0x46, 0xc4, 0x76, 0xbe, 0x7f, 0x30, 0x50, 0xeb, 0x00, 0xfe,
+ 0x3a, 0xb7, 0x82, 0x6f, 0x96, 0x36, 0xea, 0xf8, 0x98, 0x46, 0xec, 0xbf,
+ 0xbe, 0xe6, 0xbf, 0xea, 0xf8, 0xa6, 0x29, 0x9d, 0xbb, 0x12, 0xbe, 0x8d,
+ 0xba, 0x71, 0xc9, 0x32, 0x6c, 0x9b, 0xaa, 0xc5, 0x2e, 0xbf, 0xdc, 0xcc,
+ 0x1c, 0x7a, 0xb2, 0x5c, 0x9f, 0x77, 0x12, 0xf2, 0x1e, 0xab, 0xd5, 0x49,
+ 0x2e, 0x15, 0x1f, 0x45, 0xe5, 0xe0, 0xaa, 0xdf, 0x9a, 0x62, 0x99, 0x95,
+ 0xdf, 0x9a, 0x34, 0x89, 0x82, 0xce, 0x7c, 0x7f, 0x5e, 0xe5, 0x5d, 0x0b,
+ 0xce, 0xcf, 0xcb, 0xd2, 0xbd, 0x16, 0xf0, 0xc7, 0xaf, 0x9f, 0x50, 0xbe,
+ 0x75, 0x9f, 0x92, 0xd5, 0x3f, 0xba, 0x1a, 0xca, 0x3e, 0x55, 0x43, 0xf9,
+ 0x5a, 0x73, 0xb0, 0x86, 0x72, 0x4e, 0x2e, 0x5f, 0x43, 0xd9, 0xb7, 0x4a,
+ 0x0d, 0xe5, 0x15, 0xa9, 0xd7, 0x50, 0x5e, 0x11, 0xbf, 0x86, 0x62, 0xc8,
+ 0xd2, 0x7a, 0xce, 0xb3, 0x1f, 0xef, 0x8c, 0xe0, 0x37, 0x8c, 0x9f, 0x5b,
+ 0x53, 0x39, 0x57, 0xa3, 0x7f, 0xb5, 0x9a, 0xca, 0x37, 0x9b, 0xdf, 0x4f,
+ 0x4d, 0xc5, 0xf5, 0x01, 0x7e, 0x4d, 0xa5, 0x05, 0xf1, 0x0e, 0x7c, 0x8e,
+ 0x1e, 0xac, 0xa9, 0xfc, 0x2d, 0xed, 0x01, 0x7d, 0x2a, 0x46, 0x40, 0x3f,
+ 0xec, 0x02, 0x7e, 0x29, 0xa3, 0x6a, 0x1c, 0x9f, 0xf6, 0x78, 0xb8, 0x1b,
+ 0x7b, 0x8e, 0x43, 0x16, 0xe4, 0x63, 0x8f, 0x8a, 0x2d, 0x33, 0x66, 0x4c,
+ 0xcb, 0xf6, 0xc2, 0x9b, 0x4d, 0xf3, 0x5b, 0x74, 0x4c, 0xc6, 0x2b, 0xd4,
+ 0xf1, 0x2e, 0xc4, 0xe2, 0x26, 0xfa, 0x76, 0xa3, 0xed, 0xc7, 0x54, 0xfd,
+ 0xb5, 0x39, 0x68, 0x9b, 0x0b, 0xc0, 0x59, 0xe0, 0xc4, 0x55, 0xf8, 0xa8,
+ 0x6d, 0xa0, 0x39, 0xb8, 0x8f, 0x22, 0xfc, 0x13, 0xfa, 0x94, 0xcc, 0x19,
+ 0x5b, 0xfa, 0xb4, 0xc4, 0x69, 0xe7, 0x57, 0x31, 0x1f, 0xfb, 0xb6, 0xa9,
+ 0x7c, 0xac, 0x30, 0xc0, 0xbd, 0xd2, 0xd7, 0x2d, 0x82, 0x3e, 0xf4, 0x95,
+ 0x98, 0x03, 0xd2, 0xef, 0xf9, 0x39, 0x5a, 0x44, 0xe5, 0x68, 0x9d, 0x8a,
+ 0x1f, 0xe4, 0xf5, 0x8d, 0x61, 0x62, 0x65, 0xa7, 0xcd, 0x3d, 0x0c, 0x7b,
+ 0x58, 0xc7, 0xb6, 0x9b, 0x0b, 0x66, 0x74, 0xde, 0x3f, 0x02, 0xb9, 0xb2,
+ 0x4e, 0xe3, 0xcb, 0xef, 0x21, 0x6f, 0xdf, 0x83, 0x52, 0xec, 0x94, 0xf0,
+ 0x7a, 0xd0, 0x93, 0x9f, 0x61, 0xdc, 0xfd, 0x09, 0x95, 0x83, 0x44, 0xed,
+ 0x4b, 0xdb, 0xed, 0x5d, 0xd7, 0x60, 0xb7, 0x23, 0x97, 0xb5, 0xdb, 0xcf,
+ 0x85, 0x83, 0x76, 0x7b, 0xd7, 0x35, 0xd8, 0xed, 0xfe, 0x6b, 0xb2, 0x5b,
+ 0xee, 0x8d, 0x98, 0xe4, 0xd7, 0xc4, 0x56, 0xc6, 0x59, 0xfe, 0xba, 0x13,
+ 0x58, 0x33, 0x73, 0x89, 0x35, 0xc7, 0x2e, 0x59, 0x5b, 0x6d, 0x8c, 0xb1,
+ 0xae, 0x46, 0xde, 0xcc, 0xad, 0xe8, 0x6f, 0x23, 0x9e, 0x5f, 0xba, 0xdd,
+ 0xcb, 0xe7, 0xfd, 0xbc, 0x3e, 0x68, 0x3f, 0xd4, 0x0b, 0xea, 0xc2, 0x63,
+ 0xe0, 0x17, 0xf5, 0xc1, 0xb7, 0xb9, 0x9e, 0x06, 0x1d, 0x5c, 0x44, 0xbe,
+ 0xdf, 0xe3, 0xe9, 0x20, 0x65, 0xdd, 0xab, 0xbe, 0x11, 0x95, 0x9c, 0x47,
+ 0xdc, 0x3c, 0x1f, 0x3a, 0x90, 0x2f, 0xf9, 0xb6, 0x06, 0x9e, 0x44, 0xfd,
+ 0x67, 0xe4, 0xa3, 0x8d, 0x98, 0x67, 0x0b, 0xe2, 0x35, 0xf0, 0x48, 0xf5,
+ 0x2f, 0xaf, 0x09, 0x5f, 0x1e, 0xcf, 0xa4, 0x18, 0xc2, 0xd8, 0x53, 0x03,
+ 0xb0, 0xf1, 0x01, 0x62, 0x54, 0x1a, 0x79, 0x0f, 0xf5, 0x90, 0xba, 0xb9,
+ 0x29, 0xb9, 0x43, 0x67, 0x4c, 0xb5, 0x07, 0xb6, 0x47, 0x7d, 0x8d, 0xcb,
+ 0x8e, 0xca, 0xa6, 0x33, 0xe7, 0x74, 0xae, 0x51, 0xad, 0xe6, 0x99, 0x2b,
+ 0x5a, 0xa2, 0x77, 0xf7, 0xff, 0x45, 0x98, 0x7e, 0xe9, 0x7a, 0xdb, 0xf0,
+ 0x74, 0x2d, 0x83, 0x7b, 0xea, 0xed, 0xeb, 0xf0, 0xf7, 0xfc, 0xc6, 0xfe,
+ 0x03, 0xf4, 0xc7, 0x60, 0xf3, 0xf4, 0xef, 0xcc, 0x47, 0xb6, 0x7a, 0xe3,
+ 0x7a, 0xd4, 0xf7, 0xcf, 0x6c, 0xea, 0x56, 0xef, 0xbb, 0x13, 0xfd, 0x4f,
+ 0x82, 0x3e, 0x7b, 0x99, 0x9c, 0x79, 0x46, 0x21, 0xa7, 0xf2, 0x19, 0xbe,
+ 0xaf, 0x74, 0x12, 0x39, 0x88, 0x19, 0xa8, 0xa5, 0x87, 0xbd, 0xdc, 0x8d,
+ 0x36, 0x16, 0x81, 0x0c, 0xb7, 0x7b, 0xb9, 0x0a, 0xf3, 0xd7, 0xe5, 0x67,
+ 0x13, 0x56, 0xd7, 0x81, 0x0d, 0xef, 0x43, 0x07, 0x1a, 0xe5, 0x17, 0x86,
+ 0xed, 0xfb, 0xf2, 0xf3, 0xe3, 0x98, 0x79, 0x6f, 0xdf, 0x3d, 0xae, 0x0c,
+ 0x7f, 0x2c, 0xf6, 0xa9, 0x05, 0xf6, 0xe9, 0xe3, 0xd1, 0x3e, 0x6f, 0x9f,
+ 0x5b, 0x1b, 0xf0, 0x68, 0xa4, 0xc1, 0x66, 0x3f, 0x4a, 0x3c, 0x3a, 0xb4,
+ 0xe6, 0xa3, 0xc7, 0x23, 0xee, 0x6b, 0xe3, 0xaa, 0x38, 0xe4, 0xee, 0xe3,
+ 0x77, 0x45, 0x4f, 0x7f, 0x98, 0xf9, 0xde, 0xfb, 0x91, 0x4f, 0x10, 0x47,
+ 0x28, 0x93, 0x36, 0x15, 0xc3, 0xba, 0xb6, 0x07, 0x5f, 0x5e, 0x0a, 0xc9,
+ 0x1b, 0xf7, 0x84, 0xe5, 0x7f, 0x6f, 0xe3, 0xf7, 0x30, 0xd3, 0xab, 0x69,
+ 0xb1, 0xfd, 0xc2, 0x1a, 0xd7, 0x0f, 0xbd, 0xd0, 0xee, 0xfa, 0x1d, 0xbe,
+ 0xe3, 0xdb, 0xb3, 0x85, 0xe7, 0x7c, 0xb6, 0x91, 0x5f, 0x4c, 0xae, 0x21,
+ 0x07, 0xdc, 0x64, 0x5d, 0xd0, 0x57, 0xcb, 0x01, 0x2f, 0x5f, 0x0f, 0xac,
+ 0xe7, 0x80, 0xc4, 0xd9, 0x0e, 0xa5, 0x1b, 0xf9, 0x28, 0x73, 0x1f, 0xc3,
+ 0xc3, 0x4e, 0xde, 0x23, 0xb7, 0x75, 0x90, 0xef, 0x42, 0xb6, 0xcf, 0x21,
+ 0x5e, 0x7a, 0xd6, 0x41, 0x8e, 0xeb, 0x20, 0xb7, 0x75, 0x90, 0xdb, 0x3a,
+ 0xc8, 0x6d, 0x9d, 0xa4, 0x97, 0x23, 0x8f, 0x78, 0x75, 0x7f, 0x7e, 0xe3,
+ 0x66, 0x7d, 0xa1, 0x08, 0x5f, 0x32, 0xc5, 0x73, 0x13, 0x7a, 0x36, 0xb5,
+ 0xc6, 0xdb, 0x9f, 0x5f, 0x13, 0xef, 0xf2, 0x6a, 0x36, 0xdf, 0x54, 0x75,
+ 0x43, 0xd1, 0x1f, 0x68, 0x71, 0xbf, 0x83, 0xf3, 0x7c, 0xc7, 0xaf, 0x21,
+ 0x2e, 0x51, 0x67, 0x88, 0x68, 0xa3, 0x55, 0x3d, 0xcd, 0x9a, 0x8c, 0xe8,
+ 0x7a, 0xfa, 0x16, 0xbc, 0xb3, 0xc5, 0xcd, 0x09, 0xa2, 0x62, 0xe8, 0xe9,
+ 0x56, 0xf2, 0x54, 0xd3, 0xd3, 0x6b, 0xbd, 0xb9, 0xf6, 0xb7, 0xb8, 0xb1,
+ 0x55, 0x2f, 0xdb, 0xa6, 0xce, 0x38, 0x41, 0xc5, 0xda, 0x7e, 0xff, 0xc5,
+ 0xf6, 0xe5, 0x6b, 0x85, 0x14, 0xbe, 0x67, 0x53, 0xf7, 0x62, 0x3e, 0xb6,
+ 0xeb, 0xfc, 0xd6, 0x2f, 0xc9, 0xef, 0x90, 0xc7, 0x6f, 0x97, 0xc7, 0x06,
+ 0xc7, 0xa9, 0xba, 0x30, 0x79, 0xed, 0xcf, 0xa7, 0xea, 0x7a, 0x58, 0x47,
+ 0x9d, 0xcd, 0xc0, 0xf5, 0x07, 0xa6, 0xb4, 0x8d, 0xee, 0x0e, 0xd9, 0xc1,
+ 0x75, 0xfd, 0x6f, 0xe2, 0x57, 0xb3, 0x66, 0x8f, 0xfa, 0x8e, 0xe6, 0xfa,
+ 0x8c, 0x90, 0xd2, 0x41, 0x33, 0xcd, 0x7d, 0xfd, 0x50, 0x9d, 0xa9, 0xa1,
+ 0xfe, 0xe5, 0x90, 0xc7, 0x4c, 0x0d, 0x6c, 0x8a, 0x9b, 0xfa, 0x48, 0x0b,
+ 0xeb, 0xaf, 0x43, 0x15, 0x1f, 0xf7, 0xb8, 0x5e, 0xa3, 0x1f, 0x67, 0x5d,
+ 0xcd, 0xc7, 0x33, 0xd9, 0xe0, 0xd6, 0xdb, 0x3e, 0x88, 0x2d, 0xb5, 0x34,
+ 0xd8, 0x92, 0xbf, 0x4f, 0xee, 0x9f, 0xd7, 0xd5, 0xcf, 0x43, 0x2c, 0x56,
+ 0x02, 0xdf, 0x47, 0x6a, 0xba, 0xc1, 0xb3, 0x2a, 0x9f, 0x85, 0x0e, 0xf2,
+ 0xdb, 0xc0, 0x4e, 0xd8, 0x51, 0xb5, 0x3a, 0xc4, 0x1a, 0x73, 0xdf, 0x67,
+ 0x54, 0x7e, 0xa9, 0xa7, 0xe7, 0x55, 0xfd, 0xc1, 0x5c, 0x51, 0x7f, 0x18,
+ 0x82, 0xae, 0x20, 0x06, 0x70, 0xda, 0x54, 0x4c, 0xa7, 0xe2, 0x85, 0x4a,
+ 0xe3, 0xf7, 0x97, 0xfb, 0x5b, 0x5d, 0x3e, 0xfc, 0x5d, 0x8b, 0xfb, 0x0d,
+ 0xe2, 0x8f, 0xa2, 0xcb, 0xdb, 0x7c, 0xff, 0xaf, 0x5b, 0xfc, 0xb3, 0x3b,
+ 0x85, 0x13, 0x43, 0xd0, 0x45, 0xe4, 0xe4, 0x6a, 0x3e, 0xc4, 0xbb, 0x4f,
+ 0xcc, 0x76, 0x2c, 0x1f, 0x8f, 0xbe, 0x13, 0xfe, 0xf8, 0x8e, 0x86, 0xf1,
+ 0x1d, 0x18, 0xff, 0x7b, 0x0d, 0xe3, 0x3b, 0x02, 0xe3, 0xa3, 0x0d, 0xe3,
+ 0xa3, 0x18, 0xff, 0x7c, 0xc3, 0xf8, 0x68, 0x60, 0x7c, 0x67, 0xc3, 0xf8,
+ 0x4e, 0x8c, 0x7f, 0xa1, 0x61, 0x3c, 0xfa, 0x4e, 0x34, 0x79, 0xdf, 0xc5,
+ 0x88, 0xb1, 0xfb, 0xbd, 0x5c, 0x1c, 0xd7, 0x72, 0xe3, 0xb7, 0x16, 0xea,
+ 0x5d, 0x17, 0x64, 0xe0, 0x9f, 0xa7, 0xa3, 0xbd, 0x66, 0x60, 0xaf, 0xf5,
+ 0x58, 0xc6, 0xd5, 0xc7, 0xa0, 0x2e, 0x12, 0x1f, 0x8a, 0x62, 0xd8, 0xd0,
+ 0x9d, 0x12, 0x74, 0xa8, 0xe4, 0xfb, 0x24, 0x9e, 0x83, 0xe2, 0x19, 0x53,
+ 0xd7, 0xf7, 0x86, 0xec, 0x45, 0x2f, 0x07, 0x7b, 0x9b, 0xb4, 0x03, 0x2f,
+ 0x7d, 0xcc, 0x94, 0x63, 0xae, 0xdd, 0x50, 0x7f, 0x39, 0xbf, 0x67, 0x3f,
+ 0xd4, 0x55, 0x6f, 0x9d, 0xa1, 0x15, 0xb8, 0x16, 0x5f, 0x51, 0xdb, 0x32,
+ 0xae, 0x02, 0xd7, 0x46, 0x6a, 0xb8, 0xf6, 0x59, 0x99, 0xaf, 0xe5, 0xdb,
+ 0xc3, 0x72, 0xc0, 0xd9, 0xc5, 0x33, 0x36, 0xc7, 0x32, 0xf2, 0xe1, 0xe4,
+ 0xdb, 0xbb, 0x6a, 0x7e, 0x92, 0x67, 0x3a, 0x96, 0x0e, 0x31, 0x87, 0xf2,
+ 0x6b, 0xb3, 0x53, 0xce, 0xcf, 0xb6, 0x42, 0x2e, 0xb0, 0x8d, 0x6b, 0xcd,
+ 0xb7, 0x39, 0x5f, 0x54, 0x0e, 0xb8, 0xe7, 0x1d, 0x6a, 0xf3, 0x16, 0x6b,
+ 0xf3, 0xc6, 0x3c, 0x7b, 0xa3, 0x0f, 0xae, 0xfb, 0xcb, 0x1c, 0xfc, 0xe5,
+ 0x18, 0x72, 0xee, 0x45, 0x67, 0xb5, 0xfa, 0xe8, 0xb5, 0xfa, 0xcb, 0xc6,
+ 0x3a, 0x73, 0xa3, 0xbf, 0xe4, 0x3a, 0x8d, 0xb5, 0xe5, 0x78, 0x03, 0xfe,
+ 0x53, 0x9f, 0x0e, 0x7b, 0x31, 0x35, 0xae, 0xa5, 0xc3, 0xb0, 0x47, 0x5d,
+ 0xc6, 0x94, 0xfe, 0xb2, 0xed, 0xe7, 0x96, 0xbb, 0x6b, 0xb9, 0x65, 0x3d,
+ 0x1f, 0x44, 0xec, 0x9a, 0xfc, 0xa4, 0x87, 0x8f, 0x8c, 0x91, 0xa7, 0xd0,
+ 0x7f, 0x0c, 0x3a, 0xc0, 0x67, 0xac, 0x97, 0xde, 0x2c, 0x9f, 0x32, 0x5d,
+ 0xff, 0xe4, 0xd6, 0xa6, 0x76, 0xab, 0xf8, 0x9f, 0xdf, 0x0b, 0x0a, 0xa9,
+ 0x76, 0x2f, 0xde, 0xbb, 0x12, 0xae, 0x2e, 0xcf, 0x4d, 0x75, 0xfd, 0x51,
+ 0xbc, 0xcb, 0xdc, 0xd4, 0x8c, 0x10, 0x43, 0xb3, 0x95, 0xcb, 0xbe, 0x5f,
+ 0xa4, 0x7f, 0x29, 0xa8, 0xef, 0x82, 0x2a, 0x0f, 0xc5, 0xb8, 0x45, 0xef,
+ 0x7d, 0x37, 0x0f, 0xcd, 0x56, 0xbe, 0xdd, 0xea, 0xe2, 0xe0, 0xe5, 0x72,
+ 0x96, 0x9f, 0x88, 0xb0, 0xae, 0xb7, 0xe8, 0x5c, 0x89, 0xd6, 0x95, 0x79,
+ 0xaf, 0xb1, 0x22, 0xef, 0x1d, 0xf5, 0xf2, 0xda, 0xcf, 0xa9, 0xbc, 0xd7,
+ 0xe5, 0x31, 0xf7, 0x12, 0xcc, 0xa3, 0x6c, 0x60, 0x21, 0xbf, 0xa9, 0x10,
+ 0x1f, 0x26, 0x94, 0xdf, 0xca, 0x4f, 0xdf, 0x09, 0x3e, 0x47, 0x57, 0xd1,
+ 0x9b, 0x8f, 0xda, 0x4f, 0xf8, 0x7b, 0x3f, 0x2c, 0x6e, 0xbd, 0x6e, 0x27,
+ 0x68, 0x61, 0x6e, 0x15, 0xf2, 0xf4, 0xe1, 0xbb, 0xde, 0x39, 0x53, 0x7f,
+ 0x9c, 0x9f, 0xc7, 0xd7, 0xbe, 0xbb, 0x16, 0x33, 0xcb, 0xea, 0x27, 0x1b,
+ 0x09, 0xc3, 0x90, 0x7b, 0xe6, 0x1a, 0xbe, 0x5b, 0x7c, 0x90, 0xf3, 0x11,
+ 0x8d, 0x7e, 0x8d, 0xdf, 0x4d, 0xf9, 0xad, 0x54, 0xb4, 0xbb, 0x7b, 0x6d,
+ 0xd8, 0x00, 0xcf, 0x2c, 0x07, 0xf1, 0x35, 0x2c, 0xf9, 0x39, 0x09, 0x47,
+ 0xd3, 0xfc, 0x06, 0x40, 0xff, 0xff, 0xba, 0xb7, 0xcf, 0x98, 0xec, 0x9f,
+ 0x71, 0x6b, 0x9e, 0xfa, 0x65, 0xcf, 0xc5, 0x1d, 0x00, 0x1f, 0x12, 0x47,
+ 0xfd, 0x9a, 0xa7, 0xee, 0x9e, 0x8b, 0x3b, 0xfa, 0xe1, 0x9d, 0x8b, 0xe3,
+ 0xfc, 0xa6, 0xec, 0x5a, 0xe5, 0x5c, 0x9c, 0x71, 0x95, 0xe7, 0xe2, 0xda,
+ 0x55, 0xcd, 0x93, 0xf3, 0xb8, 0x35, 0x4f, 0xb6, 0xbb, 0xfb, 0x59, 0x2b,
+ 0xe1, 0xd9, 0xb7, 0x01, 0x75, 0x06, 0xb9, 0xbb, 0xff, 0x47, 0x91, 0xa3,
+ 0x7c, 0x3d, 0xf2, 0xd1, 0xe7, 0x28, 0xdc, 0xcb, 0xaf, 0xb8, 0xdf, 0x77,
+ 0xe5, 0x5a, 0xea, 0x00, 0x1f, 0xac, 0xae, 0xb9, 0x5f, 0xd5, 0x35, 0xbf,
+ 0x13, 0x09, 0xd6, 0x35, 0xf5, 0x2b, 0x9c, 0x0d, 0xdb, 0xbf, 0x4a, 0x5d,
+ 0x33, 0x14, 0x38, 0x1b, 0x16, 0xf2, 0xce, 0x86, 0xb5, 0xdb, 0xc8, 0x25,
+ 0xbd, 0x3a, 0xa6, 0x7e, 0xd9, 0xb3, 0x61, 0xff, 0x19, 0xf9, 0xe0, 0x75,
+ 0xcc, 0x15, 0x67, 0xc3, 0xe0, 0xeb, 0x36, 0x48, 0xfc, 0x9a, 0xf2, 0x9e,
+ 0x0f, 0x92, 0xf3, 0xf0, 0xbc, 0x7e, 0x13, 0xf6, 0x1c, 0x92, 0x5d, 0x51,
+ 0xea, 0x27, 0xcf, 0x36, 0xf6, 0xc2, 0x16, 0x70, 0xad, 0xb0, 0x9d, 0xa4,
+ 0x8c, 0xb4, 0x91, 0xde, 0xe5, 0xe7, 0x10, 0xea, 0xe7, 0x71, 0xc3, 0xb5,
+ 0xf3, 0xb8, 0x47, 0xa0, 0x37, 0xfa, 0x4c, 0x58, 0x16, 0x02, 0x3a, 0x35,
+ 0x85, 0x78, 0x4f, 0x9f, 0xb3, 0xbc, 0xe7, 0xfc, 0x9f, 0x8a, 0x28, 0x30,
+ 0x8f, 0x67, 0x78, 0xdb, 0xc4, 0x98, 0x73, 0xbf, 0x59, 0xba, 0xff, 0x57,
+ 0x12, 0xc3, 0x18, 0x9e, 0xf1, 0x0c, 0xc9, 0x01, 0x55, 0xb3, 0xf0, 0x75,
+ 0x79, 0xc7, 0x5a, 0x69, 0x59, 0x9f, 0xa9, 0xb7, 0xa3, 0xab, 0xf8, 0x7d,
+ 0xc4, 0x91, 0x33, 0xd4, 0xe7, 0x5b, 0x25, 0xe7, 0xd5, 0x83, 0x0a, 0x95,
+ 0x6d, 0x5e, 0x7e, 0xa1, 0xbe, 0xed, 0x80, 0x97, 0xdd, 0x9e, 0x0f, 0xc6,
+ 0xb5, 0xd4, 0x4d, 0x9f, 0x87, 0x35, 0x4e, 0xca, 0xd0, 0xf4, 0x96, 0xd8,
+ 0x38, 0xf0, 0x6e, 0x4c, 0xad, 0x79, 0x2d, 0x3c, 0xd7, 0x2e, 0xf1, 0xbd,
+ 0xf1, 0x6a, 0xf9, 0xee, 0xc7, 0xc7, 0x8f, 0x62, 0x7f, 0xdd, 0xd0, 0x8f,
+ 0x87, 0x25, 0x77, 0xe2, 0x66, 0x19, 0x9a, 0x4d, 0x80, 0x9e, 0x1f, 0x56,
+ 0x0b, 0x29, 0xc4, 0xd2, 0x4f, 0xf0, 0xdc, 0x18, 0x30, 0x14, 0x7c, 0x7b,
+ 0x66, 0xc5, 0x77, 0xec, 0xe0, 0x59, 0xb3, 0x64, 0xed, 0xec, 0xd0, 0x53,
+ 0x15, 0x09, 0x77, 0x90, 0xe6, 0x99, 0xfa, 0xd9, 0xef, 0xc5, 0xca, 0x0e,
+ 0xe5, 0xdb, 0x9e, 0xac, 0x2c, 0xab, 0xfd, 0x28, 0x19, 0x4e, 0x94, 0x9f,
+ 0x04, 0x2f, 0x5e, 0x51, 0xfe, 0xed, 0x88, 0x23, 0x37, 0x19, 0x42, 0x79,
+ 0x88, 0x06, 0x1e, 0xa8, 0x33, 0x1c, 0xee, 0xf7, 0xfd, 0x2e, 0x25, 0x57,
+ 0x17, 0x2b, 0x76, 0x06, 0xce, 0x60, 0xd4, 0x65, 0xeb, 0x9e, 0xcd, 0x70,
+ 0x65, 0xe1, 0x9e, 0x1f, 0x21, 0x3f, 0x97, 0x0e, 0xed, 0xb2, 0xdd, 0xf3,
+ 0x23, 0x3d, 0x73, 0xec, 0xeb, 0x6c, 0xf0, 0x7d, 0x61, 0xe8, 0x00, 0xcf,
+ 0x1d, 0xf1, 0xcc, 0x37, 0x69, 0x56, 0xb5, 0x8e, 0x55, 0xbf, 0x6d, 0x5f,
+ 0x5b, 0xcd, 0xd5, 0x5d, 0xb3, 0x5b, 0xad, 0x79, 0x9d, 0x87, 0x59, 0xfe,
+ 0x59, 0xef, 0x94, 0xf6, 0xff, 0xd4, 0x5d, 0x7b, 0x6c, 0x1b, 0xf7, 0x7d,
+ 0xff, 0xf2, 0x48, 0x3d, 0xac, 0xe7, 0x49, 0xa6, 0x64, 0x5a, 0x52, 0x94,
+ 0x3b, 0xe9, 0x64, 0x29, 0xb1, 0x12, 0x70, 0x9e, 0xba, 0x0a, 0x88, 0x9a,
+ 0xb0, 0x24, 0xfd, 0x58, 0x10, 0x0c, 0xb4, 0xad, 0x64, 0xee, 0x92, 0xad,
+ 0x0e, 0x25, 0xa7, 0x1d, 0x30, 0x60, 0x6e, 0xd6, 0x02, 0x69, 0x07, 0xc7,
+ 0x0c, 0x65, 0x27, 0xc6, 0xaa, 0x88, 0x4c, 0xcc, 0x6a, 0x1d, 0xb0, 0x62,
+ 0x1c, 0xa5, 0x38, 0x69, 0xa7, 0x80, 0x69, 0xda, 0x04, 0xc5, 0xfe, 0xb1,
+ 0x26, 0x3b, 0x7b, 0x61, 0x7f, 0x04, 0xdb, 0x80, 0x1a, 0x5b, 0x81, 0xba,
+ 0x76, 0x8a, 0x65, 0x1b, 0xe0, 0x34, 0xdb, 0xb0, 0x75, 0x58, 0x0b, 0xee,
+ 0xfb, 0xf9, 0x3d, 0xc8, 0x23, 0x79, 0xd4, 0xc3, 0x71, 0x06, 0x4c, 0x80,
+ 0x40, 0xde, 0xf1, 0x77, 0x77, 0xbf, 0xdf, 0xf7, 0xf7, 0x7d, 0xbf, 0x6e,
+ 0x2e, 0x33, 0x1e, 0xf2, 0x33, 0x7e, 0xcf, 0x15, 0x61, 0x5f, 0x37, 0xd2,
+ 0xe1, 0x36, 0x83, 0x67, 0xa4, 0x0e, 0x9e, 0xd5, 0x34, 0xc1, 0xf6, 0x78,
+ 0x99, 0x77, 0x4b, 0xd8, 0xc9, 0xf3, 0xc8, 0x63, 0xd7, 0x39, 0x0e, 0x12,
+ 0x76, 0x65, 0x1a, 0x5a, 0x72, 0xe7, 0x37, 0x54, 0x60, 0x77, 0xb2, 0x0c,
+ 0xbb, 0x3d, 0xff, 0x8f, 0x60, 0x77, 0x4d, 0xe8, 0xbf, 0xdf, 0x2e, 0x22,
+ 0x6f, 0x4d, 0xeb, 0x00, 0xba, 0x6e, 0x09, 0x70, 0x04, 0x3f, 0xb5, 0xf3,
+ 0xeb, 0x04, 0x9e, 0x8a, 0xbc, 0xe2, 0x52, 0xe9, 0x3b, 0xe1, 0xb2, 0x9f,
+ 0x92, 0xed, 0x12, 0xd8, 0x27, 0xf0, 0xe7, 0x35, 0x96, 0x91, 0x47, 0x6f,
+ 0x4b, 0x46, 0x42, 0x57, 0xaa, 0xb5, 0x4f, 0x7e, 0xbb, 0xcb, 0x6d, 0x9f,
+ 0x1c, 0xdd, 0xa1, 0x7d, 0x72, 0x5a, 0xda, 0x27, 0xa9, 0xed, 0xdb, 0x27,
+ 0x03, 0x75, 0x79, 0x5d, 0x95, 0xf5, 0xec, 0xdc, 0x3e, 0x31, 0x36, 0xb5,
+ 0x4f, 0x46, 0x5d, 0xbe, 0x18, 0xcc, 0xf7, 0x57, 0x29, 0x75, 0x0c, 0x3c,
+ 0x4e, 0xc3, 0x19, 0x30, 0x3e, 0x56, 0xe3, 0x17, 0xfe, 0x38, 0x61, 0xfd,
+ 0xd7, 0xff, 0xc7, 0xb0, 0x1e, 0xac, 0xf3, 0x79, 0x57, 0xd6, 0x03, 0x21,
+ 0xfe, 0x51, 0x60, 0x3d, 0xd8, 0xd0, 0x77, 0xda, 0x38, 0x67, 0xb1, 0xda,
+ 0x77, 0x3a, 0x62, 0x34, 0xe2, 0xed, 0x7f, 0xe4, 0xf2, 0xa9, 0xba, 0xf9,
+ 0x3b, 0x68, 0x8a, 0x7c, 0x47, 0xc7, 0xf5, 0xb3, 0x40, 0x4b, 0x76, 0x2a,
+ 0x45, 0xb0, 0x99, 0xf0, 0xbc, 0x90, 0xa0, 0xb5, 0x1a, 0x7d, 0x8b, 0x9f,
+ 0xc7, 0xeb, 0x7b, 0xf5, 0x09, 0x21, 0xa7, 0xa4, 0xff, 0x01, 0xe3, 0x27,
+ 0x7c, 0xf3, 0x62, 0xac, 0xcc, 0x6f, 0x52, 0xfe, 0x08, 0xa5, 0xfb, 0x37,
+ 0xf2, 0x43, 0xd4, 0xcb, 0xbc, 0x9d, 0xd9, 0x0a, 0x9a, 0xc6, 0xef, 0xe6,
+ 0x7d, 0x09, 0x55, 0xd9, 0x5a, 0xe0, 0x9f, 0xa7, 0x59, 0x2f, 0x18, 0x29,
+ 0xeb, 0x04, 0xd5, 0x7b, 0x73, 0x4e, 0xd8, 0x74, 0x9a, 0x77, 0x26, 0x64,
+ 0xee, 0xa9, 0x38, 0x0f, 0x3d, 0x4d, 0xf3, 0xce, 0x5a, 0x3d, 0xf8, 0x6e,
+ 0x0f, 0xbc, 0xf0, 0xca, 0x69, 0x2a, 0xef, 0x9d, 0x85, 0x9c, 0xf3, 0xb8,
+ 0xe7, 0xde, 0x95, 0x6b, 0xc2, 0x52, 0x95, 0xb1, 0xf2, 0xfa, 0xb8, 0x58,
+ 0xd7, 0x0f, 0x8e, 0x44, 0x51, 0xfb, 0x56, 0xae, 0x17, 0xab, 0xad, 0x77,
+ 0x82, 0x1c, 0xd0, 0x74, 0xa8, 0x6b, 0xa2, 0x01, 0x8b, 0x61, 0x8f, 0x7a,
+ 0x27, 0xb7, 0x2c, 0xc1, 0x75, 0xb5, 0xb0, 0xa8, 0xc8, 0x91, 0xf3, 0x4a,
+ 0x8e, 0x14, 0x5c, 0x7c, 0xbc, 0x5e, 0x6f, 0xef, 0xf5, 0xd0, 0xdb, 0xbd,
+ 0x6a, 0x9e, 0x30, 0xa7, 0x67, 0x58, 0x0f, 0xb9, 0x1f, 0x7a, 0x88, 0x89,
+ 0xba, 0x25, 0xa9, 0x8b, 0xe0, 0x77, 0x96, 0x35, 0xaf, 0x86, 0x18, 0x57,
+ 0x8e, 0xd0, 0x53, 0xac, 0x6b, 0x5f, 0xa2, 0x7b, 0x94, 0x7d, 0x16, 0x71,
+ 0xe5, 0x99, 0x22, 0x8f, 0xdf, 0x47, 0xa9, 0x27, 0xec, 0x89, 0x08, 0x1d,
+ 0xa1, 0x53, 0x22, 0x67, 0x06, 0xf1, 0x3d, 0xe4, 0x1c, 0xdc, 0x2b, 0x9e,
+ 0x2f, 0x7d, 0x19, 0x77, 0x22, 0xa7, 0x6e, 0xfb, 0xf9, 0xfb, 0xba, 0x56,
+ 0x2f, 0x2a, 0x9e, 0xb9, 0xaa, 0x68, 0x4a, 0x9c, 0xe3, 0xeb, 0x9f, 0x31,
+ 0xea, 0xaf, 0x8f, 0x18, 0xf1, 0x62, 0xdc, 0x88, 0xae, 0x60, 0xdc, 0x33,
+ 0x46, 0xac, 0x08, 0x1b, 0x52, 0xe3, 0x88, 0x1d, 0x06, 0xbd, 0x6d, 0xd0,
+ 0xd6, 0xb1, 0x88, 0x02, 0xd5, 0xd4, 0x49, 0x6c, 0x63, 0xde, 0x87, 0xaa,
+ 0xe6, 0xad, 0xe1, 0x8b, 0xef, 0xf0, 0xf7, 0x44, 0x18, 0xa6, 0x5a, 0xaf,
+ 0x6d, 0x83, 0x7f, 0x7d, 0x22, 0x45, 0x9b, 0xe9, 0xb5, 0x76, 0x9d, 0x5e,
+ 0x5b, 0xd8, 0x72, 0xde, 0x1f, 0x95, 0xc6, 0x65, 0x3d, 0xa2, 0xdf, 0x11,
+ 0xfa, 0x2b, 0xcf, 0xbb, 0x4a, 0xb7, 0xad, 0xc1, 0x29, 0x8c, 0xd1, 0x7e,
+ 0x70, 0xed, 0x07, 0xeb, 0x52, 0xf9, 0xc0, 0x3a, 0x3f, 0xa1, 0x0d, 0xf5,
+ 0x5e, 0xa6, 0xcc, 0x6b, 0x85, 0x8d, 0xb5, 0xce, 0xf3, 0x83, 0xbd, 0xf5,
+ 0xa0, 0x98, 0x23, 0xdb, 0x5b, 0x56, 0x8c, 0xa4, 0xaf, 0x7b, 0xbe, 0x58,
+ 0x55, 0xff, 0xe9, 0x51, 0x07, 0x39, 0xe2, 0x51, 0x07, 0xe9, 0xa6, 0xb5,
+ 0x80, 0x8b, 0xd6, 0x42, 0x2e, 0xbd, 0x6d, 0x88, 0xed, 0x96, 0x0e, 0xe6,
+ 0x21, 0xb0, 0x5b, 0xda, 0xc8, 0xff, 0xb2, 0xdb, 0x6e, 0xa9, 0xad, 0x45,
+ 0x07, 0xdd, 0x41, 0x37, 0x93, 0x36, 0x4c, 0x3c, 0x57, 0xae, 0x63, 0xe7,
+ 0x75, 0x57, 0x6a, 0x0e, 0x57, 0xea, 0xea, 0x23, 0xbd, 0xe6, 0x3b, 0x5c,
+ 0x37, 0x5f, 0xc8, 0xaf, 0x48, 0x43, 0x9d, 0xce, 0xcb, 0xae, 0xba, 0x53,
+ 0xf3, 0xab, 0xe5, 0x67, 0x78, 0xd6, 0x88, 0xf0, 0x79, 0xa7, 0xca, 0xbc,
+ 0x6c, 0x5a, 0xce, 0x37, 0x53, 0x6d, 0x67, 0xf8, 0x97, 0x48, 0xc1, 0xce,
+ 0x9b, 0xb7, 0xef, 0xcc, 0x7f, 0xd6, 0x5e, 0x23, 0x77, 0xdf, 0x33, 0xa5,
+ 0x5f, 0xac, 0x49, 0xe5, 0x61, 0xf7, 0x29, 0x7b, 0x6f, 0x2b, 0x7c, 0xc7,
+ 0xb9, 0x26, 0xe5, 0x4b, 0xb4, 0xad, 0x3c, 0x01, 0xcf, 0x8f, 0x9d, 0x68,
+ 0x72, 0x4c, 0x15, 0xcb, 0x42, 0xbc, 0x0a, 0x78, 0xaf, 0xef, 0x0f, 0x9e,
+ 0xbd, 0x9d, 0x3d, 0xb3, 0xea, 0xf6, 0x4c, 0xe2, 0x15, 0x6c, 0x2d, 0xe4,
+ 0x17, 0x4f, 0xd6, 0xe4, 0x78, 0x7f, 0x14, 0x58, 0x74, 0x79, 0xe4, 0x3d,
+ 0x23, 0x6f, 0xb9, 0xd1, 0x3c, 0xaf, 0xbb, 0xf4, 0x72, 0xcc, 0xb7, 0x54,
+ 0x7a, 0x23, 0x3c, 0x20, 0x65, 0x71, 0xd1, 0x5b, 0x47, 0x32, 0xb7, 0x3d,
+ 0xbf, 0x5a, 0xd9, 0xbb, 0x77, 0x9b, 0xb2, 0x57, 0xf4, 0xf4, 0xf0, 0x1d,
+ 0x14, 0x3c, 0xa0, 0x83, 0x56, 0x72, 0xc8, 0xbf, 0xfe, 0x05, 0xd0, 0x3c,
+ 0xf3, 0x59, 0x57, 0x4d, 0x9a, 0xf7, 0x3e, 0x96, 0x63, 0x2a, 0x81, 0x19,
+ 0xc4, 0xfe, 0x90, 0x5b, 0xd2, 0xcb, 0xbc, 0x07, 0xe3, 0xc7, 0xac, 0xab,
+ 0xf0, 0xf7, 0x2a, 0xff, 0x53, 0x5c, 0xc9, 0x97, 0x83, 0xdb, 0x88, 0xad,
+ 0xec, 0x8c, 0x4f, 0xdb, 0xd6, 0x3a, 0x21, 0xee, 0x83, 0x7c, 0xe1, 0xfb,
+ 0xba, 0xa8, 0xeb, 0x33, 0x2d, 0x2d, 0xce, 0x97, 0x7a, 0x64, 0x2c, 0x0a,
+ 0xbf, 0x75, 0xd0, 0x2b, 0x39, 0xe4, 0x72, 0xe3, 0xb7, 0xdf, 0xe0, 0xdf,
+ 0xbc, 0x78, 0x94, 0xce, 0x45, 0x87, 0x2e, 0x27, 0xf7, 0x27, 0x4f, 0xb0,
+ 0x95, 0x4a, 0xf4, 0xb7, 0xe1, 0x5f, 0x94, 0xf1, 0x8c, 0xe2, 0x9d, 0x8e,
+ 0xd5, 0x78, 0xf9, 0x0b, 0xdf, 0xec, 0xb9, 0xdd, 0xdc, 0xc8, 0x2f, 0x6c,
+ 0xcb, 0x5f, 0x88, 0x38, 0xff, 0x76, 0x62, 0x26, 0x3a, 0x36, 0x3c, 0x25,
+ 0x6a, 0x4e, 0xdd, 0x78, 0x70, 0x67, 0xe2, 0xc3, 0xc0, 0x87, 0xe1, 0x3a,
+ 0x5e, 0xf5, 0xd1, 0xfd, 0xfd, 0xb5, 0x70, 0x6d, 0xf3, 0xf4, 0x55, 0x79,
+ 0xc7, 0x81, 0x11, 0xf3, 0x87, 0x9f, 0xfa, 0x21, 0x9a, 0xbf, 0x08, 0x1c,
+ 0x36, 0x18, 0xdb, 0x46, 0x69, 0x21, 0x88, 0xba, 0x22, 0x51, 0x9b, 0xa3,
+ 0xe2, 0x86, 0xb2, 0x56, 0x68, 0x5e, 0xd4, 0x40, 0x8e, 0x85, 0x6e, 0xf2,
+ 0xbc, 0xe7, 0x8b, 0x29, 0x3a, 0xc5, 0x32, 0xf6, 0xd4, 0x4a, 0x45, 0x77,
+ 0xaf, 0xaf, 0x83, 0xac, 0xc6, 0xf1, 0x9b, 0x02, 0xc7, 0x87, 0x36, 0xc5,
+ 0xf1, 0xc3, 0x65, 0x1c, 0xff, 0x44, 0xaf, 0xc4, 0xe7, 0x67, 0xf9, 0x5e,
+ 0x5d, 0x74, 0x50, 0xdc, 0x37, 0xc5, 0xdf, 0xdb, 0xe9, 0xa0, 0xec, 0x61,
+ 0xc1, 0xcf, 0x66, 0x1e, 0x9f, 0x49, 0xd1, 0x53, 0x17, 0x53, 0xbe, 0xb8,
+ 0xa8, 0x5f, 0x70, 0xf7, 0xe8, 0xd0, 0xd7, 0x63, 0x5c, 0x23, 0xfc, 0xd7,
+ 0x7c, 0x49, 0xd6, 0x5c, 0xe5, 0x25, 0x7f, 0xa2, 0x77, 0xc3, 0x83, 0x35,
+ 0xf8, 0x5f, 0x6d, 0x3b, 0x9e, 0x56, 0x32, 0xf0, 0xd8, 0x26, 0x7e, 0x8d,
+ 0x7a, 0xbc, 0xec, 0xf1, 0xd0, 0x87, 0x7f, 0xbd, 0x57, 0xc6, 0xa9, 0x36,
+ 0xf3, 0x6b, 0xb8, 0x71, 0xb4, 0x2a, 0x6e, 0xcf, 0x7c, 0xff, 0xbf, 0x55,
+ 0x1c, 0xfd, 0xa5, 0x5e, 0x29, 0x2f, 0x50, 0x1f, 0x98, 0x60, 0x38, 0x9c,
+ 0x64, 0x5d, 0x65, 0x90, 0x9a, 0x5f, 0xd6, 0x6b, 0x1d, 0x14, 0xfc, 0xd6,
+ 0xed, 0xa7, 0x39, 0xa7, 0x6a, 0xbb, 0xd3, 0xae, 0x35, 0x9d, 0x13, 0x36,
+ 0x4e, 0x63, 0x7a, 0x6b, 0x9c, 0x73, 0x35, 0x54, 0x23, 0x13, 0x6a, 0xf1,
+ 0x0d, 0xbd, 0x4f, 0xb0, 0xbf, 0x64, 0x48, 0x3d, 0x78, 0x9a, 0xf5, 0xdb,
+ 0x9d, 0xc6, 0x8b, 0x3e, 0xaa, 0x8e, 0x58, 0xdb, 0x53, 0xa3, 0xf6, 0x3b,
+ 0xf6, 0x41, 0xda, 0x1c, 0xc9, 0x57, 0x1f, 0x12, 0xbc, 0xe0, 0xdc, 0x64,
+ 0x89, 0x62, 0xe1, 0x4e, 0x4a, 0x4e, 0xf2, 0xb3, 0xa7, 0x1d, 0xb6, 0xbd,
+ 0xfc, 0x94, 0x62, 0xfa, 0x4d, 0x4e, 0xee, 0x52, 0xfa, 0xa2, 0xf6, 0xa7,
+ 0xb7, 0xa8, 0x3c, 0x87, 0x67, 0x45, 0x5c, 0x52, 0xf6, 0xc6, 0xe0, 0xef,
+ 0x2b, 0xfa, 0xde, 0xcf, 0x8a, 0xf8, 0x68, 0xf2, 0x62, 0xb3, 0x1a, 0xd7,
+ 0xee, 0x1a, 0x87, 0x31, 0xed, 0x6a, 0x2c, 0xee, 0xa9, 0x75, 0x8a, 0x56,
+ 0xc5, 0x6f, 0x1f, 0x11, 0x75, 0x60, 0xb2, 0x56, 0x0f, 0xbf, 0x9f, 0xa6,
+ 0xb9, 0xf2, 0x5a, 0xda, 0x79, 0xec, 0xcf, 0x4a, 0x11, 0x61, 0xcb, 0xb5,
+ 0xb3, 0xce, 0x8b, 0x79, 0xd7, 0xcf, 0x09, 0x6b, 0xf1, 0x8b, 0xf8, 0x10,
+ 0x7f, 0x57, 0xcf, 0x39, 0x59, 0x9e, 0x13, 0x72, 0x34, 0xec, 0x90, 0xbc,
+ 0x97, 0x1e, 0xd7, 0xee, 0x1a, 0xa7, 0x79, 0x85, 0x8e, 0x3f, 0xfc, 0x80,
+ 0xe7, 0xf1, 0x37, 0x2a, 0x87, 0xd7, 0x14, 0xf1, 0x53, 0x99, 0xa3, 0xa1,
+ 0xbf, 0xc3, 0xbf, 0x8c, 0x9c, 0x0a, 0xe4, 0x49, 0xb8, 0xf9, 0x8d, 0x5c,
+ 0x6f, 0x00, 0xb2, 0xa8, 0x88, 0xb8, 0x29, 0xe2, 0x15, 0x8d, 0x74, 0xe7,
+ 0xbd, 0xc8, 0xcd, 0xdf, 0x81, 0x0e, 0xba, 0x1d, 0xfa, 0xb3, 0x3c, 0xe8,
+ 0xcf, 0xfd, 0x7c, 0xd4, 0xc1, 0xa1, 0x1e, 0x2e, 0x35, 0x61, 0x50, 0x89,
+ 0x6d, 0x05, 0x83, 0xf2, 0xa6, 0x8f, 0x9e, 0x72, 0xec, 0xf0, 0x0a, 0xc9,
+ 0x9a, 0xc9, 0xd8, 0xa2, 0x3d, 0xb1, 0x4e, 0xfb, 0x45, 0xcd, 0x38, 0x7a,
+ 0x1f, 0xe4, 0x59, 0x06, 0x9f, 0xa4, 0x09, 0xb6, 0x8f, 0xd8, 0xfe, 0x9c,
+ 0x45, 0xbc, 0x45, 0xef, 0x0b, 0x6a, 0xe0, 0xf1, 0x39, 0xc1, 0x70, 0x7a,
+ 0x6c, 0x37, 0xb5, 0x45, 0xf8, 0x9e, 0x13, 0xe0, 0x4f, 0xe8, 0xe7, 0x45,
+ 0x51, 0xb6, 0x93, 0x60, 0xb3, 0x9e, 0x9c, 0xb5, 0xcd, 0x3c, 0x19, 0x3c,
+ 0x16, 0xb6, 0x2b, 0xee, 0x83, 0xeb, 0x23, 0x66, 0x13, 0xd5, 0xd6, 0xe4,
+ 0x3e, 0x2b, 0xea, 0x14, 0xdf, 0x0d, 0xdf, 0x47, 0x46, 0x3f, 0xf8, 0x15,
+ 0xf6, 0xed, 0x5e, 0x15, 0x27, 0x3a, 0xcb, 0xdf, 0xc7, 0xd5, 0xf7, 0xaf,
+ 0x88, 0xfd, 0x94, 0xdf, 0x35, 0x7e, 0xe3, 0xef, 0x5f, 0x5a, 0xc8, 0xf9,
+ 0xa1, 0xca, 0x59, 0xa9, 0xca, 0x05, 0x09, 0x8d, 0x1a, 0x5f, 0xa1, 0xd3,
+ 0x2b, 0x9b, 0xf9, 0x5f, 0xbc, 0x6a, 0x5d, 0xbb, 0xb7, 0x59, 0xeb, 0xfa,
+ 0x07, 0xbb, 0x65, 0x6d, 0x99, 0x7b, 0x2e, 0xff, 0xc9, 0x73, 0xf1, 0xd2,
+ 0xc9, 0xea, 0xf4, 0x44, 0x5e, 0x6f, 0x89, 0xfe, 0x29, 0xfc, 0x49, 0xba,
+ 0x1e, 0x0c, 0xa9, 0x9c, 0x25, 0xe4, 0x28, 0xdd, 0xa7, 0xf0, 0x5a, 0xf3,
+ 0x7e, 0xf2, 0xe0, 0xfd, 0x8f, 0x89, 0x5c, 0x4d, 0x29, 0x3b, 0x06, 0x15,
+ 0x3c, 0x00, 0xb3, 0x90, 0x0b, 0x66, 0x7d, 0x2e, 0x98, 0x19, 0xea, 0x7b,
+ 0xa7, 0x38, 0x3e, 0xbd, 0xf2, 0x99, 0x6e, 0x59, 0x2f, 0x8e, 0x58, 0xe2,
+ 0xbc, 0xfa, 0xbe, 0xd5, 0x7a, 0x7f, 0xce, 0x6b, 0x15, 0xfe, 0x26, 0xd7,
+ 0x5a, 0x5f, 0x27, 0x72, 0x5a, 0x82, 0xf5, 0x30, 0xf8, 0x8e, 0xeb, 0x3c,
+ 0xe6, 0x38, 0xe6, 0x9a, 0xe3, 0x88, 0x6b, 0x8e, 0x77, 0x37, 0x98, 0x23,
+ 0xf3, 0xf8, 0xe2, 0x69, 0xfe, 0xbf, 0xdd, 0xb9, 0xca, 0x79, 0xce, 0x0b,
+ 0x78, 0xb6, 0x53, 0x3a, 0x18, 0x52, 0xb2, 0xe3, 0xfb, 0xaa, 0x16, 0xdd,
+ 0x6b, 0xce, 0xff, 0x40, 0x8d, 0xf7, 0xcd, 0x8d, 0xab, 0xee, 0xfa, 0xe3,
+ 0x97, 0x28, 0x26, 0xeb, 0xc8, 0x15, 0x6d, 0x7f, 0xb5, 0x81, 0x1f, 0xfa,
+ 0x41, 0xa1, 0xff, 0xcc, 0xcb, 0x78, 0xd0, 0x80, 0xec, 0xbf, 0x16, 0xa0,
+ 0xd5, 0x72, 0x2d, 0xaf, 0x5f, 0xd5, 0xee, 0xdc, 0x1f, 0xbc, 0xb3, 0x75,
+ 0xbc, 0x38, 0xff, 0x88, 0xf0, 0xe5, 0xc9, 0xf8, 0x51, 0x42, 0xd5, 0x23,
+ 0xdb, 0x16, 0x72, 0x03, 0x0a, 0x6b, 0xf0, 0xbf, 0x36, 0xaa, 0xdd, 0xc5,
+ 0xb5, 0xf0, 0x03, 0x6a, 0x3b, 0xfe, 0x84, 0xe0, 0x89, 0xd2, 0x3f, 0x26,
+ 0xeb, 0x6f, 0x0b, 0x6b, 0x27, 0x45, 0xcd, 0x6b, 0x54, 0xd5, 0xf1, 0x26,
+ 0xa9, 0x43, 0xe8, 0xb9, 0xb7, 0x5f, 0x7f, 0xfb, 0x5c, 0x70, 0xe7, 0xf5,
+ 0xb7, 0xee, 0x6b, 0x76, 0x56, 0x7f, 0x6b, 0xf2, 0xda, 0x8d, 0x65, 0x59,
+ 0x7f, 0x5b, 0x1d, 0x93, 0x91, 0xfe, 0xc0, 0xa4, 0x4b, 0x7f, 0x90, 0xfa,
+ 0xfa, 0x6f, 0xb9, 0xf2, 0xb7, 0x65, 0x6d, 0x6d, 0xa1, 0xac, 0xb3, 0xca,
+ 0xda, 0x5a, 0x99, 0xef, 0xed, 0xee, 0x03, 0x23, 0x63, 0x3f, 0xf2, 0x39,
+ 0x9d, 0x35, 0xb1, 0x1f, 0x59, 0x53, 0x6b, 0x19, 0x8d, 0x6c, 0x38, 0xd1,
+ 0xe7, 0xa2, 0x8f, 0xba, 0x22, 0x8c, 0xbb, 0xed, 0x0d, 0xfa, 0x21, 0x44,
+ 0x1a, 0xf4, 0x43, 0x70, 0xf3, 0x7e, 0xb7, 0x8e, 0x05, 0x9d, 0x18, 0xb2,
+ 0x11, 0xba, 0x30, 0xfa, 0x19, 0x84, 0xe9, 0x74, 0x59, 0xf7, 0xbc, 0x8f,
+ 0x12, 0x4a, 0xf7, 0x3c, 0xbd, 0xa2, 0xf9, 0xd1, 0x48, 0x0d, 0x3f, 0xf2,
+ 0xd2, 0x45, 0x6d, 0x95, 0xe7, 0xa3, 0xe9, 0x35, 0xe5, 0xa2, 0xd7, 0x94,
+ 0x07, 0xbd, 0x8a, 0x67, 0x34, 0x98, 0xf7, 0xf7, 0xd5, 0x35, 0xf8, 0x4f,
+ 0x84, 0xd0, 0xb3, 0x85, 0x79, 0x6a, 0x50, 0xe9, 0x7f, 0x2e, 0x7a, 0x3d,
+ 0xc5, 0xf4, 0xaa, 0xcf, 0x63, 0xbe, 0x0d, 0x73, 0x41, 0x95, 0xce, 0x38,
+ 0xe8, 0x3b, 0x74, 0xf1, 0x1b, 0x22, 0x4f, 0xaa, 0xda, 0x5e, 0xd4, 0xfa,
+ 0xc4, 0x3e, 0x41, 0x4b, 0xd7, 0xfd, 0xc8, 0x5b, 0xd1, 0xe7, 0x4c, 0xe5,
+ 0x27, 0xd3, 0xb0, 0x68, 0xae, 0xd2, 0x39, 0x2a, 0xfa, 0x86, 0xc8, 0xf1,
+ 0x75, 0xcd, 0xed, 0x43, 0x9e, 0x9b, 0x3e, 0xaf, 0x65, 0xe6, 0xb5, 0x2a,
+ 0x7f, 0xc6, 0xe5, 0xaa, 0x9e, 0x83, 0xf0, 0x1d, 0x75, 0x26, 0x0c, 0x27,
+ 0x2e, 0x72, 0x4c, 0x7b, 0x1c, 0xf8, 0xc9, 0xa2, 0x4c, 0xfb, 0x3d, 0x09,
+ 0xe4, 0x33, 0xf7, 0x2c, 0x59, 0x74, 0x3c, 0x73, 0xff, 0x5d, 0x12, 0x57,
+ 0xce, 0x8a, 0x3e, 0x92, 0xe8, 0x67, 0x16, 0x63, 0xf9, 0x1c, 0xf5, 0x4f,
+ 0xd3, 0xf9, 0x62, 0x0b, 0x15, 0x58, 0xbb, 0xf7, 0x3b, 0x79, 0xe1, 0xeb,
+ 0x63, 0x9e, 0x94, 0x45, 0x2f, 0x51, 0x63, 0xb9, 0x99, 0xef, 0xdb, 0x4f,
+ 0xab, 0xb9, 0x31, 0xd1, 0x13, 0x4a, 0xf6, 0x17, 0xc1, 0x58, 0x1f, 0xf5,
+ 0x3a, 0x07, 0xfb, 0xa8, 0xed, 0xb3, 0x22, 0xc7, 0xb2, 0x90, 0x3d, 0x2b,
+ 0x3f, 0xf3, 0x0f, 0xa8, 0x67, 0xf0, 0xf3, 0x8a, 0x7f, 0x4a, 0x91, 0x5e,
+ 0xcb, 0x65, 0xcb, 0xb9, 0xff, 0xbc, 0xf5, 0x95, 0xa3, 0x3b, 0xd2, 0x57,
+ 0x52, 0x89, 0x8a, 0xbe, 0xe2, 0xbe, 0x77, 0x39, 0x07, 0xa6, 0x5f, 0xf6,
+ 0x7b, 0x00, 0x0c, 0xda, 0xa1, 0x8b, 0x25, 0x00, 0x4b, 0x63, 0xc6, 0x0e,
+ 0x45, 0xfd, 0x53, 0xb4, 0x50, 0x1c, 0x32, 0x92, 0x59, 0xe8, 0xcc, 0xfc,
+ 0x99, 0x8f, 0xee, 0x91, 0x3e, 0x1a, 0x7d, 0x0d, 0xf8, 0xca, 0x6e, 0x1e,
+ 0xff, 0x7a, 0xbf, 0xcc, 0xcb, 0x76, 0x9f, 0xef, 0xe2, 0xf3, 0x7b, 0x42,
+ 0xd5, 0xe7, 0x77, 0xf1, 0xf9, 0xde, 0x04, 0xf6, 0xd0, 0x58, 0x82, 0x5f,
+ 0xd2, 0xa1, 0x34, 0xef, 0xcd, 0x42, 0x91, 0x65, 0xeb, 0xcb, 0xcc, 0x47,
+ 0x57, 0xf4, 0xb8, 0x3e, 0xd4, 0xec, 0x88, 0x3d, 0x31, 0x78, 0xcc, 0xb9,
+ 0xcc, 0x04, 0x8f, 0x1b, 0x24, 0xff, 0xcb, 0x6c, 0x8b, 0xae, 0x68, 0x5c,
+ 0xd5, 0xf9, 0xf6, 0xdf, 0xe8, 0x93, 0x39, 0x55, 0xdf, 0xdd, 0x23, 0xe1,
+ 0xe7, 0x08, 0x9e, 0x72, 0x9e, 0xe1, 0xf2, 0xbc, 0xc0, 0x43, 0x7b, 0xda,
+ 0x2a, 0x3f, 0xbf, 0x13, 0x78, 0xd5, 0x8a, 0xbc, 0xd9, 0xc0, 0x12, 0xf3,
+ 0xc5, 0x19, 0xc7, 0x4c, 0x97, 0x73, 0xd5, 0x1e, 0x1f, 0x90, 0xd7, 0xbf,
+ 0xd9, 0x27, 0xfb, 0x83, 0x7e, 0x6b, 0x40, 0xf7, 0x48, 0x94, 0x32, 0x07,
+ 0xf9, 0xcb, 0x3e, 0x01, 0x1b, 0xff, 0x32, 0xf8, 0xa5, 0xc1, 0xdf, 0x79,
+ 0x3d, 0x09, 0xcc, 0xf1, 0x4a, 0x9f, 0xee, 0x17, 0x23, 0xd7, 0x15, 0xe7,
+ 0xf9, 0x46, 0x78, 0x5d, 0xfa, 0xfc, 0x0c, 0x1f, 0x7b, 0xed, 0x2f, 0xee,
+ 0xd5, 0x96, 0x90, 0xfd, 0xc5, 0xda, 0x12, 0xc9, 0x09, 0xb9, 0xcf, 0x15,
+ 0x9f, 0x6e, 0xa8, 0xec, 0xd3, 0x3d, 0x9f, 0xb9, 0xd5, 0x07, 0xff, 0x86,
+ 0xb1, 0xc4, 0xfb, 0x1d, 0x7c, 0x9e, 0xc7, 0xa2, 0x56, 0x21, 0xcd, 0x9f,
+ 0x1d, 0x2a, 0xaf, 0xa7, 0x1e, 0x57, 0x64, 0x9e, 0x84, 0x96, 0x5b, 0xb8,
+ 0xf6, 0x43, 0xbe, 0x87, 0x94, 0x5d, 0x8d, 0x9f, 0x43, 0x75, 0x79, 0x30,
+ 0xf5, 0x38, 0xb6, 0x99, 0x1f, 0x56, 0xc4, 0x13, 0x3d, 0xf0, 0x6c, 0xb3,
+ 0x7e, 0x06, 0xd7, 0x84, 0x1f, 0x2d, 0x56, 0x47, 0xaf, 0xa0, 0xe3, 0x00,
+ 0xfd, 0xce, 0x62, 0x8a, 0x76, 0xf1, 0x5e, 0xfd, 0xa6, 0xf1, 0x00, 0xe2,
+ 0xed, 0x24, 0x73, 0x9e, 0x18, 0xc6, 0x19, 0x67, 0xe2, 0x94, 0x11, 0x01,
+ 0xbf, 0x2c, 0x05, 0x9c, 0x0e, 0x6a, 0x66, 0x5a, 0xfd, 0x65, 0x1a, 0x65,
+ 0xfb, 0x0f, 0x34, 0xeb, 0x84, 0xe2, 0x04, 0x7a, 0xb3, 0xcd, 0x43, 0xac,
+ 0x13, 0xc7, 0x8a, 0xc0, 0x67, 0x83, 0x3e, 0x9f, 0x23, 0xfa, 0x5c, 0x6e,
+ 0xd4, 0xfc, 0x26, 0x39, 0x56, 0xe5, 0x77, 0xdb, 0x8c, 0xf2, 0x3c, 0xe2,
+ 0xc5, 0x2f, 0xd3, 0xfb, 0xa2, 0xcf, 0x09, 0xe0, 0xa8, 0xf7, 0xfd, 0x4b,
+ 0x74, 0x32, 0x81, 0x79, 0x6f, 0x9f, 0x3e, 0x8f, 0xef, 0x88, 0x3e, 0xdb,
+ 0x3c, 0xe8, 0xf3, 0xc5, 0x7e, 0x89, 0x37, 0x25, 0xc6, 0xd1, 0x36, 0x9a,
+ 0xcb, 0x22, 0x07, 0xec, 0xd3, 0xe8, 0x3b, 0x95, 0x4d, 0x32, 0x5f, 0x4a,
+ 0x56, 0xf8, 0xd2, 0x85, 0x28, 0x1b, 0xc3, 0x4c, 0xe3, 0xe8, 0xcb, 0xa6,
+ 0xf2, 0x7e, 0xb0, 0x8e, 0x01, 0x1a, 0x5d, 0x6e, 0xe7, 0x6b, 0x69, 0x3d,
+ 0x3a, 0x15, 0x51, 0xb5, 0xfe, 0xb6, 0x15, 0x63, 0xfe, 0x78, 0x9e, 0x69,
+ 0x39, 0x9d, 0xbd, 0x97, 0x0a, 0xc1, 0x21, 0x1a, 0x59, 0xd6, 0xfd, 0x4d,
+ 0x44, 0xce, 0xc6, 0xa0, 0xe4, 0x49, 0x7a, 0xdd, 0x9f, 0x10, 0xbe, 0x0b,
+ 0xeb, 0xd2, 0xc7, 0xb5, 0xee, 0xf6, 0x2d, 0xf8, 0xd2, 0x25, 0x45, 0xb3,
+ 0xa5, 0xcb, 0xd1, 0x30, 0xa5, 0xa2, 0x53, 0xaf, 0xf4, 0x03, 0xff, 0x47,
+ 0x2e, 0xc1, 0x0f, 0x07, 0x1e, 0x6d, 0x51, 0x22, 0x53, 0x0b, 0x8b, 0x21,
+ 0x5e, 0x37, 0x7e, 0x2f, 0x7d, 0x30, 0x17, 0x7e, 0x40, 0xc8, 0xfe, 0xd1,
+ 0x4b, 0x3c, 0x4e, 0xca, 0x26, 0xc5, 0x37, 0xbc, 0xf0, 0x50, 0xf7, 0xc5,
+ 0xd4, 0xb8, 0x28, 0x73, 0x3d, 0x59, 0x7f, 0x33, 0x13, 0xfe, 0x5a, 0x9c,
+ 0xbc, 0xe6, 0x3b, 0xba, 0x68, 0xd1, 0xb1, 0x8c, 0xfd, 0xf5, 0x14, 0x4d,
+ 0x31, 0x5d, 0xbb, 0xe5, 0x05, 0x8f, 0x27, 0xe0, 0xd9, 0x34, 0xd3, 0x3e,
+ 0xdb, 0xcd, 0x59, 0x4b, 0xe6, 0xdd, 0x89, 0xde, 0x73, 0x38, 0x46, 0xdd,
+ 0xf1, 0x5f, 0xf5, 0x6b, 0x79, 0x90, 0xcc, 0xa2, 0x8e, 0x90, 0x3f, 0xf3,
+ 0x3c, 0x1e, 0xb9, 0xff, 0x39, 0xdc, 0x07, 0xf2, 0x0e, 0x73, 0xe7, 0xe3,
+ 0x55, 0xb9, 0xaf, 0x23, 0x7c, 0x6f, 0xd4, 0xdd, 0x1f, 0x2b, 0x4e, 0xf2,
+ 0xfe, 0x76, 0x09, 0xde, 0x2c, 0xf7, 0x73, 0x9a, 0xce, 0x79, 0xf2, 0x15,
+ 0xb9, 0x2f, 0x49, 0x17, 0x7d, 0x27, 0x05, 0x7d, 0x4f, 0x8b, 0xfd, 0x48,
+ 0xe6, 0x0c, 0xd6, 0xd7, 0xb4, 0xef, 0x81, 0xed, 0xec, 0x5c, 0x40, 0xe7,
+ 0x06, 0xf2, 0xf7, 0x0f, 0xfb, 0x45, 0x5e, 0x22, 0xec, 0xef, 0x1c, 0x3e,
+ 0xa7, 0xe9, 0x79, 0x96, 0xeb, 0x2f, 0x64, 0x5a, 0xe8, 0x6a, 0xb6, 0x85,
+ 0xde, 0xc9, 0x0e, 0xd1, 0x95, 0xc5, 0x6e, 0x3a, 0xc7, 0x3a, 0xf3, 0x39,
+ 0x27, 0x60, 0xa5, 0xa9, 0x1b, 0xf1, 0x45, 0xe4, 0x0c, 0x31, 0xdd, 0x61,
+ 0x3c, 0xf4, 0xbf, 0xe8, 0x5e, 0xc6, 0x39, 0xd6, 0xbd, 0x5b, 0xe9, 0x3d,
+ 0x7e, 0x66, 0x3a, 0xa3, 0x73, 0x1d, 0xe0, 0x93, 0x1f, 0x2b, 0xeb, 0xaf,
+ 0x5b, 0xe3, 0x88, 0xb9, 0x05, 0x8e, 0x4c, 0x8b, 0xf8, 0xd6, 0xc2, 0x22,
+ 0xff, 0xbe, 0x08, 0xff, 0x39, 0xc3, 0x9b, 0xf9, 0xf3, 0x93, 0x01, 0x8c,
+ 0xc7, 0x39, 0x47, 0xe6, 0x4a, 0x8a, 0xb5, 0x85, 0xf8, 0xd8, 0x27, 0x6a,
+ 0xa4, 0x25, 0x1c, 0x5a, 0x79, 0x7d, 0x3e, 0x31, 0x3e, 0xb9, 0xda, 0x4a,
+ 0xf3, 0x39, 0xd6, 0x41, 0x72, 0x7e, 0xb6, 0x61, 0x30, 0xf6, 0xef, 0x54,
+ 0x6f, 0x61, 0xdc, 0xbf, 0x8b, 0xd2, 0x62, 0x1c, 0x7f, 0xae, 0x76, 0xd1,
+ 0x42, 0xae, 0x43, 0x1d, 0xdf, 0x2b, 0x72, 0xdc, 0x65, 0x1f, 0x23, 0xfc,
+ 0xb6, 0x19, 0x7f, 0x7b, 0x97, 0x71, 0x0a, 0x32, 0x55, 0xda, 0xa5, 0xe0,
+ 0x35, 0x97, 0xeb, 0x7a, 0x22, 0x03, 0xe7, 0xa6, 0xe8, 0x25, 0x96, 0xb7,
+ 0x23, 0x2f, 0xc3, 0x7f, 0xfc, 0x38, 0xf0, 0x26, 0x9f, 0xa2, 0x41, 0x3e,
+ 0x46, 0x5f, 0x24, 0xbf, 0xa8, 0x73, 0x8a, 0x05, 0x27, 0x44, 0x6d, 0x88,
+ 0xa4, 0xd1, 0x59, 0xd1, 0x8b, 0xee, 0x2d, 0xc1, 0x9b, 0xec, 0x94, 0x65,
+ 0x40, 0x1f, 0x81, 0x0f, 0x46, 0xe6, 0x60, 0x1d, 0x77, 0x7a, 0xde, 0xed,
+ 0x9b, 0x19, 0xa7, 0x48, 0x3f, 0xf0, 0x5e, 0xd2, 0xac, 0xea, 0x2f, 0x20,
+ 0xf8, 0xbd, 0xb9, 0x4f, 0xd7, 0x4b, 0xea, 0x63, 0x2d, 0x2b, 0xf4, 0x71,
+ 0x47, 0xcd, 0xef, 0x66, 0xcd, 0xef, 0xe5, 0x7c, 0x39, 0x96, 0x79, 0x2c,
+ 0xe7, 0x49, 0xf6, 0x28, 0x4a, 0x2e, 0x4b, 0xfc, 0x33, 0xf7, 0x8d, 0x99,
+ 0x8f, 0x2a, 0x1d, 0x3c, 0xb9, 0x36, 0x1a, 0xea, 0x31, 0x26, 0x8c, 0xe4,
+ 0xe4, 0x3f, 0x96, 0x22, 0x09, 0xe8, 0x45, 0x4f, 0xee, 0x51, 0xf9, 0xa7,
+ 0x3c, 0xaf, 0x54, 0x18, 0xaa, 0xdb, 0xec, 0x5a, 0x07, 0xad, 0x8b, 0x9e,
+ 0x5c, 0x42, 0xc7, 0xe0, 0xeb, 0x71, 0x9f, 0x94, 0xd9, 0x44, 0xe8, 0x73,
+ 0x0e, 0x1a, 0xdf, 0x1f, 0xba, 0xc4, 0xfb, 0x19, 0x5f, 0xfb, 0x69, 0xe9,
+ 0xa4, 0xe8, 0x71, 0x83, 0xb1, 0x5d, 0x34, 0x27, 0x74, 0x7e, 0xd6, 0x5f,
+ 0xaa, 0xec, 0xaa, 0x29, 0xcc, 0x33, 0x85, 0xd8, 0x8a, 0xe1, 0xfc, 0xbe,
+ 0x2f, 0x99, 0x97, 0xb1, 0xf2, 0x78, 0x4d, 0xac, 0x7c, 0x56, 0xc4, 0xca,
+ 0x11, 0x27, 0x07, 0x5c, 0x01, 0x4b, 0xaf, 0x9c, 0x16, 0xec, 0x63, 0x98,
+ 0x90, 0x1b, 0x7e, 0xee, 0xa2, 0xe0, 0x37, 0xe1, 0x98, 0x5f, 0xe6, 0x57,
+ 0xc7, 0x79, 0xc6, 0x06, 0x5d, 0x60, 0x7c, 0xb0, 0x27, 0x36, 0x58, 0x97,
+ 0x58, 0xc9, 0x7e, 0x99, 0xae, 0xe4, 0x9b, 0x58, 0xd7, 0x5b, 0xa0, 0x8d,
+ 0x3c, 0xb1, 0x4e, 0xd8, 0x4d, 0x0b, 0x61, 0xc6, 0xb1, 0x89, 0x36, 0xde,
+ 0x4f, 0xd6, 0x6b, 0x27, 0x98, 0xee, 0x78, 0xee, 0x2b, 0xb9, 0xd2, 0x8f,
+ 0xd2, 0xe1, 0x88, 0x15, 0x9d, 0xea, 0x60, 0xbb, 0xc5, 0xe4, 0x7f, 0x87,
+ 0xff, 0x77, 0x85, 0x00, 0x93, 0xc2, 0x2a, 0x7e, 0x67, 0x9d, 0x27, 0x53,
+ 0xfa, 0xd1, 0x1c, 0x8f, 0x99, 0x9b, 0x82, 0xfd, 0x03, 0x3b, 0xcf, 0xe1,
+ 0x7f, 0x39, 0x66, 0x65, 0x95, 0xf1, 0xfb, 0x62, 0x2a, 0x64, 0x08, 0xde,
+ 0xbe, 0xce, 0x3c, 0xfe, 0x02, 0xcd, 0xf1, 0x1c, 0xae, 0x10, 0xae, 0xb5,
+ 0x28, 0x19, 0xde, 0xc7, 0x78, 0xdf, 0xcd, 0x9f, 0xa8, 0xbf, 0x6a, 0xa7,
+ 0x85, 0xc9, 0x31, 0x55, 0x7f, 0xf5, 0xbd, 0x06, 0xf5, 0x57, 0xb8, 0x8e,
+ 0xe5, 0xfe, 0x62, 0xe9, 0xe6, 0x5c, 0xd8, 0xfd, 0x3c, 0x32, 0x92, 0xe1,
+ 0x4e, 0xa1, 0x23, 0xad, 0xac, 0xfa, 0xf8, 0xd9, 0x11, 0x2b, 0x39, 0xc5,
+ 0x73, 0xcc, 0xb9, 0xe7, 0x5d, 0xba, 0x19, 0x0b, 0x63, 0x9c, 0xbf, 0x66,
+ 0x1c, 0xdb, 0xca, 0x53, 0x72, 0x3d, 0x85, 0x5c, 0xe9, 0xe7, 0xd1, 0xb0,
+ 0x5e, 0x9f, 0xfb, 0x5a, 0xac, 0x03, 0xf4, 0xc4, 0x9f, 0x2b, 0x5d, 0xbe,
+ 0x2b, 0x59, 0xd8, 0xdf, 0x06, 0xe3, 0x39, 0x66, 0x34, 0x44, 0xa9, 0x15,
+ 0xa6, 0xef, 0x8b, 0x1d, 0xbe, 0x8d, 0xec, 0x95, 0x52, 0xb2, 0x2a, 0x97,
+ 0xa5, 0xda, 0xef, 0x2e, 0x6d, 0xae, 0x21, 0x72, 0x96, 0x20, 0x33, 0x21,
+ 0x2f, 0x53, 0x25, 0xbf, 0x03, 0xfd, 0x0e, 0xb6, 0xd0, 0x59, 0xe6, 0x57,
+ 0x32, 0x1f, 0x89, 0x79, 0x27, 0xf3, 0x2c, 0x49, 0x2f, 0xf1, 0xaa, 0xd7,
+ 0x0d, 0x48, 0x9c, 0x1d, 0xa9, 0xe4, 0x41, 0xba, 0xe2, 0xe9, 0x01, 0x57,
+ 0x3c, 0xdd, 0x74, 0xe5, 0x41, 0x06, 0x85, 0x3e, 0x56, 0xd1, 0xa1, 0x82,
+ 0x4a, 0x87, 0x82, 0xae, 0x25, 0x79, 0x59, 0xa1, 0xcc, 0xcb, 0x76, 0x6f,
+ 0xc1, 0xcb, 0xbc, 0x6c, 0xd3, 0x75, 0xc5, 0x37, 0xec, 0x30, 0xe4, 0xfc,
+ 0xe5, 0xe2, 0x34, 0xbd, 0xcd, 0x3c, 0xe2, 0xad, 0x62, 0x98, 0xf9, 0xc6,
+ 0x24, 0xf3, 0x8d, 0x09, 0xe6, 0x1b, 0x0e, 0xc3, 0xc0, 0xe2, 0xb5, 0x5f,
+ 0xf3, 0x5d, 0x59, 0x84, 0xbc, 0x98, 0xa2, 0xe7, 0x8b, 0xe0, 0xc1, 0x93,
+ 0xac, 0xf3, 0x5c, 0xf3, 0x6d, 0x2c, 0x76, 0x31, 0xbe, 0x4a, 0x3d, 0xa7,
+ 0xda, 0x8e, 0x41, 0xaf, 0x15, 0xf8, 0x87, 0xaf, 0x82, 0xcf, 0xbc, 0x91,
+ 0xa2, 0x4e, 0x86, 0x3d, 0xe0, 0xbc, 0x8e, 0xde, 0x14, 0xaf, 0x81, 0x96,
+ 0xd1, 0x13, 0xf8, 0xbb, 0xe3, 0x53, 0x3c, 0xf7, 0x4e, 0xdf, 0x02, 0xef,
+ 0xcb, 0xd3, 0xe1, 0x94, 0xd9, 0xcb, 0x38, 0x7f, 0xac, 0x82, 0xf3, 0xa9,
+ 0x34, 0xaf, 0xa0, 0x67, 0xb9, 0x9b, 0xc6, 0x0e, 0x44, 0xf7, 0xf6, 0x30,
+ 0x9d, 0x22, 0x37, 0xa2, 0xd2, 0xa7, 0xc7, 0x4f, 0x27, 0x83, 0x6d, 0xaa,
+ 0xbf, 0x8f, 0xc5, 0xf2, 0xf1, 0x03, 0xbe, 0xcf, 0x2d, 0x5f, 0x3a, 0xfb,
+ 0x2a, 0x3f, 0x03, 0xc7, 0x5f, 0x85, 0xff, 0x93, 0xed, 0x83, 0x56, 0xe1,
+ 0x3f, 0x2a, 0x88, 0xb1, 0x38, 0xb6, 0x27, 0x98, 0x97, 0x85, 0xd7, 0x0d,
+ 0x7b, 0x3a, 0x62, 0x30, 0xd1, 0x75, 0x99, 0xbc, 0xde, 0xd2, 0xa0, 0x8c,
+ 0xc1, 0xed, 0xdd, 0x2b, 0xf9, 0x06, 0xe3, 0x66, 0x30, 0x22, 0x6c, 0xb4,
+ 0xa6, 0x25, 0x29, 0x27, 0x0b, 0xbc, 0xcf, 0x2b, 0xe1, 0x09, 0xde, 0xe7,
+ 0x0e, 0x25, 0x23, 0x53, 0xfc, 0xbb, 0x90, 0xbf, 0x2c, 0x2b, 0x87, 0xd0,
+ 0xb3, 0xda, 0x14, 0xfd, 0x20, 0x66, 0xd1, 0x6f, 0xa7, 0x83, 0xef, 0x6b,
+ 0x33, 0xd6, 0x82, 0x4f, 0x7c, 0xe0, 0x4b, 0x66, 0xf1, 0x5c, 0xe0, 0x21,
+ 0x7f, 0xcf, 0x4f, 0xd1, 0x85, 0x8c, 0x9e, 0xc3, 0x80, 0x61, 0xbc, 0x84,
+ 0x79, 0xf8, 0x68, 0xb7, 0xf3, 0x43, 0x86, 0x17, 0x1f, 0xff, 0x71, 0xed,
+ 0x9c, 0x86, 0xd5, 0x9c, 0xd0, 0xd3, 0xb2, 0x05, 0x3d, 0x7c, 0x08, 0xbd,
+ 0x8f, 0x0a, 0xa2, 0xe7, 0x64, 0xb3, 0xb0, 0x4d, 0x0b, 0xc2, 0xc6, 0x28,
+ 0x85, 0x2a, 0x7d, 0x30, 0xef, 0xa9, 0x39, 0xf7, 0x13, 0x5f, 0x7a, 0xf1,
+ 0xa0, 0xd0, 0xc5, 0x46, 0x0e, 0xec, 0x55, 0xf5, 0xa7, 0x5d, 0xe2, 0xbe,
+ 0xc6, 0x32, 0x7e, 0x7b, 0x50, 0xfd, 0xf6, 0x49, 0xa1, 0x03, 0x23, 0x2f,
+ 0x2e, 0xb0, 0x24, 0xf0, 0x9c, 0xf7, 0xd7, 0x99, 0x60, 0x3c, 0x0f, 0xad,
+ 0xc0, 0x77, 0x2f, 0xe0, 0xa9, 0xe1, 0x01, 0x58, 0x00, 0xf7, 0x3b, 0x14,
+ 0xde, 0xdb, 0x56, 0xdc, 0xaf, 0xd7, 0xdd, 0x08, 0xce, 0xac, 0xd3, 0x64,
+ 0xb0, 0x56, 0xac, 0x69, 0x8f, 0x2f, 0x92, 0xb7, 0x8c, 0xf4, 0x22, 0x6c,
+ 0x1a, 0xd4, 0xb5, 0xdc, 0x85, 0xbc, 0x29, 0x9e, 0xc3, 0x1e, 0x8a, 0x24,
+ 0x30, 0x2f, 0x8c, 0xd3, 0x30, 0xf8, 0xb7, 0x1a, 0x58, 0xb8, 0xaf, 0xeb,
+ 0x56, 0xd7, 0xb5, 0x8a, 0xbd, 0x20, 0x03, 0xcf, 0xd1, 0xcf, 0xc6, 0x73,
+ 0xf1, 0x7c, 0x5c, 0x87, 0xfb, 0xc9, 0xfb, 0xf6, 0x31, 0x7f, 0x8e, 0x4e,
+ 0xc9, 0x7b, 0x19, 0x97, 0xe4, 0x6f, 0x7d, 0x8e, 0xf7, 0x7c, 0xe5, 0xfe,
+ 0xf9, 0x54, 0xbf, 0x1e, 0xec, 0x5f, 0x37, 0xe5, 0x85, 0x8f, 0x13, 0xbf,
+ 0x75, 0x8a, 0xdf, 0xa2, 0x4e, 0xa7, 0xd8, 0xd7, 0xf3, 0x7c, 0x3c, 0x9f,
+ 0xed, 0xf2, 0xc1, 0x36, 0x4f, 0x27, 0x3a, 0x7d, 0xf9, 0x3c, 0xd6, 0xdb,
+ 0xe9, 0x8b, 0x33, 0xee, 0xc7, 0xb2, 0xf1, 0xd2, 0x82, 0xe0, 0x31, 0xac,
+ 0xd3, 0xf6, 0xda, 0xe6, 0x49, 0xe3, 0x4f, 0x86, 0x64, 0x6f, 0x5b, 0x7c,
+ 0x67, 0xfa, 0xcb, 0x30, 0xfd, 0x65, 0x98, 0xfe, 0x32, 0x4c, 0x7f, 0x19,
+ 0xa6, 0x3f, 0xb6, 0x4b, 0xdf, 0x64, 0x99, 0xf1, 0x6d, 0x96, 0x19, 0x92,
+ 0x66, 0x23, 0xca, 0x8f, 0xa9, 0x69, 0xb6, 0xb6, 0x3e, 0x53, 0xd3, 0x28,
+ 0xe4, 0x34, 0xf9, 0x0e, 0x8f, 0x57, 0xd3, 0xea, 0x55, 0xa6, 0xd5, 0xa6,
+ 0x99, 0x7e, 0xba, 0x91, 0xc3, 0x9e, 0xd9, 0xd6, 0x79, 0xe6, 0xd1, 0x71,
+ 0x3f, 0x74, 0xaa, 0x00, 0xd3, 0x13, 0x74, 0x4a, 0x9b, 0xe1, 0xde, 0x4f,
+ 0x37, 0x99, 0x4f, 0xdf, 0xc8, 0x81, 0x76, 0xef, 0x52, 0xc7, 0x19, 0xa6,
+ 0x5d, 0xc8, 0xb9, 0x25, 0xdf, 0xd5, 0xac, 0xc1, 0xba, 0x57, 0xc0, 0x4c,
+ 0x12, 0xf8, 0xa8, 0xd0, 0xc7, 0x78, 0xdf, 0xd7, 0x99, 0xdf, 0xc3, 0x57,
+ 0x87, 0xbe, 0x5f, 0x79, 0x1f, 0xcb, 0x89, 0xd0, 0x15, 0xe6, 0xa3, 0xa7,
+ 0x73, 0x4b, 0x4c, 0xef, 0xbd, 0xf4, 0x85, 0x1c, 0xe4, 0x31, 0x60, 0xc4,
+ 0xc7, 0x79, 0x12, 0x3e, 0x30, 0x63, 0x06, 0x6b, 0x1f, 0x4b, 0x19, 0x02,
+ 0x4f, 0x9e, 0x01, 0x1c, 0x18, 0xf6, 0x67, 0xf6, 0xa2, 0x67, 0x7d, 0xc4,
+ 0x68, 0x56, 0x3e, 0x45, 0x7c, 0xc7, 0x78, 0x8c, 0x05, 0xdc, 0x70, 0xdc,
+ 0x28, 0xfe, 0x88, 0xf7, 0x42, 0x84, 0x19, 0x1e, 0xb5, 0x7c, 0xeb, 0x02,
+ 0x7a, 0x91, 0x02, 0x5e, 0xd3, 0x51, 0x3f, 0x6a, 0xc5, 0xe9, 0x39, 0xbc,
+ 0xff, 0xe0, 0x85, 0x22, 0xe6, 0xbd, 0x48, 0x0b, 0x41, 0xf0, 0x21, 0x3b,
+ 0x7c, 0x9d, 0x24, 0xec, 0x5a, 0x59, 0xbf, 0xfc, 0xbc, 0x37, 0x6f, 0xb3,
+ 0xa2, 0x42, 0x1f, 0x6e, 0x61, 0xfb, 0x06, 0xb0, 0x79, 0x8b, 0x71, 0x2d,
+ 0x0c, 0x9b, 0x5f, 0xf1, 0xb5, 0x37, 0x99, 0xe7, 0x60, 0xcf, 0x3a, 0x85,
+ 0x8c, 0xf1, 0xe2, 0x65, 0x1b, 0x8a, 0x97, 0x39, 0x2e, 0x5e, 0x96, 0x2e,
+ 0xf3, 0x32, 0xc6, 0x09, 0xc1, 0xc3, 0xc0, 0xa3, 0x66, 0x59, 0x4f, 0x94,
+ 0xdf, 0xa1, 0xff, 0xed, 0x16, 0x3c, 0x8b, 0x79, 0x3d, 0xdb, 0x0d, 0x85,
+ 0x62, 0xca, 0x77, 0x48, 0xf0, 0x0e, 0x8d, 0xd7, 0xff, 0xa3, 0xe8, 0xa1,
+ 0x55, 0xf0, 0x81, 0xf4, 0x2c, 0xf8, 0x95, 0xd7, 0xf8, 0xff, 0x02, 0x6c,
+ 0x79, 0xbc, 0x13, 0x7a, 0x8d, 0xf9, 0x58, 0x21, 0x0c, 0x9b, 0xb5, 0x43,
+ 0xd9, 0x36, 0xe8, 0xbb, 0xb5, 0x07, 0xb9, 0x96, 0x56, 0xb4, 0xcc, 0xc7,
+ 0x76, 0x2b, 0xbf, 0x05, 0xfc, 0x8c, 0xd8, 0xeb, 0x3a, 0x5d, 0xc0, 0x82,
+ 0x2e, 0xc0, 0x63, 0x03, 0x0c, 0x1f, 0xd1, 0x1b, 0x9c, 0xe8, 0x16, 0xc3,
+ 0x01, 0xfb, 0x7c, 0x0b, 0xfb, 0xcc, 0xba, 0x2c, 0x05, 0xe6, 0xa6, 0x02,
+ 0x03, 0x98, 0xdf, 0xc2, 0x6a, 0x85, 0x1f, 0x9e, 0xcf, 0x0c, 0x18, 0x85,
+ 0xac, 0x9c, 0xe3, 0xca, 0xb8, 0xe4, 0x79, 0x85, 0x3c, 0x7a, 0x7b, 0x89,
+ 0xb9, 0xf2, 0x1c, 0xf5, 0xfa, 0x04, 0xff, 0x52, 0x74, 0xbf, 0x1d, 0x5a,
+ 0x4b, 0x30, 0x5d, 0x61, 0x4f, 0x52, 0x2e, 0x9c, 0x79, 0x94, 0x9f, 0x8f,
+ 0x73, 0x8d, 0xd7, 0x71, 0xb3, 0xbc, 0x8e, 0x08, 0xaf, 0x03, 0x63, 0x6f,
+ 0xf9, 0x6e, 0xa8, 0x75, 0xdc, 0x28, 0xaf, 0x63, 0x56, 0xad, 0x83, 0xd2,
+ 0xc6, 0xcc, 0x6e, 0xa5, 0xc7, 0x6f, 0x79, 0xcf, 0xd6, 0x28, 0xeb, 0x27,
+ 0xe9, 0x55, 0xc0, 0xf3, 0x1e, 0x85, 0x2f, 0x6e, 0x7f, 0xa8, 0x7b, 0x6e,
+ 0xf6, 0xc4, 0x75, 0xfa, 0x5d, 0xba, 0x29, 0xf4, 0x93, 0x61, 0xd6, 0x4f,
+ 0x70, 0x9e, 0x16, 0xc0, 0x87, 0xd3, 0x41, 0xf4, 0x9b, 0x1d, 0x64, 0x98,
+ 0xb1, 0x5d, 0x35, 0xc5, 0x9f, 0xc2, 0x4f, 0x86, 0xfb, 0xe8, 0xeb, 0xbf,
+ 0x48, 0x37, 0x17, 0xc1, 0xab, 0xa1, 0x8f, 0xca, 0x9e, 0xb4, 0x37, 0xd7,
+ 0xa4, 0x9f, 0x36, 0xee, 0xe9, 0xa7, 0x85, 0x8f, 0x36, 0x0c, 0x7d, 0xdd,
+ 0x84, 0x3f, 0x37, 0x26, 0xde, 0x67, 0xc1, 0xc7, 0x45, 0xdc, 0xcb, 0x8b,
+ 0xef, 0x4c, 0xbb, 0x72, 0xdc, 0x90, 0x73, 0x92, 0x62, 0x3e, 0xe2, 0x98,
+ 0x4d, 0x86, 0xac, 0x9d, 0xb9, 0x5c, 0xd4, 0x3a, 0x51, 0x9c, 0xf7, 0xc8,
+ 0x09, 0x1b, 0x46, 0x44, 0xf8, 0x0c, 0x5a, 0x9d, 0x0e, 0x6a, 0x61, 0x39,
+ 0x79, 0x8a, 0xd0, 0x13, 0xcd, 0xb6, 0xe0, 0xcb, 0xbf, 0xc0, 0xb8, 0xb7,
+ 0x10, 0xb6, 0x43, 0x9f, 0x13, 0xf6, 0x25, 0xe4, 0x07, 0xde, 0xa7, 0x02,
+ 0x18, 0x63, 0x0e, 0xfc, 0x7d, 0x15, 0xfd, 0x30, 0xc3, 0xbc, 0x7e, 0xf8,
+ 0x81, 0x47, 0xad, 0x77, 0x58, 0xee, 0x5c, 0x10, 0xfe, 0x95, 0xb3, 0x94,
+ 0x66, 0x3a, 0x3c, 0x2c, 0xe8, 0xd0, 0x18, 0x66, 0x6a, 0x61, 0xfa, 0x41,
+ 0x8e, 0xc1, 0x98, 0xe8, 0xbf, 0x23, 0x6d, 0x16, 0x5e, 0xe5, 0x9a, 0xea,
+ 0x6b, 0x90, 0x00, 0x6f, 0xd8, 0xbe, 0x6f, 0x21, 0xf1, 0x91, 0x7d, 0x2a,
+ 0x6e, 0x5d, 0xab, 0xd6, 0x87, 0x0d, 0xfb, 0xcc, 0x12, 0x7d, 0x1f, 0x01,
+ 0x3b, 0xe1, 0x17, 0x34, 0x26, 0x19, 0x6e, 0xfa, 0xdd, 0x35, 0x6e, 0xfb,
+ 0xff, 0x29, 0x51, 0x9f, 0xff, 0x46, 0x51, 0xca, 0xd8, 0x34, 0xdb, 0xe6,
+ 0x0b, 0x07, 0xdc, 0x3a, 0x87, 0x9d, 0x8d, 0x09, 0x9f, 0xcc, 0x00, 0x45,
+ 0x97, 0x27, 0xe9, 0xb1, 0x0c, 0x78, 0x14, 0x5d, 0x8f, 0x3a, 0x78, 0xc3,
+ 0x06, 0x68, 0x79, 0x92, 0xe2, 0x45, 0xc0, 0xc8, 0x47, 0x0b, 0x2c, 0x05,
+ 0xd2, 0x59, 0xc4, 0xee, 0xf9, 0x7b, 0x1e, 0xef, 0x57, 0xf9, 0x15, 0xe5,
+ 0xf7, 0x1e, 0xa2, 0xd8, 0x32, 0xa5, 0x92, 0xe1, 0x87, 0x45, 0xcf, 0xea,
+ 0x64, 0x78, 0x5c, 0xf9, 0x68, 0x42, 0x7c, 0x1e, 0x7e, 0x2f, 0x8b, 0x1e,
+ 0xcd, 0xd8, 0xa9, 0x24, 0x49, 0xdf, 0x03, 0xf1, 0x1c, 0x0c, 0x96, 0xad,
+ 0xbb, 0x99, 0x57, 0x1c, 0x17, 0xfe, 0x07, 0xd6, 0x44, 0x16, 0x31, 0x1e,
+ 0xbe, 0x83, 0x5e, 0x82, 0xbd, 0x95, 0xcc, 0x3e, 0xa0, 0xc6, 0x96, 0xc8,
+ 0x64, 0x5c, 0x30, 0x7f, 0xc9, 0x49, 0x85, 0x8d, 0xca, 0xf5, 0xf0, 0x5d,
+ 0x1c, 0x17, 0xfa, 0xe1, 0x30, 0xdb, 0x30, 0x62, 0x5c, 0x69, 0x4e, 0xf8,
+ 0x21, 0xf8, 0x38, 0xff, 0xd3, 0x01, 0xfd, 0x6e, 0x03, 0x9c, 0x97, 0xfe,
+ 0x09, 0xbe, 0x67, 0x9e, 0xe7, 0x51, 0x95, 0x17, 0x3f, 0x44, 0x91, 0x1d,
+ 0xf8, 0x8b, 0x66, 0xef, 0xa8, 0xbf, 0x88, 0x61, 0xcd, 0xb2, 0xe5, 0x32,
+ 0xd3, 0xc6, 0xdb, 0x5b, 0xda, 0x71, 0xef, 0x6b, 0x19, 0xcd, 0xb0, 0x32,
+ 0xc5, 0xfb, 0x2f, 0xd0, 0xeb, 0x73, 0xa1, 0xf8, 0x29, 0xbc, 0x47, 0xc6,
+ 0x97, 0x10, 0x3a, 0x6f, 0x88, 0x75, 0x17, 0xe8, 0x30, 0xa3, 0x22, 0xbe,
+ 0x15, 0x79, 0xc2, 0x32, 0x16, 0xd6, 0xfa, 0xc9, 0x0f, 0xbf, 0x9a, 0xa3,
+ 0x73, 0x22, 0x5a, 0x45, 0xfe, 0xba, 0x8c, 0x2b, 0x42, 0xfe, 0x82, 0x07,
+ 0xfe, 0xc4, 0x97, 0x5c, 0xf3, 0xf7, 0xe9, 0x7c, 0xb7, 0x48, 0xb0, 0x9c,
+ 0x4f, 0xa3, 0x78, 0x8a, 0xc6, 0x3d, 0x1d, 0xb3, 0x70, 0xbf, 0xd7, 0x0a,
+ 0xb4, 0xeb, 0xd6, 0x19, 0xe0, 0x67, 0x12, 0x7b, 0x74, 0x01, 0x71, 0x5c,
+ 0xa3, 0x2a, 0x1e, 0xd1, 0xc2, 0xfb, 0x04, 0x3b, 0x0f, 0xfe, 0xbb, 0xcf,
+ 0xf2, 0x27, 0xe2, 0x0a, 0x27, 0x07, 0xa1, 0x27, 0xf5, 0x38, 0x8c, 0x33,
+ 0x53, 0x38, 0xee, 0x67, 0xbb, 0x4b, 0xeb, 0xb5, 0xd2, 0xa7, 0xc4, 0xb6,
+ 0x98, 0xda, 0x2f, 0xf8, 0x93, 0x46, 0x54, 0xbf, 0x01, 0x9b, 0xac, 0x5e,
+ 0xc0, 0xe9, 0xe3, 0xa2, 0xc7, 0xad, 0x62, 0x10, 0xdb, 0xc9, 0x59, 0xc2,
+ 0x3b, 0xb7, 0xd0, 0x77, 0xf3, 0x6e, 0xc0, 0x9e, 0xf7, 0xc8, 0x1d, 0xa3,
+ 0xf8, 0x94, 0x7a, 0xff, 0xcf, 0x9d, 0xda, 0xb7, 0x5d, 0x1e, 0xfb, 0xf6,
+ 0xbd, 0x41, 0x19, 0x03, 0xbb, 0x4b, 0x8d, 0xf1, 0xca, 0x53, 0xfd, 0xfb,
+ 0xa7, 0xe1, 0x4f, 0xaa, 0xd4, 0x51, 0x5c, 0x13, 0x7c, 0xa5, 0xde, 0xa7,
+ 0x1d, 0x62, 0x7e, 0x2a, 0xe9, 0xf8, 0xb8, 0x07, 0x1d, 0xf7, 0xce, 0x40,
+ 0x2f, 0xb9, 0x7d, 0x3a, 0x3e, 0xd6, 0x90, 0x8e, 0xff, 0x75, 0x50, 0xfa,
+ 0x54, 0xeb, 0xe9, 0x18, 0xb5, 0x3c, 0xc7, 0x8b, 0x8d, 0xfc, 0x57, 0xd8,
+ 0x07, 0xd4, 0xa4, 0xc3, 0xe7, 0x01, 0x58, 0x69, 0xbf, 0x07, 0xe2, 0x7e,
+ 0xc0, 0x47, 0xc4, 0x4e, 0xfe, 0x90, 0xe2, 0x8b, 0xb5, 0xb1, 0xd0, 0xcd,
+ 0xae, 0xf9, 0x96, 0xc7, 0x35, 0xd0, 0xc5, 0x41, 0x0b, 0x76, 0x48, 0xda,
+ 0xf4, 0x1a, 0x5e, 0xef, 0xf9, 0x0e, 0xe5, 0xec, 0x54, 0x9e, 0xe0, 0xa3,
+ 0x0e, 0xd2, 0x53, 0x88, 0x2b, 0x2b, 0x1f, 0xf0, 0xd1, 0x8c, 0x5c, 0xb7,
+ 0x79, 0x40, 0xe0, 0x03, 0xf4, 0xd5, 0x50, 0xc2, 0x9f, 0xe0, 0x3d, 0x95,
+ 0xfe, 0xdf, 0xe4, 0x6a, 0x48, 0xed, 0x13, 0x8f, 0xc5, 0xfd, 0x3c, 0xeb,
+ 0xfc, 0xb0, 0x3f, 0xf6, 0xd7, 0xd7, 0xcb, 0x79, 0xc5, 0x90, 0x05, 0x25,
+ 0xfa, 0x0f, 0x96, 0x73, 0xfe, 0x03, 0xa6, 0xe8, 0xb9, 0x70, 0xb9, 0x78,
+ 0x80, 0xf5, 0x47, 0xec, 0x21, 0x7c, 0x87, 0xda, 0xb7, 0xfb, 0xf6, 0x30,
+ 0x75, 0xed, 0x67, 0xa9, 0x6f, 0x90, 0xc3, 0x7a, 0xa3, 0x71, 0x00, 0xf9,
+ 0xe1, 0x16, 0x5f, 0x83, 0x5e, 0x51, 0x63, 0x56, 0x9c, 0x3a, 0xe0, 0x4f,
+ 0x40, 0x0f, 0x68, 0x2b, 0x5d, 0x45, 0x53, 0xb3, 0x82, 0xa6, 0xe2, 0x6b,
+ 0xb3, 0x8a, 0xa6, 0x66, 0x95, 0xff, 0x7c, 0x56, 0xd1, 0xd4, 0xac, 0xa2,
+ 0xa9, 0x59, 0x45, 0x53, 0xb3, 0x8c, 0xd7, 0xa3, 0xac, 0xaf, 0x42, 0xf7,
+ 0xd0, 0xfe, 0xcb, 0x2e, 0x4a, 0xe6, 0x70, 0x1e, 0xf2, 0xb8, 0x96, 0xae,
+ 0x7e, 0x6d, 0x58, 0xfb, 0x47, 0x0b, 0x32, 0xcf, 0x8e, 0x9f, 0x85, 0x3d,
+ 0x78, 0x98, 0xe1, 0x77, 0xcd, 0x37, 0xbf, 0x88, 0xb9, 0xfa, 0x28, 0x26,
+ 0x7a, 0xc0, 0x36, 0x51, 0xd4, 0xad, 0xe3, 0x9a, 0xa8, 0xeb, 0x92, 0xb6,
+ 0x5c, 0xaa, 0x61, 0x8d, 0x97, 0xc6, 0x8b, 0x69, 0xb5, 0x5f, 0xb5, 0x76,
+ 0x4e, 0x0b, 0x25, 0xb2, 0x80, 0x2b, 0x72, 0x21, 0x2d, 0xde, 0x1b, 0x01,
+ 0xa7, 0x94, 0xe9, 0x01, 0x83, 0xa3, 0x0a, 0x06, 0x4f, 0x8b, 0x35, 0x22,
+ 0x97, 0x10, 0x3e, 0xc8, 0xc6, 0x70, 0x48, 0x67, 0x46, 0xf9, 0x3e, 0x8c,
+ 0xfb, 0x07, 0x42, 0xcc, 0x83, 0xb6, 0x0b, 0x07, 0xf7, 0xda, 0x1b, 0xf1,
+ 0x9a, 0xed, 0xd6, 0xd3, 0x5c, 0x77, 0xc9, 0x8e, 0x90, 0x92, 0x1b, 0x52,
+ 0xef, 0xdd, 0xe5, 0xd8, 0x89, 0x14, 0xcf, 0xed, 0x2f, 0xc2, 0x7f, 0x39,
+ 0x44, 0x6d, 0x25, 0x3a, 0x12, 0x06, 0x3e, 0x77, 0xb1, 0x5d, 0xc9, 0x73,
+ 0x18, 0x2b, 0xd1, 0x85, 0xf0, 0x3e, 0xb6, 0x5d, 0xf6, 0xb3, 0x0e, 0x3a,
+ 0xca, 0xff, 0x4e, 0xc4, 0xef, 0xc3, 0xbc, 0x3a, 0xf8, 0xda, 0x7e, 0x32,
+ 0x7a, 0x52, 0x66, 0x2b, 0xeb, 0x07, 0x47, 0x2a, 0xf6, 0x88, 0x05, 0xff,
+ 0x1c, 0xeb, 0xb6, 0xc6, 0x5c, 0xb8, 0x5b, 0xd5, 0x9c, 0xc1, 0x87, 0x8d,
+ 0xf8, 0xd6, 0x3f, 0x97, 0x64, 0xaf, 0x80, 0x21, 0x75, 0xfc, 0xe3, 0x52,
+ 0x64, 0x08, 0xc7, 0x78, 0xe7, 0x90, 0x3d, 0x11, 0xf1, 0xfd, 0x58, 0xea,
+ 0xf2, 0x3e, 0xfb, 0x88, 0x7c, 0x3f, 0x80, 0x6d, 0x5a, 0x3e, 0x2f, 0xbc,
+ 0x97, 0x3a, 0x4f, 0x25, 0x5f, 0x15, 0x74, 0x50, 0xa2, 0x7f, 0x67, 0x9a,
+ 0x35, 0x09, 0xb1, 0x8c, 0x29, 0x51, 0x0b, 0x8d, 0x7c, 0xe5, 0xf9, 0x45,
+ 0x3d, 0x2f, 0x47, 0xed, 0xf5, 0xfd, 0xc8, 0x37, 0xcb, 0x16, 0x68, 0x73,
+ 0x99, 0x01, 0x3f, 0xda, 0xe8, 0xf2, 0x46, 0x4f, 0x50, 0xd4, 0x66, 0x77,
+ 0xb3, 0x8e, 0xa3, 0xf3, 0x92, 0xc7, 0xf8, 0xfe, 0x01, 0xf1, 0xbe, 0xb9,
+ 0xd8, 0x12, 0xc6, 0x35, 0xd3, 0xc8, 0x72, 0xe9, 0x21, 0xfe, 0x5d, 0xc4,
+ 0x11, 0x93, 0xd4, 0xaa, 0x62, 0x04, 0x1d, 0x2a, 0xae, 0x14, 0x62, 0x5a,
+ 0xaa, 0xd4, 0x1c, 0x8f, 0x94, 0x7d, 0x6d, 0xc0, 0xf1, 0x5a, 0x5f, 0xdb,
+ 0x73, 0x5b, 0xc8, 0x9b, 0xad, 0xf0, 0x1a, 0x39, 0xa5, 0x2d, 0xa4, 0x7c,
+ 0x88, 0xd6, 0x02, 0x6d, 0xb7, 0xb6, 0x6e, 0xc7, 0xd7, 0xb4, 0x36, 0xcf,
+ 0xac, 0x9f, 0x79, 0xc7, 0x69, 0x53, 0xf8, 0xd4, 0x4c, 0xf3, 0xb9, 0x36,
+ 0x96, 0xd9, 0xa8, 0x97, 0x02, 0xbc, 0xfc, 0x43, 0xa8, 0x37, 0x79, 0x32,
+ 0xd0, 0x4c, 0xab, 0xab, 0xc8, 0x79, 0x78, 0xfc, 0x2e, 0x99, 0xe7, 0xfb,
+ 0x08, 0xc3, 0x65, 0x3f, 0xcb, 0x37, 0x43, 0xc5, 0x70, 0x70, 0x0e, 0xbc,
+ 0x41, 0xf4, 0xfd, 0x0c, 0x3c, 0x3c, 0xde, 0xc6, 0x7a, 0xbd, 0x8c, 0x01,
+ 0x1c, 0xe4, 0x7b, 0x7f, 0x33, 0xf7, 0x08, 0xfc, 0x59, 0xe6, 0x61, 0xbe,
+ 0x7f, 0x8c, 0xf5, 0x81, 0x08, 0x35, 0xd3, 0xca, 0x6a, 0x33, 0xeb, 0xf5,
+ 0xcd, 0xac, 0x0f, 0x8c, 0x9a, 0x23, 0x3e, 0xf1, 0x2c, 0x51, 0xdb, 0xf2,
+ 0xe9, 0xc0, 0x7e, 0xc6, 0x41, 0x3c, 0xeb, 0x8b, 0xea, 0x59, 0xb5, 0xcf,
+ 0xb8, 0x55, 0xc2, 0xf1, 0x61, 0xff, 0xfa, 0x99, 0xab, 0x78, 0x2f, 0xd4,
+ 0xe2, 0x34, 0xeb, 0xbe, 0x41, 0xf1, 0x6e, 0x46, 0x63, 0x66, 0x86, 0xed,
+ 0x80, 0x30, 0x1f, 0x1f, 0xa1, 0x54, 0x31, 0x41, 0xbf, 0x57, 0x74, 0xfb,
+ 0x6a, 0x8f, 0xf0, 0x9c, 0x65, 0x6d, 0x7d, 0x0b, 0xcf, 0xeb, 0x7d, 0xa7,
+ 0x96, 0x67, 0xb4, 0x91, 0xff, 0x6b, 0x41, 0x6a, 0x7e, 0x11, 0xbe, 0x91,
+ 0x12, 0x65, 0xc3, 0xf6, 0x85, 0xeb, 0xe2, 0xbd, 0x1b, 0x16, 0xbd, 0x22,
+ 0xf2, 0x5b, 0xf9, 0x7a, 0xbe, 0xe7, 0x79, 0x8c, 0x7b, 0xc5, 0xa2, 0x2b,
+ 0x8e, 0x84, 0xf7, 0x9f, 0x05, 0x82, 0xe4, 0x7f, 0x1d, 0x39, 0x48, 0xd0,
+ 0xb5, 0xd6, 0xcf, 0x38, 0xfb, 0x98, 0x5f, 0xbf, 0x88, 0xeb, 0xf8, 0xf3,
+ 0x75, 0x1c, 0xb7, 0xf1, 0x3a, 0x21, 0x6f, 0x91, 0x77, 0x02, 0x3e, 0xb7,
+ 0x3f, 0x64, 0x0a, 0xfc, 0x3b, 0xc2, 0x38, 0xd5, 0x24, 0x7c, 0x81, 0xbd,
+ 0x18, 0xeb, 0x0c, 0xb2, 0x6e, 0xb0, 0x7e, 0x66, 0x7c, 0x1f, 0x8e, 0x23,
+ 0x3d, 0x7e, 0x86, 0x91, 0xc4, 0xa1, 0xb0, 0x78, 0xff, 0xa1, 0xeb, 0x2f,
+ 0x70, 0x70, 0x9c, 0x78, 0x3f, 0xa1, 0x3f, 0xf0, 0x7e, 0x9a, 0xe8, 0xb3,
+ 0xd4, 0x46, 0x71, 0x7e, 0x46, 0x2c, 0x27, 0xd7, 0x7d, 0xbe, 0xe8, 0x27,
+ 0xe9, 0x47, 0x6a, 0x1e, 0xd6, 0xef, 0x29, 0xa4, 0x7e, 0xdc, 0x5b, 0xd3,
+ 0x0a, 0xbe, 0x77, 0xd1, 0x8d, 0x5c, 0x07, 0xdd, 0x54, 0xb1, 0xa5, 0x1b,
+ 0xc2, 0xae, 0x62, 0x9e, 0x9c, 0xe8, 0xa2, 0xeb, 0xab, 0x4d, 0x44, 0xbd,
+ 0x6d, 0x22, 0xf6, 0x7b, 0x23, 0x97, 0xc7, 0xf3, 0x87, 0xa5, 0xdf, 0xa5,
+ 0x82, 0x23, 0x37, 0x3c, 0x70, 0xe4, 0x3d, 0x81, 0x23, 0xef, 0x6d, 0x81,
+ 0x23, 0x7b, 0x95, 0x2d, 0xd1, 0x46, 0xcd, 0x0a, 0x3f, 0x5e, 0x63, 0xfc,
+ 0x78, 0x81, 0xf1, 0xe3, 0x50, 0x03, 0xfc, 0x30, 0x6a, 0xf0, 0xe3, 0xb0,
+ 0xc0, 0x8f, 0x9f, 0x6d, 0x8a, 0x1f, 0x87, 0xfc, 0x9b, 0xf9, 0x82, 0x34,
+ 0x6e, 0x0e, 0xd0, 0x4a, 0xce, 0xa1, 0xd5, 0x45, 0x9b, 0x2d, 0x7b, 0xd8,
+ 0xe6, 0x88, 0x19, 0xce, 0x88, 0x7a, 0x97, 0x82, 0xc0, 0x2b, 0x96, 0xe3,
+ 0x33, 0xa8, 0x69, 0xaa, 0xdb, 0x03, 0x12, 0xef, 0xa5, 0x14, 0xf0, 0x97,
+ 0x7b, 0x12, 0xcb, 0xac, 0x9f, 0xf9, 0x73, 0xde, 0xc7, 0x2b, 0x6b, 0x81,
+ 0x00, 0x7e, 0xf3, 0xcf, 0x04, 0x69, 0x63, 0x8d, 0xed, 0x54, 0xc6, 0xb1,
+ 0xab, 0xb9, 0x21, 0xba, 0x92, 0x1b, 0xa0, 0x8d, 0xdc, 0x30, 0xbd, 0x93,
+ 0xc3, 0x33, 0x00, 0x73, 0x3e, 0x16, 0x30, 0x37, 0xe8, 0x60, 0x90, 0xc7,
+ 0xac, 0x0e, 0xd0, 0xfa, 0xaa, 0xc6, 0x57, 0xe0, 0x2a, 0xf6, 0x3f, 0xd2,
+ 0x23, 0xeb, 0xd0, 0xea, 0x71, 0x20, 0x56, 0x85, 0x03, 0xf2, 0x1a, 0xec,
+ 0xfd, 0x42, 0x7d, 0x0d, 0x6d, 0xab, 0x39, 0x83, 0x1c, 0xb8, 0x36, 0xb6,
+ 0xc9, 0x6d, 0xe1, 0x73, 0x3d, 0xe8, 0x87, 0x4e, 0x6b, 0xdc, 0x4d, 0x5d,
+ 0xbc, 0x07, 0x0e, 0xf2, 0x87, 0x86, 0x59, 0x3f, 0xed, 0x16, 0xfa, 0x68,
+ 0xd4, 0x09, 0x84, 0x62, 0x54, 0x3a, 0x6b, 0x38, 0xe8, 0x93, 0xf8, 0x08,
+ 0xdf, 0xcf, 0x50, 0x7e, 0x9e, 0x4e, 0x17, 0x3e, 0xd5, 0xea, 0x9e, 0x88,
+ 0xd1, 0x9e, 0xe0, 0x39, 0x43, 0x4e, 0x56, 0xe2, 0x22, 0x54, 0x8e, 0x8b,
+ 0xb4, 0xf2, 0xba, 0x25, 0x2d, 0xcd, 0x39, 0x3c, 0xae, 0xc8, 0xe3, 0x8a,
+ 0x88, 0xa9, 0xf1, 0xf9, 0x55, 0xc4, 0x73, 0x87, 0x68, 0x63, 0x11, 0x34,
+ 0x07, 0xff, 0x44, 0x25, 0x86, 0xba, 0xb1, 0x86, 0xf3, 0xf0, 0x51, 0x54,
+ 0x62, 0xa8, 0x1b, 0x2a, 0x86, 0xba, 0xb1, 0x36, 0x2d, 0xf8, 0xf0, 0x42,
+ 0x8e, 0x79, 0x40, 0xce, 0xaf, 0xf2, 0x07, 0xf7, 0xa9, 0x77, 0xf6, 0x9c,
+ 0x10, 0x3e, 0xe4, 0x1e, 0x67, 0x73, 0x18, 0x1e, 0xac, 0x83, 0xe1, 0xb4,
+ 0xd0, 0x83, 0xe2, 0x7c, 0xcf, 0x58, 0xee, 0x04, 0xc3, 0x73, 0x96, 0x69,
+ 0x69, 0xb7, 0xa2, 0x25, 0x1d, 0x93, 0xed, 0x26, 0xf5, 0xfe, 0x1f, 0xa1,
+ 0xeb, 0x4b, 0xfe, 0x33, 0x54, 0xc3, 0x7f, 0x28, 0x10, 0x1d, 0x97, 0xd7,
+ 0xa7, 0x8b, 0xaf, 0x0c, 0x6b, 0xff, 0x5b, 0x9a, 0xef, 0xbb, 0x90, 0xdb,
+ 0x49, 0x4c, 0x97, 0xe5, 0xa6, 0x67, 0xce, 0xe0, 0x76, 0x9f, 0xad, 0x71,
+ 0xe1, 0xc4, 0x6d, 0xe0, 0x93, 0xbc, 0x47, 0x05, 0x9f, 0xfe, 0x77, 0x16,
+ 0xc0, 0xb2, 0x93, 0x05, 0x98, 0x57, 0x84, 0x80, 0xf5, 0x03, 0x03, 0xb4,
+ 0x8e, 0x39, 0x00, 0x1e, 0x53, 0x68, 0x02, 0xe6, 0x19, 0xa7, 0xf5, 0x40,
+ 0xfb, 0xfb, 0x95, 0xc1, 0xeb, 0x5d, 0x1b, 0xa0, 0x67, 0x4f, 0x2d, 0xea,
+ 0x79, 0x2c, 0x07, 0xca, 0xa3, 0x4e, 0x2a, 0x0c, 0x24, 0xe6, 0x27, 0x90,
+ 0xff, 0x80, 0xfe, 0x00, 0xf9, 0x11, 0x98, 0x9f, 0x9c, 0x81, 0x72, 0xa0,
+ 0x35, 0x53, 0xcd, 0x6b, 0x40, 0xfa, 0x40, 0x61, 0x08, 0x2a, 0x53, 0x41,
+ 0x63, 0x1d, 0x40, 0xf6, 0x12, 0x21, 0x68, 0xd8, 0x01, 0x69, 0x20, 0xbb,
+ 0x79, 0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x4f,
+ 0xec, 0x40, 0x97, 0xc2, 0xdc, 0xf4, 0xff, 0xff, 0x31, 0x15, 0x16, 0x60,
+ 0xda, 0x03, 0xad, 0xf9, 0xfc, 0xfd, 0xff, 0x80, 0x08, 0x0b, 0x43, 0x0b,
+ 0x7c, 0xed, 0x9e, 0xb0, 0x3c, 0xa8, 0x9c, 0x5b, 0x00, 0x64, 0xb5, 0xc1,
+ 0xeb, 0x6d, 0x16, 0xf0, 0x7d, 0xc4, 0x0b, 0x18, 0x7e, 0x01, 0xcb, 0x95,
+ 0xff, 0xff, 0x97, 0xc2, 0xd5, 0x82, 0x00, 0x00, 0xd4, 0xc2, 0xcb, 0x42,
+ 0x60, 0x7c, 0x00, 0x00, 0x00 };
+static u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = {
+ 0x08001ad8, 0x08001b14, 0x08001b14, 0x08001b14, 0x08001b14, 0x08001b14,
+ 0x08001a24, 0x08001b14, 0x08001a98, 0x08001b14, 0x080019ac, 0x08001b14,
+ 0x08001b14, 0x08001b14, 0x080019b8, 0x0, 0x08002a2c, 0x08002a7c,
+ 0x08002aac, 0x08002adc, 0x08002b0c, 0x0, 0x08005fac, 0x08005fac,
+ 0x08005fac, 0x08005fac, 0x08005fac, 0x08005fd8, 0x08005fd8, 0x08006018,
+ 0x08006024, 0x08006024, 0x08005fac, 0x0, 0x0 };
+static u32 bnx2_COM_b09FwBss[(0x88/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b09FwSbss[(0x5c/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_com_fw_09 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x080000b0,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x7c5c,
+ .text_index = 0x0,
+ .gz_text = bnx2_COM_b09FwText,
+ .gz_text_len = sizeof(bnx2_COM_b09FwText),
+
+ .data_addr = 0x08007d00,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_COM_b09FwData,
+
+ .sbss_addr = 0x08007d00,
+ .sbss_len = 0x5c,
+ .sbss_index = 0x0,
+ .sbss = bnx2_COM_b09FwSbss,
+
+ .bss_addr = 0x08007d60,
+ .bss_len = 0x88,
+ .bss_index = 0x0,
+ .bss = bnx2_COM_b09FwBss,
+
+ .rodata_addr = 0x08007c60,
+ .rodata_len = 0x88,
+ .rodata_index = 0x0,
+ .rodata = bnx2_COM_b09FwRodata,
+};
+
+static u8 bnx2_CP_b09FwText[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0x8e, 0xfc, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xbd, 0x7d, 0x0d, 0x74,
+ 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x79, 0x92, 0xc6, 0xb2, 0x2c, 0x3f,
+ 0xcb, 0x63, 0x65, 0x22, 0x0b, 0x7b, 0x46, 0x7a, 0xb2, 0x95, 0x58, 0x64,
+ 0xc7, 0xae, 0x00, 0x6d, 0x3b, 0x85, 0xe9, 0x48, 0xb2, 0x9d, 0x0f, 0x8a,
+ 0x4c, 0x44, 0x4f, 0x5a, 0xe8, 0x22, 0xc6, 0x76, 0x48, 0x80, 0xb2, 0x4e,
+ 0x09, 0x69, 0x80, 0x04, 0x0f, 0x23, 0xf9, 0x83, 0x74, 0xec, 0x51, 0x12,
+ 0xc5, 0x76, 0x4f, 0x73, 0x58, 0x55, 0x92, 0x1d, 0x43, 0xa7, 0x1e, 0x27,
+ 0x71, 0x68, 0xf6, 0x6c, 0x68, 0xb4, 0x4a, 0xe2, 0xa6, 0x3d, 0xd9, 0xd6,
+ 0xf4, 0x84, 0x6e, 0xda, 0x43, 0x77, 0x85, 0x71, 0x88, 0x4b, 0xb3, 0x4b,
+ 0xf8, 0x68, 0x61, 0xa1, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d, 0xd2, 0xe8,
+ 0xc3, 0x09, 0xa1, 0xbb, 0xf5, 0x39, 0xcf, 0x6f, 0xde, 0xfd, 0xfc, 0xdf,
+ 0xff, 0xfd, 0x7f, 0xdf, 0x0f, 0xad, 0x17, 0xa9, 0x17, 0xfb, 0x6f, 0x15,
+ 0x9e, 0x6d, 0x89, 0x7d, 0xbb, 0xb7, 0x5e, 0xd7, 0x73, 0x1d, 0x7e, 0x6e,
+ 0x75, 0x57, 0x46, 0x95, 0xbc, 0x89, 0x7f, 0x89, 0x9f, 0xa1, 0x4c, 0x44,
+ 0xc4, 0x0b, 0xfb, 0xe2, 0x23, 0x51, 0x95, 0x1e, 0xfc, 0x64, 0xd6, 0x97,
+ 0x68, 0x24, 0x7d, 0xf6, 0xb3, 0xbb, 0x7d, 0x91, 0x4c, 0x79, 0x4b, 0xa2,
+ 0x57, 0xfe, 0x25, 0xc8, 0xc7, 0x5c, 0x61, 0xfa, 0x5b, 0xd2, 0xff, 0xfc,
+ 0x9f, 0xbe, 0xf2, 0x8e, 0xe4, 0x6b, 0xe3, 0x11, 0x89, 0x7a, 0xe9, 0x8f,
+ 0x89, 0xb7, 0x49, 0xa2, 0xad, 0xe9, 0x81, 0x4f, 0x3e, 0xbc, 0xf9, 0x6f,
+ 0x44, 0x1a, 0xc3, 0xb6, 0x2e, 0x07, 0x5f, 0xd9, 0x2c, 0xf9, 0x96, 0x74,
+ 0x7c, 0xc8, 0x4d, 0x7b, 0xf2, 0x74, 0x45, 0x06, 0x0a, 0xc5, 0xa8, 0x44,
+ 0xd2, 0x1d, 0x2f, 0xf5, 0x46, 0xf6, 0x07, 0x11, 0xdf, 0xf7, 0x7a, 0xa5,
+ 0xa1, 0x27, 0xdb, 0x8d, 0xf4, 0xf2, 0x56, 0x51, 0x7e, 0x54, 0xb2, 0x15,
+ 0x69, 0x50, 0xbe, 0x8f, 0x77, 0xbd, 0xa8, 0x74, 0xd2, 0xcb, 0x46, 0x5c,
+ 0x29, 0x54, 0x2e, 0xac, 0x30, 0x6d, 0x96, 0xec, 0xfb, 0x6f, 0xa2, 0xe6,
+ 0x8d, 0x36, 0x4b, 0x51, 0x99, 0x8d, 0xc4, 0x05, 0xfd, 0x00, 0xe6, 0x06,
+ 0x19, 0x2e, 0x25, 0x24, 0x5b, 0x64, 0xbf, 0xae, 0xe4, 0x3c, 0xf6, 0xd9,
+ 0x80, 0xfa, 0x2b, 0x9d, 0xe5, 0xcb, 0xb3, 0xec, 0x4b, 0x28, 0x9b, 0x40,
+ 0xb9, 0x56, 0x79, 0xbc, 0x12, 0x97, 0xc7, 0x2a, 0x31, 0x79, 0xb4, 0x72,
+ 0x87, 0x64, 0x50, 0xf7, 0x6c, 0x05, 0x7d, 0x97, 0x6a, 0xa5, 0x77, 0xac,
+ 0x5e, 0xb2, 0x63, 0xed, 0xf1, 0x9c, 0x04, 0xc1, 0x27, 0x52, 0x1f, 0x95,
+ 0xa1, 0x26, 0x94, 0x2f, 0x31, 0x2f, 0xbe, 0x20, 0x2f, 0x97, 0xda, 0xe2,
+ 0xe5, 0x94, 0x23, 0x99, 0xc1, 0x64, 0x7c, 0x48, 0xf1, 0xbb, 0x46, 0xb2,
+ 0x5d, 0xf8, 0x1e, 0x70, 0x25, 0xe2, 0x07, 0xc1, 0x1d, 0xa9, 0x26, 0xc0,
+ 0x91, 0x4c, 0x24, 0x14, 0xeb, 0xb2, 0x5e, 0x32, 0x9f, 0x50, 0x51, 0xc9,
+ 0x57, 0xae, 0x93, 0x44, 0x53, 0x10, 0xbc, 0x37, 0xe5, 0x21, 0x5d, 0xa4,
+ 0xb7, 0x28, 0xfb, 0x54, 0xda, 0x47, 0x9b, 0x92, 0x52, 0xe9, 0xb5, 0x18,
+ 0xc7, 0x16, 0xe0, 0xa9, 0x56, 0x32, 0x31, 0xc9, 0xa8, 0xb4, 0x24, 0x54,
+ 0x7a, 0x05, 0xd2, 0x1c, 0xa9, 0xf1, 0xa7, 0x2c, 0x9d, 0xac, 0xc6, 0xb7,
+ 0x0c, 0xa8, 0x74, 0xd3, 0xa2, 0xf4, 0x64, 0x42, 0xd4, 0x8f, 0xea, 0xd0,
+ 0x67, 0x67, 0x46, 0x31, 0x0d, 0x6f, 0x9d, 0x76, 0xfd, 0x32, 0x69, 0x1f,
+ 0x74, 0x16, 0xa6, 0x3d, 0xb5, 0x8a, 0xb0, 0x8a, 0xe2, 0xef, 0x28, 0xe0,
+ 0x6a, 0x41, 0xff, 0xed, 0x5e, 0x0d, 0xc6, 0x35, 0x90, 0x4a, 0x7a, 0xfd,
+ 0xea, 0xc5, 0x40, 0x9a, 0x09, 0x33, 0xf3, 0x14, 0xf2, 0x50, 0x34, 0x9d,
+ 0xc2, 0xbc, 0xb9, 0x72, 0x08, 0x63, 0xbb, 0x38, 0x96, 0xf4, 0xda, 0x14,
+ 0xde, 0x53, 0xfc, 0xdd, 0x34, 0x14, 0x49, 0x07, 0x41, 0x36, 0x35, 0x2e,
+ 0xb9, 0x72, 0xd2, 0x9b, 0x05, 0x70, 0xbd, 0x63, 0x71, 0x8c, 0x1f, 0xe3,
+ 0x88, 0x65, 0x92, 0x6b, 0xa4, 0xcb, 0xce, 0xcf, 0x5f, 0xa2, 0xef, 0x76,
+ 0xef, 0x0e, 0xd5, 0xee, 0xa5, 0x54, 0xd2, 0x9b, 0x90, 0x3f, 0xc4, 0x77,
+ 0x10, 0xec, 0x4a, 0x25, 0xe3, 0x79, 0xcc, 0xdd, 0xa5, 0x62, 0x4c, 0x5e,
+ 0x2e, 0x26, 0x41, 0xa9, 0xc9, 0xce, 0x49, 0xd9, 0x92, 0x9a, 0x04, 0xdc,
+ 0x05, 0x3c, 0x07, 0x99, 0x57, 0x46, 0x5e, 0x99, 0x75, 0x83, 0xe0, 0xe6,
+ 0xd4, 0x89, 0x60, 0xa8, 0xd9, 0xd0, 0xfe, 0xd3, 0x25, 0xcc, 0x2b, 0xe6,
+ 0xe9, 0xb1, 0x12, 0xe6, 0xb5, 0x84, 0x39, 0xd5, 0xf3, 0xdf, 0x89, 0xf9,
+ 0x27, 0x8d, 0x90, 0x3e, 0xb6, 0x59, 0x7a, 0x7d, 0xb7, 0x7d, 0x8b, 0x64,
+ 0x4b, 0x8e, 0x64, 0x53, 0x3f, 0x09, 0x32, 0x9a, 0x27, 0xc4, 0xe9, 0x2d,
+ 0x91, 0x26, 0x6b, 0x00, 0x2b, 0x3f, 0x7f, 0xdd, 0x96, 0x8b, 0x3a, 0x18,
+ 0x06, 0xe7, 0x83, 0xf9, 0x51, 0xe5, 0xd7, 0xd9, 0xfc, 0x90, 0xf6, 0xf9,
+ 0x0f, 0x74, 0xe7, 0xcf, 0x97, 0xcb, 0x92, 0x36, 0x2b, 0x22, 0xb9, 0x07,
+ 0x03, 0xe9, 0x4d, 0x01, 0x5f, 0x6c, 0xd3, 0x4b, 0x89, 0xae, 0xeb, 0xb1,
+ 0x8c, 0x2e, 0x8b, 0x7f, 0x3f, 0xae, 0x41, 0x1f, 0x4e, 0x5f, 0x69, 0xbe,
+ 0x6e, 0x5f, 0xe9, 0x85, 0x98, 0x85, 0x0f, 0xdf, 0x3d, 0x4e, 0xb6, 0xf2,
+ 0x77, 0x76, 0x8e, 0xc3, 0x71, 0x74, 0x2d, 0x43, 0xe3, 0x2e, 0xf8, 0xc1,
+ 0x93, 0x5c, 0xb1, 0x07, 0xfd, 0xc6, 0xf0, 0x0e, 0x82, 0x91, 0x54, 0x26,
+ 0xe9, 0x4a, 0x1a, 0xdf, 0x03, 0x98, 0xaf, 0x0e, 0xe0, 0x4f, 0xdc, 0xec,
+ 0xe6, 0x94, 0xf4, 0x55, 0x40, 0x7b, 0x95, 0x37, 0x96, 0x14, 0x7a, 0x0c,
+ 0xa9, 0x7f, 0xb1, 0xb8, 0x61, 0x3f, 0x7c, 0xbb, 0x32, 0x02, 0xfa, 0x28,
+ 0x8c, 0xf9, 0x32, 0x5c, 0x9c, 0xf6, 0x94, 0x24, 0x41, 0xbb, 0x69, 0xe9,
+ 0xad, 0xf8, 0x52, 0x28, 0xe2, 0x5d, 0x6a, 0x07, 0xfd, 0xba, 0x92, 0x89,
+ 0x9b, 0x39, 0x29, 0x14, 0x7f, 0x09, 0xe3, 0x02, 0x8e, 0x7d, 0xfe, 0xee,
+ 0xb1, 0xb0, 0x80, 0xf7, 0xbb, 0x53, 0x1a, 0x3f, 0x6f, 0x0e, 0x06, 0xf6,
+ 0x8d, 0x31, 0x60, 0x9c, 0x85, 0xb2, 0x8b, 0x77, 0x0c, 0xef, 0x90, 0x16,
+ 0xe3, 0x80, 0xa9, 0x55, 0x86, 0x41, 0x8b, 0xbd, 0x82, 0xdf, 0x53, 0x84,
+ 0x91, 0xfd, 0xb6, 0xe8, 0xdf, 0xc3, 0x63, 0x1b, 0xf4, 0x77, 0x6e, 0xa0,
+ 0x45, 0xf2, 0x53, 0xe1, 0x58, 0x28, 0x0f, 0x28, 0x03, 0x92, 0x87, 0x45,
+ 0x28, 0x13, 0x82, 0xe0, 0xc1, 0x14, 0xe5, 0x42, 0x10, 0x3c, 0x96, 0xa2,
+ 0x9c, 0x38, 0x07, 0xfe, 0xa7, 0x6c, 0x20, 0xaf, 0xae, 0x55, 0x9c, 0x83,
+ 0x6c, 0x11, 0x7d, 0x40, 0x4e, 0xe4, 0xba, 0x4e, 0x40, 0x6e, 0x50, 0xae,
+ 0x5c, 0xf8, 0x44, 0xd6, 0xcf, 0xc7, 0x23, 0x1a, 0x0f, 0x98, 0x6f, 0xc8,
+ 0xbc, 0x8c, 0x86, 0xbc, 0x4d, 0x0a, 0x5d, 0xa3, 0xb6, 0xcc, 0x65, 0x5d,
+ 0xc6, 0x5d, 0x52, 0xe6, 0x76, 0x65, 0xf8, 0xae, 0x15, 0xf3, 0xb1, 0x42,
+ 0x11, 0x4f, 0x6d, 0x9b, 0xf8, 0x2d, 0xd1, 0x9a, 0xf4, 0x97, 0x90, 0x37,
+ 0x7d, 0xd7, 0x49, 0x7f, 0xb9, 0xbc, 0x59, 0x77, 0x69, 0xde, 0x88, 0xb8,
+ 0x7e, 0xb2, 0x73, 0x97, 0x9a, 0x01, 0x3d, 0x05, 0xc1, 0xc9, 0x54, 0x98,
+ 0xfe, 0x8f, 0xee, 0xd2, 0x3e, 0x12, 0x35, 0x4b, 0xd3, 0xee, 0x5d, 0x26,
+ 0xed, 0xc4, 0x32, 0x69, 0x1b, 0x6a, 0x97, 0xa6, 0xbd, 0x7f, 0x99, 0xb4,
+ 0xfb, 0x97, 0x49, 0xfb, 0x5f, 0xcb, 0xa4, 0x7d, 0x67, 0x99, 0xb4, 0xef,
+ 0x2d, 0x93, 0xd6, 0x52, 0xb7, 0x34, 0xcd, 0x05, 0x3f, 0x6d, 0x92, 0x42,
+ 0xec, 0x73, 0x1c, 0xbb, 0xc5, 0xcd, 0xfe, 0xc8, 0x52, 0xdc, 0xd4, 0xa0,
+ 0x5c, 0xeb, 0xa2, 0x72, 0x53, 0xcb, 0x94, 0xab, 0x45, 0xb9, 0xa6, 0x45,
+ 0xe5, 0x92, 0xcb, 0xe0, 0xba, 0x4e, 0xeb, 0xaf, 0x85, 0xe5, 0x0a, 0xcb,
+ 0x94, 0x63, 0xfa, 0x1e, 0xdb, 0xcf, 0x16, 0x68, 0x99, 0xd7, 0x9b, 0xaf,
+ 0x5a, 0x91, 0x66, 0xa6, 0xb7, 0x42, 0x47, 0xac, 0x50, 0x86, 0xdf, 0x29,
+ 0x5b, 0x98, 0xe6, 0x81, 0xee, 0xa3, 0xa0, 0x3b, 0xca, 0x47, 0xf0, 0x91,
+ 0x4f, 0xfe, 0x5d, 0x25, 0x43, 0xb1, 0x2d, 0xde, 0x2f, 0xa8, 0x06, 0xd0,
+ 0x58, 0xd2, 0x4b, 0x28, 0xf2, 0x97, 0xe4, 0x23, 0x69, 0x3f, 0xdf, 0x2b,
+ 0x2a, 0xa6, 0x24, 0x90, 0xbe, 0x94, 0x6a, 0x52, 0xb2, 0x1f, 0xfc, 0x93,
+ 0x81, 0x4e, 0xda, 0x15, 0xf4, 0x6a, 0x1e, 0x32, 0x65, 0xaf, 0x2c, 0x2b,
+ 0x7d, 0x39, 0x48, 0x19, 0x97, 0xce, 0xdc, 0x95, 0xf5, 0xa7, 0x7b, 0x6a,
+ 0x41, 0xb3, 0x17, 0x51, 0x67, 0x07, 0x6a, 0xee, 0x2d, 0xbb, 0xd2, 0x57,
+ 0xee, 0x04, 0x2f, 0x38, 0x72, 0xde, 0x5f, 0x2d, 0xe7, 0x53, 0x28, 0x5b,
+ 0x89, 0xc8, 0x4c, 0xcc, 0x91, 0x19, 0x7c, 0x67, 0x53, 0xc8, 0xab, 0x84,
+ 0xbc, 0xd5, 0x29, 0x07, 0x4a, 0xbe, 0x1c, 0x2e, 0xfd, 0x92, 0x0a, 0xf5,
+ 0x56, 0x7f, 0x6a, 0xa5, 0x9c, 0xf6, 0x4c, 0xdb, 0x3b, 0xfc, 0x69, 0x68,
+ 0x4c, 0x57, 0x2e, 0xfa, 0xc9, 0xf8, 0x8c, 0xe6, 0x89, 0x1f, 0x06, 0x7d,
+ 0x68, 0x67, 0xc2, 0x4f, 0x7a, 0x7f, 0x8a, 0xef, 0xa1, 0x32, 0xed, 0x90,
+ 0xf9, 0xb6, 0x86, 0xd1, 0xd6, 0xa1, 0xd2, 0x2a, 0xf9, 0xb0, 0xad, 0xbf,
+ 0xdd, 0x9f, 0xee, 0x04, 0xcf, 0x79, 0xa7, 0x28, 0x23, 0x8a, 0x80, 0x6b,
+ 0x10, 0xbc, 0x8d, 0xba, 0xcf, 0x69, 0x39, 0x05, 0xbb, 0xa5, 0xb8, 0x1a,
+ 0x72, 0xf7, 0x1f, 0x83, 0x0f, 0xc7, 0x58, 0x9e, 0x69, 0xd4, 0x25, 0x32,
+ 0xaa, 0xd2, 0x90, 0x09, 0xdd, 0x94, 0x85, 0x09, 0xc8, 0x41, 0xc8, 0x96,
+ 0xd2, 0x4f, 0x83, 0x8c, 0x5b, 0x2d, 0xdf, 0x24, 0x3f, 0x5f, 0x86, 0x69,
+ 0x09, 0x23, 0x2f, 0x4b, 0xb3, 0x73, 0xb2, 0x22, 0x0f, 0xf9, 0xf2, 0x74,
+ 0x85, 0x72, 0xe1, 0x7a, 0xf0, 0x68, 0xab, 0xf4, 0x15, 0x93, 0xf9, 0x8c,
+ 0x6c, 0xc2, 0xfc, 0x7d, 0x1e, 0x73, 0xea, 0xe2, 0xb9, 0xaf, 0x5e, 0x1a,
+ 0x53, 0xd0, 0xcd, 0x4c, 0x47, 0xa3, 0xcd, 0x51, 0xc8, 0xa8, 0xdf, 0x03,
+ 0x1e, 0x86, 0x39, 0xe7, 0xf1, 0x6c, 0xc4, 0x19, 0xa0, 0x3d, 0x32, 0x40,
+ 0xfd, 0x50, 0x66, 0xdb, 0x84, 0x37, 0x6e, 0x7f, 0x47, 0xb5, 0x8c, 0x31,
+ 0xbf, 0x1b, 0xf0, 0x3b, 0x61, 0x7f, 0x7b, 0xf8, 0xed, 0xdb, 0xdf, 0x31,
+ 0xfc, 0xee, 0xb4, 0xbf, 0xa1, 0x5b, 0x8b, 0x5d, 0xfa, 0xf7, 0x48, 0x69,
+ 0xfb, 0x76, 0xe5, 0x5f, 0x27, 0xb9, 0xa9, 0x56, 0x39, 0x50, 0xf4, 0xad,
+ 0x6c, 0xc1, 0x23, 0x4f, 0x3a, 0x66, 0x9c, 0x80, 0x9b, 0xb2, 0xb3, 0x94,
+ 0x77, 0x06, 0x08, 0x3f, 0x68, 0xa0, 0xb7, 0xb8, 0xc5, 0x5b, 0x23, 0xa4,
+ 0x81, 0x11, 0xa7, 0xb7, 0xe2, 0x64, 0x60, 0xaf, 0xc5, 0x87, 0xe5, 0x30,
+ 0x7e, 0x8b, 0x17, 0x49, 0x3f, 0x89, 0xb7, 0xc1, 0x01, 0xf5, 0xce, 0x70,
+ 0x89, 0xf2, 0xd2, 0xc7, 0xd8, 0x13, 0x72, 0x6e, 0x81, 0x0d, 0x45, 0x5c,
+ 0x28, 0xc9, 0x8d, 0x25, 0x4f, 0xe4, 0x25, 0x99, 0x1f, 0x07, 0x43, 0xec,
+ 0x4a, 0xb9, 0xf2, 0xde, 0x14, 0x68, 0xf7, 0x3a, 0x47, 0xb6, 0x5f, 0xe7,
+ 0xc2, 0xe6, 0xf1, 0xc7, 0xb7, 0x83, 0xfe, 0x31, 0xcf, 0x9a, 0x1e, 0xd4,
+ 0x19, 0x81, 0x9d, 0x08, 0x6c, 0x9f, 0xe9, 0xea, 0x1b, 0x2e, 0xe6, 0x3e,
+ 0xa6, 0xd2, 0xfb, 0x3e, 0x95, 0xed, 0xbe, 0x46, 0x72, 0x83, 0x0a, 0x38,
+ 0x6a, 0x1e, 0x82, 0x1e, 0xc4, 0xb8, 0x82, 0x00, 0xf4, 0x0c, 0x79, 0x7e,
+ 0xf3, 0xcd, 0x91, 0x74, 0x8d, 0xf4, 0x0e, 0x36, 0xa3, 0x0e, 0xf3, 0x88,
+ 0xaf, 0xaf, 0xa2, 0x9d, 0x64, 0xa2, 0x4f, 0xe4, 0x9e, 0x91, 0xee, 0x59,
+ 0x67, 0x78, 0xf4, 0x37, 0xc0, 0x93, 0x5b, 0x51, 0xff, 0x01, 0xd4, 0x7f,
+ 0xcd, 0x29, 0x8c, 0xfd, 0xc8, 0x19, 0x1e, 0xfb, 0x9e, 0x33, 0x32, 0xb6,
+ 0x61, 0x43, 0x7f, 0xcf, 0x86, 0x0d, 0xbb, 0x7b, 0x5c, 0x99, 0x00, 0x8f,
+ 0x65, 0xbc, 0x0d, 0x1b, 0x46, 0x7a, 0xba, 0x80, 0x83, 0x2d, 0x5e, 0x9f,
+ 0xf8, 0xde, 0x76, 0x01, 0xff, 0xc4, 0xd8, 0x67, 0x14, 0xf9, 0x49, 0xe4,
+ 0xb3, 0x7e, 0x5c, 0xe7, 0xf7, 0xca, 0x96, 0x78, 0x93, 0xb0, 0xff, 0x88,
+ 0x2d, 0x53, 0x13, 0x91, 0xfa, 0x07, 0xec, 0xfc, 0x66, 0x9c, 0x1a, 0x9f,
+ 0xe9, 0x1c, 0x0b, 0xd3, 0x39, 0xb7, 0x7f, 0x67, 0x6d, 0xd5, 0xd5, 0x48,
+ 0xe7, 0x37, 0x71, 0x46, 0xbc, 0xd0, 0xc6, 0xa8, 0xd1, 0xb6, 0x61, 0xae,
+ 0x48, 0x9a, 0x71, 0x65, 0x4f, 0xd1, 0x41, 0x1d, 0xd0, 0xc5, 0x19, 0xfb,
+ 0x1c, 0x05, 0x6c, 0x83, 0x68, 0xeb, 0xe8, 0x21, 0xd4, 0xa3, 0xcc, 0x48,
+ 0x76, 0x8a, 0xfa, 0x00, 0xca, 0x6c, 0xf1, 0xd6, 0x0a, 0x6d, 0x89, 0x3b,
+ 0x25, 0x57, 0x22, 0x7f, 0x77, 0x00, 0x9e, 0xa8, 0x24, 0x9a, 0xf1, 0x5d,
+ 0x81, 0x4d, 0xf1, 0x60, 0x8d, 0x58, 0xdb, 0x45, 0xe6, 0x6d, 0x91, 0x3b,
+ 0x94, 0xc0, 0xde, 0x18, 0x9a, 0x5c, 0x8f, 0x72, 0x0e, 0xf0, 0x42, 0xfb,
+ 0x03, 0xb4, 0x36, 0x99, 0x91, 0xec, 0x26, 0xf0, 0xc9, 0xa4, 0x87, 0x6f,
+ 0xc0, 0x35, 0xf9, 0x16, 0xbc, 0x23, 0xfa, 0xdb, 0xc0, 0x09, 0xbc, 0xa6,
+ 0x22, 0x56, 0x67, 0x75, 0xa1, 0xef, 0xf7, 0x48, 0x76, 0x34, 0x4e, 0x5b,
+ 0x62, 0x75, 0xd6, 0xcf, 0x40, 0xd7, 0x2b, 0x28, 0x41, 0x8c, 0x61, 0xd2,
+ 0x81, 0x3c, 0xa9, 0x95, 0xdd, 0x8f, 0xe0, 0xf7, 0x83, 0xc6, 0xe6, 0xdd,
+ 0x3d, 0xc9, 0x7e, 0x1a, 0x00, 0x13, 0x6c, 0x90, 0x47, 0x60, 0x9b, 0x3e,
+ 0x02, 0x1b, 0xe4, 0x91, 0x66, 0x3c, 0x1c, 0x1b, 0xdb, 0x9f, 0x59, 0x03,
+ 0x31, 0xa9, 0xbf, 0x73, 0xa4, 0x57, 0xd8, 0xea, 0xb9, 0x62, 0xca, 0x94,
+ 0x2f, 0x76, 0xeb, 0xb7, 0xa1, 0xeb, 0x1e, 0xfb, 0x3b, 0xae, 0xf9, 0x3a,
+ 0xdf, 0x04, 0x9a, 0xaf, 0x74, 0x69, 0x99, 0x93, 0xf5, 0xf1, 0x86, 0xcd,
+ 0x99, 0x69, 0xe2, 0x18, 0xe3, 0x36, 0x2d, 0xae, 0xd3, 0x12, 0x4d, 0xd6,
+ 0xde, 0x28, 0x59, 0x5b, 0x03, 0xb8, 0x19, 0x6a, 0x06, 0xc4, 0x94, 0xcf,
+ 0x12, 0xe2, 0x93, 0x32, 0x00, 0xf4, 0x0b, 0x9b, 0xe2, 0xdc, 0x15, 0xe5,
+ 0xdf, 0xac, 0xb6, 0xb1, 0xce, 0x56, 0x48, 0xc7, 0xa4, 0xed, 0x20, 0xb8,
+ 0x3f, 0x55, 0x87, 0xf6, 0xc9, 0xf3, 0xb0, 0x40, 0x8e, 0x02, 0x26, 0x60,
+ 0xa2, 0xc6, 0x3f, 0xab, 0x69, 0xa0, 0xd6, 0x27, 0x0d, 0x57, 0xf3, 0x97,
+ 0xe8, 0xf1, 0x9e, 0x05, 0x8f, 0xc1, 0xbe, 0x81, 0xfd, 0xd6, 0x01, 0xdb,
+ 0x98, 0x7d, 0x1c, 0xe6, 0xb7, 0xa7, 0xc0, 0x53, 0xd9, 0x39, 0x9e, 0x12,
+ 0x99, 0x28, 0x12, 0x37, 0xa1, 0x5d, 0xc7, 0x79, 0x26, 0x7e, 0x32, 0x18,
+ 0x33, 0xdf, 0x7d, 0x16, 0x4f, 0x3b, 0x2d, 0x9e, 0x6e, 0xb2, 0xef, 0x11,
+ 0xbc, 0x69, 0xe3, 0x0d, 0xe0, 0xcd, 0xf9, 0x19, 0xc4, 0x9b, 0xbc, 0x75,
+ 0x0b, 0xde, 0x28, 0x5b, 0xca, 0xc8, 0x6e, 0x6d, 0x87, 0x45, 0xe4, 0x57,
+ 0xb4, 0x6c, 0xfb, 0x02, 0xe6, 0xb2, 0x48, 0xfa, 0x95, 0x7c, 0x2c, 0x02,
+ 0x9c, 0x14, 0xf0, 0xfb, 0x4e, 0xd7, 0xd0, 0x2a, 0x71, 0xb2, 0xc0, 0x57,
+ 0xaa, 0x82, 0x29, 0x66, 0xe5, 0x5c, 0x42, 0xdb, 0xfa, 0xb9, 0xe2, 0x07,
+ 0x34, 0x5c, 0xb7, 0x42, 0xde, 0xe5, 0x45, 0x35, 0x43, 0x37, 0x80, 0x16,
+ 0x54, 0x0c, 0x9a, 0x2b, 0x78, 0x06, 0x7a, 0x29, 0x37, 0x49, 0xdb, 0xb8,
+ 0x8d, 0x7e, 0x49, 0x34, 0xd7, 0xd5, 0x48, 0x3a, 0x52, 0x0a, 0xf6, 0x17,
+ 0xbe, 0x55, 0xae, 0x4b, 0xd3, 0xa9, 0xa3, 0xfc, 0x98, 0xb6, 0x7f, 0x5d,
+ 0x1f, 0xd2, 0xd6, 0xf8, 0xbd, 0xae, 0xf2, 0xd7, 0x2e, 0x4e, 0x4b, 0x50,
+ 0x0f, 0xa3, 0x5e, 0x22, 0xd7, 0xd5, 0x4c, 0x1e, 0xf3, 0x40, 0xbf, 0x19,
+ 0xe5, 0x6b, 0xdf, 0x27, 0xaf, 0xba, 0x57, 0x2f, 0x2a, 0xaf, 0xdf, 0x8e,
+ 0xfd, 0x76, 0xed, 0xdb, 0xb3, 0xef, 0x84, 0x7d, 0xe7, 0xdd, 0x6e, 0xbe,
+ 0x1d, 0x71, 0xd3, 0x7c, 0x83, 0x92, 0xd3, 0x6c, 0x43, 0xf3, 0x95, 0x95,
+ 0x33, 0x1d, 0x5e, 0x41, 0xc8, 0x57, 0x9f, 0x93, 0x5b, 0x27, 0x8d, 0xfc,
+ 0xdd, 0x0e, 0x19, 0x04, 0xff, 0xcc, 0x9b, 0x11, 0xc0, 0x3f, 0x98, 0x96,
+ 0x5b, 0x2b, 0xc4, 0xdb, 0xef, 0x02, 0x7f, 0x60, 0xe2, 0x7a, 0xea, 0x74,
+ 0xca, 0xdd, 0x3b, 0x61, 0xf7, 0xa2, 0x7c, 0x91, 0x38, 0x1f, 0xd2, 0x73,
+ 0x53, 0x28, 0xee, 0xd1, 0x73, 0x73, 0xb0, 0x38, 0x03, 0xfc, 0xdc, 0x06,
+ 0xba, 0x0f, 0x82, 0x99, 0x54, 0x01, 0x94, 0xf3, 0x11, 0xfc, 0x86, 0x1d,
+ 0x50, 0xfc, 0x18, 0xf2, 0x1b, 0xa5, 0x30, 0x4a, 0x9e, 0x73, 0x2d, 0x0f,
+ 0xbf, 0x13, 0xfc, 0x14, 0x45, 0xbb, 0x48, 0xeb, 0xe6, 0xef, 0x9f, 0x20,
+ 0x0f, 0xef, 0x49, 0x4c, 0x62, 0x33, 0x6d, 0x1d, 0xf6, 0xcd, 0xb9, 0xe3,
+ 0x9c, 0xc5, 0xb4, 0x2c, 0x3f, 0x3b, 0x37, 0x6f, 0x97, 0xe7, 0xe8, 0x36,
+ 0x4f, 0x1f, 0x8f, 0xf9, 0x1a, 0x56, 0xd2, 0xfd, 0xb7, 0xb4, 0x5c, 0x72,
+ 0x8f, 0xce, 0xac, 0x30, 0xef, 0xc5, 0x75, 0x39, 0xe7, 0xd5, 0x34, 0x48,
+ 0xbf, 0x25, 0xd9, 0x93, 0x07, 0x3f, 0x61, 0x9c, 0xd2, 0xa7, 0x7d, 0x1d,
+ 0xd2, 0x04, 0x69, 0x60, 0xdc, 0xd2, 0xe6, 0x94, 0xa5, 0xcd, 0x27, 0xf1,
+ 0xc6, 0x53, 0xba, 0x60, 0x69, 0xf3, 0x29, 0xbc, 0xf1, 0x94, 0x5e, 0x9c,
+ 0xe3, 0xe3, 0x5e, 0xf8, 0x72, 0xdb, 0xa1, 0xdf, 0x76, 0x57, 0x40, 0xbf,
+ 0xe0, 0xbb, 0x1c, 0x7c, 0x80, 0x5c, 0x69, 0x1f, 0xde, 0xec, 0x67, 0xa3,
+ 0x6d, 0x3f, 0x23, 0x7b, 0x4a, 0x01, 0xc6, 0x78, 0x37, 0xc6, 0xfb, 0x39,
+ 0xbc, 0x3f, 0xa3, 0xe5, 0x8c, 0xf2, 0x0f, 0x5b, 0x79, 0xf5, 0x79, 0xbc,
+ 0xdb, 0xe3, 0x07, 0xa5, 0xdd, 0x8b, 0xc8, 0x34, 0xda, 0xfa, 0xba, 0xec,
+ 0xa9, 0xcc, 0xe2, 0xb9, 0x84, 0xe7, 0x55, 0x3c, 0x97, 0xd1, 0xde, 0x0b,
+ 0x48, 0x5f, 0x29, 0xd3, 0x5e, 0x3d, 0xca, 0xbf, 0x86, 0xdf, 0xcf, 0xcb,
+ 0xd0, 0x23, 0x2f, 0xe1, 0xf9, 0x01, 0xf2, 0x9f, 0x45, 0xfd, 0x60, 0xf5,
+ 0x8c, 0x4f, 0x19, 0xf6, 0x9c, 0x6d, 0x3b, 0xe5, 0xe4, 0x2a, 0xa0, 0xe9,
+ 0xd2, 0x00, 0xfa, 0xde, 0xa3, 0x79, 0xa6, 0x0f, 0x32, 0x3f, 0x07, 0x19,
+ 0x37, 0xa4, 0x61, 0x6a, 0x07, 0x7c, 0x79, 0xcc, 0x05, 0xde, 0x93, 0xb5,
+ 0x32, 0x1b, 0xa3, 0x1d, 0x79, 0x93, 0x2e, 0x9f, 0x2b, 0x35, 0x69, 0xbb,
+ 0x7a, 0x7c, 0x09, 0xff, 0xd0, 0xef, 0x0a, 0xe5, 0x81, 0x91, 0xc6, 0x13,
+ 0x45, 0xca, 0x02, 0xe8, 0x9f, 0xe2, 0x08, 0xde, 0xb5, 0x5a, 0x26, 0x14,
+ 0x24, 0x94, 0x07, 0xac, 0x47, 0x99, 0x50, 0x2d, 0x77, 0x28, 0x6b, 0x28,
+ 0x7b, 0x28, 0x4b, 0xcc, 0x7c, 0xec, 0x7e, 0x90, 0x32, 0x1c, 0xb4, 0x10,
+ 0xa3, 0xfd, 0xe1, 0x19, 0x1f, 0x64, 0xec, 0x3e, 0x2b, 0x4f, 0x47, 0xf5,
+ 0x5c, 0xec, 0x29, 0xaa, 0x98, 0x2b, 0xa7, 0x91, 0x86, 0xe7, 0xf8, 0xc3,
+ 0x78, 0x7f, 0x49, 0xf6, 0xe0, 0xc9, 0x1d, 0xff, 0x02, 0x7e, 0x73, 0x6e,
+ 0xca, 0x28, 0x87, 0xa7, 0x74, 0x02, 0x6f, 0x3c, 0xa5, 0x31, 0x2b, 0x47,
+ 0xc6, 0xad, 0x1c, 0xe1, 0x9c, 0xde, 0x04, 0x3c, 0x70, 0x7c, 0x4a, 0xc7,
+ 0x17, 0xc0, 0xcf, 0x4e, 0x6e, 0xf2, 0x5d, 0xd6, 0x8f, 0x6d, 0x14, 0xc3,
+ 0x83, 0x78, 0x3a, 0xc9, 0xcf, 0x0d, 0xda, 0x0e, 0xce, 0x69, 0xda, 0xfd,
+ 0x2b, 0xd7, 0xf0, 0x62, 0xcc, 0xe8, 0x14, 0xaf, 0x59, 0x34, 0xef, 0xcf,
+ 0xe1, 0x31, 0x63, 0xf1, 0xc8, 0xdf, 0xca, 0xfe, 0x86, 0xdc, 0x82, 0x4d,
+ 0x9b, 0xf5, 0x7d, 0xcc, 0x03, 0xc6, 0x72, 0x7c, 0x14, 0x7d, 0x3b, 0xb2,
+ 0xdb, 0xa7, 0x0c, 0x67, 0x0c, 0x81, 0xe3, 0x63, 0xbb, 0x48, 0xd7, 0x38,
+ 0x48, 0xc9, 0xbc, 0x6f, 0x7e, 0x13, 0xe6, 0x2c, 0x23, 0x7b, 0x4b, 0xf7,
+ 0x6a, 0x5f, 0xb9, 0xf6, 0x68, 0x93, 0xf5, 0x73, 0xc2, 0x72, 0xa0, 0xd5,
+ 0x18, 0x6d, 0x9b, 0x2f, 0xc5, 0x0c, 0xcd, 0xf3, 0x37, 0xe5, 0x73, 0xb5,
+ 0xbc, 0x37, 0x76, 0x4d, 0x61, 0x81, 0xac, 0xa3, 0x6d, 0x81, 0x39, 0x2b,
+ 0x57, 0xe3, 0x9d, 0xbe, 0x3b, 0xf9, 0x8a, 0xfc, 0x74, 0x10, 0x3c, 0xf1,
+ 0x5d, 0xcb, 0xfb, 0xf4, 0x35, 0xd8, 0xe7, 0x62, 0x7e, 0xf2, 0x60, 0xfb,
+ 0xba, 0x72, 0x0a, 0xb6, 0xdb, 0xf6, 0xb9, 0x36, 0xae, 0x06, 0x3c, 0x51,
+ 0x79, 0xa4, 0xd8, 0x20, 0x93, 0x45, 0xd5, 0x1c, 0xb1, 0xb2, 0x33, 0x22,
+ 0x09, 0x4d, 0xdf, 0xb4, 0xef, 0x7a, 0xc7, 0x22, 0x96, 0xee, 0xd6, 0xd5,
+ 0x48, 0xfd, 0xef, 0x42, 0xc7, 0xa6, 0xa1, 0x63, 0x1b, 0xa1, 0x83, 0x17,
+ 0xcb, 0x88, 0x35, 0x35, 0x4b, 0x65, 0x04, 0xeb, 0x24, 0xe1, 0x75, 0x1f,
+ 0x44, 0xbd, 0x90, 0xfe, 0xa2, 0x9a, 0xd6, 0x72, 0x92, 0x77, 0xb6, 0x57,
+ 0x46, 0x9c, 0x1d, 0x95, 0xc5, 0x3a, 0x68, 0x8b, 0xe7, 0x8a, 0x81, 0xf5,
+ 0x91, 0x22, 0x6d, 0xd4, 0x64, 0x2a, 0x0b, 0x9c, 0xec, 0x00, 0xcc, 0xcf,
+ 0x8c, 0xc2, 0x4f, 0xa7, 0x5c, 0x06, 0xcc, 0xa7, 0x01, 0xf3, 0xc4, 0xa8,
+ 0x13, 0xda, 0x06, 0xc2, 0xa0, 0xc8, 0xc4, 0x58, 0x97, 0xcc, 0x4c, 0x91,
+ 0x0e, 0x21, 0x03, 0x46, 0x31, 0x9f, 0xa9, 0x15, 0xb0, 0x03, 0xd8, 0x3f,
+ 0xe4, 0xf6, 0x58, 0x8b, 0xce, 0x33, 0xfa, 0xbc, 0x55, 0x66, 0xca, 0x69,
+ 0x0b, 0xdb, 0xe1, 0x2a, 0xd8, 0x56, 0xcc, 0xc1, 0xb6, 0x03, 0xb0, 0xed,
+ 0x5c, 0x16, 0xb6, 0xe5, 0x74, 0x71, 0x1b, 0x6c, 0x1a, 0xa3, 0x8b, 0x0d,
+ 0x5e, 0x9b, 0x2d, 0x3d, 0xbc, 0xdf, 0xda, 0xbb, 0xb4, 0x89, 0x7e, 0x0a,
+ 0x78, 0x48, 0x63, 0xf8, 0x3d, 0x79, 0x2f, 0x65, 0x19, 0xd2, 0xf9, 0xbd,
+ 0x07, 0x65, 0xf0, 0x3d, 0xf9, 0x67, 0x2b, 0x4c, 0xd9, 0xbb, 0x2d, 0x2c,
+ 0xb4, 0x13, 0x32, 0xb0, 0x89, 0xfb, 0x9c, 0xec, 0x24, 0x61, 0xf8, 0x8f,
+ 0x80, 0x17, 0x79, 0x95, 0xea, 0x36, 0xf9, 0x66, 0xbb, 0xd7, 0xda, 0x76,
+ 0xd8, 0x76, 0x38, 0x96, 0x95, 0x56, 0xcf, 0x87, 0xf4, 0x15, 0xda, 0xd7,
+ 0x23, 0x4e, 0x66, 0xc9, 0xb8, 0xaa, 0x69, 0x8e, 0xf2, 0xd6, 0x95, 0x7e,
+ 0xd0, 0x49, 0xff, 0x02, 0x5a, 0x33, 0x72, 0xc3, 0xd0, 0xf1, 0x0a, 0x3b,
+ 0xbe, 0x1a, 0xc3, 0x37, 0xa9, 0x28, 0xf4, 0x21, 0xe5, 0xcd, 0x0e, 0xe3,
+ 0x9b, 0xcb, 0x43, 0x80, 0x35, 0xfc, 0x3e, 0xa8, 0x6d, 0xce, 0xa7, 0x4b,
+ 0x94, 0x49, 0xf3, 0xb4, 0x68, 0x7c, 0x97, 0x56, 0xf4, 0x55, 0x6d, 0xaf,
+ 0xbb, 0x32, 0x60, 0xe6, 0xfc, 0x30, 0xe7, 0x9c, 0xbe, 0x48, 0xfb, 0x03,
+ 0x03, 0x96, 0xbf, 0x92, 0xa3, 0x79, 0x79, 0xbb, 0x1d, 0xfb, 0x1f, 0x2e,
+ 0x33, 0x77, 0x8d, 0x73, 0x73, 0x37, 0x50, 0x59, 0x3c, 0x46, 0x91, 0xb6,
+ 0x07, 0x58, 0xcf, 0x85, 0x8d, 0x94, 0x92, 0x5a, 0x9f, 0xf2, 0x93, 0xb6,
+ 0x12, 0xd2, 0x27, 0xb6, 0x78, 0x4d, 0xf0, 0x01, 0x9e, 0x5e, 0x62, 0x77,
+ 0x25, 0xac, 0xdc, 0xa4, 0x1f, 0x1c, 0xf6, 0x91, 0xb7, 0x72, 0x32, 0x8f,
+ 0xf6, 0x47, 0x9c, 0xfe, 0xca, 0x72, 0xf2, 0x32, 0x94, 0x93, 0x1c, 0x8f,
+ 0x23, 0x77, 0x3c, 0x48, 0x1e, 0x7d, 0xbf, 0xb6, 0xaf, 0xb7, 0x6e, 0xab,
+ 0x01, 0xfe, 0x08, 0xc7, 0xcc, 0x1a, 0xa2, 0x33, 0xf7, 0x08, 0x6c, 0x22,
+ 0x3b, 0x6f, 0xbb, 0xe7, 0xe6, 0x5f, 0xd3, 0x05, 0x7e, 0x33, 0x8e, 0x6a,
+ 0x68, 0xa4, 0xc6, 0x77, 0x34, 0x2d, 0xd4, 0x2e, 0xb1, 0x65, 0x39, 0x06,
+ 0xda, 0xb3, 0xb5, 0xc6, 0x16, 0x2c, 0xd1, 0xfe, 0xa4, 0xec, 0xa2, 0xfd,
+ 0xf9, 0x43, 0xe0, 0x88, 0xe3, 0xe9, 0xb2, 0x69, 0xb4, 0x53, 0x17, 0x8f,
+ 0x6f, 0xb1, 0xff, 0x48, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x84, 0x22, 0x6c,
+ 0x81, 0x0c, 0x80, 0x97, 0x39, 0x07, 0x8a, 0xb6, 0xeb, 0xb6, 0xbf, 0xa8,
+ 0x31, 0x31, 0xe4, 0xd5, 0xb5, 0x52, 0xcf, 0x3e, 0xc9, 0x7f, 0x7c, 0xaf,
+ 0xd2, 0xf6, 0xef, 0x52, 0x59, 0x56, 0xad, 0x7b, 0xae, 0x9e, 0xc3, 0x5f,
+ 0xff, 0x82, 0x39, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x35, 0x0e, 0x49, 0x13,
+ 0x86, 0x16, 0x0c, 0x2d, 0x6e, 0xb4, 0xfa, 0x26, 0xa4, 0xbd, 0xab, 0x40,
+ 0x7b, 0xf7, 0x81, 0xc6, 0x28, 0xc3, 0x19, 0x97, 0x5b, 0x8b, 0xef, 0x23,
+ 0xf8, 0x0e, 0xf9, 0xe4, 0x4a, 0x32, 0x9c, 0xf2, 0x9b, 0x75, 0xb2, 0x56,
+ 0xee, 0x87, 0x7e, 0x2e, 0xeb, 0x70, 0xdc, 0x94, 0xff, 0xff, 0x15, 0xed,
+ 0xac, 0xad, 0x35, 0xf6, 0xca, 0x8d, 0xb5, 0x94, 0xaf, 0x6b, 0xe4, 0x60,
+ 0x55, 0xda, 0x95, 0xe4, 0x77, 0xf5, 0x98, 0xd7, 0xff, 0x3f, 0x18, 0x73,
+ 0x7c, 0xd1, 0x98, 0x3d, 0x3b, 0xe6, 0x77, 0x21, 0xbf, 0xc9, 0xf8, 0x38,
+ 0x1e, 0xf9, 0x2e, 0x1c, 0xb3, 0xc5, 0x85, 0x1e, 0x57, 0xb5, 0x9c, 0x08,
+ 0x65, 0x04, 0xc7, 0x35, 0x60, 0xc7, 0xf0, 0xb9, 0xaa, 0x71, 0x0d, 0xbc,
+ 0x89, 0x71, 0xb5, 0x2e, 0x18, 0xd7, 0xf6, 0x2b, 0x8e, 0x6b, 0x39, 0x1e,
+ 0x27, 0x2f, 0x87, 0xe3, 0x8b, 0xca, 0xae, 0x22, 0xc7, 0xd8, 0x8f, 0x31,
+ 0x1e, 0xd4, 0xfe, 0x80, 0x19, 0x63, 0xda, 0x8e, 0x51, 0x54, 0xdb, 0xb6,
+ 0x7f, 0x8f, 0xdf, 0xd5, 0xe3, 0xa3, 0xee, 0xff, 0x3e, 0x68, 0xba, 0x4e,
+ 0xb2, 0x5d, 0x75, 0x56, 0xfe, 0xdf, 0x24, 0x1f, 0x2e, 0x71, 0xae, 0x93,
+ 0x19, 0x91, 0x51, 0xe8, 0xe0, 0xff, 0x5c, 0xcb, 0xd8, 0xfd, 0xf6, 0x94,
+ 0xd5, 0x63, 0xd0, 0x17, 0x3b, 0x60, 0xf3, 0xf5, 0x17, 0x55, 0x77, 0x44,
+ 0x82, 0xe0, 0xb6, 0xd4, 0xa7, 0xd1, 0xf7, 0x7e, 0xed, 0xab, 0x2e, 0x8d,
+ 0x9b, 0x3f, 0x57, 0x2b, 0x3e, 0xed, 0x0d, 0xea, 0x73, 0xe8, 0xbb, 0xe3,
+ 0xb4, 0xc1, 0xb2, 0xb0, 0x93, 0x33, 0xf1, 0x88, 0xb6, 0xc5, 0xa8, 0x13,
+ 0x93, 0xf1, 0x8c, 0xa4, 0xd1, 0x5f, 0x26, 0xae, 0x84, 0x7d, 0xc0, 0x56,
+ 0x83, 0x0d, 0xf9, 0xe1, 0xca, 0x3e, 0x3c, 0x0f, 0xcb, 0xad, 0xb0, 0x77,
+ 0x6e, 0x7d, 0xe4, 0x0b, 0x72, 0x1b, 0x6c, 0x9d, 0xdb, 0x1e, 0x19, 0x93,
+ 0xbd, 0xb0, 0x6d, 0xf6, 0xc2, 0xce, 0xd9, 0x5b, 0xa1, 0xed, 0x39, 0x8e,
+ 0xb2, 0xad, 0x55, 0xb4, 0x46, 0x1b, 0x87, 0xe3, 0x23, 0xee, 0x0f, 0x72,
+ 0x0e, 0x52, 0x09, 0xf5, 0x8a, 0x9e, 0x97, 0xa6, 0x05, 0x69, 0xaf, 0x27,
+ 0xab, 0x42, 0xfd, 0xb4, 0xca, 0xc6, 0x8d, 0x8c, 0x0d, 0x78, 0x65, 0xda,
+ 0x22, 0x8d, 0x78, 0xc0, 0x33, 0xf1, 0x47, 0xda, 0xaa, 0x1e, 0x7f, 0x63,
+ 0x9d, 0xf8, 0x2b, 0xeb, 0xa4, 0xfe, 0x73, 0x90, 0xaf, 0xd5, 0x34, 0xc5,
+ 0xb7, 0x67, 0x75, 0x0d, 0x69, 0x8b, 0x32, 0x38, 0xa4, 0x87, 0x8d, 0xaf,
+ 0x23, 0x7f, 0xaf, 0x48, 0x4f, 0xfb, 0xb9, 0x2e, 0xb3, 0xbb, 0x5b, 0x56,
+ 0x33, 0x1e, 0x90, 0xad, 0xcc, 0xc7, 0x04, 0x94, 0x5f, 0x1d, 0x13, 0xa0,
+ 0x9f, 0xf5, 0x01, 0xe0, 0xec, 0x16, 0x3c, 0xfb, 0x64, 0x88, 0x71, 0x87,
+ 0x4a, 0x68, 0x97, 0x7f, 0xd5, 0xda, 0xe5, 0x21, 0x1c, 0x09, 0xc0, 0x61,
+ 0xe4, 0xf3, 0x52, 0x3d, 0xb7, 0x50, 0x7f, 0xe7, 0xe7, 0x6c, 0xda, 0x84,
+ 0xec, 0x2a, 0x71, 0xdc, 0x94, 0xc1, 0xc4, 0x4d, 0xb5, 0x0c, 0x8e, 0x5b,
+ 0x3b, 0x0a, 0x65, 0xb4, 0xfc, 0x5c, 0x2a, 0x3b, 0x29, 0xf7, 0x18, 0x9f,
+ 0x7f, 0x20, 0x45, 0x5a, 0x7f, 0xb7, 0x64, 0xe6, 0xe2, 0xf3, 0x02, 0x7a,
+ 0x93, 0x54, 0x24, 0xad, 0xd7, 0xd3, 0xbc, 0x09, 0xd9, 0x21, 0xbd, 0x31,
+ 0xc6, 0x3a, 0x19, 0xcf, 0xf3, 0xf3, 0x13, 0xb0, 0x1f, 0x86, 0x4b, 0x0a,
+ 0x16, 0x7c, 0xad, 0x0c, 0x79, 0x81, 0x6c, 0x4f, 0x39, 0x3a, 0x76, 0x6c,
+ 0x74, 0x6d, 0xa9, 0xce, 0xd8, 0xae, 0x8e, 0x8e, 0xff, 0xce, 0x80, 0xfa,
+ 0x66, 0xb4, 0x7d, 0xab, 0xb4, 0xfe, 0x9d, 0xd6, 0x65, 0x46, 0xeb, 0xc2,
+ 0x38, 0xe6, 0x8c, 0x17, 0xb1, 0xe5, 0xaa, 0xd3, 0xa7, 0xea, 0x42, 0x5b,
+ 0xb0, 0x50, 0x09, 0xd3, 0x9e, 0x5c, 0x26, 0xed, 0x85, 0x65, 0xd2, 0xfe,
+ 0x76, 0x99, 0x34, 0x13, 0x17, 0xec, 0x2f, 0x5e, 0x46, 0xde, 0x88, 0xe6,
+ 0x55, 0x69, 0x36, 0xf6, 0x75, 0x7e, 0xae, 0xcc, 0x2a, 0xeb, 0x97, 0x31,
+ 0x46, 0x6c, 0x62, 0xc3, 0x39, 0x1d, 0x1b, 0xde, 0xe2, 0x6d, 0x53, 0x8c,
+ 0x75, 0x11, 0x17, 0x09, 0xd9, 0xab, 0xf1, 0x42, 0x9c, 0x7c, 0x85, 0x31,
+ 0xe0, 0x3c, 0xd7, 0x5a, 0x13, 0xea, 0x4a, 0xb4, 0x3d, 0x6f, 0x9b, 0x98,
+ 0x79, 0x8b, 0xe9, 0x75, 0xd5, 0x3e, 0xd8, 0x0a, 0xfd, 0xc5, 0x26, 0xd9,
+ 0x3e, 0x96, 0x58, 0x41, 0xbd, 0xb5, 0x63, 0xcc, 0xf8, 0x83, 0x7b, 0xc1,
+ 0x57, 0x19, 0x21, 0x8c, 0xc9, 0x94, 0x08, 0x6d, 0xe2, 0xa5, 0xb6, 0xf0,
+ 0xeb, 0xb7, 0xd7, 0x7b, 0x85, 0xf6, 0x1c, 0xd8, 0x0e, 0x3f, 0x6b, 0x7b,
+ 0xf5, 0xd2, 0x37, 0x16, 0xe2, 0x4a, 0xfd, 0x9c, 0xf5, 0x22, 0x57, 0xa8,
+ 0xa7, 0xed, 0x12, 0x79, 0x66, 0x4e, 0x16, 0x6f, 0x84, 0xcd, 0x24, 0x41,
+ 0xb6, 0x5b, 0x5a, 0x23, 0xa2, 0x63, 0x3c, 0x29, 0x23, 0x9b, 0x3b, 0xb8,
+ 0xb6, 0x03, 0xfa, 0x37, 0xb6, 0x8a, 0x89, 0x9b, 0x86, 0x76, 0xca, 0x72,
+ 0xb4, 0x7b, 0xbd, 0xa5, 0x5d, 0xae, 0xa9, 0xee, 0xa0, 0xcc, 0xc5, 0x9c,
+ 0x18, 0x3a, 0xde, 0x5e, 0x94, 0x44, 0x48, 0xc7, 0x33, 0xf0, 0x8b, 0xab,
+ 0xe9, 0x78, 0x46, 0x52, 0x9a, 0x8e, 0x6b, 0x17, 0xd0, 0x71, 0xab, 0xa5,
+ 0xe3, 0x77, 0x44, 0x0d, 0x5d, 0x28, 0xad, 0xa7, 0x48, 0xa7, 0x86, 0x8e,
+ 0x1d, 0x4d, 0xc7, 0x33, 0x78, 0xbb, 0x7e, 0x8f, 0x2d, 0x13, 0xb1, 0x69,
+ 0xfc, 0x1d, 0xa6, 0x51, 0x2e, 0xfe, 0x66, 0xd4, 0xe8, 0xa5, 0x14, 0xe8,
+ 0x28, 0x4c, 0xff, 0x60, 0xd4, 0xd0, 0x67, 0x75, 0x9a, 0x89, 0x8f, 0xf4,
+ 0x17, 0xdf, 0x13, 0x5d, 0x48, 0x9f, 0x29, 0xd0, 0x67, 0x58, 0xe6, 0xf5,
+ 0xe8, 0xb3, 0xde, 0xae, 0x5b, 0x44, 0xf5, 0xba, 0x7b, 0x26, 0x66, 0x68,
+ 0xf5, 0x56, 0x3d, 0x76, 0x8e, 0xfb, 0xd9, 0x9f, 0x81, 0x56, 0xcd, 0xdc,
+ 0x9c, 0x9f, 0xf7, 0xb7, 0x19, 0x8b, 0x4a, 0x98, 0x18, 0x36, 0xe3, 0xa4,
+ 0x57, 0xb2, 0x1d, 0x8d, 0x7c, 0xaa, 0xd1, 0xf2, 0xa9, 0x71, 0x48, 0xa5,
+ 0xab, 0x65, 0x76, 0x37, 0x74, 0x05, 0x6d, 0x6c, 0x2d, 0xa7, 0x91, 0xd7,
+ 0x9a, 0xc8, 0x16, 0xff, 0xd9, 0xee, 0x5f, 0xe0, 0xba, 0x80, 0x0c, 0x39,
+ 0x48, 0x6b, 0x2b, 0x9b, 0x71, 0x29, 0xbf, 0x11, 0xdf, 0xdd, 0xd2, 0x56,
+ 0x56, 0x72, 0xfb, 0x58, 0x83, 0xec, 0x2b, 0xba, 0xf2, 0x51, 0xd4, 0xff,
+ 0x48, 0xd1, 0x83, 0x3f, 0x3e, 0x1e, 0xa5, 0x5d, 0xb8, 0xb7, 0xc8, 0xf5,
+ 0x49, 0xc7, 0xac, 0x19, 0x2d, 0x58, 0xf3, 0x8c, 0x48, 0x5b, 0x47, 0x01,
+ 0x9e, 0x8a, 0xb8, 0x3b, 0x01, 0x47, 0x5d, 0x3a, 0x2d, 0xaf, 0x74, 0x0f,
+ 0x38, 0xda, 0x97, 0x70, 0x7a, 0xe4, 0xc6, 0x4a, 0x5a, 0x6e, 0xa8, 0x98,
+ 0x75, 0xd2, 0xf9, 0x75, 0xd0, 0xa4, 0x37, 0x0d, 0x9d, 0x93, 0xf1, 0x82,
+ 0xe0, 0x3c, 0xe4, 0xb7, 0x3a, 0xe2, 0x4a, 0xb4, 0x23, 0x19, 0x9f, 0x16,
+ 0xf3, 0x7d, 0xb1, 0xfc, 0xe3, 0x60, 0x28, 0xe6, 0xca, 0x2b, 0x3e, 0xc7,
+ 0xd5, 0x23, 0xd7, 0x97, 0xab, 0xfb, 0xe3, 0x5a, 0xe9, 0x13, 0x51, 0xae,
+ 0x4d, 0x64, 0x2b, 0xe5, 0x28, 0xe3, 0xe7, 0x22, 0x79, 0x69, 0x7b, 0x2b,
+ 0x7c, 0x37, 0x48, 0xeb, 0xb6, 0xb7, 0x82, 0x56, 0x62, 0xd0, 0xf3, 0x5b,
+ 0x01, 0xd7, 0x56, 0xc6, 0xbb, 0x18, 0xe7, 0xe2, 0xf7, 0x5f, 0xa2, 0x5f,
+ 0xd6, 0xfd, 0x5d, 0xbd, 0x66, 0x25, 0x8a, 0x73, 0x6e, 0xf8, 0x65, 0x79,
+ 0x5d, 0xd3, 0x38, 0x14, 0x4d, 0x8b, 0x13, 0x7d, 0x5b, 0x5c, 0x56, 0xf8,
+ 0xd5, 0xfd, 0x73, 0xed, 0x57, 0x14, 0x70, 0xe8, 0xee, 0xd8, 0xdc, 0x23,
+ 0x7d, 0x18, 0x5f, 0xff, 0x92, 0xf1, 0xed, 0x17, 0xc6, 0x54, 0x2f, 0x16,
+ 0x39, 0x86, 0xf9, 0x71, 0xa9, 0x3f, 0x32, 0xe3, 0x8a, 0x76, 0x2c, 0x1e,
+ 0x8f, 0xae, 0xaf, 0x4e, 0x01, 0x96, 0xe7, 0xf4, 0x1e, 0x81, 0x20, 0xb8,
+ 0xa6, 0xe3, 0x62, 0x90, 0x58, 0x97, 0xec, 0x9c, 0x9e, 0x5f, 0xd3, 0x19,
+ 0x8a, 0xa4, 0x33, 0x1a, 0xff, 0xf8, 0x4e, 0xe4, 0xca, 0xdd, 0x98, 0x3b,
+ 0x71, 0x73, 0x5d, 0xae, 0xe6, 0x8d, 0x9c, 0xdf, 0x6d, 0xd7, 0xad, 0x42,
+ 0xbf, 0x29, 0x08, 0x94, 0xbf, 0x58, 0x56, 0x50, 0x47, 0x61, 0xec, 0xb2,
+ 0xdb, 0xee, 0x4b, 0x49, 0x31, 0x6e, 0x38, 0xe4, 0xa6, 0xa3, 0x89, 0x42,
+ 0xb9, 0x0b, 0xbf, 0x1b, 0xf0, 0xfe, 0x45, 0xd8, 0x28, 0x3d, 0xb0, 0x61,
+ 0x24, 0xa6, 0x8c, 0x3c, 0x00, 0xfd, 0x76, 0xe4, 0x95, 0x22, 0x3f, 0x7a,
+ 0x89, 0xe1, 0x72, 0x2c, 0x31, 0x5a, 0xde, 0xcb, 0xfa, 0x28, 0x7b, 0xa5,
+ 0xf8, 0x1d, 0xfb, 0x62, 0x1f, 0xf4, 0x79, 0x7f, 0x96, 0x3e, 0x5c, 0xdb,
+ 0x36, 0xdb, 0x0c, 0xf1, 0xe2, 0xd2, 0x0d, 0xc7, 0xbf, 0x6e, 0xeb, 0x8f,
+ 0x70, 0x7c, 0x7b, 0x2d, 0xdc, 0x8b, 0xfb, 0x7d, 0x49, 0xdb, 0x2c, 0x8f,
+ 0x55, 0x68, 0x27, 0x72, 0x4d, 0x27, 0x79, 0x62, 0x5c, 0x08, 0x47, 0x10,
+ 0x5c, 0x48, 0x19, 0x7d, 0xfd, 0x74, 0x85, 0xeb, 0x1a, 0x41, 0xf0, 0x5d,
+ 0xda, 0xc2, 0x83, 0x25, 0xf4, 0x17, 0xe2, 0x60, 0x63, 0xde, 0x85, 0x2c,
+ 0x1c, 0xe9, 0x26, 0x7e, 0x05, 0x5e, 0x69, 0x87, 0xb7, 0x4b, 0xa2, 0x89,
+ 0xdf, 0x2e, 0x37, 0x24, 0x3e, 0x51, 0xf6, 0x80, 0x67, 0x8e, 0x3b, 0x96,
+ 0xd8, 0x63, 0xc7, 0xcc, 0xfd, 0x20, 0xaf, 0xbf, 0x4f, 0xe3, 0xa5, 0x05,
+ 0x3e, 0x12, 0x61, 0x9a, 0x87, 0x85, 0xb0, 0x25, 0x2c, 0x6e, 0x82, 0xe0,
+ 0xfb, 0x29, 0xf6, 0xd9, 0xcd, 0xfd, 0x00, 0x23, 0xe8, 0x37, 0xbf, 0x56,
+ 0x11, 0x0f, 0xd1, 0xc4, 0x1d, 0xe8, 0xfb, 0xb7, 0xd1, 0xf7, 0xbe, 0x32,
+ 0xfb, 0x83, 0x7c, 0xc0, 0xd8, 0x47, 0x2a, 0x21, 0xbc, 0xcb, 0xf5, 0x1d,
+ 0xce, 0x79, 0xa7, 0xb5, 0xeb, 0xc2, 0x6f, 0x8d, 0x48, 0x4f, 0xc1, 0x97,
+ 0xcb, 0x56, 0x66, 0xd6, 0xb8, 0xf2, 0x2e, 0xc8, 0xda, 0x40, 0x4e, 0x42,
+ 0x86, 0xcd, 0x68, 0xba, 0xc9, 0xae, 0xe7, 0xff, 0x11, 0xf9, 0xe4, 0x0a,
+ 0xc6, 0x94, 0x7b, 0x7d, 0xda, 0xab, 0xb3, 0xc1, 0x8c, 0x4f, 0x99, 0xbc,
+ 0x4a, 0xc6, 0xbd, 0x7c, 0x27, 0xf4, 0x03, 0xd2, 0x1a, 0xe9, 0x63, 0x27,
+ 0xb2, 0x91, 0x64, 0x62, 0x58, 0xb8, 0xc7, 0x89, 0xfb, 0x13, 0xb8, 0xef,
+ 0x87, 0xf2, 0xc0, 0x85, 0x9c, 0xe3, 0x1c, 0x9a, 0xfe, 0x86, 0xcb, 0xf3,
+ 0x65, 0x0f, 0x08, 0xd7, 0x09, 0x93, 0xf1, 0xbd, 0xda, 0x26, 0x01, 0xd5,
+ 0x15, 0x59, 0x76, 0x33, 0x2c, 0x12, 0xbf, 0xaa, 0xbc, 0xde, 0x73, 0x05,
+ 0x3e, 0x67, 0x1c, 0x21, 0x1a, 0xcd, 0x16, 0xe5, 0xb5, 0x48, 0xb7, 0xbc,
+ 0x96, 0x4d, 0xd5, 0x4b, 0xaf, 0x96, 0xf9, 0xcc, 0xd3, 0xe9, 0xb3, 0x26,
+ 0xdd, 0x85, 0x2e, 0xe1, 0x9c, 0xf4, 0x40, 0x46, 0x4f, 0x00, 0x6e, 0xe2,
+ 0xb0, 0x87, 0x32, 0x89, 0xf3, 0xa7, 0x54, 0x3a, 0x16, 0xcd, 0x95, 0xa5,
+ 0x2f, 0x57, 0xb4, 0xb1, 0x9e, 0x01, 0x8e, 0x7f, 0x95, 0xc5, 0x43, 0xa3,
+ 0xb8, 0x80, 0xad, 0x2f, 0x92, 0x70, 0xe0, 0x2b, 0x43, 0xd7, 0x3f, 0xba,
+ 0x4a, 0x1a, 0x89, 0x9b, 0x1e, 0xf0, 0x52, 0x0d, 0x74, 0xd1, 0xfd, 0xcd,
+ 0x5c, 0x37, 0xd5, 0x36, 0x64, 0xec, 0x63, 0xbf, 0xac, 0xd2, 0x7f, 0x1b,
+ 0x57, 0xe9, 0x51, 0x2b, 0x2f, 0xa3, 0x7d, 0x94, 0x97, 0x4f, 0x97, 0x08,
+ 0x8f, 0x78, 0x11, 0x3f, 0xd1, 0xd7, 0x5b, 0x16, 0x15, 0x49, 0x7b, 0xd1,
+ 0xde, 0xf2, 0x42, 0xfa, 0x7f, 0xba, 0xf2, 0x61, 0x6b, 0x0b, 0x56, 0xc7,
+ 0x54, 0xab, 0xf3, 0xc8, 0x83, 0xcb, 0xe5, 0x11, 0x26, 0x89, 0xae, 0x48,
+ 0x5f, 0xf8, 0x54, 0x7b, 0x47, 0xde, 0xab, 0x15, 0xe2, 0x39, 0x80, 0xdc,
+ 0x06, 0xae, 0xcb, 0x5c, 0xaf, 0xde, 0x8f, 0x79, 0xfb, 0x3f, 0x41, 0x26,
+ 0xc6, 0x7c, 0x4f, 0xea, 0xe0, 0xdb, 0xbe, 0x0c, 0xdd, 0xf9, 0x8a, 0x7f,
+ 0xe1, 0x53, 0x9d, 0x1d, 0x41, 0xf0, 0xac, 0x9f, 0x4f, 0xb8, 0x90, 0x1f,
+ 0x87, 0x2d, 0xbe, 0x87, 0x81, 0xef, 0x89, 0x39, 0x7c, 0x27, 0xe4, 0x62,
+ 0xd7, 0xf7, 0x03, 0xae, 0xf5, 0x0d, 0x97, 0x6f, 0xbd, 0x55, 0xa5, 0x3f,
+ 0xfe, 0xa1, 0x6c, 0x37, 0xfb, 0x1b, 0x91, 0xc3, 0x95, 0x9b, 0x88, 0xbf,
+ 0x28, 0xc6, 0x7a, 0x4f, 0x9f, 0x6f, 0xfa, 0xed, 0x5b, 0xd0, 0x2f, 0xe9,
+ 0xe5, 0x47, 0xac, 0x8b, 0x32, 0xd5, 0x75, 0x33, 0xa0, 0xcb, 0xbc, 0xad,
+ 0x3b, 0x70, 0x85, 0xba, 0xde, 0x15, 0xea, 0x1e, 0x46, 0xdd, 0x3d, 0xb6,
+ 0xee, 0x85, 0xcf, 0xbc, 0xb9, 0x7e, 0x07, 0xb8, 0xc7, 0x0e, 0x3e, 0x80,
+ 0xb8, 0x11, 0xff, 0x36, 0xfc, 0xbe, 0x85, 0xed, 0x28, 0xda, 0xf7, 0x23,
+ 0x95, 0x21, 0x19, 0xae, 0xec, 0xc4, 0x33, 0x88, 0xb4, 0x3e, 0x3c, 0xfb,
+ 0xf0, 0x3b, 0x8d, 0x47, 0xa2, 0x6e, 0xfa, 0xc2, 0x5d, 0xc3, 0x7e, 0x88,
+ 0x57, 0xae, 0xcd, 0xb3, 0x0f, 0xd8, 0x17, 0x5d, 0x3f, 0x41, 0x1f, 0x61,
+ 0xfa, 0x07, 0x50, 0x67, 0x1a, 0x69, 0x2b, 0x69, 0x7b, 0x62, 0xae, 0xab,
+ 0xeb, 0x54, 0xc3, 0x36, 0x1d, 0xce, 0x05, 0xf2, 0x0d, 0x8d, 0xf6, 0x16,
+ 0x43, 0x18, 0xef, 0x44, 0x1b, 0xe3, 0x57, 0x29, 0xff, 0x1e, 0xc2, 0x15,
+ 0x57, 0xfe, 0xc7, 0xf0, 0x7e, 0x2d, 0xd8, 0x9d, 0x62, 0x4c, 0x9e, 0xf3,
+ 0x7e, 0xdd, 0xaa, 0xa5, 0x7b, 0x9f, 0x42, 0x1a, 0xe8, 0x84, 0x4e, 0x69,
+ 0xb0, 0x74, 0x5a, 0x80, 0xe5, 0x43, 0x1a, 0xe5, 0x98, 0x17, 0x97, 0x4d,
+ 0x76, 0xe6, 0xa5, 0x07, 0xba, 0x8c, 0xb2, 0xf6, 0xd3, 0xf5, 0x26, 0x0e,
+ 0x03, 0xcb, 0xd1, 0xef, 0x04, 0x3d, 0x37, 0x88, 0x87, 0xfa, 0x03, 0x11,
+ 0x0f, 0x34, 0x18, 0xd6, 0x4f, 0x7a, 0x03, 0x11, 0x8e, 0x19, 0x1c, 0x5f,
+ 0xe6, 0xba, 0x34, 0x6d, 0x6b, 0xd6, 0x0f, 0x6d, 0x1c, 0xfe, 0x7b, 0x59,
+ 0xc4, 0x67, 0x1a, 0xdb, 0x0b, 0xde, 0x55, 0xe3, 0x2f, 0x59, 0x63, 0xc1,
+ 0x38, 0xf3, 0x49, 0x68, 0x30, 0xaf, 0x4f, 0xcb, 0xe9, 0xfc, 0x35, 0x35,
+ 0xd2, 0xe0, 0xf5, 0xeb, 0xdf, 0x2c, 0xd3, 0xe0, 0x81, 0x4f, 0x17, 0x95,
+ 0x61, 0x1a, 0xf3, 0x0a, 0x6b, 0x94, 0xde, 0xab, 0xa4, 0xf7, 0x28, 0xc9,
+ 0x83, 0xa9, 0x64, 0x62, 0x48, 0x25, 0xbd, 0x71, 0xd9, 0x0f, 0xb9, 0x43,
+ 0x39, 0x39, 0x73, 0x7f, 0x44, 0xb8, 0x9f, 0xef, 0x5d, 0x92, 0xf5, 0x29,
+ 0x3f, 0x0b, 0x9f, 0x57, 0x94, 0x75, 0x95, 0x97, 0x1a, 0xcc, 0xd8, 0xb8,
+ 0x0f, 0x01, 0x70, 0x36, 0xd1, 0x86, 0xbb, 0xb5, 0x81, 0x3c, 0x94, 0x50,
+ 0x11, 0xd9, 0x45, 0x3f, 0x5f, 0x7d, 0xb1, 0x5e, 0xea, 0xa7, 0xd7, 0x78,
+ 0x52, 0xd1, 0xe9, 0x66, 0x7f, 0x60, 0xb2, 0x73, 0x48, 0x89, 0x1e, 0x7b,
+ 0x46, 0xbd, 0x91, 0xcc, 0x9e, 0xb5, 0xfa, 0x23, 0x90, 0xc7, 0xb4, 0xbe,
+ 0x98, 0xf9, 0xbc, 0x2b, 0x17, 0x82, 0xb6, 0x4d, 0x17, 0xda, 0xb3, 0x5d,
+ 0xb4, 0x73, 0x57, 0xd9, 0xfd, 0x95, 0x8c, 0x63, 0xbd, 0x4b, 0x9e, 0xf3,
+ 0x0b, 0x18, 0xf7, 0x7e, 0xb9, 0xe0, 0xb3, 0xbf, 0x99, 0xcf, 0x79, 0xc2,
+ 0x74, 0xc2, 0x6e, 0xfa, 0x13, 0xf5, 0xa7, 0x80, 0x87, 0x7d, 0x52, 0x07,
+ 0x5f, 0xc9, 0xee, 0x4b, 0x0e, 0xe4, 0x45, 0xcf, 0x4b, 0x8f, 0xa0, 0xad,
+ 0x15, 0x3e, 0xf8, 0x10, 0x76, 0x73, 0xcd, 0x91, 0xab, 0x21, 0x77, 0x1d,
+ 0xbd, 0xc7, 0x02, 0x93, 0xe1, 0x4d, 0x61, 0xde, 0x33, 0x03, 0x2c, 0x57,
+ 0x2f, 0xd3, 0x31, 0xf2, 0xba, 0xe6, 0x97, 0x4f, 0x65, 0xfd, 0x76, 0x4f,
+ 0x39, 0xc3, 0x8c, 0x31, 0x00, 0xaf, 0xa4, 0xcd, 0x54, 0x6c, 0xbb, 0xcf,
+ 0xb6, 0x58, 0xe6, 0x2a, 0xf9, 0xf6, 0xc0, 0x85, 0x7f, 0x78, 0xd6, 0xff,
+ 0x7b, 0xc0, 0x91, 0x81, 0x4c, 0xe0, 0xf3, 0x6a, 0x90, 0x8f, 0x31, 0xa6,
+ 0xf5, 0xbf, 0xeb, 0xad, 0x9d, 0xac, 0x79, 0x7f, 0x58, 0xef, 0x93, 0x79,
+ 0xfe, 0x33, 0x59, 0xae, 0x77, 0xc0, 0x36, 0xc9, 0x69, 0xb9, 0x18, 0xfd,
+ 0x69, 0x0e, 0xf0, 0x14, 0x2a, 0xb4, 0x43, 0xfe, 0x06, 0x76, 0x88, 0xd6,
+ 0x93, 0xf2, 0xed, 0x41, 0xe6, 0xb1, 0xdd, 0xec, 0xd5, 0xae, 0xd6, 0x0b,
+ 0x21, 0x2c, 0xc9, 0xce, 0x1c, 0xf2, 0x47, 0xb4, 0x1d, 0xef, 0xc9, 0xac,
+ 0xe7, 0xea, 0x7d, 0x27, 0xf9, 0xc1, 0x20, 0x78, 0xc5, 0x77, 0xe5, 0xa4,
+ 0x86, 0xf9, 0x05, 0xf4, 0xe1, 0xc8, 0xc4, 0x80, 0xfb, 0xd3, 0x93, 0x3e,
+ 0xc7, 0xc7, 0x3c, 0xae, 0x2b, 0x6d, 0x8e, 0x1b, 0xf8, 0x68, 0x9b, 0x7e,
+ 0x2f, 0x98, 0x8d, 0x71, 0xdd, 0x02, 0x3c, 0x5d, 0x6a, 0xf7, 0x6e, 0x90,
+ 0xdb, 0xe6, 0x6c, 0x9a, 0x69, 0x31, 0x36, 0xa3, 0xd1, 0x69, 0x17, 0xfe,
+ 0x61, 0xc4, 0xbf, 0xb0, 0xba, 0x80, 0xb9, 0x81, 0x0e, 0x5b, 0x0c, 0x4b,
+ 0x8a, 0xb0, 0x0c, 0x6b, 0x58, 0x62, 0xc0, 0xa5, 0x0b, 0xd9, 0x77, 0x9b,
+ 0x1c, 0x02, 0xde, 0x87, 0x06, 0x45, 0x9e, 0x85, 0x4d, 0x76, 0xbe, 0x0a,
+ 0x9e, 0x19, 0xc0, 0x73, 0xde, 0xe7, 0x5e, 0x00, 0xe6, 0xf9, 0xde, 0xb0,
+ 0x70, 0x2f, 0x00, 0x71, 0xd8, 0x81, 0xdf, 0x22, 0x33, 0xd0, 0xbf, 0x27,
+ 0xfd, 0xd7, 0x82, 0xf1, 0x18, 0x75, 0x23, 0xda, 0x99, 0xdb, 0x1b, 0x14,
+ 0xc8, 0xe7, 0x53, 0xd4, 0x43, 0xb5, 0xd2, 0xb6, 0x8e, 0x7e, 0x88, 0x91,
+ 0x9f, 0x37, 0xf8, 0x19, 0xf4, 0xf5, 0x5b, 0x2b, 0xa5, 0x3e, 0x2f, 0xfd,
+ 0x1d, 0x75, 0xc8, 0x73, 0x6d, 0xde, 0x80, 0xce, 0xeb, 0xef, 0x38, 0x8c,
+ 0xfc, 0x8f, 0xaf, 0x64, 0xbc, 0xdb, 0xf5, 0xd7, 0x4b, 0xdb, 0x1a, 0xe6,
+ 0x55, 0xf3, 0xe0, 0xab, 0xdc, 0x83, 0x69, 0x75, 0x38, 0x64, 0x59, 0x29,
+ 0xef, 0x71, 0xa7, 0xdd, 0x21, 0xcc, 0xc5, 0x6e, 0x9f, 0xb2, 0xed, 0xbf,
+ 0xa3, 0x6e, 0x4a, 0x6e, 0xf4, 0x07, 0x91, 0x37, 0x8d, 0xbc, 0xc3, 0x36,
+ 0x6f, 0xd0, 0xe6, 0x6d, 0x43, 0xde, 0x3e, 0xe0, 0xef, 0x6e, 0x9d, 0x9e,
+ 0xe5, 0x6f, 0x53, 0xc7, 0x5b, 0xd9, 0x71, 0xe1, 0x33, 0x37, 0xf8, 0x84,
+ 0x0b, 0x79, 0x25, 0xae, 0x8b, 0xde, 0x26, 0x79, 0x2f, 0x79, 0x0b, 0x7b,
+ 0xfd, 0x66, 0xb1, 0x0e, 0xb2, 0x89, 0x7b, 0x80, 0x69, 0xb3, 0x6e, 0xf1,
+ 0x5e, 0x96, 0xff, 0x40, 0xba, 0xeb, 0xc9, 0x38, 0x5f, 0x5b, 0xc9, 0xb8,
+ 0xd8, 0x88, 0x4f, 0xfb, 0x3a, 0x90, 0x9c, 0x5e, 0x3f, 0xa1, 0x7f, 0x5b,
+ 0x44, 0x3a, 0xe9, 0x41, 0x35, 0x45, 0xf4, 0x3e, 0x2d, 0x7e, 0x47, 0x61,
+ 0xf7, 0x06, 0x42, 0x9f, 0x8f, 0x36, 0x5d, 0xc6, 0xe3, 0xda, 0x50, 0x98,
+ 0xe7, 0x21, 0x4f, 0x6d, 0x8a, 0xc0, 0x26, 0xaa, 0xf5, 0x1d, 0x1d, 0xa3,
+ 0x2e, 0xe8, 0x75, 0x00, 0xc6, 0xdf, 0x32, 0xf0, 0x63, 0x02, 0xe9, 0x47,
+ 0xdf, 0xa4, 0xfd, 0x68, 0x87, 0xef, 0x1d, 0x10, 0xee, 0x67, 0x65, 0x7a,
+ 0xbb, 0xf7, 0x6d, 0x99, 0xa7, 0xf3, 0x19, 0x49, 0x66, 0x94, 0x03, 0xff,
+ 0x75, 0xab, 0x23, 0xf5, 0xb0, 0x3d, 0x6e, 0x30, 0xfa, 0xcd, 0xe3, 0x9e,
+ 0xc4, 0x8b, 0xda, 0x56, 0x6b, 0xb4, 0xf3, 0x91, 0x05, 0x6e, 0xb8, 0x1f,
+ 0x7c, 0xe0, 0x9e, 0xdd, 0x7e, 0x21, 0x09, 0x6a, 0xd4, 0xba, 0x71, 0x18,
+ 0xb4, 0x91, 0x4d, 0x19, 0xdd, 0x78, 0xc3, 0x9c, 0x6e, 0xfc, 0xf3, 0x95,
+ 0xe4, 0x89, 0xe1, 0x72, 0x1c, 0x75, 0xf5, 0x3a, 0x4a, 0x82, 0x75, 0x6b,
+ 0x31, 0x9f, 0xe7, 0xfd, 0xec, 0x35, 0xa0, 0x2f, 0xc8, 0xe1, 0x64, 0xe7,
+ 0x29, 0xd4, 0x2d, 0xa0, 0xee, 0xe4, 0x5c, 0x5d, 0x47, 0x46, 0x7c, 0xbd,
+ 0xef, 0x59, 0x26, 0xcb, 0x21, 0x1d, 0x26, 0xe3, 0xb7, 0x6a, 0x5e, 0xe0,
+ 0x7e, 0x30, 0x37, 0x71, 0x9f, 0x6c, 0xd6, 0xb4, 0xdd, 0x27, 0xdc, 0x27,
+ 0xc5, 0xb6, 0xef, 0x0b, 0xda, 0xd6, 0x10, 0xbe, 0x12, 0xde, 0xa4, 0x8d,
+ 0x31, 0xbc, 0xc3, 0xf9, 0x37, 0xf3, 0x3e, 0xe4, 0x10, 0xdf, 0xbf, 0x1f,
+ 0xe4, 0x07, 0x39, 0x2f, 0xfc, 0x9e, 0xa7, 0xb9, 0x11, 0xd0, 0x5c, 0xc4,
+ 0x7f, 0xbb, 0x0c, 0xeb, 0x3d, 0x10, 0x29, 0x99, 0xd0, 0xf1, 0xcc, 0x0b,
+ 0xc1, 0x23, 0x0b, 0xe4, 0xf8, 0x47, 0x94, 0xa1, 0x21, 0xfe, 0x2e, 0x24,
+ 0xea, 0x64, 0x66, 0x4d, 0x9d, 0xde, 0xf1, 0x41, 0x7c, 0x8c, 0xde, 0x73,
+ 0x3b, 0xf8, 0xf5, 0xfa, 0xb9, 0xb1, 0x00, 0xdf, 0xc0, 0xe3, 0x4e, 0x63,
+ 0xeb, 0x63, 0x1c, 0x19, 0xed, 0xbf, 0x67, 0x8b, 0x4a, 0xef, 0x0b, 0xa2,
+ 0x8e, 0x3f, 0x00, 0x9d, 0x6a, 0xf6, 0xa4, 0xe0, 0x5d, 0xe1, 0xbc, 0x29,
+ 0xed, 0x73, 0x1c, 0x04, 0x0f, 0x1f, 0xf4, 0xb3, 0x6b, 0x6a, 0x75, 0xdb,
+ 0x49, 0xef, 0x7a, 0x6d, 0x13, 0x6e, 0x94, 0x99, 0x14, 0xdb, 0x23, 0x5e,
+ 0xfe, 0x47, 0x30, 0xe4, 0xcd, 0xa0, 0x7f, 0x43, 0xff, 0x59, 0x5f, 0xb5,
+ 0xd4, 0x49, 0xf5, 0x3e, 0x53, 0xe2, 0xc9, 0x85, 0xbd, 0xd2, 0x01, 0xfc,
+ 0x18, 0x78, 0x73, 0xe5, 0xb7, 0x49, 0x21, 0xe6, 0xda, 0xb1, 0x45, 0xb4,
+ 0x2f, 0x37, 0x91, 0xaa, 0x83, 0x2d, 0xf8, 0x17, 0xc1, 0xe4, 0x82, 0x31,
+ 0x1e, 0xac, 0x1a, 0xe3, 0x4c, 0x02, 0xd8, 0x68, 0x89, 0xcc, 0xc9, 0x01,
+ 0xf6, 0x65, 0x64, 0x52, 0x38, 0xc6, 0x3a, 0x8c, 0x71, 0xc7, 0xdc, 0x18,
+ 0x0f, 0x2f, 0x1a, 0xe3, 0x61, 0x8c, 0x11, 0xf6, 0x42, 0x29, 0xd3, 0xe9,
+ 0xce, 0xcf, 0xfb, 0xd5, 0x35, 0x73, 0xf3, 0x29, 0xdc, 0xeb, 0x84, 0xf1,
+ 0xd3, 0xa6, 0xd8, 0x08, 0x78, 0x74, 0x5b, 0x90, 0x71, 0x0e, 0x64, 0x5b,
+ 0x76, 0x4d, 0x8d, 0x1d, 0xff, 0x76, 0x96, 0x2b, 0x1b, 0x1c, 0x9c, 0x4c,
+ 0xb9, 0x9d, 0x8f, 0xa0, 0xbf, 0xbd, 0x76, 0x5c, 0xbd, 0xe5, 0xab, 0x31,
+ 0xae, 0x0b, 0xdf, 0xc1, 0x18, 0xe0, 0xb3, 0x9d, 0xa0, 0x0f, 0x9c, 0x18,
+ 0x92, 0x05, 0xb2, 0xeb, 0x33, 0xf3, 0x72, 0xd4, 0xc0, 0x4c, 0xdb, 0xba,
+ 0x30, 0x07, 0xf3, 0xdd, 0x8b, 0x60, 0xbe, 0x1b, 0x30, 0xef, 0xb3, 0xf3,
+ 0xb2, 0xaf, 0x6a, 0xcf, 0x62, 0x48, 0x47, 0xfc, 0xfd, 0xbc, 0xf5, 0x45,
+ 0x3e, 0x20, 0xf7, 0x97, 0x3a, 0xe5, 0xcb, 0x95, 0xe4, 0x59, 0xc6, 0xd1,
+ 0xcf, 0x55, 0x92, 0xe3, 0x22, 0x5d, 0xf2, 0xc7, 0xb0, 0x73, 0xae, 0x82,
+ 0x6f, 0xf1, 0x34, 0xfc, 0xd7, 0x3f, 0xa9, 0xf8, 0xf2, 0xc4, 0xdc, 0x7e,
+ 0x38, 0xea, 0xba, 0xb4, 0x9c, 0x84, 0x4f, 0xbb, 0xed, 0x68, 0x1b, 0xf7,
+ 0x2a, 0x11, 0xbe, 0xbb, 0xa8, 0x73, 0xda, 0x94, 0xe6, 0xc5, 0xef, 0x62,
+ 0xbc, 0xa7, 0xa9, 0x6b, 0xd6, 0xfa, 0xbe, 0x77, 0xb3, 0x5a, 0x47, 0x99,
+ 0x90, 0xff, 0x5a, 0xe4, 0x03, 0xf5, 0x26, 0xc6, 0x92, 0xf1, 0x9a, 0xc9,
+ 0x1b, 0xdb, 0x3a, 0x12, 0x7d, 0x42, 0x5b, 0x82, 0xfe, 0x36, 0x6c, 0xa1,
+ 0xd2, 0xe6, 0xf8, 0x5a, 0xa1, 0x4c, 0xa2, 0x5d, 0x94, 0x96, 0x09, 0xc0,
+ 0x3e, 0x06, 0x89, 0x50, 0x68, 0xf6, 0x47, 0x7b, 0xd5, 0x44, 0x03, 0x79,
+ 0x70, 0xdb, 0x19, 0xd0, 0xd7, 0x36, 0x8c, 0xa9, 0x2b, 0x79, 0x76, 0x46,
+ 0x65, 0x4e, 0xac, 0x95, 0x57, 0x82, 0xa1, 0x66, 0x47, 0x9e, 0xd8, 0xc4,
+ 0x3c, 0x2d, 0xb7, 0x3f, 0xd5, 0x0b, 0xf9, 0xd4, 0xce, 0x73, 0x0b, 0x03,
+ 0xf2, 0x2f, 0x77, 0x80, 0x06, 0x7f, 0xb8, 0xe9, 0x6b, 0xc1, 0x6c, 0xb3,
+ 0x2b, 0x5b, 0x37, 0x25, 0xbd, 0xbc, 0xc2, 0x78, 0x4a, 0x18, 0x4f, 0x09,
+ 0xe3, 0xe3, 0x98, 0x4b, 0x18, 0xd7, 0x15, 0xf7, 0x4a, 0xf5, 0x2c, 0x88,
+ 0xcb, 0x1a, 0x3f, 0x2d, 0x93, 0x77, 0x65, 0x83, 0xdd, 0x2b, 0x35, 0x5c,
+ 0x1f, 0xae, 0xb1, 0x65, 0x64, 0x3c, 0x28, 0xf8, 0x7f, 0x70, 0x55, 0xb6,
+ 0x2b, 0xb6, 0x58, 0xe7, 0xdc, 0x35, 0xaf, 0x73, 0x44, 0x9e, 0x33, 0xf3,
+ 0x86, 0x39, 0xf3, 0xbd, 0x49, 0x6e, 0x86, 0x87, 0x0e, 0xdc, 0xaa, 0xf7,
+ 0x3c, 0x77, 0xe0, 0x9b, 0x36, 0xd5, 0xa7, 0xf5, 0x3a, 0xe2, 0x4c, 0xf9,
+ 0x1e, 0x3b, 0x77, 0xf7, 0x68, 0x3d, 0xbb, 0x75, 0xd3, 0xa5, 0x80, 0xfb,
+ 0xdc, 0xbc, 0x4d, 0xcb, 0xc5, 0x22, 0x68, 0xef, 0xd5, 0x69, 0xde, 0xe7,
+ 0x7a, 0x76, 0x41, 0x9f, 0x13, 0x01, 0xde, 0xe6, 0xe2, 0x62, 0xf5, 0x48,
+ 0xa3, 0xbe, 0xf8, 0x69, 0x83, 0x59, 0x47, 0xa5, 0x6c, 0x58, 0x83, 0x34,
+ 0xd7, 0xec, 0x05, 0x5e, 0x90, 0xf7, 0xdf, 0xea, 0xcd, 0x9e, 0x8f, 0xea,
+ 0xb2, 0xe0, 0x31, 0xbd, 0x2f, 0x84, 0xfb, 0x03, 0x7f, 0x79, 0xa5, 0xb1,
+ 0x4d, 0xc3, 0x7c, 0xa6, 0xff, 0x38, 0x98, 0xd0, 0x31, 0x36, 0xf6, 0xf5,
+ 0x43, 0xfc, 0x5e, 0xbc, 0x5f, 0x24, 0xb4, 0x5d, 0xeb, 0x40, 0xf7, 0xda,
+ 0x5f, 0x16, 0x94, 0x89, 0xe7, 0x25, 0x22, 0x13, 0x55, 0x30, 0x4e, 0x10,
+ 0xee, 0x52, 0xd7, 0xaa, 0xf9, 0xd8, 0xdd, 0x6a, 0xa4, 0x11, 0xc6, 0x75,
+ 0x8b, 0xf2, 0xc8, 0x1b, 0xad, 0x2b, 0x49, 0x37, 0xd3, 0xc2, 0xb4, 0xf9,
+ 0x31, 0xcd, 0x68, 0xfb, 0xb9, 0x6d, 0x95, 0xde, 0xfb, 0xc4, 0x35, 0x46,
+ 0xc6, 0x08, 0x63, 0x26, 0xdf, 0xf5, 0xff, 0x56, 0xd7, 0x19, 0x9a, 0xab,
+ 0xa3, 0xe7, 0x02, 0xf9, 0x6e, 0x55, 0x5e, 0x35, 0xdc, 0xd4, 0x5f, 0x43,
+ 0x9d, 0x75, 0xd0, 0x89, 0x17, 0x53, 0xab, 0xc3, 0xbd, 0xf0, 0xb0, 0x21,
+ 0xb2, 0xd7, 0xd4, 0x5a, 0x99, 0x3f, 0x81, 0x79, 0x7d, 0x26, 0x65, 0x78,
+ 0x51, 0xf3, 0x61, 0xf1, 0x36, 0xf8, 0xeb, 0xa1, 0xde, 0xa0, 0x9c, 0x26,
+ 0x6f, 0x22, 0xad, 0x42, 0x9f, 0xe0, 0xc2, 0xea, 0x99, 0xae, 0x57, 0x03,
+ 0xee, 0xb3, 0x7c, 0x45, 0xdb, 0x51, 0x43, 0xb2, 0xb0, 0xed, 0xd1, 0x7b,
+ 0x5e, 0xbf, 0xed, 0xa1, 0x65, 0xda, 0x1e, 0xb2, 0x6d, 0x8b, 0x6b, 0xda,
+ 0x8e, 0x5e, 0xa1, 0xed, 0x81, 0x37, 0x68, 0x7b, 0x70, 0x99, 0xb6, 0x07,
+ 0xc3, 0xb6, 0x95, 0x69, 0xdb, 0x0b, 0xdb, 0x4e, 0x2c, 0xc2, 0xc9, 0x67,
+ 0x5e, 0xbf, 0xed, 0x7d, 0xcb, 0xb4, 0xbd, 0x6f, 0x11, 0xdc, 0xc4, 0x49,
+ 0x2d, 0x74, 0xff, 0x3d, 0xda, 0xe6, 0xac, 0x03, 0xdf, 0x5c, 0x84, 0xfc,
+ 0x36, 0xfe, 0xc8, 0x85, 0xbb, 0x66, 0xcb, 0xe0, 0x2b, 0xf8, 0xd7, 0x99,
+ 0x72, 0x03, 0x9e, 0x71, 0xd8, 0x33, 0x28, 0x07, 0x7b, 0xbc, 0x26, 0x1d,
+ 0xc8, 0xc9, 0x6e, 0x96, 0xcd, 0xc7, 0x6b, 0xe7, 0xf4, 0xc6, 0x3d, 0xe8,
+ 0x8f, 0x6d, 0xfb, 0x5e, 0xbf, 0xbc, 0xa6, 0xfb, 0xcb, 0x95, 0xe9, 0x8f,
+ 0x21, 0xbd, 0x42, 0x1f, 0x97, 0xf5, 0x42, 0x19, 0x58, 0x67, 0xd7, 0x3e,
+ 0x68, 0x6b, 0x32, 0x0e, 0xa7, 0xed, 0x51, 0x29, 0x94, 0x7f, 0x12, 0x4c,
+ 0x83, 0x2e, 0x46, 0xe6, 0x74, 0xc8, 0x93, 0xab, 0x68, 0xb3, 0x8f, 0x53,
+ 0xb3, 0x54, 0xc5, 0xa0, 0x46, 0x7c, 0xa6, 0xfd, 0x98, 0x6d, 0xc2, 0x0e,
+ 0x0c, 0xcb, 0x32, 0x6e, 0x6c, 0x62, 0x4e, 0x67, 0x21, 0x33, 0xcd, 0x9e,
+ 0x0e, 0xfa, 0x2a, 0x4f, 0x81, 0x97, 0xf7, 0x43, 0x76, 0x24, 0xf3, 0x22,
+ 0x3d, 0x8d, 0xe6, 0xac, 0x45, 0x4c, 0x72, 0x5d, 0xbf, 0x69, 0xf1, 0xb8,
+ 0xef, 0xce, 0xe5, 0xcf, 0x59, 0x40, 0x3e, 0x38, 0x94, 0x91, 0xd7, 0x37,
+ 0x9a, 0x75, 0xbb, 0xb7, 0x36, 0x32, 0x1e, 0xa3, 0x36, 0x75, 0xaf, 0xd6,
+ 0xf2, 0xc7, 0x09, 0xbf, 0xbf, 0xb2, 0xe8, 0x3b, 0xac, 0xf7, 0x93, 0xd5,
+ 0x0b, 0xeb, 0x85, 0xe9, 0x70, 0x4d, 0x16, 0xa4, 0x1f, 0x58, 0xb3, 0xb0,
+ 0x7e, 0xac, 0x69, 0xe1, 0xf7, 0xe0, 0xa2, 0xef, 0xcf, 0x2c, 0xfa, 0x7e,
+ 0x61, 0xd1, 0xf7, 0x75, 0x6b, 0x17, 0x95, 0x5f, 0xf4, 0xfd, 0xe5, 0xb5,
+ 0xcb, 0xc3, 0xfb, 0x57, 0x6b, 0x17, 0xc2, 0xf5, 0x94, 0x5e, 0x73, 0x1d,
+ 0xaf, 0xb8, 0xb2, 0xbd, 0x88, 0x7c, 0xe7, 0xd6, 0x18, 0xf2, 0xe1, 0xcb,
+ 0x54, 0xe7, 0x73, 0x8d, 0xe3, 0x1d, 0xb1, 0x85, 0xed, 0xcd, 0xd7, 0xdb,
+ 0x31, 0x5f, 0x2f, 0x35, 0x5f, 0xcf, 0xf8, 0x23, 0x13, 0x15, 0xe6, 0x31,
+ 0x3d, 0x6c, 0xd7, 0xd4, 0x1d, 0x29, 0x79, 0xfa, 0x3c, 0xc2, 0x80, 0x3e,
+ 0x8f, 0x90, 0x80, 0x6f, 0xf4, 0x94, 0x8e, 0xeb, 0xaf, 0x51, 0x48, 0xaf,
+ 0x34, 0xea, 0xd8, 0xbe, 0xe8, 0x33, 0x09, 0x03, 0xb0, 0xb9, 0x78, 0x0e,
+ 0x21, 0x90, 0x9d, 0x29, 0xf3, 0x36, 0xe7, 0x12, 0x0e, 0x07, 0xbd, 0x5e,
+ 0x10, 0x0c, 0xfb, 0x67, 0xad, 0x2c, 0xc7, 0xbb, 0x62, 0xea, 0xd0, 0xd7,
+ 0x7c, 0x14, 0xfa, 0x66, 0xde, 0xc7, 0x7c, 0x8a, 0xf6, 0x3a, 0x68, 0xa6,
+ 0x1b, 0x7a, 0x37, 0xf9, 0xa4, 0x68, 0xdd, 0xd1, 0x05, 0x9d, 0xeb, 0xdd,
+ 0xfb, 0x3e, 0xd8, 0x3a, 0x5f, 0x06, 0xad, 0x1f, 0x4b, 0xf5, 0x68, 0xff,
+ 0xff, 0x1c, 0x74, 0x31, 0xe3, 0x84, 0x8f, 0x69, 0xda, 0x22, 0x8d, 0x35,
+ 0xe8, 0xb3, 0x50, 0x27, 0x53, 0x4e, 0x34, 0xdb, 0x75, 0xde, 0xc4, 0xcd,
+ 0x53, 0xed, 0xde, 0x73, 0xe0, 0xb5, 0x7e, 0x7f, 0x03, 0x6c, 0x66, 0xd1,
+ 0x3a, 0xbf, 0x50, 0x5a, 0x6f, 0x6d, 0x83, 0x66, 0x19, 0x77, 0xb9, 0x56,
+ 0x93, 0xec, 0x19, 0x32, 0x3e, 0x66, 0x3c, 0xa1, 0x18, 0x23, 0xe6, 0xfa,
+ 0x05, 0xcf, 0x39, 0x70, 0x9d, 0x9b, 0xf1, 0x90, 0xf1, 0x7b, 0x47, 0xfc,
+ 0xbc, 0x17, 0xb1, 0x67, 0x23, 0xb2, 0x45, 0x43, 0x9b, 0x7b, 0xb4, 0xad,
+ 0x1a, 0x05, 0x3f, 0x7d, 0x0f, 0x74, 0xcf, 0xba, 0xa4, 0xfd, 0xef, 0x04,
+ 0x93, 0xae, 0x89, 0x4f, 0x29, 0xd4, 0xcb, 0x6a, 0x5c, 0x3d, 0x25, 0x07,
+ 0x4a, 0xe4, 0xff, 0xa8, 0x96, 0xe5, 0xbb, 0x53, 0x94, 0x07, 0x51, 0xe0,
+ 0x71, 0x0a, 0xf8, 0x6b, 0x90, 0xdd, 0x5d, 0x45, 0x94, 0x89, 0xc8, 0xd0,
+ 0x40, 0x03, 0x78, 0x8f, 0x76, 0x09, 0xdf, 0x2e, 0xca, 0x7b, 0x32, 0x55,
+ 0x1c, 0xd7, 0x7b, 0x9e, 0x1f, 0x43, 0xdd, 0xc7, 0xf1, 0x4c, 0x14, 0xcb,
+ 0xa8, 0xf3, 0xb0, 0x2e, 0x3f, 0x31, 0xca, 0x73, 0x22, 0x02, 0x7b, 0xff,
+ 0x49, 0x29, 0x4c, 0xb6, 0xc1, 0x2f, 0x99, 0x1e, 0x77, 0xe7, 0xe2, 0xe4,
+ 0xff, 0xa5, 0x91, 0xeb, 0xcc, 0x85, 0xeb, 0xb8, 0x27, 0x47, 0xdc, 0x81,
+ 0xcd, 0xaa, 0xb3, 0x49, 0xaf, 0xf9, 0xf4, 0x48, 0x3f, 0x6c, 0x8a, 0x9b,
+ 0x2b, 0xcf, 0xc4, 0xcc, 0xda, 0xc0, 0x82, 0xf5, 0x86, 0xc3, 0xc4, 0x8a,
+ 0x3a, 0xea, 0xf2, 0xdc, 0xa7, 0x4c, 0x9c, 0x81, 0xf6, 0x39, 0x1a, 0xae,
+ 0xe7, 0x30, 0xcd, 0x93, 0xb6, 0xeb, 0x00, 0xd7, 0x99, 0x7f, 0xd2, 0xf2,
+ 0xf5, 0x89, 0x4d, 0x61, 0x5f, 0xf9, 0x60, 0x6c, 0x53, 0x5e, 0x3e, 0x81,
+ 0x27, 0x77, 0x5d, 0x72, 0x34, 0xab, 0xd8, 0xef, 0x37, 0x02, 0xc6, 0x02,
+ 0x54, 0xba, 0x55, 0xf2, 0x4d, 0xd5, 0xfd, 0x33, 0xad, 0xc3, 0x2b, 0xa8,
+ 0xd7, 0x83, 0x63, 0x26, 0x11, 0x03, 0x0e, 0xf2, 0x6f, 0x08, 0xcf, 0x16,
+ 0xcf, 0x57, 0xcb, 0xc1, 0x73, 0xc2, 0xae, 0xd7, 0x70, 0x0d, 0x66, 0x05,
+ 0xf0, 0xd2, 0x80, 0xf4, 0x09, 0x19, 0x39, 0xfe, 0x3b, 0x31, 0xee, 0x17,
+ 0xaa, 0xd1, 0x7e, 0xf5, 0x7d, 0xf5, 0x26, 0x06, 0xf2, 0x2c, 0xca, 0x30,
+ 0x7f, 0x1c, 0x75, 0x92, 0xf9, 0x6c, 0x64, 0xad, 0x0c, 0xe9, 0x7e, 0x83,
+ 0x48, 0xdb, 0xb6, 0x7a, 0xbd, 0x4f, 0x5f, 0xce, 0x30, 0x6e, 0x11, 0xd6,
+ 0x7d, 0x56, 0xef, 0x83, 0x73, 0xd3, 0xc9, 0x7c, 0x5f, 0x84, 0xf2, 0xa9,
+ 0x53, 0x7a, 0xb9, 0xce, 0x73, 0x66, 0x5c, 0xd3, 0x76, 0xfb, 0x26, 0x9e,
+ 0x07, 0xdd, 0x02, 0xfb, 0xef, 0x3b, 0x80, 0x89, 0x30, 0x9e, 0x40, 0x3a,
+ 0x7c, 0xc2, 0xd7, 0x85, 0x61, 0xfa, 0x4d, 0xc2, 0x30, 0xfd, 0x26, 0x61,
+ 0x20, 0x2e, 0x00, 0x47, 0xa5, 0x7d, 0x75, 0x68, 0x53, 0x5c, 0x85, 0x71,
+ 0x1c, 0x2c, 0x4d, 0xc3, 0xbf, 0xd5, 0x31, 0x94, 0xce, 0x69, 0x45, 0x9e,
+ 0xf7, 0xc0, 0x73, 0xe0, 0xad, 0x12, 0x78, 0x0f, 0xb6, 0xe1, 0x97, 0x61,
+ 0x1b, 0x3e, 0x01, 0xdb, 0xf0, 0x1c, 0x6c, 0xc3, 0xc7, 0x31, 0x37, 0x8f,
+ 0x2d, 0xe0, 0xd5, 0x8c, 0xe6, 0xd5, 0x42, 0xe9, 0x02, 0x78, 0xb5, 0xeb,
+ 0x0a, 0xfc, 0xe8, 0xc2, 0xc6, 0xa7, 0x0d, 0xed, 0xc0, 0x96, 0xff, 0xb8,
+ 0xf6, 0x8b, 0x1f, 0x4c, 0x8d, 0xb1, 0x0e, 0x68, 0x38, 0x49, 0x9f, 0x16,
+ 0xf2, 0x3f, 0x99, 0x07, 0xef, 0x61, 0xac, 0x8e, 0xa3, 0xae, 0x5b, 0x23,
+ 0xd4, 0x1f, 0xee, 0x36, 0xee, 0xef, 0xe6, 0x58, 0x13, 0x8b, 0xf0, 0x64,
+ 0xf8, 0x73, 0x8f, 0x4f, 0x3d, 0x42, 0xbe, 0x4c, 0x7c, 0x76, 0xc4, 0xaf,
+ 0xe6, 0xc5, 0x1d, 0x1c, 0x5f, 0xe0, 0x6d, 0x5a, 0xae, 0xee, 0x7c, 0xf9,
+ 0x35, 0x73, 0xe5, 0x75, 0xff, 0xa3, 0xe4, 0x37, 0xe8, 0x6e, 0xe2, 0x3e,
+ 0x91, 0x8d, 0x6c, 0xb0, 0xb8, 0xdf, 0x2f, 0x6d, 0xdb, 0x60, 0xaf, 0x0f,
+ 0x82, 0x7e, 0xa7, 0x02, 0xf1, 0xb7, 0x85, 0x6d, 0xce, 0xb7, 0xe3, 0xd9,
+ 0x76, 0x76, 0xc3, 0x96, 0xed, 0xdb, 0xc4, 0xb5, 0x5e, 0xd8, 0xf2, 0xa9,
+ 0x70, 0x3e, 0x60, 0xf9, 0xea, 0x39, 0xa7, 0x0c, 0xa5, 0xec, 0x6c, 0xb0,
+ 0xf1, 0x7e, 0xb6, 0x77, 0x61, 0xd1, 0x3c, 0x5d, 0x0a, 0x78, 0xce, 0x76,
+ 0xc4, 0x1f, 0xab, 0xa2, 0x95, 0xbf, 0xb2, 0xb4, 0xa2, 0x16, 0x8d, 0xe3,
+ 0x9c, 0xa5, 0x95, 0x10, 0xde, 0x58, 0x48, 0x2b, 0x75, 0x21, 0xad, 0xe4,
+ 0xc7, 0x43, 0x5a, 0x61, 0xdd, 0x73, 0x21, 0xad, 0x24, 0xaa, 0x69, 0x25,
+ 0x3f, 0xee, 0xe0, 0x59, 0x0c, 0x07, 0xe9, 0x85, 0xed, 0x90, 0x5e, 0x00,
+ 0x4b, 0xa5, 0x32, 0x47, 0x2f, 0x31, 0xb4, 0x73, 0xa8, 0xa4, 0x34, 0xad,
+ 0x0c, 0xa9, 0x50, 0x47, 0x78, 0x98, 0x73, 0xcc, 0xfd, 0x15, 0x69, 0x24,
+ 0x65, 0x69, 0x64, 0xfe, 0x2c, 0xd1, 0x22, 0xda, 0x00, 0xee, 0x79, 0x5e,
+ 0x60, 0xb3, 0xa6, 0x8d, 0xfb, 0x53, 0x2f, 0xa0, 0xec, 0x28, 0x68, 0x23,
+ 0xc4, 0xc1, 0x03, 0x16, 0x07, 0x8b, 0xe7, 0xf2, 0xb4, 0xc5, 0xc1, 0xa8,
+ 0xc5, 0x81, 0xe6, 0x97, 0x3c, 0xe7, 0x4c, 0x69, 0x1c, 0xd4, 0x69, 0x1c,
+ 0x88, 0x0a, 0xeb, 0x9e, 0x5e, 0x06, 0x07, 0x2c, 0x33, 0xaa, 0xc7, 0x1f,
+ 0xc1, 0xf8, 0xf7, 0x61, 0xfc, 0x4a, 0x8f, 0x9f, 0xf3, 0xc0, 0xf1, 0x03,
+ 0x96, 0xca, 0x77, 0xe6, 0xc6, 0xdf, 0x84, 0x36, 0x0e, 0x6a, 0xdb, 0x99,
+ 0xf1, 0x54, 0xea, 0x46, 0x33, 0xfe, 0xc7, 0x2a, 0xe6, 0x8c, 0xc9, 0x63,
+ 0x4b, 0xf4, 0xd8, 0x0b, 0x96, 0x37, 0x7c, 0xbd, 0xce, 0xc6, 0x73, 0x6d,
+ 0xe7, 0xa0, 0xbb, 0xc6, 0x52, 0x09, 0x7b, 0xe6, 0xd4, 0xd8, 0x43, 0x5f,
+ 0x4d, 0x91, 0x77, 0x3e, 0xaa, 0xf7, 0xfa, 0x9d, 0xa5, 0x5d, 0x54, 0x6a,
+ 0x92, 0xbe, 0xb1, 0x6a, 0xb8, 0x09, 0x6f, 0x3e, 0x50, 0x3e, 0x63, 0x37,
+ 0xfb, 0xa1, 0x3b, 0x4c, 0xdc, 0x1a, 0xb4, 0x84, 0xf4, 0x64, 0xbe, 0x37,
+ 0x52, 0x27, 0xea, 0x81, 0x0f, 0x60, 0xcc, 0x2e, 0x7c, 0xcc, 0x76, 0x6f,
+ 0x9b, 0xa2, 0xae, 0xbb, 0xba, 0x4a, 0xd7, 0x35, 0x5b, 0x5d, 0xb7, 0x86,
+ 0xba, 0x0e, 0x70, 0x3f, 0x25, 0x87, 0x4b, 0x9c, 0xbf, 0x7c, 0xa2, 0x4e,
+ 0xc7, 0x40, 0x1d, 0x1b, 0xe7, 0x4b, 0xc6, 0x0f, 0x6b, 0x5a, 0xa6, 0xce,
+ 0x4a, 0xea, 0xb8, 0xe4, 0x4c, 0xd7, 0x3f, 0xd9, 0x75, 0x10, 0xea, 0xb5,
+ 0xef, 0x07, 0x7f, 0xb0, 0x8c, 0x5e, 0x83, 0xfe, 0xd1, 0xf6, 0x59, 0x0d,
+ 0x64, 0xad, 0x9c, 0x6a, 0xc6, 0xb3, 0x9a, 0xe7, 0xc1, 0x3a, 0x3b, 0x54,
+ 0xbd, 0xd4, 0x9c, 0x6a, 0x94, 0x3d, 0x63, 0x7a, 0xdd, 0x5c, 0xd4, 0x29,
+ 0xe0, 0xff, 0x14, 0xcf, 0x14, 0x88, 0x3e, 0x03, 0x95, 0x1b, 0x85, 0x3f,
+ 0x33, 0xf1, 0x94, 0xd9, 0x1b, 0x38, 0x56, 0xa3, 0x7f, 0xd3, 0xc6, 0x28,
+ 0xa4, 0x32, 0xfa, 0xec, 0xd0, 0x1e, 0xb4, 0xd9, 0xbe, 0xa9, 0x16, 0x63,
+ 0x8e, 0xa1, 0x2e, 0xf7, 0x16, 0xaa, 0x36, 0x57, 0x6a, 0xc5, 0x9d, 0x88,
+ 0xea, 0xf3, 0x4b, 0x3c, 0x7f, 0x9f, 0xed, 0x69, 0x42, 0x5e, 0x44, 0xaf,
+ 0x15, 0xd4, 0x9c, 0x9a, 0x3f, 0xa7, 0xae, 0x8e, 0x8a, 0x5d, 0xc3, 0x4f,
+ 0x6b, 0xbd, 0x12, 0x39, 0x4a, 0x9d, 0xc3, 0xfd, 0x55, 0x3d, 0x98, 0xf7,
+ 0xe5, 0xf4, 0x8d, 0x31, 0x62, 0xb3, 0x98, 0x3f, 0x75, 0x86, 0x67, 0x8d,
+ 0x5b, 0xf1, 0x0e, 0xdb, 0x0b, 0xf5, 0x08, 0x74, 0xdf, 0xdb, 0x3f, 0xe1,
+ 0x49, 0x3d, 0xf0, 0x3d, 0xa1, 0x80, 0x6b, 0x57, 0xd3, 0x42, 0x5e, 0x85,
+ 0xb1, 0x69, 0x43, 0x0f, 0x8f, 0xbf, 0x21, 0x3f, 0x90, 0x26, 0x3a, 0x6d,
+ 0x6c, 0xc1, 0xb7, 0x31, 0x7e, 0xd2, 0xb6, 0xa1, 0x87, 0x47, 0x53, 0x19,
+ 0xc5, 0xbd, 0x51, 0x66, 0x1d, 0x94, 0xb4, 0x41, 0x9a, 0x4f, 0xe8, 0xf5,
+ 0xd1, 0x8c, 0xbc, 0x2c, 0x99, 0xa6, 0x76, 0xd8, 0x5d, 0xff, 0xb6, 0x73,
+ 0x6c, 0xee, 0x2e, 0xd0, 0x34, 0x07, 0xdd, 0xc4, 0x7d, 0xca, 0x9d, 0xf2,
+ 0x5e, 0x9e, 0x57, 0x98, 0x70, 0xa0, 0x94, 0x9f, 0xd2, 0x7b, 0xbf, 0x77,
+ 0x14, 0x57, 0xcb, 0xad, 0xa9, 0xa8, 0x5d, 0xe7, 0xac, 0x05, 0x1d, 0x40,
+ 0x50, 0x9f, 0xaa, 0xc5, 0x13, 0x75, 0x38, 0x7f, 0x17, 0x53, 0x99, 0xa4,
+ 0x22, 0xb3, 0xc3, 0xe7, 0x9f, 0x91, 0x2d, 0xde, 0x1e, 0x7d, 0xce, 0x4e,
+ 0x9c, 0xba, 0x53, 0x7f, 0xe9, 0xd1, 0x06, 0x25, 0xfd, 0xcc, 0xf8, 0xb5,
+ 0x7a, 0x5d, 0xab, 0x3f, 0x15, 0x04, 0x39, 0xcc, 0x5f, 0x41, 0x4c, 0xfc,
+ 0x6c, 0xc2, 0x67, 0x1a, 0xfd, 0xda, 0x06, 0xa7, 0xf6, 0x4c, 0xa3, 0x63,
+ 0x68, 0x45, 0x22, 0x2a, 0x5d, 0xef, 0xd4, 0x9c, 0xba, 0x93, 0x73, 0x06,
+ 0xba, 0xf2, 0x1c, 0x43, 0x57, 0x31, 0x67, 0x9e, 0xae, 0xd6, 0xd9, 0xdf,
+ 0x2a, 0x5d, 0x27, 0x99, 0x64, 0x1d, 0xc6, 0xdb, 0x5b, 0x0c, 0x61, 0x3c,
+ 0x0c, 0xb8, 0x08, 0xcf, 0xdd, 0x18, 0xc3, 0x30, 0x9e, 0x3c, 0x60, 0x01,
+ 0xb3, 0x9f, 0x2a, 0x00, 0xe6, 0x83, 0x78, 0x18, 0x27, 0x6b, 0x76, 0x22,
+ 0x13, 0xd5, 0xf0, 0x12, 0xc6, 0x1f, 0x5b, 0x78, 0x5f, 0x0f, 0x56, 0x4f,
+ 0x66, 0xba, 0x8b, 0x80, 0x87, 0x70, 0xde, 0x07, 0x18, 0x69, 0x97, 0x8e,
+ 0xe2, 0xdb, 0x03, 0x7c, 0x63, 0x16, 0x26, 0xd0, 0xe3, 0xd8, 0x43, 0xf3,
+ 0xbf, 0x8b, 0xb4, 0x93, 0x8f, 0xd9, 0xef, 0xd6, 0x45, 0x32, 0xe0, 0x15,
+ 0x87, 0x78, 0x1e, 0x29, 0xbd, 0xe6, 0xc0, 0x0e, 0x00, 0xdf, 0xbf, 0xe4,
+ 0x44, 0xce, 0xc4, 0xe5, 0x50, 0x91, 0x31, 0x84, 0xe3, 0x0e, 0xe7, 0x41,
+ 0xf9, 0x57, 0xa1, 0x4c, 0x5c, 0xc9, 0xc4, 0xd5, 0x78, 0xde, 0x82, 0x67,
+ 0x03, 0x9e, 0x8d, 0x78, 0xd6, 0xe3, 0x69, 0xc5, 0xf3, 0x2d, 0x94, 0x53,
+ 0xb1, 0x3a, 0xe1, 0x7e, 0xd5, 0x16, 0xa5, 0x34, 0x1f, 0x71, 0xcf, 0xc2,
+ 0x65, 0xc0, 0xe5, 0x2b, 0xd0, 0x3b, 0x1e, 0x9e, 0xf1, 0xf8, 0x3a, 0xfa,
+ 0x98, 0xc5, 0xd3, 0xa9, 0xe4, 0x4c, 0x17, 0x9e, 0x14, 0x9e, 0x6e, 0x3c,
+ 0x3d, 0x78, 0xd2, 0x78, 0x5e, 0x75, 0x0c, 0xcf, 0x5d, 0x02, 0xbe, 0x42,
+ 0x1e, 0x01, 0xce, 0x17, 0xf0, 0x9c, 0xe7, 0xbc, 0x09, 0x9e, 0x73, 0x2c,
+ 0xcf, 0x39, 0xf3, 0x3c, 0x57, 0xeb, 0xa8, 0x63, 0xf5, 0x4e, 0xe4, 0x18,
+ 0x7d, 0x85, 0x5a, 0xc7, 0xf0, 0x7f, 0x44, 0x7a, 0x07, 0x41, 0x4b, 0xc7,
+ 0x30, 0x67, 0xc7, 0x48, 0x57, 0x2e, 0xd2, 0xc7, 0x16, 0xf5, 0x3b, 0xfa,
+ 0x26, 0xfa, 0x3d, 0x61, 0xfb, 0x7d, 0xb8, 0xaa, 0xdf, 0x83, 0x68, 0xfb,
+ 0x3e, 0xdb, 0xef, 0xc1, 0xaa, 0x7e, 0x41, 0x2b, 0xc7, 0xf2, 0x78, 0x48,
+ 0x17, 0x23, 0x48, 0x0f, 0x65, 0xc2, 0xdd, 0x6b, 0xa4, 0xbe, 0x46, 0x9f,
+ 0x27, 0x8d, 0xf9, 0x35, 0x73, 0xba, 0x31, 0x53, 0xa5, 0x1f, 0x7e, 0x16,
+ 0xfd, 0x38, 0x5c, 0xa2, 0x8d, 0x38, 0x5d, 0x25, 0x17, 0xe8, 0xfb, 0x04,
+ 0x72, 0x5c, 0xfb, 0x39, 0xf4, 0x79, 0xe8, 0xff, 0x2c, 0xb6, 0xad, 0x3e,
+ 0xae, 0xf7, 0xe7, 0xde, 0x55, 0x6c, 0x95, 0x4f, 0x14, 0x69, 0x13, 0x92,
+ 0x5e, 0x82, 0x60, 0xcf, 0x36, 0xda, 0xa7, 0xf9, 0x60, 0x9d, 0x9f, 0xd4,
+ 0xb1, 0xb5, 0x4f, 0x2e, 0xd5, 0x19, 0xa3, 0xbd, 0xf0, 0xcd, 0xb3, 0x47,
+ 0x3f, 0x08, 0x9d, 0x51, 0x03, 0xb8, 0x9f, 0xd2, 0x77, 0x80, 0xec, 0x1a,
+ 0x55, 0x23, 0x6b, 0x25, 0x2e, 0x37, 0x17, 0x6b, 0x61, 0xf7, 0x30, 0x56,
+ 0x5e, 0x2f, 0xed, 0xdb, 0xa2, 0xe6, 0x6c, 0x8d, 0x17, 0xc3, 0x6f, 0xcf,
+ 0x9c, 0xf5, 0x89, 0xc5, 0x91, 0x1f, 0x69, 0xa2, 0x1c, 0x8c, 0xf9, 0xef,
+ 0xd4, 0xfb, 0x26, 0xdb, 0xb6, 0xd1, 0x6e, 0xb9, 0x41, 0xeb, 0x70, 0x77,
+ 0x89, 0x9d, 0xa4, 0x5a, 0x3c, 0x99, 0xb7, 0xd1, 0x76, 0x17, 0x93, 0x09,
+ 0xc2, 0xf5, 0x90, 0x70, 0x3f, 0xc1, 0x7e, 0x29, 0xa4, 0x1a, 0x25, 0x92,
+ 0xe6, 0xba, 0x5c, 0xb2, 0x93, 0xb6, 0xd1, 0xc4, 0x98, 0x67, 0xcf, 0x9e,
+ 0xac, 0x96, 0x0b, 0xba, 0x9f, 0x5a, 0x0d, 0xa3, 0x39, 0x8f, 0xc6, 0x35,
+ 0x2f, 0x9e, 0x81, 0x72, 0xf1, 0x6e, 0xd0, 0x7a, 0x67, 0xa2, 0xcc, 0xb3,
+ 0x4e, 0xf0, 0x97, 0xca, 0x31, 0x7d, 0xc6, 0xd4, 0x7b, 0x3b, 0xfc, 0xd8,
+ 0xf2, 0x06, 0xd9, 0x3d, 0xb6, 0x82, 0xeb, 0x28, 0xb1, 0xb5, 0xd0, 0x1f,
+ 0xac, 0xd3, 0xb6, 0x0d, 0xfe, 0xdf, 0xf8, 0x46, 0x79, 0x7c, 0x9c, 0x6d,
+ 0xb7, 0xc8, 0xe4, 0x94, 0x38, 0xde, 0xdb, 0x57, 0xa2, 0x8c, 0xc7, 0xf1,
+ 0x08, 0xf7, 0x3c, 0xb5, 0x6d, 0x13, 0xe5, 0xbd, 0xdd, 0x95, 0xf3, 0xdd,
+ 0x11, 0xbd, 0x26, 0xe3, 0x82, 0x4e, 0xd8, 0xde, 0xf9, 0xee, 0x56, 0x39,
+ 0x3b, 0x05, 0x9a, 0x80, 0xdc, 0xef, 0x3b, 0x45, 0x98, 0x44, 0xb6, 0x4f,
+ 0xc0, 0x5e, 0x90, 0x76, 0x3c, 0xa0, 0x0f, 0xc8, 0xef, 0x5b, 0xbb, 0xd9,
+ 0x17, 0xf4, 0x12, 0x74, 0x5c, 0xdb, 0x36, 0x23, 0x0b, 0x32, 0x13, 0x35,
+ 0x48, 0x67, 0xbb, 0xf0, 0x0f, 0x07, 0xd9, 0x4e, 0x58, 0x57, 0x61, 0x4c,
+ 0xb5, 0x9a, 0x5e, 0x66, 0x17, 0xe9, 0x8f, 0x73, 0x3f, 0x97, 0xfd, 0xcd,
+ 0x36, 0x3a, 0x41, 0x2b, 0xbe, 0xde, 0xc3, 0x63, 0x6c, 0x2b, 0xce, 0x09,
+ 0x6d, 0x22, 0xda, 0x55, 0xd7, 0x6a, 0xfb, 0x62, 0xb2, 0xc2, 0x19, 0xe4,
+ 0xda, 0x48, 0x38, 0x47, 0x71, 0x39, 0x59, 0x9a, 0x9b, 0xa7, 0x0d, 0x35,
+ 0x0b, 0xe7, 0x89, 0xb4, 0x92, 0x1a, 0xb2, 0xb6, 0xc7, 0x8c, 0x3c, 0x0f,
+ 0xbb, 0xac, 0x53, 0xcf, 0xd9, 0x0c, 0x6c, 0x59, 0x3b, 0x67, 0xda, 0x9e,
+ 0x2d, 0x84, 0x73, 0x36, 0x00, 0x8d, 0x53, 0xbe, 0x41, 0xcf, 0x99, 0x07,
+ 0xba, 0xc9, 0x03, 0xef, 0x79, 0xcc, 0x53, 0x1e, 0x73, 0x94, 0x2f, 0xb7,
+ 0xc8, 0xc4, 0x71, 0xd5, 0x5a, 0x23, 0x92, 0xd8, 0xed, 0xb7, 0xc8, 0xf0,
+ 0x14, 0x63, 0x05, 0x1b, 0x60, 0x83, 0x6d, 0xc4, 0xd3, 0x8a, 0x6f, 0xd6,
+ 0xe3, 0x1d, 0x1f, 0x0a, 0x75, 0xeb, 0x96, 0xd8, 0x59, 0x67, 0xd1, 0xf7,
+ 0xd3, 0xc0, 0xc3, 0xa3, 0xc0, 0xc3, 0x3c, 0xef, 0xbc, 0x50, 0x15, 0x5f,
+ 0xe2, 0x58, 0xb5, 0x0e, 0xc5, 0x78, 0x63, 0x7a, 0x3e, 0x75, 0x9c, 0xa9,
+ 0x54, 0xfb, 0x66, 0xec, 0xa9, 0x38, 0xed, 0xa9, 0xdc, 0xa8, 0x67, 0xce,
+ 0x60, 0x0d, 0xc0, 0x77, 0xf2, 0xf7, 0x69, 0x5a, 0x1f, 0x1a, 0x27, 0x5c,
+ 0xd1, 0x10, 0xae, 0x05, 0x73, 0xc6, 0x33, 0xb3, 0x4b, 0xe3, 0x18, 0x2f,
+ 0xcc, 0xed, 0x11, 0x87, 0x2e, 0x97, 0xd1, 0x14, 0xe3, 0x24, 0xad, 0xcb,
+ 0xc0, 0xf4, 0x94, 0xb6, 0x61, 0x45, 0x9d, 0x96, 0x03, 0x25, 0x9e, 0xb7,
+ 0xe5, 0x1a, 0xcc, 0xef, 0x31, 0x7e, 0xd4, 0x39, 0x21, 0xc7, 0xd0, 0x37,
+ 0xd7, 0xc5, 0x95, 0x8d, 0xcf, 0xac, 0xb2, 0x7b, 0xf2, 0xaa, 0x63, 0x34,
+ 0x66, 0xdd, 0x7c, 0xe1, 0xd9, 0x93, 0xe4, 0xc0, 0xac, 0x5e, 0x77, 0xe5,
+ 0x9a, 0xa1, 0x8c, 0x46, 0xa0, 0xfd, 0x76, 0x77, 0x27, 0x7b, 0xcc, 0x59,
+ 0xc3, 0x84, 0xf4, 0x97, 0xcc, 0xf8, 0x2f, 0xea, 0x7d, 0x93, 0x66, 0x7f,
+ 0xb8, 0xd9, 0x53, 0xb9, 0x5f, 0x2e, 0xa6, 0xa2, 0x55, 0x73, 0x5b, 0x27,
+ 0xc3, 0xc0, 0x85, 0x5e, 0xcb, 0x84, 0x5d, 0x9c, 0xeb, 0x7e, 0xbc, 0x89,
+ 0x67, 0xd1, 0xa2, 0x98, 0x9f, 0xc2, 0x38, 0xcf, 0xa7, 0xb3, 0xdd, 0x2b,
+ 0xb5, 0x45, 0x31, 0xcb, 0xb3, 0x4e, 0x90, 0x95, 0x6f, 0xdd, 0x12, 0xaf,
+ 0xd7, 0xf9, 0x2b, 0xec, 0x99, 0x16, 0xd8, 0x0d, 0xbb, 0x02, 0xf9, 0x33,
+ 0xe8, 0xc9, 0xd3, 0x76, 0x4c, 0x09, 0x1d, 0x93, 0x92, 0xe0, 0x7c, 0x2a,
+ 0x6e, 0xe3, 0xce, 0x1c, 0xcb, 0x98, 0xa5, 0x6f, 0x63, 0xff, 0xcc, 0xdb,
+ 0xd0, 0x5d, 0x9a, 0xd6, 0x1f, 0xd7, 0xb2, 0xb0, 0xcb, 0xda, 0xce, 0x3a,
+ 0x8e, 0x73, 0x42, 0xf4, 0x1e, 0xac, 0xd0, 0x37, 0xea, 0xa8, 0xf2, 0x0b,
+ 0x8c, 0x2f, 0x57, 0x18, 0x5b, 0x4e, 0x46, 0xcd, 0xfb, 0x84, 0xf4, 0xe5,
+ 0xf6, 0x6c, 0xe2, 0xdd, 0x30, 0xa1, 0x2f, 0xd7, 0x65, 0x7d, 0xb9, 0x46,
+ 0xed, 0xcb, 0x99, 0xd8, 0x43, 0xe3, 0x9c, 0x2f, 0x57, 0x18, 0xcb, 0x83,
+ 0x56, 0x6a, 0xed, 0x59, 0x09, 0x63, 0x0b, 0x0d, 0x17, 0x5d, 0xbd, 0x6f,
+ 0x24, 0x37, 0xa0, 0xe0, 0x37, 0x18, 0x1f, 0x8b, 0xb1, 0x0a, 0xa5, 0xfe,
+ 0xce, 0xfa, 0x17, 0x1b, 0x24, 0xd3, 0xbc, 0x02, 0xe3, 0x7e, 0x4a, 0xcf,
+ 0xb9, 0x59, 0xc3, 0x82, 0x5c, 0x1b, 0x64, 0xcc, 0x87, 0x67, 0x47, 0x35,
+ 0x7f, 0x25, 0x7a, 0x23, 0x9d, 0xc6, 0x9e, 0xf5, 0x13, 0x6b, 0xa5, 0xfe,
+ 0xb8, 0x53, 0x18, 0x8f, 0xda, 0x7e, 0x13, 0x80, 0xa9, 0x06, 0x73, 0xf3,
+ 0x4e, 0x2b, 0x93, 0xd9, 0xf7, 0x3b, 0xea, 0x18, 0x1b, 0x98, 0x2a, 0x9a,
+ 0x18, 0x60, 0x5f, 0x31, 0x12, 0x9e, 0x5b, 0x57, 0x5c, 0x47, 0xce, 0x0c,
+ 0xae, 0x00, 0x2c, 0x2b, 0x96, 0xb5, 0x59, 0x1f, 0x7b, 0x43, 0x1d, 0x45,
+ 0x9a, 0x7a, 0x4a, 0xef, 0x2f, 0x5c, 0xd9, 0x9d, 0xdc, 0xa9, 0xcf, 0x23,
+ 0xe9, 0x58, 0x62, 0x5e, 0xb8, 0x7f, 0xf7, 0x9b, 0xf2, 0x36, 0x2d, 0xfb,
+ 0x0f, 0xa4, 0xa8, 0xc7, 0xb6, 0xe9, 0xdf, 0xb5, 0xe9, 0x20, 0x38, 0xdf,
+ 0xfd, 0x2c, 0x6c, 0x16, 0xdf, 0xfb, 0x96, 0xb4, 0xc7, 0x7b, 0xb5, 0x0d,
+ 0x85, 0xb9, 0x1a, 0xac, 0x97, 0x15, 0xfe, 0xb8, 0xdd, 0xab, 0x68, 0xd6,
+ 0x03, 0x0b, 0xc2, 0xfb, 0x17, 0x3a, 0x6c, 0x5e, 0x3e, 0xa8, 0x07, 0x3d,
+ 0x7d, 0x44, 0x8c, 0xac, 0xc9, 0xcd, 0xcb, 0x1a, 0xee, 0xa7, 0xcb, 0x90,
+ 0xa0, 0xdd, 0x23, 0x92, 0xe4, 0xdd, 0x49, 0xec, 0xbb, 0x20, 0x57, 0x41,
+ 0x3f, 0xb3, 0x1e, 0x6d, 0x56, 0x7e, 0x73, 0x0f, 0x8a, 0xef, 0x1d, 0x84,
+ 0x8e, 0xb9, 0x61, 0xa9, 0x8e, 0x89, 0xd3, 0xbf, 0xcf, 0x8d, 0xd2, 0x47,
+ 0x5c, 0x89, 0x3a, 0x2d, 0xf2, 0xd1, 0xb1, 0xdf, 0x5a, 0x4b, 0x1e, 0x1b,
+ 0x82, 0x7c, 0x57, 0xf7, 0x87, 0xe7, 0x2e, 0x99, 0xc6, 0x7c, 0xb6, 0x5b,
+ 0x27, 0x89, 0xf7, 0x79, 0xf2, 0xc5, 0x4a, 0x32, 0x31, 0x0b, 0x1d, 0x35,
+ 0xe4, 0x0c, 0xb7, 0x9a, 0xd8, 0xe9, 0xa7, 0xd6, 0x9a, 0x73, 0x5a, 0xf5,
+ 0xc0, 0x69, 0x18, 0x4f, 0xad, 0xa6, 0xdd, 0x59, 0x2b, 0x97, 0x83, 0xa0,
+ 0xbe, 0x5b, 0xcb, 0xe2, 0x9d, 0x94, 0xc5, 0x07, 0x52, 0x1d, 0x86, 0x07,
+ 0xb4, 0xef, 0xc4, 0x3d, 0x00, 0xc0, 0x43, 0xb7, 0xcb, 0xbd, 0xd0, 0x96,
+ 0x4f, 0xfd, 0xcc, 0x8c, 0x95, 0x4f, 0xca, 0x59, 0xca, 0x9f, 0x6a, 0x6b,
+ 0x74, 0x81, 0xec, 0x3d, 0x34, 0x46, 0xbd, 0x9c, 0x9a, 0xfe, 0x26, 0xe4,
+ 0x55, 0x4e, 0xe3, 0xa1, 0x45, 0xee, 0x1b, 0x93, 0xcc, 0x45, 0xe8, 0xac,
+ 0xc2, 0xd4, 0x42, 0x1e, 0x5d, 0xda, 0x1e, 0xc7, 0x7a, 0x7a, 0xad, 0xf1,
+ 0x71, 0x17, 0x8e, 0x75, 0x9a, 0x7b, 0x8c, 0xf4, 0x58, 0xb9, 0x37, 0xff,
+ 0x9c, 0x1d, 0xeb, 0xca, 0x70, 0xac, 0x3d, 0x0b, 0xc7, 0x1a, 0xfa, 0xf8,
+ 0xa1, 0xfc, 0x4d, 0xe8, 0xb3, 0x49, 0xfa, 0x4c, 0xcc, 0xd8, 0x4a, 0xe9,
+ 0x1d, 0x6d, 0xb4, 0x72, 0xd3, 0x83, 0x0e, 0xe2, 0x79, 0xa1, 0xe9, 0xcf,
+ 0x79, 0x62, 0x71, 0xa6, 0x88, 0x07, 0xca, 0xdc, 0x26, 0x7d, 0x9e, 0x71,
+ 0x02, 0x7e, 0xd6, 0x87, 0x8b, 0x2c, 0x1b, 0xe6, 0x5f, 0x29, 0x46, 0x1c,
+ 0xfa, 0xd6, 0xf4, 0x9f, 0x3a, 0x97, 0xc4, 0x16, 0x4c, 0x1c, 0x98, 0xf1,
+ 0x5f, 0x73, 0xcf, 0x02, 0xf7, 0x7d, 0xdf, 0x01, 0xde, 0xfa, 0xed, 0x62,
+ 0xb2, 0x27, 0x1b, 0xa1, 0x3c, 0x9d, 0x95, 0x43, 0x95, 0x3e, 0x69, 0xd3,
+ 0x67, 0xed, 0xdf, 0x30, 0x46, 0x9c, 0xa9, 0x8e, 0x11, 0x8b, 0x63, 0x62,
+ 0xc4, 0x3b, 0x7f, 0x8e, 0x18, 0xb1, 0x38, 0x26, 0x46, 0xbc, 0x9c, 0x9f,
+ 0x35, 0x52, 0x9a, 0xc5, 0xb8, 0xea, 0x21, 0x53, 0x94, 0x93, 0x9b, 0x6a,
+ 0xc0, 0xbb, 0x16, 0x6f, 0xc0, 0x32, 0x56, 0xc0, 0xdb, 0xc3, 0xfb, 0x20,
+ 0xde, 0x31, 0x19, 0x99, 0xd3, 0x1d, 0xb3, 0x90, 0x1f, 0xd4, 0x69, 0xac,
+ 0x6b, 0xfc, 0x82, 0xc9, 0x72, 0x33, 0xca, 0x5d, 0x72, 0x26, 0x58, 0xaf,
+ 0xd4, 0x28, 0xc3, 0x63, 0x94, 0xdd, 0x4d, 0x32, 0x3a, 0x16, 0xda, 0xb8,
+ 0x9f, 0x5d, 0xcf, 0xb5, 0x81, 0x21, 0x09, 0x6d, 0xd8, 0x67, 0xd6, 0x9b,
+ 0xb5, 0xdb, 0x2d, 0x31, 0xa9, 0x5f, 0x8d, 0x39, 0x38, 0xee, 0x5c, 0x1c,
+ 0x5f, 0xbd, 0xc0, 0x96, 0x4d, 0xd8, 0xd8, 0xe0, 0xb8, 0xd5, 0xc1, 0xcb,
+ 0xcb, 0x88, 0xea, 0xf9, 0x8f, 0xdb, 0x73, 0xbc, 0x51, 0x7b, 0xd7, 0x5f,
+ 0x42, 0xcf, 0xcf, 0x40, 0x65, 0x16, 0xfd, 0xad, 0x57, 0x99, 0x71, 0x8e,
+ 0x73, 0xee, 0x7e, 0x1e, 0xc8, 0xc5, 0x56, 0x35, 0x34, 0xbe, 0x80, 0x2e,
+ 0x41, 0xb7, 0x1c, 0x9b, 0x03, 0xda, 0xbd, 0x57, 0x26, 0x46, 0x09, 0x5f,
+ 0x47, 0x3c, 0xa2, 0xcf, 0xf5, 0xe2, 0x7b, 0xdc, 0x9c, 0x27, 0xea, 0xad,
+ 0x84, 0x67, 0x7a, 0xd7, 0x00, 0xde, 0xc5, 0xe7, 0x7a, 0xad, 0x9e, 0xd6,
+ 0x36, 0x04, 0xcf, 0xf7, 0x86, 0x63, 0x58, 0x8e, 0x9e, 0x02, 0x19, 0xd6,
+ 0xfb, 0x7d, 0xd7, 0xca, 0xe9, 0x07, 0xe7, 0xce, 0x17, 0x34, 0xc1, 0x56,
+ 0x69, 0x85, 0xa9, 0x3c, 0xe0, 0xa6, 0xb9, 0xef, 0x82, 0xfb, 0x0b, 0x3a,
+ 0xe2, 0xb7, 0xe9, 0x73, 0x1f, 0xf3, 0x67, 0xac, 0xe7, 0xcf, 0x7e, 0x84,
+ 0x67, 0x5a, 0xe3, 0xd2, 0x07, 0x3a, 0xec, 0xd7, 0xe9, 0x31, 0x8c, 0x87,
+ 0x6b, 0xbe, 0x1a, 0x0f, 0x90, 0x3d, 0x5c, 0xfb, 0xc5, 0xd8, 0x2b, 0x2d,
+ 0x2a, 0xa7, 0xcf, 0x58, 0x47, 0x2d, 0x8d, 0x5d, 0x76, 0xf6, 0x94, 0x13,
+ 0x6a, 0x4f, 0xd9, 0x57, 0x7b, 0xcb, 0x36, 0xaf, 0xfb, 0x01, 0xcc, 0x07,
+ 0x7e, 0x8f, 0x17, 0x9d, 0x21, 0xe0, 0xab, 0x50, 0x3a, 0xe2, 0x64, 0xf4,
+ 0xfb, 0xa8, 0x7d, 0x43, 0x0e, 0x60, 0xae, 0x7a, 0xc7, 0xa3, 0x5a, 0xde,
+ 0xcf, 0xdf, 0xd3, 0x17, 0xce, 0xeb, 0x0b, 0x7a, 0x0d, 0x68, 0x5a, 0x88,
+ 0x6b, 0xcf, 0xda, 0x10, 0xc7, 0x9d, 0x9c, 0xc6, 0x3d, 0xcb, 0x7c, 0x4b,
+ 0xff, 0x06, 0x9d, 0x2b, 0xd3, 0x5e, 0x2b, 0xde, 0x8b, 0xf7, 0x4d, 0x86,
+ 0xfa, 0x86, 0x70, 0xdf, 0x09, 0xbd, 0x16, 0xec, 0x37, 0xf2, 0x6a, 0x56,
+ 0x46, 0x2a, 0x5c, 0xc3, 0x64, 0x3b, 0x48, 0x2f, 0xd7, 0xc0, 0x1e, 0x58,
+ 0x78, 0xbe, 0xba, 0x7f, 0x7e, 0x1e, 0x12, 0xe3, 0x42, 0x58, 0xee, 0xd6,
+ 0x67, 0x17, 0xab, 0xef, 0x1e, 0xb9, 0xf2, 0xbf, 0x70, 0xfd, 0xd0, 0xc8,
+ 0x50, 0x0b, 0x47, 0x86, 0xf2, 0xce, 0xc8, 0x95, 0xaf, 0xcb, 0x41, 0xe0,
+ 0xf1, 0x30, 0x60, 0x52, 0xf7, 0xf3, 0xce, 0xab, 0x57, 0xa5, 0x30, 0x59,
+ 0x2f, 0xea, 0xa1, 0x82, 0xe3, 0x3e, 0x54, 0x2b, 0x91, 0x87, 0x94, 0x53,
+ 0xf3, 0x50, 0xbb, 0xf6, 0xcf, 0x77, 0xa4, 0xda, 0xe3, 0x7b, 0xe5, 0xb8,
+ 0xe3, 0xde, 0xaf, 0xf4, 0x59, 0xdb, 0x82, 0xc7, 0x58, 0xdf, 0x71, 0x27,
+ 0x72, 0x7f, 0xd4, 0x9e, 0xd3, 0x37, 0xf1, 0xbd, 0x59, 0xcd, 0xf7, 0xdf,
+ 0x58, 0x47, 0x9c, 0xcd, 0x0a, 0xf1, 0xf1, 0x59, 0xc8, 0xad, 0x4f, 0x4b,
+ 0x76, 0x34, 0x31, 0x57, 0xc6, 0xec, 0xb3, 0xdf, 0xb0, 0xce, 0xf0, 0x0b,
+ 0xcb, 0xbc, 0xe2, 0xf0, 0xce, 0x1c, 0xa3, 0x33, 0x3e, 0xdf, 0x12, 0xee,
+ 0xb9, 0x37, 0x73, 0xca, 0xfc, 0xc6, 0x75, 0x52, 0xff, 0x0a, 0xe6, 0x8b,
+ 0xfd, 0x11, 0x57, 0xab, 0xf4, 0x3d, 0x05, 0x9e, 0x6c, 0x89, 0xd7, 0xcd,
+ 0xd9, 0x43, 0x46, 0xf6, 0xd6, 0x01, 0x6e, 0xc0, 0x6f, 0xec, 0x3b, 0x21,
+ 0x9d, 0x0a, 0x24, 0x37, 0x69, 0xb6, 0xa3, 0x67, 0x87, 0x98, 0x39, 0x33,
+ 0x34, 0xb3, 0xc2, 0xd8, 0x91, 0xf8, 0x36, 0x74, 0xa1, 0x64, 0xfb, 0xd8,
+ 0x4b, 0x4e, 0x3f, 0xcf, 0x3c, 0x8a, 0xb6, 0x1b, 0x97, 0xb3, 0x09, 0xc1,
+ 0x4b, 0xcf, 0x5b, 0xff, 0x32, 0x08, 0xc6, 0x52, 0x29, 0xde, 0x2b, 0xb8,
+ 0x8c, 0x4f, 0xb9, 0xca, 0x99, 0x1c, 0x6d, 0x70, 0x26, 0x46, 0x03, 0xd9,
+ 0x93, 0xe2, 0x9d, 0x49, 0xdc, 0x93, 0xa0, 0xe3, 0xe3, 0x48, 0x6b, 0x87,
+ 0x6e, 0x7d, 0xc7, 0x3a, 0xee, 0x71, 0xbb, 0xd9, 0x6f, 0xb4, 0xe5, 0x88,
+ 0x63, 0xfa, 0xca, 0xed, 0x27, 0x72, 0xc2, 0xbb, 0x8b, 0xb6, 0xc4, 0x63,
+ 0x7a, 0x7f, 0xe2, 0x17, 0x50, 0x0f, 0x7d, 0x94, 0xd8, 0xaf, 0xeb, 0x4c,
+ 0x40, 0x9e, 0x4d, 0x8e, 0xf1, 0xbe, 0x14, 0x9e, 0x63, 0x88, 0xb4, 0x2a,
+ 0xb9, 0xd6, 0x1b, 0xb6, 0xf7, 0x69, 0xe6, 0xe1, 0x0a, 0x45, 0x74, 0xda,
+ 0x16, 0x6f, 0xf7, 0xdc, 0x1d, 0x9b, 0x61, 0x5a, 0x78, 0xd7, 0xa6, 0xd2,
+ 0x67, 0x56, 0xe0, 0xd3, 0x9e, 0x1e, 0x92, 0xb8, 0x33, 0x55, 0x6c, 0x75,
+ 0x4e, 0x16, 0x33, 0x5b, 0xd7, 0x81, 0x3e, 0xce, 0xa7, 0x3e, 0x46, 0xf9,
+ 0x05, 0xdb, 0xef, 0x45, 0xc9, 0x57, 0x3e, 0x24, 0xe3, 0x2d, 0xed, 0xde,
+ 0xfd, 0x7a, 0x6e, 0x2e, 0x03, 0x67, 0x2d, 0x2a, 0x3b, 0xfa, 0xc4, 0x3a,
+ 0xea, 0xb7, 0xdd, 0x45, 0x05, 0x5e, 0x56, 0xbf, 0x88, 0x07, 0x36, 0x6e,
+ 0xad, 0xb6, 0x51, 0xf6, 0xa6, 0x58, 0xae, 0xc1, 0xe9, 0x1d, 0x5d, 0x85,
+ 0x79, 0xdc, 0x05, 0xfd, 0xe9, 0xc0, 0x46, 0x22, 0xae, 0x1b, 0x9c, 0x3d,
+ 0xa3, 0x79, 0xf4, 0xc8, 0x7d, 0xd6, 0xbc, 0xf7, 0xf0, 0x30, 0xc6, 0xa8,
+ 0xe5, 0x2b, 0x78, 0xf7, 0x12, 0xd7, 0xdb, 0x83, 0x49, 0xd8, 0x06, 0xb9,
+ 0xae, 0x7f, 0x67, 0xd7, 0xab, 0xa7, 0xaf, 0xb0, 0x5e, 0xed, 0xc9, 0x23,
+ 0x15, 0x7d, 0x6f, 0x48, 0xe7, 0xb8, 0xe2, 0x3a, 0x6e, 0xf3, 0x55, 0x7a,
+ 0x7e, 0x54, 0x87, 0xdd, 0x1b, 0x78, 0x72, 0x9d, 0xbd, 0xd3, 0x06, 0x70,
+ 0x5c, 0x05, 0x18, 0x36, 0x62, 0xfc, 0x84, 0xc1, 0xd4, 0x11, 0x75, 0x4b,
+ 0x9c, 0x3a, 0x70, 0x56, 0x4e, 0xaf, 0x0b, 0xf7, 0x7b, 0xa0, 0x1d, 0xc8,
+ 0xb5, 0x47, 0xe3, 0x46, 0x37, 0xae, 0x5d, 0xa6, 0x9d, 0x70, 0x3c, 0x8e,
+ 0x1d, 0x0f, 0x69, 0x75, 0x43, 0x0b, 0xfd, 0x89, 0x59, 0xa9, 0x5b, 0x54,
+ 0x9e, 0xf1, 0xfc, 0x5d, 0xad, 0x66, 0xdf, 0x11, 0xcb, 0x7a, 0xb0, 0x4b,
+ 0x69, 0xe3, 0x12, 0x77, 0x7a, 0xae, 0x8a, 0xdc, 0x5b, 0x9c, 0xf3, 0x2f,
+ 0x43, 0x9e, 0x5c, 0xeb, 0xbd, 0x4d, 0x91, 0xf6, 0x42, 0xfc, 0x12, 0xb7,
+ 0x09, 0xe0, 0x95, 0x71, 0x95, 0xd3, 0x41, 0x66, 0x80, 0x7c, 0xc5, 0x36,
+ 0x98, 0xff, 0xa2, 0x8e, 0xe5, 0x0e, 0xa6, 0x18, 0x27, 0x6a, 0x3f, 0x71,
+ 0x87, 0x0a, 0x65, 0xd3, 0x2c, 0xd7, 0x10, 0x1c, 0xde, 0x21, 0xba, 0x0b,
+ 0x1d, 0x5e, 0x9c, 0x52, 0xce, 0x37, 0xc7, 0x5c, 0x7c, 0xd7, 0xd8, 0xfb,
+ 0x42, 0x8d, 0x6e, 0x12, 0xf9, 0xeb, 0x70, 0xbc, 0xf1, 0x3c, 0xe6, 0xfb,
+ 0x12, 0xe6, 0x7b, 0xf9, 0xfb, 0x41, 0x91, 0x57, 0x46, 0x5e, 0xf9, 0x43,
+ 0x41, 0xa6, 0x89, 0xf4, 0x47, 0x9a, 0x7b, 0x3d, 0x9f, 0x59, 0xef, 0x63,
+ 0x02, 0x6c, 0x67, 0xc1, 0x0b, 0x19, 0xae, 0x25, 0x07, 0xc7, 0x52, 0x37,
+ 0x81, 0x17, 0x76, 0xca, 0x9f, 0xc0, 0x16, 0xf8, 0xe3, 0x4a, 0x1a, 0x3c,
+ 0xd1, 0x03, 0x1e, 0xe9, 0x06, 0x5f, 0xa4, 0xb4, 0x5d, 0xfc, 0x28, 0x74,
+ 0xde, 0xd9, 0x4a, 0xc9, 0xd9, 0x3b, 0x5a, 0x74, 0x72, 0xa3, 0x47, 0x41,
+ 0x17, 0xdc, 0x03, 0xab, 0xae, 0xa9, 0x11, 0x37, 0x3e, 0x29, 0xa4, 0xff,
+ 0x76, 0xee, 0xed, 0x68, 0x06, 0xae, 0xce, 0x10, 0x57, 0x93, 0x95, 0x2d,
+ 0xde, 0x3a, 0xf0, 0x41, 0xb3, 0xe6, 0x83, 0x46, 0x27, 0xe3, 0xdd, 0x64,
+ 0xf9, 0x60, 0x04, 0x7c, 0x50, 0x58, 0xc2, 0x07, 0xcf, 0x58, 0x9a, 0x9f,
+ 0xae, 0xe2, 0x83, 0x49, 0x9b, 0x36, 0x7e, 0x05, 0x3e, 0xb8, 0xca, 0x4f,
+ 0x3e, 0x39, 0x24, 0x27, 0xc0, 0x07, 0x0f, 0x6b, 0x3e, 0xb8, 0x4a, 0xf3,
+ 0x01, 0xe3, 0x46, 0xe4, 0x85, 0x56, 0xc8, 0x0e, 0xf2, 0xc2, 0xb3, 0x32,
+ 0x0b, 0x5e, 0x78, 0x51, 0xb1, 0xef, 0xcb, 0xb4, 0x0f, 0x46, 0xe9, 0x8f,
+ 0x9d, 0x2a, 0x15, 0xc1, 0xbb, 0x4a, 0xbe, 0x30, 0x16, 0x04, 0x33, 0xf0,
+ 0xd1, 0x1f, 0x84, 0x0d, 0xef, 0xea, 0x3b, 0x69, 0xa7, 0x61, 0xbb, 0x10,
+ 0x36, 0xda, 0xe4, 0xe3, 0x0e, 0xe8, 0xfd, 0xf0, 0x04, 0xc6, 0xb0, 0x47,
+ 0xfd, 0x3e, 0xfc, 0x60, 0x0f, 0xf3, 0x4a, 0xdb, 0xfe, 0xb8, 0xe6, 0x9b,
+ 0x1a, 0xe8, 0x80, 0x93, 0xdd, 0x8c, 0x33, 0xf9, 0xde, 0x5e, 0xd5, 0x9e,
+ 0xef, 0x03, 0xcc, 0x11, 0x75, 0xbf, 0x30, 0xc6, 0xd1, 0xb4, 0xc8, 0xb6,
+ 0xa7, 0x5c, 0x18, 0x90, 0xfb, 0x6c, 0x5e, 0x3e, 0xa8, 0x83, 0x1d, 0x5a,
+ 0xa7, 0x8c, 0x5d, 0xae, 0xb6, 0x25, 0xbd, 0xdf, 0x80, 0xd0, 0xac, 0x4d,
+ 0x9b, 0x3d, 0x81, 0x7d, 0xc5, 0x6a, 0xbb, 0xfe, 0x5e, 0xd8, 0xf5, 0xac,
+ 0x23, 0xae, 0xb1, 0xeb, 0xef, 0xb2, 0xbc, 0xc6, 0xdf, 0x9e, 0xb6, 0xf1,
+ 0x0f, 0x00, 0xbe, 0x1d, 0x73, 0x36, 0x3e, 0xdb, 0xa0, 0xad, 0x21, 0x72,
+ 0x03, 0xec, 0xbc, 0x1b, 0xc1, 0x83, 0x37, 0xc1, 0x8f, 0x7a, 0x77, 0xd1,
+ 0x93, 0x9d, 0xc5, 0x66, 0xf8, 0xdb, 0xad, 0xf2, 0xab, 0x63, 0x1b, 0xa5,
+ 0x7f, 0xf4, 0x77, 0x9a, 0xa1, 0x57, 0x61, 0x97, 0xbe, 0x08, 0x38, 0x23,
+ 0x56, 0x56, 0x47, 0xc1, 0x03, 0xed, 0x89, 0x1f, 0xa8, 0x44, 0xab, 0x91,
+ 0xed, 0x3c, 0x4b, 0xbe, 0x5c, 0x3b, 0x31, 0xd4, 0x67, 0x1c, 0xa5, 0x45,
+ 0xce, 0x1c, 0xa7, 0xe7, 0x95, 0x80, 0x2d, 0x9e, 0x82, 0x1d, 0xb2, 0x01,
+ 0xed, 0x31, 0x96, 0xbc, 0x5a, 0x9e, 0xd9, 0xea, 0xde, 0x9d, 0xd3, 0x7c,
+ 0x78, 0xc9, 0xc9, 0x8e, 0xdd, 0x24, 0x85, 0xc1, 0x28, 0xc6, 0xa0, 0x9a,
+ 0xd7, 0xca, 0xf5, 0xd2, 0xaf, 0xc7, 0x73, 0x59, 0x0e, 0x42, 0x1f, 0xff,
+ 0x69, 0xb1, 0x5f, 0x66, 0x07, 0x9a, 0xf0, 0x1d, 0x95, 0x67, 0x8a, 0x5b,
+ 0xe0, 0xef, 0xfc, 0x0a, 0x70, 0x54, 0x8b, 0xef, 0x5a, 0xe9, 0x5d, 0x47,
+ 0x5e, 0x6d, 0x90, 0x19, 0xa4, 0xdf, 0x28, 0xbf, 0x64, 0xd3, 0x99, 0x46,
+ 0xde, 0x68, 0x40, 0xdd, 0xa8, 0x9c, 0x2f, 0xd2, 0x96, 0xd4, 0x3c, 0xd1,
+ 0xf3, 0xb2, 0x6c, 0xc9, 0xbc, 0x0c, 0xdb, 0xf4, 0x59, 0x3c, 0xcf, 0x4b,
+ 0x72, 0xe7, 0x6e, 0x67, 0x4b, 0xa2, 0xdd, 0x81, 0xbe, 0xc4, 0xe3, 0x3a,
+ 0x5b, 0xbc, 0x5a, 0xe7, 0x5a, 0xdb, 0x46, 0x8d, 0x3c, 0x3f, 0xa8, 0xe2,
+ 0x0d, 0x98, 0x93, 0xcd, 0x4e, 0x87, 0x4d, 0xe3, 0xb7, 0xbe, 0x2f, 0x51,
+ 0xda, 0xcf, 0xa8, 0x0d, 0xab, 0x44, 0xda, 0x1a, 0x60, 0xe7, 0xec, 0x11,
+ 0xd5, 0xdc, 0x20, 0xae, 0xb4, 0x4f, 0xa8, 0x56, 0xa4, 0xf9, 0x36, 0x2d,
+ 0xd6, 0x00, 0x9d, 0x80, 0xb4, 0x16, 0xa4, 0x6d, 0xb2, 0x69, 0x4d, 0x0d,
+ 0x52, 0x8b, 0xb4, 0xcb, 0x9a, 0xe7, 0x2f, 0x76, 0xf8, 0x5e, 0xce, 0xa9,
+ 0x97, 0xb6, 0x53, 0x0d, 0x90, 0x0d, 0xab, 0x65, 0x66, 0x6b, 0x9d, 0xb4,
+ 0x21, 0x8f, 0x31, 0xee, 0xd4, 0xa9, 0xa8, 0xbc, 0xf3, 0x54, 0x7b, 0xfc,
+ 0xa3, 0x18, 0x43, 0xfb, 0x19, 0xc6, 0xbc, 0xff, 0xac, 0x99, 0x31, 0x9f,
+ 0xb6, 0x33, 0x7c, 0xd7, 0x69, 0xf9, 0x43, 0x7c, 0x98, 0x3b, 0xdf, 0x60,
+ 0x63, 0x94, 0x8e, 0x3b, 0xc3, 0xa3, 0xd4, 0xdb, 0xed, 0xf6, 0x7e, 0xa2,
+ 0xff, 0xd9, 0x4c, 0x5f, 0x6d, 0x82, 0x36, 0x54, 0x89, 0xfc, 0x48, 0xdd,
+ 0x83, 0xf7, 0xb8, 0x23, 0x85, 0x79, 0x99, 0x35, 0x45, 0xbe, 0x3a, 0xae,
+ 0xb8, 0x4f, 0x05, 0x69, 0x95, 0x77, 0x05, 0x66, 0x8e, 0xc9, 0x0b, 0x46,
+ 0x2e, 0xfd, 0x9a, 0x91, 0x4b, 0xa7, 0xcf, 0x2d, 0x90, 0x4b, 0x05, 0x2d,
+ 0x97, 0x06, 0x05, 0xef, 0xa9, 0x02, 0xe4, 0xd2, 0x08, 0xbe, 0x3d, 0x2d,
+ 0x97, 0x62, 0x62, 0x6d, 0x64, 0x89, 0x5e, 0xc5, 0xfe, 0x27, 0x4b, 0xae,
+ 0xb6, 0xa5, 0x0a, 0xe3, 0xb0, 0x43, 0x4a, 0x23, 0x56, 0x67, 0x4b, 0xba,
+ 0x49, 0x3a, 0x7a, 0x7e, 0x2a, 0xa1, 0x9d, 0x39, 0xdb, 0xcc, 0x3b, 0x8f,
+ 0x5f, 0x54, 0x94, 0x61, 0x27, 0x20, 0xc3, 0x1e, 0xbe, 0x82, 0x0c, 0x43,
+ 0x5e, 0x19, 0x79, 0x65, 0xb6, 0xfb, 0xdd, 0x9f, 0x0e, 0x79, 0x94, 0x1f,
+ 0x94, 0x19, 0x90, 0x49, 0x25, 0xc8, 0xa4, 0x12, 0xe4, 0x54, 0x09, 0x72,
+ 0xa9, 0x04, 0xb9, 0x54, 0x82, 0x5c, 0x2a, 0x41, 0x2e, 0x41, 0xc6, 0x3d,
+ 0x0a, 0x19, 0x67, 0x64, 0xda, 0x00, 0xed, 0x35, 0xb9, 0xcf, 0xea, 0x77,
+ 0x13, 0x27, 0xe9, 0xb2, 0x7e, 0x91, 0xd9, 0xb3, 0x7a, 0xae, 0x2a, 0x2e,
+ 0xb8, 0xeb, 0x88, 0xe6, 0x77, 0xcf, 0x57, 0xd7, 0x3a, 0xdc, 0x1f, 0xf3,
+ 0x03, 0xed, 0xb3, 0x6f, 0xe6, 0x6f, 0xa9, 0x03, 0x5f, 0xbf, 0x62, 0xf9,
+ 0x7a, 0xf3, 0x1c, 0x5f, 0x27, 0x1d, 0xc6, 0x89, 0x97, 0xe7, 0xeb, 0x16,
+ 0x9b, 0x97, 0x0f, 0x56, 0x80, 0xaf, 0x57, 0x2c, 0xe2, 0xeb, 0x28, 0xf8,
+ 0x7a, 0xe7, 0x12, 0xbe, 0x5e, 0xe5, 0xf4, 0xea, 0x3a, 0x3c, 0x83, 0xc6,
+ 0xef, 0x5a, 0x67, 0x9e, 0xaf, 0xf7, 0x6b, 0xbe, 0x3e, 0x04, 0xbe, 0xbe,
+ 0xbe, 0x8a, 0xaf, 0x77, 0x4a, 0xf2, 0x96, 0x6c, 0x64, 0xa3, 0xec, 0xbe,
+ 0x5f, 0x35, 0xaf, 0x91, 0x7f, 0x11, 0x53, 0xdf, 0xf0, 0x58, 0xef, 0x58,
+ 0xb3, 0xe4, 0x1e, 0xfa, 0x11, 0xd7, 0x06, 0xc8, 0x23, 0x43, 0x19, 0xc7,
+ 0x93, 0x83, 0x47, 0x7e, 0x20, 0xd3, 0x9a, 0xb7, 0x44, 0xf6, 0x1c, 0x89,
+ 0xca, 0xf0, 0x11, 0xc6, 0x1e, 0xbe, 0x63, 0xe9, 0xbd, 0x4e, 0x86, 0x07,
+ 0xb9, 0x5f, 0xd2, 0x95, 0xdd, 0x47, 0xe0, 0x63, 0x1d, 0x61, 0xec, 0xe1,
+ 0xf2, 0x1c, 0x8f, 0x4d, 0x43, 0xb6, 0xec, 0x3e, 0xa2, 0xe7, 0x1a, 0xed,
+ 0x34, 0xc8, 0xa1, 0x23, 0x22, 0xb7, 0x1d, 0x71, 0xe5, 0xf6, 0x23, 0x73,
+ 0xbc, 0x36, 0x10, 0xf2, 0xda, 0x9f, 0x83, 0xd7, 0xda, 0x2d, 0xaf, 0xa9,
+ 0x39, 0x5e, 0xfb, 0x5a, 0x15, 0xaf, 0xb1, 0x3e, 0x79, 0xed, 0x82, 0x4d,
+ 0xe3, 0xb7, 0x2b, 0x7b, 0x8f, 0xb4, 0xca, 0xee, 0x87, 0xde, 0x22, 0x7b,
+ 0xee, 0x27, 0xac, 0xe6, 0x9e, 0x3c, 0xda, 0x5f, 0xe3, 0x95, 0x76, 0xb4,
+ 0x1f, 0xee, 0x0f, 0xd2, 0x77, 0x65, 0x75, 0x4e, 0x48, 0x32, 0xcf, 0xfe,
+ 0x6a, 0xe1, 0x3b, 0x9f, 0x82, 0x4f, 0xb1, 0x17, 0x30, 0xdd, 0x7a, 0x44,
+ 0x92, 0xae, 0xbc, 0x26, 0x23, 0xa9, 0x47, 0x5b, 0x8d, 0x3d, 0x71, 0x09,
+ 0xbc, 0x42, 0xfa, 0xcf, 0x48, 0xee, 0xed, 0x81, 0xf6, 0x2b, 0x46, 0xcb,
+ 0x42, 0xff, 0x9f, 0x31, 0x73, 0xc7, 0xdc, 0x77, 0xc7, 0xf3, 0xbe, 0x35,
+ 0xfa, 0xbc, 0x9b, 0x8e, 0xd7, 0x76, 0x33, 0xbf, 0x46, 0xef, 0x37, 0xcd,
+ 0xe9, 0xb3, 0xdc, 0xac, 0xcf, 0x76, 0x62, 0x3a, 0x9e, 0x5e, 0x28, 0xf3,
+ 0x8e, 0x30, 0xde, 0xbd, 0xcc, 0xbb, 0x06, 0xff, 0xf8, 0x2a, 0x13, 0x9b,
+ 0x25, 0xdf, 0x7d, 0xdd, 0xc9, 0x15, 0x2f, 0xe9, 0x7d, 0x85, 0x59, 0x1f,
+ 0xbf, 0xcb, 0xfc, 0x66, 0xf9, 0x4b, 0x8c, 0x71, 0x24, 0x12, 0xea, 0x81,
+ 0x56, 0xee, 0x3b, 0x18, 0x9c, 0x32, 0x76, 0x94, 0xe1, 0xd1, 0x06, 0xed,
+ 0x6b, 0x8c, 0xe0, 0x7b, 0xf7, 0x68, 0xa3, 0x53, 0xa0, 0x6d, 0x32, 0xd0,
+ 0xe0, 0xe4, 0xc7, 0xf7, 0xb4, 0x1a, 0x9b, 0x79, 0x20, 0xce, 0x3d, 0x85,
+ 0x19, 0xb5, 0x54, 0x26, 0x9f, 0x92, 0x50, 0x26, 0x27, 0x6f, 0xc9, 0xc0,
+ 0xb6, 0xce, 0x1d, 0xd1, 0xf7, 0xf7, 0x25, 0xda, 0x15, 0xc7, 0xf4, 0x09,
+ 0xc8, 0xd7, 0x90, 0x16, 0xe2, 0xf2, 0xf1, 0x23, 0xa4, 0x07, 0x15, 0x6b,
+ 0x94, 0xdf, 0xb2, 0xf4, 0x70, 0x59, 0x8a, 0x90, 0x3b, 0x47, 0x8e, 0xdc,
+ 0x2e, 0xe3, 0xbb, 0x16, 0xd3, 0xc3, 0x9e, 0x79, 0x7a, 0x88, 0xc1, 0x3e,
+ 0x73, 0xaa, 0xe9, 0xe1, 0x37, 0xe7, 0xe8, 0x61, 0xdc, 0xf9, 0xd7, 0xd2,
+ 0xc3, 0x0d, 0x0b, 0xe8, 0x61, 0x44, 0xd3, 0x43, 0xff, 0x1c, 0x3d, 0x8c,
+ 0x1c, 0x61, 0xbf, 0x7a, 0x5d, 0xd4, 0x9b, 0x71, 0x38, 0xe7, 0x73, 0xb4,
+ 0x90, 0x18, 0xd6, 0xfb, 0x44, 0x93, 0x79, 0x9e, 0x25, 0x5d, 0xa5, 0x18,
+ 0x1b, 0x99, 0x9f, 0xff, 0xc6, 0x7f, 0xd3, 0xf9, 0x7f, 0x47, 0xfc, 0xff,
+ 0xef, 0xfc, 0x5f, 0x8f, 0xf6, 0x29, 0x8b, 0x43, 0x79, 0x1c, 0xd2, 0xc3,
+ 0x7b, 0xe2, 0x46, 0x2f, 0x70, 0x8e, 0xf9, 0x6d, 0xf6, 0xac, 0x9f, 0x83,
+ 0xfc, 0x7b, 0x1c, 0xf2, 0xef, 0xb1, 0x05, 0xeb, 0x01, 0x3d, 0x36, 0x06,
+ 0x11, 0xc8, 0xc1, 0xd4, 0x3c, 0x3e, 0x66, 0xba, 0x89, 0x0f, 0xb3, 0xf7,
+ 0xe4, 0x6c, 0x65, 0x31, 0x4e, 0x5c, 0xbd, 0xdf, 0xe8, 0x64, 0xaa, 0x1a,
+ 0x27, 0x84, 0x7b, 0xb6, 0x6a, 0x8c, 0xf8, 0x5d, 0xe6, 0xf7, 0x65, 0xbd,
+ 0x87, 0xa4, 0xa0, 0xd7, 0x9f, 0x88, 0x17, 0xae, 0x3f, 0x11, 0x27, 0xae,
+ 0xb6, 0xf7, 0x0b, 0xe5, 0x3a, 0xbd, 0x2f, 0xfc, 0xc0, 0x54, 0x4c, 0x66,
+ 0x62, 0x8c, 0xeb, 0xf1, 0xde, 0x57, 0xfa, 0xca, 0x7e, 0xbc, 0x20, 0x79,
+ 0x7b, 0xd6, 0x67, 0x95, 0xa5, 0x6d, 0xc6, 0x03, 0x79, 0x27, 0x42, 0xb8,
+ 0x0e, 0xd1, 0x69, 0x65, 0x5d, 0x43, 0x55, 0x9c, 0x12, 0x78, 0x1f, 0x93,
+ 0x44, 0xb6, 0x1b, 0xef, 0x29, 0xf6, 0xfd, 0xa4, 0x8c, 0x3c, 0x58, 0x86,
+ 0x2d, 0xf7, 0x30, 0x74, 0x8e, 0x23, 0x10, 0x93, 0xfa, 0x2e, 0x14, 0xc2,
+ 0x30, 0xa1, 0xef, 0xf5, 0xa3, 0xdf, 0x47, 0x7a, 0x88, 0xe3, 0xfb, 0xb2,
+ 0x8d, 0x25, 0xc5, 0xa5, 0x50, 0xfc, 0x01, 0xe0, 0xe7, 0x1d, 0x94, 0x3f,
+ 0xc2, 0xfb, 0x8d, 0xe6, 0xc3, 0xf8, 0x21, 0x03, 0xfa, 0xcd, 0xb9, 0x79,
+ 0xcd, 0xc9, 0x94, 0xcd, 0xfe, 0x96, 0xaa, 0xfb, 0xf5, 0xe5, 0xb0, 0xb6,
+ 0x9f, 0xd3, 0x76, 0x5f, 0x0b, 0xcf, 0xe7, 0x19, 0x1b, 0xfa, 0xcb, 0xb0,
+ 0xa1, 0x9f, 0xa8, 0x64, 0xf4, 0x1a, 0xd6, 0x63, 0xb0, 0xa1, 0x1f, 0x85,
+ 0xee, 0xa1, 0xce, 0x89, 0x59, 0x9d, 0x33, 0xa2, 0x76, 0x69, 0x9d, 0xf3,
+ 0xd7, 0x5a, 0xe7, 0xfc, 0xea, 0x12, 0x9d, 0x73, 0x48, 0xb5, 0x8f, 0x52,
+ 0xe7, 0xf4, 0xaa, 0x9d, 0x0e, 0xed, 0xc5, 0xb5, 0xcb, 0xe8, 0x9c, 0xf7,
+ 0xca, 0xaf, 0xd8, 0xbc, 0xfd, 0xf2, 0xbe, 0x6d, 0x7a, 0xdd, 0xc6, 0x9b,
+ 0x50, 0xbc, 0xcb, 0xce, 0xe8, 0xa0, 0xeb, 0x55, 0xa7, 0x5e, 0xef, 0xfd,
+ 0x6a, 0x95, 0xce, 0x69, 0x53, 0xdd, 0x4e, 0xaf, 0xae, 0xc3, 0x78, 0x04,
+ 0xbf, 0x53, 0x4e, 0x66, 0xa0, 0x0e, 0xdf, 0x71, 0x89, 0x1c, 0xc1, 0xd8,
+ 0xcd, 0x7d, 0x7b, 0xca, 0xe4, 0x5d, 0x63, 0xf3, 0x54, 0x98, 0xee, 0x9a,
+ 0xf4, 0x76, 0x9b, 0x6e, 0x74, 0x55, 0x9b, 0x6a, 0xd5, 0xba, 0x6a, 0x33,
+ 0x18, 0x6a, 0x02, 0xfa, 0x75, 0xa2, 0x14, 0xea, 0x2c, 0xfe, 0x66, 0xbc,
+ 0x99, 0x71, 0x89, 0x30, 0x6e, 0x9d, 0x40, 0x19, 0x3c, 0xa5, 0xd0, 0xa6,
+ 0xe4, 0x6f, 0xf8, 0x0a, 0x78, 0xa6, 0x80, 0xd7, 0x5b, 0xc0, 0x3f, 0xbf,
+ 0x5e, 0x64, 0xdc, 0xb3, 0x59, 0x8e, 0x8e, 0x55, 0xe7, 0xb5, 0xca, 0xbb,
+ 0xc7, 0x36, 0xc8, 0xbe, 0x51, 0xff, 0x6a, 0xa9, 0xdf, 0x28, 0x23, 0xa3,
+ 0x2f, 0xea, 0xfb, 0x40, 0xd6, 0xe8, 0x7b, 0x92, 0x78, 0x7f, 0x98, 0x91,
+ 0x91, 0xfd, 0x8e, 0x91, 0x91, 0x19, 0x35, 0x6f, 0xb3, 0x86, 0x6d, 0xf2,
+ 0x6e, 0xa6, 0xbe, 0xd1, 0xb8, 0xbe, 0x43, 0x7a, 0xa2, 0x72, 0xad, 0xfc,
+ 0xd1, 0x71, 0x75, 0xa7, 0x9a, 0xbf, 0x4b, 0x41, 0xdb, 0xac, 0x93, 0x0b,
+ 0x6c, 0xd6, 0xbf, 0x97, 0x99, 0xf7, 0x45, 0x31, 0x4e, 0xd0, 0xf0, 0x75,
+ 0x2f, 0x73, 0x1d, 0xb4, 0x39, 0x26, 0x97, 0xa4, 0x4f, 0xe3, 0x8f, 0xf2,
+ 0xb4, 0x01, 0x72, 0x70, 0x56, 0xeb, 0xd7, 0xb5, 0xbc, 0xf3, 0xf8, 0x08,
+ 0x6d, 0xd7, 0xaf, 0x6b, 0x79, 0xb6, 0xd6, 0xda, 0xae, 0xd3, 0x90, 0xd3,
+ 0x94, 0xa3, 0x37, 0xca, 0x5f, 0xdb, 0x74, 0xa6, 0x25, 0xe3, 0xb3, 0x42,
+ 0x7d, 0x17, 0x83, 0x0c, 0xa5, 0x3c, 0xfd, 0x59, 0x6d, 0xd7, 0xe7, 0x6c,
+ 0x1b, 0x94, 0x9f, 0x46, 0x76, 0x6f, 0x76, 0xa6, 0x6d, 0x1a, 0xbf, 0xc3,
+ 0x18, 0xba, 0x9f, 0xc9, 0x59, 0x3e, 0x53, 0xce, 0x93, 0xc8, 0x5f, 0x83,
+ 0x7c, 0xf2, 0xd9, 0x63, 0x9a, 0xcf, 0xb4, 0x7d, 0xe2, 0x74, 0xd9, 0x35,
+ 0x85, 0xb9, 0xf5, 0x80, 0x3c, 0xf9, 0x4c, 0x1d, 0xf5, 0xa6, 0x8d, 0x3c,
+ 0xf0, 0x90, 0xfe, 0x45, 0xe8, 0x0e, 0xd6, 0x45, 0xfa, 0xb1, 0x0c, 0xe6,
+ 0xf0, 0x24, 0xfc, 0x9f, 0x46, 0x7c, 0x37, 0xe3, 0x7b, 0x42, 0x7e, 0x75,
+ 0x30, 0xaa, 0xc7, 0x3d, 0x82, 0x71, 0x1c, 0x38, 0x82, 0x31, 0x39, 0xc6,
+ 0x76, 0x76, 0xcf, 0xb8, 0x52, 0x73, 0x86, 0x7c, 0xc7, 0x33, 0x86, 0x41,
+ 0xb0, 0xb7, 0x8b, 0x74, 0x9b, 0xf4, 0xfa, 0xf5, 0xf9, 0xb7, 0xcd, 0xf1,
+ 0x08, 0x70, 0x72, 0x00, 0xf3, 0x31, 0x52, 0xf4, 0xbd, 0xac, 0xe3, 0xc7,
+ 0x31, 0x4e, 0xd8, 0x80, 0xed, 0xb0, 0x05, 0xdb, 0x61, 0x07, 0xb6, 0xc3,
+ 0x0e, 0x5c, 0x2d, 0xa7, 0xb6, 0x72, 0x7f, 0x49, 0xfe, 0x9d, 0xbc, 0x77,
+ 0xf9, 0x1b, 0x3a, 0x36, 0x5f, 0x7b, 0x4b, 0x1f, 0x7c, 0x76, 0xf1, 0x92,
+ 0x03, 0xdc, 0x63, 0x3f, 0xeb, 0xd5, 0xde, 0xd2, 0x2f, 0xed, 0x3d, 0xc8,
+ 0xef, 0xb9, 0x24, 0x1d, 0xb7, 0x7c, 0xd8, 0xa9, 0x1d, 0xe8, 0x03, 0x1e,
+ 0x33, 0x4e, 0x32, 0x3e, 0xe4, 0x30, 0x4e, 0x91, 0xdd, 0x1c, 0xd1, 0x67,
+ 0xc4, 0xa6, 0x19, 0x8b, 0xb8, 0xa5, 0x3d, 0xb2, 0x25, 0xb1, 0xdb, 0x49,
+ 0x0e, 0xa8, 0x48, 0x72, 0xa0, 0xcf, 0x09, 0xcb, 0xf1, 0x0e, 0x6a, 0xc8,
+ 0x19, 0xc0, 0x7a, 0xa0, 0xf4, 0x75, 0xd0, 0xd3, 0x79, 0x29, 0x1c, 0x6f,
+ 0x90, 0xa9, 0x62, 0xbb, 0x97, 0x55, 0x31, 0xe1, 0xbe, 0x12, 0x75, 0x0a,
+ 0x44, 0x7f, 0x26, 0x2a, 0x13, 0xa3, 0x1b, 0x45, 0x69, 0xdb, 0xbd, 0x45,
+ 0xb2, 0x63, 0xa3, 0x72, 0xbe, 0x5b, 0x9a, 0x14, 0xda, 0xe7, 0xdd, 0xde,
+ 0xea, 0x14, 0xd7, 0x11, 0x43, 0x5e, 0x58, 0x4f, 0x3e, 0x19, 0x05, 0x0e,
+ 0x41, 0xb7, 0x8c, 0xeb, 0xd6, 0x09, 0xe5, 0xde, 0xed, 0x3a, 0x66, 0xca,
+ 0x38, 0x6d, 0xf5, 0x7a, 0x03, 0xf9, 0x23, 0xba, 0x2c, 0x7f, 0x4c, 0x96,
+ 0xb8, 0x36, 0x23, 0x79, 0x97, 0x71, 0x61, 0x1f, 0xbf, 0xc7, 0x59, 0xb6,
+ 0x4e, 0x46, 0xba, 0xf3, 0x76, 0x8f, 0xc7, 0x37, 0xc1, 0x07, 0x1c, 0x9f,
+ 0x5e, 0x27, 0x01, 0xaf, 0x2f, 0x5e, 0xcf, 0x88, 0x56, 0xc9, 0x03, 0x47,
+ 0x66, 0x46, 0xc3, 0xf5, 0x0f, 0xb6, 0x87, 0xef, 0x71, 0x23, 0x6f, 0xb3,
+ 0x4b, 0xea, 0x11, 0x2e, 0xae, 0x55, 0x2e, 0x94, 0xb1, 0x4a, 0x9f, 0x13,
+ 0xf6, 0xb4, 0x7c, 0x3d, 0x5d, 0x31, 0xb2, 0x75, 0xbc, 0x12, 0xea, 0x96,
+ 0xa8, 0xd1, 0xa5, 0x4b, 0xf4, 0x89, 0x89, 0x60, 0xce, 0xeb, 0x93, 0x4b,
+ 0x3a, 0x46, 0xf7, 0x6b, 0x53, 0x2d, 0xe2, 0x1e, 0x93, 0xd9, 0x11, 0xff,
+ 0x54, 0x2b, 0xf7, 0x69, 0x8c, 0xa4, 0xde, 0x8c, 0x7e, 0x8c, 0xb5, 0x50,
+ 0x1f, 0x0e, 0xa9, 0xb5, 0x78, 0xaf, 0xd1, 0xf4, 0x07, 0x9e, 0xc2, 0xb7,
+ 0xf1, 0x13, 0xbe, 0x0c, 0x3f, 0xe1, 0x09, 0xe8, 0xba, 0x73, 0xf0, 0x13,
+ 0x1e, 0x87, 0x9f, 0xf0, 0x18, 0xfc, 0x84, 0x47, 0xa1, 0x27, 0xab, 0xfd,
+ 0x83, 0xe1, 0x05, 0xfe, 0x41, 0xa0, 0xf9, 0x9f, 0x31, 0xc0, 0xc7, 0xab,
+ 0x7c, 0x83, 0xbd, 0x46, 0x5f, 0xc1, 0xef, 0x37, 0x7c, 0xd4, 0xa6, 0x6e,
+ 0xd6, 0xfa, 0xd1, 0xec, 0xd9, 0x1d, 0x98, 0xd3, 0x57, 0x6d, 0xca, 0xe8,
+ 0xab, 0x89, 0x79, 0x7d, 0x65, 0xf8, 0xe8, 0xd8, 0xa8, 0x44, 0xfc, 0xd1,
+ 0xe9, 0x6c, 0x6a, 0xbb, 0xe6, 0xa1, 0x26, 0x7f, 0xa3, 0x44, 0x1e, 0x50,
+ 0xcd, 0x35, 0x92, 0xb5, 0xdf, 0xa0, 0xaf, 0xa3, 0x5f, 0x47, 0x5b, 0xef,
+ 0x94, 0x9c, 0xb6, 0xcf, 0xae, 0x8c, 0xef, 0x47, 0x17, 0xe1, 0xbb, 0x50,
+ 0x7a, 0x56, 0xe3, 0xfc, 0x7e, 0x7d, 0x26, 0xbf, 0x41, 0x86, 0xcb, 0x21,
+ 0xce, 0x79, 0x06, 0x8e, 0xfb, 0x30, 0x5a, 0x25, 0x72, 0xac, 0x45, 0xfa,
+ 0x53, 0xa2, 0x72, 0xa9, 0x95, 0x7a, 0xff, 0xca, 0xa9, 0x6e, 0x89, 0xe7,
+ 0xba, 0x49, 0xab, 0xf7, 0xc9, 0x84, 0x9e, 0x8b, 0x16, 0xa9, 0x39, 0x46,
+ 0x1b, 0x25, 0x5c, 0xc3, 0xbb, 0xbd, 0xc5, 0xde, 0x41, 0x1d, 0x35, 0xe5,
+ 0x44, 0x0e, 0xea, 0xf9, 0x9a, 0xd5, 0x7b, 0x0c, 0x6f, 0x9e, 0x62, 0x2c,
+ 0x9e, 0xf7, 0xfd, 0x31, 0x0e, 0xff, 0xaf, 0x99, 0xbf, 0x42, 0x8b, 0xb1,
+ 0x67, 0xd6, 0x58, 0x3b, 0xc6, 0xc4, 0xa9, 0x96, 0xb7, 0x61, 0xd8, 0x4e,
+ 0xf5, 0x1d, 0xb5, 0xab, 0xe0, 0x03, 0x37, 0xa0, 0x4d, 0xae, 0x63, 0xdb,
+ 0xbf, 0x17, 0xe4, 0xfd, 0xb3, 0x73, 0xc0, 0x5f, 0x85, 0xb4, 0x06, 0xe4,
+ 0x31, 0x66, 0xf3, 0x85, 0x16, 0xc6, 0x65, 0xb3, 0x7e, 0xa3, 0x4d, 0x5b,
+ 0xe5, 0x8c, 0x8c, 0xb6, 0xc3, 0x37, 0xe7, 0x39, 0x76, 0xe6, 0xf7, 0x73,
+ 0xee, 0x84, 0x7f, 0xab, 0x69, 0x12, 0xf2, 0x67, 0x8f, 0x5c, 0x6b, 0xe3,
+ 0xce, 0xd4, 0xc3, 0xbf, 0xb8, 0x60, 0xbd, 0xf6, 0x10, 0xf4, 0xd8, 0xad,
+ 0x90, 0x47, 0xd4, 0xc3, 0x87, 0xe4, 0x17, 0x2c, 0x3d, 0x2f, 0xd4, 0xc3,
+ 0x17, 0x85, 0xb1, 0xe1, 0x2e, 0xe4, 0xe5, 0x83, 0x28, 0xe8, 0xe1, 0x70,
+ 0x95, 0xaf, 0x46, 0xbf, 0xaf, 0x2e, 0x6d, 0xd6, 0xc0, 0x16, 0xfa, 0x7d,
+ 0x90, 0x03, 0xb1, 0xd0, 0xcf, 0xab, 0x9d, 0x5b, 0xa3, 0xdd, 0x69, 0xeb,
+ 0x8e, 0xa4, 0x5e, 0x22, 0x8e, 0x12, 0x87, 0xe4, 0xf6, 0xf5, 0xbc, 0x26,
+ 0xcf, 0xf5, 0xbf, 0xa5, 0x71, 0x26, 0x8a, 0xb4, 0xb7, 0x46, 0xc3, 0x68,
+ 0xe5, 0x7c, 0x22, 0xdc, 0xbf, 0x51, 0xb0, 0x75, 0xf7, 0xd8, 0xf5, 0xf8,
+ 0x82, 0x7c, 0x9b, 0x71, 0xce, 0x44, 0x5f, 0x64, 0x25, 0xcf, 0x64, 0xa3,
+ 0xee, 0xed, 0xda, 0x6f, 0xcf, 0x48, 0xd8, 0x16, 0xbf, 0x6b, 0xaa, 0xda,
+ 0xa6, 0x1d, 0xc5, 0xf7, 0xe2, 0xfb, 0x1b, 0x9e, 0xd7, 0x6b, 0x8b, 0xe6,
+ 0x6e, 0x9a, 0x90, 0x4f, 0xc8, 0x3b, 0x09, 0x7d, 0x8e, 0xc9, 0x3f, 0x46,
+ 0xbb, 0x87, 0xeb, 0xae, 0xde, 0xf4, 0x70, 0xea, 0x23, 0xfa, 0x0e, 0xd5,
+ 0x71, 0x11, 0xa7, 0x90, 0xda, 0xab, 0xf7, 0x9d, 0x14, 0x74, 0x7c, 0x39,
+ 0x8f, 0xf7, 0xbc, 0x8f, 0xda, 0x76, 0x8c, 0x7f, 0x0b, 0x88, 0x69, 0x1f,
+ 0x04, 0x6c, 0xd4, 0x21, 0x94, 0xbd, 0x31, 0x69, 0x3b, 0xfa, 0x7e, 0xcd,
+ 0x0b, 0x6b, 0xe1, 0x0b, 0xf4, 0x1e, 0x85, 0xae, 0x3e, 0x1a, 0x97, 0xfe,
+ 0xa3, 0x5a, 0x37, 0x66, 0x96, 0xc6, 0x0a, 0xb6, 0x78, 0x2e, 0xfd, 0x89,
+ 0x98, 0x27, 0xd7, 0x1c, 0x8d, 0xc8, 0xe1, 0xd8, 0x16, 0xaf, 0xc3, 0xb9,
+ 0xd1, 0xea, 0x42, 0x43, 0x7f, 0xa0, 0x15, 0xd4, 0x37, 0xeb, 0x90, 0xbd,
+ 0xf3, 0xb1, 0x6b, 0xd4, 0x7f, 0x49, 0x46, 0xc8, 0x4b, 0x95, 0x88, 0x8c,
+ 0x0f, 0xb6, 0x02, 0x9e, 0xb7, 0xae, 0x07, 0x0e, 0x40, 0x53, 0x98, 0x1f,
+ 0xfd, 0xf7, 0x3c, 0xdc, 0x38, 0xe5, 0x57, 0x1b, 0xfa, 0xef, 0x3b, 0x4a,
+ 0x1d, 0xe6, 0x6b, 0xbe, 0x46, 0xbf, 0x5e, 0x8d, 0xf6, 0x3d, 0xc8, 0x8b,
+ 0x6f, 0x11, 0xff, 0x01, 0xc8, 0xb5, 0xa3, 0x51, 0xe9, 0x38, 0xda, 0x20,
+ 0x9b, 0x8e, 0xd2, 0xf7, 0xa8, 0xf6, 0x45, 0x69, 0x8b, 0x5e, 0xc2, 0xb8,
+ 0x6e, 0x34, 0xf7, 0x0d, 0x4e, 0x45, 0x65, 0x1f, 0xf9, 0x15, 0x65, 0x73,
+ 0xb0, 0x93, 0xb3, 0x47, 0x3d, 0xbd, 0x16, 0x9a, 0xc5, 0x38, 0xf9, 0x37,
+ 0x2c, 0xfa, 0x8e, 0x1a, 0x39, 0x53, 0xa0, 0x6f, 0x32, 0xd0, 0x02, 0xbc,
+ 0x3e, 0x60, 0xf9, 0xe5, 0x3d, 0xeb, 0x2d, 0x5f, 0xfe, 0x9c, 0xfc, 0x96,
+ 0x5b, 0x6f, 0xe4, 0xe5, 0x87, 0xd6, 0x73, 0x2f, 0xd2, 0x5a, 0x9f, 0xef,
+ 0x3a, 0x6d, 0x43, 0x18, 0xb9, 0xf9, 0x7a, 0xfc, 0x27, 0xc0, 0x51, 0xb8,
+ 0xfe, 0x44, 0x3e, 0xe4, 0x1a, 0xb2, 0x3e, 0xb3, 0x92, 0x9a, 0xd1, 0x7f,
+ 0x53, 0x89, 0x6b, 0x61, 0xf3, 0xf7, 0x59, 0x6d, 0xaf, 0x30, 0x36, 0xfe,
+ 0x4c, 0xf8, 0x37, 0x9c, 0xaa, 0xf6, 0x19, 0x56, 0xaf, 0x75, 0x31, 0xbe,
+ 0x34, 0xb7, 0x17, 0x28, 0x18, 0xd5, 0x77, 0xc2, 0xc5, 0x9c, 0x8b, 0xc5,
+ 0x5a, 0xe7, 0x9b, 0x63, 0x12, 0xb8, 0x7e, 0xdc, 0xf9, 0x96, 0xcf, 0xb5,
+ 0x71, 0xcf, 0x79, 0xb9, 0xe8, 0x83, 0xf7, 0xfe, 0x02, 0xe3, 0x68, 0x75,
+ 0x5e, 0xc1, 0x9c, 0x1e, 0x2c, 0x65, 0x92, 0x9e, 0x8d, 0x83, 0x3f, 0x5b,
+ 0x6c, 0x75, 0x9e, 0x9b, 0x8f, 0x21, 0xf5, 0x84, 0x74, 0x71, 0x88, 0x79,
+ 0x65, 0xe4, 0x95, 0x19, 0xeb, 0xad, 0x77, 0x26, 0xc7, 0xec, 0x7e, 0x12,
+ 0xa3, 0x8b, 0xe6, 0xd6, 0x5f, 0x06, 0xf4, 0xfa, 0x84, 0xeb, 0x4c, 0x4e,
+ 0x4d, 0xaf, 0x37, 0xfb, 0x8a, 0x6a, 0x91, 0x67, 0xf6, 0x58, 0x4e, 0x4c,
+ 0xd5, 0xa2, 0x4c, 0xbd, 0x33, 0xa1, 0x63, 0x5e, 0xda, 0xf6, 0x70, 0xc6,
+ 0xa7, 0xea, 0x9d, 0x29, 0xbd, 0xd6, 0x1c, 0x75, 0x4e, 0x8e, 0xb1, 0xed,
+ 0x28, 0xca, 0x88, 0x73, 0x0a, 0xed, 0x4d, 0x8d, 0xb5, 0xc7, 0xf7, 0x49,
+ 0x3b, 0x6c, 0x01, 0xfe, 0x8d, 0x34, 0xde, 0x17, 0xe0, 0x3a, 0x53, 0x73,
+ 0xed, 0x2a, 0xb4, 0xc3, 0xb2, 0xa4, 0x41, 0xf6, 0xeb, 0xa2, 0xfd, 0xa5,
+ 0x6b, 0x52, 0x4b, 0x71, 0x32, 0x06, 0x9c, 0x1c, 0xb4, 0x38, 0x39, 0x61,
+ 0x71, 0x32, 0x5a, 0x85, 0x93, 0x87, 0x17, 0xe1, 0xe4, 0x04, 0x70, 0xf2,
+ 0xf0, 0x15, 0x70, 0x82, 0xbc, 0xf2, 0xc3, 0x16, 0x27, 0xf7, 0x2d, 0xc2,
+ 0x49, 0x7e, 0x2e, 0x16, 0x6f, 0x70, 0x32, 0x02, 0x9c, 0xd4, 0xb4, 0x1a,
+ 0xd8, 0x0f, 0x5a, 0x9c, 0xe0, 0x3d, 0x75, 0x10, 0x65, 0xee, 0xab, 0xc2,
+ 0xc9, 0x41, 0xe0, 0xe4, 0x3e, 0x8b, 0x93, 0xc3, 0x16, 0x27, 0x87, 0x51,
+ 0x26, 0x0f, 0x9c, 0x14, 0x96, 0xc1, 0xc9, 0x08, 0x70, 0x12, 0xb6, 0x5b,
+ 0x40, 0x3b, 0x87, 0xab, 0x70, 0x32, 0xb2, 0x0c, 0x4e, 0xb8, 0xe6, 0x1a,
+ 0xee, 0xe1, 0xbe, 0xfc, 0x06, 0x7b, 0xb8, 0x53, 0x9f, 0x7d, 0xe3, 0x3d,
+ 0xdc, 0x2c, 0x73, 0xb9, 0xea, 0xcc, 0xfb, 0xb3, 0x76, 0x4f, 0x9a, 0xd9,
+ 0xfb, 0x37, 0x7f, 0x0f, 0x5e, 0x3b, 0xf8, 0xbc, 0x90, 0xf7, 0xc4, 0xec,
+ 0x21, 0x75, 0xb7, 0x4d, 0x81, 0xd7, 0x8e, 0xca, 0x81, 0xe3, 0xb5, 0x87,
+ 0x73, 0x36, 0xcd, 0xdf, 0xd6, 0x9e, 0x57, 0x8a, 0x79, 0xe1, 0xde, 0x83,
+ 0x17, 0xcd, 0x5d, 0x50, 0x31, 0x9e, 0xc7, 0xa8, 0x5e, 0x7b, 0x7e, 0xd1,
+ 0xde, 0x55, 0xe4, 0xdd, 0x9b, 0xf5, 0xa7, 0x13, 0xdc, 0x57, 0x55, 0xd0,
+ 0xf0, 0x72, 0x2d, 0xad, 0x47, 0xef, 0xa5, 0xca, 0x16, 0x69, 0x67, 0x27,
+ 0xb8, 0x27, 0x0d, 0xf6, 0x31, 0xf7, 0xed, 0x9a, 0x7d, 0xba, 0xbd, 0x0b,
+ 0xf6, 0xe9, 0x56, 0x9f, 0xef, 0x26, 0xdf, 0xcd, 0xd3, 0xcd, 0xc1, 0xb9,
+ 0xbb, 0x57, 0x8f, 0x3b, 0xcf, 0xe8, 0xf8, 0x70, 0x3d, 0xe6, 0x27, 0x08,
+ 0x4e, 0xa7, 0x4c, 0x5c, 0x76, 0x46, 0xc7, 0x65, 0x05, 0x1e, 0xf8, 0xb0,
+ 0x8d, 0xcd, 0x76, 0xf4, 0x5c, 0x9e, 0x8b, 0xcb, 0x2e, 0xd8, 0xa3, 0xa3,
+ 0xef, 0xff, 0xc8, 0x8e, 0x5e, 0xd2, 0x7b, 0x71, 0xfa, 0x52, 0x8e, 0x14,
+ 0x20, 0x23, 0xf6, 0x8c, 0xbf, 0x2a, 0xc3, 0x0f, 0xf2, 0x9b, 0x3a, 0x2d,
+ 0x02, 0xbd, 0x45, 0xb9, 0x9d, 0x97, 0x6c, 0x0f, 0xd3, 0x4c, 0x9d, 0x3e,
+ 0xed, 0x23, 0x1f, 0x77, 0x7a, 0xe7, 0xfa, 0x27, 0x7e, 0xc3, 0x35, 0x70,
+ 0xfe, 0xa6, 0x9d, 0x93, 0x71, 0xb2, 0x15, 0xe6, 0x87, 0x6b, 0xe1, 0x77,
+ 0xdb, 0xfb, 0x08, 0x99, 0x5f, 0x7d, 0xff, 0xb5, 0xe1, 0xd3, 0xac, 0xfe,
+ 0x3b, 0x22, 0x23, 0x4e, 0x1f, 0xea, 0x4c, 0x7b, 0x0d, 0x03, 0x2a, 0x7d,
+ 0xd3, 0x00, 0xcf, 0xca, 0x4d, 0x2c, 0xf9, 0xfb, 0x01, 0xf3, 0xba, 0xb0,
+ 0xa0, 0xe7, 0x94, 0xfb, 0xb0, 0xa6, 0x41, 0x8b, 0x9a, 0xb6, 0x34, 0xfd,
+ 0x1f, 0x98, 0xd3, 0x91, 0xd4, 0xad, 0xd4, 0x93, 0xa1, 0x8e, 0x4c, 0xc6,
+ 0xfb, 0x78, 0x7f, 0x84, 0xa6, 0x71, 0x7b, 0x97, 0xc4, 0xd4, 0x39, 0xad,
+ 0xdf, 0x47, 0x52, 0xbc, 0x5f, 0x66, 0x99, 0xb2, 0xa3, 0x55, 0x65, 0xf5,
+ 0xb8, 0x3d, 0xf9, 0x43, 0xcc, 0xcd, 0x17, 0x61, 0x6f, 0xf6, 0x8e, 0xbd,
+ 0x0a, 0x9f, 0x31, 0x2e, 0x5f, 0x2a, 0xbd, 0x04, 0x7a, 0xcd, 0xaf, 0xb5,
+ 0x77, 0xe1, 0x65, 0x01, 0x37, 0xcf, 0x38, 0xeb, 0xfd, 0xc3, 0x91, 0x3f,
+ 0x02, 0x5d, 0xfc, 0xc1, 0x4b, 0xec, 0x03, 0xb0, 0x44, 0x60, 0xcf, 0xc3,
+ 0x36, 0x18, 0x7f, 0x49, 0xef, 0x95, 0xbb, 0xbe, 0xfc, 0x92, 0x8e, 0x53,
+ 0xf4, 0x97, 0x5b, 0x65, 0x7b, 0xb9, 0x41, 0x76, 0x40, 0x2f, 0xec, 0x28,
+ 0xfb, 0x78, 0xa2, 0x72, 0x63, 0xd9, 0xcc, 0xd3, 0x47, 0xca, 0x9c, 0xef,
+ 0x6d, 0x32, 0x71, 0xbc, 0x9a, 0x66, 0xa7, 0xed, 0xde, 0x31, 0xd2, 0x0f,
+ 0x9e, 0x52, 0x32, 0x3f, 0xad, 0xc7, 0xce, 0x5d, 0xac, 0xc9, 0xc3, 0xb3,
+ 0xc2, 0xbd, 0xf8, 0xfc, 0x1b, 0x74, 0xdf, 0x68, 0xe5, 0x19, 0x77, 0xde,
+ 0x8f, 0xd8, 0x5f, 0x09, 0xf7, 0x86, 0xbf, 0xfe, 0x19, 0x10, 0xfd, 0x77,
+ 0x5d, 0xf4, 0xde, 0x70, 0x4d, 0x7b, 0xd2, 0x76, 0x26, 0xa6, 0x75, 0x84,
+ 0xa1, 0xf1, 0xf9, 0xbf, 0xe7, 0x22, 0xf2, 0x7f, 0x01, 0x95, 0xf6, 0x2d,
+ 0x58, 0xd0, 0x73, 0x00, 0x00, 0x00 };
+static u32 bnx2_CP_b09FwData[(0x50/4) + 1] = {
+ 0x00010030, 0x00000030, 0x00000000, 0x00000001, 0x00010fd0, 0x00000fd0,
+ 0x00001430, 0x0000007f, 0x00030400, 0x00001000, 0x00000030, 0x00000020,
+ 0x00050200, 0x00001000, 0x00000030, 0x00000010, 0x00010400, 0x00000400,
+ 0x00001030, 0x00000020, 0x00000000 };
+static u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = {
+ 0x080005d8, 0x080007f8, 0x0800073c, 0x08000764, 0x0800078c, 0x080007b4,
+ 0x08000610, 0x080005fc, 0x08000820, 0x08000820, 0x0800062c, 0x08000648,
+ 0x08000648, 0x08000820, 0x08000660, 0x08000674, 0x08000820, 0x08000688,
+ 0x08000820, 0x08000820, 0x0800069c, 0x08000820, 0x08000820, 0x08000820,
+ 0x08000820, 0x08000820, 0x08000820, 0x08000820, 0x08000820, 0x08000820,
+ 0x08000820, 0x080006b0, 0x08000820, 0x080006c4, 0x080006d8, 0x080006ec,
+ 0x08000820, 0x08000700, 0x08000714, 0x08000728, 0x08003740, 0x08003758,
+ 0x08003768, 0x08003778, 0x08003790, 0x080037a8, 0x080037b8, 0x080037c8,
+ 0x080037e8, 0x080037f8, 0x08003808, 0x08003898, 0x080037d8, 0x08003818,
+ 0x08003828, 0x08003840, 0x08003860, 0x08003898, 0x08003878, 0x08003878,
+ 0x080055f0, 0x080055f0, 0x080055f0, 0x080055f0, 0x080055f0, 0x08005618,
+ 0x08005618, 0x08005640, 0x08005690, 0x08005660, 0x00000000 };
+static u32 bnx2_CP_b09FwBss[(0x870/4) + 1] = { 0x0 };
+static u32 bnx2_CP_b09FwSbss[(0xe9/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_cp_fw_09 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x0800006c,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x73cc,
+ .text_index = 0x0,
+ .gz_text = bnx2_CP_b09FwText,
+ .gz_text_len = sizeof(bnx2_CP_b09FwText),
+
+ .data_addr = 0x08007500,
+ .data_len = 0x50,
+ .data_index = 0x0,
+ .data = bnx2_CP_b09FwData,
+
+ .sbss_addr = 0x08007554,
+ .sbss_len = 0xe9,
+ .sbss_index = 0x0,
+ .sbss = bnx2_CP_b09FwSbss,
+
+ .bss_addr = 0x08007640,
+ .bss_len = 0x870,
+ .bss_index = 0x0,
+ .bss = bnx2_CP_b09FwBss,
+
+ .rodata_addr = 0x080073d0,
+ .rodata_len = 0x118,
+ .rodata_index = 0x0,
+ .rodata = bnx2_CP_b09FwRodata,
+};
+
+static u8 bnx2_RXP_b09FwText[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0x19, 0xfd, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5c, 0x6b, 0x6c,
+ 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x20, 0xb5, 0xa2, 0xf8, 0x18, 0x2e, 0x57,
+ 0xcc, 0x4a, 0x66, 0xec, 0x5d, 0x71, 0x24, 0xb2, 0x16, 0x6b, 0x8c, 0xd8,
+ 0xad, 0x4d, 0x04, 0x6b, 0x7b, 0x33, 0xbb, 0x92, 0x98, 0x54, 0x85, 0x29,
+ 0x87, 0x75, 0x0c, 0xc3, 0x75, 0xd9, 0xa5, 0x1a, 0xbb, 0xae, 0x51, 0xc8,
+ 0x8f, 0xc4, 0x06, 0x6a, 0xd6, 0x9b, 0x25, 0xdd, 0xa8, 0xe9, 0x82, 0x43,
+ 0x4b, 0xaa, 0xe9, 0x02, 0x69, 0xbb, 0x20, 0xa9, 0xc7, 0x8f, 0x85, 0x56,
+ 0x76, 0x52, 0xc7, 0xf9, 0xe1, 0x48, 0x50, 0x95, 0x20, 0x28, 0x0c, 0x43,
+ 0x48, 0x8d, 0xd6, 0x3f, 0xda, 0x40, 0x95, 0x9f, 0x68, 0x92, 0x42, 0x41,
+ 0x0b, 0xc7, 0x68, 0x6c, 0x4f, 0xbf, 0xef, 0xce, 0x0c, 0xb9, 0xa4, 0x5f,
+ 0x40, 0x7f, 0xf4, 0x4f, 0xe7, 0x02, 0x8b, 0xb9, 0xf7, 0xce, 0x3d, 0xe7,
+ 0x9e, 0x7b, 0xde, 0xe7, 0x0e, 0xa5, 0xdf, 0xef, 0x94, 0x0e, 0x09, 0x5b,
+ 0x17, 0x7e, 0x99, 0xc3, 0x8f, 0x3d, 0x74, 0xc3, 0xd8, 0x0d, 0xa3, 0x22,
+ 0x7b, 0xf6, 0x18, 0x5b, 0x12, 0x7a, 0x34, 0x1f, 0xb7, 0xb8, 0xc5, 0x2d,
+ 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e,
+ 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71,
+ 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b,
+ 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b,
+ 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc,
+ 0xe2, 0xf6, 0xff, 0xbd, 0x19, 0x22, 0x16, 0x9f, 0x5d, 0xe1, 0x4f, 0x12,
+ 0x7a, 0xfe, 0xf2, 0x1f, 0xba, 0xb6, 0x24, 0x8c, 0xfc, 0xcf, 0x66, 0xa6,
+ 0x6d, 0x91, 0x42, 0x63, 0x77, 0xa6, 0x28, 0xef, 0xfb, 0x95, 0x94, 0x29,
+ 0x9c, 0xff, 0x6c, 0xfe, 0xbd, 0xbf, 0x7d, 0xf1, 0xa6, 0xec, 0xd5, 0xba,
+ 0x21, 0x09, 0x2b, 0x3f, 0xb7, 0xc7, 0xda, 0x25, 0x89, 0x01, 0xc0, 0x7c,
+ 0x6b, 0xe8, 0xc7, 0xdd, 0xd2, 0x2d, 0x6b, 0x78, 0xec, 0x84, 0x5c, 0x36,
+ 0x5e, 0xd0, 0xdc, 0xa6, 0xef, 0x9f, 0x70, 0x7c, 0xff, 0x87, 0xf8, 0xbd,
+ 0xe5, 0x60, 0xec, 0x7d, 0xe0, 0x17, 0x4c, 0x43, 0x74, 0xfb, 0x2f, 0x34,
+ 0x77, 0xb9, 0x43, 0xaa, 0x8b, 0xa6, 0xcc, 0x7a, 0x29, 0x39, 0xe2, 0x55,
+ 0xb4, 0x52, 0xb3, 0xa6, 0xed, 0x3d, 0x35, 0xaf, 0xed, 0x3b, 0x75, 0x44,
+ 0xdb, 0x7f, 0x6a, 0x41, 0x73, 0x4f, 0x49, 0x45, 0xdf, 0xd3, 0x29, 0x05,
+ 0xeb, 0xb4, 0x56, 0x6c, 0xf6, 0x6b, 0xee, 0xe2, 0x7b, 0xbe, 0xeb, 0x64,
+ 0xad, 0xbb, 0xc4, 0x2c, 0x80, 0x16, 0x71, 0x6b, 0x3e, 0xc6, 0xa6, 0x14,
+ 0x52, 0xbe, 0xaf, 0xe7, 0xfd, 0x27, 0xdc, 0x9c, 0x6d, 0xe9, 0x5a, 0x4a,
+ 0xaa, 0xcd, 0x7e, 0xe0, 0xed, 0xd4, 0x8a, 0x8b, 0xa6, 0x56, 0xf2, 0xfc,
+ 0x73, 0xae, 0x23, 0x03, 0x86, 0xf8, 0xfe, 0x9c, 0xb3, 0x33, 0x7d, 0x48,
+ 0x4e, 0x02, 0x6f, 0x03, 0xf8, 0xc4, 0xd2, 0xf3, 0xa4, 0x8f, 0x74, 0x92,
+ 0xe4, 0x8a, 0x56, 0x1c, 0x8a, 0xe8, 0x93, 0x0c, 0xe9, 0x2f, 0xaf, 0xe8,
+ 0xa0, 0x73, 0x8b, 0x94, 0xeb, 0x96, 0x4c, 0xad, 0x6c, 0x5c, 0x7f, 0xd9,
+ 0x7f, 0x71, 0x28, 0x25, 0xcf, 0x36, 0xb3, 0x47, 0x2a, 0x92, 0x90, 0x39,
+ 0x2f, 0x23, 0x7a, 0x5e, 0x0a, 0x6e, 0x6e, 0x40, 0xce, 0x35, 0xd3, 0xf2,
+ 0x5c, 0xd3, 0x4e, 0x57, 0x65, 0x93, 0x94, 0x53, 0x96, 0x9c, 0x6d, 0xa6,
+ 0x70, 0x46, 0xff, 0x9c, 0x6e, 0xdb, 0x56, 0x15, 0x6b, 0xab, 0xcd, 0x97,
+ 0xf8, 0xef, 0x5f, 0xac, 0xe9, 0x9c, 0x82, 0xa9, 0x80, 0xee, 0x70, 0x2d,
+ 0xcf, 0xa1, 0xd6, 0xaa, 0xb3, 0x04, 0x6b, 0xa5, 0x32, 0x9d, 0xc3, 0x5c,
+ 0x73, 0x34, 0xe4, 0xef, 0x16, 0x9c, 0x97, 0x4f, 0x4b, 0xaa, 0x9e, 0x01,
+ 0xde, 0xb0, 0xff, 0xcf, 0xc0, 0x37, 0x80, 0xf3, 0x5e, 0xab, 0x7e, 0xee,
+ 0xa2, 0xa4, 0x74, 0xd9, 0x99, 0x2e, 0x0b, 0x78, 0xdb, 0xec, 0xc4, 0x98,
+ 0xf4, 0xf9, 0xfe, 0x7e, 0x47, 0xac, 0xaa, 0xd3, 0x03, 0x98, 0x8c, 0x54,
+ 0x9d, 0x6e, 0xe0, 0x69, 0x13, 0xcb, 0xe6, 0xb9, 0xb8, 0xd7, 0x66, 0xcc,
+ 0xfb, 0x5d, 0x46, 0xde, 0xf7, 0xa7, 0x73, 0xd2, 0x1d, 0xcc, 0xed, 0x56,
+ 0x38, 0xa6, 0x26, 0x34, 0xac, 0xfb, 0x05, 0x69, 0x4e, 0x24, 0xf3, 0xec,
+ 0xf3, 0x99, 0x13, 0x77, 0xfe, 0xda, 0x90, 0x96, 0x34, 0x68, 0xb9, 0x26,
+ 0xec, 0x83, 0xff, 0x1e, 0xf8, 0xe0, 0x7c, 0x06, 0x63, 0xed, 0x3a, 0xe0,
+ 0x19, 0xae, 0x0a, 0xf7, 0xe8, 0x93, 0xa5, 0x94, 0xe8, 0x57, 0x9c, 0xde,
+ 0x70, 0x5d, 0x37, 0x68, 0x8d, 0xf4, 0xa0, 0x5f, 0xe6, 0x16, 0xc9, 0xeb,
+ 0x1a, 0x64, 0x83, 0xe7, 0x8d, 0x15, 0xad, 0xd0, 0x3c, 0x82, 0xbe, 0x29,
+ 0xd3, 0xb6, 0x7f, 0x6e, 0xce, 0x99, 0xd7, 0x8a, 0xa7, 0x4e, 0x6a, 0xa5,
+ 0x53, 0x2f, 0x68, 0x7b, 0x9b, 0x2f, 0x74, 0x49, 0x47, 0x16, 0xa7, 0x4e,
+ 0xc8, 0x93, 0x9e, 0x26, 0xa4, 0x73, 0x09, 0xbc, 0x2b, 0x58, 0x15, 0x31,
+ 0xed, 0x6e, 0x6d, 0x1f, 0xf0, 0xb4, 0xd9, 0x7f, 0xd2, 0x29, 0xdd, 0x86,
+ 0x6c, 0xb2, 0xa3, 0xb5, 0x29, 0xf9, 0x33, 0xd0, 0x74, 0xc1, 0x49, 0x91,
+ 0x5f, 0x3d, 0x01, 0x4c, 0x44, 0x07, 0xf5, 0x8a, 0x3a, 0xa5, 0x17, 0x4a,
+ 0xc7, 0xff, 0xbc, 0xaf, 0x3a, 0xb2, 0x85, 0x6b, 0xa0, 0xff, 0xd6, 0xfd,
+ 0xd3, 0xb6, 0xdb, 0x6b, 0x4a, 0xc5, 0xd2, 0x25, 0x6b, 0x15, 0xe5, 0x3a,
+ 0x99, 0x73, 0x44, 0x8a, 0x35, 0xec, 0x69, 0x9b, 0xe0, 0x8d, 0x0d, 0xde,
+ 0xec, 0x3c, 0x32, 0xa8, 0xff, 0x96, 0x64, 0xfa, 0x2b, 0x9a, 0x19, 0xf2,
+ 0x71, 0x49, 0x6e, 0x51, 0xf0, 0x7a, 0xde, 0x81, 0x7e, 0x76, 0xb0, 0x8f,
+ 0x7d, 0x13, 0x6a, 0x5f, 0x23, 0x6f, 0xa7, 0x97, 0x45, 0x34, 0x3d, 0xbf,
+ 0x1b, 0xf8, 0xa8, 0xb7, 0x5c, 0xf7, 0x04, 0x68, 0x24, 0xed, 0xec, 0xdb,
+ 0x80, 0x49, 0x88, 0xeb, 0x74, 0xb5, 0xd0, 0x49, 0x79, 0x93, 0xd7, 0xe4,
+ 0x9d, 0x3a, 0xa7, 0xb6, 0x76, 0xce, 0x5f, 0xf9, 0x9b, 0x46, 0x4d, 0xf9,
+ 0xa1, 0x3a, 0x2f, 0x6d, 0x8c, 0xeb, 0x52, 0xa1, 0x4e, 0x24, 0xa0, 0x47,
+ 0xa2, 0x95, 0x1d, 0x6b, 0x15, 0x57, 0x59, 0x44, 0x37, 0xf2, 0x9d, 0x52,
+ 0x54, 0xf4, 0x8d, 0x61, 0x2f, 0xda, 0x1e, 0x6c, 0xc8, 0xe6, 0x59, 0x38,
+ 0x97, 0x87, 0x8d, 0x67, 0xd9, 0x97, 0xf2, 0x02, 0xed, 0x9d, 0xb4, 0x9d,
+ 0xcf, 0xaa, 0x7f, 0x8e, 0x45, 0x5d, 0x3c, 0xd6, 0x03, 0xda, 0x38, 0x86,
+ 0x1d, 0xda, 0x78, 0x3f, 0xa2, 0x89, 0x3b, 0x36, 0x08, 0xfe, 0x70, 0x9d,
+ 0x9d, 0x81, 0x9c, 0x0b, 0x2e, 0xf6, 0x74, 0x9d, 0xdf, 0x50, 0x3c, 0xe8,
+ 0xc5, 0x79, 0x06, 0xe7, 0xc9, 0xaf, 0x0e, 0xe8, 0xb6, 0x26, 0x65, 0x27,
+ 0x9b, 0xa1, 0xdc, 0x03, 0xda, 0x75, 0xd9, 0x74, 0x63, 0x2b, 0xed, 0x91,
+ 0xac, 0xa8, 0x87, 0xa6, 0x24, 0x47, 0xb9, 0x96, 0xeb, 0xb8, 0x3e, 0x3b,
+ 0x26, 0xfa, 0xaf, 0x7c, 0x6b, 0xdd, 0x59, 0x6d, 0xd9, 0x31, 0x0f, 0x1a,
+ 0x02, 0xde, 0x82, 0x27, 0x9f, 0xb6, 0x96, 0x7c, 0xdd, 0xc8, 0x3f, 0xae,
+ 0x6d, 0x5d, 0x07, 0x9d, 0xe8, 0x27, 0x0d, 0x27, 0x3a, 0x03, 0x5b, 0x8b,
+ 0x68, 0x8a, 0x64, 0xa3, 0x85, 0x38, 0x3e, 0xe9, 0x1c, 0x5c, 0x0f, 0x1f,
+ 0xe0, 0xc1, 0x07, 0xc0, 0xaf, 0x3d, 0xeb, 0xc1, 0xfe, 0x3d, 0xfa, 0x8c,
+ 0x8c, 0xbc, 0x38, 0x04, 0x1f, 0xb7, 0xe6, 0x63, 0xd0, 0xc6, 0xd1, 0xd7,
+ 0xc5, 0x80, 0x8f, 0x99, 0xad, 0xeb, 0xb0, 0x59, 0xf0, 0x78, 0x85, 0x73,
+ 0xb0, 0xed, 0x95, 0x12, 0x9e, 0xb6, 0x54, 0x1b, 0xd4, 0xab, 0xc8, 0x97,
+ 0xd2, 0xe7, 0xa4, 0xe1, 0x5f, 0xe8, 0x77, 0xe8, 0x57, 0xb8, 0xd6, 0xf7,
+ 0x4b, 0x0e, 0x61, 0x7d, 0x99, 0x70, 0x68, 0x43, 0x9d, 0xa2, 0x27, 0x2b,
+ 0xda, 0xc1, 0x21, 0xd8, 0xd6, 0xf5, 0x6d, 0xa0, 0x95, 0x36, 0x76, 0x8d,
+ 0x48, 0x3b, 0xf7, 0xfb, 0x69, 0x57, 0xf0, 0xef, 0xee, 0x36, 0x61, 0x0d,
+ 0x9f, 0xef, 0x86, 0x63, 0x2d, 0xf4, 0x2d, 0x7c, 0x9f, 0xcd, 0x14, 0xa4,
+ 0x3f, 0x1c, 0xb3, 0xbf, 0x4a, 0xaf, 0xa3, 0xdf, 0x98, 0x90, 0x1d, 0x27,
+ 0x03, 0x9f, 0xb8, 0x63, 0xc9, 0x12, 0xfb, 0x64, 0x40, 0xe3, 0x8e, 0x33,
+ 0x91, 0x6f, 0x7c, 0x1f, 0xf0, 0xa0, 0xcf, 0x5b, 0x8d, 0x03, 0x68, 0x3f,
+ 0xd3, 0x60, 0x2a, 0x98, 0xdb, 0xc8, 0x0b, 0xfa, 0x63, 0xda, 0x9b, 0xd5,
+ 0x6a, 0x6f, 0x7b, 0x60, 0x6f, 0x4e, 0xbb, 0x64, 0x9d, 0xbf, 0x87, 0xbd,
+ 0x7d, 0xc3, 0xd1, 0xc0, 0x1b, 0x91, 0x8b, 0xb5, 0x34, 0x6c, 0xdd, 0x4c,
+ 0xbf, 0x26, 0x3b, 0x33, 0xb3, 0xa2, 0xc9, 0x09, 0xce, 0x35, 0x30, 0xa7,
+ 0x7c, 0x71, 0xe0, 0x0b, 0x2e, 0x1b, 0x4f, 0x81, 0x2e, 0xdf, 0x9f, 0x05,
+ 0xce, 0xf2, 0x88, 0x11, 0xda, 0x56, 0x34, 0x6f, 0xdd, 0xef, 0xda, 0xee,
+ 0xaf, 0x19, 0x52, 0x19, 0x6e, 0x93, 0xec, 0xf0, 0x12, 0x70, 0x4f, 0x3b,
+ 0x81, 0x1d, 0x53, 0xd7, 0x97, 0x81, 0x7f, 0xce, 0x1b, 0x82, 0x1e, 0xd3,
+ 0x0e, 0x40, 0x17, 0xf0, 0x2f, 0x03, 0xff, 0x5c, 0xb3, 0x4d, 0xbe, 0x6e,
+ 0x46, 0xb1, 0x32, 0x3a, 0x4f, 0x37, 0x96, 0x45, 0xfb, 0x1e, 0x96, 0x2f,
+ 0x7a, 0x49, 0xcd, 0x3d, 0x46, 0xff, 0x5a, 0x1d, 0x86, 0x9d, 0x68, 0x55,
+ 0x87, 0x7b, 0x1b, 0xb2, 0xbc, 0xba, 0x46, 0x0a, 0xd5, 0xc0, 0x06, 0x0b,
+ 0xee, 0x50, 0x25, 0x6d, 0x28, 0x5f, 0x22, 0xb2, 0x0f, 0xb6, 0xb7, 0x6c,
+ 0x73, 0xcc, 0xf9, 0x60, 0x6e, 0xbc, 0xd6, 0x0f, 0x9f, 0xc8, 0xf1, 0x7b,
+ 0xfe, 0xb4, 0x13, 0xcc, 0x7d, 0xa1, 0x76, 0x57, 0x37, 0xfd, 0x2e, 0xe2,
+ 0x44, 0xa6, 0xea, 0xfc, 0xbb, 0x0f, 0xfd, 0x5d, 0x07, 0xf3, 0xd1, 0x78,
+ 0xb2, 0xe3, 0x81, 0xce, 0x8a, 0xb6, 0xdf, 0xd6, 0xfb, 0xdb, 0x43, 0x1f,
+ 0xb6, 0x1f, 0x93, 0x7b, 0x6b, 0xd5, 0xbe, 0x76, 0x79, 0xcf, 0x60, 0x1c,
+ 0xbd, 0x22, 0x62, 0xba, 0xb5, 0x5d, 0xe0, 0x47, 0xb5, 0xb7, 0x65, 0x2e,
+ 0x51, 0xaa, 0xf9, 0x72, 0xc1, 0x09, 0x60, 0x30, 0xee, 0x2c, 0xd6, 0xf4,
+ 0xfe, 0x84, 0xac, 0x8e, 0x2d, 0xc2, 0xac, 0xc8, 0xae, 0xe1, 0x65, 0x51,
+ 0xb0, 0x7d, 0x89, 0x35, 0xd8, 0x54, 0xa9, 0x56, 0xed, 0x6d, 0x19, 0xa7,
+ 0x8b, 0xc0, 0xa5, 0xef, 0x59, 0x85, 0x1d, 0x58, 0x83, 0xdd, 0x2a, 0x99,
+ 0x5e, 0xc2, 0xeb, 0xfd, 0x9b, 0xd7, 0x70, 0x67, 0x42, 0x7a, 0xfa, 0x36,
+ 0xaf, 0xe1, 0xb0, 0x89, 0xb3, 0x65, 0x3c, 0x4c, 0x9c, 0x3b, 0xd6, 0x70,
+ 0x8e, 0xac, 0xa7, 0xe7, 0xb0, 0xc0, 0x07, 0x25, 0xda, 0xf3, 0xb2, 0xe7,
+ 0x62, 0x6d, 0x70, 0xe2, 0x8b, 0x82, 0x58, 0x37, 0xb2, 0x29, 0xf4, 0xc9,
+ 0xe6, 0x1e, 0x17, 0xbc, 0x32, 0x85, 0x3e, 0x4e, 0x93, 0x2a, 0xe4, 0x7c,
+ 0x7f, 0x43, 0xf6, 0x5c, 0x68, 0x98, 0xa1, 0x2e, 0x51, 0x27, 0xde, 0x86,
+ 0x8d, 0x75, 0x4e, 0x99, 0x88, 0xc3, 0xe7, 0x94, 0x8d, 0xc9, 0x44, 0xb5,
+ 0x26, 0x95, 0xed, 0xf9, 0x27, 0x7c, 0xe8, 0xe2, 0x94, 0x05, 0x3f, 0x5a,
+ 0x94, 0xce, 0x31, 0x37, 0x87, 0xf9, 0x06, 0x6d, 0x0b, 0x7e, 0x05, 0xb0,
+ 0xd0, 0xb5, 0x84, 0x31, 0xbf, 0xf3, 0x55, 0xd7, 0xe0, 0x3e, 0x19, 0xe4,
+ 0x4d, 0x89, 0x84, 0x3e, 0x7f, 0xd5, 0xa7, 0x9e, 0x4d, 0x8f, 0x5c, 0x45,
+ 0x9e, 0x62, 0xc1, 0x57, 0xc2, 0x7f, 0x40, 0xdf, 0x67, 0x9b, 0x82, 0xb8,
+ 0xfe, 0x40, 0x4f, 0x60, 0x63, 0x47, 0xb7, 0x06, 0x4f, 0x31, 0xe9, 0x9b,
+ 0xa7, 0x73, 0xcc, 0x01, 0xda, 0x13, 0x6e, 0x6e, 0x7c, 0x9b, 0x71, 0xe6,
+ 0xc0, 0x36, 0xfd, 0x4c, 0x65, 0x9b, 0x0e, 0x9f, 0x0e, 0x9b, 0xd2, 0xdd,
+ 0x1c, 0xfa, 0x67, 0x22, 0x1b, 0x4a, 0xc3, 0x86, 0xde, 0x56, 0x39, 0xc8,
+ 0xb9, 0xe6, 0x29, 0xd8, 0xab, 0xa2, 0x55, 0x26, 0x90, 0x13, 0xe8, 0xa3,
+ 0xef, 0x43, 0x4f, 0x70, 0x16, 0xf8, 0xc0, 0x02, 0xb8, 0xa4, 0x8f, 0xbe,
+ 0x11, 0xda, 0x33, 0xfb, 0xef, 0xf8, 0x41, 0x7c, 0xf8, 0x7c, 0xb8, 0xff,
+ 0x3f, 0x75, 0x07, 0x3e, 0x20, 0xc2, 0x45, 0x3c, 0xc3, 0xda, 0x04, 0xf2,
+ 0x99, 0x89, 0xa6, 0xa9, 0xd1, 0x9f, 0x17, 0x3d, 0xe6, 0x21, 0xcc, 0x41,
+ 0x1e, 0x0b, 0xfd, 0x22, 0x73, 0x8f, 0xce, 0x90, 0xa7, 0xb9, 0x28, 0xce,
+ 0x29, 0x7b, 0x43, 0xcc, 0xc9, 0x94, 0x9d, 0x36, 0xe5, 0x93, 0xa7, 0x73,
+ 0x9d, 0x58, 0x87, 0xb9, 0x26, 0xce, 0x0d, 0xbf, 0x84, 0x5c, 0x06, 0x6b,
+ 0xce, 0x63, 0x7d, 0x7b, 0x68, 0xf3, 0x17, 0xa5, 0x0c, 0x9f, 0x6a, 0xda,
+ 0x7c, 0x9f, 0xeb, 0x91, 0x0e, 0x8c, 0x1b, 0xd8, 0x0b, 0x7e, 0xc2, 0x50,
+ 0x7c, 0x46, 0x2c, 0x48, 0x5d, 0xc7, 0x1c, 0x09, 0x6b, 0x33, 0x58, 0x4b,
+ 0xbf, 0xcb, 0xb5, 0xcf, 0x82, 0x0e, 0x8c, 0x1b, 0x84, 0xa1, 0x8f, 0x12,
+ 0xdf, 0xcd, 0x6d, 0x86, 0x26, 0xf9, 0xe7, 0x0c, 0x3b, 0x5a, 0x1b, 0xe1,
+ 0xdd, 0xb8, 0x96, 0xf9, 0x09, 0x71, 0xf7, 0x84, 0xf1, 0x7f, 0x5c, 0x0a,
+ 0xcd, 0x02, 0x7e, 0x22, 0xd3, 0xc7, 0x90, 0x8f, 0xd9, 0x6d, 0x88, 0x55,
+ 0x9c, 0xdf, 0x6a, 0x05, 0x67, 0x8d, 0xe0, 0xee, 0xef, 0x5b, 0x3f, 0xfe,
+ 0x42, 0x72, 0xcd, 0x47, 0xd2, 0xc2, 0xa4, 0x80, 0x18, 0x01, 0x5e, 0x65,
+ 0xa6, 0x98, 0xc3, 0x15, 0x1b, 0x4a, 0xa6, 0x98, 0x1b, 0x83, 0x5f, 0x0c,
+ 0xf2, 0xa2, 0x73, 0xde, 0x46, 0xd9, 0x59, 0xe0, 0x77, 0x01, 0x3c, 0xce,
+ 0x40, 0x87, 0xc6, 0x01, 0x2b, 0x87, 0x81, 0x83, 0xf1, 0xd7, 0xd1, 0xf3,
+ 0x49, 0x29, 0x5b, 0xcc, 0x13, 0xda, 0x49, 0x67, 0x81, 0xf6, 0xaf, 0xe7,
+ 0x37, 0x63, 0x8e, 0xfd, 0x7b, 0x7b, 0x02, 0x99, 0x75, 0x71, 0x3c, 0xa1,
+ 0xe7, 0x7b, 0x36, 0xcc, 0x7f, 0xbf, 0x2b, 0xa0, 0x4d, 0x8d, 0x31, 0xff,
+ 0xf2, 0x86, 0xf1, 0xef, 0x25, 0xd7, 0x8f, 0xef, 0xda, 0x16, 0xea, 0x20,
+ 0xfa, 0x8f, 0x85, 0xf4, 0x82, 0xb6, 0x55, 0x5a, 0xa3, 0x9c, 0x57, 0x16,
+ 0x74, 0xe4, 0x7f, 0x6e, 0x6e, 0x27, 0x62, 0x7d, 0x46, 0x4a, 0x4d, 0xd0,
+ 0xbd, 0x1a, 0xcb, 0x56, 0xd7, 0x54, 0xd6, 0xd6, 0x04, 0xbe, 0xbe, 0xd4,
+ 0xf4, 0x91, 0x3b, 0xb5, 0xc6, 0xbd, 0x61, 0xf4, 0x2b, 0xd8, 0xa7, 0x20,
+ 0xd3, 0xde, 0x85, 0x82, 0x6e, 0x1f, 0x09, 0xf2, 0x3e, 0xfb, 0x9b, 0x5a,
+ 0x69, 0x99, 0xf9, 0x20, 0xec, 0xc9, 0x56, 0xf9, 0x3f, 0xe2, 0xca, 0x51,
+ 0xad, 0x70, 0xea, 0x38, 0xf2, 0xc1, 0x15, 0xfc, 0x4e, 0xe3, 0xd7, 0xc0,
+ 0x2f, 0xca, 0xc3, 0x9f, 0x41, 0x1e, 0xaf, 0x7c, 0x2c, 0xe2, 0x41, 0xb0,
+ 0xff, 0x1b, 0x2b, 0xd0, 0xb3, 0xe3, 0x29, 0xf9, 0x86, 0xad, 0xf7, 0xe9,
+ 0x81, 0x5f, 0x29, 0x20, 0x8f, 0xb5, 0xde, 0x96, 0xdf, 0x0e, 0xf3, 0x22,
+ 0x91, 0xd7, 0x16, 0xc0, 0xc7, 0x91, 0xfd, 0xa1, 0xce, 0x16, 0xee, 0x75,
+ 0x95, 0xff, 0x0c, 0xf3, 0x1e, 0xe4, 0x5f, 0x05, 0xb5, 0xea, 0x5b, 0xe0,
+ 0x8d, 0x26, 0x6f, 0x41, 0x87, 0x5e, 0x5b, 0xe8, 0x00, 0x3d, 0xb6, 0x94,
+ 0x27, 0x91, 0x2f, 0x68, 0x83, 0xd6, 0x26, 0xad, 0x03, 0x76, 0x0c, 0x1b,
+ 0x57, 0x63, 0x49, 0xb4, 0xe5, 0x2f, 0xcd, 0x2c, 0xd5, 0x74, 0xac, 0x45,
+ 0xee, 0x93, 0x43, 0x1f, 0xb2, 0xbf, 0xb2, 0x40, 0x38, 0x5d, 0x5e, 0x5f,
+ 0x30, 0xe4, 0x4d, 0xe4, 0x52, 0x6f, 0xd9, 0x97, 0x66, 0x10, 0xb7, 0xfa,
+ 0x11, 0x23, 0x50, 0x8b, 0xec, 0xa4, 0x9f, 0xde, 0x61, 0xe2, 0x59, 0xc2,
+ 0x6f, 0x1f, 0x72, 0xc1, 0x8f, 0x86, 0xf9, 0xb8, 0xf5, 0xa4, 0x2d, 0x01,
+ 0x18, 0xae, 0x37, 0x41, 0x5b, 0x37, 0xe4, 0x9f, 0xb5, 0xa6, 0xe4, 0xf5,
+ 0x1e, 0x95, 0xaf, 0x68, 0x9c, 0x0f, 0x7c, 0xd3, 0x87, 0xe7, 0xc9, 0x67,
+ 0x03, 0x3a, 0xce, 0x31, 0xdf, 0xd1, 0x87, 0x12, 0x5f, 0x76, 0xac, 0x80,
+ 0xc3, 0x5c, 0x59, 0x08, 0xfa, 0xd1, 0x9c, 0x68, 0x51, 0x1c, 0xa3, 0x6f,
+ 0x2c, 0xc1, 0x4e, 0x38, 0x9e, 0x10, 0x25, 0x83, 0x75, 0xf2, 0x94, 0x84,
+ 0x99, 0x3f, 0x3b, 0x33, 0x67, 0x53, 0xae, 0xf0, 0x71, 0xb5, 0x48, 0xae,
+ 0x94, 0x51, 0xbb, 0x54, 0x17, 0xbe, 0x09, 0xb9, 0xea, 0x61, 0xbe, 0x0f,
+ 0x1b, 0x3f, 0x4e, 0xf9, 0xa2, 0xfe, 0x5b, 0x40, 0xee, 0xb3, 0x20, 0xc9,
+ 0xa0, 0x5e, 0x39, 0x8a, 0x3c, 0x1f, 0xf2, 0xab, 0x1d, 0x07, 0x0e, 0xd8,
+ 0x69, 0x6d, 0x05, 0x4f, 0xd4, 0x16, 0xb5, 0xd3, 0x78, 0x0e, 0xe0, 0xd9,
+ 0xa0, 0x6e, 0x86, 0xb9, 0xc6, 0x87, 0xe8, 0x81, 0x3d, 0x95, 0x68, 0x4f,
+ 0xf2, 0xfd, 0x66, 0x5e, 0xbe, 0xdb, 0x1c, 0x93, 0xe7, 0x9b, 0x39, 0xf9,
+ 0xbb, 0xa6, 0x23, 0xdf, 0x69, 0x8e, 0xc8, 0xb7, 0x9b, 0xc3, 0xac, 0xc9,
+ 0x90, 0x37, 0x65, 0x98, 0x37, 0xc9, 0xbd, 0xde, 0xad, 0xb0, 0x77, 0xca,
+ 0xff, 0xd2, 0x4c, 0xa1, 0x31, 0x28, 0xe5, 0x63, 0xf0, 0xcf, 0xce, 0xcd,
+ 0xac, 0x25, 0xe5, 0x11, 0x87, 0x35, 0x41, 0x1b, 0xdf, 0xa3, 0xce, 0x84,
+ 0xff, 0x86, 0x3f, 0x9b, 0x4a, 0x65, 0x4f, 0xbb, 0x46, 0x47, 0xe8, 0x03,
+ 0x6e, 0x49, 0x4a, 0x07, 0xf6, 0x82, 0x0f, 0x5c, 0x7a, 0x1a, 0x36, 0xa0,
+ 0x6a, 0x9a, 0x04, 0xfc, 0x0d, 0x73, 0x01, 0x93, 0x76, 0x8c, 0x3a, 0x30,
+ 0x9b, 0x71, 0x0d, 0xd6, 0x77, 0xb4, 0x67, 0x03, 0x81, 0x83, 0x70, 0xfb,
+ 0x2c, 0xca, 0xcd, 0xb4, 0xe9, 0x57, 0x0b, 0xa1, 0x8f, 0x4b, 0x84, 0x7a,
+ 0x69, 0x61, 0xfe, 0xf1, 0xd0, 0x27, 0x6f, 0xdc, 0x07, 0xf1, 0x02, 0xf9,
+ 0x64, 0xb0, 0x8e, 0xb0, 0x5a, 0x08, 0xdb, 0x17, 0xce, 0x75, 0x82, 0xdf,
+ 0x8e, 0x94, 0xbd, 0x37, 0x35, 0xe6, 0xd9, 0xc8, 0x77, 0x30, 0x1e, 0xc1,
+ 0xf8, 0x4a, 0x38, 0xfe, 0x9c, 0x4c, 0x2f, 0x0a, 0x68, 0xfd, 0x89, 0x56,
+ 0x54, 0xe3, 0x31, 0x8c, 0x75, 0x8c, 0x0d, 0xd6, 0x02, 0x68, 0x37, 0x27,
+ 0xa9, 0xeb, 0xba, 0x4d, 0x5f, 0x38, 0x19, 0xfa, 0xc3, 0x82, 0x1c, 0xf6,
+ 0x06, 0x0b, 0x57, 0x11, 0x33, 0xb4, 0xb6, 0x28, 0xff, 0xd9, 0x0e, 0xbe,
+ 0xf8, 0xfe, 0xed, 0xac, 0xb9, 0x93, 0xa6, 0x7c, 0x7b, 0x3e, 0x6b, 0x3d,
+ 0xa4, 0x7f, 0x0d, 0x67, 0xf2, 0xfd, 0x83, 0x76, 0xf6, 0xc8, 0x94, 0xde,
+ 0x25, 0xdf, 0x3d, 0xca, 0xd8, 0x7b, 0x76, 0xe6, 0x07, 0xd0, 0xbd, 0xfa,
+ 0x4a, 0xbb, 0xd4, 0xeb, 0xa6, 0x5c, 0x19, 0x1d, 0x04, 0x9d, 0x96, 0xd4,
+ 0x1b, 0x49, 0xe4, 0x73, 0x9b, 0x65, 0xb6, 0x5f, 0x19, 0x18, 0xfc, 0xf4,
+ 0xb0, 0xf2, 0xd3, 0xae, 0x8d, 0x67, 0xe3, 0xe7, 0x3d, 0xeb, 0xcf, 0x5c,
+ 0x02, 0xfd, 0xd0, 0xeb, 0xe4, 0x76, 0x25, 0xe7, 0xb2, 0x37, 0x68, 0x95,
+ 0x75, 0xc4, 0x2e, 0x73, 0xd0, 0xba, 0x57, 0xff, 0x2f, 0xff, 0xf3, 0x26,
+ 0x65, 0xf7, 0xaa, 0xaa, 0x61, 0x54, 0xac, 0xc3, 0x7e, 0x4b, 0x2b, 0x2f,
+ 0x83, 0x16, 0xf8, 0xd8, 0xc6, 0xf6, 0x70, 0x9c, 0x51, 0xbc, 0x38, 0xdb,
+ 0xe8, 0x90, 0xef, 0xd4, 0xb7, 0xc8, 0x72, 0x9d, 0xef, 0xdb, 0x65, 0xa9,
+ 0x3e, 0x78, 0xb5, 0x4f, 0xef, 0x97, 0xf3, 0xd7, 0x5c, 0x6f, 0xdd, 0xa3,
+ 0x23, 0x37, 0x98, 0xfc, 0x40, 0x7e, 0x39, 0xda, 0x23, 0x3f, 0xfe, 0x72,
+ 0xf6, 0x99, 0x3f, 0xd5, 0x61, 0x03, 0xa3, 0x9d, 0xb4, 0x6d, 0xf4, 0x39,
+ 0x9f, 0xbd, 0x5a, 0xd0, 0xa9, 0xdb, 0x3f, 0x02, 0x4f, 0xb3, 0x0b, 0x81,
+ 0x1d, 0x10, 0x37, 0xf1, 0x42, 0x37, 0xec, 0xef, 0x01, 0x27, 0xde, 0x35,
+ 0x06, 0x81, 0xeb, 0x7b, 0x8a, 0x17, 0xb7, 0x3b, 0xd9, 0xab, 0x08, 0x49,
+ 0xfe, 0x15, 0x7b, 0x70, 0x78, 0x87, 0xbe, 0x5d, 0xea, 0xe9, 0xeb, 0xad,
+ 0xe7, 0xe0, 0xff, 0x0b, 0xa9, 0xec, 0x91, 0xcb, 0x72, 0x76, 0xe6, 0xa2,
+ 0x4d, 0xfd, 0xa7, 0xdf, 0x78, 0x09, 0xb9, 0xa7, 0x25, 0x0b, 0x0d, 0xfa,
+ 0x4b, 0xe2, 0x62, 0xfe, 0xbf, 0xcb, 0x3a, 0xac, 0x33, 0x4f, 0xc0, 0x3b,
+ 0xcc, 0x1b, 0xbf, 0x4e, 0x39, 0xb7, 0x11, 0x76, 0xb8, 0xa0, 0xff, 0x62,
+ 0x03, 0x8f, 0x06, 0xad, 0xbd, 0x3a, 0xf7, 0xfb, 0x37, 0xec, 0xfb, 0x0e,
+ 0x68, 0x1d, 0x04, 0x2c, 0x62, 0x66, 0xba, 0x75, 0x8f, 0x57, 0xd4, 0x1e,
+ 0xc7, 0x1a, 0xc8, 0xf5, 0x56, 0xf7, 0xc0, 0x5c, 0x43, 0xc7, 0x39, 0x4d,
+ 0x25, 0x97, 0x2b, 0xa3, 0xe4, 0xef, 0x9e, 0x5e, 0xe6, 0x99, 0x46, 0xfe,
+ 0xaf, 0xfd, 0xa8, 0x7e, 0x7c, 0x7e, 0x7e, 0x12, 0xfe, 0xd9, 0xf7, 0x2f,
+ 0xec, 0x1a, 0x04, 0x0d, 0xa8, 0x43, 0xd3, 0xe4, 0xf9, 0xd9, 0x19, 0x17,
+ 0x38, 0x8a, 0x0a, 0xf7, 0x25, 0x59, 0x01, 0xee, 0x09, 0xf2, 0x01, 0xb8,
+ 0xe7, 0x38, 0xaf, 0x64, 0x80, 0xf9, 0x46, 0x06, 0x78, 0x23, 0xfd, 0x4c,
+ 0x42, 0xd7, 0x76, 0x5b, 0xb7, 0x07, 0xba, 0x9e, 0x60, 0x6c, 0x7b, 0x0e,
+ 0xba, 0x57, 0x48, 0x52, 0x7f, 0xda, 0x7b, 0xd7, 0xf4, 0xa7, 0x15, 0x7f,
+ 0xbb, 0x94, 0x16, 0x12, 0xc0, 0x6b, 0xca, 0x5c, 0x8e, 0x78, 0x31, 0xae,
+ 0x53, 0xf7, 0x2b, 0xa1, 0xee, 0x77, 0x86, 0xb8, 0x17, 0xc1, 0x93, 0x6c,
+ 0xa6, 0xae, 0xb3, 0x8e, 0xda, 0xa6, 0x6a, 0x5b, 0x03, 0x36, 0x5d, 0xae,
+ 0xb1, 0x0e, 0xe5, 0xfd, 0xc8, 0xa5, 0x99, 0x69, 0xd4, 0xaa, 0xe5, 0xda,
+ 0x88, 0x56, 0x6e, 0xda, 0x5a, 0xd9, 0xa3, 0xbe, 0xed, 0xb2, 0x2e, 0x28,
+ 0x1e, 0xa7, 0x65, 0xa9, 0xf9, 0x4b, 0xbf, 0xba, 0x6b, 0x13, 0xfa, 0xd0,
+ 0xfd, 0x09, 0xca, 0xf7, 0xb3, 0xa4, 0x0b, 0x41, 0x9c, 0xfc, 0x4e, 0xc9,
+ 0xc9, 0x21, 0x14, 0xbd, 0xc8, 0xad, 0x4e, 0x0d, 0x11, 0x3f, 0xe8, 0x48,
+ 0xa5, 0x64, 0xd9, 0xe3, 0x1e, 0x67, 0x67, 0xc8, 0xcb, 0xf2, 0x71, 0x4b,
+ 0x0e, 0x2b, 0xf9, 0xbd, 0xac, 0x6c, 0xbb, 0xbc, 0x62, 0xc8, 0x74, 0x72,
+ 0xd0, 0x7a, 0x58, 0xb2, 0x57, 0x2f, 0x18, 0xd9, 0x67, 0xa6, 0x60, 0xd7,
+ 0x4b, 0x8b, 0x86, 0xb8, 0xaa, 0xde, 0xa2, 0x8c, 0xb2, 0x0b, 0xb0, 0xfc,
+ 0xf0, 0xec, 0x7b, 0x5b, 0xce, 0xde, 0x2d, 0x2b, 0x4f, 0xff, 0x26, 0x7c,
+ 0xce, 0x01, 0xc8, 0xc2, 0xcc, 0x1c, 0x42, 0x5e, 0xf1, 0xb4, 0x0c, 0x5a,
+ 0x55, 0xe4, 0xc9, 0xe0, 0x3b, 0xda, 0x01, 0x65, 0x03, 0x17, 0x74, 0x8c,
+ 0x07, 0xc8, 0x27, 0x8e, 0xaf, 0x95, 0x0b, 0xca, 0x96, 0xd2, 0xea, 0xdd,
+ 0x0e, 0xe0, 0x08, 0xde, 0x71, 0xfc, 0x19, 0xd9, 0xa1, 0xde, 0xdd, 0xa9,
+ 0xde, 0x55, 0xe9, 0x2b, 0x94, 0xfc, 0xbe, 0x82, 0x3d, 0xc9, 0xe3, 0x68,
+ 0xbe, 0x4b, 0x02, 0x5b, 0x8a, 0xf8, 0x6e, 0xc9, 0xc1, 0x46, 0x4a, 0xbe,
+ 0x84, 0xfa, 0xe7, 0x8e, 0xc6, 0x80, 0x94, 0x20, 0xc7, 0xe9, 0xdc, 0x83,
+ 0xbd, 0x3c, 0x5b, 0x71, 0x25, 0xfb, 0x8c, 0xe8, 0xa4, 0xf5, 0x4e, 0x39,
+ 0xe4, 0x45, 0xf4, 0x74, 0x86, 0xf4, 0x4d, 0x86, 0xe3, 0x44, 0x48, 0x43,
+ 0x2b, 0xbe, 0x4e, 0xe0, 0x42, 0xac, 0xcf, 0x79, 0x21, 0x1e, 0xfa, 0x11,
+ 0xd0, 0x3a, 0x99, 0x96, 0x15, 0x8f, 0x74, 0x6c, 0x91, 0x6a, 0x8a, 0xfd,
+ 0x03, 0xd0, 0x37, 0xe2, 0xd9, 0xc4, 0x7c, 0x66, 0x1d, 0x8f, 0x1f, 0x6c,
+ 0x54, 0xc0, 0x63, 0xf2, 0x97, 0xeb, 0x10, 0x23, 0x3e, 0x47, 0xf9, 0xed,
+ 0x46, 0x2e, 0x6f, 0x07, 0xba, 0x69, 0xad, 0xed, 0x59, 0x3a, 0xde, 0x0d,
+ 0x59, 0x71, 0xdf, 0x0e, 0x99, 0x84, 0xdd, 0x17, 0xeb, 0xdc, 0x7f, 0x12,
+ 0x7a, 0x74, 0x51, 0xed, 0x5f, 0x5a, 0xe9, 0x0f, 0xe1, 0x09, 0xdb, 0xbd,
+ 0x01, 0xb6, 0x5d, 0xf6, 0x2e, 0x58, 0x1f, 0x01, 0xff, 0xbb, 0x80, 0xd7,
+ 0xe5, 0x44, 0x8e, 0xf0, 0xc4, 0x83, 0x75, 0xf5, 0xd4, 0x27, 0xe0, 0x49,
+ 0xaa, 0xba, 0xbe, 0x58, 0x6f, 0x97, 0xe2, 0x42, 0x84, 0x8b, 0x78, 0x3e,
+ 0x40, 0xdd, 0x7b, 0xb7, 0xc2, 0x35, 0xad, 0x70, 0xe1, 0x7d, 0x9d, 0x3e,
+ 0xe7, 0x26, 0xc0, 0xa3, 0x76, 0xb7, 0x41, 0x5b, 0xb2, 0x4b, 0xaa, 0xaa,
+ 0x76, 0xef, 0x50, 0xbe, 0xa6, 0x9a, 0xdc, 0x8c, 0xf7, 0x3e, 0xf6, 0xdc,
+ 0x8d, 0x7c, 0xa6, 0x1b, 0x73, 0x99, 0x0d, 0x73, 0x1b, 0xe9, 0x4f, 0x6c,
+ 0xa0, 0xff, 0xbf, 0x7b, 0x19, 0x52, 0xe6, 0x72, 0xc1, 0xba, 0x12, 0xd6,
+ 0xcd, 0x1e, 0x87, 0x4d, 0x30, 0x4f, 0x4f, 0x31, 0x36, 0x5f, 0xa3, 0x68,
+ 0x99, 0x5d, 0xf9, 0x29, 0xd6, 0xf5, 0x03, 0x36, 0x1a, 0x07, 0x7c, 0x78,
+ 0x0a, 0x78, 0x8e, 0xd7, 0xd5, 0x1d, 0x05, 0x64, 0xf0, 0xbe, 0x3a, 0x7b,
+ 0xb5, 0xfe, 0x69, 0x3c, 0xbb, 0xa6, 0x85, 0x5f, 0xe4, 0x15, 0xe9, 0x25,
+ 0xad, 0xbc, 0x2f, 0x82, 0xbd, 0x39, 0xd0, 0xe3, 0xa4, 0x21, 0xa5, 0x1c,
+ 0xe2, 0xba, 0xc7, 0xbb, 0x57, 0xda, 0xe5, 0x40, 0x50, 0x23, 0xd8, 0x8c,
+ 0xef, 0xa6, 0x3a, 0xfb, 0xa1, 0x15, 0xde, 0xbf, 0x66, 0x78, 0x47, 0x37,
+ 0x8c, 0xda, 0x5b, 0x1e, 0x5a, 0xb1, 0xe5, 0x6b, 0x8d, 0x61, 0x79, 0xb8,
+ 0x91, 0xb5, 0xee, 0x81, 0x0f, 0x28, 0xaf, 0xde, 0xcb, 0x6e, 0x4b, 0xd2,
+ 0x7f, 0x99, 0xc8, 0x3d, 0xdb, 0xec, 0x20, 0x17, 0xa9, 0xb2, 0x36, 0x3b,
+ 0x9e, 0xe5, 0x7d, 0x8d, 0x55, 0x97, 0x8d, 0xf9, 0xca, 0xff, 0x65, 0xae,
+ 0xc2, 0xfd, 0xe9, 0xaf, 0x91, 0x9b, 0x78, 0xc8, 0x4d, 0x3c, 0xe4, 0x26,
+ 0x1e, 0x72, 0x13, 0x0f, 0xb9, 0x89, 0x87, 0xdc, 0xc4, 0x43, 0x6e, 0xe2,
+ 0x21, 0x37, 0x41, 0x1d, 0x10, 0xd4, 0x07, 0xe3, 0xc8, 0xb9, 0xe1, 0xbf,
+ 0xbc, 0x5b, 0xc2, 0xdc, 0x22, 0x8a, 0xcd, 0x9c, 0x3b, 0xbf, 0xc9, 0x0d,
+ 0xea, 0x2b, 0xe5, 0x13, 0x0a, 0xcd, 0x89, 0x30, 0x07, 0xe2, 0x9a, 0x28,
+ 0x76, 0x73, 0x9d, 0x8c, 0xb9, 0xa8, 0x3d, 0x0b, 0x93, 0xcc, 0x91, 0x82,
+ 0x98, 0x15, 0xe4, 0xe7, 0xaf, 0x22, 0x4f, 0xca, 0x20, 0x4f, 0x1a, 0x40,
+ 0x4e, 0xc4, 0x7b, 0xea, 0xe8, 0x2e, 0xa9, 0xa0, 0x1d, 0xf4, 0xc6, 0xb5,
+ 0x2f, 0x79, 0xcc, 0xdf, 0xed, 0x4c, 0x59, 0xd7, 0x8f, 0xf7, 0x89, 0x2f,
+ 0xc5, 0xd1, 0xaf, 0x23, 0x57, 0xfe, 0x4b, 0x75, 0x6f, 0x36, 0x31, 0x44,
+ 0x99, 0xdf, 0xf7, 0x31, 0xf9, 0x72, 0xc4, 0xdf, 0xe0, 0xbe, 0x4f, 0x5f,
+ 0x22, 0xff, 0x44, 0x7a, 0xcf, 0x80, 0xe1, 0x67, 0x12, 0x92, 0x3c, 0xb9,
+ 0x05, 0x73, 0x96, 0xf4, 0xa9, 0x3b, 0x23, 0x88, 0xf2, 0xcc, 0x7f, 0x40,
+ 0x5e, 0xb6, 0xe8, 0x67, 0x78, 0xb3, 0x40, 0xbc, 0xf4, 0xaf, 0xf5, 0x99,
+ 0x62, 0xbd, 0xae, 0x74, 0xea, 0x60, 0xa3, 0x84, 0x3c, 0xca, 0xe8, 0x93,
+ 0x0e, 0x13, 0xb5, 0x54, 0x84, 0x9b, 0x38, 0xdf, 0x4c, 0xaa, 0x1a, 0xe7,
+ 0xcc, 0xaa, 0x3c, 0x21, 0x6b, 0xee, 0x53, 0x9f, 0xa9, 0x2e, 0x64, 0xd3,
+ 0xac, 0x71, 0x0b, 0x56, 0x7d, 0xe6, 0x49, 0xe0, 0x58, 0x46, 0x6e, 0x60,
+ 0xa8, 0xbd, 0xeb, 0x33, 0xb3, 0x0b, 0xc1, 0xbd, 0x55, 0x40, 0x03, 0xe3,
+ 0x55, 0x87, 0x18, 0x4b, 0xc1, 0xfd, 0x95, 0xae, 0x60, 0x09, 0x47, 0x78,
+ 0x13, 0x70, 0x94, 0xdb, 0x30, 0x60, 0x29, 0x3b, 0xd2, 0x50, 0x9f, 0xa9,
+ 0xd4, 0x5b, 0x69, 0x20, 0x1e, 0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0x24, 0x45,
+ 0x3f, 0xe9, 0xfb, 0xe5, 0xd1, 0x81, 0xb0, 0xae, 0x44, 0x1d, 0x79, 0xcc,
+ 0x0c, 0xf4, 0x5c, 0x8d, 0xff, 0x58, 0xc5, 0xa9, 0x8c, 0xce, 0x79, 0x3e,
+ 0xf1, 0x2e, 0xf7, 0x28, 0xe6, 0x30, 0x5e, 0x8e, 0xd6, 0xea, 0xe1, 0xda,
+ 0xae, 0x16, 0x7e, 0xb6, 0x85, 0xfb, 0x91, 0x26, 0x9e, 0xf3, 0x15, 0xec,
+ 0x45, 0xba, 0xb8, 0xc6, 0x04, 0x6d, 0x90, 0xa5, 0xf7, 0xbf, 0xe5, 0x7d,
+ 0xeb, 0x99, 0xc8, 0x53, 0x13, 0x30, 0x5c, 0x4f, 0x1c, 0x11, 0x0c, 0x5e,
+ 0x9c, 0x09, 0xe0, 0xf4, 0xd5, 0x7b, 0xbe, 0x4f, 0xda, 0xb7, 0x95, 0xd6,
+ 0x68, 0xff, 0x08, 0xcf, 0x70, 0x20, 0xb7, 0x55, 0x78, 0xf5, 0x7f, 0x7f,
+ 0xe1, 0x09, 0x5d, 0xfc, 0xd0, 0x7d, 0xe9, 0x70, 0x4b, 0x8d, 0x1c, 0xdd,
+ 0x3b, 0xb0, 0xfe, 0x67, 0x3d, 0xcf, 0xef, 0x03, 0xad, 0xf5, 0x69, 0x29,
+ 0x8c, 0x65, 0xdb, 0xa4, 0x60, 0xb2, 0x56, 0x19, 0x0f, 0xc7, 0x5b, 0x11,
+ 0xdb, 0x38, 0xbe, 0x15, 0xfc, 0x85, 0x2e, 0x3b, 0x1d, 0x61, 0xad, 0x94,
+ 0x0c, 0xbe, 0xeb, 0x0c, 0xd3, 0x8e, 0x58, 0x6b, 0x6e, 0x0e, 0xe7, 0x22,
+ 0x3b, 0xa2, 0x1f, 0x36, 0xc3, 0x39, 0xfa, 0x5b, 0x1d, 0xf5, 0x12, 0xfb,
+ 0xc0, 0xb3, 0xdc, 0x6a, 0x4b, 0xd1, 0x33, 0x29, 0xa7, 0x17, 0x23, 0xbf,
+ 0x05, 0x9f, 0x32, 0x64, 0x86, 0xbe, 0xbf, 0x13, 0xbe, 0xaf, 0x5b, 0xf6,
+ 0xc2, 0x67, 0xed, 0x83, 0xcf, 0xda, 0x8f, 0x1a, 0x75, 0x7c, 0xa5, 0xf5,
+ 0x3e, 0x97, 0x75, 0x71, 0x55, 0x0e, 0x29, 0xf9, 0x57, 0x7c, 0xc3, 0xfe,
+ 0x00, 0x3a, 0xb0, 0x53, 0xe5, 0x7b, 0x81, 0x4e, 0xc0, 0xdf, 0x3a, 0x49,
+ 0xe8, 0xc4, 0xc6, 0x7b, 0xe3, 0x61, 0xd8, 0x46, 0x47, 0x41, 0xc5, 0x86,
+ 0x95, 0x80, 0xf7, 0xd5, 0x7a, 0xc0, 0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5,
+ 0xd2, 0xb0, 0xa4, 0x82, 0x7d, 0x2b, 0xd8, 0xb7, 0x82, 0xda, 0x72, 0xb6,
+ 0xd1, 0xfa, 0xed, 0xaa, 0x2b, 0xa4, 0x9d, 0xb0, 0x51, 0xdf, 0x6a, 0x39,
+ 0x7f, 0xf4, 0x3c, 0x02, 0xfe, 0x3f, 0x02, 0xfe, 0x1f, 0x46, 0x4d, 0xf5,
+ 0x00, 0x6a, 0xaa, 0xfb, 0x50, 0x53, 0x1d, 0x42, 0x4d, 0x35, 0x85, 0x9a,
+ 0xea, 0x6e, 0xf8, 0x8f, 0x3b, 0xe1, 0x3f, 0x26, 0xe1, 0x3f, 0x26, 0xd4,
+ 0x9d, 0xd1, 0x41, 0x6f, 0xe3, 0x1d, 0x4a, 0xb4, 0x17, 0xdb, 0x1b, 0x22,
+ 0x50, 0x81, 0xf2, 0xb1, 0x71, 0xa9, 0x37, 0x59, 0x5b, 0x39, 0xea, 0x3e,
+ 0x6c, 0xda, 0x99, 0xd4, 0xa6, 0x90, 0xbf, 0xdf, 0x33, 0xc2, 0x9a, 0x2b,
+ 0xa9, 0x15, 0x55, 0xcd, 0x95, 0x7d, 0xc1, 0x45, 0x8a, 0x84, 0xdc, 0x0f,
+ 0x67, 0xce, 0x9e, 0x2e, 0x1a, 0x51, 0xbd, 0xd3, 0xbb, 0x5a, 0xef, 0x2c,
+ 0xcf, 0xb3, 0xde, 0x79, 0x75, 0xb5, 0xde, 0x59, 0x9e, 0x67, 0xbd, 0xf3,
+ 0xca, 0xba, 0x7a, 0xe7, 0xca, 0xd3, 0x97, 0xd6, 0xd5, 0x3b, 0x57, 0x9e,
+ 0x7e, 0x29, 0x1c, 0x4b, 0xa8, 0x0f, 0x21, 0xad, 0x96, 0x83, 0x67, 0x4f,
+ 0x98, 0x73, 0x34, 0xfb, 0xd6, 0xff, 0xdf, 0x74, 0xca, 0x96, 0x35, 0xb1,
+ 0xff, 0x68, 0x6b, 0x50, 0x23, 0xb5, 0xce, 0x77, 0xb7, 0xcc, 0x5f, 0x56,
+ 0xdf, 0x4b, 0xcb, 0xb5, 0xcd, 0xef, 0xc2, 0x03, 0xcb, 0xca, 0x10, 0xf3,
+ 0xbc, 0x0f, 0x7c, 0x7e, 0xf3, 0x73, 0xf5, 0x0e, 0xf5, 0xcd, 0xcd, 0x55,
+ 0xf9, 0x36, 0xec, 0x7c, 0xf4, 0xd1, 0xad, 0x81, 0x2f, 0x60, 0x3f, 0xa5,
+ 0x05, 0xfe, 0xfd, 0x01, 0xe0, 0x01, 0xaf, 0x3d, 0x53, 0xdd, 0x07, 0x05,
+ 0xe7, 0x0d, 0xee, 0xc6, 0xcd, 0xfc, 0xe5, 0x19, 0xe6, 0xd6, 0x55, 0x85,
+ 0x9b, 0xf5, 0x23, 0x6b, 0xce, 0x28, 0x06, 0x44, 0xb8, 0x5e, 0x4d, 0x05,
+ 0x74, 0xbb, 0xa8, 0x1d, 0xb9, 0x26, 0x1a, 0xb7, 0xd6, 0x9a, 0x9d, 0xe1,
+ 0xbd, 0xdb, 0xe5, 0x20, 0xaf, 0x52, 0xf8, 0xcc, 0x10, 0xdf, 0xcf, 0xfd,
+ 0xc0, 0xf7, 0x10, 0xde, 0x6a, 0x81, 0x1f, 0x47, 0xae, 0xc7, 0x7b, 0x1a,
+ 0xe6, 0x6c, 0xa6, 0xbc, 0x33, 0xdf, 0x25, 0xff, 0x79, 0xd4, 0xf7, 0x27,
+ 0x9c, 0xec, 0xf0, 0x25, 0xd4, 0x1e, 0x27, 0x69, 0x27, 0xa3, 0xa4, 0x73,
+ 0x30, 0x33, 0x2b, 0xa9, 0x3e, 0xd2, 0x72, 0x5e, 0x3f, 0xac, 0x7d, 0x98,
+ 0x6e, 0x3d, 0xdc, 0xe7, 0x1f, 0x5b, 0xf6, 0xc9, 0xb4, 0xec, 0x53, 0xa0,
+ 0xcd, 0xd6, 0xef, 0xc0, 0x99, 0x2b, 0xdb, 0xaf, 0xb7, 0x52, 0x61, 0x5d,
+ 0xf6, 0xf0, 0xe8, 0x66, 0x59, 0xe8, 0xcf, 0x9e, 0x7d, 0x05, 0xf9, 0x7a,
+ 0x79, 0x14, 0x73, 0xa9, 0x41, 0xbc, 0xe3, 0x7c, 0xb6, 0x8e, 0x5c, 0xf4,
+ 0x6c, 0x5d, 0xb6, 0x01, 0x3e, 0x5b, 0x11, 0xe1, 0x3c, 0xfb, 0x8a, 0xb6,
+ 0x7a, 0xe8, 0x03, 0xd2, 0x17, 0x70, 0xe6, 0x29, 0xd4, 0x5f, 0x87, 0x83,
+ 0x7b, 0xb4, 0x70, 0x9f, 0x1b, 0xb5, 0x20, 0x6f, 0xce, 0x69, 0x95, 0xf0,
+ 0x0e, 0xf0, 0x2b, 0xf0, 0x17, 0x86, 0x4e, 0xd8, 0x77, 0x80, 0x5b, 0x93,
+ 0xa5, 0xa3, 0x86, 0xba, 0x3b, 0x2d, 0x8f, 0x52, 0xd6, 0x7c, 0x7e, 0x14,
+ 0xef, 0xa2, 0x33, 0xfd, 0x4d, 0x78, 0xa6, 0xd1, 0xb0, 0x6e, 0x8f, 0xce,
+ 0x94, 0x90, 0xd7, 0xe7, 0x2d, 0xc0, 0x8e, 0x80, 0x1f, 0x25, 0x59, 0x69,
+ 0x66, 0x3e, 0x05, 0x4f, 0xad, 0x85, 0x37, 0xe6, 0x06, 0x19, 0x46, 0x75,
+ 0x0f, 0x78, 0x30, 0x91, 0x86, 0x1d, 0xde, 0xd7, 0x17, 0xdd, 0xe9, 0x1a,
+ 0xb6, 0xae, 0x05, 0x75, 0x3c, 0xe7, 0x07, 0x60, 0x8b, 0x19, 0xd8, 0x27,
+ 0x73, 0xa6, 0x12, 0x6b, 0x15, 0xda, 0x93, 0xe5, 0x1a, 0x59, 0x6b, 0x52,
+ 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x79, 0x59, 0x6e, 0x46, 0x34, 0xe4, 0x60,
+ 0x8f, 0x63, 0xf8, 0x8d, 0xe0, 0x9d, 0x83, 0x1f, 0x6b, 0xa5, 0x82, 0x7c,
+ 0x55, 0xe5, 0xe2, 0xc8, 0xb5, 0x87, 0x48, 0xdf, 0x01, 0xac, 0xa7, 0x3e,
+ 0x53, 0x4f, 0x0f, 0x88, 0xdb, 0x4f, 0x5f, 0x91, 0x06, 0x6e, 0xc0, 0x78,
+ 0xaf, 0xc1, 0xd6, 0x07, 0xf0, 0xcc, 0x5a, 0x65, 0xf2, 0x56, 0xe1, 0xf7,
+ 0x7d, 0x23, 0xc7, 0x6f, 0x11, 0xe3, 0xe1, 0x78, 0xd0, 0xfa, 0x1d, 0xea,
+ 0x5e, 0xfa, 0x5a, 0x39, 0xbb, 0x18, 0xc5, 0xc1, 0x19, 0xd8, 0x20, 0xef,
+ 0x68, 0xc7, 0xc1, 0x17, 0x8e, 0xb5, 0x30, 0x1e, 0x62, 0x7e, 0xf9, 0xaf,
+ 0x70, 0xee, 0xbc, 0x9c, 0x44, 0xfd, 0x2f, 0xfd, 0x7c, 0x66, 0x80, 0x7f,
+ 0x4b, 0xa8, 0xef, 0xeb, 0xe1, 0x0d, 0x9b, 0xfd, 0x71, 0xd0, 0x67, 0xb6,
+ 0xc0, 0x13, 0x26, 0xac, 0x4f, 0x04, 0xf1, 0x38, 0xed, 0xdf, 0xaa, 0xe7,
+ 0xef, 0x96, 0x3f, 0x50, 0x67, 0xca, 0xcb, 0xa1, 0x45, 0xdf, 0x77, 0x73,
+ 0x83, 0xc3, 0xcb, 0x92, 0x1d, 0x7e, 0x52, 0x76, 0x5b, 0x7b, 0x59, 0x8f,
+ 0x59, 0xc4, 0xe3, 0xdf, 0xda, 0x96, 0xf7, 0xfd, 0x13, 0xa0, 0xfd, 0x07,
+ 0x6a, 0x9f, 0xbb, 0x41, 0x3f, 0x78, 0xa5, 0x6a, 0x12, 0xd2, 0x0a, 0xde,
+ 0xa4, 0x48, 0x6f, 0xa7, 0x1c, 0x6a, 0x3e, 0x1f, 0xca, 0xe6, 0x11, 0x71,
+ 0xbd, 0xb7, 0x0d, 0xde, 0x6f, 0x97, 0x9b, 0x8f, 0x86, 0xb4, 0xe5, 0x41,
+ 0x2f, 0xf6, 0x6f, 0xfe, 0x43, 0x8a, 0xbe, 0x81, 0x32, 0x77, 0x91, 0x35,
+ 0xba, 0xa3, 0xcf, 0x40, 0x07, 0x3f, 0xce, 0x0f, 0x24, 0x65, 0xbd, 0x1f,
+ 0x20, 0x5c, 0xf2, 0x23, 0x74, 0x85, 0x74, 0x88, 0xf2, 0x9f, 0x2a, 0x6e,
+ 0x29, 0x7c, 0xc6, 0x06, 0x5f, 0xf0, 0xa4, 0x7a, 0x9e, 0x37, 0xe8, 0x9b,
+ 0x18, 0xff, 0xa8, 0xc3, 0xdd, 0xf0, 0x7f, 0xd0, 0x41, 0xd8, 0x71, 0x71,
+ 0x91, 0xf7, 0x13, 0x43, 0xea, 0x4e, 0xab, 0x04, 0xd9, 0x2e, 0xf1, 0x3b,
+ 0x63, 0x2a, 0xc8, 0x27, 0x83, 0xfa, 0x2b, 0x43, 0x5f, 0x88, 0xf6, 0xb8,
+ 0xf2, 0x93, 0x25, 0xf5, 0x5d, 0x31, 0x89, 0x35, 0x3e, 0x9e, 0xad, 0x7f,
+ 0x27, 0xf1, 0xa3, 0x42, 0xf0, 0x77, 0x12, 0xe1, 0x37, 0xde, 0x7a, 0x90,
+ 0x47, 0x3c, 0xd8, 0x30, 0x65, 0xaa, 0x11, 0xfd, 0xdd, 0x04, 0xe5, 0x60,
+ 0x4b, 0xb9, 0x11, 0xe5, 0x0e, 0x7e, 0x50, 0xd3, 0xac, 0x93, 0xe5, 0xe3,
+ 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4, 0x78, 0x39, 0x90, 0xdf, 0x92,
+ 0xbe, 0x03, 0xf2, 0x03, 0xcf, 0x3d, 0x13, 0xb6, 0x94, 0x0e, 0xe3, 0xba,
+ 0xc5, 0x1a, 0x33, 0xac, 0x7b, 0xb7, 0x4b, 0x75, 0x92, 0xef, 0x13, 0xf2,
+ 0xda, 0xfc, 0x40, 0x70, 0x4f, 0x24, 0x89, 0xf0, 0x3d, 0xc7, 0x49, 0x29,
+ 0xab, 0xf7, 0x77, 0x86, 0xf8, 0x50, 0xa7, 0xdd, 0x19, 0x8d, 0xd3, 0x90,
+ 0x63, 0x00, 0x37, 0x8d, 0x58, 0xf6, 0x55, 0xc4, 0xb1, 0x69, 0xf0, 0xbd,
+ 0x38, 0x51, 0x91, 0x6b, 0x6d, 0x4b, 0xc5, 0x7d, 0x37, 0x49, 0x1d, 0xa3,
+ 0x7e, 0x11, 0xa6, 0x07, 0xb9, 0x2a, 0xce, 0x3b, 0x2a, 0x53, 0x46, 0xfe,
+ 0xdd, 0xdb, 0xca, 0xb5, 0xac, 0x55, 0x90, 0xf7, 0x7d, 0xd7, 0xe4, 0xf8,
+ 0xfc, 0x6d, 0x0f, 0x06, 0x77, 0xfe, 0xba, 0x9e, 0xbf, 0x78, 0x5b, 0x39,
+ 0xe8, 0xe3, 0xcc, 0xef, 0x86, 0x7d, 0xc2, 0x19, 0xea, 0x7b, 0xec, 0x4f,
+ 0x6e, 0x32, 0xe5, 0xc2, 0x4d, 0xbe, 0x7f, 0x0f, 0xbf, 0x09, 0x85, 0x75,
+ 0xac, 0xa5, 0xea, 0xd8, 0x0e, 0x95, 0x8f, 0xb8, 0xa3, 0x19, 0xad, 0x04,
+ 0xdb, 0x3d, 0xe9, 0xa1, 0xe6, 0xd1, 0xb3, 0x63, 0xe7, 0x75, 0x0b, 0xf1,
+ 0x37, 0x9b, 0x39, 0x2e, 0xb9, 0x3e, 0x7e, 0x63, 0x9e, 0x73, 0xb8, 0x66,
+ 0x5b, 0x70, 0xef, 0x75, 0x83, 0xab, 0x7c, 0xae, 0x48, 0x18, 0x87, 0x6e,
+ 0x68, 0xb5, 0x8f, 0xd6, 0x3c, 0x93, 0x76, 0x21, 0x53, 0x26, 0xe8, 0xa9,
+ 0xd6, 0xa2, 0x9c, 0x8d, 0x7f, 0x0f, 0x70, 0xfe, 0xb6, 0xa7, 0x1a, 0x17,
+ 0x6f, 0x9b, 0x85, 0x7c, 0x78, 0xa6, 0xd9, 0x46, 0xa4, 0x7f, 0x51, 0xdd,
+ 0xc0, 0x3e, 0xe2, 0xbf, 0x87, 0xf8, 0xef, 0x21, 0xfe, 0x7b, 0x88, 0xff,
+ 0x1e, 0xe2, 0xbf, 0x87, 0xf8, 0x0f, 0x1e, 0x3e, 0x07, 0x7d, 0x79, 0xd6,
+ 0x9b, 0x08, 0x73, 0xb6, 0xc7, 0x56, 0x73, 0x36, 0xfe, 0xcd, 0xcb, 0xb9,
+ 0xa6, 0xa2, 0xa5, 0x52, 0x91, 0x20, 0xe7, 0x15, 0x9d, 0xf9, 0x4d, 0x94,
+ 0xf3, 0x7e, 0xf4, 0xf7, 0x90, 0x00, 0x8e, 0xf9, 0x1e, 0xe1, 0x2a, 0x9a,
+ 0x6e, 0x13, 0x2e, 0xc8, 0xf9, 0x58, 0x67, 0xad, 0x87, 0xe1, 0x77, 0x37,
+ 0xfa, 0xb6, 0xe0, 0x9b, 0x4f, 0xf0, 0x7d, 0xa9, 0x76, 0x87, 0x8b, 0x58,
+ 0x5c, 0x6e, 0xa8, 0x78, 0x8c, 0x71, 0xe3, 0x0e, 0xfe, 0xad, 0x02, 0x64,
+ 0xc0, 0x77, 0x5f, 0x66, 0x6d, 0x51, 0x6e, 0x20, 0x2f, 0x5a, 0x8e, 0x72,
+ 0x21, 0xc0, 0x79, 0x6f, 0x6a, 0xa5, 0x05, 0xca, 0x59, 0x97, 0xd9, 0x14,
+ 0x98, 0x62, 0xb7, 0xe6, 0x78, 0x97, 0x54, 0xbd, 0x74, 0xb6, 0x49, 0x7a,
+ 0x46, 0x40, 0x5b, 0x74, 0x8f, 0x2c, 0x62, 0xcc, 0xa7, 0x44, 0x9f, 0x47,
+ 0x7e, 0x6b, 0x0f, 0xa9, 0xbf, 0x6f, 0xe8, 0xc5, 0x3e, 0xfa, 0xfc, 0x8e,
+ 0x96, 0x7b, 0x5a, 0x29, 0x04, 0x3e, 0x9b, 0xb1, 0x87, 0xe7, 0x48, 0xc1,
+ 0x76, 0xdd, 0x6d, 0x38, 0x1b, 0xe4, 0xfa, 0xaf, 0x5b, 0x55, 0x0e, 0x0e,
+ 0x3f, 0x7a, 0x62, 0xa8, 0xbf, 0x5f, 0xba, 0xb7, 0xcb, 0xc9, 0x21, 0xd6,
+ 0x6b, 0x9b, 0x81, 0x8f, 0x6b, 0x79, 0xff, 0xb4, 0x5d, 0x4e, 0x2d, 0xc2,
+ 0xcf, 0x2e, 0x66, 0x1d, 0xea, 0xf2, 0xd2, 0x50, 0x0a, 0xfe, 0xf9, 0xe6,
+ 0x7e, 0xc6, 0xe7, 0xe5, 0x26, 0x75, 0xa5, 0x17, 0xf0, 0x03, 0xd0, 0xcb,
+ 0x4d, 0xb0, 0x27, 0x1d, 0xfb, 0x47, 0xb8, 0xff, 0x45, 0xe1, 0xee, 0xb5,
+ 0x9d, 0x6d, 0x4a, 0x37, 0xf4, 0xac, 0x95, 0xd1, 0x41, 0xfb, 0xff, 0x14,
+ 0x6e, 0x6d, 0x31, 0x71, 0x5c, 0x67, 0xf8, 0x3f, 0xb3, 0xdc, 0x8c, 0xd7,
+ 0x30, 0x86, 0xf5, 0xb2, 0x58, 0xae, 0xba, 0x03, 0x63, 0x33, 0xd1, 0x62,
+ 0x65, 0xb0, 0xec, 0x16, 0x55, 0x96, 0xba, 0xda, 0x05, 0x42, 0xe2, 0x3a,
+ 0xdd, 0x24, 0xb4, 0x72, 0xd5, 0x2a, 0x42, 0x60, 0x37, 0x8e, 0xfa, 0xd2,
+ 0x46, 0x55, 0xdb, 0x37, 0xaf, 0x16, 0xec, 0x38, 0xcd, 0xac, 0x17, 0x37,
+ 0x38, 0xf4, 0x71, 0xb3, 0x2c, 0x0e, 0x90, 0x75, 0x56, 0x6e, 0xf2, 0x90,
+ 0x3e, 0x19, 0x6d, 0xa2, 0x24, 0x55, 0xa5, 0xbc, 0x54, 0x7d, 0xab, 0x5a,
+ 0x0b, 0x27, 0xc4, 0x0f, 0xa9, 0xad, 0xf6, 0xa5, 0x77, 0x4d, 0xbf, 0xef,
+ 0xcc, 0x2c, 0xc6, 0xa4, 0x51, 0x91, 0x56, 0x73, 0xe6, 0xcc, 0xb9, 0x9f,
+ 0xff, 0xf2, 0xfd, 0x17, 0x3e, 0x67, 0x67, 0xba, 0xc2, 0xbd, 0xcd, 0x95,
+ 0x76, 0xc6, 0xfe, 0xb6, 0xd4, 0xcc, 0x02, 0xf3, 0x1a, 0x86, 0x64, 0xdc,
+ 0x64, 0xae, 0xcf, 0x96, 0x3a, 0x57, 0x66, 0x1b, 0x1b, 0x65, 0xda, 0xe4,
+ 0x4b, 0x6a, 0xa6, 0xdc, 0x23, 0x17, 0x41, 0xc7, 0x85, 0xe1, 0xd6, 0xd0,
+ 0xf7, 0xda, 0x19, 0xf2, 0x73, 0x77, 0x3c, 0xd4, 0x57, 0x1a, 0x57, 0x16,
+ 0x34, 0xb6, 0xee, 0xde, 0xf5, 0xed, 0x49, 0xac, 0x29, 0x41, 0x5f, 0x79,
+ 0x5c, 0xcb, 0x26, 0x83, 0xef, 0x7d, 0xbb, 0xde, 0xe3, 0xbb, 0xde, 0x0f,
+ 0xfc, 0x8f, 0xf6, 0x2c, 0xef, 0xa6, 0x07, 0xae, 0xd3, 0x1a, 0xe5, 0x2c,
+ 0x05, 0xcf, 0x36, 0x66, 0x3d, 0x2b, 0x4d, 0x5c, 0x90, 0x15, 0x5f, 0x65,
+ 0xdd, 0x36, 0xc8, 0xbb, 0x36, 0x99, 0x5f, 0x04, 0xcd, 0x63, 0x1f, 0xed,
+ 0x36, 0x63, 0xe4, 0x43, 0x71, 0xf2, 0x4c, 0x07, 0xae, 0xc1, 0xb0, 0x07,
+ 0x13, 0x68, 0xe7, 0x3f, 0xef, 0xa6, 0xcc, 0xb3, 0xda, 0x97, 0x43, 0x3c,
+ 0xe3, 0xab, 0x82, 0xce, 0xf7, 0x60, 0x9b, 0x16, 0xb9, 0x63, 0x67, 0x7a,
+ 0xc2, 0x7c, 0x20, 0xd8, 0xbe, 0x5f, 0x8d, 0x13, 0x6b, 0x3c, 0xe7, 0x6e,
+ 0xd7, 0x99, 0x9b, 0xc2, 0x1c, 0x2b, 0x10, 0xcd, 0x53, 0x22, 0xe5, 0xaa,
+ 0xc8, 0xeb, 0xf8, 0xfd, 0xa6, 0x1a, 0xc6, 0x4f, 0x14, 0xed, 0xee, 0x93,
+ 0xb2, 0x5e, 0xfa, 0x9a, 0xd4, 0xa0, 0x7f, 0xd6, 0x5c, 0xdf, 0xbf, 0xeb,
+ 0x26, 0xf5, 0x99, 0xbf, 0xe8, 0x29, 0x19, 0x18, 0xa1, 0x7e, 0x6b, 0x93,
+ 0x97, 0x17, 0x5b, 0x64, 0xc3, 0xb4, 0xcc, 0xbb, 0x44, 0x01, 0x5e, 0x42,
+ 0x26, 0x63, 0x11, 0x8d, 0x51, 0xe5, 0x5b, 0x22, 0x5b, 0xf8, 0xb6, 0xb5,
+ 0xf8, 0x4c, 0x9c, 0xfe, 0x97, 0x4f, 0x16, 0xf9, 0x6e, 0xe0, 0x69, 0x48,
+ 0xc3, 0x8e, 0x00, 0xcb, 0x42, 0x08, 0x99, 0x3c, 0x77, 0xee, 0xf7, 0xbb,
+ 0x5c, 0x1b, 0xea, 0x68, 0xcf, 0xb6, 0x49, 0xe1, 0x30, 0x64, 0xa2, 0x1a,
+ 0xd4, 0x39, 0x47, 0x8d, 0x98, 0x96, 0xd1, 0x91, 0x0a, 0x7d, 0xf8, 0xe6,
+ 0x5e, 0x2d, 0xaf, 0x33, 0x37, 0x7e, 0xa4, 0xf7, 0x82, 0x72, 0xbe, 0xe2,
+ 0x92, 0x56, 0x4d, 0x59, 0x03, 0xaf, 0xad, 0xd6, 0x5f, 0xed, 0xe3, 0x5d,
+ 0xad, 0xd7, 0x5f, 0x88, 0x07, 0xf6, 0x1a, 0xeb, 0x7e, 0x1c, 0x0f, 0xea,
+ 0x92, 0xa1, 0xfd, 0x45, 0x3b, 0xad, 0x8c, 0xbd, 0xbd, 0x20, 0xf5, 0xa5,
+ 0x9f, 0xc9, 0x3b, 0xa5, 0x9f, 0xc8, 0xaf, 0x97, 0xce, 0x00, 0x7f, 0x58,
+ 0xe5, 0x3c, 0xf4, 0xc9, 0xcd, 0xba, 0xef, 0xdf, 0x74, 0xa7, 0x60, 0x2b,
+ 0xf8, 0xfe, 0xef, 0xdc, 0x0d, 0x19, 0x38, 0xf6, 0x3d, 0xec, 0x39, 0x07,
+ 0x1e, 0xa2, 0x2c, 0x9c, 0x04, 0xbd, 0xb9, 0x7d, 0xd2, 0x19, 0xd5, 0x74,
+ 0x32, 0x78, 0xac, 0x15, 0x7b, 0x30, 0x42, 0x4c, 0xce, 0xbd, 0x8c, 0xf4,
+ 0x91, 0x66, 0x8c, 0x7a, 0x09, 0xf3, 0xb7, 0x82, 0x2f, 0xf6, 0xe2, 0xa7,
+ 0xe4, 0xee, 0x08, 0xd6, 0x3a, 0x42, 0xda, 0x6b, 0x95, 0x81, 0x47, 0xb1,
+ 0x8f, 0x5c, 0x8b, 0xdc, 0xf3, 0x7e, 0x19, 0xa7, 0x6f, 0xef, 0x9e, 0xc7,
+ 0xb2, 0xf1, 0x95, 0x2e, 0xf1, 0xa5, 0x05, 0xba, 0x7c, 0xfe, 0x78, 0x80,
+ 0x9b, 0xde, 0x55, 0x43, 0x68, 0x6f, 0xe7, 0xdf, 0x53, 0xc4, 0x79, 0x79,
+ 0xbf, 0x15, 0xb8, 0x7c, 0x1c, 0x78, 0x28, 0x53, 0xbf, 0x20, 0x8d, 0x91,
+ 0x28, 0xda, 0x10, 0xaf, 0x68, 0x59, 0x22, 0x59, 0x8f, 0x39, 0x5a, 0xcc,
+ 0x97, 0xc2, 0x1a, 0xa7, 0x74, 0x2e, 0x57, 0x1f, 0xcf, 0x9c, 0x58, 0x3e,
+ 0xa8, 0xb3, 0x41, 0x23, 0xac, 0x23, 0x7d, 0xa7, 0x35, 0xa6, 0x82, 0x0e,
+ 0xc5, 0x78, 0xc3, 0x92, 0xd1, 0xe5, 0x2e, 0x8c, 0x77, 0x41, 0x32, 0x6e,
+ 0x73, 0xcc, 0x51, 0xb4, 0xa1, 0x9c, 0x19, 0x05, 0x96, 0xf8, 0x58, 0x8d,
+ 0x2d, 0xc6, 0xa0, 0xcb, 0xe3, 0x32, 0x66, 0xee, 0xd9, 0xb1, 0xc7, 0xbc,
+ 0xb6, 0x15, 0x0c, 0x63, 0x38, 0x5c, 0x53, 0xd7, 0x8e, 0x35, 0xb1, 0x3f,
+ 0x7e, 0xb0, 0x93, 0x33, 0x8b, 0x0b, 0x90, 0x53, 0x0b, 0x1f, 0x66, 0xdc,
+ 0x67, 0x25, 0x1b, 0x6b, 0xd3, 0xb6, 0x4d, 0x05, 0xf7, 0x92, 0xf5, 0xe8,
+ 0xd3, 0xfa, 0x0e, 0xe4, 0xd0, 0x9e, 0xb0, 0x8e, 0x6d, 0xc5, 0xc8, 0xe0,
+ 0xec, 0x03, 0x1b, 0x97, 0x75, 0x5f, 0x96, 0xcc, 0x42, 0x4e, 0x26, 0x74,
+ 0x3f, 0x9e, 0xe1, 0x41, 0x8d, 0x43, 0xc8, 0xab, 0x03, 0xbd, 0x38, 0xcb,
+ 0xd4, 0x03, 0x7b, 0x38, 0xd9, 0x4b, 0x2e, 0xfa, 0x4f, 0xc8, 0xb3, 0xf8,
+ 0xd6, 0xcb, 0x3b, 0x6a, 0x93, 0x81, 0x67, 0xa0, 0x2f, 0xbd, 0x66, 0x7d,
+ 0x54, 0x3e, 0xf3, 0xfc, 0x38, 0x63, 0x2e, 0x7f, 0xf6, 0x4c, 0xf9, 0xc4,
+ 0xd3, 0xb1, 0xd8, 0xe9, 0x88, 0x58, 0xe7, 0x03, 0x5b, 0xfd, 0xf0, 0xf4,
+ 0xbc, 0xe2, 0xf7, 0xc3, 0xe7, 0x57, 0x54, 0x07, 0xda, 0x46, 0xd1, 0x8e,
+ 0xeb, 0x30, 0x65, 0xdc, 0xfb, 0xab, 0x3f, 0x73, 0xc4, 0xf7, 0x27, 0x74,
+ 0x4e, 0x58, 0xca, 0x9c, 0x57, 0x4d, 0x7c, 0xee, 0x88, 0x17, 0x6b, 0xc7,
+ 0x5c, 0x29, 0x73, 0x45, 0x1d, 0xc6, 0x7a, 0x58, 0xee, 0x25, 0x4f, 0x24,
+ 0x36, 0x84, 0xe3, 0x5b, 0x93, 0xcb, 0x2a, 0x95, 0x1c, 0x54, 0x56, 0xba,
+ 0x80, 0x5f, 0x8b, 0xd2, 0x71, 0xcc, 0x44, 0x52, 0x81, 0x77, 0xb1, 0x27,
+ 0xfb, 0xa8, 0xef, 0x4f, 0xda, 0xac, 0x4f, 0x99, 0x51, 0x45, 0xdf, 0x4b,
+ 0xa7, 0x8e, 0x77, 0x5e, 0x3e, 0x90, 0x32, 0x8f, 0xaa, 0xfd, 0xe1, 0xfb,
+ 0x28, 0x64, 0xe6, 0xf6, 0x78, 0x67, 0x96, 0x95, 0x29, 0x2f, 0x79, 0xa9,
+ 0xe4, 0xac, 0xb2, 0x72, 0x18, 0x33, 0x37, 0xa6, 0x28, 0x37, 0x52, 0x66,
+ 0xa7, 0xa2, 0x7f, 0xb4, 0x5d, 0xef, 0x7b, 0x12, 0xfd, 0x53, 0xaa, 0x25,
+ 0x5c, 0x0f, 0xef, 0xeb, 0x4a, 0x5f, 0xc0, 0x33, 0x94, 0x39, 0xfd, 0xc6,
+ 0xcc, 0x02, 0xf3, 0xcb, 0x74, 0x5e, 0x43, 0x7a, 0xe0, 0x18, 0xdf, 0x0d,
+ 0xb9, 0x7f, 0xe2, 0x6f, 0xa8, 0x43, 0xb9, 0xcc, 0x3a, 0x27, 0xe4, 0xb7,
+ 0x23, 0x1a, 0x3f, 0xdf, 0x3f, 0x91, 0xd7, 0xb9, 0x8b, 0x0d, 0x35, 0x10,
+ 0xee, 0x7b, 0xfb, 0xce, 0x92, 0x19, 0xf7, 0x4b, 0x1c, 0x67, 0x21, 0x72,
+ 0xb2, 0x5d, 0x98, 0x23, 0x3a, 0x5e, 0x6a, 0xd2, 0x06, 0x7d, 0x03, 0xcc,
+ 0x15, 0x68, 0xc6, 0xdd, 0x2f, 0x88, 0x71, 0xac, 0x63, 0x07, 0x9d, 0x00,
+ 0x77, 0x02, 0xaf, 0x56, 0x31, 0x4e, 0x61, 0x51, 0xf2, 0x41, 0x7f, 0xe9,
+ 0x60, 0x4e, 0x6a, 0xa1, 0xfa, 0x45, 0x63, 0x04, 0x3a, 0x70, 0x1c, 0xef,
+ 0xf7, 0x4f, 0x90, 0x3e, 0x79, 0x36, 0x49, 0x35, 0xbe, 0xc4, 0xf5, 0x1c,
+ 0x94, 0x89, 0x45, 0x60, 0x23, 0xfc, 0xe6, 0x17, 0x83, 0x7b, 0xbb, 0x0e,
+ 0x9c, 0x3d, 0xe1, 0x99, 0x9a, 0x5f, 0x67, 0x5d, 0xc6, 0x4f, 0xc0, 0x2b,
+ 0x3a, 0x8f, 0x8a, 0x7d, 0x99, 0x4b, 0x78, 0x88, 0xfa, 0xd1, 0x6d, 0x48,
+ 0x0c, 0x6d, 0x89, 0x59, 0x59, 0x6f, 0x8d, 0x26, 0x23, 0xdd, 0x32, 0x0f,
+ 0x79, 0x57, 0x81, 0xee, 0x2c, 0x5c, 0x89, 0xca, 0xac, 0xa7, 0xe3, 0xd9,
+ 0xc9, 0x8f, 0x95, 0x2b, 0xb5, 0xfa, 0x71, 0xb9, 0x51, 0x77, 0xf4, 0x37,
+ 0xea, 0xb5, 0xc2, 0xab, 0x86, 0x7c, 0xff, 0x88, 0xce, 0xa5, 0x73, 0x2a,
+ 0xd2, 0xd9, 0x4f, 0xcc, 0xb3, 0xa2, 0xf3, 0xea, 0x20, 0x3b, 0x80, 0x39,
+ 0xde, 0x06, 0xe6, 0x78, 0x0b, 0x98, 0xe3, 0x57, 0xc0, 0xd8, 0x37, 0x4b,
+ 0x93, 0xa1, 0xfc, 0x9f, 0x86, 0x1c, 0xa2, 0xae, 0xb6, 0xce, 0xe0, 0x4e,
+ 0xa7, 0xf3, 0xa0, 0xc1, 0xdb, 0xb0, 0x3f, 0xd6, 0x4b, 0x19, 0x59, 0x5d,
+ 0x9a, 0x90, 0xb5, 0xa5, 0x20, 0x0f, 0xf9, 0x03, 0xe6, 0x7d, 0x8d, 0xf0,
+ 0x9e, 0x1c, 0xc8, 0xa1, 0x3d, 0x32, 0x70, 0x94, 0xf2, 0xa3, 0x43, 0x96,
+ 0x8b, 0xab, 0x5a, 0x0e, 0x2d, 0x17, 0x59, 0x8e, 0x88, 0xce, 0x21, 0x9b,
+ 0xda, 0x90, 0x8a, 0x5b, 0x47, 0xfd, 0x3e, 0xed, 0x0f, 0x0a, 0xfc, 0xf3,
+ 0x94, 0x97, 0x7f, 0x0a, 0xef, 0x5e, 0xe9, 0xdc, 0xba, 0x19, 0xb3, 0x1b,
+ 0xed, 0x9a, 0xb2, 0x6b, 0x30, 0x88, 0xb9, 0xab, 0xdb, 0x68, 0x83, 0x39,
+ 0x80, 0x19, 0xaf, 0x43, 0x87, 0x34, 0x9c, 0x6e, 0x8d, 0xfd, 0x1a, 0xce,
+ 0x21, 0x9d, 0x77, 0xcb, 0x71, 0x0a, 0x45, 0x5b, 0xe6, 0x8a, 0x56, 0x32,
+ 0x0f, 0xfa, 0xbb, 0x01, 0xbb, 0x6d, 0x15, 0x77, 0xb0, 0x86, 0x33, 0x58,
+ 0xaf, 0x53, 0xcf, 0x6f, 0x6a, 0xd9, 0xbb, 0x5c, 0xff, 0x23, 0xc6, 0xb1,
+ 0xce, 0xa4, 0xe5, 0x0f, 0x7d, 0x94, 0x81, 0xf4, 0x4d, 0x65, 0x75, 0xff,
+ 0xa0, 0xdf, 0x2a, 0xda, 0xae, 0xd5, 0x29, 0x8f, 0x45, 0x2e, 0x79, 0x36,
+ 0x74, 0xc9, 0xcb, 0x09, 0x62, 0x80, 0xb2, 0x6a, 0xf6, 0xf3, 0xc3, 0x35,
+ 0xfb, 0xfe, 0x5e, 0x9b, 0xeb, 0x72, 0x42, 0xb9, 0x4d, 0xdd, 0xbf, 0xa1,
+ 0xb1, 0x8d, 0x57, 0x7a, 0x56, 0xde, 0xc4, 0x7d, 0x07, 0x18, 0x27, 0x27,
+ 0x6f, 0x00, 0xe3, 0xd5, 0x4b, 0xcd, 0xbc, 0xed, 0x93, 0x38, 0xa7, 0x92,
+ 0x9a, 0xbb, 0xda, 0x29, 0x97, 0xaf, 0x15, 0xd4, 0x4b, 0xd7, 0x3c, 0xf5,
+ 0xf3, 0xab, 0x45, 0x55, 0xb8, 0xea, 0xfb, 0xff, 0x70, 0x67, 0xe4, 0x9d,
+ 0x25, 0x5f, 0x4e, 0xbb, 0x46, 0x7f, 0x44, 0x9a, 0xf9, 0x74, 0xbe, 0xdf,
+ 0x01, 0xd9, 0xbc, 0x7e, 0xc0, 0xf7, 0x1f, 0x19, 0x19, 0x11, 0xe7, 0x00,
+ 0x31, 0xca, 0x70, 0x82, 0x39, 0xae, 0x94, 0x39, 0x19, 0xdb, 0x3e, 0x5f,
+ 0x51, 0x0a, 0xf2, 0xad, 0x3b, 0xc0, 0x2f, 0x8f, 0xee, 0x0b, 0xe3, 0x26,
+ 0x3f, 0x7c, 0x9e, 0x7e, 0xe5, 0xc4, 0xe7, 0xfc, 0xca, 0xa6, 0x9c, 0x2d,
+ 0xf6, 0xa2, 0x7f, 0x4c, 0x7e, 0x50, 0x8c, 0xee, 0x2a, 0x9b, 0x78, 0x3a,
+ 0x46, 0xa1, 0x78, 0xcf, 0x1f, 0xd4, 0xf1, 0x03, 0x60, 0x12, 0xd3, 0xf7,
+ 0x67, 0x5d, 0xce, 0xd7, 0x8d, 0xf9, 0x36, 0xcc, 0x7d, 0xd0, 0xff, 0xa7,
+ 0xb5, 0x7e, 0x2e, 0x2b, 0xd8, 0xc1, 0xe0, 0xef, 0x98, 0x8c, 0x15, 0xa1,
+ 0xe3, 0x15, 0xf3, 0x4c, 0x89, 0x15, 0xac, 0xc4, 0x2c, 0x64, 0xc7, 0x0c,
+ 0xe4, 0xcd, 0x29, 0x1d, 0x67, 0xed, 0xd5, 0xb2, 0x67, 0x8e, 0xe5, 0x9c,
+ 0xa4, 0x2b, 0x6e, 0x8f, 0x3e, 0xbf, 0xcd, 0x1b, 0x2f, 0x26, 0x82, 0x3b,
+ 0x07, 0x1f, 0xe7, 0x94, 0xb4, 0xc1, 0x1e, 0xca, 0xae, 0x4c, 0x81, 0x27,
+ 0x12, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xe8, 0xef, 0x86, 0xf6, 0x29,
+ 0x06, 0xb1, 0x8b, 0x86, 0xc9, 0x76, 0xa7, 0xd0, 0xaf, 0x5d, 0x32, 0x57,
+ 0xdb, 0xb4, 0x5c, 0x7d, 0xb8, 0x2e, 0x0d, 0x1c, 0xf2, 0x04, 0xca, 0x11,
+ 0xd4, 0x25, 0xc3, 0xb2, 0x81, 0xf2, 0x34, 0xca, 0x2d, 0x78, 0xb2, 0xcd,
+ 0x61, 0xe0, 0x0a, 0x3c, 0x5f, 0xc3, 0x78, 0x23, 0x58, 0x73, 0xce, 0x94,
+ 0x8f, 0x4e, 0x50, 0x97, 0x38, 0x06, 0x73, 0x91, 0x67, 0x6d, 0x3c, 0x6b,
+ 0x45, 0x95, 0x5d, 0x60, 0x19, 0xcf, 0x72, 0xf0, 0xfd, 0x21, 0x99, 0x84,
+ 0x3e, 0x99, 0x6b, 0x81, 0x4c, 0xfa, 0x68, 0x5b, 0x26, 0xb1, 0xae, 0x5d,
+ 0xc6, 0xae, 0x92, 0xd7, 0x4d, 0xd0, 0x5b, 0xa7, 0x64, 0xaf, 0xc5, 0x34,
+ 0x1e, 0xad, 0x80, 0x16, 0xaf, 0x83, 0xae, 0x96, 0x41, 0x53, 0x99, 0xa2,
+ 0x35, 0x3a, 0xad, 0x92, 0xda, 0x2f, 0xf0, 0x38, 0xe8, 0xb5, 0xe3, 0x0a,
+ 0xb1, 0x28, 0x79, 0xd9, 0x01, 0xed, 0x89, 0xdf, 0x61, 0xdb, 0x93, 0x8e,
+ 0xb2, 0x41, 0x83, 0xa0, 0xcb, 0x62, 0xc0, 0xd3, 0xef, 0x29, 0x2d, 0x57,
+ 0x47, 0xef, 0x48, 0x2a, 0x7d, 0x47, 0x2c, 0xc8, 0x02, 0xcb, 0xfd, 0x50,
+ 0x5c, 0x8c, 0x79, 0x5c, 0x5e, 0xc7, 0x3c, 0x06, 0xf8, 0xfb, 0xc8, 0x90,
+ 0xe6, 0xef, 0x51, 0x89, 0xec, 0xe6, 0x71, 0xd0, 0x1b, 0x64, 0x50, 0xc0,
+ 0xd3, 0xe9, 0x90, 0x46, 0x9f, 0x06, 0xff, 0x5a, 0xb0, 0xca, 0x92, 0x32,
+ 0x0f, 0xfe, 0xbf, 0x8e, 0xef, 0xb7, 0xea, 0x9f, 0xaa, 0xb9, 0x05, 0x15,
+ 0xe6, 0xb2, 0x7c, 0x1b, 0x38, 0xf9, 0xf7, 0x38, 0xbb, 0x2e, 0x8d, 0xdd,
+ 0x07, 0x46, 0x18, 0x4b, 0xfb, 0xb7, 0xba, 0x6c, 0x1f, 0x95, 0xcd, 0xe1,
+ 0xe3, 0x28, 0xef, 0xc3, 0xd3, 0xc0, 0x39, 0x44, 0x75, 0x2c, 0x7c, 0xd9,
+ 0x1b, 0x36, 0x0a, 0x3a, 0xef, 0xe0, 0x98, 0xce, 0xcf, 0x37, 0xec, 0x03,
+ 0xf8, 0x4e, 0xbf, 0x0c, 0xf7, 0x06, 0xcc, 0xa4, 0x12, 0x3a, 0xc7, 0xb4,
+ 0x02, 0x2c, 0xb1, 0x82, 0xf1, 0xde, 0xa7, 0x5f, 0xaf, 0x06, 0x1e, 0x1e,
+ 0xfe, 0xa7, 0x9f, 0x8e, 0x31, 0x27, 0x7d, 0x33, 0x11, 0xe8, 0xbf, 0xcf,
+ 0xfc, 0x4d, 0x7b, 0x6e, 0xd4, 0xc0, 0xcb, 0x6d, 0x33, 0x86, 0xb6, 0xd0,
+ 0x65, 0xd0, 0x45, 0x65, 0x4d, 0xbf, 0x6c, 0x17, 0xf4, 0x2d, 0xd4, 0x52,
+ 0xe6, 0x07, 0x12, 0xf4, 0x9d, 0xb7, 0xa9, 0x77, 0xda, 0x21, 0x5f, 0x92,
+ 0x1a, 0x57, 0xbe, 0x6f, 0xe7, 0x21, 0x15, 0xac, 0xe4, 0x24, 0x68, 0xb4,
+ 0x4d, 0x2c, 0x67, 0x5c, 0x1e, 0xcc, 0x3b, 0xab, 0xfb, 0xb2, 0x6d, 0xb3,
+ 0x6f, 0x73, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0xa7, 0x36, 0x35,
+ 0x8d, 0x36, 0x6a, 0xed, 0xfd, 0x01, 0x8d, 0x36, 0xf7, 0x11, 0xfb, 0x3f,
+ 0xfb, 0x20, 0x9d, 0x0c, 0x1b, 0x41, 0x0e, 0x06, 0x9e, 0x35, 0x9e, 0xe7,
+ 0xa7, 0xc0, 0xf7, 0x3b, 0xe9, 0xa7, 0xe9, 0x67, 0x0c, 0xe8, 0xe7, 0x91,
+ 0x6d, 0xfa, 0x21, 0xdd, 0x74, 0xca, 0xd8, 0x35, 0x5b, 0x26, 0x8a, 0xfa,
+ 0xbe, 0x81, 0x35, 0xe9, 0x3f, 0x3a, 0x0e, 0xba, 0x21, 0xad, 0x93, 0xb7,
+ 0x4c, 0x29, 0x83, 0x8e, 0xca, 0x90, 0x4f, 0x65, 0xd0, 0x14, 0x31, 0x50,
+ 0x19, 0xf2, 0xad, 0x5c, 0xb7, 0x9c, 0x2a, 0xf6, 0x4c, 0x9d, 0xbd, 0x02,
+ 0x3a, 0xba, 0x5e, 0xe7, 0xfd, 0xeb, 0x35, 0x9b, 0xd4, 0x83, 0xb7, 0xb6,
+ 0xef, 0xfe, 0xef, 0xb8, 0xfb, 0x43, 0x72, 0x03, 0x76, 0xcb, 0x9b, 0xa5,
+ 0x61, 0xc8, 0x24, 0x21, 0x5e, 0x04, 0x6d, 0x8c, 0xca, 0x6a, 0xe9, 0xa4,
+ 0xac, 0x41, 0x3f, 0xad, 0x2f, 0x0d, 0x00, 0x4f, 0x43, 0x8e, 0xbe, 0x72,
+ 0x44, 0xde, 0x58, 0x52, 0x32, 0x63, 0x43, 0xbf, 0x2c, 0xd3, 0x07, 0x0f,
+ 0x7a, 0x2e, 0x77, 0xea, 0x98, 0xfd, 0x58, 0x35, 0xf0, 0xc5, 0x8f, 0x57,
+ 0xbb, 0x64, 0xa2, 0x6a, 0xca, 0x63, 0xd5, 0x1e, 0x79, 0xa2, 0x1a, 0x93,
+ 0xd3, 0xb5, 0x84, 0x7c, 0xa3, 0x7a, 0x50, 0x4e, 0x55, 0x0f, 0xc9, 0x93,
+ 0xb5, 0xa4, 0x7c, 0x13, 0x76, 0x61, 0xae, 0xe6, 0xc8, 0x64, 0x6d, 0x58,
+ 0x1e, 0xaf, 0xd1, 0xc7, 0x8e, 0xf9, 0xf0, 0xcb, 0x6e, 0xfb, 0x2e, 0xb8,
+ 0xae, 0x0e, 0xac, 0xcb, 0x51, 0xe3, 0x3a, 0x66, 0x29, 0xb9, 0xc0, 0xff,
+ 0x21, 0x72, 0x0e, 0x7d, 0x2f, 0xbe, 0xa2, 0xa4, 0xa2, 0xe7, 0x6f, 0xfe,
+ 0xdf, 0x48, 0x54, 0xdb, 0x46, 0xe7, 0xca, 0x07, 0xd1, 0xc6, 0xa6, 0x4d,
+ 0x12, 0xfa, 0x41, 0x9a, 0xfe, 0xff, 0xa6, 0xed, 0x65, 0x68, 0x1f, 0xf6,
+ 0x2d, 0xda, 0x5e, 0xfa, 0xec, 0x29, 0x3f, 0x68, 0xe7, 0xd0, 0xd6, 0xda,
+ 0x19, 0xe7, 0x68, 0xce, 0x7b, 0x31, 0xf7, 0xf0, 0xff, 0xa7, 0x04, 0xf1,
+ 0xaa, 0xb3, 0xb5, 0x83, 0xfc, 0x3f, 0x15, 0xac, 0xe5, 0x8b, 0xf3, 0xc5,
+ 0x27, 0x4a, 0x63, 0xea, 0xb1, 0x12, 0x11, 0x8d, 0x2f, 0x17, 0xb7, 0x73,
+ 0xf2, 0xbe, 0x2e, 0xcb, 0x6e, 0x54, 0xaf, 0x21, 0xf0, 0xdb, 0xa7, 0x75,
+ 0x7e, 0xde, 0xd8, 0x10, 0xe9, 0x8f, 0x71, 0xb8, 0xae, 0x30, 0xb6, 0x00,
+ 0x6c, 0xeb, 0x9a, 0x72, 0xa9, 0x1a, 0xf8, 0xaf, 0xe6, 0x34, 0xbd, 0xbc,
+ 0x05, 0x9a, 0x63, 0xfc, 0x21, 0x78, 0xe6, 0xcb, 0x41, 0xdf, 0xec, 0x90,
+ 0x43, 0x7b, 0x1c, 0xfb, 0x35, 0x7a, 0x38, 0x17, 0xff, 0x4f, 0x07, 0xe5,
+ 0x70, 0xbd, 0xcc, 0x2f, 0xb6, 0x35, 0x2d, 0x06, 0x31, 0x5e, 0x47, 0x9e,
+ 0xc3, 0x5d, 0x54, 0x4c, 0xae, 0xbf, 0x43, 0x2a, 0x0e, 0x6d, 0x5b, 0xca,
+ 0xef, 0x21, 0x29, 0x63, 0x9e, 0x8a, 0xd3, 0xf4, 0x8d, 0x05, 0x72, 0xb6,
+ 0x62, 0x3e, 0x98, 0x77, 0xba, 0xbc, 0x1f, 0xef, 0xa8, 0x73, 0x80, 0x99,
+ 0xa6, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0xe6, 0xf0, 0x4c, 0x84, 0x75,
+ 0xaf, 0xf5, 0x6b, 0xac, 0x7e, 0xf2, 0x41, 0xbf, 0x99, 0xb2, 0x95, 0xcf,
+ 0x44, 0xb6, 0x94, 0xf1, 0x8b, 0xf5, 0x7e, 0xca, 0xdc, 0xfd, 0x36, 0x7f,
+ 0x51, 0xf9, 0x8b, 0xa9, 0x7d, 0x0a, 0xe1, 0xb7, 0x3d, 0xf2, 0x94, 0xc9,
+ 0xdc, 0xf5, 0xb4, 0x1a, 0x2b, 0xfd, 0x34, 0xcc, 0xd3, 0xdd, 0x52, 0xfb,
+ 0x2b, 0x6f, 0xf7, 0x07, 0x79, 0xee, 0x1c, 0x7b, 0x67, 0x6e, 0xfb, 0x4e,
+ 0x3a, 0x61, 0x8e, 0x7b, 0x3b, 0x70, 0xab, 0x56, 0x62, 0xe0, 0x41, 0xc8,
+ 0x3b, 0xbb, 0x45, 0xf3, 0x63, 0xa1, 0xf6, 0x2f, 0x7f, 0x43, 0xf3, 0x73,
+ 0xd3, 0xc7, 0xf0, 0xdb, 0x7e, 0xda, 0xb6, 0x94, 0x1b, 0x97, 0x02, 0xbf,
+ 0x91, 0xb6, 0xa1, 0x21, 0x2b, 0x50, 0x47, 0x5e, 0x05, 0x9f, 0x6c, 0xb7,
+ 0xe5, 0xdf, 0x7f, 0x01, 0x99, 0xe7, 0xd3, 0x46, 0x40, 0x67, 0x00, 0x00,
+ 0x00 };
+static u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = {
+ 0x08003fa4, 0x08003ea4, 0x08003f48, 0x08003f60, 0x08003f78, 0x08003f98,
+ 0x08003fa4, 0x08003fa4, 0x08003eac, 0x00000000, 0x080049d4, 0x08004a0c,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004a44, 0x08004c08,
+ 0x08004b50, 0x08004b88, 0x08004c08, 0x08004ad8, 0x08004c08, 0x08004c08,
+ 0x08004b88, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004bc8,
+ 0x08004c08, 0x08004bc8, 0x08004b50, 0x08004c08, 0x08004c08, 0x08004bc8,
+ 0x08004bc8, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08,
+ 0x08004ab4, 0x00000000, 0x0800602c, 0x08006044, 0x08006044, 0x08006044,
+ 0x0800602c, 0x08006044, 0x08006044, 0x08006044, 0x0800602c, 0x08006044,
+ 0x08006044, 0x08006044, 0x0800602c, 0x08006044, 0x08006044, 0x08006044,
+ 0x08006038, 0x00000000, 0x00000000 };
+static u32 bnx2_RXP_b09FwBss[(0x13dc/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b09FwSbss[(0x2c/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_rxp_fw_09 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x08003184,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x673c,
+ .text_index = 0x0,
+ .gz_text = bnx2_RXP_b09FwText,
+ .gz_text_len = sizeof(bnx2_RXP_b09FwText),
+
+ .data_addr = 0x080069e0,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_RXP_b09FwData,
+
+ .sbss_addr = 0x080069e0,
+ .sbss_len = 0x2c,
+ .sbss_index = 0x0,
+ .sbss = bnx2_RXP_b09FwSbss,
+
+ .bss_addr = 0x08006a10,
+ .bss_len = 0x13dc,
+ .bss_index = 0x0,
+ .bss = bnx2_RXP_b09FwBss,
+
+ .rodata_addr = 0x08006740,
+ .rodata_len = 0x278,
+ .rodata_index = 0x0,
+ .rodata = bnx2_RXP_b09FwRodata,
+};
+
+static u8 bnx2_TPAT_b09FwText[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0xdb, 0xfd, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x58, 0x5d, 0x6c,
+ 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xbb, 0x13, 0x77, 0xed, 0xbd, 0x49, 0x97,
+ 0x6a, 0x13, 0xb9, 0x74, 0xc6, 0x1e, 0x3b, 0x8b, 0x1c, 0x35, 0x93, 0xb0,
+ 0x24, 0x16, 0x5a, 0xd1, 0xc9, 0xcc, 0xae, 0x6b, 0xe5, 0x29, 0x86, 0xbc,
+ 0xf1, 0xb2, 0xac, 0xed, 0x46, 0x54, 0x48, 0x4d, 0x51, 0x84, 0x22, 0x81,
+ 0x94, 0x65, 0x76, 0x53, 0x40, 0x5a, 0x65, 0xc1, 0xa0, 0x04, 0x21, 0x84,
+ 0x22, 0x9b, 0x66, 0x91, 0x58, 0x3c, 0x4d, 0xe9, 0x6b, 0x94, 0xbc, 0x90,
+ 0x96, 0x17, 0x9e, 0x4b, 0x9e, 0xac, 0x02, 0x12, 0x0f, 0xa8, 0x8a, 0x78,
+ 0x40, 0x15, 0x0d, 0x1e, 0xbe, 0x33, 0x3f, 0x9b, 0x5d, 0xd7, 0x29, 0x79,
+ 0xa8, 0x84, 0xa5, 0xf1, 0xcc, 0xfd, 0x39, 0xf7, 0xe7, 0x7c, 0xdf, 0x77,
+ 0xee, 0xb9, 0x5b, 0x92, 0x69, 0x82, 0xd2, 0xbf, 0x49, 0x3c, 0x97, 0xbe,
+ 0x71, 0xf1, 0xd2, 0xe2, 0x8b, 0x27, 0x4d, 0x3a, 0x71, 0xe2, 0x45, 0xe9,
+ 0x19, 0x43, 0xa6, 0xcf, 0xe0, 0x4f, 0x21, 0x12, 0xd9, 0xf8, 0xfc, 0x90,
+ 0x21, 0x57, 0x6f, 0x4e, 0x7b, 0x36, 0x19, 0x4a, 0xd5, 0x79, 0x61, 0xd5,
+ 0x26, 0x72, 0x07, 0x0b, 0xa6, 0x4f, 0xff, 0x89, 0x5a, 0x45, 0x95, 0xb8,
+ 0xfe, 0xf9, 0xea, 0xa3, 0xe3, 0x77, 0x4e, 0x5b, 0x0f, 0x6f, 0x2a, 0x64,
+ 0x88, 0x6a, 0xc3, 0x10, 0xf3, 0x64, 0x4c, 0xc3, 0xe6, 0x97, 0x47, 0x57,
+ 0x34, 0x9a, 0xca, 0xc6, 0x12, 0x14, 0xf4, 0x0c, 0xaa, 0x77, 0x31, 0x8e,
+ 0x7d, 0x59, 0xf2, 0x43, 0x55, 0xf2, 0x6f, 0x18, 0x24, 0x57, 0x5d, 0xc9,
+ 0x0b, 0x6d, 0xb4, 0x49, 0xe4, 0x39, 0x39, 0x72, 0x45, 0x14, 0x7d, 0xd3,
+ 0x91, 0x49, 0xb6, 0x77, 0xa3, 0xd9, 0xb9, 0x25, 0xc9, 0xeb, 0x2f, 0x4b,
+ 0x7e, 0xdf, 0xe3, 0x7d, 0x63, 0x1d, 0x4b, 0x92, 0xdb, 0xe7, 0x77, 0xd5,
+ 0xf0, 0xbb, 0x53, 0xd4, 0x28, 0x52, 0x41, 0xb6, 0xd9, 0xd6, 0x24, 0xdf,
+ 0x59, 0x28, 0x29, 0x34, 0x8b, 0xe7, 0x00, 0xad, 0x3b, 0x94, 0xf7, 0x1c,
+ 0x52, 0x15, 0x5b, 0x26, 0xbf, 0x28, 0xd1, 0xaf, 0x2b, 0x1a, 0x9e, 0xb3,
+ 0x52, 0xad, 0xbf, 0x96, 0x8e, 0x53, 0xa4, 0x36, 0xd6, 0xd2, 0x2c, 0xf2,
+ 0xda, 0x12, 0x7b, 0xcf, 0x59, 0x10, 0x32, 0xcd, 0xe2, 0x99, 0xc4, 0x77,
+ 0x13, 0xfd, 0x34, 0xf2, 0x2a, 0x7b, 0xdb, 0x0e, 0xe0, 0x1b, 0xeb, 0xc4,
+ 0x58, 0x5e, 0xbc, 0x0e, 0x13, 0xeb, 0xb0, 0xa9, 0xd3, 0x5b, 0xc6, 0x3e,
+ 0xe6, 0x4a, 0x4d, 0xd2, 0xa9, 0x13, 0xaf, 0x7d, 0x92, 0x02, 0xa1, 0x50,
+ 0x70, 0x4c, 0x23, 0xf7, 0x9c, 0x8a, 0xf2, 0x21, 0x6a, 0x09, 0x09, 0x7d,
+ 0x3a, 0x29, 0x7e, 0x39, 0xb4, 0xeb, 0xa8, 0x2f, 0x50, 0x50, 0x3c, 0x28,
+ 0xc9, 0xd5, 0xef, 0xa1, 0x7e, 0x4e, 0x34, 0xe9, 0xbb, 0x78, 0x4b, 0x28,
+ 0x1f, 0xe4, 0xf1, 0x50, 0x96, 0x48, 0xb1, 0x49, 0x78, 0xa1, 0x49, 0xed,
+ 0x30, 0xb3, 0xe5, 0xfa, 0xa4, 0xae, 0x15, 0xee, 0xc5, 0x0e, 0xfd, 0x7a,
+ 0x75, 0x6a, 0x08, 0x6a, 0xa9, 0x55, 0xf4, 0xe9, 0xd9, 0xa2, 0x06, 0x9c,
+ 0xdc, 0x18, 0xcf, 0x97, 0xb8, 0x9e, 0xff, 0x50, 0x6f, 0x92, 0x52, 0xb5,
+ 0x85, 0x4f, 0x5f, 0xa6, 0xa4, 0x8d, 0xf7, 0x29, 0x63, 0x6f, 0xa7, 0xd2,
+ 0x72, 0x51, 0x78, 0x37, 0xbe, 0x48, 0x6e, 0xec, 0x1f, 0x03, 0xdf, 0x02,
+ 0x7b, 0xd4, 0x81, 0x75, 0xe0, 0xca, 0xd4, 0x2a, 0x19, 0x64, 0x2d, 0xae,
+ 0xa1, 0xe5, 0x6f, 0x5d, 0x05, 0x7e, 0x67, 0xdc, 0xd4, 0xd4, 0x8e, 0x71,
+ 0xfe, 0x23, 0xd6, 0xd9, 0x12, 0x06, 0xf0, 0x6e, 0x9c, 0x8f, 0xa2, 0x37,
+ 0x9d, 0x28, 0xd2, 0xab, 0x76, 0xf9, 0x16, 0x2d, 0x94, 0x34, 0x9a, 0x17,
+ 0x78, 0xc3, 0x8f, 0x36, 0x7c, 0xa5, 0x65, 0xeb, 0xc9, 0x78, 0x86, 0xbf,
+ 0xcb, 0x12, 0x96, 0x42, 0x1f, 0x74, 0xdf, 0x63, 0x7f, 0x94, 0x97, 0x62,
+ 0x9b, 0x28, 0xda, 0x5c, 0xfc, 0x34, 0x9b, 0xef, 0xa7, 0x36, 0x51, 0x54,
+ 0xaf, 0xf0, 0xbc, 0x16, 0xf6, 0xcc, 0x5c, 0x25, 0xaa, 0x0f, 0x1c, 0xa3,
+ 0xd9, 0xc5, 0xfa, 0x6c, 0xbc, 0x07, 0x25, 0xec, 0xc1, 0x2a, 0x9b, 0x92,
+ 0x41, 0x81, 0x1d, 0xbd, 0x00, 0x7e, 0xb8, 0xbe, 0x6d, 0xbd, 0xef, 0x2b,
+ 0x05, 0xda, 0x72, 0xf2, 0xd4, 0x09, 0x4b, 0x14, 0x84, 0x1d, 0xf2, 0x42,
+ 0x19, 0x73, 0x14, 0x68, 0xd3, 0x7e, 0x18, 0xd5, 0x1d, 0x07, 0x7e, 0x21,
+ 0xb6, 0x2b, 0xd5, 0x69, 0x1a, 0xed, 0x0b, 0x62, 0x8d, 0x1c, 0x60, 0x21,
+ 0xc3, 0x37, 0xb3, 0xf1, 0x77, 0x10, 0x3a, 0x68, 0xa7, 0x96, 0x5c, 0xb1,
+ 0x44, 0x40, 0x56, 0xc9, 0x53, 0x48, 0xc8, 0x55, 0x81, 0x3e, 0x2d, 0xaa,
+ 0x85, 0x06, 0xed, 0x28, 0x97, 0x63, 0x7e, 0xb7, 0x7b, 0x3b, 0xd1, 0x9d,
+ 0xa3, 0x25, 0xba, 0x1b, 0x16, 0xe9, 0x76, 0x48, 0x72, 0xd3, 0x01, 0x37,
+ 0x8a, 0x82, 0xde, 0x0a, 0x47, 0xf7, 0xf2, 0x1b, 0xec, 0x25, 0x38, 0xa2,
+ 0x40, 0x83, 0xab, 0xce, 0x3d, 0x30, 0xc8, 0x02, 0x46, 0x2d, 0xec, 0x3d,
+ 0x7b, 0xf3, 0xbe, 0x76, 0xa6, 0x57, 0x6d, 0xeb, 0x87, 0x3e, 0xa3, 0x76,
+ 0x4d, 0x43, 0xed, 0x5e, 0x7f, 0x0c, 0x30, 0x86, 0xa0, 0xab, 0xd0, 0x93,
+ 0x0c, 0xbf, 0xcc, 0x6c, 0x1b, 0xd4, 0xef, 0xe6, 0xc8, 0xdc, 0x54, 0xa9,
+ 0xd9, 0x2b, 0x92, 0x33, 0x6f, 0x99, 0x24, 0xcb, 0x45, 0x99, 0x54, 0x9a,
+ 0xd9, 0x8c, 0x68, 0x09, 0xeb, 0xb8, 0x6f, 0xff, 0x48, 0xa7, 0xa9, 0xc0,
+ 0xd1, 0x89, 0xfb, 0x18, 0x34, 0x73, 0xcb, 0x90, 0xfc, 0x1e, 0xef, 0x83,
+ 0x7d, 0x6e, 0xa4, 0x3e, 0x57, 0x25, 0xef, 0x46, 0x8e, 0x66, 0x37, 0xfe,
+ 0x11, 0x79, 0x36, 0x7c, 0x0d, 0x9e, 0xaf, 0x56, 0xbe, 0xa0, 0xd0, 0x04,
+ 0xea, 0x36, 0xb9, 0xed, 0x61, 0x5a, 0xcf, 0x63, 0x44, 0x91, 0xe7, 0x3c,
+ 0x4b, 0x1e, 0xf3, 0xff, 0x3c, 0xdb, 0xe4, 0x68, 0x66, 0x83, 0x75, 0x83,
+ 0xf7, 0x26, 0x97, 0x79, 0x6d, 0x07, 0xa8, 0x89, 0x1d, 0x35, 0xcb, 0x45,
+ 0xf8, 0x41, 0x8e, 0x35, 0xd2, 0xc4, 0x8e, 0x65, 0x7b, 0x02, 0x6f, 0x9e,
+ 0xef, 0xac, 0x92, 0xf0, 0x9d, 0xe3, 0x46, 0x9e, 0x7c, 0xe0, 0xab, 0x62,
+ 0x3d, 0x6b, 0x34, 0x57, 0x5a, 0x8f, 0xdb, 0x50, 0x37, 0xe0, 0x36, 0xb1,
+ 0xa7, 0x0d, 0xe5, 0x41, 0xb6, 0x06, 0x70, 0xda, 0x6e, 0x63, 0x16, 0x2d,
+ 0xde, 0x6b, 0xdd, 0xe1, 0xfe, 0xdc, 0xb7, 0x55, 0xd6, 0xc8, 0x2a, 0x6f,
+ 0x62, 0xf4, 0x7e, 0x17, 0xfb, 0xbd, 0xce, 0xb1, 0xc8, 0x36, 0xff, 0x4a,
+ 0xdc, 0x7f, 0x16, 0x7b, 0x9e, 0x5b, 0x6c, 0x73, 0xdb, 0x40, 0x23, 0x7b,
+ 0xa3, 0x25, 0x54, 0xf8, 0x5f, 0x86, 0xf3, 0xfd, 0x1f, 0xff, 0x2b, 0xd2,
+ 0xaa, 0xe0, 0x74, 0xa5, 0x00, 0x7c, 0x2c, 0xb3, 0x0d, 0xbd, 0xdb, 0x18,
+ 0x37, 0x70, 0x14, 0xd8, 0x25, 0x38, 0x71, 0xbf, 0xa5, 0x6e, 0x44, 0xed,
+ 0x78, 0xae, 0x2b, 0x3c, 0x17, 0x62, 0x92, 0xbd, 0xf8, 0x07, 0x70, 0xa3,
+ 0x49, 0x79, 0x9a, 0xdf, 0xce, 0xd3, 0x85, 0x41, 0x9e, 0x66, 0xae, 0xe9,
+ 0xf0, 0x43, 0x14, 0x75, 0x2a, 0xac, 0x51, 0xe0, 0x6d, 0x73, 0x3f, 0xab,
+ 0xa4, 0xc8, 0xbc, 0x0e, 0xb4, 0x6f, 0x13, 0xad, 0x0d, 0x74, 0xf8, 0x4d,
+ 0x1d, 0x19, 0x5b, 0xa6, 0x97, 0x7f, 0x46, 0xf4, 0xf2, 0x80, 0x6d, 0x79,
+ 0xfc, 0xc4, 0xa6, 0x89, 0x3d, 0xcb, 0xc0, 0xfc, 0xc2, 0x40, 0x46, 0xbc,
+ 0x40, 0x3c, 0xed, 0x7b, 0x88, 0x93, 0x35, 0x3c, 0x4b, 0x88, 0x9d, 0x8c,
+ 0x0d, 0xc7, 0x91, 0x5d, 0xe0, 0xb3, 0x8c, 0xb6, 0xb3, 0xa8, 0x4b, 0xf4,
+ 0xae, 0xd8, 0x3a, 0xd5, 0x9c, 0x49, 0x6a, 0x67, 0xb1, 0x4a, 0x70, 0xac,
+ 0x3a, 0x08, 0x4e, 0x1d, 0x40, 0xfc, 0xf9, 0x9d, 0x32, 0x1e, 0xab, 0x10,
+ 0xd3, 0x8a, 0x87, 0x11, 0x9b, 0xfa, 0xa8, 0xe7, 0xf1, 0x6e, 0xe1, 0x7d,
+ 0x00, 0xe5, 0xc3, 0xe8, 0x3b, 0x1a, 0xa7, 0x32, 0xbb, 0x27, 0xc5, 0x28,
+ 0xf0, 0x6e, 0xc3, 0x40, 0x7f, 0x13, 0xba, 0x61, 0x7f, 0xe7, 0x10, 0x3f,
+ 0xd8, 0xe7, 0x39, 0xf8, 0x54, 0xc7, 0xdc, 0x82, 0x66, 0xb7, 0xa9, 0xa5,
+ 0xa4, 0xf1, 0xcb, 0x1f, 0xc6, 0xaf, 0x52, 0xcc, 0x83, 0x20, 0x14, 0xb0,
+ 0x61, 0xfd, 0x66, 0x7a, 0x65, 0xec, 0xc8, 0xf5, 0xa0, 0x65, 0x4f, 0x89,
+ 0xa2, 0x55, 0xa7, 0x40, 0x4d, 0xe0, 0xee, 0x42, 0xc3, 0x4d, 0x68, 0xd8,
+ 0x1f, 0xd1, 0xb0, 0xff, 0x3f, 0x35, 0x0c, 0x7d, 0x42, 0x23, 0xb7, 0xc1,
+ 0xa9, 0xb7, 0x7a, 0xfb, 0xe9, 0x99, 0xb5, 0xcc, 0x9a, 0x36, 0xe9, 0xce,
+ 0xd1, 0xa7, 0xd5, 0x74, 0x49, 0x7e, 0x4a, 0x4d, 0xb7, 0x58, 0xd3, 0x2a,
+ 0x6b, 0xba, 0xb8, 0x57, 0xd3, 0xd3, 0x18, 0x23, 0xd1, 0xe6, 0x19, 0xb5,
+ 0x48, 0xda, 0x3c, 0xf0, 0xd8, 0xc8, 0x93, 0x72, 0xed, 0x31, 0xef, 0x98,
+ 0xcb, 0xfe, 0x00, 0xff, 0xb6, 0x35, 0xb4, 0x49, 0xe3, 0xf5, 0x88, 0x81,
+ 0x6a, 0xd5, 0x2a, 0xad, 0xc5, 0x7d, 0x54, 0xd2, 0xe1, 0xff, 0xd7, 0x8f,
+ 0x5a, 0xa6, 0x29, 0x8f, 0x6a, 0x1f, 0xea, 0xdf, 0x88, 0xae, 0x68, 0x55,
+ 0x9e, 0xa7, 0x65, 0x82, 0xf3, 0xe6, 0x4f, 0x80, 0x55, 0xbb, 0xcb, 0x7c,
+ 0xb7, 0x45, 0x3d, 0xe6, 0x19, 0xca, 0xd0, 0x84, 0x06, 0xde, 0xe6, 0xd0,
+ 0x4f, 0xdd, 0x48, 0x74, 0x74, 0x1b, 0xe3, 0x6e, 0x75, 0x99, 0x67, 0x06,
+ 0xe9, 0xd7, 0xed, 0xd2, 0x85, 0x38, 0x06, 0xcf, 0x8a, 0x25, 0x62, 0x0d,
+ 0xf2, 0xb9, 0x88, 0xf6, 0x41, 0x8e, 0x94, 0x58, 0xf7, 0x13, 0xa9, 0xee,
+ 0x9f, 0x87, 0xaf, 0x26, 0x50, 0x66, 0xed, 0x1f, 0x4e, 0xb5, 0x3f, 0x85,
+ 0x37, 0xd7, 0xad, 0xa8, 0x09, 0x87, 0xc0, 0xc7, 0x0d, 0xc6, 0x37, 0x8f,
+ 0x58, 0xc7, 0xf3, 0xff, 0x33, 0x5a, 0xb5, 0x19, 0x63, 0xdb, 0xfc, 0x01,
+ 0xcd, 0x41, 0x7f, 0xa8, 0xdf, 0xe6, 0xbe, 0x6c, 0x93, 0xf5, 0x15, 0x69,
+ 0xdf, 0x0f, 0xf7, 0xf4, 0x45, 0xfd, 0x36, 0xf7, 0x63, 0x7d, 0x1c, 0x22,
+ 0xe5, 0x3a, 0x9f, 0xdb, 0x1e, 0xeb, 0x03, 0x76, 0x35, 0xd4, 0x71, 0x6e,
+ 0xc1, 0xf6, 0x7c, 0x86, 0xf3, 0x3a, 0x39, 0xef, 0xe0, 0x73, 0x7e, 0xcf,
+ 0x79, 0x3e, 0xd4, 0xc8, 0x19, 0xf0, 0xfe, 0x3b, 0xea, 0x27, 0x35, 0xb2,
+ 0x02, 0x4d, 0x5c, 0x54, 0x13, 0x8d, 0xbc, 0x86, 0xf7, 0x19, 0x94, 0x57,
+ 0xf6, 0x68, 0x24, 0xb3, 0x7b, 0xf2, 0x39, 0x1e, 0xf4, 0x4a, 0xf1, 0x99,
+ 0xcb, 0xf3, 0x29, 0x1b, 0xd4, 0xd2, 0x52, 0x3d, 0xd4, 0x87, 0x7a, 0x98,
+ 0x40, 0xcc, 0xc8, 0xa5, 0x5c, 0xc7, 0xdb, 0xfe, 0x48, 0xf1, 0x1d, 0x4b,
+ 0xb4, 0x89, 0xb5, 0x31, 0x7a, 0x9e, 0xfd, 0xbf, 0xf4, 0x41, 0xe0, 0x51,
+ 0x3c, 0x37, 0x72, 0x11, 0x3e, 0x17, 0xa2, 0xe8, 0x15, 0x07, 0xed, 0x59,
+ 0x4e, 0x12, 0x63, 0x9f, 0xc3, 0xd9, 0xcb, 0x78, 0x20, 0x0f, 0xb4, 0x67,
+ 0xa1, 0x07, 0x8e, 0x05, 0xbb, 0xd1, 0x96, 0xed, 0xa1, 0xae, 0x06, 0xff,
+ 0x33, 0x26, 0xcb, 0xd2, 0x52, 0xdf, 0x60, 0x3b, 0xe8, 0x6d, 0xbf, 0x5c,
+ 0x4c, 0x87, 0xae, 0x1e, 0xe3, 0xc4, 0x3c, 0x6a, 0x8e, 0xe0, 0xd4, 0x88,
+ 0x71, 0xda, 0x19, 0xe2, 0xd4, 0x4c, 0x71, 0x6a, 0xc6, 0x38, 0x3d, 0x48,
+ 0x71, 0xfa, 0xf3, 0x13, 0x70, 0xda, 0x79, 0x0a, 0x9c, 0x0c, 0xda, 0xb2,
+ 0x4b, 0x38, 0x6f, 0xf5, 0x38, 0x77, 0xbd, 0xef, 0xec, 0x97, 0x7b, 0xb1,
+ 0xdf, 0xc7, 0xb0, 0x8a, 0x18, 0xab, 0x2d, 0x1a, 0xcd, 0x43, 0x2c, 0xf3,
+ 0x1e, 0x15, 0x70, 0x6e, 0xe4, 0xe9, 0xea, 0x9e, 0x5c, 0x24, 0x00, 0x4e,
+ 0xb5, 0x14, 0xa7, 0xab, 0xc0, 0xa9, 0x96, 0xe2, 0xb4, 0x3e, 0x82, 0xd3,
+ 0xfa, 0x18, 0x4e, 0x1c, 0x53, 0x2a, 0xc6, 0x7a, 0x37, 0xc3, 0x28, 0xc3,
+ 0x47, 0xa7, 0x9b, 0x62, 0x0a, 0xfb, 0x3f, 0x4e, 0xed, 0x9f, 0xaa, 0x9c,
+ 0xff, 0x02, 0xbb, 0x97, 0x54, 0x39, 0x3e, 0x17, 0xf8, 0xfb, 0x71, 0xbe,
+ 0x82, 0xb9, 0x5c, 0xcf, 0xe1, 0x3d, 0x21, 0xcf, 0xb5, 0x47, 0x63, 0xd1,
+ 0x07, 0x88, 0x45, 0x5c, 0xc7, 0xfd, 0x54, 0xa9, 0x06, 0xcd, 0x2b, 0xc8,
+ 0xe1, 0xfd, 0x61, 0x0e, 0x9f, 0xf8, 0xe1, 0x6a, 0x9a, 0xc3, 0x6f, 0xd9,
+ 0x9c, 0xc3, 0x9f, 0xd0, 0x68, 0x62, 0x39, 0xc5, 0x93, 0x79, 0x3d, 0x89,
+ 0xb6, 0xb3, 0x31, 0xee, 0x6d, 0xc4, 0xf2, 0x55, 0xf8, 0xa0, 0x19, 0xf3,
+ 0x13, 0x79, 0x57, 0xca, 0x5d, 0xe4, 0xbb, 0xe4, 0x87, 0x09, 0x4f, 0x3f,
+ 0xdb, 0x5c, 0xec, 0xef, 0x88, 0xd9, 0x46, 0x43, 0xc5, 0x1d, 0xe0, 0x6e,
+ 0x18, 0xc7, 0xea, 0x73, 0x41, 0x97, 0x5a, 0x47, 0xaa, 0x57, 0x22, 0xe0,
+ 0xee, 0x7e, 0xfd, 0x34, 0x9f, 0x39, 0xf9, 0x45, 0xaf, 0x82, 0xfa, 0x81,
+ 0x41, 0xc8, 0x83, 0x70, 0xa7, 0xa1, 0x96, 0x77, 0x5a, 0x42, 0xbe, 0x83,
+ 0x32, 0x6c, 0x82, 0x70, 0xba, 0x21, 0x57, 0x4b, 0xe0, 0x43, 0x8b, 0x5c,
+ 0xac, 0xd3, 0x0d, 0xe3, 0x7b, 0x4d, 0x43, 0xa9, 0x1a, 0xc8, 0x37, 0xc9,
+ 0xc0, 0x99, 0x0f, 0x9f, 0x98, 0x46, 0x7b, 0x80, 0x9c, 0x08, 0x79, 0x80,
+ 0xb7, 0x08, 0xbf, 0x1c, 0x03, 0x76, 0xa1, 0x0a, 0xdb, 0x6f, 0xe9, 0xc9,
+ 0x9d, 0x88, 0xc8, 0x8b, 0xfd, 0xf5, 0x71, 0xca, 0x91, 0x38, 0xe7, 0x92,
+ 0x6a, 0x3d, 0x32, 0x9b, 0x0e, 0xb8, 0x8e, 0x33, 0xa5, 0x13, 0x72, 0x5e,
+ 0x7d, 0xcc, 0x90, 0xaf, 0x71, 0x3c, 0x7f, 0x00, 0x1f, 0xe2, 0x7b, 0x9b,
+ 0xcf, 0x19, 0x85, 0x73, 0x73, 0xdc, 0x7d, 0xca, 0x88, 0x37, 0x34, 0x89,
+ 0xd8, 0x87, 0xd8, 0x3b, 0xcd, 0x58, 0xb9, 0xc9, 0x19, 0xc4, 0xe3, 0x1d,
+ 0x97, 0x93, 0x79, 0xfe, 0xa4, 0x25, 0x1c, 0xc6, 0x7d, 0x07, 0xfe, 0x5b,
+ 0xed, 0x39, 0x1c, 0x73, 0x3f, 0xaf, 0xd0, 0x43, 0x8a, 0x39, 0x29, 0x4e,
+ 0x20, 0x16, 0x9f, 0x86, 0x8d, 0x1b, 0xeb, 0x31, 0xc9, 0xbd, 0x32, 0x9b,
+ 0x0f, 0xf7, 0x8c, 0xf1, 0x17, 0x65, 0xbc, 0xec, 0x82, 0xd3, 0x95, 0x74,
+ 0xbe, 0x51, 0x8e, 0x2c, 0x20, 0xe5, 0x79, 0xa0, 0x0d, 0xf3, 0xb7, 0xa2,
+ 0x8e, 0x7e, 0xbc, 0x46, 0xd6, 0x25, 0xdb, 0x1c, 0xd1, 0xc6, 0xc7, 0x99,
+ 0xdd, 0x67, 0x8c, 0xea, 0xc8, 0x18, 0x45, 0xde, 0x9b, 0x68, 0x3a, 0xcf,
+ 0xa4, 0xf7, 0x0c, 0x8e, 0x2d, 0x02, 0x3a, 0x95, 0x9f, 0x93, 0xb1, 0x0f,
+ 0x0f, 0x7b, 0xf6, 0xe3, 0xfa, 0x5f, 0xe9, 0xe3, 0xe3, 0xfe, 0x56, 0x4d,
+ 0xca, 0xc7, 0x12, 0x6e, 0xda, 0x78, 0x87, 0x0f, 0x46, 0xd6, 0xae, 0xed,
+ 0x33, 0xef, 0xd7, 0x38, 0x5d, 0x43, 0xbc, 0x21, 0x57, 0xc1, 0x1d, 0xcc,
+ 0x27, 0x7c, 0x87, 0xaf, 0x67, 0x3e, 0x04, 0x6f, 0xe8, 0x5c, 0x3b, 0xe5,
+ 0x8b, 0x9c, 0xf0, 0x85, 0xf3, 0xba, 0xc5, 0x55, 0xf0, 0xa5, 0x0d, 0xbe,
+ 0xc0, 0xae, 0xa1, 0x55, 0xa7, 0xc1, 0x05, 0x8e, 0x4d, 0x28, 0x87, 0xcc,
+ 0x1d, 0xe6, 0x0a, 0xf3, 0xe6, 0x31, 0x5f, 0x5e, 0xe9, 0x1a, 0xc6, 0xe6,
+ 0xa7, 0x70, 0xe5, 0x8d, 0x98, 0x2b, 0xcc, 0xd9, 0x24, 0x7e, 0x74, 0x80,
+ 0x55, 0x90, 0xc6, 0x8f, 0x00, 0xf1, 0xa3, 0xc6, 0xf9, 0x4f, 0x1c, 0x0b,
+ 0x12, 0xfd, 0xac, 0x41, 0x3f, 0x35, 0x85, 0xf3, 0x23, 0xd6, 0x0e, 0xdb,
+ 0xb1, 0x7e, 0xd8, 0xae, 0x90, 0xda, 0x8d, 0xc7, 0x91, 0x76, 0xcf, 0x32,
+ 0xb3, 0x38, 0xd2, 0x86, 0x76, 0x3a, 0xa9, 0x8e, 0xda, 0xa9, 0x8e, 0xd0,
+ 0xa7, 0xa5, 0x54, 0xf8, 0x4c, 0xb0, 0x4c, 0x1f, 0xf1, 0xa3, 0x13, 0x8f,
+ 0xd9, 0xa2, 0xe4, 0x2e, 0xc3, 0xda, 0xe6, 0xb8, 0x3b, 0x12, 0x6f, 0xd3,
+ 0x7b, 0x6e, 0x23, 0xbe, 0xe7, 0x7e, 0x45, 0x1f, 0x8f, 0xb7, 0x38, 0x6b,
+ 0xe2, 0x7b, 0xee, 0x29, 0x9d, 0xef, 0xb9, 0x01, 0x7d, 0x49, 0x1f, 0xbd,
+ 0xe7, 0x06, 0x63, 0xf7, 0xdc, 0xcc, 0x96, 0xeb, 0xf7, 0x8b, 0xbb, 0x99,
+ 0x4f, 0x38, 0xf6, 0x32, 0x9f, 0xf6, 0xcb, 0x15, 0xb3, 0x3e, 0x1c, 0x93,
+ 0x58, 0xef, 0x1c, 0xcb, 0x92, 0xdc, 0xec, 0x6e, 0x98, 0xe9, 0xe2, 0x55,
+ 0xcc, 0x83, 0x72, 0x6f, 0x3f, 0x5d, 0x18, 0xa9, 0x2e, 0x26, 0x13, 0x9b,
+ 0xde, 0xa8, 0x36, 0x5e, 0xd5, 0xc7, 0xb5, 0x91, 0x8d, 0x93, 0x69, 0x23,
+ 0x19, 0x73, 0x47, 0x29, 0xe1, 0x0c, 0x2c, 0x23, 0x1e, 0x09, 0xbe, 0xa3,
+ 0x21, 0x5e, 0x54, 0xf3, 0xb8, 0xa7, 0x14, 0x78, 0xec, 0x76, 0xf8, 0x2c,
+ 0x35, 0x8a, 0x8c, 0x0b, 0xaf, 0xff, 0x61, 0x7c, 0x7f, 0xc0, 0xba, 0x0b,
+ 0x01, 0xff, 0xfe, 0xf1, 0x09, 0x3e, 0xbe, 0x06, 0x3e, 0x66, 0xfb, 0x19,
+ 0xad, 0xbf, 0x34, 0x52, 0x5f, 0x4e, 0x31, 0x4f, 0x7c, 0x7e, 0x2f, 0xd5,
+ 0xc8, 0x26, 0x72, 0xb7, 0xfb, 0xc8, 0x8b, 0xde, 0x44, 0xfc, 0x0e, 0x06,
+ 0x1f, 0x47, 0xf7, 0x8a, 0x2a, 0x75, 0x86, 0x36, 0xbf, 0xc0, 0xba, 0x2d,
+ 0x71, 0x13, 0x5f, 0x6f, 0x0c, 0xb2, 0xb1, 0xb9, 0x9d, 0xeb, 0xfe, 0x8d,
+ 0xf3, 0x19, 0x79, 0xdf, 0xb0, 0xef, 0xfb, 0x11, 0xe7, 0xbb, 0x77, 0x81,
+ 0xc5, 0x3b, 0xe1, 0x34, 0xfd, 0x1e, 0x1c, 0x7b, 0x3b, 0xce, 0x79, 0x93,
+ 0x5c, 0x17, 0xfe, 0xc3, 0x99, 0xc7, 0x67, 0xbd, 0xf7, 0x39, 0x99, 0x2e,
+ 0xd3, 0x57, 0x1d, 0xae, 0x93, 0xa9, 0x7e, 0x2a, 0x8a, 0x2e, 0xe2, 0xdc,
+ 0x5f, 0x19, 0x3b, 0xf7, 0x71, 0x07, 0x3c, 0xc9, 0xf9, 0x7f, 0x96, 0xf3,
+ 0xef, 0x46, 0x33, 0xf3, 0xd6, 0x4d, 0x97, 0x5c, 0xa9, 0xde, 0xe7, 0x7c,
+ 0x6c, 0x98, 0x8b, 0x11, 0x1d, 0x7a, 0x14, 0xc9, 0xf3, 0x7c, 0x36, 0xbd,
+ 0x9b, 0xfa, 0x1c, 0x6d, 0x37, 0x1e, 0xe1, 0x1e, 0x53, 0x8b, 0x7f, 0x17,
+ 0x72, 0xfb, 0x3c, 0x0f, 0x97, 0xf1, 0x0e, 0x39, 0x47, 0x78, 0xd2, 0x6f,
+ 0x35, 0x2a, 0xf0, 0xb5, 0xcc, 0x75, 0x85, 0xe2, 0x7b, 0x21, 0xee, 0x6e,
+ 0x3f, 0x6f, 0x53, 0x12, 0x3b, 0x6a, 0xce, 0x39, 0xac, 0x05, 0x98, 0x88,
+ 0x06, 0x30, 0x9e, 0x47, 0xac, 0xb2, 0xcc, 0x93, 0x72, 0xf2, 0x5b, 0xd5,
+ 0x1a, 0xc6, 0x56, 0x4e, 0x72, 0x2e, 0xf9, 0x51, 0xb4, 0x36, 0x88, 0xcf,
+ 0x44, 0x87, 0xb9, 0xe6, 0x87, 0x07, 0x65, 0x7e, 0xbb, 0x21, 0x7f, 0xeb,
+ 0x98, 0xc7, 0x7c, 0x02, 0x0f, 0x8b, 0xa2, 0x76, 0xc3, 0x14, 0xf5, 0x9e,
+ 0x29, 0x96, 0x7a, 0x32, 0x54, 0x52, 0xc8, 0xd1, 0x14, 0xe7, 0x08, 0x3a,
+ 0xd1, 0x73, 0x58, 0xcb, 0x2d, 0x53, 0xf8, 0xc8, 0xa3, 0xbe, 0xad, 0x58,
+ 0x62, 0x85, 0x76, 0xb1, 0xc7, 0x47, 0x51, 0x72, 0xa7, 0x35, 0x45, 0x6d,
+ 0x38, 0xf7, 0x23, 0xcc, 0xcd, 0x6b, 0x62, 0x2d, 0xf3, 0x79, 0xb6, 0x2c,
+ 0x9d, 0x83, 0x8f, 0xce, 0xf7, 0x77, 0x11, 0x43, 0xf9, 0x3c, 0xcb, 0x23,
+ 0xe6, 0x59, 0x26, 0x5f, 0xf6, 0xef, 0x62, 0xff, 0xef, 0xf4, 0x80, 0x0f,
+ 0x72, 0xc7, 0xb7, 0x87, 0x79, 0x1a, 0x63, 0x58, 0x06, 0x17, 0xd9, 0x3e,
+ 0x8a, 0x82, 0xc5, 0x38, 0x47, 0xc1, 0x5a, 0xe6, 0xca, 0xb7, 0x90, 0xa7,
+ 0xd7, 0x69, 0xa1, 0x5c, 0x8f, 0xdf, 0x11, 0x72, 0x12, 0xfe, 0x5d, 0xc0,
+ 0x12, 0x4d, 0x7c, 0xd7, 0xd2, 0xef, 0x80, 0x73, 0xf8, 0x45, 0x1e, 0x83,
+ 0x73, 0x79, 0xd6, 0xe1, 0x7f, 0x01, 0x17, 0xc6, 0xf1, 0xb2, 0x84, 0x14,
+ 0x00, 0x00, 0x00 };
+static u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b09FwBss[(0x250/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b09FwSbss[(0x34/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_tpat_fw_09 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x08000860,
+
+ .text_addr = 0x08000800,
+ .text_len = 0x1480,
+ .text_index = 0x0,
+ .gz_text = bnx2_TPAT_b09FwText,
+ .gz_text_len = sizeof(bnx2_TPAT_b09FwText),
+
+ .data_addr = 0x08001ca0,
+ .data_len = 0x0,
+ .data_index = 0x0,
+ .data = bnx2_TPAT_b09FwData,
+
+ .sbss_addr = 0x08001ca0,
+ .sbss_len = 0x34,
+ .sbss_index = 0x0,
+ .sbss = bnx2_TPAT_b09FwSbss,
+
+ .bss_addr = 0x08001ce0,
+ .bss_len = 0x250,
+ .bss_index = 0x0,
+ .bss = bnx2_TPAT_b09FwBss,
+
+ .rodata_addr = 0x00000000,
+ .rodata_len = 0x0,
+ .rodata_index = 0x0,
+ .rodata = bnx2_TPAT_b09FwRodata,
+};
+
+static u8 bnx2_TXP_b09FwText[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0x51, 0xfe, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65,
+ 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xcd, 0x7b, 0x7f, 0x70,
+ 0x1b, 0xe7, 0x99, 0xde, 0xbb, 0x0b, 0x80, 0x04, 0x29, 0x8a, 0x5a, 0x31,
+ 0x30, 0x83, 0x38, 0xb4, 0x8d, 0x15, 0x17, 0x34, 0x6d, 0xf2, 0x1c, 0x58,
+ 0xe5, 0xf9, 0xd8, 0x06, 0xb5, 0xd7, 0xc0, 0x92, 0xa2, 0x63, 0x26, 0x47,
+ 0xbb, 0xcc, 0x9d, 0x92, 0x51, 0x7d, 0x28, 0x48, 0x29, 0x6e, 0xe3, 0xb4,
+ 0xaa, 0xe3, 0x3f, 0x34, 0x4d, 0x5b, 0xc3, 0x00, 0x25, 0xcb, 0x2e, 0x44,
+ 0xd0, 0x16, 0x63, 0xa5, 0x33, 0x37, 0x53, 0x18, 0x80, 0x28, 0xe7, 0xba,
+ 0x24, 0xdc, 0xe4, 0x2e, 0xe9, 0x1f, 0xc9, 0x99, 0xa5, 0x6c, 0xc5, 0x6d,
+ 0xae, 0x33, 0xbe, 0x3f, 0xda, 0xa6, 0x37, 0xd7, 0x19, 0x8d, 0xfc, 0x23,
+ 0xce, 0x8f, 0xb9, 0xb8, 0x69, 0x7a, 0x56, 0x5b, 0xd9, 0xe8, 0xf3, 0x7c,
+ 0xbb, 0x4b, 0x82, 0x32, 0x15, 0x5b, 0xd7, 0x76, 0xa6, 0x9c, 0xc1, 0x10,
+ 0xfb, 0xed, 0xb7, 0xdf, 0xf7, 0xfe, 0x7e, 0xdf, 0xe7, 0xfd, 0x16, 0x71,
+ 0x91, 0x6e, 0xf1, 0xff, 0x76, 0xe3, 0x93, 0x38, 0x7a, 0xec, 0xb1, 0x3b,
+ 0xc6, 0xef, 0xd8, 0x2f, 0x72, 0xe7, 0x9d, 0xb2, 0x2b, 0xaa, 0xf3, 0xe6,
+ 0xdb, 0x21, 0x91, 0xdc, 0x4f, 0xe5, 0xaf, 0xfc, 0x87, 0xc7, 0x8d, 0x60,
+ 0x7d, 0x7e, 0x24, 0xaa, 0xa7, 0x5f, 0xcc, 0x64, 0x2c, 0x89, 0x86, 0xd2,
+ 0x33, 0x9f, 0x9d, 0xb3, 0x44, 0x6c, 0x77, 0x24, 0x91, 0x95, 0xf7, 0x5a,
+ 0x85, 0x58, 0x58, 0x38, 0x7e, 0x53, 0xfa, 0xca, 0xe3, 0xdf, 0xff, 0x2d,
+ 0xf3, 0x9d, 0x6a, 0x48, 0xa2, 0x46, 0x3a, 0x27, 0xc6, 0x90, 0x44, 0x07,
+ 0xf0, 0xcc, 0xef, 0xdf, 0x3a, 0xa5, 0x4b, 0x6f, 0xb0, 0x56, 0x5c, 0x16,
+ 0x2a, 0x6f, 0xb7, 0xbe, 0x7f, 0x6b, 0x4c, 0xfe, 0x55, 0xd3, 0x90, 0x17,
+ 0x9b, 0x61, 0x6d, 0xb2, 0xd2, 0x23, 0xa5, 0x8a, 0x2b, 0xc7, 0xcb, 0x05,
+ 0xc9, 0x36, 0x5f, 0x90, 0xe2, 0xb2, 0xd1, 0x9b, 0x39, 0xf7, 0x07, 0x52,
+ 0x5a, 0xee, 0xeb, 0xcd, 0x9e, 0x73, 0xa5, 0x58, 0x8e, 0xf7, 0x66, 0x9a,
+ 0x46, 0x6f, 0xf6, 0x4c, 0x0c, 0xd7, 0x7d, 0xbd, 0x99, 0x33, 0x66, 0x41,
+ 0xa4, 0x1f, 0x73, 0xe2, 0xbd, 0xd9, 0x8a, 0x99, 0x13, 0x19, 0x4c, 0xbd,
+ 0x22, 0x03, 0xbd, 0xd9, 0x66, 0x4d, 0x5b, 0x37, 0x34, 0x29, 0xfe, 0x86,
+ 0x18, 0xbd, 0xe9, 0xcb, 0xad, 0x4f, 0x58, 0x86, 0xec, 0xb5, 0x64, 0xcf,
+ 0x1e, 0x4b, 0x9e, 0x88, 0xa7, 0xa3, 0x92, 0x3f, 0xdd, 0x25, 0xb6, 0xe2,
+ 0xc9, 0x90, 0xfc, 0x99, 0x11, 0x63, 0x43, 0x22, 0x62, 0xc7, 0x82, 0xeb,
+ 0x56, 0x2b, 0x93, 0xfa, 0x02, 0xe5, 0x8a, 0xbd, 0xa4, 0x77, 0xb2, 0x29,
+ 0x92, 0xa9, 0x44, 0x25, 0x93, 0x7a, 0xaf, 0xe5, 0x3d, 0x13, 0xc5, 0xbe,
+ 0xe1, 0xde, 0x89, 0x4a, 0xab, 0xe5, 0xa4, 0xb0, 0x47, 0x2a, 0x78, 0x36,
+ 0x22, 0xd5, 0x98, 0x5d, 0x2d, 0xa5, 0x4c, 0xdd, 0xd3, 0x09, 0x79, 0xe4,
+ 0xb5, 0x2d, 0xba, 0xf5, 0xdb, 0x92, 0x8f, 0x49, 0xb5, 0x98, 0xba, 0x4b,
+ 0x9e, 0x4e, 0x19, 0x72, 0x12, 0xeb, 0x3d, 0x95, 0x82, 0x1c, 0xad, 0x63,
+ 0x5a, 0xa6, 0x69, 0xc6, 0x45, 0x7b, 0x5a, 0x32, 0x67, 0x06, 0x8d, 0xac,
+ 0x60, 0x6f, 0xab, 0x75, 0x4b, 0x26, 0x85, 0xfd, 0x46, 0xff, 0x67, 0xcb,
+ 0x8e, 0x99, 0xb9, 0xaa, 0x0c, 0x48, 0xb1, 0x32, 0x98, 0xfa, 0x13, 0xd1,
+ 0xa4, 0xd3, 0xa2, 0x7c, 0x5a, 0x72, 0x3f, 0xf6, 0xcd, 0x58, 0x18, 0x6f,
+ 0x8a, 0xad, 0x27, 0x23, 0xf2, 0x0f, 0x0c, 0x33, 0x91, 0x09, 0xf5, 0x4b,
+ 0xf1, 0x74, 0x27, 0xe8, 0xb4, 0xfb, 0x74, 0xcc, 0x3d, 0x30, 0x26, 0xb1,
+ 0x5d, 0x22, 0x5a, 0x28, 0x9d, 0xc4, 0xba, 0x22, 0x45, 0x77, 0x00, 0xcf,
+ 0x26, 0xc7, 0x7f, 0x2a, 0x7b, 0x24, 0xb1, 0x37, 0x2c, 0x25, 0xb7, 0x1b,
+ 0x72, 0x34, 0xa0, 0x83, 0xe4, 0xf8, 0x5f, 0x40, 0x29, 0xba, 0x95, 0x8c,
+ 0x1f, 0x93, 0x9c, 0x96, 0x6d, 0x76, 0x48, 0x29, 0x19, 0x95, 0x05, 0xd0,
+ 0xb1, 0x90, 0xfa, 0xa2, 0x96, 0x39, 0x77, 0x50, 0xcb, 0x9e, 0xc3, 0xbc,
+ 0x66, 0xdd, 0xb7, 0x35, 0x03, 0xeb, 0xe8, 0x52, 0x4c, 0x1e, 0xc4, 0xbd,
+ 0xa8, 0xcc, 0x61, 0xde, 0x1c, 0x78, 0x2a, 0x35, 0xf7, 0xc8, 0xfa, 0x6c,
+ 0xac, 0x37, 0x03, 0x1d, 0x16, 0x71, 0xff, 0xb7, 0x67, 0x34, 0x31, 0x2c,
+ 0x5b, 0x7e, 0x3c, 0x06, 0x1d, 0x9e, 0x81, 0xfe, 0xce, 0xc4, 0xe5, 0x78,
+ 0x45, 0x62, 0xba, 0x24, 0xe3, 0x79, 0x79, 0x41, 0xea, 0x2e, 0xf5, 0x0f,
+ 0x7d, 0x42, 0xdf, 0x45, 0x97, 0xcf, 0x41, 0x6f, 0x15, 0x07, 0xf2, 0x98,
+ 0x02, 0x0d, 0x0f, 0x6a, 0xf7, 0xd7, 0x67, 0xb5, 0x03, 0xcd, 0x1f, 0x6b,
+ 0xd2, 0x7d, 0x4c, 0xfb, 0x5c, 0xf3, 0x88, 0xe6, 0xcb, 0x1e, 0xba, 0x8b,
+ 0x8a, 0x3d, 0x13, 0x95, 0x95, 0xa6, 0xa7, 0xbb, 0x1a, 0xec, 0xd3, 0x36,
+ 0x6c, 0xe8, 0xe1, 0x6f, 0x6f, 0xce, 0x59, 0x69, 0xc6, 0x64, 0x01, 0xb4,
+ 0x1d, 0x6f, 0x72, 0xfe, 0xef, 0x41, 0x3f, 0x51, 0x71, 0x6f, 0xed, 0x91,
+ 0x1c, 0xc6, 0x8b, 0x67, 0xc4, 0xce, 0xa4, 0x74, 0x3c, 0xd3, 0x2b, 0x21,
+ 0xab, 0x1f, 0x9f, 0x6e, 0x99, 0xab, 0x77, 0xda, 0x21, 0x2b, 0x26, 0x73,
+ 0x4d, 0xca, 0x10, 0xff, 0x2b, 0x81, 0x1c, 0x49, 0x2b, 0xc7, 0xf9, 0x1c,
+ 0xc7, 0x0d, 0x8c, 0xb7, 0x8f, 0xd1, 0x2e, 0x7a, 0x41, 0x8f, 0x39, 0x2c,
+ 0x18, 0xcb, 0x57, 0x92, 0xc6, 0xe7, 0xf8, 0xbf, 0x49, 0xd9, 0x06, 0x32,
+ 0x0d, 0x63, 0xae, 0x2e, 0xf9, 0x3a, 0xf6, 0x39, 0x7d, 0xa5, 0x15, 0x19,
+ 0xc3, 0xb5, 0xf5, 0x4b, 0xc8, 0x92, 0xfb, 0x86, 0x41, 0x93, 0x2e, 0xb9,
+ 0x3a, 0xd7, 0xe2, 0x7d, 0x81, 0xee, 0x8b, 0x7b, 0x75, 0x19, 0x86, 0x7e,
+ 0x4d, 0xec, 0xd3, 0x85, 0x39, 0x3d, 0x90, 0x1f, 0x78, 0x3d, 0x87, 0xef,
+ 0xe0, 0x5d, 0xb7, 0x74, 0x3c, 0xdf, 0x29, 0x73, 0x29, 0xda, 0x0b, 0xe9,
+ 0xdc, 0x85, 0xb5, 0xbb, 0x64, 0xfe, 0x34, 0xe5, 0x01, 0xbb, 0xaa, 0xc4,
+ 0xa4, 0x74, 0xc6, 0x34, 0x1c, 0x31, 0x21, 0x1b, 0x1b, 0xf3, 0x3a, 0x25,
+ 0x67, 0xb4, 0x5a, 0x13, 0xa9, 0x11, 0xe3, 0x9b, 0xca, 0xce, 0x47, 0x8c,
+ 0xa4, 0x26, 0x85, 0x8e, 0xf4, 0x10, 0x64, 0x6b, 0x1e, 0x14, 0xe1, 0xf5,
+ 0x0f, 0xc4, 0x9e, 0xa5, 0xff, 0xc4, 0xb8, 0x17, 0xfc, 0xa9, 0x1f, 0xf4,
+ 0xd3, 0xe7, 0x06, 0xa0, 0x97, 0xb8, 0xf2, 0x83, 0x89, 0x1d, 0xfd, 0xc0,
+ 0x9c, 0xaa, 0x82, 0xdf, 0xe2, 0xb9, 0x30, 0xfd, 0x2f, 0x05, 0x73, 0x93,
+ 0x5d, 0x56, 0x14, 0xb6, 0x40, 0x5a, 0xc6, 0xb1, 0x7e, 0xab, 0xf5, 0xd9,
+ 0x94, 0x47, 0x53, 0xf1, 0x8c, 0x8d, 0x67, 0xc3, 0x90, 0xbb, 0xf9, 0x70,
+ 0x42, 0xed, 0x3f, 0xee, 0xef, 0x6f, 0xc8, 0x1c, 0xe8, 0x2e, 0x56, 0x42,
+ 0x92, 0x35, 0xb8, 0xc6, 0x9f, 0x71, 0x3c, 0xe7, 0xad, 0x05, 0xbb, 0x3d,
+ 0x35, 0x68, 0xdc, 0x07, 0x5f, 0xa2, 0x8f, 0x15, 0x57, 0x29, 0x63, 0xac,
+ 0x33, 0x46, 0x19, 0x1b, 0x8a, 0xc6, 0xcc, 0x19, 0xda, 0x91, 0x0c, 0x84,
+ 0x84, 0x76, 0x8e, 0x98, 0x01, 0xbb, 0x2a, 0xf9, 0x76, 0x95, 0x77, 0xa9,
+ 0xff, 0xbb, 0x7d, 0xff, 0xd4, 0x65, 0x28, 0x49, 0x7b, 0x7f, 0x5a, 0xb2,
+ 0xf0, 0xf1, 0x39, 0xec, 0x54, 0x07, 0x4f, 0xb5, 0xca, 0x20, 0x64, 0x15,
+ 0xf8, 0x1d, 0xf4, 0x3b, 0xfa, 0x6e, 0x2b, 0x88, 0x05, 0xc5, 0x0a, 0x7d,
+ 0xa6, 0x68, 0xe8, 0x52, 0xc0, 0x07, 0x76, 0x63, 0x99, 0xc3, 0x99, 0x90,
+ 0x39, 0x93, 0x03, 0x6d, 0xb0, 0x7b, 0xc9, 0xdc, 0x49, 0x7b, 0xc6, 0x9c,
+ 0xa6, 0xec, 0x0f, 0xfc, 0xac, 0xe6, 0x52, 0x4f, 0xdd, 0xd8, 0x37, 0xa0,
+ 0x29, 0x8c, 0x31, 0xae, 0x13, 0x85, 0xcd, 0x07, 0x36, 0x43, 0xfb, 0x33,
+ 0xed, 0x75, 0xe9, 0x90, 0xe1, 0x24, 0x62, 0xd9, 0x19, 0x1d, 0xfa, 0x1b,
+ 0x40, 0x4c, 0x09, 0xcb, 0x11, 0xc8, 0xea, 0x4b, 0x15, 0xd2, 0xe7, 0xc0,
+ 0xef, 0x10, 0xdb, 0xce, 0x4c, 0xc2, 0xcf, 0xa6, 0xb4, 0x09, 0xf8, 0xc4,
+ 0x67, 0xea, 0xa4, 0xa9, 0x25, 0xf4, 0x4b, 0xe7, 0x5c, 0x4e, 0x9b, 0x6c,
+ 0x1e, 0xd4, 0xa6, 0xce, 0xd1, 0x4f, 0xe8, 0x23, 0xa6, 0xf1, 0x80, 0x78,
+ 0x3c, 0x14, 0x9b, 0xaf, 0x68, 0xf4, 0xd5, 0xe2, 0xa9, 0x2e, 0xd0, 0xb1,
+ 0x0b, 0xf4, 0x18, 0xf0, 0x3d, 0xd8, 0x97, 0x65, 0xce, 0xd0, 0x66, 0x9c,
+ 0xa4, 0x95, 0xf8, 0xe7, 0xf2, 0x41, 0x39, 0x4c, 0x6c, 0xca, 0x61, 0x04,
+ 0x32, 0xd9, 0x2e, 0x87, 0x85, 0x0f, 0xca, 0xc1, 0x2e, 0x40, 0x0e, 0x0b,
+ 0x88, 0x43, 0x0b, 0x4d, 0xf2, 0xdc, 0x12, 0xfd, 0x4e, 0x81, 0x75, 0xca,
+ 0xbd, 0x7a, 0x9a, 0x36, 0x4a, 0x3f, 0x49, 0x26, 0x4a, 0x58, 0xa1, 0xe1,
+ 0xf6, 0x28, 0xdf, 0x98, 0x54, 0xb2, 0xf8, 0x30, 0x7e, 0xc9, 0xdf, 0x16,
+ 0xcf, 0x53, 0x75, 0xc6, 0x1b, 0xd8, 0x79, 0xd2, 0x32, 0xbe, 0x20, 0x5b,
+ 0x7c, 0xdf, 0xb7, 0xc5, 0x37, 0xf6, 0x09, 0x62, 0x10, 0x79, 0x0e, 0xe2,
+ 0x31, 0x6d, 0xe5, 0xa5, 0x56, 0xc8, 0xb2, 0xa0, 0x03, 0xda, 0x0b, 0x69,
+ 0x30, 0x8d, 0xcf, 0x0a, 0xfe, 0x23, 0x2e, 0xd0, 0x97, 0x72, 0x6a, 0x5e,
+ 0x87, 0xe4, 0xf6, 0x7a, 0xf3, 0xe7, 0x2a, 0xad, 0x5f, 0xe8, 0xe9, 0xf7,
+ 0x5b, 0x99, 0x31, 0xcb, 0xf7, 0xf1, 0xa8, 0x7c, 0xb9, 0x6e, 0xe6, 0x12,
+ 0x5a, 0x8f, 0x14, 0x6e, 0x40, 0x5c, 0xa9, 0xd0, 0x3f, 0xfa, 0xaf, 0x11,
+ 0xcb, 0x06, 0xfc, 0x58, 0xf6, 0x13, 0xc8, 0x9e, 0xb9, 0xe7, 0xf0, 0xfb,
+ 0xeb, 0x31, 0xfe, 0x4f, 0x1a, 0x33, 0xf2, 0x05, 0xe6, 0x9b, 0x3d, 0xba,
+ 0x8a, 0xdf, 0x16, 0x73, 0x41, 0x21, 0x9c, 0xee, 0x96, 0xc2, 0x5e, 0x29,
+ 0x84, 0xd2, 0xf4, 0x23, 0xfa, 0x46, 0x87, 0x4f, 0x77, 0x90, 0x3b, 0xf8,
+ 0x77, 0x4c, 0x17, 0x8b, 0x73, 0x90, 0x27, 0x2a, 0xe4, 0xe3, 0xbd, 0x40,
+ 0x27, 0x78, 0x46, 0x22, 0x9e, 0xcd, 0x4d, 0x23, 0x66, 0x52, 0xa6, 0xed,
+ 0xf6, 0xc2, 0x58, 0x2a, 0x09, 0xdd, 0x62, 0x2c, 0x15, 0x23, 0x94, 0x7e,
+ 0x50, 0xb3, 0xeb, 0x5f, 0xd4, 0x6c, 0xc8, 0xce, 0x86, 0xec, 0x6c, 0xc8,
+ 0x2e, 0x03, 0xd9, 0x65, 0x9b, 0xa4, 0x87, 0xb4, 0x78, 0xeb, 0x3b, 0xde,
+ 0xfa, 0xa0, 0xb3, 0x5f, 0xf2, 0xca, 0xc7, 0xc9, 0x2f, 0x62, 0xb2, 0x8a,
+ 0x07, 0x93, 0x9a, 0x17, 0x0f, 0xb8, 0xde, 0x14, 0x9e, 0xbf, 0x1b, 0x79,
+ 0xce, 0xd6, 0x75, 0x6b, 0x4b, 0x26, 0x0b, 0x6d, 0x32, 0x29, 0xb9, 0x94,
+ 0x11, 0xe7, 0xd3, 0x97, 0x5d, 0xe8, 0x3d, 0x90, 0xcb, 0x34, 0x68, 0xe8,
+ 0x24, 0xef, 0x3e, 0x1f, 0x5c, 0xbf, 0xcf, 0x5f, 0xff, 0xd3, 0x58, 0x93,
+ 0xbe, 0xbb, 0xd3, 0xbe, 0xdc, 0x93, 0xb9, 0xf4, 0xd7, 0xf1, 0x83, 0x5a,
+ 0x02, 0x31, 0xfa, 0x45, 0xf8, 0xda, 0xc5, 0x50, 0x5c, 0xbe, 0x7f, 0xeb,
+ 0x6b, 0xa8, 0x2f, 0xa4, 0x70, 0x63, 0xba, 0x95, 0x08, 0xa7, 0xdf, 0x6b,
+ 0x2d, 0x8c, 0x21, 0x7e, 0xa6, 0xcd, 0x78, 0x26, 0x34, 0x2a, 0x2f, 0x35,
+ 0x87, 0xe5, 0x3b, 0x4d, 0x4b, 0xfe, 0xa8, 0x99, 0x90, 0x3f, 0x6c, 0x0e,
+ 0xc8, 0xb7, 0x9b, 0x71, 0xf9, 0x56, 0x33, 0xa8, 0x45, 0xe2, 0xb4, 0xa5,
+ 0x5e, 0xa7, 0xb9, 0x53, 0x3d, 0x04, 0x3b, 0xc7, 0x5a, 0x99, 0xb1, 0x70,
+ 0x2e, 0x94, 0x56, 0x35, 0xc2, 0xcc, 0xd1, 0xf2, 0xe3, 0x2d, 0xdd, 0xb2,
+ 0x0a, 0xba, 0xde, 0x33, 0x6e, 0xdc, 0x25, 0x39, 0x3d, 0x8d, 0x31, 0x77,
+ 0x3c, 0xec, 0x94, 0xbb, 0x90, 0x5f, 0xa2, 0xa8, 0x65, 0x06, 0xa4, 0x80,
+ 0x75, 0x0b, 0xcd, 0x56, 0x6b, 0x29, 0xf5, 0x0f, 0x3f, 0x65, 0xfc, 0x8d,
+ 0x7f, 0xd9, 0x29, 0xbd, 0xdf, 0x5e, 0x37, 0x86, 0xfe, 0xbb, 0x5f, 0x0f,
+ 0xa1, 0xc6, 0xea, 0x57, 0x8b, 0xe7, 0xb4, 0xf4, 0xa8, 0x93, 0x70, 0x37,
+ 0x70, 0x5f, 0xa2, 0xfd, 0xd6, 0xcf, 0x51, 0x85, 0xc8, 0xee, 0x98, 0xc5,
+ 0x9a, 0x6b, 0x26, 0xfb, 0x79, 0xfc, 0xff, 0x58, 0x5a, 0xf6, 0xf4, 0xe1,
+ 0xff, 0xde, 0x34, 0x4c, 0x2a, 0xcd, 0x98, 0xac, 0xb5, 0xc5, 0x64, 0xd1,
+ 0x1c, 0xe4, 0xdf, 0x05, 0xf0, 0xe4, 0x40, 0x1e, 0xbf, 0xd3, 0x8c, 0x6a,
+ 0xd9, 0xd3, 0xfd, 0x52, 0xaa, 0x33, 0xaf, 0x71, 0x5e, 0xd4, 0xaf, 0x7b,
+ 0x78, 0xdd, 0x81, 0x6b, 0x41, 0xae, 0xf9, 0x94, 0x48, 0xaf, 0xf9, 0xa3,
+ 0xcf, 0x4b, 0xdd, 0xaf, 0x5b, 0x22, 0xb2, 0xac, 0x6c, 0x8c, 0xe3, 0xaf,
+ 0x65, 0xbf, 0x36, 0xb4, 0x35, 0xfe, 0xec, 0xe6, 0xf8, 0x3b, 0xd9, 0x4f,
+ 0x6f, 0x8e, 0x77, 0x87, 0x3d, 0x1e, 0xc6, 0xb5, 0x99, 0x66, 0xc1, 0x1f,
+ 0xbb, 0x0c, 0xb9, 0xb7, 0x5a, 0x0b, 0xc8, 0x3d, 0x45, 0xeb, 0x32, 0xea,
+ 0x24, 0xc6, 0x9f, 0xeb, 0x89, 0x37, 0xdb, 0x62, 0x8d, 0x91, 0x09, 0x51,
+ 0x9f, 0x51, 0xf1, 0xd6, 0xe4, 0xfd, 0x4e, 0xc4, 0x9d, 0xcb, 0xf8, 0xce,
+ 0x3c, 0x17, 0xc4, 0x3c, 0xce, 0xe1, 0xf3, 0x6f, 0x5f, 0x43, 0xe7, 0x31,
+ 0xe8, 0xfc, 0xff, 0x1b, 0xdd, 0xe2, 0x4f, 0xe9, 0x56, 0xc5, 0x9d, 0x97,
+ 0xb6, 0xd9, 0x2c, 0xe9, 0xef, 0xf6, 0x69, 0x96, 0x68, 0x38, 0x6d, 0x38,
+ 0x0b, 0xd6, 0x8d, 0x12, 0x41, 0x0d, 0x4b, 0x9b, 0x2d, 0x35, 0xbf, 0x8b,
+ 0xe7, 0x99, 0x27, 0x25, 0x1a, 0x49, 0xd3, 0x2e, 0xd6, 0x07, 0x32, 0xd6,
+ 0x31, 0xa7, 0xe6, 0x1e, 0x73, 0xce, 0x2a, 0x3b, 0x59, 0xbf, 0xc9, 0xab,
+ 0xcd, 0x7f, 0x74, 0x13, 0x6a, 0x73, 0x3c, 0xcf, 0x98, 0xcb, 0xf1, 0x46,
+ 0x4f, 0xc6, 0x62, 0x0e, 0x5a, 0x72, 0x8a, 0xf8, 0x2c, 0xa8, 0xb9, 0xaf,
+ 0x0e, 0x70, 0x6e, 0x67, 0x3a, 0x76, 0xd3, 0x8f, 0xf1, 0xbf, 0x23, 0xfd,
+ 0xce, 0x4d, 0x17, 0x2c, 0xae, 0x3b, 0x75, 0xd3, 0x59, 0xb5, 0x46, 0x18,
+ 0xf1, 0x8c, 0xf3, 0x2e, 0xdf, 0xc4, 0x67, 0x9f, 0x44, 0x1c, 0x3f, 0xe1,
+ 0x42, 0x97, 0xee, 0x8b, 0x4e, 0x1e, 0x9f, 0x39, 0xd2, 0x54, 0xe1, 0x7d,
+ 0xe3, 0xe6, 0x8c, 0x15, 0x56, 0xf9, 0xf6, 0x4b, 0x98, 0x73, 0x04, 0x73,
+ 0x0e, 0xbb, 0x01, 0x3f, 0xea, 0xbe, 0x93, 0xc5, 0xfd, 0xc3, 0x65, 0xc3,
+ 0x71, 0xca, 0xe6, 0x38, 0x6a, 0x8e, 0xf8, 0x71, 0xe4, 0xe3, 0x1c, 0x72,
+ 0xa0, 0x2d, 0xe6, 0x70, 0x41, 0xd2, 0x5d, 0x93, 0xa8, 0xe5, 0x56, 0x90,
+ 0x4f, 0x50, 0x87, 0xa4, 0xaa, 0x32, 0xd8, 0x95, 0x39, 0xad, 0xc3, 0x3e,
+ 0xef, 0x80, 0xbd, 0x1a, 0x8e, 0x9e, 0x44, 0x5c, 0x47, 0xdc, 0x5c, 0xa8,
+ 0x58, 0x5a, 0xb6, 0x3c, 0x68, 0x94, 0xe4, 0x56, 0x59, 0x37, 0xcc, 0xf8,
+ 0xa4, 0xec, 0x92, 0x6c, 0x18, 0xf3, 0x86, 0x3f, 0x2e, 0xb9, 0xb8, 0x86,
+ 0xd8, 0x70, 0x03, 0xe2, 0x16, 0xeb, 0xe4, 0xf6, 0x18, 0xfa, 0x0b, 0x11,
+ 0xeb, 0x8b, 0x21, 0xc6, 0x9e, 0x4e, 0x8b, 0x75, 0x3f, 0xe7, 0xed, 0x92,
+ 0x8d, 0x0f, 0xcc, 0x7b, 0xb7, 0x6d, 0x5e, 0xfb, 0xf8, 0x7b, 0x18, 0xdf,
+ 0x25, 0x17, 0x41, 0x47, 0x38, 0x39, 0x26, 0x25, 0xf0, 0x10, 0x39, 0xd5,
+ 0x6a, 0x5d, 0x00, 0x3f, 0x3a, 0xf8, 0x2f, 0x56, 0x59, 0x0b, 0x84, 0xa4,
+ 0x6a, 0xe0, 0x9e, 0xdb, 0x6a, 0xd5, 0x10, 0x46, 0xf5, 0x55, 0xd2, 0x1c,
+ 0x95, 0x49, 0x77, 0x48, 0xec, 0x06, 0xe5, 0x60, 0xc2, 0xeb, 0xfe, 0xac,
+ 0x2b, 0x7b, 0x86, 0x39, 0x13, 0x16, 0xb1, 0xfa, 0xe7, 0x5d, 0x19, 0xe4,
+ 0x3e, 0x7d, 0xf5, 0x62, 0x57, 0x16, 0x7a, 0x0f, 0xad, 0xfe, 0xe7, 0x2e,
+ 0xe7, 0x34, 0xe9, 0x0a, 0x21, 0xf7, 0xdd, 0x22, 0x45, 0xa3, 0x25, 0xdf,
+ 0x44, 0x8d, 0x50, 0x1c, 0x46, 0x2e, 0x83, 0x17, 0xe8, 0xa0, 0xbb, 0x60,
+ 0x48, 0xb4, 0x3b, 0xfd, 0x7d, 0xd0, 0x37, 0x06, 0xd9, 0xec, 0xc2, 0x9c,
+ 0x10, 0xc6, 0x87, 0xf0, 0xbf, 0x7d, 0xfc, 0x8d, 0x2e, 0xe4, 0x05, 0xc4,
+ 0x60, 0x89, 0x66, 0xc6, 0x7a, 0xb0, 0xfe, 0xf7, 0x30, 0x8e, 0x09, 0xc9,
+ 0xcd, 0xf1, 0x27, 0xbc, 0xf1, 0xb7, 0x41, 0x0b, 0x9f, 0x63, 0x8d, 0x22,
+ 0xd1, 0xb9, 0x31, 0x03, 0x34, 0x70, 0x6e, 0x4c, 0xcd, 0x75, 0xce, 0xd0,
+ 0x06, 0x0c, 0xa7, 0x66, 0xdd, 0x2c, 0xd9, 0xe5, 0x7e, 0x99, 0x5c, 0xee,
+ 0x93, 0x03, 0xcb, 0xe6, 0x4c, 0x95, 0xd8, 0x0f, 0x3c, 0x0b, 0xea, 0x30,
+ 0x7d, 0x55, 0x20, 0x01, 0x33, 0x7e, 0x44, 0x06, 0xe3, 0x5f, 0x92, 0x5f,
+ 0xb6, 0x90, 0xef, 0x91, 0xeb, 0x7b, 0x24, 0xac, 0xd6, 0x89, 0x07, 0x7b,
+ 0xd2, 0x46, 0xb7, 0xed, 0xeb, 0x9c, 0xb9, 0xd6, 0xba, 0x70, 0xfe, 0xd5,
+ 0xf8, 0x55, 0xeb, 0xfe, 0x85, 0xbf, 0xae, 0x81, 0x75, 0x07, 0xb0, 0x26,
+ 0x79, 0x34, 0xbb, 0x26, 0x4e, 0x8b, 0xdd, 0x09, 0xfa, 0x9c, 0xe4, 0x8d,
+ 0xc0, 0x86, 0xfd, 0x72, 0x62, 0x99, 0xf1, 0x42, 0xfa, 0xf1, 0x19, 0x8d,
+ 0x48, 0x72, 0xf8, 0x1c, 0xea, 0xae, 0x09, 0xb5, 0x86, 0x57, 0x93, 0xe9,
+ 0xab, 0x29, 0xd4, 0xc4, 0x3f, 0x05, 0x3d, 0xac, 0x15, 0xc8, 0x73, 0x18,
+ 0xfc, 0xa6, 0x50, 0x8b, 0x11, 0x47, 0xb5, 0x1e, 0xcf, 0xa4, 0xf0, 0xfd,
+ 0x5c, 0xa2, 0x2b, 0x8b, 0x98, 0x08, 0xff, 0xbe, 0x39, 0xa4, 0x72, 0x18,
+ 0xf5, 0x32, 0xda, 0x45, 0x3c, 0x83, 0xe7, 0xa1, 0x27, 0xca, 0x68, 0xbc,
+ 0xcb, 0xa9, 0x50, 0x46, 0x02, 0x7a, 0x2c, 0xd8, 0x64, 0x58, 0x61, 0x29,
+ 0x7d, 0xd5, 0xc6, 0xbc, 0xb7, 0x42, 0xac, 0x77, 0x33, 0x16, 0xbf, 0x23,
+ 0xe6, 0xac, 0x4e, 0x61, 0x2e, 0xbf, 0xdf, 0x85, 0x75, 0x07, 0x87, 0x8b,
+ 0xd2, 0x31, 0x7c, 0x18, 0xf1, 0x4e, 0x1f, 0x1b, 0x01, 0x6d, 0xb4, 0xf3,
+ 0x16, 0xb0, 0xc0, 0x6f, 0x81, 0x1f, 0xf8, 0x46, 0xd2, 0x92, 0xf9, 0x25,
+ 0xca, 0x55, 0x3e, 0x0e, 0x1e, 0xc0, 0x7f, 0x12, 0x71, 0x8d, 0x3c, 0x70,
+ 0x6f, 0x41, 0x8e, 0xbe, 0x5b, 0xf2, 0x4b, 0x51, 0x55, 0xeb, 0xdb, 0x06,
+ 0xf7, 0xd7, 0x34, 0x3d, 0xdd, 0x0d, 0x1d, 0x93, 0xb7, 0x1c, 0x68, 0x7b,
+ 0x0c, 0x79, 0x80, 0xbc, 0x91, 0x2f, 0xfa, 0xca, 0x28, 0xfc, 0x84, 0xf4,
+ 0xfb, 0xb6, 0xa7, 0xad, 0x23, 0xa6, 0xa8, 0x38, 0x98, 0xca, 0x20, 0xb0,
+ 0xbd, 0xd4, 0x1c, 0x97, 0x3f, 0x6e, 0x8e, 0xc9, 0x77, 0x9b, 0x29, 0xe4,
+ 0xc0, 0x51, 0xe4, 0xc0, 0x61, 0xe4, 0x40, 0x0b, 0x39, 0x30, 0x81, 0x1c,
+ 0x38, 0x80, 0x1c, 0x18, 0x47, 0x9c, 0x14, 0x39, 0xa1, 0xf2, 0x6d, 0x2c,
+ 0x0a, 0xcc, 0x1d, 0xb5, 0x9b, 0x0e, 0x78, 0x99, 0xc1, 0x5e, 0xb3, 0xe0,
+ 0xeb, 0x50, 0xd7, 0x44, 0x65, 0x1c, 0x31, 0xd7, 0x42, 0x3c, 0x4a, 0x20,
+ 0xdf, 0x8c, 0x01, 0x6b, 0x89, 0x6c, 0x2c, 0x25, 0x10, 0x13, 0x5b, 0xe2,
+ 0x00, 0x13, 0x97, 0x8c, 0x14, 0x9e, 0xdd, 0xab, 0xec, 0x33, 0x94, 0xbe,
+ 0x3b, 0x2c, 0xdd, 0xa3, 0x92, 0x2f, 0x9f, 0xc4, 0x58, 0x1c, 0xeb, 0x75,
+ 0x21, 0x2f, 0x31, 0x2e, 0x30, 0x06, 0x2c, 0x39, 0xbf, 0x6b, 0xd1, 0xd7,
+ 0xba, 0xb5, 0xcc, 0xe9, 0x82, 0x30, 0x96, 0x23, 0x0f, 0xc0, 0x1e, 0x38,
+ 0x36, 0x89, 0xe7, 0xf8, 0xfd, 0x2f, 0xfd, 0x98, 0xf9, 0xb1, 0x4e, 0x81,
+ 0xd1, 0xbe, 0xc4, 0x9c, 0x67, 0x61, 0x3d, 0xb7, 0xdd, 0x4f, 0x9f, 0x47,
+ 0xad, 0x14, 0xdc, 0x27, 0xae, 0x66, 0x3f, 0xe1, 0x24, 0x68, 0x1e, 0x04,
+ 0xbe, 0x47, 0x6d, 0x75, 0xb0, 0x8a, 0xef, 0xed, 0xf3, 0x5d, 0xcc, 0x57,
+ 0x63, 0x51, 0x23, 0x6d, 0xb1, 0x9e, 0x43, 0xac, 0x3c, 0x86, 0xb8, 0x68,
+ 0x3b, 0xfa, 0x5a, 0x03, 0x7c, 0x42, 0x8e, 0x65, 0xdb, 0x09, 0x0f, 0xbd,
+ 0xd6, 0x7a, 0xd6, 0x1a, 0x96, 0x89, 0xb5, 0x31, 0xc9, 0xae, 0x0d, 0xc6,
+ 0xcf, 0x4b, 0xd7, 0x65, 0x5b, 0x5e, 0x6b, 0x95, 0x5c, 0xf3, 0xa4, 0x0d,
+ 0xbb, 0xdc, 0xb7, 0xdf, 0x90, 0x1a, 0x30, 0xdc, 0xbe, 0xfd, 0x9d, 0xac,
+ 0xe9, 0x5f, 0x14, 0x3d, 0x21, 0x99, 0x45, 0x5b, 0xc6, 0xf6, 0x07, 0xb5,
+ 0xe7, 0x2f, 0x3b, 0xa4, 0x1b, 0x63, 0x6b, 0x09, 0xcc, 0x61, 0xdd, 0xaf,
+ 0xfa, 0x27, 0xe0, 0x59, 0xf3, 0x9e, 0x51, 0x39, 0x8f, 0x98, 0x19, 0xbc,
+ 0x37, 0x6d, 0xe7, 0xfc, 0x22, 0x70, 0x0d, 0xe4, 0x99, 0x59, 0x24, 0xee,
+ 0xda, 0x05, 0x39, 0x45, 0x60, 0x23, 0xd4, 0xfd, 0x20, 0x9e, 0x6d, 0xc9,
+ 0x57, 0x53, 0xb4, 0x87, 0xc7, 0x20, 0x4b, 0xac, 0x15, 0x0e, 0xf8, 0xf9,
+ 0x9a, 0xcc, 0x2d, 0x51, 0x7e, 0x71, 0xd4, 0x96, 0xdc, 0x5b, 0xa2, 0x5d,
+ 0xe9, 0xab, 0xeb, 0x46, 0xdb, 0xd9, 0x58, 0xc4, 0xfa, 0x43, 0xc4, 0xd8,
+ 0x88, 0xd5, 0x65, 0xf6, 0x06, 0x58, 0x53, 0x1d, 0x80, 0x4e, 0xa6, 0x15,
+ 0xe6, 0xce, 0xd4, 0x53, 0x62, 0x9d, 0x62, 0xac, 0x92, 0x44, 0xc8, 0x22,
+ 0xbe, 0x17, 0x43, 0x4f, 0xcf, 0xe2, 0x1e, 0xe5, 0xc9, 0x5a, 0x1f, 0xf7,
+ 0x57, 0xff, 0xa3, 0xd2, 0x49, 0x08, 0xba, 0xcb, 0xef, 0x67, 0x11, 0x22,
+ 0x4b, 0xa1, 0x34, 0x62, 0xe0, 0x18, 0x79, 0x50, 0x7b, 0xa3, 0x9e, 0xa4,
+ 0xdf, 0x81, 0x67, 0xd8, 0x46, 0x5b, 0x5d, 0xa9, 0xfe, 0x4a, 0x95, 0x08,
+ 0x6c, 0x59, 0x0a, 0x91, 0x34, 0x78, 0x1a, 0xc3, 0x77, 0x38, 0xff, 0x09,
+ 0xe8, 0xf3, 0x2c, 0x9e, 0x5f, 0x00, 0x5f, 0x1b, 0x65, 0xd2, 0x9d, 0x4c,
+ 0x1c, 0x57, 0xbe, 0x8b, 0x6b, 0x97, 0xb5, 0xcc, 0xd7, 0xe4, 0xbc, 0xe2,
+ 0xef, 0x13, 0xac, 0x9d, 0xa1, 0xa7, 0xeb, 0xe1, 0x6f, 0xf2, 0x3a, 0xf9,
+ 0xf3, 0xd6, 0x67, 0xce, 0xca, 0x58, 0x09, 0xc9, 0x96, 0x5f, 0x6a, 0x85,
+ 0x2d, 0x2b, 0x3e, 0xef, 0xeb, 0x31, 0xeb, 0x46, 0x41, 0x07, 0xfb, 0x00,
+ 0xfb, 0x95, 0x2e, 0x41, 0x07, 0x6d, 0xa7, 0x10, 0x4d, 0x3f, 0x2e, 0x2b,
+ 0x4b, 0xff, 0x54, 0x6a, 0x4b, 0x05, 0xa9, 0x2f, 0xfd, 0x23, 0x39, 0xb7,
+ 0xd4, 0x92, 0x0b, 0x29, 0x15, 0x93, 0xac, 0x0e, 0xe5, 0xcf, 0x72, 0xa3,
+ 0x87, 0x07, 0x93, 0xe3, 0x97, 0x20, 0xc0, 0x95, 0xaa, 0x47, 0xfb, 0x54,
+ 0x1b, 0xed, 0x17, 0x60, 0x6b, 0xaf, 0x58, 0xa4, 0x7f, 0x4c, 0x6a, 0x65,
+ 0xd2, 0xfe, 0xa0, 0xa2, 0xfd, 0xc0, 0x26, 0xed, 0x92, 0x0b, 0x59, 0xa4,
+ 0x7f, 0x27, 0xda, 0x81, 0xf3, 0xfb, 0x49, 0x7f, 0x02, 0xcf, 0x7e, 0xd0,
+ 0xfe, 0x6a, 0xee, 0x6b, 0xad, 0x8d, 0x72, 0x44, 0xd1, 0x1c, 0x4a, 0x8f,
+ 0x41, 0x3e, 0xaf, 0xb5, 0xd6, 0x5d, 0xfa, 0x11, 0xbe, 0xbb, 0xf7, 0x20,
+ 0x46, 0xf5, 0x61, 0xaf, 0x5e, 0xc9, 0xcf, 0x46, 0x11, 0x27, 0xc7, 0xa1,
+ 0xdb, 0x2e, 0xe5, 0x87, 0x08, 0x17, 0xd0, 0xd9, 0x34, 0xe6, 0x1f, 0xa2,
+ 0xbf, 0x29, 0xb9, 0x38, 0x90, 0x4b, 0xb1, 0x9c, 0x8e, 0xa0, 0xfe, 0xc7,
+ 0x3e, 0x86, 0x93, 0x73, 0xf9, 0xcc, 0x00, 0x62, 0x1a, 0xff, 0x7f, 0x64,
+ 0x7b, 0x28, 0x20, 0xd6, 0x42, 0xe7, 0x3d, 0x90, 0x1f, 0xe8, 0x18, 0x9b,
+ 0x41, 0x6e, 0x4d, 0x0e, 0xd7, 0x54, 0x7f, 0x91, 0x71, 0xe5, 0x28, 0xf2,
+ 0xe9, 0x21, 0x7c, 0xbc, 0xfd, 0x26, 0x9a, 0xdc, 0x73, 0x3b, 0x4f, 0x45,
+ 0x77, 0x7d, 0x2f, 0x01, 0x52, 0xa6, 0xc9, 0x7d, 0x0b, 0x12, 0x4a, 0x87,
+ 0xb0, 0x2f, 0xc7, 0x7a, 0x10, 0x63, 0x06, 0xa2, 0xd9, 0xe6, 0xcf, 0x31,
+ 0x4e, 0x5f, 0x66, 0x7c, 0x0f, 0x68, 0x1f, 0xc5, 0x9a, 0x8c, 0xbb, 0x63,
+ 0xe0, 0x99, 0x35, 0x26, 0xe3, 0x26, 0xf2, 0x48, 0xe3, 0x47, 0xcc, 0x2d,
+ 0xf8, 0x3e, 0xe0, 0x7f, 0xe7, 0x7d, 0x89, 0xde, 0x9c, 0x36, 0xab, 0x05,
+ 0x31, 0xb1, 0x27, 0x74, 0x6e, 0xc5, 0xa5, 0xd8, 0x30, 0x5f, 0x20, 0x66,
+ 0xd4, 0x29, 0x83, 0x35, 0xca, 0x89, 0xfd, 0x27, 0xd4, 0x7f, 0xb5, 0xe7,
+ 0x21, 0x8f, 0xa8, 0xec, 0xb5, 0x0e, 0x22, 0xa6, 0x80, 0xfe, 0xca, 0x18,
+ 0x78, 0x63, 0x8f, 0x66, 0x10, 0xf9, 0x2b, 0x04, 0x21, 0xa0, 0x96, 0x5a,
+ 0x0b, 0xc9, 0xbd, 0xe1, 0x11, 0xa3, 0x28, 0x8f, 0x46, 0x58, 0x36, 0x17,
+ 0xd6, 0x98, 0x07, 0xc2, 0xb2, 0xb0, 0x26, 0x72, 0x69, 0x91, 0x71, 0x45,
+ 0xfd, 0x41, 0xe6, 0x86, 0x33, 0x8f, 0x3c, 0x5b, 0x5a, 0x62, 0x8c, 0x61,
+ 0x9c, 0xb8, 0x01, 0xba, 0x48, 0x7e, 0xe3, 0xab, 0xc8, 0x49, 0xa5, 0xf2,
+ 0x20, 0x62, 0xa6, 0xac, 0xeb, 0x90, 0x29, 0x72, 0x19, 0x6b, 0xd4, 0x1d,
+ 0xfa, 0x32, 0x41, 0x4f, 0x26, 0x2a, 0xc5, 0x45, 0xf6, 0x63, 0xa2, 0xa0,
+ 0x85, 0x35, 0x76, 0x48, 0xd5, 0x3f, 0x37, 0xa8, 0xd8, 0xca, 0xff, 0xe1,
+ 0xb6, 0x7d, 0x93, 0x27, 0xf7, 0xe9, 0x8c, 0x63, 0x37, 0x8b, 0x3d, 0x63,
+ 0x77, 0x1d, 0xa8, 0x74, 0x48, 0xb5, 0x8f, 0x76, 0x49, 0xfd, 0xbf, 0xa0,
+ 0x62, 0xed, 0x02, 0x78, 0x2a, 0x2e, 0x12, 0xe3, 0x86, 0x31, 0x2f, 0xe6,
+ 0xcf, 0xa3, 0x5c, 0xff, 0x89, 0xcc, 0xed, 0x7f, 0x17, 0x74, 0x79, 0x71,
+ 0x2d, 0xbf, 0x1f, 0xf1, 0x76, 0x46, 0x97, 0x3b, 0xef, 0x1a, 0xc7, 0xb3,
+ 0xcc, 0x81, 0xef, 0xf8, 0x78, 0x92, 0x63, 0xec, 0x61, 0x81, 0xbe, 0x15,
+ 0x03, 0xff, 0xfb, 0xa4, 0xb0, 0x12, 0x85, 0x1c, 0x90, 0x4b, 0x6b, 0xde,
+ 0x5a, 0xac, 0x77, 0x4f, 0x42, 0x47, 0xfa, 0xa9, 0xa8, 0x44, 0x4e, 0xf5,
+ 0x49, 0xf8, 0xeb, 0xdd, 0xd2, 0xf1, 0xf5, 0x21, 0x09, 0x7d, 0xdd, 0x64,
+ 0x4e, 0x4f, 0x9c, 0x80, 0xbe, 0xe6, 0x65, 0x5c, 0x9e, 0x44, 0xde, 0x62,
+ 0x5e, 0x57, 0x76, 0x6a, 0xf4, 0x4b, 0x08, 0x05, 0xab, 0xfe, 0x8c, 0x2d,
+ 0x8f, 0xee, 0xff, 0x85, 0xea, 0x33, 0x01, 0xc3, 0x8b, 0xfe, 0xfc, 0x94,
+ 0xd8, 0xcd, 0x77, 0x21, 0x6b, 0xc3, 0x79, 0xed, 0xd6, 0xa0, 0xa6, 0x1c,
+ 0x56, 0xfd, 0xc2, 0x47, 0xf7, 0x7b, 0x35, 0x25, 0xf0, 0xb8, 0xe6, 0xa8,
+ 0x9a, 0x12, 0xf1, 0x35, 0xcc, 0x79, 0xfd, 0xa2, 0x63, 0xaf, 0xbc, 0x0c,
+ 0x42, 0x4f, 0xb7, 0x88, 0x7d, 0x08, 0x7e, 0xf1, 0x9c, 0x2c, 0xe9, 0x69,
+ 0x4d, 0xad, 0x19, 0x7a, 0x86, 0x71, 0x8a, 0xf1, 0x8b, 0x36, 0x9e, 0x4c,
+ 0x14, 0x61, 0x7f, 0xa1, 0xe7, 0x19, 0xa3, 0x3c, 0xdb, 0x9e, 0x68, 0x8b,
+ 0x75, 0x0b, 0x95, 0x7b, 0xa0, 0x43, 0xd4, 0xf2, 0x16, 0xe2, 0x9c, 0x81,
+ 0x5c, 0x6e, 0xf1, 0xda, 0xeb, 0xe1, 0xe5, 0x63, 0x31, 0x75, 0x5d, 0xac,
+ 0x7a, 0x18, 0xdc, 0x5b, 0x9f, 0x75, 0x07, 0x62, 0x4c, 0x93, 0x74, 0x70,
+ 0xdf, 0x01, 0x09, 0x3d, 0x17, 0x93, 0xf0, 0x73, 0xb4, 0x3f, 0x33, 0xe1,
+ 0x40, 0x7e, 0x0b, 0x16, 0x31, 0xd0, 0x0a, 0xb0, 0xc5, 0xcd, 0xa2, 0xaf,
+ 0x0c, 0xc0, 0x77, 0xcc, 0x78, 0x55, 0x92, 0x12, 0xaa, 0x45, 0xe5, 0xad,
+ 0x45, 0x33, 0x41, 0x7b, 0x39, 0x6b, 0x61, 0xbc, 0xd9, 0x75, 0x79, 0x5d,
+ 0x51, 0xc1, 0xb1, 0x2f, 0x87, 0x80, 0x19, 0x86, 0x6d, 0xbd, 0x47, 0x5e,
+ 0x87, 0xbe, 0x73, 0x6a, 0xec, 0x66, 0xac, 0x0b, 0x1a, 0x9e, 0x33, 0xc1,
+ 0x03, 0xd7, 0xfd, 0x1e, 0xd6, 0x54, 0xf8, 0xca, 0xd9, 0x60, 0x4d, 0xba,
+ 0x48, 0xdb, 0xed, 0x83, 0xdd, 0xe1, 0xba, 0xd9, 0x21, 0xb9, 0xd9, 0x84,
+ 0xe8, 0x8b, 0x9f, 0x91, 0xc1, 0xfd, 0xba, 0xc7, 0x8f, 0xe2, 0x91, 0x63,
+ 0xec, 0xc7, 0xdd, 0xae, 0xfc, 0x51, 0x5f, 0x83, 0xcd, 0x3c, 0x48, 0x1d,
+ 0x23, 0xf7, 0x23, 0x8f, 0x31, 0x8e, 0x85, 0x90, 0xc7, 0xb2, 0x4d, 0x4f,
+ 0xef, 0xd5, 0x07, 0xfb, 0xe5, 0xc9, 0xe7, 0x68, 0x4f, 0xb8, 0xb7, 0x69,
+ 0x53, 0x41, 0x0f, 0x98, 0xf7, 0x2c, 0x39, 0xf9, 0x6c, 0x50, 0x73, 0xb0,
+ 0xbe, 0x32, 0xe3, 0x07, 0xc0, 0x8f, 0x7e, 0x27, 0xe3, 0x81, 0xae, 0x6c,
+ 0x37, 0x6f, 0x59, 0x5e, 0xdd, 0x51, 0x49, 0xb0, 0x2f, 0x6e, 0xb0, 0x4e,
+ 0xb3, 0xe3, 0x9e, 0xbc, 0x8b, 0x18, 0x2b, 0x35, 0x67, 0x11, 0xa3, 0x23,
+ 0x72, 0x71, 0xd6, 0x86, 0xee, 0x3f, 0x0b, 0xba, 0x0e, 0x75, 0x11, 0x23,
+ 0x5f, 0x9c, 0x75, 0x70, 0x7d, 0x48, 0xd5, 0x66, 0xa1, 0x3b, 0x61, 0xc7,
+ 0xcd, 0x7e, 0xfa, 0x91, 0xaf, 0xa7, 0x84, 0x56, 0x5c, 0x32, 0xb5, 0x12,
+ 0x62, 0xf6, 0x64, 0x8a, 0x39, 0xbe, 0x53, 0xf5, 0x4d, 0xd9, 0xaf, 0xc9,
+ 0x2b, 0xbc, 0xb0, 0x4f, 0x2b, 0x56, 0x19, 0xe7, 0x0b, 0xf1, 0x0e, 0x21,
+ 0x0e, 0x11, 0xad, 0x66, 0x51, 0x27, 0x9a, 0x9c, 0x57, 0xbd, 0x58, 0x11,
+ 0xc7, 0x3d, 0x42, 0x19, 0x68, 0xf5, 0xea, 0x3e, 0xad, 0x50, 0x0d, 0xc9,
+ 0xc5, 0x18, 0xe9, 0x4e, 0xa8, 0xfa, 0x7d, 0xbf, 0xb2, 0xb5, 0x1e, 0xe4,
+ 0x12, 0xd8, 0x4c, 0xea, 0x93, 0xd8, 0x57, 0x8d, 0xc1, 0xa6, 0xa8, 0x7b,
+ 0xea, 0x5d, 0xc5, 0x48, 0x5f, 0xf7, 0x3b, 0xe5, 0x4c, 0xd0, 0x51, 0x26,
+ 0x7e, 0xef, 0xf4, 0xf1, 0xfb, 0xa2, 0x5f, 0x0f, 0x3d, 0x26, 0xac, 0x53,
+ 0x16, 0x2a, 0xa4, 0x05, 0xf1, 0xd6, 0xdd, 0xc9, 0x96, 0x28, 0x47, 0x2f,
+ 0xa6, 0x1c, 0x45, 0x1d, 0xa3, 0xaf, 0x19, 0xbe, 0x0d, 0xf0, 0x6f, 0x14,
+ 0xf7, 0xbc, 0x5a, 0xaa, 0xd8, 0x8c, 0xc0, 0xdf, 0xa7, 0x21, 0x23, 0xea,
+ 0x06, 0xfa, 0x5b, 0xe3, 0x99, 0x0a, 0xf4, 0xb7, 0xf6, 0xf2, 0xfb, 0x76,
+ 0x1f, 0x63, 0xde, 0xb0, 0x3c, 0x89, 0xf1, 0x13, 0x67, 0x48, 0xcf, 0xb8,
+ 0x8f, 0xc7, 0x12, 0x90, 0x09, 0x63, 0xfc, 0xa8, 0xbc, 0xd5, 0x70, 0x14,
+ 0xfe, 0xdb, 0xb7, 0x7f, 0x46, 0xe6, 0xdd, 0x59, 0xe0, 0x3f, 0xc8, 0xdf,
+ 0x48, 0xc0, 0x3f, 0xe3, 0x2a, 0x3e, 0x1e, 0xfe, 0x68, 0x35, 0x49, 0xd8,
+ 0xcb, 0xd9, 0xf7, 0x5e, 0x67, 0xce, 0xde, 0x0d, 0xfc, 0xf5, 0x91, 0xd6,
+ 0x0f, 0x79, 0xeb, 0xff, 0x17, 0xe8, 0xea, 0x73, 0xd8, 0x23, 0x0a, 0xfa,
+ 0xfa, 0x29, 0xd3, 0x0f, 0x7b, 0x4e, 0xf7, 0x9e, 0xbb, 0xff, 0x3a, 0xe9,
+ 0x32, 0xa4, 0x01, 0x8c, 0x50, 0x50, 0x79, 0x94, 0xb5, 0x62, 0xc4, 0xd7,
+ 0xdf, 0x31, 0x60, 0x67, 0xae, 0x1b, 0xc4, 0xde, 0x4e, 0x29, 0xf4, 0x05,
+ 0xf5, 0x27, 0x62, 0xf6, 0xe6, 0x78, 0x50, 0xcf, 0xf2, 0xf9, 0x94, 0x93,
+ 0x2f, 0xb3, 0x4f, 0xc8, 0x5c, 0xc0, 0x31, 0x65, 0x87, 0x1f, 0x42, 0xb7,
+ 0x09, 0xcf, 0x20, 0xdd, 0xf7, 0x29, 0xba, 0x1d, 0x45, 0x37, 0xfd, 0x8b,
+ 0x67, 0x3a, 0xec, 0xa3, 0x05, 0x7d, 0x33, 0xae, 0x07, 0x4c, 0x00, 0x7d,
+ 0x7f, 0x17, 0x3a, 0xfe, 0x4e, 0x05, 0x98, 0xa0, 0x02, 0x4c, 0x80, 0x3d,
+ 0xbe, 0x0d, 0x1d, 0x7f, 0xab, 0x02, 0x4c, 0x50, 0x89, 0xfb, 0x3d, 0x0a,
+ 0x9b, 0x98, 0xfe, 0x23, 0xda, 0x6e, 0xd0, 0x93, 0xb9, 0xda, 0x2e, 0x39,
+ 0xce, 0xf9, 0x01, 0x36, 0x8e, 0xc2, 0x8e, 0x78, 0x6e, 0x11, 0xf4, 0x3b,
+ 0xfc, 0x1c, 0xd1, 0xe0, 0xb9, 0x00, 0x72, 0x44, 0x83, 0xe7, 0x18, 0x23,
+ 0xf1, 0x10, 0x30, 0x61, 0x48, 0xe2, 0xc2, 0x5e, 0xef, 0xdc, 0x18, 0xd6,
+ 0x1a, 0x1d, 0x84, 0x27, 0x75, 0xa8, 0xbe, 0xd6, 0x71, 0xd5, 0x6f, 0x40,
+ 0x5c, 0xa8, 0x06, 0xb5, 0x5b, 0x52, 0x26, 0x96, 0x88, 0x33, 0x65, 0xaf,
+ 0x9e, 0x86, 0x0e, 0x5c, 0x62, 0xc3, 0xcd, 0xbe, 0xf4, 0x70, 0x1d, 0x7b,
+ 0x16, 0x2d, 0x8f, 0xbe, 0xe3, 0xee, 0xd6, 0x33, 0x07, 0x10, 0x9f, 0xa7,
+ 0xca, 0x09, 0x99, 0x2c, 0x7b, 0x98, 0x00, 0xf5, 0xcf, 0x55, 0xfd, 0x51,
+ 0x9b, 0x7a, 0x80, 0xfe, 0x36, 0x6d, 0x23, 0x71, 0x3e, 0x45, 0x19, 0x53,
+ 0xff, 0xd3, 0xaa, 0x67, 0x7d, 0xa0, 0xee, 0xf5, 0xe5, 0x27, 0x95, 0x2d,
+ 0x84, 0x19, 0x67, 0xa8, 0x3f, 0xcf, 0x87, 0x61, 0x17, 0x79, 0x37, 0x90,
+ 0x4b, 0x3b, 0x1e, 0xf9, 0xbc, 0x26, 0xd6, 0x4e, 0xe3, 0xb9, 0xb6, 0xf1,
+ 0xcd, 0xfb, 0x3e, 0xbd, 0x88, 0x7d, 0x9b, 0x3d, 0x06, 0xc6, 0xa9, 0xad,
+ 0xf1, 0x10, 0xea, 0x87, 0xb0, 0xba, 0x8f, 0x18, 0xde, 0x88, 0x49, 0xb6,
+ 0x61, 0x89, 0x53, 0xe5, 0x3c, 0xf6, 0x2d, 0x18, 0x8f, 0x9e, 0x90, 0xec,
+ 0x52, 0xaf, 0xe4, 0x62, 0x66, 0xca, 0x96, 0xbf, 0x27, 0x1b, 0xcb, 0x85,
+ 0x04, 0xcf, 0x0d, 0x0b, 0x33, 0x1a, 0x9e, 0x7b, 0x18, 0xd7, 0xa4, 0xd9,
+ 0x92, 0xc3, 0x65, 0xe6, 0x9d, 0x91, 0x78, 0x03, 0xf7, 0x72, 0xb3, 0xec,
+ 0xd5, 0x54, 0x61, 0x93, 0x66, 0xa2, 0x8a, 0x78, 0xf0, 0x72, 0x99, 0xfb,
+ 0x01, 0x1b, 0x95, 0xd9, 0xcf, 0x09, 0xee, 0x3f, 0x01, 0x1c, 0x88, 0x58,
+ 0x1d, 0xf3, 0xe7, 0x28, 0x5e, 0x6d, 0x23, 0x2c, 0x81, 0xae, 0x3b, 0x65,
+ 0xdd, 0x8f, 0xbb, 0xb5, 0xb2, 0xd7, 0x47, 0x39, 0x4b, 0x7a, 0xdc, 0xff,
+ 0xd5, 0x5a, 0x8f, 0xa1, 0x16, 0xda, 0xe4, 0xf5, 0x8f, 0xb9, 0x8f, 0x81,
+ 0xb0, 0x2b, 0x27, 0xdc, 0x40, 0x26, 0xbc, 0xcf, 0x31, 0x9e, 0x8d, 0xb6,
+ 0x5a, 0x67, 0xad, 0xf6, 0x9e, 0xdf, 0xf5, 0xf4, 0xcc, 0xde, 0xb8, 0x2d,
+ 0x63, 0xbd, 0xe6, 0xa0, 0x26, 0xf6, 0x7b, 0x66, 0x87, 0x46, 0xbc, 0x9e,
+ 0xd9, 0xfc, 0xc8, 0xf6, 0x9e, 0xd9, 0xcf, 0x6f, 0xf3, 0x7a, 0x66, 0x17,
+ 0x9d, 0x22, 0x3e, 0x5e, 0xcf, 0x6c, 0xf8, 0x76, 0xaf, 0x67, 0xf6, 0xf0,
+ 0xed, 0x5e, 0xcf, 0xec, 0x91, 0x11, 0xaf, 0x67, 0xf6, 0xfb, 0xb7, 0x6f,
+ 0xef, 0x99, 0x3d, 0x36, 0xb2, 0xbd, 0x67, 0x26, 0x13, 0xc8, 0x77, 0x13,
+ 0x5b, 0x3d, 0xb3, 0xf2, 0xc8, 0xb5, 0x7b, 0x66, 0xaf, 0x06, 0x78, 0x1d,
+ 0xfc, 0x8c, 0x81, 0x87, 0x14, 0xf0, 0xfa, 0x28, 0xf0, 0xfa, 0xaf, 0xeb,
+ 0x59, 0x87, 0xc1, 0xe7, 0xcd, 0x7e, 0x5e, 0xb8, 0x1e, 0xdc, 0x7e, 0xbb,
+ 0xff, 0x8c, 0xa0, 0xde, 0x4d, 0xf8, 0xb5, 0x0a, 0xb1, 0xfb, 0x1e, 0xbf,
+ 0x66, 0xfb, 0x6b, 0xd1, 0xad, 0xf3, 0xec, 0xf6, 0xff, 0x37, 0xa0, 0xf4,
+ 0x0e, 0xf0, 0x3c, 0xf9, 0x79, 0x0d, 0xb5, 0x1f, 0xf9, 0x47, 0xa2, 0xef,
+ 0xbe, 0xe8, 0x7c, 0xd5, 0x22, 0xc6, 0x7f, 0x1c, 0xbe, 0x6a, 0xef, 0x0d,
+ 0xc9, 0x3a, 0xfc, 0x96, 0x39, 0xea, 0xa4, 0x64, 0x31, 0x3f, 0xab, 0xe6,
+ 0x27, 0x26, 0xb6, 0xe6, 0xa7, 0x26, 0xbe, 0xaa, 0x6a, 0x52, 0xf3, 0x5f,
+ 0xe3, 0xf3, 0x0d, 0x65, 0xdf, 0x96, 0x87, 0xe1, 0x9d, 0x4a, 0x80, 0xb7,
+ 0xc2, 0x3e, 0x76, 0x36, 0x1c, 0xdb, 0x9d, 0xc0, 0x33, 0xe6, 0x8b, 0xb6,
+ 0x34, 0x14, 0x7e, 0x0f, 0xa5, 0xcd, 0x17, 0x73, 0xaa, 0x5e, 0x33, 0x9c,
+ 0xbc, 0x1b, 0xd4, 0xdf, 0xa8, 0xa1, 0x86, 0x06, 0xd5, 0xf9, 0x9b, 0xbe,
+ 0x36, 0x8c, 0x3c, 0xd6, 0x5e, 0x63, 0xb3, 0xae, 0xd6, 0xfd, 0xba, 0xda,
+ 0x90, 0xbb, 0xf7, 0xb7, 0x63, 0x73, 0x99, 0xf8, 0x5b, 0x0a, 0x9b, 0xef,
+ 0x42, 0x6d, 0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7e,
+ 0x01, 0xeb, 0x19, 0xe6, 0x46, 0xd6, 0x37, 0x31, 0x7c, 0xf8, 0xbe, 0x41,
+ 0x80, 0xd1, 0x3b, 0xfc, 0xf8, 0xce, 0xba, 0x28, 0xc0, 0x2a, 0x77, 0x75,
+ 0x7b, 0xb5, 0xd1, 0x2e, 0xcd, 0xab, 0x3f, 0x13, 0xfe, 0x9c, 0xf0, 0x26,
+ 0x16, 0x0e, 0x6f, 0x62, 0xe1, 0x6d, 0xe7, 0x30, 0xa2, 0xde, 0x6d, 0x50,
+ 0xe7, 0x39, 0x3c, 0xdf, 0x11, 0x4d, 0x4f, 0xf3, 0x8c, 0x07, 0x38, 0xc7,
+ 0xe2, 0x99, 0x0f, 0x7d, 0xe9, 0x41, 0x2d, 0x5b, 0x37, 0x10, 0xef, 0x99,
+ 0x7f, 0x90, 0x6b, 0xcb, 0xc1, 0xd9, 0x62, 0xa0, 0x27, 0xca, 0x8e, 0x63,
+ 0x7f, 0xaa, 0xa1, 0xe6, 0x4d, 0x45, 0xac, 0x43, 0xa0, 0x65, 0x0a, 0xff,
+ 0x03, 0x99, 0xde, 0xa3, 0x72, 0x5f, 0x27, 0x6c, 0xf6, 0x78, 0x85, 0xd8,
+ 0xf5, 0x71, 0x69, 0xf8, 0xf8, 0x75, 0x65, 0xc9, 0xc3, 0xae, 0xe1, 0xed,
+ 0xd8, 0x35, 0xb5, 0x21, 0x1e, 0x8d, 0x07, 0x76, 0xa4, 0xd1, 0x70, 0x5e,
+ 0x19, 0x22, 0x66, 0x25, 0x9d, 0xcc, 0x3d, 0xd3, 0x88, 0x81, 0xcc, 0x39,
+ 0xcc, 0x37, 0xc4, 0xa5, 0xd7, 0xa2, 0x4f, 0x8d, 0x1d, 0xed, 0xb0, 0xa2,
+ 0xf8, 0xcc, 0x83, 0x8e, 0x19, 0x3c, 0x93, 0x96, 0x85, 0xd3, 0x5f, 0xd1,
+ 0x9c, 0xfa, 0x3c, 0xe8, 0x99, 0x42, 0xae, 0xa3, 0x2d, 0x15, 0x0c, 0xcf,
+ 0x8e, 0xd6, 0x11, 0xf7, 0x5d, 0xc6, 0x02, 0xd4, 0xae, 0xa8, 0x47, 0xca,
+ 0x8c, 0xbd, 0x3c, 0xeb, 0x0a, 0x62, 0x2e, 0xfb, 0x26, 0xa8, 0x59, 0x59,
+ 0xbb, 0x2e, 0x72, 0xdf, 0xed, 0xba, 0xa8, 0xb9, 0xc4, 0x5d, 0x86, 0xb3,
+ 0xbe, 0x46, 0xdc, 0xf8, 0x51, 0x31, 0xa4, 0xe1, 0xbc, 0x3c, 0x44, 0x1c,
+ 0x79, 0x3d, 0xf8, 0xd1, 0x84, 0x34, 0xcd, 0x17, 0xd6, 0xf5, 0x76, 0xfc,
+ 0xe8, 0x61, 0xc7, 0xcc, 0xda, 0x41, 0xac, 0xc9, 0xda, 0x8c, 0x38, 0xd1,
+ 0x44, 0x98, 0x1b, 0xc4, 0xb3, 0x83, 0xe0, 0xc7, 0xc3, 0x8a, 0x59, 0x60,
+ 0xc5, 0xbf, 0x03, 0xac, 0x58, 0x92, 0xf7, 0xa2, 0xc4, 0x8a, 0xb6, 0x8f,
+ 0x15, 0x1d, 0xd8, 0x71, 0x7e, 0x9b, 0x1d, 0x6b, 0xaa, 0x07, 0xc5, 0x7b,
+ 0x79, 0x60, 0xbd, 0xec, 0xa2, 0x79, 0x1d, 0xf8, 0x50, 0x93, 0x98, 0x3a,
+ 0xaf, 0x0f, 0xb7, 0xad, 0x19, 0xe0, 0xc0, 0x7d, 0x0a, 0xdf, 0xdd, 0x57,
+ 0xd9, 0x85, 0xda, 0x44, 0xe1, 0x3d, 0xff, 0x9c, 0x2f, 0x7c, 0xd5, 0xd9,
+ 0x67, 0xb8, 0xed, 0xec, 0x73, 0x0b, 0x17, 0xe2, 0x39, 0xbf, 0xc7, 0x17,
+ 0x81, 0xde, 0xfe, 0x07, 0x69, 0x82, 0x5f, 0xd1, 0x07, 0x34, 0xcf, 0x4f,
+ 0xb6, 0xe1, 0xc3, 0xff, 0x7a, 0x15, 0x3e, 0x44, 0xce, 0x5a, 0x89, 0x49,
+ 0x06, 0xd8, 0xd0, 0x5e, 0xe3, 0x5a, 0xf4, 0xe5, 0x51, 0xe9, 0x00, 0x7f,
+ 0x9d, 0x8b, 0x7d, 0xc0, 0x44, 0xdd, 0x12, 0x05, 0x36, 0x8a, 0x28, 0x6c,
+ 0x34, 0x44, 0x0c, 0x33, 0x7c, 0x18, 0x98, 0xa6, 0xb1, 0x89, 0x8f, 0xcc,
+ 0xd4, 0x0f, 0xa0, 0x97, 0x87, 0x95, 0xad, 0x8c, 0xcb, 0x53, 0x88, 0x9d,
+ 0x1d, 0x6b, 0xc0, 0x75, 0x2b, 0x1e, 0x6e, 0x8a, 0x5c, 0x85, 0x9b, 0x8e,
+ 0xec, 0x88, 0x9b, 0x54, 0xbf, 0x7e, 0x9c, 0x32, 0x79, 0xdd, 0xf5, 0xfa,
+ 0xf5, 0x97, 0x5c, 0xaf, 0x5f, 0xff, 0xba, 0xdb, 0xde, 0xaf, 0xbf, 0x49,
+ 0x8a, 0x86, 0x69, 0x5f, 0x94, 0xab, 0xfa, 0xf5, 0x33, 0xec, 0x7f, 0x57,
+ 0xbb, 0xbc, 0xbe, 0x7c, 0xb7, 0xdf, 0xaf, 0x37, 0xa5, 0xb8, 0x6d, 0xdc,
+ 0x90, 0xb7, 0xad, 0xa0, 0x5f, 0xff, 0x2f, 0x30, 0xd6, 0x83, 0x3d, 0xb6,
+ 0xf7, 0xea, 0x2f, 0xb9, 0xec, 0xd5, 0xc7, 0x38, 0xcf, 0xef, 0xd5, 0x73,
+ 0x1e, 0x6a, 0x78, 0x97, 0x7d, 0xfa, 0x9b, 0x21, 0x8b, 0x7e, 0xc8, 0xa1,
+ 0x4f, 0x3a, 0x9e, 0x8b, 0x73, 0x8e, 0xea, 0xcf, 0x5f, 0x74, 0x63, 0x78,
+ 0xce, 0xeb, 0xa3, 0x1f, 0x86, 0x5d, 0x1d, 0xd9, 0xec, 0xcf, 0x7b, 0x7b,
+ 0xbc, 0xe1, 0x6e, 0x5f, 0x7f, 0xfb, 0x3a, 0x03, 0xfe, 0x3a, 0x31, 0xac,
+ 0x13, 0xbf, 0x6a, 0x9d, 0xad, 0x7e, 0xfc, 0x1b, 0xae, 0xd7, 0x8b, 0x77,
+ 0x4e, 0x8b, 0xdd, 0x81, 0x98, 0xfc, 0xe2, 0xd0, 0x8d, 0xfe, 0x1a, 0x9b,
+ 0xbd, 0x78, 0xc6, 0x0e, 0xe0, 0x75, 0xc6, 0x0f, 0x3e, 0xff, 0xff, 0xbe,
+ 0x17, 0xcf, 0x3e, 0xbc, 0x77, 0x9e, 0x42, 0xff, 0x04, 0x2e, 0x7f, 0xd6,
+ 0xeb, 0xc1, 0x4f, 0x54, 0x82, 0xde, 0x3a, 0xeb, 0xc6, 0xe0, 0xbd, 0x8c,
+ 0xc1, 0xc4, 0x71, 0xa1, 0xad, 0x90, 0x3e, 0xae, 0xdb, 0x23, 0x73, 0x0a,
+ 0x17, 0xc1, 0xa6, 0x92, 0xd7, 0xc6, 0xc6, 0xb5, 0xc5, 0x00, 0x1b, 0xc7,
+ 0x14, 0x36, 0xae, 0xad, 0x05, 0xd8, 0x38, 0x73, 0x0d, 0x6c, 0xfc, 0xdf,
+ 0xba, 0xbc, 0xf8, 0x1f, 0x95, 0x82, 0xc2, 0xc6, 0xd7, 0x7a, 0xc7, 0x86,
+ 0xf7, 0xba, 0x89, 0x03, 0xc4, 0x3b, 0x17, 0xef, 0xbb, 0x86, 0xaf, 0x05,
+ 0x78, 0x99, 0xb9, 0xbe, 0x5f, 0x66, 0x9e, 0xdb, 0xc2, 0xcb, 0x1e, 0x26,
+ 0x36, 0x13, 0x47, 0x55, 0x2e, 0x04, 0x3e, 0x68, 0xb2, 0xef, 0x7d, 0x48,
+ 0xd9, 0x6e, 0xa9, 0x32, 0xab, 0x70, 0x59, 0x1e, 0xb5, 0x6d, 0x51, 0xe1,
+ 0x60, 0x62, 0xe0, 0x2e, 0x91, 0xbe, 0x20, 0x17, 0x05, 0x18, 0x33, 0xec,
+ 0xc7, 0x67, 0x9e, 0x29, 0xbc, 0x1d, 0xca, 0x10, 0x03, 0xbb, 0x41, 0x8d,
+ 0x40, 0x39, 0x0f, 0x23, 0x76, 0x19, 0xbe, 0xac, 0x3c, 0x9f, 0xdd, 0xb7,
+ 0xff, 0x87, 0xef, 0xdb, 0x06, 0xe3, 0x5a, 0x80, 0x11, 0x51, 0x03, 0x55,
+ 0xc6, 0xd5, 0xbb, 0x0e, 0x1e, 0x46, 0xf4, 0xf0, 0x61, 0xd6, 0x9d, 0x01,
+ 0x4e, 0x9e, 0x95, 0x09, 0xe0, 0xf3, 0xf5, 0xdf, 0x65, 0xef, 0x29, 0xc0,
+ 0x44, 0x36, 0xfe, 0xb7, 0xf7, 0xa2, 0x78, 0xdd, 0xa1, 0xce, 0xfe, 0xce,
+ 0x0f, 0x45, 0xdb, 0xc6, 0xff, 0x3e, 0xe2, 0x37, 0xea, 0xa1, 0x0a, 0x73,
+ 0x1d, 0xb1, 0xd0, 0x6f, 0x40, 0x07, 0x63, 0xd7, 0xc0, 0x42, 0x57, 0xe7,
+ 0x26, 0xe6, 0xcb, 0xad, 0xbc, 0xe4, 0x6c, 0xe6, 0x25, 0xee, 0xf1, 0xeb,
+ 0x72, 0x27, 0xc7, 0x6c, 0x23, 0x62, 0x4d, 0xe1, 0x33, 0x8f, 0x7c, 0xbd,
+ 0x3d, 0x37, 0xcd, 0x5d, 0x47, 0x6e, 0x9a, 0x50, 0xb9, 0x89, 0xf4, 0xa2,
+ 0x9e, 0x83, 0x4c, 0xbe, 0x0b, 0x59, 0x7e, 0x07, 0xb4, 0xff, 0x11, 0xf8,
+ 0xf9, 0x43, 0x60, 0xac, 0x6f, 0x03, 0x63, 0x7d, 0xab, 0xd2, 0xfe, 0x0e,
+ 0xc3, 0xb8, 0xb0, 0x0e, 0xf4, 0xea, 0x66, 0x0f, 0xc3, 0x1f, 0x86, 0x57,
+ 0x35, 0xca, 0x86, 0x33, 0x57, 0x1e, 0x31, 0xe6, 0xbd, 0xf3, 0xd2, 0x44,
+ 0x4e, 0xd2, 0x88, 0x11, 0xcc, 0x15, 0xea, 0x3a, 0xce, 0x7e, 0x25, 0xb1,
+ 0x42, 0x5d, 0xd5, 0x93, 0x43, 0x52, 0x6d, 0x78, 0xf8, 0x6a, 0xe1, 0x8c,
+ 0xb7, 0xc6, 0x9c, 0x8f, 0xaf, 0xf2, 0x3e, 0xbe, 0xca, 0x35, 0x36, 0x12,
+ 0xac, 0xcf, 0x17, 0x52, 0xdb, 0x31, 0xd5, 0x61, 0x1f, 0x53, 0xcd, 0xff,
+ 0x15, 0x31, 0x15, 0xf7, 0xca, 0xe3, 0x99, 0xc9, 0xa5, 0x84, 0x1c, 0x80,
+ 0x7c, 0x27, 0xca, 0xd4, 0x93, 0x69, 0xc3, 0x6e, 0x3e, 0x44, 0x57, 0x8e,
+ 0xd2, 0x4b, 0x28, 0xe9, 0xe9, 0x69, 0x12, 0x7a, 0x9a, 0xf8, 0xb5, 0xf5,
+ 0x8d, 0x1a, 0x33, 0xde, 0x1c, 0x8b, 0xe2, 0xf3, 0x7f, 0xaa, 0x23, 0xd2,
+ 0x4f, 0x3d, 0x5d, 0x8d, 0xb9, 0xae, 0x07, 0x7b, 0x6d, 0xc7, 0x5d, 0xb6,
+ 0xc2, 0x5d, 0x1d, 0xfe, 0x9c, 0x99, 0x89, 0x49, 0xe8, 0xf0, 0xdf, 0x63,
+ 0xce, 0x9f, 0xc0, 0xb7, 0x7e, 0x88, 0x78, 0xfd, 0xef, 0xa0, 0x8b, 0x7f,
+ 0x8b, 0xda, 0xe0, 0x55, 0xe4, 0x9f, 0x1f, 0x60, 0x6c, 0x0b, 0xc7, 0xa8,
+ 0x33, 0xfa, 0xd1, 0x8c, 0x95, 0x98, 0x28, 0xba, 0x89, 0x09, 0x0f, 0x7f,
+ 0xfc, 0xea, 0x6f, 0x66, 0xac, 0x29, 0xbe, 0xc3, 0x00, 0xf9, 0xfe, 0xf9,
+ 0xdd, 0x73, 0x0a, 0x7b, 0x04, 0x98, 0x23, 0x67, 0x73, 0xff, 0x92, 0x9b,
+ 0x9a, 0xa8, 0xe1, 0xe3, 0x61, 0x9b, 0xef, 0xd9, 0x1e, 0xb6, 0x59, 0xfa,
+ 0xeb, 0xd4, 0xbb, 0x87, 0x6b, 0x1e, 0x4e, 0xd3, 0xaf, 0xeb, 0xc0, 0x1c,
+ 0x35, 0xf8, 0x64, 0xa1, 0x69, 0xab, 0xcf, 0xf1, 0x8a, 0x6d, 0x46, 0x20,
+ 0x1f, 0xf6, 0x58, 0x4f, 0xd1, 0x0b, 0x5d, 0xd3, 0x28, 0x13, 0x81, 0xba,
+ 0x66, 0xfc, 0x9f, 0xf9, 0xd7, 0x4f, 0xfb, 0xd7, 0x4f, 0xf9, 0xd7, 0x27,
+ 0x91, 0x77, 0x9f, 0x54, 0xb9, 0x93, 0xe3, 0x1c, 0x83, 0x72, 0x5d, 0xac,
+ 0x85, 0xf5, 0xce, 0x8e, 0xfe, 0xb4, 0x55, 0x8d, 0x79, 0xfe, 0x5c, 0x68,
+ 0x3a, 0xf8, 0xfc, 0x63, 0x7c, 0x0e, 0xe2, 0x33, 0x8d, 0xcf, 0x63, 0xf8,
+ 0x6c, 0xca, 0x54, 0xcb, 0x56, 0xa8, 0xa3, 0x61, 0xc9, 0x62, 0xbc, 0x88,
+ 0x3a, 0x34, 0x93, 0x7a, 0x44, 0x8a, 0xf5, 0x92, 0x94, 0x96, 0x34, 0xe9,
+ 0xb6, 0xd2, 0x52, 0xaa, 0x1f, 0x93, 0xe3, 0x4b, 0xde, 0xb9, 0x61, 0x57,
+ 0xda, 0xc6, 0xdc, 0x96, 0x3c, 0x9c, 0x7a, 0x5c, 0xf4, 0x3b, 0x8f, 0x61,
+ 0x9e, 0xe8, 0xc5, 0xd1, 0xdb, 0xd4, 0xf9, 0x58, 0x3d, 0xe5, 0xc9, 0xf8,
+ 0x80, 0x65, 0x9b, 0xc8, 0x5b, 0xc3, 0x4f, 0x62, 0xed, 0x8c, 0x7a, 0x3f,
+ 0x30, 0x2d, 0x27, 0x4e, 0x6f, 0xec, 0xf5, 0x62, 0xa9, 0x69, 0xbc, 0x81,
+ 0x4d, 0xeb, 0xe0, 0xc3, 0x46, 0xec, 0x9b, 0x82, 0x9d, 0x1f, 0x71, 0xc3,
+ 0xda, 0x04, 0x62, 0xe0, 0x84, 0xab, 0x6a, 0x3d, 0xc4, 0x2a, 0xc3, 0x49,
+ 0x9e, 0x8a, 0xe1, 0x9a, 0xef, 0xd0, 0x20, 0x0f, 0x2a, 0x5b, 0xd9, 0x00,
+ 0x8e, 0xd1, 0x54, 0xbf, 0xaf, 0xb4, 0x79, 0x0e, 0xa4, 0xfa, 0xff, 0x4e,
+ 0x32, 0xa9, 0x4b, 0x7e, 0x8c, 0x38, 0xd6, 0x56, 0xb9, 0xa8, 0x51, 0xb6,
+ 0x3f, 0xc1, 0xda, 0xf0, 0x75, 0x61, 0x5e, 0xbb, 0x07, 0xf3, 0x06, 0x10,
+ 0x7f, 0x71, 0xaf, 0x09, 0x5e, 0x4e, 0x93, 0x57, 0x3e, 0x83, 0xda, 0xb6,
+ 0xfa, 0x49, 0xbd, 0xb8, 0xe4, 0xd7, 0x44, 0xaa, 0x76, 0x48, 0x48, 0x7d,
+ 0xf3, 0xcc, 0xc9, 0xeb, 0x93, 0xd4, 0xdd, 0x00, 0x3b, 0xf4, 0x60, 0x0e,
+ 0xeb, 0x08, 0xc8, 0xc8, 0x3b, 0x27, 0x53, 0x67, 0x64, 0x45, 0xf7, 0x93,
+ 0x7a, 0x69, 0x29, 0x83, 0x71, 0xf6, 0xa4, 0xf1, 0xbd, 0xaa, 0x2b, 0xec,
+ 0x7f, 0x31, 0x74, 0x58, 0x1a, 0xd5, 0x16, 0xe8, 0x45, 0x8e, 0xdd, 0x7b,
+ 0x58, 0x6a, 0xd5, 0x79, 0x79, 0xa1, 0xba, 0xb1, 0x0b, 0xd8, 0x09, 0x32,
+ 0x25, 0xfd, 0x3d, 0x3e, 0xfd, 0x54, 0x41, 0x30, 0x0e, 0x79, 0x9e, 0x2e,
+ 0xc4, 0xbd, 0xba, 0x96, 0xb8, 0xed, 0x24, 0xdf, 0x1b, 0x8c, 0xf3, 0x3d,
+ 0xbe, 0x23, 0xcb, 0xb4, 0xc9, 0x8b, 0xf7, 0x2e, 0x58, 0x9f, 0x92, 0x0b,
+ 0xa9, 0x3d, 0xb2, 0x91, 0x52, 0xf5, 0x2f, 0xf1, 0x01, 0x7c, 0xdb, 0x34,
+ 0xd6, 0xe5, 0x6e, 0x39, 0x01, 0x3f, 0xbd, 0x90, 0xca, 0xa9, 0xf3, 0x9b,
+ 0xe3, 0x4d, 0x62, 0xfb, 0x79, 0xd6, 0x54, 0xb2, 0xae, 0x7a, 0x60, 0xad,
+ 0xd6, 0x64, 0x8a, 0xb1, 0xa7, 0x43, 0x36, 0x14, 0xd6, 0xf2, 0x7a, 0xe3,
+ 0x1b, 0xb3, 0x9e, 0x6f, 0x84, 0x94, 0xbd, 0xff, 0x1b, 0xd0, 0x71, 0x0c,
+ 0x36, 0x1b, 0x51, 0x73, 0x42, 0xe9, 0x4e, 0x7f, 0x8e, 0xc2, 0x66, 0x6d,
+ 0x73, 0xc6, 0xc7, 0x33, 0x96, 0xf1, 0xa9, 0x8c, 0x35, 0x36, 0xe1, 0xf5,
+ 0x53, 0x4c, 0xc3, 0xd6, 0x2e, 0xb6, 0x82, 0xf7, 0x4d, 0xa6, 0xe0, 0x4f,
+ 0x2f, 0x6d, 0x62, 0x63, 0x18, 0xe7, 0xf3, 0x0b, 0xd0, 0x6b, 0x58, 0x3a,
+ 0x4e, 0xb5, 0xee, 0x99, 0x4b, 0x8d, 0x24, 0x8e, 0x08, 0xdf, 0x30, 0x62,
+ 0xfd, 0x6c, 0x82, 0xda, 0x05, 0xe4, 0xc3, 0x2b, 0xc4, 0x08, 0xc3, 0xe7,
+ 0xe5, 0xca, 0x3d, 0x99, 0xd4, 0x7e, 0xad, 0x36, 0x8b, 0xea, 0xe4, 0xf9,
+ 0x29, 0xe6, 0xd3, 0xa3, 0xec, 0x7d, 0x86, 0x4e, 0xbd, 0xad, 0x39, 0x65,
+ 0xf5, 0x8e, 0x39, 0xf4, 0xd2, 0xd2, 0xe6, 0x21, 0x37, 0x3c, 0x3f, 0xc3,
+ 0x04, 0xa8, 0x5b, 0x83, 0x09, 0x47, 0x72, 0xec, 0x71, 0x49, 0x7e, 0x59,
+ 0xf6, 0x65, 0x10, 0x47, 0xed, 0x99, 0x0e, 0x99, 0x6f, 0x18, 0xce, 0xe0,
+ 0xe2, 0x51, 0xac, 0x31, 0x87, 0xb5, 0xa6, 0x51, 0x83, 0xcc, 0x22, 0x27,
+ 0x53, 0xae, 0x8c, 0xd5, 0x0f, 0x43, 0x46, 0x37, 0xf1, 0xcc, 0x78, 0x3c,
+ 0x27, 0xe6, 0x4c, 0x41, 0xad, 0xfb, 0x9e, 0x96, 0x1f, 0xfd, 0x18, 0x72,
+ 0x5a, 0x58, 0x0e, 0x24, 0x45, 0x9f, 0x4e, 0x86, 0xdf, 0x9f, 0xb3, 0x38,
+ 0x16, 0xe5, 0x98, 0x8e, 0xb1, 0xf0, 0xe7, 0x92, 0x51, 0x3d, 0x93, 0x34,
+ 0xc7, 0xd9, 0xef, 0x0d, 0x59, 0x73, 0x12, 0x7a, 0xbe, 0xb7, 0x47, 0xba,
+ 0xa7, 0xa5, 0x77, 0xd5, 0x1c, 0x7f, 0x1d, 0xb4, 0x84, 0x55, 0x6c, 0x9f,
+ 0x13, 0xdd, 0x1f, 0xef, 0xd9, 0x1c, 0x0f, 0xfb, 0xe3, 0xd3, 0xd2, 0xbd,
+ 0x3a, 0x62, 0xbc, 0x29, 0x87, 0xb1, 0x66, 0x48, 0x2e, 0xa1, 0xa6, 0xb1,
+ 0x86, 0xe6, 0xe0, 0x73, 0x0f, 0x91, 0x96, 0x83, 0xc0, 0x14, 0xf0, 0x09,
+ 0xd4, 0xd9, 0xd6, 0x27, 0xe5, 0x4b, 0x46, 0x97, 0xe4, 0x55, 0x4d, 0x1b,
+ 0xf6, 0x7a, 0xa5, 0xb0, 0xf3, 0x5b, 0x87, 0xa6, 0x77, 0x7b, 0xfd, 0x00,
+ 0x9e, 0x67, 0x8c, 0x62, 0xec, 0x4a, 0x6b, 0xc5, 0xe2, 0x18, 0xef, 0x5d,
+ 0x69, 0xd5, 0xad, 0x11, 0x23, 0xab, 0x45, 0xfd, 0x73, 0xed, 0x79, 0xc5,
+ 0x7b, 0xa1, 0x3a, 0x68, 0xd4, 0xe4, 0x16, 0x2d, 0x7b, 0x03, 0xf2, 0x83,
+ 0xfb, 0x19, 0xcc, 0xbd, 0xd2, 0xca, 0x58, 0xf3, 0xaa, 0x7f, 0x5f, 0x93,
+ 0xe0, 0x9a, 0xeb, 0x8c, 0x18, 0x93, 0xea, 0xd9, 0x11, 0xe3, 0x84, 0xd6,
+ 0xfe, 0xac, 0xa1, 0x4d, 0x6e, 0x7b, 0xb6, 0x5b, 0xc9, 0x28, 0x64, 0x79,
+ 0x73, 0x4a, 0xd5, 0x69, 0x79, 0xda, 0xe5, 0xbc, 0x2b, 0xad, 0xac, 0x15,
+ 0xd1, 0x4e, 0xdc, 0xc0, 0x18, 0xc8, 0xb9, 0x97, 0xaf, 0xda, 0x87, 0xd7,
+ 0xd7, 0xda, 0xe3, 0x5d, 0xd9, 0xbe, 0xc7, 0x2e, 0x35, 0xe7, 0x82, 0x9a,
+ 0x13, 0x56, 0xb2, 0xde, 0xbe, 0xcf, 0xcf, 0x64, 0xfb, 0x3e, 0xdd, 0x9b,
+ 0x3c, 0x97, 0xb0, 0xe6, 0x93, 0x98, 0x5b, 0x76, 0x07, 0xe3, 0x75, 0xb9,
+ 0xdc, 0xca, 0x5b, 0x17, 0xe5, 0xc2, 0xe6, 0xda, 0xbf, 0xc2, 0x75, 0x3b,
+ 0x4d, 0xbf, 0xf2, 0x69, 0xe4, 0x77, 0x8e, 0x3d, 0xaa, 0xe4, 0xbd, 0xdb,
+ 0x1a, 0x3c, 0x58, 0xd3, 0xcc, 0xf1, 0x9f, 0x09, 0x75, 0x75, 0x44, 0xc5,
+ 0x98, 0xdb, 0xa0, 0xa7, 0x7d, 0xcf, 0xc0, 0x67, 0x47, 0x6d, 0x35, 0xe7,
+ 0x92, 0x35, 0x2d, 0xfb, 0x4e, 0x0d, 0x1a, 0x97, 0x10, 0xdb, 0x9c, 0x18,
+ 0xaf, 0x51, 0x2b, 0x59, 0x7c, 0x27, 0xfe, 0x4e, 0xd6, 0x01, 0xd0, 0xe5,
+ 0xe0, 0xf0, 0xcf, 0xe4, 0xa8, 0x9c, 0xa8, 0x1c, 0x43, 0x2e, 0x9c, 0x93,
+ 0xe1, 0x67, 0x90, 0x37, 0x2a, 0x05, 0x3c, 0x49, 0x9f, 0xf5, 0x72, 0xe0,
+ 0x9c, 0x7a, 0xcf, 0xfc, 0x24, 0xea, 0x64, 0xd8, 0x6e, 0x79, 0x70, 0x78,
+ 0x05, 0xcf, 0xbc, 0xa0, 0x70, 0xa8, 0x2b, 0x0d, 0xf8, 0x40, 0xe2, 0xf9,
+ 0x3d, 0xb2, 0xfb, 0x01, 0xda, 0x22, 0x32, 0xfd, 0x6d, 0x11, 0xf5, 0xee,
+ 0xbd, 0x6e, 0x75, 0x8a, 0xec, 0xa5, 0xdd, 0x34, 0x61, 0x63, 0x73, 0xde,
+ 0x99, 0xd6, 0xb6, 0x6b, 0x73, 0xe6, 0xa2, 0xac, 0x2a, 0xfb, 0xbb, 0x7d,
+ 0xd5, 0xfb, 0x3f, 0xba, 0x8a, 0x72, 0x38, 0x39, 0x2d, 0x77, 0xac, 0x7a,
+ 0xf6, 0x56, 0x5a, 0x3a, 0xaa, 0xe4, 0x3a, 0xa7, 0xe4, 0xda, 0x92, 0xc3,
+ 0x29, 0xca, 0x9c, 0xbc, 0xf0, 0xbd, 0x40, 0x4f, 0x16, 0xf7, 0xfb, 0xf6,
+ 0x33, 0xf8, 0x0c, 0x7f, 0x57, 0x42, 0xd9, 0xb0, 0xee, 0xbe, 0x7f, 0x37,
+ 0xcf, 0x59, 0xf7, 0xad, 0x92, 0xcf, 0x1b, 0xb7, 0xf1, 0xf9, 0x14, 0x62,
+ 0xea, 0xd0, 0x90, 0xc7, 0xeb, 0xab, 0x4b, 0x1f, 0xce, 0xeb, 0x37, 0x37,
+ 0x79, 0x0d, 0x49, 0x43, 0xd5, 0xaf, 0x5d, 0xbd, 0xd2, 0x8d, 0xa8, 0x07,
+ 0x7b, 0xf8, 0x09, 0xf6, 0x9a, 0x12, 0xd2, 0xe0, 0xed, 0xb7, 0xe1, 0x92,
+ 0x96, 0x80, 0x76, 0xd2, 0x73, 0x9f, 0xaf, 0x2f, 0xee, 0x7f, 0x74, 0xc7,
+ 0x7b, 0x97, 0xc4, 0x70, 0x86, 0x31, 0xa6, 0x2b, 0x9d, 0x65, 0x7d, 0xff,
+ 0x9a, 0x16, 0x5d, 0xe9, 0xcc, 0xde, 0xd4, 0xd9, 0xeb, 0xd0, 0x59, 0x5d,
+ 0x7e, 0x13, 0xbc, 0xc0, 0x9f, 0x9f, 0x19, 0x31, 0x0e, 0x13, 0x5b, 0x18,
+ 0x5c, 0x0f, 0x31, 0xd4, 0xd7, 0x5d, 0xc7, 0x47, 0xd0, 0xdd, 0x9b, 0xa2,
+ 0xf4, 0x07, 0x7e, 0x90, 0x7f, 0xd4, 0xf3, 0x8c, 0x61, 0xe4, 0xa9, 0x43,
+ 0xf9, 0x3e, 0x69, 0x53, 0x67, 0xfc, 0x33, 0x9e, 0x3e, 0x95, 0x6f, 0xfb,
+ 0xfa, 0xcc, 0xcd, 0x50, 0x67, 0xe6, 0x6e, 0x4f, 0x7f, 0x9d, 0x6a, 0xce,
+ 0x62, 0x32, 0xa1, 0xfc, 0xda, 0x1a, 0xba, 0x65, 0x37, 0x75, 0xf8, 0xb4,
+ 0xeb, 0xfd, 0x2f, 0xbb, 0xd3, 0xb2, 0xe8, 0x7e, 0x98, 0x1e, 0x3d, 0x1d,
+ 0x4e, 0x88, 0xe7, 0x3f, 0x57, 0xeb, 0x4f, 0x5f, 0x0d, 0x2b, 0x5b, 0x9d,
+ 0x80, 0xec, 0x4e, 0x56, 0x3e, 0xe6, 0xdb, 0xb7, 0xc7, 0xeb, 0xd0, 0x87,
+ 0xf0, 0x7a, 0xb8, 0x3c, 0x68, 0xbc, 0x8d, 0xb5, 0x26, 0x15, 0x86, 0x8b,
+ 0x88, 0xe3, 0xf3, 0x9a, 0xd8, 0xe4, 0x35, 0xa0, 0xcd, 0x9b, 0x97, 0x65,
+ 0x5d, 0xea, 0x32, 0x3e, 0x3d, 0xaa, 0xde, 0xbf, 0x7f, 0xa3, 0xcc, 0xb8,
+ 0x0c, 0xcc, 0x13, 0xeb, 0x93, 0x4b, 0x8d, 0x84, 0x5c, 0x22, 0x96, 0x18,
+ 0xc3, 0x7f, 0xf7, 0x98, 0x9f, 0x9b, 0xa3, 0xf2, 0x66, 0xb9, 0xbd, 0x56,
+ 0x1c, 0x95, 0xd7, 0xcb, 0x41, 0xbd, 0x48, 0x2c, 0xcb, 0xfc, 0x3f, 0x27,
+ 0x6f, 0x2d, 0x0d, 0xca, 0xfa, 0x0c, 0xf2, 0xf8, 0x10, 0x65, 0x30, 0x62,
+ 0x7c, 0x46, 0xfd, 0xbe, 0xe2, 0x4a, 0xeb, 0xbc, 0x85, 0x75, 0x97, 0x5b,
+ 0x72, 0x84, 0xe7, 0xd0, 0xfc, 0xde, 0xf8, 0x04, 0x56, 0xe1, 0xbc, 0x3e,
+ 0xa9, 0x2d, 0xa3, 0x2e, 0x2f, 0x73, 0x5d, 0xca, 0x69, 0x5a, 0x7d, 0x9f,
+ 0xc4, 0x3e, 0xf7, 0xf3, 0xbd, 0xf4, 0x18, 0x75, 0x71, 0xa5, 0xb5, 0x61,
+ 0xf1, 0x1c, 0x72, 0x4e, 0x1a, 0xd0, 0xd7, 0x97, 0x93, 0x3c, 0x27, 0xcf,
+ 0x0b, 0x7f, 0x9f, 0x52, 0x6b, 0xcc, 0xa0, 0x16, 0xb8, 0xd2, 0x5a, 0xb0,
+ 0x9e, 0x52, 0x7a, 0x6a, 0x54, 0x1f, 0xf0, 0xc7, 0x79, 0xcd, 0x7b, 0x86,
+ 0xb3, 0x6f, 0x88, 0xf5, 0xe7, 0x03, 0xc8, 0xff, 0xac, 0x3d, 0x89, 0xb7,
+ 0x28, 0x8b, 0x04, 0x6a, 0x5c, 0xae, 0xc5, 0xdf, 0x04, 0x25, 0x87, 0xf3,
+ 0x32, 0x09, 0x7a, 0x80, 0xcb, 0x5c, 0xc6, 0xfd, 0x5b, 0x65, 0x23, 0xe6,
+ 0xc5, 0x77, 0xbe, 0xaf, 0xb5, 0x81, 0x98, 0xbf, 0xb1, 0x19, 0xf3, 0xfb,
+ 0x71, 0x6d, 0x38, 0xa9, 0xa1, 0xff, 0x84, 0xf5, 0xd9, 0x77, 0x61, 0xcc,
+ 0x1f, 0xc7, 0x7c, 0x8e, 0xf5, 0x49, 0x69, 0x59, 0x6c, 0xf6, 0x99, 0x6a,
+ 0xc2, 0x77, 0x31, 0x72, 0xb2, 0xd8, 0x18, 0x8c, 0x9f, 0xd7, 0x1c, 0xf5,
+ 0xce, 0x46, 0x72, 0x88, 0x7d, 0xb7, 0x3e, 0x69, 0x2c, 0x4b, 0x22, 0x94,
+ 0x7e, 0x48, 0xdc, 0x86, 0x87, 0xb9, 0x17, 0x34, 0xf6, 0xdf, 0x6c, 0x69,
+ 0x6c, 0x9f, 0x63, 0x84, 0xd2, 0x87, 0xe4, 0x0f, 0xfc, 0x39, 0x8e, 0x9a,
+ 0xf3, 0x1f, 0x76, 0xf3, 0xec, 0xab, 0xe1, 0xf6, 0x82, 0x06, 0xd2, 0x76,
+ 0x63, 0xfb, 0xbe, 0x89, 0xad, 0x7d, 0xb9, 0x27, 0x6a, 0x98, 0xbd, 0x36,
+ 0xf6, 0x7d, 0x15, 0xcf, 0x3c, 0x04, 0x3a, 0xae, 0x84, 0x74, 0xeb, 0x21,
+ 0x29, 0x36, 0xae, 0xde, 0xa3, 0x9d, 0x06, 0x3e, 0xc3, 0xf5, 0xb9, 0xcf,
+ 0x21, 0xd0, 0x77, 0x45, 0xd3, 0xad, 0x43, 0x90, 0xa5, 0xb7, 0x47, 0xe8,
+ 0x39, 0xd3, 0xf8, 0xa1, 0x0c, 0x89, 0xbe, 0xa2, 0x29, 0xf9, 0xeb, 0xb5,
+ 0x51, 0x38, 0xc4, 0x94, 0x74, 0xaf, 0xcd, 0x4a, 0x68, 0x8d, 0x3d, 0x00,
+ 0xda, 0x22, 0xf5, 0xb8, 0x0b, 0x7e, 0x2c, 0x76, 0xd8, 0x22, 0xde, 0x67,
+ 0x1f, 0x77, 0xb5, 0x57, 0x7a, 0x89, 0xf7, 0x59, 0x0f, 0x1c, 0xc4, 0x7f,
+ 0xd6, 0x04, 0x2f, 0xb5, 0x32, 0xa9, 0x77, 0x54, 0xde, 0xcc, 0x37, 0x78,
+ 0xdf, 0x4c, 0x88, 0xf0, 0x1e, 0xe3, 0x43, 0x9f, 0x44, 0xbe, 0x3e, 0x8c,
+ 0x98, 0x90, 0x03, 0x76, 0xc6, 0xba, 0xa7, 0x86, 0x24, 0xec, 0xbd, 0xeb,
+ 0xa0, 0xfa, 0x25, 0x6f, 0x2d, 0x9b, 0xfe, 0xef, 0x53, 0x64, 0xdf, 0xf9,
+ 0x14, 0x7b, 0x9a, 0x03, 0xb0, 0x53, 0xd6, 0x23, 0xa2, 0x6f, 0xa0, 0xde,
+ 0xbc, 0xd4, 0x88, 0xf6, 0xf2, 0x7d, 0xcb, 0xd7, 0x5d, 0x5c, 0x13, 0xbb,
+ 0xc7, 0x14, 0x56, 0xf4, 0xef, 0xf1, 0x3b, 0xea, 0xa0, 0x6d, 0x98, 0x32,
+ 0x01, 0x4c, 0xc9, 0x3a, 0x69, 0xca, 0x7f, 0xe7, 0xcd, 0x70, 0x4e, 0x6c,
+ 0xab, 0x95, 0x86, 0x65, 0x03, 0x38, 0x6b, 0xdd, 0xb5, 0x10, 0x07, 0xdf,
+ 0xd6, 0xea, 0x65, 0xf5, 0xbb, 0x34, 0xed, 0x01, 0x60, 0xac, 0x44, 0x9f,
+ 0xaa, 0x75, 0x4e, 0x3e, 0x20, 0x9e, 0xbd, 0xc3, 0xca, 0x54, 0xcc, 0x5a,
+ 0xaf, 0x7a, 0xb5, 0xc5, 0x46, 0x75, 0x4a, 0xfe, 0xd4, 0x5d, 0x50, 0xbd,
+ 0xd2, 0x25, 0xd4, 0x1b, 0xe1, 0x45, 0x55, 0x6b, 0xb5, 0xe1, 0x54, 0xc4,
+ 0xb7, 0x67, 0x8f, 0xc0, 0x07, 0x4d, 0xf5, 0x6e, 0x81, 0xbe, 0xd2, 0x6a,
+ 0x65, 0x11, 0x2f, 0x74, 0xcb, 0x32, 0x8a, 0xc8, 0x73, 0x59, 0xf5, 0x7e,
+ 0x0a, 0xfd, 0xf7, 0xf7, 0x54, 0x1c, 0x96, 0x1a, 0x64, 0xf3, 0x5c, 0x02,
+ 0xeb, 0x68, 0xca, 0x3e, 0x43, 0x4a, 0x0f, 0x0f, 0x28, 0xec, 0x1a, 0x5a,
+ 0x41, 0x80, 0x5a, 0x1b, 0x12, 0x59, 0x81, 0xbf, 0xc2, 0x77, 0xc3, 0x6b,
+ 0xd4, 0x01, 0x65, 0x3b, 0x2b, 0x11, 0xc8, 0x9e, 0x58, 0x22, 0xb4, 0x48,
+ 0x19, 0xc7, 0x61, 0x17, 0x5c, 0x07, 0x32, 0xe6, 0xbb, 0x2c, 0xcb, 0x1d,
+ 0xf2, 0x4c, 0xc3, 0xf4, 0xdf, 0x3d, 0x7f, 0x89, 0xef, 0xa3, 0xeb, 0x73,
+ 0x63, 0x03, 0xc4, 0x4f, 0x52, 0x6a, 0x00, 0x63, 0x9c, 0x66, 0x0d, 0xce,
+ 0x18, 0x50, 0x88, 0x47, 0x94, 0xaf, 0xb3, 0x06, 0xf6, 0x7c, 0x9f, 0xf8,
+ 0x3a, 0x62, 0x11, 0xdb, 0x8e, 0x62, 0x8f, 0x9d, 0xe4, 0xea, 0xd5, 0x9e,
+ 0x93, 0xa0, 0xf3, 0xfc, 0x92, 0x39, 0x55, 0x90, 0x14, 0xdf, 0x71, 0x9e,
+ 0xb1, 0xc1, 0xf7, 0x06, 0xe2, 0xe4, 0x42, 0x85, 0xef, 0x33, 0x17, 0xe1,
+ 0x59, 0x53, 0x72, 0xbe, 0xcc, 0x1a, 0xf0, 0x76, 0xe8, 0x8b, 0xd7, 0xc5,
+ 0xf1, 0x10, 0xfc, 0xff, 0xa2, 0xc1, 0xdf, 0x91, 0xf1, 0x77, 0x41, 0x66,
+ 0x2a, 0xa1, 0x1d, 0x84, 0x8e, 0x0b, 0x46, 0xc4, 0xb7, 0x03, 0xa7, 0x4c,
+ 0x8c, 0x35, 0x62, 0x9c, 0xc3, 0xf7, 0x97, 0xdd, 0xcb, 0x2d, 0xd6, 0x3f,
+ 0x17, 0x10, 0xe7, 0xa6, 0x92, 0x53, 0xb0, 0x9d, 0x42, 0xbc, 0x13, 0xb4,
+ 0xfe, 0x5d, 0xdc, 0xcb, 0xbb, 0xdc, 0xc7, 0x4c, 0x5d, 0x94, 0x22, 0x30,
+ 0xfd, 0x48, 0xe2, 0x65, 0xd9, 0x83, 0x3a, 0x55, 0x93, 0x37, 0x2d, 0x73,
+ 0x5c, 0x34, 0xb5, 0xde, 0xf0, 0x7d, 0xb0, 0xbd, 0x37, 0x10, 0xdf, 0x3a,
+ 0xfc, 0xda, 0x3d, 0x5b, 0x26, 0x16, 0x3a, 0xaa, 0xde, 0x05, 0xb8, 0x60,
+ 0xb1, 0x7f, 0xc7, 0xdf, 0x44, 0xfe, 0xa5, 0xda, 0x63, 0xeb, 0x8c, 0x8d,
+ 0xfd, 0x63, 0xd2, 0xe7, 0xf1, 0x78, 0xc0, 0xf2, 0x68, 0xe4, 0x3a, 0x91,
+ 0xb6, 0x75, 0xce, 0xfb, 0xeb, 0x9c, 0xf5, 0xd7, 0xa9, 0xf9, 0xeb, 0x5c,
+ 0xd8, 0x5c, 0xe7, 0x6e, 0xe8, 0xbf, 0xd5, 0x7a, 0x0a, 0xf8, 0x21, 0x93,
+ 0x6a, 0xb5, 0x1c, 0xd4, 0x59, 0xa5, 0xd1, 0x79, 0x75, 0x46, 0xaa, 0xa7,
+ 0xbf, 0x71, 0x6f, 0xc6, 0x2a, 0xc4, 0xc3, 0x0a, 0x7b, 0xa0, 0x92, 0x82,
+ 0x1d, 0x16, 0xc4, 0xc3, 0xdc, 0x3c, 0xb7, 0xf3, 0xce, 0xf5, 0xba, 0xa1,
+ 0xc3, 0x1c, 0x72, 0x86, 0x91, 0x39, 0x67, 0x49, 0x61, 0xdf, 0x6f, 0xea,
+ 0xb0, 0xf3, 0x5e, 0xe4, 0x87, 0x9f, 0xc0, 0x66, 0x8c, 0x4c, 0xbd, 0x91,
+ 0x43, 0xbd, 0xc3, 0xf9, 0x77, 0x40, 0x8f, 0x85, 0x4c, 0xad, 0x51, 0xc8,
+ 0x9c, 0xe5, 0x79, 0x0e, 0xe6, 0xd5, 0x1a, 0x3d, 0x90, 0x7b, 0x8f, 0xea,
+ 0x8b, 0xbc, 0x5c, 0x8e, 0x31, 0x06, 0xc1, 0xd6, 0x63, 0x18, 0x8b, 0xab,
+ 0xdf, 0x68, 0xd5, 0xdd, 0x65, 0xf8, 0x74, 0x02, 0xe3, 0xd5, 0xae, 0x49,
+ 0x85, 0x47, 0x2d, 0x59, 0x71, 0x7f, 0xa5, 0x15, 0xcb, 0x97, 0xb5, 0x52,
+ 0x79, 0x18, 0x73, 0x46, 0xf9, 0x5b, 0x9f, 0x3d, 0xc0, 0x49, 0x53, 0xd5,
+ 0x1d, 0x69, 0x4a, 0x80, 0x26, 0xbd, 0x8d, 0xa6, 0x04, 0xe8, 0x41, 0xcc,
+ 0x3c, 0xc5, 0xde, 0xf1, 0xa8, 0x9c, 0x28, 0xf3, 0x9d, 0x26, 0xfe, 0x46,
+ 0xd5, 0x90, 0x30, 0xb0, 0x65, 0xe4, 0x94, 0x19, 0x5f, 0x57, 0xbd, 0x1a,
+ 0x73, 0xb8, 0x2e, 0x23, 0xa9, 0xba, 0xa8, 0xfc, 0x92, 0x38, 0x81, 0x7c,
+ 0xf5, 0x86, 0xdb, 0x23, 0x6f, 0xfa, 0x7b, 0x5d, 0x14, 0x9e, 0x33, 0x6e,
+ 0xdf, 0xeb, 0xc9, 0x4a, 0x2a, 0xf3, 0x8a, 0x15, 0xf2, 0xf9, 0xea, 0xc3,
+ 0x5e, 0x7b, 0x30, 0x37, 0x95, 0x39, 0xdf, 0xd8, 0x69, 0xae, 0x83, 0xb9,
+ 0x91, 0xb6, 0xb9, 0x0e, 0xe6, 0xf5, 0x20, 0xef, 0xf5, 0x28, 0x9e, 0x4a,
+ 0xa0, 0xeb, 0x52, 0x99, 0x3c, 0xf1, 0x0c, 0x82, 0x7b, 0x1a, 0xc4, 0xc6,
+ 0x53, 0xe2, 0x9f, 0xd9, 0xf2, 0xf7, 0x7a, 0x57, 0xf5, 0x6b, 0x94, 0x0d,
+ 0x4c, 0x58, 0x3c, 0x9b, 0x99, 0xd1, 0xb2, 0xf5, 0x3c, 0x72, 0xd5, 0x8d,
+ 0xc4, 0x43, 0x29, 0x1b, 0xb9, 0x92, 0xe7, 0x3c, 0x8d, 0x72, 0x81, 0xef,
+ 0x3d, 0xc3, 0x2e, 0xde, 0x21, 0x5e, 0xbe, 0x31, 0xa4, 0xde, 0x43, 0x70,
+ 0xfc, 0x73, 0x20, 0x31, 0x32, 0x63, 0x7c, 0xf7, 0xe0, 0x6e, 0xa9, 0x2f,
+ 0x7f, 0x11, 0x63, 0x19, 0xe4, 0xc5, 0x43, 0x5a, 0xe6, 0xdc, 0x24, 0xae,
+ 0x1f, 0xc2, 0x35, 0xe2, 0xf0, 0x72, 0x0e, 0xf7, 0x1f, 0xc2, 0xf5, 0xbc,
+ 0x96, 0x6d, 0xe6, 0x70, 0xfd, 0x30, 0xae, 0x27, 0x48, 0x9b, 0xf3, 0x8a,
+ 0x35, 0xa5, 0xd9, 0x58, 0xcb, 0x3e, 0x37, 0x89, 0x4f, 0xfb, 0x7a, 0xbc,
+ 0x07, 0x3d, 0x95, 0x79, 0x3e, 0x96, 0x04, 0x4d, 0x0f, 0x6a, 0x4e, 0xbd,
+ 0x1b, 0x6b, 0x0c, 0xe1, 0x79, 0xda, 0x54, 0xfb, 0x39, 0xd4, 0x6d, 0xaa,
+ 0x67, 0x14, 0x4a, 0xa7, 0x81, 0x77, 0x1f, 0x41, 0xde, 0xd7, 0xc4, 0xb1,
+ 0x1e, 0x97, 0x62, 0x2a, 0x2d, 0x0b, 0xf5, 0x90, 0x64, 0x63, 0x05, 0x7c,
+ 0x2f, 0x48, 0x66, 0x1c, 0xf7, 0xeb, 0xb4, 0x05, 0xce, 0x2b, 0x49, 0xb1,
+ 0x4a, 0xfc, 0xce, 0x7e, 0xd1, 0x57, 0xc0, 0x37, 0xfb, 0x44, 0x79, 0xc8,
+ 0x20, 0x46, 0xfb, 0xdd, 0xa1, 0xa7, 0xe5, 0xbd, 0xd3, 0x8c, 0x7c, 0xac,
+ 0x65, 0xea, 0xfe, 0x59, 0x9d, 0xc5, 0xdf, 0x2b, 0xb1, 0x47, 0x25, 0xc5,
+ 0x50, 0x9a, 0x7d, 0x0e, 0xd5, 0x17, 0x4f, 0x79, 0x67, 0x7a, 0xed, 0xef,
+ 0x90, 0x04, 0xfe, 0xc2, 0x7d, 0xbf, 0x82, 0xe7, 0xbd, 0xbe, 0x54, 0xb6,
+ 0xf9, 0x41, 0x5d, 0xf0, 0x5d, 0xfd, 0x15, 0xe8, 0xe2, 0xfc, 0x87, 0xf6,
+ 0xb9, 0xd8, 0xe3, 0x9a, 0x47, 0x2c, 0x62, 0x7f, 0x2c, 0x90, 0xdf, 0xd5,
+ 0x34, 0x92, 0xbe, 0xc3, 0x58, 0x4b, 0x52, 0x8c, 0xb3, 0xb9, 0x58, 0x42,
+ 0xd5, 0xbe, 0x1b, 0x4b, 0xf2, 0xc4, 0x16, 0xbd, 0xa4, 0x95, 0x72, 0x78,
+ 0x04, 0xf5, 0x1a, 0x7f, 0xff, 0xf0, 0xb8, 0xe4, 0x53, 0xec, 0xd1, 0x84,
+ 0x90, 0x0b, 0x0b, 0xf8, 0xbe, 0x25, 0xb7, 0x92, 0x2f, 0xb7, 0x7c, 0xf5,
+ 0x5b, 0x4a, 0x77, 0x35, 0x8b, 0xfb, 0x05, 0xbd, 0x8b, 0x69, 0xa5, 0xb3,
+ 0x9a, 0x7a, 0xcf, 0x36, 0xe0, 0x3d, 0xe8, 0xbf, 0xed, 0x6c, 0x73, 0x93,
+ 0x16, 0x69, 0xfb, 0x38, 0xdf, 0x5b, 0x18, 0xb6, 0x85, 0xf4, 0x93, 0x0f,
+ 0xe6, 0xac, 0xe0, 0x5c, 0x34, 0xe0, 0x21, 0xe0, 0xf3, 0xa3, 0xca, 0x85,
+ 0x74, 0xee, 0x31, 0xa4, 0x7b, 0xca, 0x08, 0x59, 0xcc, 0x01, 0x9f, 0xf6,
+ 0xfb, 0xf8, 0xff, 0x37, 0xe5, 0xea, 0xf1, 0x1e, 0x86, 0xa8, 0xfc, 0xdf,
+ 0x8b, 0xee, 0xa0, 0xf7, 0xab, 0xcf, 0x80, 0x0d, 0xe7, 0xac, 0xb5, 0xc5,
+ 0x67, 0x6d, 0x07, 0x3e, 0x6b, 0x3e, 0x9f, 0x1f, 0x7e, 0x4e, 0xea, 0xd1,
+ 0x59, 0x5b, 0xb2, 0xc1, 0x23, 0x6d, 0x6a, 0x27, 0x7b, 0xe3, 0x6f, 0x9c,
+ 0xd4, 0xef, 0xad, 0xa2, 0xb6, 0x7b, 0xad, 0x5e, 0x27, 0xeb, 0x64, 0xcf,
+ 0xee, 0xce, 0x22, 0xd7, 0x55, 0xab, 0x5e, 0xcd, 0x5c, 0x75, 0xd9, 0x6b,
+ 0xde, 0x69, 0x6f, 0x0d, 0x34, 0xff, 0x8e, 0x7a, 0xef, 0xa4, 0xe4, 0x7a,
+ 0x7d, 0xa9, 0x6a, 0xb5, 0x3d, 0x57, 0xde, 0xc0, 0x3c, 0x39, 0x5c, 0x90,
+ 0x19, 0xe8, 0x31, 0x89, 0xeb, 0x9b, 0xe5, 0xe5, 0x65, 0x75, 0x86, 0xe4,
+ 0x9f, 0xd5, 0xf0, 0x0c, 0x46, 0x9d, 0x43, 0x23, 0x5e, 0xcd, 0xaa, 0x78,
+ 0xbd, 0xb1, 0xac, 0xee, 0xa9, 0xdf, 0x3c, 0xd4, 0xdd, 0x19, 0xc4, 0x73,
+ 0xd4, 0x06, 0xd6, 0x6e, 0x29, 0xa2, 0x86, 0x3e, 0x6b, 0xcd, 0x18, 0xc4,
+ 0x29, 0x5c, 0x6b, 0x03, 0x6b, 0x9d, 0x5f, 0x96, 0xbd, 0x7c, 0xa7, 0xa3,
+ 0xaa, 0xce, 0xbd, 0xbc, 0x7e, 0xf5, 0xbc, 0x04, 0xbf, 0xd7, 0x8d, 0xfa,
+ 0x39, 0x8e, 0xef, 0x95, 0xf0, 0xb7, 0xa7, 0x8c, 0x01, 0xa8, 0x6b, 0x66,
+ 0x0a, 0x58, 0xaf, 0xd5, 0xf2, 0xfa, 0xd9, 0x2d, 0xd8, 0x7d, 0x84, 0xbf,
+ 0x65, 0xc0, 0xdf, 0x23, 0xb0, 0x13, 0xf8, 0xc1, 0xe6, 0x38, 0xaf, 0x59,
+ 0x4b, 0x04, 0xd7, 0x4c, 0x58, 0xff, 0x1b, 0xed, 0xcc, 0xfa, 0xa1, 0x98,
+ 0x41, 0x00, 0x00, 0x00 };
+static u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
+ 0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010,
+ 0x00000030, 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000010,
+ 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00008002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+static u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
+ 0x08003be8, 0x08003c14, 0x08003c5c, 0x08003c5c, 0x08003ae8, 0x08003b14,
+ 0x08003b14, 0x08003c5c, 0x08003c5c, 0x08003c5c, 0x08003b7c, 0x00000000,
+ 0x00000000 };
+static u32 bnx2_TXP_b09FwBss[(0xa20/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b09FwSbss[(0x80/4) + 1] = { 0x0 };
+
+static struct fw_info bnx2_txp_fw_09 = {
+ .ver_major = 0x1,
+ .ver_minor = 0x0,
+ .ver_fix = 0x0,
+
+ .start_addr = 0x08000060,
+
+ .text_addr = 0x08000000,
+ .text_len = 0x4194,
+ .text_index = 0x0,
+ .gz_text = bnx2_TXP_b09FwText,
+ .gz_text_len = sizeof(bnx2_TXP_b09FwText),
+
+ .data_addr = 0x080041e0,
+ .data_len = 0xd0,
+ .data_index = 0x0,
+ .data = bnx2_TXP_b09FwData,
+
+ .sbss_addr = 0x080042b0,
+ .sbss_len = 0x80,
+ .sbss_index = 0x0,
+ .sbss = bnx2_TXP_b09FwSbss,
+
+ .bss_addr = 0x08004330,
+ .bss_len = 0xa20,
+ .bss_index = 0x0,
+ .bss = bnx2_TXP_b09FwBss,
+
+ .rodata_addr = 0x08004198,
+ .rodata_len = 0x30,
+ .rodata_index = 0x0,
+ .rodata = bnx2_TXP_b09FwRodata,
+};
+
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 488d8ed9e740..6482aed4bb7c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3684,7 +3684,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
mii->val_out = 0;
read_lock_bh(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (bond->curr_active_slave) {
+ if (netif_carrier_ok(bond->dev)) {
mii->val_out = BMSR_LSTATUS;
}
read_unlock(&bond->curr_slave_lock);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 521c5b71023c..c8126484c2be 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2825,7 +2825,7 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring,
u64 csum_start_off, csum_stuff_off;
csum_start_off = (u64) (skb->h.raw - skb->data);
- csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data);
+ csum_stuff_off = csum_start_off + skb->csum_offset;
ctrl = TX_DESC_CSUM_EN |
CAS_BASE(TX_DESC_CSUM_START, csum_start_off) |
@@ -4066,9 +4066,9 @@ static int cas_alloc_rxds(struct cas *cp)
return 0;
}
-static void cas_reset_task(void *data)
+static void cas_reset_task(struct work_struct *work)
{
- struct cas *cp = (struct cas *) data;
+ struct cas *cp = container_of(work, struct cas, reset_task);
#if 0
int pending = atomic_read(&cp->reset_task_pending);
#else
@@ -5006,7 +5006,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
atomic_set(&cp->reset_task_pending_spare, 0);
atomic_set(&cp->reset_task_pending_mtu, 0);
#endif
- INIT_WORK(&cp->reset_task, cas_reset_task, cp);
+ INIT_WORK(&cp->reset_task, cas_reset_task);
/* Default link parameters */
if (link_mode >= 0 && link_mode <= 6)
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index b265941e1372..74758d2c7af8 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -279,7 +279,7 @@ struct adapter {
struct petp *tp;
struct port_info port[MAX_NPORTS];
- struct work_struct stats_update_task;
+ struct delayed_work stats_update_task;
struct timer_list stats_update_timer;
spinlock_t tpi_lock;
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
index 60901f25014e..cf9143499882 100644
--- a/drivers/net/chelsio/cphy.h
+++ b/drivers/net/chelsio/cphy.h
@@ -91,7 +91,7 @@ struct cphy {
int state; /* Link status state machine */
adapter_t *adapter; /* associated adapter */
- struct work_struct phy_update;
+ struct delayed_work phy_update;
u16 bmsr;
int count;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 53bec6739812..de48eadddbc4 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -953,10 +953,11 @@ static void t1_netpoll(struct net_device *dev)
* Periodic accumulation of MAC statistics. This is used only if the MAC
* does not have any other way to prevent stats counter overflow.
*/
-static void mac_stats_task(void *data)
+static void mac_stats_task(struct work_struct *work)
{
int i;
- struct adapter *adapter = data;
+ struct adapter *adapter =
+ container_of(work, struct adapter, stats_update_task.work);
for_each_port(adapter, i) {
struct port_info *p = &adapter->port[i];
@@ -977,9 +978,10 @@ static void mac_stats_task(void *data)
/*
* Processes elmer0 external interrupts in process context.
*/
-static void ext_intr_task(void *data)
+static void ext_intr_task(struct work_struct *work)
{
- struct adapter *adapter = data;
+ struct adapter *adapter =
+ container_of(work, struct adapter, ext_intr_handler_task);
t1_elmer0_ext_intr_handler(adapter);
@@ -1113,9 +1115,9 @@ static int __devinit init_one(struct pci_dev *pdev,
spin_lock_init(&adapter->mac_lock);
INIT_WORK(&adapter->ext_intr_handler_task,
- ext_intr_task, adapter);
- INIT_WORK(&adapter->stats_update_task, mac_stats_task,
- adapter);
+ ext_intr_task);
+ INIT_DELAYED_WORK(&adapter->stats_update_task,
+ mac_stats_task);
pci_set_drvdata(pdev, netdev);
}
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c
index 0b90014d5b3e..c7731b6f9de3 100644
--- a/drivers/net/chelsio/my3126.c
+++ b/drivers/net/chelsio/my3126.c
@@ -93,9 +93,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
return cphy_cause_link_change;
}
-static void my3216_poll(void *arg)
+static void my3216_poll(struct work_struct *work)
{
- my3126_interrupt_handler(arg);
+ struct cphy *cphy = container_of(work, struct cphy, phy_update.work);
+
+ my3126_interrupt_handler(cphy);
}
static int my3126_set_loopback(struct cphy *cphy, int on)
@@ -171,7 +173,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter,
if (cphy)
cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops);
- INIT_WORK(&cphy->phy_update, my3216_poll, cphy);
+ INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll);
cphy->bmsr = 0;
return (cphy);
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index dec70c2b374a..4612f71a7106 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -1974,7 +1974,7 @@ out:
return ret;
}
-void
+void __exit
cleanup_module(void)
{
unregister_netdev(dev_cs89x0);
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 00e2a8a134d7..4ae0fed7122e 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -40,6 +40,10 @@
*
* v0.009: Module support fixes, multiple interfaces support, various
* bits. macro
+ *
+ * v0.010: Fixes for the PMAD mapping of the LANCE buffer and for the
+ * PMAX requirement to only use halfword accesses to the
+ * buffer. macro
*/
#include <linux/crc32.h>
@@ -54,6 +58,7 @@
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/types.h>
#include <asm/addrspace.h>
#include <asm/system.h>
@@ -67,7 +72,7 @@
#include <asm/dec/tc.h>
static char version[] __devinitdata =
-"declance.c: v0.009 by Linux MIPS DECstation task force\n";
+"declance.c: v0.010 by Linux MIPS DECstation task force\n";
MODULE_AUTHOR("Linux MIPS DECstation task force");
MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver");
@@ -110,24 +115,25 @@ MODULE_LICENSE("GPL");
#define LE_C3_BCON 0x1 /* Byte control */
/* Receive message descriptor 1 */
-#define LE_R1_OWN 0x80 /* Who owns the entry */
-#define LE_R1_ERR 0x40 /* Error: if FRA, OFL, CRC or BUF is set */
-#define LE_R1_FRA 0x20 /* FRA: Frame error */
-#define LE_R1_OFL 0x10 /* OFL: Frame overflow */
-#define LE_R1_CRC 0x08 /* CRC error */
-#define LE_R1_BUF 0x04 /* BUF: Buffer error */
-#define LE_R1_SOP 0x02 /* Start of packet */
-#define LE_R1_EOP 0x01 /* End of packet */
-#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
-
-#define LE_T1_OWN 0x80 /* Lance owns the packet */
-#define LE_T1_ERR 0x40 /* Error summary */
-#define LE_T1_EMORE 0x10 /* Error: more than one retry needed */
-#define LE_T1_EONE 0x08 /* Error: one retry needed */
-#define LE_T1_EDEF 0x04 /* Error: deferred */
-#define LE_T1_SOP 0x02 /* Start of packet */
-#define LE_T1_EOP 0x01 /* End of packet */
-#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
+#define LE_R1_OWN 0x8000 /* Who owns the entry */
+#define LE_R1_ERR 0x4000 /* Error: if FRA, OFL, CRC or BUF is set */
+#define LE_R1_FRA 0x2000 /* FRA: Frame error */
+#define LE_R1_OFL 0x1000 /* OFL: Frame overflow */
+#define LE_R1_CRC 0x0800 /* CRC error */
+#define LE_R1_BUF 0x0400 /* BUF: Buffer error */
+#define LE_R1_SOP 0x0200 /* Start of packet */
+#define LE_R1_EOP 0x0100 /* End of packet */
+#define LE_R1_POK 0x0300 /* Packet is complete: SOP + EOP */
+
+/* Transmit message descriptor 1 */
+#define LE_T1_OWN 0x8000 /* Lance owns the packet */
+#define LE_T1_ERR 0x4000 /* Error summary */
+#define LE_T1_EMORE 0x1000 /* Error: more than one retry needed */
+#define LE_T1_EONE 0x0800 /* Error: one retry needed */
+#define LE_T1_EDEF 0x0400 /* Error: deferred */
+#define LE_T1_SOP 0x0200 /* Start of packet */
+#define LE_T1_EOP 0x0100 /* End of packet */
+#define LE_T1_POK 0x0300 /* Packet is complete: SOP + EOP */
#define LE_T3_BUF 0x8000 /* Buffer error */
#define LE_T3_UFL 0x4000 /* Error underflow */
@@ -156,69 +162,57 @@ MODULE_LICENSE("GPL");
#undef TEST_HITS
#define ZERO 0
-/* The DS2000/3000 have a linear 64 KB buffer.
-
- * The PMAD-AA has 128 kb buffer on-board.
+/*
+ * The DS2100/3100 have a linear 64 kB buffer which supports halfword
+ * accesses only. Each halfword of the buffer is word-aligned in the
+ * CPU address space.
*
- * The IOASIC LANCE devices use a shared memory region. This region as seen
- * from the CPU is (max) 128 KB long and has to be on an 128 KB boundary.
- * The LANCE sees this as a 64 KB long continuous memory region.
+ * The PMAD-AA has a 128 kB buffer on-board.
*
- * The LANCE's DMA address is used as an index in this buffer and DMA takes
- * place in bursts of eight 16-Bit words which are packed into four 32-Bit words
- * by the IOASIC. This leads to a strange padding: 16 bytes of valid data followed
- * by a 16 byte gap :-(.
+ * The IOASIC LANCE devices use a shared memory region. This region
+ * as seen from the CPU is (max) 128 kB long and has to be on an 128 kB
+ * boundary. The LANCE sees this as a 64 kB long continuous memory
+ * region.
+ *
+ * The LANCE's DMA address is used as an index in this buffer and DMA
+ * takes place in bursts of eight 16-bit words which are packed into
+ * four 32-bit words by the IOASIC. This leads to a strange padding:
+ * 16 bytes of valid data followed by a 16 byte gap :-(.
*/
struct lance_rx_desc {
unsigned short rmd0; /* low address of packet */
- short gap0;
- unsigned char rmd1_hadr; /* high address of packet */
- unsigned char rmd1_bits; /* descriptor bits */
- short gap1;
+ unsigned short rmd1; /* high address of packet
+ and descriptor bits */
short length; /* 2s complement (negative!)
of buffer length */
- short gap2;
unsigned short mblength; /* actual number of bytes received */
- short gap3;
};
struct lance_tx_desc {
unsigned short tmd0; /* low address of packet */
- short gap0;
- unsigned char tmd1_hadr; /* high address of packet */
- unsigned char tmd1_bits; /* descriptor bits */
- short gap1;
+ unsigned short tmd1; /* high address of packet
+ and descriptor bits */
short length; /* 2s complement (negative!)
of buffer length */
- short gap2;
unsigned short misc;
- short gap3;
};
/* First part of the LANCE initialization block, described in databook. */
struct lance_init_block {
unsigned short mode; /* pre-set mode (reg. 15) */
- short gap0;
- unsigned char phys_addr[12]; /* physical ethernet address
- only 0, 1, 4, 5, 8, 9 are valid
- 2, 3, 6, 7, 10, 11 are gaps */
- unsigned short filter[8]; /* multicast filter
- only 0, 2, 4, 6 are valid
- 1, 3, 5, 7 are gaps */
+ unsigned short phys_addr[3]; /* physical ethernet address */
+ unsigned short filter[4]; /* multicast filter */
/* Receive and transmit ring base, along with extra bits. */
unsigned short rx_ptr; /* receive descriptor addr */
- short gap1;
unsigned short rx_len; /* receive len and high addr */
- short gap2;
unsigned short tx_ptr; /* transmit descriptor addr */
- short gap3;
unsigned short tx_len; /* transmit len and high addr */
- short gap4;
- short gap5[8];
+
+ short gap[4];
/* The buffer descriptors */
struct lance_rx_desc brx_ring[RX_RING_SIZE];
@@ -226,15 +220,28 @@ struct lance_init_block {
};
#define BUF_OFFSET_CPU sizeof(struct lance_init_block)
-#define BUF_OFFSET_LNC (sizeof(struct lance_init_block)>>1)
+#define BUF_OFFSET_LNC sizeof(struct lance_init_block)
-#define libdesc_offset(rt, elem) \
-((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem])))))
+#define shift_off(off, type) \
+ (type == ASIC_LANCE || type == PMAX_LANCE ? off << 1 : off)
-/*
- * This works *only* for the ring descriptors
- */
-#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
+#define lib_off(rt, type) \
+ shift_off(offsetof(struct lance_init_block, rt), type)
+
+#define lib_ptr(ib, rt, type) \
+ ((volatile u16 *)((u8 *)(ib) + lib_off(rt, type)))
+
+#define rds_off(rt, type) \
+ shift_off(offsetof(struct lance_rx_desc, rt), type)
+
+#define rds_ptr(rd, rt, type) \
+ ((volatile u16 *)((u8 *)(rd) + rds_off(rt, type)))
+
+#define tds_off(rt, type) \
+ shift_off(offsetof(struct lance_tx_desc, rt), type)
+
+#define tds_ptr(td, rt, type) \
+ ((volatile u16 *)((u8 *)(td) + tds_off(rt, type)))
struct lance_private {
struct net_device *next;
@@ -242,7 +249,6 @@ struct lance_private {
int slot;
int dma_irq;
volatile struct lance_regs *ll;
- volatile struct lance_init_block *init_block;
spinlock_t lock;
@@ -260,8 +266,8 @@ struct lance_private {
char *tx_buf_ptr_cpu[TX_RING_SIZE];
/* Pointers to the ring buffers as seen from the LANCE */
- char *rx_buf_ptr_lnc[RX_RING_SIZE];
- char *tx_buf_ptr_lnc[TX_RING_SIZE];
+ uint rx_buf_ptr_lnc[RX_RING_SIZE];
+ uint tx_buf_ptr_lnc[TX_RING_SIZE];
};
#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
@@ -294,7 +300,7 @@ static inline void writereg(volatile unsigned short *regptr, short value)
static void load_csrs(struct lance_private *lp)
{
volatile struct lance_regs *ll = lp->ll;
- int leptr;
+ uint leptr;
/* The address space as seen from the LANCE
* begins at address 0. HK
@@ -316,12 +322,14 @@ static void load_csrs(struct lance_private *lp)
* Our specialized copy routines
*
*/
-void cp_to_buf(const int type, void *to, const void *from, int len)
+static void cp_to_buf(const int type, void *to, const void *from, int len)
{
unsigned short *tp, *fp, clen;
unsigned char *rtp, *rfp;
- if (type == PMAX_LANCE) {
+ if (type == PMAD_LANCE) {
+ memcpy(to, from, len);
+ } else if (type == PMAX_LANCE) {
clen = len >> 1;
tp = (unsigned short *) to;
fp = (unsigned short *) from;
@@ -370,12 +378,14 @@ void cp_to_buf(const int type, void *to, const void *from, int len)
iob();
}
-void cp_from_buf(const int type, void *to, const void *from, int len)
+static void cp_from_buf(const int type, void *to, const void *from, int len)
{
unsigned short *tp, *fp, clen;
unsigned char *rtp, *rfp;
- if (type == PMAX_LANCE) {
+ if (type == PMAD_LANCE) {
+ memcpy(to, from, len);
+ } else if (type == PMAX_LANCE) {
clen = len >> 1;
tp = (unsigned short *) to;
fp = (unsigned short *) from;
@@ -431,12 +441,10 @@ void cp_from_buf(const int type, void *to, const void *from, int len)
static void lance_init_ring(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib;
- int leptr;
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
+ uint leptr;
int i;
- ib = (struct lance_init_block *) (dev->mem_start);
-
/* Lock out other processes while setting up hardware */
netif_stop_queue(dev);
lp->rx_new = lp->tx_new = 0;
@@ -445,55 +453,64 @@ static void lance_init_ring(struct net_device *dev)
/* Copy the ethernet address to the lance init block.
* XXX bit 0 of the physical address registers has to be zero
*/
- ib->phys_addr[0] = dev->dev_addr[0];
- ib->phys_addr[1] = dev->dev_addr[1];
- ib->phys_addr[4] = dev->dev_addr[2];
- ib->phys_addr[5] = dev->dev_addr[3];
- ib->phys_addr[8] = dev->dev_addr[4];
- ib->phys_addr[9] = dev->dev_addr[5];
+ *lib_ptr(ib, phys_addr[0], lp->type) = (dev->dev_addr[1] << 8) |
+ dev->dev_addr[0];
+ *lib_ptr(ib, phys_addr[1], lp->type) = (dev->dev_addr[3] << 8) |
+ dev->dev_addr[2];
+ *lib_ptr(ib, phys_addr[2], lp->type) = (dev->dev_addr[5] << 8) |
+ dev->dev_addr[4];
/* Setup the initialization block */
/* Setup rx descriptor pointer */
- leptr = LANCE_ADDR(libdesc_offset(brx_ring, 0));
- ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16);
- ib->rx_ptr = leptr;
+ leptr = offsetof(struct lance_init_block, brx_ring);
+ *lib_ptr(ib, rx_len, lp->type) = (LANCE_LOG_RX_BUFFERS << 13) |
+ (leptr >> 16);
+ *lib_ptr(ib, rx_ptr, lp->type) = leptr;
if (ZERO)
- printk("RX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(brx_ring, 0));
+ printk("RX ptr: %8.8x(%8.8x)\n",
+ leptr, lib_off(brx_ring, lp->type));
/* Setup tx descriptor pointer */
- leptr = LANCE_ADDR(libdesc_offset(btx_ring, 0));
- ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16);
- ib->tx_ptr = leptr;
+ leptr = offsetof(struct lance_init_block, btx_ring);
+ *lib_ptr(ib, tx_len, lp->type) = (LANCE_LOG_TX_BUFFERS << 13) |
+ (leptr >> 16);
+ *lib_ptr(ib, tx_ptr, lp->type) = leptr;
if (ZERO)
- printk("TX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(btx_ring, 0));
+ printk("TX ptr: %8.8x(%8.8x)\n",
+ leptr, lib_off(btx_ring, lp->type));
if (ZERO)
printk("TX rings:\n");
/* Setup the Tx ring entries */
for (i = 0; i < TX_RING_SIZE; i++) {
- leptr = (int) lp->tx_buf_ptr_lnc[i];
- ib->btx_ring[i].tmd0 = leptr;
- ib->btx_ring[i].tmd1_hadr = leptr >> 16;
- ib->btx_ring[i].tmd1_bits = 0;
- ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */
- ib->btx_ring[i].misc = 0;
+ leptr = lp->tx_buf_ptr_lnc[i];
+ *lib_ptr(ib, btx_ring[i].tmd0, lp->type) = leptr;
+ *lib_ptr(ib, btx_ring[i].tmd1, lp->type) = (leptr >> 16) &
+ 0xff;
+ *lib_ptr(ib, btx_ring[i].length, lp->type) = 0xf000;
+ /* The ones required by tmd2 */
+ *lib_ptr(ib, btx_ring[i].misc, lp->type) = 0;
if (i < 3 && ZERO)
- printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->tx_buf_ptr_cpu[i]);
+ printk("%d: 0x%8.8x(0x%8.8x)\n",
+ i, leptr, (uint)lp->tx_buf_ptr_cpu[i]);
}
/* Setup the Rx ring entries */
if (ZERO)
printk("RX rings:\n");
for (i = 0; i < RX_RING_SIZE; i++) {
- leptr = (int) lp->rx_buf_ptr_lnc[i];
- ib->brx_ring[i].rmd0 = leptr;
- ib->brx_ring[i].rmd1_hadr = leptr >> 16;
- ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
- ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
- ib->brx_ring[i].mblength = 0;
+ leptr = lp->rx_buf_ptr_lnc[i];
+ *lib_ptr(ib, brx_ring[i].rmd0, lp->type) = leptr;
+ *lib_ptr(ib, brx_ring[i].rmd1, lp->type) = ((leptr >> 16) &
+ 0xff) |
+ LE_R1_OWN;
+ *lib_ptr(ib, brx_ring[i].length, lp->type) = -RX_BUFF_SIZE |
+ 0xf000;
+ *lib_ptr(ib, brx_ring[i].mblength, lp->type) = 0;
if (i < 3 && ZERO)
- printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);
+ printk("%d: 0x%8.8x(0x%8.8x)\n",
+ i, leptr, (uint)lp->rx_buf_ptr_cpu[i]);
}
iob();
}
@@ -511,11 +528,13 @@ static int init_restart_lance(struct lance_private *lp)
udelay(10);
}
if ((i == 100) || (ll->rdp & LE_C0_ERR)) {
- printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
+ printk("LANCE unopened after %d ticks, csr0=%4.4x.\n",
+ i, ll->rdp);
return -1;
}
if ((ll->rdp & LE_C0_ERR)) {
- printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
+ printk("LANCE unopened after %d ticks, csr0=%4.4x.\n",
+ i, ll->rdp);
return -1;
}
writereg(&ll->rdp, LE_C0_IDON);
@@ -528,12 +547,11 @@ static int init_restart_lance(struct lance_private *lp)
static int lance_rx(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib;
- volatile struct lance_rx_desc *rd = 0;
- unsigned char bits;
- int len = 0;
- struct sk_buff *skb = 0;
- ib = (struct lance_init_block *) (dev->mem_start);
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
+ volatile u16 *rd;
+ unsigned short bits;
+ int entry, len;
+ struct sk_buff *skb;
#ifdef TEST_HITS
{
@@ -542,19 +560,22 @@ static int lance_rx(struct net_device *dev)
printk("[");
for (i = 0; i < RX_RING_SIZE; i++) {
if (i == lp->rx_new)
- printk("%s", ib->brx_ring[i].rmd1_bits &
+ printk("%s", *lib_ptr(ib, brx_ring[i].rmd1,
+ lp->type) &
LE_R1_OWN ? "_" : "X");
else
- printk("%s", ib->brx_ring[i].rmd1_bits &
+ printk("%s", *lib_ptr(ib, brx_ring[i].rmd1,
+ lp->type) &
LE_R1_OWN ? "." : "1");
}
printk("]");
}
#endif
- for (rd = &ib->brx_ring[lp->rx_new];
- !((bits = rd->rmd1_bits) & LE_R1_OWN);
- rd = &ib->brx_ring[lp->rx_new]) {
+ for (rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type);
+ !((bits = *rds_ptr(rd, rmd1, lp->type)) & LE_R1_OWN);
+ rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type)) {
+ entry = lp->rx_new;
/* We got an incomplete frame? */
if ((bits & LE_R1_POK) != LE_R1_POK) {
@@ -575,16 +596,18 @@ static int lance_rx(struct net_device *dev)
if (bits & LE_R1_EOP)
lp->stats.rx_errors++;
} else {
- len = (rd->mblength & 0xfff) - 4;
+ len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4;
skb = dev_alloc_skb(len + 2);
if (skb == 0) {
printk("%s: Memory squeeze, deferring packet.\n",
dev->name);
lp->stats.rx_dropped++;
- rd->mblength = 0;
- rd->rmd1_bits = LE_R1_OWN;
- lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;
+ *rds_ptr(rd, mblength, lp->type) = 0;
+ *rds_ptr(rd, rmd1, lp->type) =
+ ((lp->rx_buf_ptr_lnc[entry] >> 16) &
+ 0xff) | LE_R1_OWN;
+ lp->rx_new = (entry + 1) & RX_RING_MOD_MASK;
return 0;
}
lp->stats.rx_bytes += len;
@@ -594,8 +617,7 @@ static int lance_rx(struct net_device *dev)
skb_put(skb, len); /* make room */
cp_from_buf(lp->type, skb->data,
- (char *)lp->rx_buf_ptr_cpu[lp->rx_new],
- len);
+ (char *)lp->rx_buf_ptr_cpu[entry], len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
@@ -604,10 +626,11 @@ static int lance_rx(struct net_device *dev)
}
/* Return the packet to the pool */
- rd->mblength = 0;
- rd->length = -RX_BUFF_SIZE | 0xf000;
- rd->rmd1_bits = LE_R1_OWN;
- lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;
+ *rds_ptr(rd, mblength, lp->type) = 0;
+ *rds_ptr(rd, length, lp->type) = -RX_BUFF_SIZE | 0xf000;
+ *rds_ptr(rd, rmd1, lp->type) =
+ ((lp->rx_buf_ptr_lnc[entry] >> 16) & 0xff) | LE_R1_OWN;
+ lp->rx_new = (entry + 1) & RX_RING_MOD_MASK;
}
return 0;
}
@@ -615,24 +638,24 @@ static int lance_rx(struct net_device *dev)
static void lance_tx(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib;
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
volatile struct lance_regs *ll = lp->ll;
- volatile struct lance_tx_desc *td;
+ volatile u16 *td;
int i, j;
int status;
- ib = (struct lance_init_block *) (dev->mem_start);
+
j = lp->tx_old;
spin_lock(&lp->lock);
for (i = j; i != lp->tx_new; i = j) {
- td = &ib->btx_ring[i];
+ td = lib_ptr(ib, btx_ring[i], lp->type);
/* If we hit a packet not owned by us, stop */
- if (td->tmd1_bits & LE_T1_OWN)
+ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_OWN)
break;
- if (td->tmd1_bits & LE_T1_ERR) {
- status = td->misc;
+ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_ERR) {
+ status = *tds_ptr(td, misc, lp->type);
lp->stats.tx_errors++;
if (status & LE_T3_RTY)
@@ -667,18 +690,19 @@ static void lance_tx(struct net_device *dev)
init_restart_lance(lp);
goto out;
}
- } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
+ } else if ((*tds_ptr(td, tmd1, lp->type) & LE_T1_POK) ==
+ LE_T1_POK) {
/*
* So we don't count the packet more than once.
*/
- td->tmd1_bits &= ~(LE_T1_POK);
+ *tds_ptr(td, tmd1, lp->type) &= ~(LE_T1_POK);
/* One collision before packet was sent. */
- if (td->tmd1_bits & LE_T1_EONE)
+ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EONE)
lp->stats.collisions++;
/* More than one collision, be optimistic. */
- if (td->tmd1_bits & LE_T1_EMORE)
+ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EMORE)
lp->stats.collisions += 2;
lp->stats.tx_packets++;
@@ -752,7 +776,7 @@ struct net_device *last_dev = 0;
static int lance_open(struct net_device *dev)
{
- volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
int status = 0;
@@ -769,11 +793,11 @@ static int lance_open(struct net_device *dev)
*
* BTW it is common bug in all lance drivers! --ANK
*/
- ib->mode = 0;
- ib->filter [0] = 0;
- ib->filter [2] = 0;
- ib->filter [4] = 0;
- ib->filter [6] = 0;
+ *lib_ptr(ib, mode, lp->type) = 0;
+ *lib_ptr(ib, filter[0], lp->type) = 0;
+ *lib_ptr(ib, filter[1], lp->type) = 0;
+ *lib_ptr(ib, filter[2], lp->type) = 0;
+ *lib_ptr(ib, filter[3], lp->type) = 0;
lance_init_ring(dev);
load_csrs(lp);
@@ -874,12 +898,10 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
- volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
- int entry, skblen, len;
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
+ int entry, len;
- skblen = skb->len;
-
- len = skblen;
+ len = skb->len;
if (len < ETH_ZLEN) {
if (skb_padto(skb, ETH_ZLEN))
@@ -889,23 +911,17 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->stats.tx_bytes += len;
- entry = lp->tx_new & TX_RING_MOD_MASK;
- ib->btx_ring[entry].length = (-len);
- ib->btx_ring[entry].misc = 0;
-
- cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data,
- skblen);
+ entry = lp->tx_new;
+ *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
+ *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
- /* Clear the slack of the packet, do I need this? */
- /* For a firewall it's a good idea - AC */
-/*
- if (len != skblen)
- memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1);
- */
+ cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len);
/* Now, give the packet to the lance */
- ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN);
- lp->tx_new = (lp->tx_new + 1) & TX_RING_MOD_MASK;
+ *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) =
+ ((lp->tx_buf_ptr_lnc[entry] >> 16) & 0xff) |
+ (LE_T1_POK | LE_T1_OWN);
+ lp->tx_new = (entry + 1) & TX_RING_MOD_MASK;
if (TX_BUFFS_AVAIL <= 0)
netif_stop_queue(dev);
@@ -930,8 +946,8 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev)
static void lance_load_multicast(struct net_device *dev)
{
- volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
- volatile u16 *mcast_table = (u16 *) & ib->filter;
+ struct lance_private *lp = netdev_priv(dev);
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
struct dev_mc_list *dmi = dev->mc_list;
char *addrs;
int i;
@@ -939,17 +955,17 @@ static void lance_load_multicast(struct net_device *dev)
/* set all multicast bits */
if (dev->flags & IFF_ALLMULTI) {
- ib->filter[0] = 0xffff;
- ib->filter[2] = 0xffff;
- ib->filter[4] = 0xffff;
- ib->filter[6] = 0xffff;
+ *lib_ptr(ib, filter[0], lp->type) = 0xffff;
+ *lib_ptr(ib, filter[1], lp->type) = 0xffff;
+ *lib_ptr(ib, filter[2], lp->type) = 0xffff;
+ *lib_ptr(ib, filter[3], lp->type) = 0xffff;
return;
}
/* clear the multicast filter */
- ib->filter[0] = 0;
- ib->filter[2] = 0;
- ib->filter[4] = 0;
- ib->filter[6] = 0;
+ *lib_ptr(ib, filter[0], lp->type) = 0;
+ *lib_ptr(ib, filter[1], lp->type) = 0;
+ *lib_ptr(ib, filter[2], lp->type) = 0;
+ *lib_ptr(ib, filter[3], lp->type) = 0;
/* Add addresses */
for (i = 0; i < dev->mc_count; i++) {
@@ -962,7 +978,7 @@ static void lance_load_multicast(struct net_device *dev)
crc = ether_crc_le(ETH_ALEN, addrs);
crc = crc >> 26;
- mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf);
+ *lib_ptr(ib, filter[crc >> 4], lp->type) |= 1 << (crc & 0xf);
}
return;
}
@@ -970,11 +986,9 @@ static void lance_load_multicast(struct net_device *dev)
static void lance_set_multicast(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib;
+ volatile u16 *ib = (volatile u16 *)dev->mem_start;
volatile struct lance_regs *ll = lp->ll;
- ib = (struct lance_init_block *) (dev->mem_start);
-
if (!netif_running(dev))
return;
@@ -992,9 +1006,9 @@ static void lance_set_multicast(struct net_device *dev)
lance_init_ring(dev);
if (dev->flags & IFF_PROMISC) {
- ib->mode |= LE_MO_PROM;
+ *lib_ptr(ib, mode, lp->type) |= LE_MO_PROM;
} else {
- ib->mode &= ~LE_MO_PROM;
+ *lib_ptr(ib, mode, lp->type) &= ~LE_MO_PROM;
lance_load_multicast(dev);
}
load_csrs(lp);
@@ -1051,7 +1065,6 @@ static int __init dec_lance_init(const int type, const int slot)
lp->type = type;
lp->slot = slot;
switch (type) {
-#ifdef CONFIG_TC
case ASIC_LANCE:
dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
@@ -1073,20 +1086,20 @@ static int __init dec_lance_init(const int type, const int slot)
*/
for (i = 0; i < RX_RING_SIZE; i++) {
lp->rx_buf_ptr_cpu[i] =
- (char *)(dev->mem_start + BUF_OFFSET_CPU +
+ (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
2 * i * RX_BUFF_SIZE);
lp->rx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+ (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
}
for (i = 0; i < TX_RING_SIZE; i++) {
lp->tx_buf_ptr_cpu[i] =
- (char *)(dev->mem_start + BUF_OFFSET_CPU +
+ (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
2 * RX_RING_SIZE * RX_BUFF_SIZE +
2 * i * TX_BUFF_SIZE);
lp->tx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC +
- RX_RING_SIZE * RX_BUFF_SIZE +
- i * TX_BUFF_SIZE);
+ (BUF_OFFSET_LNC +
+ RX_RING_SIZE * RX_BUFF_SIZE +
+ i * TX_BUFF_SIZE);
}
/* Setup I/O ASIC LANCE DMA. */
@@ -1095,11 +1108,12 @@ static int __init dec_lance_init(const int type, const int slot)
CPHYSADDR(dev->mem_start) << 3);
break;
-
+#ifdef CONFIG_TC
case PMAD_LANCE:
claim_tc_card(slot);
dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
+ dev->mem_end = dev->mem_start + 0x100000;
dev->base_addr = dev->mem_start + 0x100000;
dev->irq = get_tc_irq_nr(slot);
esar_base = dev->mem_start + 0x1c0002;
@@ -1110,7 +1124,7 @@ static int __init dec_lance_init(const int type, const int slot)
(char *)(dev->mem_start + BUF_OFFSET_CPU +
i * RX_BUFF_SIZE);
lp->rx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+ (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
}
for (i = 0; i < TX_RING_SIZE; i++) {
lp->tx_buf_ptr_cpu[i] =
@@ -1118,18 +1132,18 @@ static int __init dec_lance_init(const int type, const int slot)
RX_RING_SIZE * RX_BUFF_SIZE +
i * TX_BUFF_SIZE);
lp->tx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC +
- RX_RING_SIZE * RX_BUFF_SIZE +
- i * TX_BUFF_SIZE);
+ (BUF_OFFSET_LNC +
+ RX_RING_SIZE * RX_BUFF_SIZE +
+ i * TX_BUFF_SIZE);
}
break;
#endif
-
case PMAX_LANCE:
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
+ dev->mem_end = dev->mem_start + KN01_SLOT_SIZE;
esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
lp->dma_irq = -1;
@@ -1138,20 +1152,20 @@ static int __init dec_lance_init(const int type, const int slot)
*/
for (i = 0; i < RX_RING_SIZE; i++) {
lp->rx_buf_ptr_cpu[i] =
- (char *)(dev->mem_start + BUF_OFFSET_CPU +
+ (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
2 * i * RX_BUFF_SIZE);
lp->rx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+ (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
}
for (i = 0; i < TX_RING_SIZE; i++) {
lp->tx_buf_ptr_cpu[i] =
- (char *)(dev->mem_start + BUF_OFFSET_CPU +
+ (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
2 * RX_RING_SIZE * RX_BUFF_SIZE +
2 * i * TX_BUFF_SIZE);
lp->tx_buf_ptr_lnc[i] =
- (char *)(BUF_OFFSET_LNC +
- RX_RING_SIZE * RX_BUFF_SIZE +
- i * TX_BUFF_SIZE);
+ (BUF_OFFSET_LNC +
+ RX_RING_SIZE * RX_BUFF_SIZE +
+ i * TX_BUFF_SIZE);
}
break;
@@ -1279,10 +1293,8 @@ static int __init dec_lance_probe(void)
/* Then handle onboard devices. */
if (dec_interrupt[DEC_IRQ_LANCE] >= 0) {
if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) {
-#ifdef CONFIG_TC
if (dec_lance_init(ASIC_LANCE, -1) >= 0)
count++;
-#endif
} else if (!TURBOCHANNEL) {
if (dec_lance_init(PMAX_LANCE, -1) >= 0)
count++;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 3a8df479cbda..03bf164f9e8d 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2102,9 +2102,10 @@ static void e100_tx_timeout(struct net_device *netdev)
schedule_work(&nic->tx_timeout_task);
}
-static void e100_tx_timeout_task(struct net_device *netdev)
+static void e100_tx_timeout_task(struct work_struct *work)
{
- struct nic *nic = netdev_priv(netdev);
+ struct nic *nic = container_of(work, struct nic, tx_timeout_task);
+ struct net_device *netdev = nic->netdev;
DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
readb(&nic->csr->scb.status));
@@ -2637,8 +2638,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
nic->blink_timer.function = e100_blink_led;
nic->blink_timer.data = (unsigned long)nic;
- INIT_WORK(&nic->tx_timeout_task,
- (void (*)(void *))e100_tx_timeout_task, netdev);
+ INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task);
if((err = e100_alloc(nic))) {
DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n");
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7a0828869ecf..73f3a85fd238 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -190,7 +190,7 @@ void e1000_set_ethtool_ops(struct net_device *netdev);
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static void e1000_tx_timeout(struct net_device *dev);
-static void e1000_reset_task(struct net_device *dev);
+static void e1000_reset_task(struct work_struct *work);
static void e1000_smartspeed(struct e1000_adapter *adapter);
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
struct sk_buff *skb);
@@ -914,8 +914,7 @@ e1000_probe(struct pci_dev *pdev,
adapter->phy_info_timer.function = &e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter;
- INIT_WORK(&adapter->reset_task,
- (void (*)(void *))e1000_reset_task, netdev);
+ INIT_WORK(&adapter->reset_task, e1000_reset_task);
e1000_check_options(adapter);
@@ -2826,7 +2825,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
context_desc->upper_setup.tcp_fields.tucss = css;
- context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
+ context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset;
context_desc->upper_setup.tcp_fields.tucse = 0;
context_desc->tcp_seg_setup.data = 0;
context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
@@ -3306,9 +3305,10 @@ e1000_tx_timeout(struct net_device *netdev)
}
static void
-e1000_reset_task(struct net_device *netdev)
+e1000_reset_task(struct work_struct *work)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_adapter *adapter =
+ container_of(work, struct e1000_adapter, reset_task);
e1000_reinit_locked(adapter);
}
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index d39e8480ca56..c62d9c6363c6 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -463,7 +463,7 @@ static void cleanup_card(struct net_device *dev)
release_region(dev->base_addr, E21_IO_EXTENT);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index a4eb0dc99ecf..b4463094c93a 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1827,7 +1827,7 @@ int __init init_module(void)
return n_eepro ? 0 : -ENODEV;
}
-void
+void __exit
cleanup_module(void)
{
int i;
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index e14be020e562..4a50fcb5ad6b 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -1719,7 +1719,7 @@ int __init init_module(void)
return -ENXIO;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 6ad696101418..83fa32f72398 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2224,11 +2224,12 @@ static int ehea_stop(struct net_device *dev)
return ret;
}
-static void ehea_reset_port(void *data)
+static void ehea_reset_port(struct work_struct *work)
{
int ret;
- struct net_device *dev = data;
- struct ehea_port *port = netdev_priv(dev);
+ struct ehea_port *port =
+ container_of(work, struct ehea_port, reset_task);
+ struct net_device *dev = port->netdev;
port->resets++;
down(&port->port_lock);
@@ -2379,7 +2380,7 @@ static int ehea_setup_single_port(struct ehea_port *port,
dev->tx_timeout = &ehea_tx_watchdog;
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
- INIT_WORK(&port->reset_task, ehea_reset_port, dev);
+ INIT_WORK(&port->reset_task, ehea_reset_port);
ehea_set_ethtool_ops(dev);
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 72ef7bde3346..f143e13b229d 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -26,6 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/mm.h>
#include "ehea.h"
#include "ehea_phyp.h"
#include "ehea_qmr.h"
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
index fd7b32a24ea4..2d2ea94a00bb 100644
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -455,7 +455,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index b7b8bc2a6307..93283e386f3a 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -1475,7 +1475,7 @@ int __init init_module(void)
return -ENXIO;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 1ed9cccd3c11..3c33d6f6a6a6 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -168,8 +168,9 @@ struct baycom_state {
int magic;
struct pardevice *pdev;
+ struct net_device *dev;
unsigned int work_running;
- struct work_struct run_work;
+ struct delayed_work run_work;
unsigned int modem;
unsigned int bitrate;
unsigned char stat;
@@ -659,16 +660,18 @@ static int receive(struct net_device *dev, int cnt)
#define GETTICK(x)
#endif /* __i386__ */
-static void epp_bh(struct net_device *dev)
+static void epp_bh(struct work_struct *work)
{
+ struct net_device *dev;
struct baycom_state *bc;
struct parport *pp;
unsigned char stat;
unsigned char tmp[2];
unsigned int time1 = 0, time2 = 0, time3 = 0;
int cnt, cnt2;
-
- bc = netdev_priv(dev);
+
+ bc = container_of(work, struct baycom_state, run_work.work);
+ dev = bc->dev;
if (!bc->work_running)
return;
baycom_int_freq(bc);
@@ -889,7 +892,7 @@ static int epp_open(struct net_device *dev)
return -EBUSY;
}
dev->irq = /*pp->irq*/ 0;
- INIT_WORK(&bc->run_work, (void *)(void *)epp_bh, dev);
+ INIT_DELAYED_WORK(&bc->run_work, epp_bh);
bc->work_running = 1;
bc->modem = EPP_CONVENTIONAL;
if (eppconfig(bc))
@@ -1213,6 +1216,7 @@ static void __init baycom_epp_dev_setup(struct net_device *dev)
/*
* initialize part of the baycom_state struct
*/
+ bc->dev = dev;
bc->magic = BAYCOM_MAGIC;
bc->cfg.fclk = 19666600;
bc->cfg.bps = 9600;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 0f8b9afd55b4..e6e721aff6f6 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -252,7 +252,7 @@ static inline void z8530_isr(struct scc_info *info);
static irqreturn_t scc_isr(int irq, void *dev_id);
static void rx_isr(struct scc_priv *priv);
static void special_condition(struct scc_priv *priv, int rc);
-static void rx_bh(void *arg);
+static void rx_bh(struct work_struct *);
static void tx_isr(struct scc_priv *priv);
static void es_isr(struct scc_priv *priv);
static void tm_isr(struct scc_priv *priv);
@@ -579,7 +579,7 @@ static int __init setup_adapter(int card_base, int type, int n)
priv->param.clocks = TCTRxCP | RCRTxCP;
priv->param.persist = 256;
priv->param.dma = -1;
- INIT_WORK(&priv->rx_work, rx_bh, priv);
+ INIT_WORK(&priv->rx_work, rx_bh);
dev->priv = priv;
sprintf(dev->name, "dmascc%i", 2 * n + i);
dev->base_addr = card_base;
@@ -1272,9 +1272,9 @@ static void special_condition(struct scc_priv *priv, int rc)
}
-static void rx_bh(void *arg)
+static void rx_bh(struct work_struct *ugli_api)
{
- struct scc_priv *priv = arg;
+ struct scc_priv *priv = container_of(ugli_api, struct scc_priv, rx_work);
int i = priv->rx_tail;
int cb;
unsigned long flags;
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index 6abcfd2a4b28..99a36cc3f8df 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -482,7 +482,7 @@ static void cleanup_card(struct net_device *dev)
release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 29470970aa27..635b13c2e2aa 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -444,7 +444,7 @@ static void cleanup_card(struct net_device *dev)
release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index f73f10a0a562..407d2acbf7c7 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -24,6 +24,7 @@
#include <linux/netdevice.h>
#include <asm/io.h>
+#include <asm/dcr.h>
/*
* These MAL "versions" probably aren't the real versions IBM uses for these
@@ -191,6 +192,7 @@ struct mal_commac {
struct ibm_ocp_mal {
int dcrbase;
+ dcr_host_t dcrhost;
struct list_head poll_list;
struct net_device poll_dev;
@@ -207,12 +209,12 @@ struct ibm_ocp_mal {
static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
- return mfdcr(mal->dcrbase + reg);
+ return dcr_read(mal->dcrhost, mal->dcrbase + reg);
}
static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
- mtdcr(mal->dcrbase + reg, val);
+ dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
}
/* Register MAL devices */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 44c9f993dcc4..99343b5836b8 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -50,7 +50,6 @@
#include <asm/semaphore.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
-#include <asm/iommu.h>
#include <asm/vio.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
@@ -1000,8 +999,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
adapter->mac_addr = 0;
memcpy(&adapter->mac_addr, mac_addr_p, 6);
- adapter->liobn = dev->iommu_table->it_index;
-
netdev->irq = dev->irq;
netdev->open = ibmveth_open;
netdev->poll = ibmveth_poll;
@@ -1115,7 +1112,6 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
- seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn);
seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
current_mac[0], current_mac[1], current_mac[2],
current_mac[3], current_mac[4], current_mac[5]);
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index f5b25bff1540..bb69ccae8ace 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -118,7 +118,6 @@ struct ibmveth_adapter {
struct net_device_stats stats;
unsigned int mcastFilterSize;
unsigned long mac_addr;
- unsigned long liobn;
void * buffer_list_addr;
void * filter_list_addr;
dma_addr_t buffer_list_dma;
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index f56b00ee385e..f0d30cf67b5f 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -57,7 +57,6 @@
#include <net/ip.h>
#include <asm/byteorder.h>
-#include <asm/checksum.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index b32c52ed19d7..f0c61f3b2a82 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -560,9 +560,9 @@ static inline int mcs_find_endpoints(struct mcs_cb *mcs,
return ret;
}
-static void mcs_speed_work(void *arg)
+static void mcs_speed_work(struct work_struct *work)
{
- struct mcs_cb *mcs = arg;
+ struct mcs_cb *mcs = container_of(work, struct mcs_cb, work);
struct net_device *netdev = mcs->netdev;
mcs_speed_change(mcs);
@@ -927,7 +927,7 @@ static int mcs_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&mcs->qos);
/* Speed change work initialisation*/
- INIT_WORK(&mcs->work, mcs_speed_work, mcs);
+ INIT_WORK(&mcs->work, mcs_speed_work);
/* Override the network functions we need to use */
ndev->hard_start_xmit = mcs_hard_xmit;
diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h
index 9fa294a546d6..2a57bc67ce35 100644
--- a/drivers/net/irda/sir-dev.h
+++ b/drivers/net/irda/sir-dev.h
@@ -22,7 +22,7 @@
struct sir_fsm {
struct semaphore sem;
- struct work_struct work;
+ struct delayed_work work;
unsigned state, substate;
int param;
int result;
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 3b5854d10c17..17b0c3ab6201 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -100,9 +100,9 @@ static int sirdev_tx_complete_fsm(struct sir_dev *dev)
* Both must be unlocked/restarted on completion - but only on final exit.
*/
-static void sirdev_config_fsm(void *data)
+static void sirdev_config_fsm(struct work_struct *work)
{
- struct sir_dev *dev = data;
+ struct sir_dev *dev = container_of(work, struct sir_dev, fsm.work.work);
struct sir_fsm *fsm = &dev->fsm;
int next_state;
int ret = -1;
@@ -309,8 +309,8 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par
fsm->param = param;
fsm->result = 0;
- INIT_WORK(&fsm->work, sirdev_config_fsm, dev);
- queue_work(irda_sir_wq, &fsm->work);
+ INIT_DELAYED_WORK(&fsm->work, sirdev_config_fsm);
+ queue_delayed_work(irda_sir_wq, &fsm->work, 0);
return 0;
}
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 2284e2ce1692..d6f4f185bf37 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -166,7 +166,7 @@ struct veth_msg {
struct veth_lpar_connection {
HvLpIndex remote_lp;
- struct work_struct statemachine_wq;
+ struct delayed_work statemachine_wq;
struct veth_msg *msgs;
int num_events;
struct veth_cap_data local_caps;
@@ -456,7 +456,7 @@ static struct kobj_type veth_port_ktype = {
static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx)
{
- schedule_work(&cnx->statemachine_wq);
+ schedule_delayed_work(&cnx->statemachine_wq, 0);
}
static void veth_take_cap(struct veth_lpar_connection *cnx,
@@ -638,9 +638,11 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
}
/* FIXME: The gotos here are a bit dubious */
-static void veth_statemachine(void *p)
+static void veth_statemachine(struct work_struct *work)
{
- struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)p;
+ struct veth_lpar_connection *cnx =
+ container_of(work, struct veth_lpar_connection,
+ statemachine_wq.work);
int rlp = cnx->remote_lp;
int rc;
@@ -827,7 +829,7 @@ static int veth_init_connection(u8 rlp)
cnx->remote_lp = rlp;
spin_lock_init(&cnx->lock);
- INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx);
+ INIT_DELAYED_WORK(&cnx->statemachine_wq, veth_statemachine);
init_timer(&cnx->ack_timer);
cnx->ack_timer.function = veth_timed_ack;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index e09f575a3a38..e628126c9c49 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -106,7 +106,7 @@ static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
void ixgb_set_ethtool_ops(struct net_device *netdev);
static void ixgb_tx_timeout(struct net_device *dev);
-static void ixgb_tx_timeout_task(struct net_device *dev);
+static void ixgb_tx_timeout_task(struct work_struct *work);
static void ixgb_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
@@ -489,8 +489,7 @@ ixgb_probe(struct pci_dev *pdev,
adapter->watchdog_timer.function = &ixgb_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
- INIT_WORK(&adapter->tx_timeout_task,
- (void (*)(void *))ixgb_tx_timeout_task, netdev);
+ INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
strcpy(netdev->name, "eth%d");
if((err = register_netdev(netdev)))
@@ -1249,7 +1248,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
if(likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
struct ixgb_buffer *buffer_info;
css = skb->h.raw - skb->data;
- cso = (skb->h.raw + skb->csum) - skb->data;
+ cso = css + skb->csum_offset;
i = adapter->tx_ring.next_to_use;
context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i);
@@ -1493,9 +1492,10 @@ ixgb_tx_timeout(struct net_device *netdev)
}
static void
-ixgb_tx_timeout_task(struct net_device *netdev)
+ixgb_tx_timeout_task(struct work_struct *work)
{
- struct ixgb_adapter *adapter = netdev_priv(netdev);
+ struct ixgb_adapter *adapter =
+ container_of(work, struct ixgb_adapter, tx_timeout_task);
adapter->tx_timeout_count++;
ixgb_down(adapter, TRUE);
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 6efbd499d752..a3843320dbe1 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -57,6 +57,7 @@ static const char version[] = "lance.c:v1.16 2006/11/09 dplatt@3do.com, becker@c
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/mm.h>
#include <linux/bitops.h>
#include <asm/io.h>
@@ -367,7 +368,7 @@ static void cleanup_card(struct net_device *dev)
kfree(lp);
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 5795ee116205..0a08d0c4e7b4 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -440,7 +440,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index c1aa60b9a982..e1d97cdf649e 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -33,7 +33,6 @@
#include <asm/ip32/ip32_ints.h>
#include <asm/io.h>
-#include <asm/checksum.h>
#include <asm/scatterlist.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 9997081c6dae..c41ae4286eea 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -277,9 +277,11 @@ static void mv643xx_eth_tx_timeout(struct net_device *dev)
*
* Actual routine to reset the adapter when a timeout on Tx has occurred
*/
-static void mv643xx_eth_tx_timeout_task(struct net_device *dev)
+static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private,
+ tx_timeout_task);
+ struct net_device *dev = mp->mii.dev; /* yuck */
if (!netif_running(dev))
return;
@@ -1098,7 +1100,7 @@ static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
ETH_TX_ENABLE_INTERRUPT;
mp->tx_skb[tx_index] = skb;
} else
- mp->tx_skb[tx_index] = 0;
+ mp->tx_skb[tx_index] = NULL;
desc = &mp->p_tx_desc_area[tx_index];
desc->l4i_chk = 0;
@@ -1134,7 +1136,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
eth_tx_fill_frag_descs(mp, skb);
length = skb_headlen(skb);
- mp->tx_skb[tx_index] = 0;
+ mp->tx_skb[tx_index] = NULL;
} else {
cmd_sts |= ETH_ZERO_PADDING |
ETH_TX_LAST_DESC |
@@ -1360,8 +1362,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
#endif
/* Configure the timeout task */
- INIT_WORK(&mp->tx_timeout_task,
- (void (*)(void *))mv643xx_eth_tx_timeout_task, dev);
+ INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task);
spin_lock_init(&mp->lock);
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 56a82d8ee8f5..e246d00bba6d 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -184,7 +184,7 @@ static int m147lance_close(struct net_device *dev)
MODULE_LICENSE("GPL");
static struct net_device *dev_mvme147_lance;
-int init_module(void)
+int __init init_module(void)
{
dev_mvme147_lance = mvme147lance_probe(-1);
if (IS_ERR(dev_mvme147_lance))
@@ -192,7 +192,7 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
struct m147lance_private *lp = dev_mvme147_lance->priv;
unregister_netdev(dev_mvme147_lance);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 806081b59733..81f127a78afa 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -89,7 +89,7 @@ MODULE_LICENSE("Dual BSD/GPL");
#define MYRI10GE_EEPROM_STRINGS_SIZE 256
#define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
-#define MYRI10GE_NO_CONFIRM_DATA 0xffffffff
+#define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
#define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
struct myri10ge_rx_buffer_state {
@@ -156,8 +156,8 @@ struct myri10ge_priv {
int sram_size;
unsigned long board_span;
unsigned long iomem_base;
- u32 __iomem *irq_claim;
- u32 __iomem *irq_deassert;
+ __be32 __iomem *irq_claim;
+ __be32 __iomem *irq_deassert;
char *mac_addr_string;
struct mcp_cmd_response *cmd;
dma_addr_t cmd_bus;
@@ -165,10 +165,10 @@ struct myri10ge_priv {
dma_addr_t fw_stats_bus;
struct pci_dev *pdev;
int msi_enabled;
- unsigned int link_state;
+ __be32 link_state;
unsigned int rdma_tags_available;
int intr_coal_delay;
- u32 __iomem *intr_coal_delay_ptr;
+ __be32 __iomem *intr_coal_delay_ptr;
int mtrr;
int wake_queue;
int stop_queue;
@@ -273,6 +273,11 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
+static inline void put_be32(__be32 val, __be32 __iomem *p)
+{
+ __raw_writel((__force __u32)val, (__force void __iomem *)p);
+}
+
static int
myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
struct myri10ge_cmd *data, int atomic)
@@ -296,7 +301,7 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
buf->response_addr.low = htonl(dma_low);
buf->response_addr.high = htonl(dma_high);
- response->result = MYRI10GE_NO_RESPONSE_RESULT;
+ response->result = htonl(MYRI10GE_NO_RESPONSE_RESULT);
mb();
myri10ge_pio_copy(cmd_addr, buf, sizeof(*buf));
@@ -311,14 +316,14 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
* (1ms will be enough for those commands) */
for (sleep_total = 0;
sleep_total < 1000
- && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+ && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
sleep_total += 10)
udelay(10);
} else {
/* use msleep for most command */
for (sleep_total = 0;
sleep_total < 15
- && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+ && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
sleep_total++)
msleep(1);
}
@@ -393,7 +398,7 @@ abort:
static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
{
char __iomem *submit;
- u32 buf[16];
+ __be32 buf[16];
u32 dma_low, dma_high;
int i;
@@ -410,7 +415,7 @@ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
buf[0] = htonl(dma_high); /* confirm addr MSW */
buf[1] = htonl(dma_low); /* confirm addr LSW */
- buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */
+ buf[2] = MYRI10GE_NO_CONFIRM_DATA; /* confirm data */
buf[3] = htonl(dma_high); /* dummy addr MSW */
buf[4] = htonl(dma_low); /* dummy addr LSW */
buf[5] = htonl(enable); /* enable? */
@@ -479,7 +484,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
}
/* check id */
- hdr_offset = ntohl(*(u32 *) (fw->data + MCP_HEADER_PTR_OFFSET));
+ hdr_offset = ntohl(*(__be32 *) (fw->data + MCP_HEADER_PTR_OFFSET));
if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->size) {
dev_err(dev, "Bad firmware file\n");
status = -EINVAL;
@@ -550,7 +555,7 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
{
char __iomem *submit;
- u32 buf[16];
+ __be32 buf[16];
u32 dma_low, dma_high, size;
int status, i;
@@ -600,7 +605,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
buf[0] = htonl(dma_high); /* confirm addr MSW */
buf[1] = htonl(dma_low); /* confirm addr LSW */
- buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */
+ buf[2] = MYRI10GE_NO_CONFIRM_DATA; /* confirm data */
/* FIX: All newest firmware should un-protect the bottom of
* the sram before handoff. However, the very first interfaces
@@ -705,21 +710,21 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
status |=
myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
- mgp->irq_claim = (__iomem u32 *) (mgp->sram + cmd.data0);
+ mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
if (!mgp->msi_enabled) {
status |= myri10ge_send_cmd
(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0);
- mgp->irq_deassert = (__iomem u32 *) (mgp->sram + cmd.data0);
+ mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
}
status |= myri10ge_send_cmd
(mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0);
- mgp->intr_coal_delay_ptr = (__iomem u32 *) (mgp->sram + cmd.data0);
+ mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0);
if (status != 0) {
dev_err(&mgp->pdev->dev, "failed set interrupt parameters\n");
return status;
}
- __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+ put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
/* Run a small DMA test.
* The magic multipliers to the length tell the firmware
@@ -786,14 +791,16 @@ static inline void
myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
struct mcp_kreq_ether_recv *src)
{
- u32 low;
+ __be32 low;
low = src->addr_low;
- src->addr_low = DMA_32BIT_MASK;
- myri10ge_pio_copy(dst, src, 8 * sizeof(*src));
+ src->addr_low = htonl(DMA_32BIT_MASK);
+ myri10ge_pio_copy(dst, src, 4 * sizeof(*src));
+ mb();
+ myri10ge_pio_copy(dst + 4, src + 4, 4 * sizeof(*src));
mb();
src->addr_low = low;
- __raw_writel(low, &dst->addr_low);
+ put_be32(low, &dst->addr_low);
mb();
}
@@ -939,11 +946,11 @@ done:
return retval;
}
-static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
+static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
{
struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
- if ((skb->protocol == ntohs(ETH_P_8021Q)) &&
+ if ((skb->protocol == htons(ETH_P_8021Q)) &&
(vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
skb->csum = hw_csum;
@@ -953,7 +960,7 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
static inline unsigned long
myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
- int bytes, int len, int csum)
+ int bytes, int len, __wsum csum)
{
dma_addr_t bus;
struct sk_buff *skb;
@@ -986,12 +993,12 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
skb->protocol = eth_type_trans(skb, mgp->dev);
if (mgp->csum_flag) {
- if ((skb->protocol == ntohs(ETH_P_IP)) ||
- (skb->protocol == ntohs(ETH_P_IPV6))) {
- skb->csum = ntohs((u16) csum);
+ if ((skb->protocol == htons(ETH_P_IP)) ||
+ (skb->protocol == htons(ETH_P_IPV6))) {
+ skb->csum = csum;
skb->ip_summed = CHECKSUM_COMPLETE;
} else
- myri10ge_vlan_ip_csum(skb, ntohs((u16) csum));
+ myri10ge_vlan_ip_csum(skb, csum);
}
netif_receive_skb(skb);
@@ -1060,12 +1067,12 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
int idx = rx_done->idx;
int cnt = rx_done->cnt;
u16 length;
- u16 checksum;
+ __wsum checksum;
while (rx_done->entry[idx].length != 0 && *limit != 0) {
length = ntohs(rx_done->entry[idx].length);
rx_done->entry[idx].length = 0;
- checksum = ntohs(rx_done->entry[idx].checksum);
+ checksum = csum_unfold(rx_done->entry[idx].checksum);
if (length <= mgp->small_bytes)
rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
mgp->small_bytes,
@@ -1142,7 +1149,7 @@ static int myri10ge_poll(struct net_device *netdev, int *budget)
if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) {
netif_rx_complete(netdev);
- __raw_writel(htonl(3), mgp->irq_claim);
+ put_be32(htonl(3), mgp->irq_claim);
return 0;
}
return 1;
@@ -1166,7 +1173,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
netif_rx_schedule(mgp->dev);
if (!mgp->msi_enabled) {
- __raw_writel(0, mgp->irq_deassert);
+ put_be32(0, mgp->irq_deassert);
if (!myri10ge_deassert_wait)
stats->valid = 0;
mb();
@@ -1195,7 +1202,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
myri10ge_check_statblock(mgp);
- __raw_writel(htonl(3), mgp->irq_claim + 1);
+ put_be32(htonl(3), mgp->irq_claim + 1);
return (IRQ_HANDLED);
}
@@ -1233,7 +1240,7 @@ myri10ge_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
struct myri10ge_priv *mgp = netdev_priv(netdev);
mgp->intr_coal_delay = coal->rx_coalesce_usecs;
- __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+ put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
return 0;
}
@@ -1748,7 +1755,7 @@ static int myri10ge_open(struct net_device *dev)
goto abort_with_rings;
}
- mgp->link_state = -1;
+ mgp->link_state = htonl(~0U);
mgp->rdma_tags_available = 15;
netif_poll_enable(mgp->dev); /* must happen prior to any irq */
@@ -1876,7 +1883,7 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
/* re-write the last 32-bits with the valid flags */
src->flags = last_flags;
- __raw_writel(*((u32 *) src + 3), (u32 __iomem *) dst + 3);
+ put_be32(*((__be32 *) src + 3), (__be32 __iomem *) dst + 3);
tx->req += cnt;
mb();
}
@@ -1919,7 +1926,8 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
struct myri10ge_tx_buf *tx = &mgp->tx;
struct skb_frag_struct *frag;
dma_addr_t bus;
- u32 low, high_swapped;
+ u32 low;
+ __be32 high_swapped;
unsigned int len;
int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
u16 pseudo_hdr_offset, cksum_offset;
@@ -1955,7 +1963,7 @@ again:
flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST);
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
cksum_offset = (skb->h.raw - skb->data);
- pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data;
+ pseudo_hdr_offset = cksum_offset + skb->csum_offset;
/* If the headers are excessively large, then we must
* fall back to a software checksum */
if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
@@ -1964,7 +1972,6 @@ again:
cksum_offset = 0;
pseudo_hdr_offset = 0;
} else {
- pseudo_hdr_offset = htons(pseudo_hdr_offset);
odd_flag = MXGEFW_FLAGS_ALIGN_ODD;
flags |= MXGEFW_FLAGS_CKSUM;
}
@@ -1986,7 +1993,7 @@ again:
/* for TSO, pseudo_hdr_offset holds mss.
* The firmware figures out where to put
* the checksum by parsing the header. */
- pseudo_hdr_offset = htons(mss);
+ pseudo_hdr_offset = mss;
} else
#endif /*NETIF_F_TSO */
/* Mark small packets, and pad out tiny packets */
@@ -2086,7 +2093,7 @@ again:
#endif /* NETIF_F_TSO */
req->addr_high = high_swapped;
req->addr_low = htonl(low);
- req->pseudo_hdr_offset = pseudo_hdr_offset;
+ req->pseudo_hdr_offset = htons(pseudo_hdr_offset);
req->pad = 0; /* complete solid 16-byte block; does this matter? */
req->rdma_count = 1;
req->length = htons(seglen);
@@ -2199,6 +2206,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
struct myri10ge_cmd cmd;
struct myri10ge_priv *mgp;
struct dev_mc_list *mc_list;
+ __be32 data[2] = {0, 0};
int err;
mgp = netdev_priv(dev);
@@ -2237,10 +2245,9 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
/* Walk the multicast list, and add each address */
for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) {
- memcpy(&cmd.data0, &mc_list->dmi_addr, 4);
- memcpy(&cmd.data1, ((char *)&mc_list->dmi_addr) + 4, 2);
- cmd.data0 = htonl(cmd.data0);
- cmd.data1 = htonl(cmd.data1);
+ memcpy(data, &mc_list->dmi_addr, 6);
+ cmd.data0 = ntohl(data[0]);
+ cmd.data1 = ntohl(data[1]);
err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP,
&cmd, 1);
@@ -2615,9 +2622,10 @@ static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
* This watchdog is used to check whether the board has suffered
* from a parity error and needs to be recovered.
*/
-static void myri10ge_watchdog(void *arg)
+static void myri10ge_watchdog(struct work_struct *work)
{
- struct myri10ge_priv *mgp = arg;
+ struct myri10ge_priv *mgp =
+ container_of(work, struct myri10ge_priv, watchdog_work);
u32 reboot;
int status;
u16 cmd, vendor;
@@ -2887,7 +2895,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(unsigned long)mgp);
SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
- INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog, mgp);
+ INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
status = register_netdev(netdev);
if (status != 0) {
dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index 9519ae7cd5ec..29463b301a84 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -6,23 +6,23 @@
/* 8 Bytes */
struct mcp_dma_addr {
- u32 high;
- u32 low;
+ __be32 high;
+ __be32 low;
};
/* 4 Bytes */
struct mcp_slot {
- u16 checksum;
- u16 length;
+ __sum16 checksum;
+ __be16 length;
};
/* 64 Bytes */
struct mcp_cmd {
- u32 cmd;
- u32 data0; /* will be low portion if data > 32 bits */
+ __be32 cmd;
+ __be32 data0; /* will be low portion if data > 32 bits */
/* 8 */
- u32 data1; /* will be high portion if data > 32 bits */
- u32 data2; /* currently unused.. */
+ __be32 data1; /* will be high portion if data > 32 bits */
+ __be32 data2; /* currently unused.. */
/* 16 */
struct mcp_dma_addr response_addr;
/* 24 */
@@ -31,8 +31,8 @@ struct mcp_cmd {
/* 8 Bytes */
struct mcp_cmd_response {
- u32 data;
- u32 result;
+ __be32 data;
+ __be32 result;
};
/*
@@ -73,10 +73,10 @@ union mcp_pso_or_cumlen {
/* 16 Bytes */
struct mcp_kreq_ether_send {
- u32 addr_high;
- u32 addr_low;
- u16 pseudo_hdr_offset;
- u16 length;
+ __be32 addr_high;
+ __be32 addr_low;
+ __be16 pseudo_hdr_offset;
+ __be16 length;
u8 pad;
u8 rdma_count;
u8 cksum_offset; /* where to start computing cksum */
@@ -85,8 +85,8 @@ struct mcp_kreq_ether_send {
/* 8 Bytes */
struct mcp_kreq_ether_recv {
- u32 addr_high;
- u32 addr_low;
+ __be32 addr_high;
+ __be32 addr_low;
};
/* Commands */
@@ -219,19 +219,19 @@ enum myri10ge_mcp_cmd_status {
struct mcp_irq_data {
/* add new counters at the beginning */
- u32 future_use[5];
- u32 dropped_multicast_filtered;
+ __be32 future_use[5];
+ __be32 dropped_multicast_filtered;
/* 40 Bytes */
- u32 send_done_count;
-
- u32 link_up;
- u32 dropped_link_overflow;
- u32 dropped_link_error_or_filtered;
- u32 dropped_runt;
- u32 dropped_overrun;
- u32 dropped_no_small_buffer;
- u32 dropped_no_big_buffer;
- u32 rdma_tags_available;
+ __be32 send_done_count;
+
+ __be32 link_up;
+ __be32 dropped_link_overflow;
+ __be32 dropped_link_error_or_filtered;
+ __be32 dropped_runt;
+ __be32 dropped_overrun;
+ __be32 dropped_no_small_buffer;
+ __be32 dropped_no_big_buffer;
+ __be32 rdma_tags_available;
u8 tx_stopped;
u8 link_down;
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index 487f7792fd46..16a810dd6d51 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -36,7 +36,7 @@
struct mcp_gen_header {
/* the first 4 fields are filled at compile time */
unsigned header_length;
- unsigned mcp_type;
+ __be32 mcp_type;
char version[128];
unsigned mcp_globals; /* pointer to mcp-type specific structure */
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 7747bfd99f91..ee26ef52289f 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -39,7 +39,6 @@ static char version[] =
#include <asm/auxio.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
-#include <asm/checksum.h>
#include "myri_sbus.h"
#include "myri_code.h"
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 787aa4221528..a5c4199e2754 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -867,7 +867,7 @@ static void cleanup_card(struct net_device *dev)
release_region(dev->base_addr, NE_IO_EXTENT);
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 5fccfea66d87..089b5bb702fc 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -813,7 +813,7 @@ static void cleanup_card(struct net_device *dev)
release_region(dev->base_addr, NE_IO_EXTENT);
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index d66328975425..1a6fed76d4cc 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -36,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/mm.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index bf58db29e2ed..69233f6aa05c 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -60,7 +60,6 @@ static struct netpoll np = {
.local_port = 6665,
.remote_port = 6666,
.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
- .drop = netpoll_queue,
};
static int configured = 0;
@@ -102,6 +101,8 @@ __setup("netconsole=", option_setup);
static int init_netconsole(void)
{
+ int err;
+
if(strlen(config))
option_setup(config);
@@ -110,8 +111,9 @@ static int init_netconsole(void)
return 0;
}
- if(netpoll_setup(&np))
- return -EINVAL;
+ err = netpoll_setup(&np);
+ if (err)
+ return err;
register_console(&netconsole);
printk(KERN_INFO "netconsole: network logging started\n");
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index d925053fe597..b5410bee5f21 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1,25 +1,25 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -63,40 +63,68 @@
#include "netxen_nic_hw.h"
-#define NETXEN_NIC_BUILD_NO "5"
-#define _NETXEN_NIC_LINUX_MAJOR 2
+#define NETXEN_NIC_BUILD_NO "1"
+#define _NETXEN_NIC_LINUX_MAJOR 3
#define _NETXEN_NIC_LINUX_MINOR 3
-#define _NETXEN_NIC_LINUX_SUBVERSION 59
-#define NETXEN_NIC_LINUX_VERSIONID "2.3.59" "-" NETXEN_NIC_BUILD_NO
-#define NETXEN_NIC_FW_VERSIONID "2.3.59"
+#define _NETXEN_NIC_LINUX_SUBVERSION 2
+#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO
+#define NETXEN_NIC_FW_VERSIONID "3.3.2"
#define RCV_DESC_RINGSIZE \
(sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
#define STATUS_DESC_RINGSIZE \
(sizeof(struct status_desc)* adapter->max_rx_desc_count)
+#define LRO_DESC_RINGSIZE \
+ (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
#define TX_RINGSIZE \
(sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
#define RCV_BUFFSIZE \
(sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
-#define NETXEN_NETDEV_STATUS 0x1
+#define NETXEN_NETDEV_STATUS 0x1
+#define NETXEN_RCV_PRODUCER_OFFSET 0
+#define NETXEN_RCV_PEG_DB_ID 2
+#define NETXEN_HOST_DUMMY_DMA_SIZE 1024
#define ADDR_IN_WINDOW1(off) \
((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
+/*
+ * In netxen_nic_down(), we must wait for any pending callback requests into
+ * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be
+ * reenabled right after it is deleted in netxen_nic_down(). FLUSH_SCHEDULED_WORK()
+ * does this synchronization.
+ *
+ * Normally, schedule_work()/flush_scheduled_work() could have worked, but
+ * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off()
+ * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a
+ * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause
+ * linkwatch_event() to be executed which also attempts to acquire the rtnl
+ * lock thus causing a deadlock.
+ */
+
+#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp)
+#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
+extern struct workqueue_struct *netxen_workq;
/*
* normalize a 64MB crb address to 32MB PCI window
* To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1
*/
-#define NETXEN_CRB_NORMAL(reg) \
- (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST
+#define NETXEN_CRB_NORMAL(reg) \
+ ((reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST)
#define NETXEN_CRB_NORMALIZE(adapter, reg) \
pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg))
+#define DB_NORMALIZE(adapter, off) \
+ (adapter->ahw.db_base + (off))
+
+#define NX_P2_C0 0x24
+#define NX_P2_C1 0x25
+
#define FIRST_PAGE_GROUP_START 0
-#define FIRST_PAGE_GROUP_END 0x400000
+#define FIRST_PAGE_GROUP_END 0x100000
#define SECOND_PAGE_GROUP_START 0x4000000
#define SECOND_PAGE_GROUP_END 0x66BC000
@@ -108,11 +136,13 @@
#define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START
#define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START
-#define MAX_RX_BUFFER_LENGTH 2000
+#define MAX_RX_BUFFER_LENGTH 1760
#define MAX_RX_JUMBO_BUFFER_LENGTH 9046
-#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN)
+#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512)
+#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2)
#define RX_JUMBO_DMA_MAP_LEN \
- (MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN)
+ (MAX_RX_JUMBO_BUFFER_LENGTH - 2)
+#define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2)
#define NETXEN_ROM_ROUNDUP 0x80000000ULL
/*
@@ -151,30 +181,38 @@ enum {
/* Host writes the following to notify that it has done the init-handshake */
#define PHAN_INITIALIZE_ACK 0xf00f
-#define NUM_RCV_DESC_RINGS 2 /* No of Rcv Descriptor contexts */
+#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */
/* descriptor types */
#define RCV_DESC_NORMAL 0x01
#define RCV_DESC_JUMBO 0x02
+#define RCV_DESC_LRO 0x04
#define RCV_DESC_NORMAL_CTXID 0
#define RCV_DESC_JUMBO_CTXID 1
+#define RCV_DESC_LRO_CTXID 2
#define RCV_DESC_TYPE(ID) \
- ((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL)
+ ((ID == RCV_DESC_JUMBO_CTXID) \
+ ? RCV_DESC_JUMBO \
+ : ((ID == RCV_DESC_LRO_CTXID) \
+ ? RCV_DESC_LRO : \
+ (RCV_DESC_NORMAL)))
#define MAX_CMD_DESCRIPTORS 1024
#define MAX_RCV_DESCRIPTORS 32768
-#define MAX_JUMBO_RCV_DESCRIPTORS 1024
+#define MAX_JUMBO_RCV_DESCRIPTORS 4096
+#define MAX_LRO_RCV_DESCRIPTORS 2048
#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
#define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS
-#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS)
#define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8)
-
+#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
+ MAX_LRO_RCV_DESCRIPTORS)
#define MIN_TX_COUNT 4096
#define MIN_RX_COUNT 4096
-
+#define NETXEN_CTX_SIGNATURE 0xdee0
+#define NETXEN_RCV_PRODUCER(ringid) (ringid)
#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
#define PHAN_PEG_RCV_INITIALIZED 0xff01
@@ -186,6 +224,67 @@ enum {
#define get_index_range(index,length,count) \
(((index) + (count)) & ((length) - 1))
+#define MPORT_SINGLE_FUNCTION_MODE 0x1111
+
+extern unsigned long long netxen_dma_mask;
+
+/*
+ * NetXen host-peg signal message structure
+ *
+ * Bit 0-1 : peg_id => 0x2 for tx and 01 for rx
+ * Bit 2 : priv_id => must be 1
+ * Bit 3-17 : count => for doorbell
+ * Bit 18-27 : ctx_id => Context id
+ * Bit 28-31 : opcode
+ */
+
+typedef u32 netxen_ctx_msg;
+
+#define _netxen_set_bits(config_word, start, bits, val) {\
+ unsigned long long mask = (((1ULL << (bits)) - 1) << (start)); \
+ unsigned long long value = (val); \
+ (config_word) &= ~mask; \
+ (config_word) |= (((value) << (start)) & mask); \
+}
+
+#define netxen_set_msg_peg_id(config_word, val) \
+ _netxen_set_bits(config_word, 0, 2, val)
+#define netxen_set_msg_privid(config_word) \
+ set_bit(2, (unsigned long*)&config_word)
+#define netxen_set_msg_count(config_word, val) \
+ _netxen_set_bits(config_word, 3, 15, val)
+#define netxen_set_msg_ctxid(config_word, val) \
+ _netxen_set_bits(config_word, 18, 10, val)
+#define netxen_set_msg_opcode(config_word, val) \
+ _netxen_set_bits(config_word, 28, 4, val)
+
+struct netxen_rcv_context {
+ u32 rcv_ring_addr_lo;
+ u32 rcv_ring_addr_hi;
+ u32 rcv_ring_size;
+ u32 rsrvd;
+};
+
+struct netxen_ring_ctx {
+
+ /* one command ring */
+ u64 cmd_consumer_offset;
+ u32 cmd_ring_addr_lo;
+ u32 cmd_ring_addr_hi;
+ u32 cmd_ring_size;
+ u32 rsrvd;
+
+ /* three receive rings */
+ struct netxen_rcv_context rcv_ctx[3];
+
+ /* one status ring */
+ u32 sts_ring_addr_lo;
+ u32 sts_ring_addr_hi;
+ u32 sts_ring_size;
+
+ u32 ctx_id;
+} __attribute__ ((aligned(64)));
+
/*
* Following data structures describe the descriptors that will be used.
* Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
@@ -203,22 +302,32 @@ enum {
#define FLAGS_IPSEC_SA_DELETE 0x08
#define FLAGS_VLAN_TAGGED 0x10
-#define CMD_DESC_TOTAL_LENGTH(cmd_desc) \
- ((cmd_desc)->length_tcp_hdr & 0x00FFFFFF)
-#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc) \
- (((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF)
-#define CMD_DESC_PORT(cmd_desc) ((cmd_desc)->port_ctxid & 0x0F)
-#define CMD_DESC_CTX_ID(cmd_desc) (((cmd_desc)->port_ctxid >> 4) & 0x0F)
+#define netxen_set_cmd_desc_port(cmd_desc, var) \
+ ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
-#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var) \
- ((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF))
-#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var) \
- ((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000))
-#define CMD_DESC_PORT_WRT(cmd_desc, var) \
- ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
+#define netxen_set_cmd_desc_flags(cmd_desc, val) \
+ _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val)
+#define netxen_set_cmd_desc_opcode(cmd_desc, val) \
+ _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val)
+
+#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \
+ _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val);
+#define netxen_set_cmd_desc_totallength(cmd_desc, val) \
+ _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val);
+
+#define netxen_get_cmd_desc_opcode(cmd_desc) \
+ (((cmd_desc)->flags_opcode >> 7) & 0x003F)
+#define netxen_get_cmd_desc_totallength(cmd_desc) \
+ (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF)
struct cmd_desc_type0 {
- u64 netxen_next; /* for fragments handled by Phantom */
+ u8 tcp_hdr_offset; /* For LSO only */
+ u8 ip_hdr_offset; /* For LSO only */
+ /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */
+ u16 flags_opcode;
+ /* Bit pattern: 0-7 total number of segments,
+ 8-31 Total size of the packet */
+ u32 num_of_buffers_total_length;
union {
struct {
u32 addr_low_part2;
@@ -227,13 +336,6 @@ struct cmd_desc_type0 {
u64 addr_buffer2;
};
- /* Bit pattern: 0-23 total length, 24-32 tcp header offset */
- u32 length_tcp_hdr;
- u8 ip_hdr_offset; /* For LSO only */
- u8 num_of_buffers; /* total number of segments */
- u8 flags; /* as defined above */
- u8 opcode;
-
u16 reference_handle; /* changed to u16 to add mss */
u16 mss; /* passed by NDIS_PACKET for LSO */
/* Bit pattern 0-3 port, 0-3 ctx id */
@@ -248,7 +350,6 @@ struct cmd_desc_type0 {
};
u64 addr_buffer3;
};
-
union {
struct {
u32 addr_low_part1;
@@ -270,6 +371,8 @@ struct cmd_desc_type0 {
u64 addr_buffer4;
};
+ u64 unused;
+
} __attribute__ ((aligned(64)));
/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
@@ -296,22 +399,49 @@ struct rcv_desc {
#define NETXEN_PROT_UNKNOWN (0)
/* Note: sizeof(status_desc) should always be a mutliple of 2 */
-#define STATUS_DESC_PORT(status_desc) \
- ((status_desc)->port_status_type_op & 0x0F)
-#define STATUS_DESC_STATUS(status_desc) \
- (((status_desc)->port_status_type_op >> 4) & 0x0F)
-#define STATUS_DESC_TYPE(status_desc) \
- (((status_desc)->port_status_type_op >> 8) & 0x0F)
-#define STATUS_DESC_OPCODE(status_desc) \
- (((status_desc)->port_status_type_op >> 12) & 0x0F)
+
+#define netxen_get_sts_desc_lro_cnt(status_desc) \
+ ((status_desc)->lro & 0x7F)
+#define netxen_get_sts_desc_lro_last_frag(status_desc) \
+ (((status_desc)->lro & 0x80) >> 7)
+
+#define netxen_get_sts_port(status_desc) \
+ ((status_desc)->status_desc_data & 0x0F)
+#define netxen_get_sts_status(status_desc) \
+ (((status_desc)->status_desc_data >> 4) & 0x0F)
+#define netxen_get_sts_type(status_desc) \
+ (((status_desc)->status_desc_data >> 8) & 0x0F)
+#define netxen_get_sts_totallength(status_desc) \
+ (((status_desc)->status_desc_data >> 12) & 0xFFFF)
+#define netxen_get_sts_refhandle(status_desc) \
+ (((status_desc)->status_desc_data >> 28) & 0xFFFF)
+#define netxen_get_sts_prot(status_desc) \
+ (((status_desc)->status_desc_data >> 44) & 0x0F)
+#define netxen_get_sts_owner(status_desc) \
+ (((status_desc)->status_desc_data >> 56) & 0x03)
+#define netxen_get_sts_opcode(status_desc) \
+ (((status_desc)->status_desc_data >> 58) & 0x03F)
+
+#define netxen_clear_sts_owner(status_desc) \
+ ((status_desc)->status_desc_data &= \
+ ~(((unsigned long long)3) << 56 ))
+#define netxen_set_sts_owner(status_desc, val) \
+ ((status_desc)->status_desc_data |= \
+ (((unsigned long long)((val) & 0x3)) << 56 ))
struct status_desc {
- /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */
- u16 port_status_type_op;
- u16 total_length; /* NIC mode */
- u16 reference_handle; /* handle for the associated packet */
- /* Bit pattern: 0-1 owner, 2-5 protocol */
- u16 owner; /* Owner of the descriptor */
+ /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+ 28-43 reference_handle, 44-47 protocol, 48-52 unused
+ 53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
+ u64 status_desc_data;
+ u32 hash_value;
+ u8 hash_type;
+ u8 msg_type;
+ u8 unused;
+ /* Bit pattern: 0-6 lro_count indicates frag sequence,
+ 7 last_frag indicates last frag */
+ u8 lro;
} __attribute__ ((aligned(8)));
enum {
@@ -559,11 +689,12 @@ typedef enum {
#define PRIMARY_START (BOOTLD_START)
#define FLASH_CRBINIT_SIZE (0x4000)
#define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info))
-#define FLASH_USER_SIZE (sizeof(netxen_user_info)/sizeof(u32))
+#define FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32))
#define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START)
#define NUM_PRIMARY_SECTORS (0x20)
#define NUM_CONFIG_SECTORS (1)
-#define PFX "netxen: "
+#define PFX "NetXen: "
+extern char netxen_nic_driver_name[];
/* Note: Make sure to not call this before adapter->port is valid */
#if !defined(NETXEN_DEBUG)
@@ -572,7 +703,7 @@ typedef enum {
#else
#define DPRINTK(klevel, fmt, args...) do { \
printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
- (adapter != NULL && adapter->port != NULL && \
+ (adapter != NULL && \
adapter->port[0] != NULL && \
adapter->port[0]->netdev != NULL) ? \
adapter->port[0]->netdev->name : NULL, \
@@ -609,7 +740,6 @@ struct netxen_cmd_buffer {
u8 frag_count;
unsigned long time_stamp;
u32 state;
- u32 no_of_descriptors;
};
/* In rx_buffer, we do not need multiple fragments as is a single buffer */
@@ -618,6 +748,9 @@ struct netxen_rx_buffer {
u64 dma;
u16 ref_handle;
u16 state;
+ u32 lro_expected_frags;
+ u32 lro_current_frags;
+ u32 lro_length;
};
/* Board types */
@@ -633,6 +766,8 @@ struct netxen_hardware_context {
void __iomem *pci_base0;
void __iomem *pci_base1;
void __iomem *pci_base2;
+ void __iomem *db_base;
+ unsigned long db_len;
u8 revision_id;
u16 board_type;
@@ -642,14 +777,13 @@ struct netxen_hardware_context {
u32 qg_linksup;
/* Address of cmd ring in Phantom */
struct cmd_desc_type0 *cmd_desc_head;
- char *pauseaddr;
struct pci_dev *cmd_desc_pdev;
dma_addr_t cmd_desc_phys_addr;
- dma_addr_t pause_physaddr;
- struct pci_dev *pause_pdev;
struct netxen_adapter *adapter;
};
+#define RCV_RING_LRO RCV_DESC_LRO
+
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
@@ -702,8 +836,13 @@ struct netxen_recv_context {
};
#define NETXEN_NIC_MSI_ENABLED 0x02
+#define NETXEN_DMA_MASK 0xfffffffe
+#define NETXEN_DB_MAPSIZE_BYTES 0x1000
-struct netxen_drvops;
+struct netxen_dummy_dma {
+ void *addr;
+ dma_addr_t phys_addr;
+};
struct netxen_adapter {
struct netxen_hardware_context ahw;
@@ -714,17 +853,19 @@ struct netxen_adapter {
spinlock_t lock;
struct work_struct watchdog_task;
struct work_struct tx_timeout_task;
+ struct net_device *netdev;
struct timer_list watchdog_timer;
u32 curr_window;
u32 cmd_producer;
- u32 cmd_consumer;
+ u32 *cmd_consumer;
u32 last_cmd_consumer;
u32 max_tx_desc_count;
u32 max_rx_desc_count;
u32 max_jumbo_rx_desc_count;
+ u32 max_lro_rx_desc_count;
/* Num of instances active on cmd buffer ring */
u32 proc_cmd_buf_counter;
@@ -746,8 +887,27 @@ struct netxen_adapter {
struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
int is_up;
- int work_done;
- struct netxen_drvops *ops;
+ int number;
+ struct netxen_dummy_dma dummy_dma;
+
+ /* Context interface shared between card and host */
+ struct netxen_ring_ctx *ctx_desc;
+ struct pci_dev *ctx_desc_pdev;
+ dma_addr_t ctx_desc_phys_addr;
+ int (*enable_phy_interrupts) (struct netxen_adapter *, int);
+ int (*disable_phy_interrupts) (struct netxen_adapter *, int);
+ void (*handle_phy_intr) (struct netxen_adapter *);
+ int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t);
+ int (*set_mtu) (struct netxen_port *, int);
+ int (*set_promisc) (struct netxen_adapter *, int,
+ netxen_niu_prom_mode_t);
+ int (*unset_promisc) (struct netxen_adapter *, int,
+ netxen_niu_prom_mode_t);
+ int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *);
+ int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val);
+ int (*init_port) (struct netxen_adapter *, int);
+ void (*init_niu) (struct netxen_adapter *);
+ int (*stop_port) (struct netxen_adapter *, int);
}; /* netxen_adapter structure */
/* Max number of xmit producer threads that can run simultaneously */
@@ -829,25 +989,6 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter,
return NULL;
}
-struct netxen_drvops {
- int (*enable_phy_interrupts) (struct netxen_adapter *, int);
- int (*disable_phy_interrupts) (struct netxen_adapter *, int);
- void (*handle_phy_intr) (struct netxen_adapter *);
- int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t);
- int (*set_mtu) (struct netxen_port *, int);
- int (*set_promisc) (struct netxen_adapter *, int,
- netxen_niu_prom_mode_t);
- int (*unset_promisc) (struct netxen_adapter *, int,
- netxen_niu_prom_mode_t);
- int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *);
- int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val);
- int (*init_port) (struct netxen_adapter *, int);
- void (*init_niu) (struct netxen_adapter *);
- int (*stop_port) (struct netxen_adapter *, int);
-};
-
-extern char netxen_nic_driver_name[];
-
int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter,
int port);
int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
@@ -886,10 +1027,20 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
int len);
int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
int len);
+int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
+ void *data, int len);
+int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
+ void *data, int len);
+int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter,
+ u64 off, void *data, int size);
+int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
+ u64 off, void *data, int size);
void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
unsigned long off, int data);
/* Functions from netxen_nic_init.c */
+void netxen_free_adapter_offload(struct netxen_adapter *adapter);
+int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
void netxen_load_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
@@ -921,10 +1072,12 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
struct netxen_port *port);
int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
-void netxen_watchdog_task(unsigned long v);
+void netxen_watchdog_task(struct work_struct *work);
void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
u32 ringid);
-void netxen_process_cmd_ring(unsigned long data);
+void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx,
+ u32 ringid);
+int netxen_process_cmd_ring(unsigned long data);
u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
void netxen_nic_set_multi(struct net_device *netdev);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1018,7 +1171,6 @@ static inline void get_brd_name_by_type(u32 type, char *name)
int netxen_is_flash_supported(struct netxen_adapter *adapter);
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
-
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
int *valp);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 9a914aeba5bc..2ab4885cc950 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -1,25 +1,25 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -118,7 +118,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
u32 fw_minor = 0;
u32 fw_build = 0;
- strncpy(drvinfo->driver, "netxen_nic", 32);
+ strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
NETXEN_FW_VERSION_MAJOR));
@@ -210,7 +210,6 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
(netxen_brdtype_t) boardinfo->board_type);
return -EIO;
-
}
return 0;
@@ -226,18 +225,18 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
/* read which mode */
if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
/* autonegotiation */
- if (adapter->ops->phy_write
- && adapter->ops->phy_write(adapter, port->portnum,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
- (__le32) ecmd->autoneg) != 0)
+ if (adapter->phy_write
+ && adapter->phy_write(adapter, port->portnum,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+ (__le32) ecmd->autoneg) != 0)
return -EIO;
else
port->link_autoneg = ecmd->autoneg;
- if (adapter->ops->phy_read
- && adapter->ops->phy_read(adapter, port->portnum,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) != 0)
+ if (adapter->phy_read
+ && adapter->phy_read(adapter, port->portnum,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+ &status) != 0)
return -EIO;
/* speed */
@@ -257,10 +256,10 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
netxen_clear_phy_duplex(status);
if (ecmd->duplex == DUPLEX_FULL)
netxen_set_phy_duplex(status);
- if (adapter->ops->phy_write
- && adapter->ops->phy_write(adapter, port->portnum,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- *((int *)&status)) != 0)
+ if (adapter->phy_write
+ && adapter->phy_write(adapter, port->portnum,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+ *((int *)&status)) != 0)
return -EIO;
else {
port->link_speed = ecmd->speed;
@@ -422,10 +421,10 @@ static u32 netxen_nic_get_link(struct net_device *dev)
/* read which mode */
if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
- if (adapter->ops->phy_read
- && adapter->ops->phy_read(adapter, port->portnum,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) != 0)
+ if (adapter->phy_read
+ && adapter->phy_read(adapter, port->portnum,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+ &status) != 0)
return -EIO;
else
return (netxen_get_phy_link(status));
@@ -460,20 +459,22 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
{
struct netxen_port *port = netdev_priv(dev);
struct netxen_adapter *adapter = port->adapter;
- int i, j;
+ int i;
ring->rx_pending = 0;
+ ring->rx_jumbo_pending = 0;
for (i = 0; i < MAX_RCV_CTX; ++i) {
- for (j = 0; j < NUM_RCV_DESC_RINGS; j++)
- ring->rx_pending +=
- adapter->recv_ctx[i].rcv_desc[j].rcv_pending;
+ ring->rx_pending += adapter->recv_ctx[i].
+ rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending;
+ ring->rx_jumbo_pending += adapter->recv_ctx[i].
+ rcv_desc[RCV_DESC_JUMBO_CTXID].rcv_pending;
}
ring->rx_max_pending = adapter->max_rx_desc_count;
ring->tx_max_pending = adapter->max_tx_desc_count;
+ ring->rx_jumbo_max_pending = adapter->max_jumbo_rx_desc_count;
ring->rx_mini_max_pending = 0;
ring->rx_mini_pending = 0;
- ring->rx_jumbo_max_pending = 0;
ring->rx_jumbo_pending = 0;
}
@@ -526,10 +527,10 @@ netxen_nic_set_pauseparam(struct net_device *dev,
*(u32 *) (&val));
/* set autoneg */
autoneg = pause->autoneg;
- if (adapter->ops->phy_write
- && adapter->ops->phy_write(adapter, port->portnum,
- NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
- (__le32) autoneg) != 0)
+ if (adapter->phy_write
+ && adapter->phy_write(adapter, port->portnum,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+ (__le32) autoneg) != 0)
return -EIO;
else {
port->link_autoneg = pause->autoneg;
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 72c6ec4ee2a0..fe8b675f9e72 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 105c24f0ad4c..9147b6048dfb 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -42,7 +42,7 @@
#define NETXEN_FLASH_BASE (BOOTLD_START)
#define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE)
-#define NETXEN_MAX_MTU 8000
+#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
#define NETXEN_MIN_MTU 64
#define NETXEN_ETH_FCS_SIZE 4
#define NETXEN_ENET_HEADER_SIZE 14
@@ -81,8 +81,8 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
DPRINTK(INFO, "valid ether addr\n");
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- if (adapter->ops->macaddr_set)
- adapter->ops->macaddr_set(port, addr->sa_data);
+ if (adapter->macaddr_set)
+ adapter->macaddr_set(port, addr->sa_data);
return 0;
}
@@ -99,17 +99,17 @@ void netxen_nic_set_multi(struct net_device *netdev)
mc_ptr = netdev->mc_list;
if (netdev->flags & IFF_PROMISC) {
- if (adapter->ops->set_promisc)
- adapter->ops->set_promisc(adapter,
- port->portnum,
- NETXEN_NIU_PROMISC_MODE);
+ if (adapter->set_promisc)
+ adapter->set_promisc(adapter,
+ port->portnum,
+ NETXEN_NIU_PROMISC_MODE);
} else {
- if (adapter->ops->unset_promisc &&
+ if (adapter->unset_promisc &&
adapter->ahw.boardcfg.board_type
!= NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
- adapter->ops->unset_promisc(adapter,
- port->portnum,
- NETXEN_NIU_NON_PROMISC_MODE);
+ adapter->unset_promisc(adapter,
+ port->portnum,
+ NETXEN_NIU_NON_PROMISC_MODE);
}
if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03);
@@ -160,8 +160,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
return -EINVAL;
}
- if (adapter->ops->set_mtu)
- adapter->ops->set_mtu(port, mtu);
+ if (adapter->set_mtu)
+ adapter->set_mtu(port, mtu);
netdev->mtu = mtu;
return 0;
@@ -176,22 +176,18 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
struct netxen_hardware_context *hw = &adapter->ahw;
u32 state = 0;
void *addr;
- void *pause_addr;
int loops = 0, err = 0;
int ctx, ring;
u32 card_cmdring = 0;
- struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
struct netxen_recv_context *recv_ctx;
struct netxen_rcv_desc_ctx *rcv_desc;
- DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE,
+ DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
- DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM,
+ DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM,
pci_base_offset(adapter, NETXEN_CRB_CAM));
- DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE,
+ DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
- DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1,
- pci_base_offset(adapter, NIC_CRB_BASE_PORT1));
/* Window 1 call */
card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
@@ -226,33 +222,42 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
addr = netxen_alloc(adapter->ahw.pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
- &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev);
+ sizeof(struct netxen_ring_ctx) +
+ sizeof(uint32_t),
+ (dma_addr_t *) & adapter->ctx_desc_phys_addr,
+ &adapter->ctx_desc_pdev);
+ printk("ctx_desc_phys_addr: 0x%llx\n",
+ (u64) adapter->ctx_desc_phys_addr);
if (addr == NULL) {
DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ return err;
}
+ memset(addr, 0, sizeof(struct netxen_ring_ctx));
+ adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
+ adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr
+ + sizeof(struct netxen_ring_ctx);
+ adapter->cmd_consumer = (uint32_t *) (((char *)addr) +
+ sizeof(struct netxen_ring_ctx));
+
+ addr = pci_alloc_consistent(adapter->ahw.pdev,
+ sizeof(struct cmd_desc_type0) *
+ adapter->max_tx_desc_count,
+ (dma_addr_t *) & hw->cmd_desc_phys_addr);
+ printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
- pause_addr = netxen_alloc(adapter->ahw.pdev, 512,
- (dma_addr_t *) & hw->pause_physaddr,
- &hw->pause_pdev);
- if (pause_addr == NULL) {
- DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n");
+ if (addr == NULL) {
+ DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+ netxen_free_hw_resources(adapter);
return -ENOMEM;
}
- hw->pauseaddr = (char *)pause_addr;
- {
- u64 *ptr = (u64 *) pause_addr;
- *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
- *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
- *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR;
- *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
- *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1;
- *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2;
- }
+ adapter->ctx_desc->cmd_ring_addr_lo =
+ hw->cmd_desc_phys_addr & 0xffffffffUL;
+ adapter->ctx_desc->cmd_ring_addr_hi =
+ ((u64) hw->cmd_desc_phys_addr >> 32);
+ adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count;
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
@@ -273,6 +278,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
return err;
}
rcv_desc->desc_head = (struct rcv_desc *)addr;
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo =
+ rcv_desc->phys_addr & 0xffffffffUL;
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi =
+ ((u64) rcv_desc->phys_addr >> 32);
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+ rcv_desc->max_rx_desc_count;
}
addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
@@ -286,47 +297,21 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
return err;
}
recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
- for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
- rcv_desc = &recv_ctx->rcv_desc[ring];
- rcv_desc_crb =
- &recv_crb_registers[ctx].rcv_desc_crb[ring];
- DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
- ring, rcv_desc_crb->crb_globalrcv_ring);
- /* Window = 1 */
- writel(lower32(rcv_desc->phys_addr),
- NETXEN_CRB_NORMALIZE(adapter,
- rcv_desc_crb->
- crb_globalrcv_ring));
- DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x"
- " val 0x%llx,"
- " virt %p\n", ctx,
- rcv_desc_crb->crb_globalrcv_ring,
- (unsigned long long)rcv_desc->phys_addr,
- +rcv_desc->desc_head);
- }
+ adapter->ctx_desc->sts_ring_addr_lo =
+ recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL;
+ adapter->ctx_desc->sts_ring_addr_hi =
+ ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32);
+ adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count;
- /* Window = 1 */
- writel(lower32(recv_ctx->rcv_status_desc_phys_addr),
- NETXEN_CRB_NORMALIZE(adapter,
- recv_crb_registers[ctx].
- crb_rcvstatus_ring));
- DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x,"
- " val 0x%x,virt%p\n",
- ctx,
- recv_crb_registers[ctx].crb_rcvstatus_ring,
- (unsigned long long)recv_ctx->rcv_status_desc_phys_addr,
- recv_ctx->rcv_status_desc_head);
}
/* Window = 1 */
- writel(lower32(hw->pause_physaddr),
- NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO));
- writel(upper32(hw->pause_physaddr),
- NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI));
-
- writel(lower32(hw->cmd_desc_phys_addr),
- NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
- writel(upper32(hw->cmd_desc_phys_addr),
- NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI));
+
+ writel(lower32(adapter->ctx_desc_phys_addr),
+ NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO));
+ writel(upper32(adapter->ctx_desc_phys_addr),
+ NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI));
+ writel(NETXEN_CTX_SIGNATURE,
+ NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
return err;
}
@@ -336,6 +321,15 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
struct netxen_rcv_desc_ctx *rcv_desc;
int ctx, ring;
+ if (adapter->ctx_desc != NULL) {
+ pci_free_consistent(adapter->ctx_desc_pdev,
+ sizeof(struct netxen_ring_ctx) +
+ sizeof(uint32_t),
+ adapter->ctx_desc,
+ adapter->ctx_desc_phys_addr);
+ adapter->ctx_desc = NULL;
+ }
+
if (adapter->ahw.cmd_desc_head != NULL) {
pci_free_consistent(adapter->ahw.cmd_desc_pdev,
sizeof(struct cmd_desc_type0) *
@@ -344,11 +338,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
adapter->ahw.cmd_desc_phys_addr);
adapter->ahw.cmd_desc_head = NULL;
}
- if (adapter->ahw.pauseaddr != NULL) {
- pci_free_consistent(adapter->ahw.pause_pdev, 512,
- adapter->ahw.pauseaddr,
- adapter->ahw.pause_physaddr);
- adapter->ahw.pauseaddr = NULL;
+ /* Special handling: there are 2 ports on this board */
+ if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
+ adapter->ahw.max_ports = 2;
}
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -383,19 +375,22 @@ void netxen_tso_check(struct netxen_adapter *adapter,
desc->total_hdr_length = sizeof(struct ethhdr) +
((skb->nh.iph)->ihl * sizeof(u32)) +
((skb->h.th)->doff * sizeof(u32));
- desc->opcode = TX_TCP_LSO;
+ netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
} else if (skb->ip_summed == CHECKSUM_COMPLETE) {
if (skb->nh.iph->protocol == IPPROTO_TCP) {
- desc->opcode = TX_TCP_PKT;
+ netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
- desc->opcode = TX_UDP_PKT;
+ netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
} else {
return;
}
}
adapter->stats.xmitcsummed++;
- CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
- desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
+ desc->tcp_hdr_offset = skb->h.raw - skb->data;
+ netxen_set_cmd_desc_totallength(desc,
+ cpu_to_le32
+ (netxen_get_cmd_desc_totallength
+ (desc)));
desc->ip_hdr_offset = skb->nh.raw - skb->data;
}
@@ -648,7 +643,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
addr = NETXEN_CRB_NORMALIZE(adapter, off);
DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
- pci_base(adapter, off), off, addr);
+ pci_base(adapter, off), off, addr, val);
writel(val, addr);
}
@@ -660,7 +655,7 @@ int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
addr = NETXEN_CRB_NORMALIZE(adapter, off);
DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
- adapter->ahw.pci_base, off, addr);
+ pci_base(adapter, off), off, addr);
val = readl(addr);
writel(val, addr);
@@ -848,8 +843,8 @@ void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
port = adapter->port[port_nr];
- if (adapter->ops->stop_port)
- adapter->ops->stop_port(adapter, port->portnum);
+ if (adapter->stop_port)
+ adapter->stop_port(adapter, port->portnum);
}
}
@@ -873,13 +868,13 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
{
struct netxen_adapter *adapter = port->adapter;
__le32 status;
- u16 autoneg;
+ __le32 autoneg;
__le32 mode;
netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */
- if (adapter->ops->phy_read
- && adapter->ops->
+ if (adapter->phy_read
+ && adapter->
phy_read(adapter, port->portnum,
NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
&status) == 0) {
@@ -909,11 +904,11 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
port->link_duplex = -1;
break;
}
- if (adapter->ops->phy_read
- && adapter->ops->
+ if (adapter->phy_read
+ && adapter->
phy_read(adapter, port->portnum,
NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
- (__le32 *) & autoneg) != 0)
+ &autoneg) != 0)
port->link_autoneg = autoneg;
} else
goto link_down;
@@ -1008,3 +1003,291 @@ int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
netxen_nic_hw_read_wx(adapter, off, &data, 4);
return data;
}
+
+int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
+ void *data, int len)
+{
+ void *addr;
+ u64 offset = off;
+ u8 *mem_ptr = NULL;
+ unsigned long mem_base;
+ unsigned long mem_page;
+
+ if (ADDR_IN_WINDOW1(off)) {
+ addr = NETXEN_CRB_NORMALIZE(adapter, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ offset = NETXEN_CRB_NORMAL(off);
+ mem_page = offset & PAGE_MASK;
+ if (mem_page != ((offset + len - 1) & PAGE_MASK))
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ return 1;
+ }
+ addr = mem_ptr;
+ addr += offset & (PAGE_SIZE - 1);
+ }
+ } else {
+ addr = pci_base_offset(adapter, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ mem_page = off & PAGE_MASK;
+ if (mem_page != ((off + len - 1) & PAGE_MASK))
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ return 1;
+ }
+ addr = mem_ptr;
+ addr += off & (PAGE_SIZE - 1);
+ }
+ netxen_nic_pci_change_crbwindow(adapter, 0);
+ }
+ switch (len) {
+ case 1:
+ writeb(*(u8 *) data, addr);
+ break;
+ case 2:
+ writew(*(u16 *) data, addr);
+ break;
+ case 4:
+ writel(*(u32 *) data, addr);
+ break;
+ case 8:
+ writeq(*(u64 *) data, addr);
+ break;
+ default:
+ DPRINTK(INFO,
+ "writing data %lx to offset %llx, num words=%d\n",
+ *(unsigned long *)data, off, (len >> 3));
+
+ netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
+ (len >> 3));
+ break;
+ }
+
+ if (!ADDR_IN_WINDOW1(off))
+ netxen_nic_pci_change_crbwindow(adapter, 1);
+ if (mem_ptr)
+ iounmap(mem_ptr);
+ return 0;
+}
+
+int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
+ void *data, int len)
+{
+ void *addr;
+ u64 offset;
+ u8 *mem_ptr = NULL;
+ unsigned long mem_base;
+ unsigned long mem_page;
+
+ if (ADDR_IN_WINDOW1(off)) {
+ addr = NETXEN_CRB_NORMALIZE(adapter, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ offset = NETXEN_CRB_NORMAL(off);
+ mem_page = offset & PAGE_MASK;
+ if (mem_page != ((offset + len - 1) & PAGE_MASK))
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ *(u8 *) data = 0;
+ return 1;
+ }
+ addr = mem_ptr;
+ addr += offset & (PAGE_SIZE - 1);
+ }
+ } else {
+ addr = pci_base_offset(adapter, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ mem_page = off & PAGE_MASK;
+ if (mem_page != ((off + len - 1) & PAGE_MASK))
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr =
+ ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL)
+ return 1;
+ addr = mem_ptr;
+ addr += off & (PAGE_SIZE - 1);
+ }
+ netxen_nic_pci_change_crbwindow(adapter, 0);
+ }
+ switch (len) {
+ case 1:
+ *(u8 *) data = readb(addr);
+ break;
+ case 2:
+ *(u16 *) data = readw(addr);
+ break;
+ case 4:
+ *(u32 *) data = readl(addr);
+ break;
+ case 8:
+ *(u64 *) data = readq(addr);
+ break;
+ default:
+ netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
+ (len >> 3));
+ break;
+ }
+ if (!ADDR_IN_WINDOW1(off))
+ netxen_nic_pci_change_crbwindow(adapter, 1);
+ if (mem_ptr)
+ iounmap(mem_ptr);
+ return 0;
+}
+
+int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off,
+ void *data, int size)
+{
+ void *addr;
+ int ret = 0;
+ u8 *mem_ptr = NULL;
+ unsigned long mem_base;
+ unsigned long mem_page;
+
+ if (data == NULL || off > (128 * 1024 * 1024)) {
+ printk(KERN_ERR "%s: data: %p off:%llx\n",
+ netxen_nic_driver_name, data, off);
+ return 1;
+ }
+ off = netxen_nic_pci_set_window(adapter, off);
+ /* Corner case : Malicious user tried to break the driver by reading
+ last few bytes in ranges and tries to read further addresses.
+ */
+ if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
+ printk(KERN_ERR "%s: Invalid access to memory address range"
+ " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
+ off + size);
+ return 1;
+ }
+ addr = pci_base_offset(adapter, off);
+ DPRINTK(INFO, "writing data %llx to offset %llx\n",
+ *(unsigned long long *)data, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ mem_page = off & PAGE_MASK;
+ /* Map two pages whenever user tries to access addresses in two
+ consecutive pages.
+ */
+ if (mem_page != ((off + size - 1) & PAGE_MASK))
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ return 1;
+ }
+ addr = mem_ptr;
+ addr += off & (PAGE_SIZE - 1);
+ }
+ switch (size) {
+ case 1:
+ writeb(*(u8 *) data, addr);
+ break;
+ case 2:
+ writew(*(u16 *) data, addr);
+ break;
+ case 4:
+ writel(*(u32 *) data, addr);
+ break;
+ case 8:
+ writeq(*(u64 *) data, addr);
+ break;
+ default:
+ DPRINTK(INFO,
+ "writing data %lx to offset %llx, num words=%d\n",
+ *(unsigned long *)data, off, (size >> 3));
+
+ netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
+ (size >> 3));
+ break;
+ }
+
+ if (mem_ptr)
+ iounmap(mem_ptr);
+ DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data);
+
+ return ret;
+}
+
+int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
+ u64 off, void *data, int size)
+{
+ void *addr;
+ int ret = 0;
+ u8 *mem_ptr = NULL;
+ unsigned long mem_base;
+ unsigned long mem_page;
+
+ if (data == NULL || off > (128 * 1024 * 1024)) {
+ printk(KERN_ERR "%s: data: %p off:%llx\n",
+ netxen_nic_driver_name, data, off);
+ return 1;
+ }
+ off = netxen_nic_pci_set_window(adapter, off);
+ /* Corner case : Malicious user tried to break the driver by reading
+ last few bytes in ranges and tries to read further addresses.
+ */
+ if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
+ printk(KERN_ERR "%s: Invalid access to memory address range"
+ " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
+ off + size);
+ return 1;
+ }
+ addr = pci_base_offset(adapter, off);
+ if (!addr) {
+ mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+ mem_page = off & PAGE_MASK;
+ /* Map two pages whenever user tries to access addresses in two
+ consecutive pages.
+ */
+ if (mem_page != ((off + size - 1) & PAGE_MASK))
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ *(u8 *) data = 0;
+ return 1;
+ }
+ addr = mem_ptr;
+ addr += off & (PAGE_SIZE - 1);
+ }
+ switch (size) {
+ case 1:
+ *(u8 *) data = readb(addr);
+ break;
+ case 2:
+ *(u16 *) data = readw(addr);
+ break;
+ case 4:
+ *(u32 *) data = readl(addr);
+ break;
+ case 8:
+ *(u64 *) data = readq(addr);
+ break;
+ default:
+ netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
+ (size >> 3));
+ break;
+ }
+
+ if (mem_ptr)
+ iounmap(mem_ptr);
+ DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data);
+
+ return ret;
+}
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index 201a636b7ab8..0685633a9c1e 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -83,8 +83,8 @@ struct netxen_adapter;
#define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20)
#define NETXEN_NIC_LOCKED_READ_REG(X, Y) \
- addr = pci_base_offset(adapter, (X)); \
- *(u32 *)Y = readl(addr);
+ addr = pci_base_offset(adapter, X); \
+ *(u32 *)Y = readl((void __iomem*) addr);
struct netxen_port;
void netxen_nic_set_link_parameters(struct netxen_port *port);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 0dca029bc3e5..290145ec08e7 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1,25 +1,25 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -137,6 +137,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
return err;
}
/* Window 1 call */
+ writel(MPORT_SINGLE_FUNCTION_MODE,
+ NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
writel(PHAN_INITIALIZE_ACK,
NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
@@ -184,15 +186,12 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
for (i = 0; i < num_rx_bufs; i++) {
rx_buf->ref_handle = i;
rx_buf->state = NETXEN_BUFFER_FREE;
-
DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
"%p\n", ctxid, i, rx_buf);
rx_buf++;
}
}
}
- DPRINTK(INFO, "initialized buffers for %s and %s\n",
- "adapter->free_cmd_buf_list", "adapter->free_rxbuf");
}
void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
@@ -212,37 +211,36 @@ void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
- struct netxen_drvops *ops = adapter->ops;
switch (adapter->ahw.board_type) {
case NETXEN_NIC_GBE:
- ops->enable_phy_interrupts =
+ adapter->enable_phy_interrupts =
netxen_niu_gbe_enable_phy_interrupts;
- ops->disable_phy_interrupts =
+ adapter->disable_phy_interrupts =
netxen_niu_gbe_disable_phy_interrupts;
- ops->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
- ops->macaddr_set = netxen_niu_macaddr_set;
- ops->set_mtu = netxen_nic_set_mtu_gb;
- ops->set_promisc = netxen_niu_set_promiscuous_mode;
- ops->unset_promisc = netxen_niu_set_promiscuous_mode;
- ops->phy_read = netxen_niu_gbe_phy_read;
- ops->phy_write = netxen_niu_gbe_phy_write;
- ops->init_port = netxen_niu_gbe_init_port;
- ops->init_niu = netxen_nic_init_niu_gb;
- ops->stop_port = netxen_niu_disable_gbe_port;
+ adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
+ adapter->macaddr_set = netxen_niu_macaddr_set;
+ adapter->set_mtu = netxen_nic_set_mtu_gb;
+ adapter->set_promisc = netxen_niu_set_promiscuous_mode;
+ adapter->unset_promisc = netxen_niu_set_promiscuous_mode;
+ adapter->phy_read = netxen_niu_gbe_phy_read;
+ adapter->phy_write = netxen_niu_gbe_phy_write;
+ adapter->init_port = netxen_niu_gbe_init_port;
+ adapter->init_niu = netxen_nic_init_niu_gb;
+ adapter->stop_port = netxen_niu_disable_gbe_port;
break;
case NETXEN_NIC_XGBE:
- ops->enable_phy_interrupts =
+ adapter->enable_phy_interrupts =
netxen_niu_xgbe_enable_phy_interrupts;
- ops->disable_phy_interrupts =
+ adapter->disable_phy_interrupts =
netxen_niu_xgbe_disable_phy_interrupts;
- ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
- ops->macaddr_set = netxen_niu_xg_macaddr_set;
- ops->set_mtu = netxen_nic_set_mtu_xgb;
- ops->init_port = netxen_niu_xg_init_port;
- ops->set_promisc = netxen_niu_xg_set_promiscuous_mode;
- ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
- ops->stop_port = netxen_niu_disable_xg_port;
+ adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
+ adapter->macaddr_set = netxen_niu_xg_macaddr_set;
+ adapter->set_mtu = netxen_nic_set_mtu_xgb;
+ adapter->init_port = netxen_niu_xg_init_port;
+ adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
+ adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
+ adapter->stop_port = netxen_niu_disable_xg_port;
break;
default:
@@ -383,8 +381,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter)
return 0;
}
-static inline int do_rom_fast_write(struct netxen_adapter *adapter,
- int addr, int data)
+static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
+ int data)
{
if (netxen_rom_wren(adapter)) {
return -1;
@@ -622,6 +620,43 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
return 0;
}
+int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
+{
+ uint64_t addr;
+ uint32_t hi;
+ uint32_t lo;
+
+ adapter->dummy_dma.addr =
+ pci_alloc_consistent(adapter->ahw.pdev,
+ NETXEN_HOST_DUMMY_DMA_SIZE,
+ &adapter->dummy_dma.phys_addr);
+ if (adapter->dummy_dma.addr == NULL) {
+ printk("%s: ERROR: Could not allocate dummy DMA memory\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ addr = (uint64_t) adapter->dummy_dma.phys_addr;
+ hi = (addr >> 32) & 0xffffffff;
+ lo = addr & 0xffffffff;
+
+ writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI));
+ writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO));
+
+ return 0;
+}
+
+void netxen_free_adapter_offload(struct netxen_adapter *adapter)
+{
+ if (adapter->dummy_dma.addr) {
+ pci_free_consistent(adapter->ahw.pdev,
+ NETXEN_HOST_DUMMY_DMA_SIZE,
+ adapter->dummy_dma.addr,
+ adapter->dummy_dma.phys_addr);
+ adapter->dummy_dma.addr = NULL;
+ }
+}
+
void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
{
u32 val = 0;
@@ -656,7 +691,8 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
desc_head = recv_ctx->rcv_status_desc_head;
desc = &desc_head[consumer];
- if (((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST))
+ if (((le16_to_cpu(netxen_get_sts_owner(desc)))
+ & STATUS_OWNER_HOST))
return 1;
}
@@ -710,12 +746,13 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
return rv;
}
-void netxen_watchdog_task(unsigned long v)
+void netxen_watchdog_task(struct work_struct *work)
{
int port_num;
struct netxen_port *port;
struct net_device *netdev;
- struct netxen_adapter *adapter = (struct netxen_adapter *)v;
+ struct netxen_adapter *adapter =
+ container_of(work, struct netxen_adapter, watchdog_task);
if (netxen_nic_check_temp(adapter))
return;
@@ -734,8 +771,8 @@ void netxen_watchdog_task(unsigned long v)
netif_wake_queue(netdev);
}
- if (adapter->ops->handle_phy_intr)
- adapter->ops->handle_phy_intr(adapter);
+ if (adapter->handle_phy_intr)
+ adapter->handle_phy_intr(adapter);
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
@@ -748,19 +785,19 @@ void
netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
struct status_desc *desc)
{
- struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)];
+ struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)];
struct pci_dev *pdev = port->pdev;
struct net_device *netdev = port->netdev;
- int index = le16_to_cpu(desc->reference_handle);
+ int index = le16_to_cpu(netxen_get_sts_refhandle(desc));
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
struct netxen_rx_buffer *buffer;
struct sk_buff *skb;
- u32 length = le16_to_cpu(desc->total_length);
+ u32 length = le16_to_cpu(netxen_get_sts_totallength(desc));
u32 desc_ctx;
struct netxen_rcv_desc_ctx *rcv_desc;
int ret;
- desc_ctx = STATUS_DESC_TYPE(desc);
+ desc_ctx = netxen_get_sts_type(desc);
if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
printk("%s: %s Bad Rcv descriptor ring\n",
netxen_nic_driver_name, netdev->name);
@@ -768,20 +805,49 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
}
rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
+ if (unlikely(index > rcv_desc->max_rx_desc_count)) {
+ DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
+ index, rcv_desc->max_rx_desc_count);
+ return;
+ }
buffer = &rcv_desc->rx_buf_arr[index];
+ if (desc_ctx == RCV_DESC_LRO_CTXID) {
+ buffer->lro_current_frags++;
+ if (netxen_get_sts_desc_lro_last_frag(desc)) {
+ buffer->lro_expected_frags =
+ netxen_get_sts_desc_lro_cnt(desc);
+ buffer->lro_length = length;
+ }
+ if (buffer->lro_current_frags != buffer->lro_expected_frags) {
+ if (buffer->lro_expected_frags != 0) {
+ printk("LRO: (refhandle:%x) recv frag."
+ "wait for last. flags: %x expected:%d"
+ "have:%d\n", index,
+ netxen_get_sts_desc_lro_last_frag(desc),
+ buffer->lro_expected_frags,
+ buffer->lro_current_frags);
+ }
+ return;
+ }
+ }
pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
PCI_DMA_FROMDEVICE);
skb = (struct sk_buff *)buffer->skb;
- if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) {
+ if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) {
port->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else
- skb->ip_summed = CHECKSUM_NONE;
+ }
skb->dev = netdev;
- skb_put(skb, length);
+ if (desc_ctx == RCV_DESC_LRO_CTXID) {
+ /* True length was only available on the last pkt */
+ skb_put(skb, buffer->lro_length);
+ } else {
+ skb_put(skb, length);
+ }
+
skb->protocol = eth_type_trans(skb, netdev);
ret = netif_receive_skb(skb);
@@ -827,6 +893,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
adapter->stats.post_called++;
buffer->skb = NULL;
buffer->state = NETXEN_BUFFER_FREE;
+ buffer->lro_current_frags = 0;
+ buffer->lro_expected_frags = 0;
port->stats.no_rcv++;
port->stats.rxbytes += length;
@@ -839,6 +907,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
struct status_desc *desc; /* used to read status desc here */
u32 consumer = recv_ctx->status_rx_consumer;
+ u32 producer = 0;
int count = 0, ring;
DPRINTK(INFO, "procesing receive\n");
@@ -850,18 +919,22 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
*/
while (count < max) {
desc = &desc_head[consumer];
- if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) {
- DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
+ if (!
+ (le16_to_cpu(netxen_get_sts_owner(desc)) &
+ STATUS_OWNER_HOST)) {
+ DPRINTK(ERR, "desc %p ownedby %x\n", desc,
+ netxen_get_sts_owner(desc));
break;
}
netxen_process_rcv(adapter, ctxid, desc);
- desc->owner = STATUS_OWNER_PHANTOM;
+ netxen_clear_sts_owner(desc);
+ netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
count++;
}
if (count) {
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
- netxen_post_rx_buffers(adapter, ctxid, ring);
+ netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
}
}
@@ -869,6 +942,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
if (count) {
adapter->stats.process_rcv++;
recv_ctx->status_rx_consumer = consumer;
+ recv_ctx->status_rx_producer = producer;
/* Window = 1 */
writel(consumer,
@@ -881,12 +955,13 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
}
/* Process Command status ring */
-void netxen_process_cmd_ring(unsigned long data)
+int netxen_process_cmd_ring(unsigned long data)
{
u32 last_consumer;
u32 consumer;
struct netxen_adapter *adapter = (struct netxen_adapter *)data;
- int count = 0;
+ int count1 = 0;
+ int count2 = 0;
struct netxen_cmd_buffer *buffer;
struct netxen_port *port; /* port #1 */
struct netxen_port *nport;
@@ -895,6 +970,7 @@ void netxen_process_cmd_ring(unsigned long data)
u32 i;
struct sk_buff *skb = NULL;
int p;
+ int done;
spin_lock(&adapter->tx_lock);
last_consumer = adapter->last_cmd_consumer;
@@ -904,14 +980,13 @@ void netxen_process_cmd_ring(unsigned long data)
* number as part of the descriptor. This way we will be able to get
* the netdev which is associated with that device.
*/
- consumer =
- readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
+ consumer = *(adapter->cmd_consumer);
if (last_consumer == consumer) { /* Ring is empty */
DPRINTK(INFO, "last_consumer %d == consumer %d\n",
last_consumer, consumer);
spin_unlock(&adapter->tx_lock);
- return;
+ return 1;
}
adapter->proc_cmd_buf_counter++;
@@ -922,7 +997,7 @@ void netxen_process_cmd_ring(unsigned long data)
*/
spin_unlock(&adapter->tx_lock);
- while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) {
+ while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
buffer = &adapter->cmd_buf_arr[last_consumer];
port = adapter->port[buffer->port];
pdev = port->pdev;
@@ -948,24 +1023,25 @@ void netxen_process_cmd_ring(unsigned long data)
&& netif_carrier_ok(port->netdev))
&& ((jiffies - port->netdev->trans_start) >
port->netdev->watchdog_timeo)) {
- schedule_work(&port->adapter->tx_timeout_task);
+ SCHEDULE_WORK(port->adapter->tx_timeout_task
+ + port->portnum);
}
last_consumer = get_next_index(last_consumer,
adapter->max_tx_desc_count);
- count++;
+ count1++;
}
- adapter->stats.noxmitdone += count;
+ adapter->stats.noxmitdone += count1;
- count = 0;
+ count2 = 0;
spin_lock(&adapter->tx_lock);
if ((--adapter->proc_cmd_buf_counter) == 0) {
adapter->last_cmd_consumer = last_consumer;
while ((adapter->last_cmd_consumer != consumer)
- && (count < MAX_STATUS_HANDLE)) {
+ && (count2 < MAX_STATUS_HANDLE)) {
buffer =
&adapter->cmd_buf_arr[adapter->last_cmd_consumer];
- count++;
+ count2++;
if (buffer->skb)
break;
else
@@ -974,7 +1050,7 @@ void netxen_process_cmd_ring(unsigned long data)
adapter->max_tx_desc_count);
}
}
- if (count) {
+ if (count1 || count2) {
for (p = 0; p < adapter->ahw.max_ports; p++) {
nport = adapter->port[p];
if (netif_queue_stopped(nport->netdev)
@@ -984,10 +1060,30 @@ void netxen_process_cmd_ring(unsigned long data)
}
}
}
+ /*
+ * If everything is freed up to consumer then check if the ring is full
+ * If the ring is full then check if more needs to be freed and
+ * schedule the call back again.
+ *
+ * This happens when there are 2 CPUs. One could be freeing and the
+ * other filling it. If the ring is full when we get out of here and
+ * the card has already interrupted the host then the host can miss the
+ * interrupt.
+ *
+ * There is still a possible race condition and the host could miss an
+ * interrupt. The card has to take care of this.
+ */
+ if (adapter->last_cmd_consumer == consumer &&
+ (((adapter->cmd_producer + 1) %
+ adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
+ consumer = *(adapter->cmd_consumer);
+ }
+ done = (adapter->last_cmd_consumer == consumer);
spin_unlock(&adapter->tx_lock);
DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
__FUNCTION__);
+ return (done);
}
/*
@@ -999,17 +1095,16 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
struct sk_buff *skb;
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
- struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx];
- struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
- u32 producer;
+ uint producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
int count = 0;
int index = 0;
+ netxen_ctx_msg msg = 0;
+ dma_addr_t dma;
adapter->stats.post_called++;
rcv_desc = &recv_ctx->rcv_desc[ringid];
- rcv_desc_crb = &crbarea->rcv_desc_crb[ringid];
producer = rcv_desc->producer;
index = rcv_desc->begin_alloc;
@@ -1019,6 +1114,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
skb = dev_alloc_skb(rcv_desc->skb_size);
if (unlikely(!skb)) {
/*
+ * TODO
* We need to schedule the posting of buffers to the pegs.
*/
rcv_desc->begin_alloc = index;
@@ -1026,9 +1122,105 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
" allocated only %d buffers\n", count);
break;
}
+
count++; /* now there should be no failure */
pdesc = &rcv_desc->desc_head[producer];
- skb_reserve(skb, NET_IP_ALIGN);
+
+#if defined(XGB_DEBUG)
+ *(unsigned long *)(skb->head) = 0xc0debabe;
+ if (skb_is_nonlinear(skb)) {
+ printk("Allocated SKB @%p is nonlinear\n");
+ }
+#endif
+ skb_reserve(skb, 2);
+ /* This will be setup when we receive the
+ * buffer after it has been filled FSL TBD TBD
+ * skb->dev = netdev;
+ */
+ dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size,
+ PCI_DMA_FROMDEVICE);
+ pdesc->addr_buffer = dma;
+ buffer->skb = skb;
+ buffer->state = NETXEN_BUFFER_BUSY;
+ buffer->dma = dma;
+ /* make a rcv descriptor */
+ pdesc->reference_handle = buffer->ref_handle;
+ pdesc->buffer_length = rcv_desc->dma_size;
+ DPRINTK(INFO, "done writing descripter\n");
+ producer =
+ get_next_index(producer, rcv_desc->max_rx_desc_count);
+ index = get_next_index(index, rcv_desc->max_rx_desc_count);
+ buffer = &rcv_desc->rx_buf_arr[index];
+ }
+ /* if we did allocate buffers, then write the count to Phantom */
+ if (count) {
+ rcv_desc->begin_alloc = index;
+ rcv_desc->rcv_pending += count;
+ adapter->stats.lastposted = count;
+ adapter->stats.posted += count;
+ rcv_desc->producer = producer;
+ if (rcv_desc->rcv_free >= 32) {
+ rcv_desc->rcv_free = 0;
+ /* Window = 1 */
+ writel((producer - 1) &
+ (rcv_desc->max_rx_desc_count - 1),
+ NETXEN_CRB_NORMALIZE(adapter,
+ recv_crb_registers[0].
+ rcv_desc_crb[ringid].
+ crb_rcv_producer_offset));
+ /*
+ * Write a doorbell msg to tell phanmon of change in
+ * receive ring producer
+ */
+ netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
+ netxen_set_msg_privid(msg);
+ netxen_set_msg_count(msg,
+ ((producer -
+ 1) & (rcv_desc->
+ max_rx_desc_count - 1)));
+ netxen_set_msg_ctxid(msg, 0);
+ netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
+ writel(msg,
+ DB_NORMALIZE(adapter,
+ NETXEN_RCV_PRODUCER_OFFSET));
+ }
+ }
+}
+
+void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
+ uint32_t ringid)
+{
+ struct pci_dev *pdev = adapter->ahw.pdev;
+ struct sk_buff *skb;
+ struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
+ struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+ u32 producer;
+ struct rcv_desc *pdesc;
+ struct netxen_rx_buffer *buffer;
+ int count = 0;
+ int index = 0;
+
+ adapter->stats.post_called++;
+ rcv_desc = &recv_ctx->rcv_desc[ringid];
+
+ producer = rcv_desc->producer;
+ index = rcv_desc->begin_alloc;
+ buffer = &rcv_desc->rx_buf_arr[index];
+ /* We can start writing rx descriptors into the phantom memory. */
+ while (buffer->state == NETXEN_BUFFER_FREE) {
+ skb = dev_alloc_skb(rcv_desc->skb_size);
+ if (unlikely(!skb)) {
+ /*
+ * We need to schedule the posting of buffers to the pegs.
+ */
+ rcv_desc->begin_alloc = index;
+ DPRINTK(ERR, "netxen_post_rx_buffers_nodb: "
+ " allocated only %d buffers\n", count);
+ break;
+ }
+ count++; /* now there should be no failure */
+ pdesc = &rcv_desc->desc_head[producer];
+ skb_reserve(skb, 2);
/*
* This will be setup when we receive the
* buffer after it has been filled
@@ -1039,6 +1231,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
buffer->dma = pci_map_single(pdev, skb->data,
rcv_desc->dma_size,
PCI_DMA_FROMDEVICE);
+
/* make a rcv descriptor */
pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
@@ -1063,7 +1256,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
writel((producer - 1) &
(rcv_desc->max_rx_desc_count - 1),
NETXEN_CRB_NORMALIZE(adapter,
- rcv_desc_crb->
+ recv_crb_registers[0].
+ rcv_desc_crb[ringid].
crb_rcv_producer_offset));
wmb();
}
@@ -1196,8 +1390,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
switch (data.cmd) {
case netxen_nic_cmd_pci_read:
- if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
- &(data.u), data.size)))
+ if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off,
+ &(data.u), data.size)))
goto error_out;
if (copy_to_user
((void __user *)&(up_data->u), &(data.u), data.size)) {
@@ -1210,8 +1404,35 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
break;
case netxen_nic_cmd_pci_write:
- data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
- data.size);
+ if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off,
+ &(data.u), data.size)))
+ goto error_out;
+ data.rv = 0;
+ break;
+
+ case netxen_nic_cmd_pci_mem_read:
+ if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u),
+ data.size)) {
+ DPRINTK(ERR, "Failed to read the data.\n");
+ retval = -EFAULT;
+ goto error_out;
+ }
+ if (copy_to_user
+ ((void __user *)&(up_data->u), &(data.u), data.size)) {
+ DPRINTK(ERR, "bad copy to userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ data.rv = 0;
+ break;
+
+ case netxen_nic_cmd_pci_mem_write:
+ if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off,
+ &(data.u),
+ data.size)))
+ goto error_out;
+ data.rv = 0;
break;
case netxen_nic_cmd_pci_config_read:
@@ -1296,7 +1517,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
retval = -EOPNOTSUPP;
goto error_out;
}
- put_user(data.rv, (u16 __user *) (&(up_data->rv)));
+ put_user(data.rv, (&(up_data->rv)));
DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
error_out:
diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h
index 23e53adbf123..1221fa527552 100644
--- a/drivers/net/netxen/netxen_nic_ioctl.h
+++ b/drivers/net/netxen/netxen_nic_ioctl.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -36,7 +36,7 @@
#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1)
#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2)
#define NETXEN_NIC_NAME_LEN 16
-#define NETXEN_NIC_NAME_RSP "NETXEN"
+#define NETXEN_NIC_NAME_RSP "NETXEN-UNM"
typedef enum {
netxen_nic_cmd_none = 0,
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c
index ae180fee8008..1b45f50fa6aa 100644
--- a/drivers/net/netxen/netxen_nic_isr.c
+++ b/drivers/net/netxen/netxen_nic_isr.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -68,8 +68,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
u32 link)
{
- struct netxen_port *pport = adapter->port[portno];
- struct net_device *netdev = pport->netdev;
+ struct net_device *netdev = (adapter->port[portno])->netdev;
if (link)
netif_carrier_on(netdev);
@@ -84,46 +83,41 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
struct netxen_port *port;
/* This should clear the interrupt source */
- if (adapter->ops->phy_read)
- adapter->ops->phy_read(adapter, portno,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
- &int_src);
+ if (adapter->phy_read)
+ adapter->phy_read(adapter, portno,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+ &int_src);
if (int_src == 0) {
DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
return;
}
- if (adapter->ops->disable_phy_interrupts)
- adapter->ops->disable_phy_interrupts(adapter, portno);
+ if (adapter->disable_phy_interrupts)
+ adapter->disable_phy_interrupts(adapter, portno);
port = adapter->port[portno];
if (netxen_get_phy_int_jabber(int_src))
- DPRINTK(INFO, "NetXen: %s Jabber interrupt \n",
- port->netdev->name);
+ DPRINTK(INFO, "Jabber interrupt \n");
if (netxen_get_phy_int_polarity_changed(int_src))
- DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n",
- port->netdev->name);
+ DPRINTK(INFO, "POLARITY CHANGED int \n");
if (netxen_get_phy_int_energy_detect(int_src))
- DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n",
- port->netdev->name);
+ DPRINTK(INFO, "ENERGY DETECT INT \n");
if (netxen_get_phy_int_downshift(int_src))
- DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n",
- port->netdev->name);
+ DPRINTK(INFO, "DOWNSHIFT INT \n");
/* write it down later.. */
if ((netxen_get_phy_int_speed_changed(int_src))
|| (netxen_get_phy_int_link_status_changed(int_src))) {
__le32 status;
- DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR"
- " LINK STATUS CHANGED \n", port->netdev->name);
+ DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
- if (adapter->ops->phy_read
- && adapter->ops->phy_read(adapter, portno,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) == 0) {
+ if (adapter->phy_read
+ && adapter->phy_read(adapter, portno,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+ &status) == 0) {
if (netxen_get_phy_int_link_status_changed(int_src)) {
if (netxen_get_phy_link(status)) {
netxen_niu_gbe_init_port(adapter,
@@ -143,8 +137,8 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
}
}
}
- if (adapter->ops->enable_phy_interrupts)
- adapter->ops->enable_phy_interrupts(adapter, portno);
+ if (adapter->enable_phy_interrupts)
+ adapter->enable_phy_interrupts(adapter, portno);
}
void netxen_nic_isr_other(struct netxen_adapter *adapter)
@@ -159,8 +153,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter)
qg_linksup = adapter->ahw.qg_linksup;
adapter->ahw.qg_linksup = val;
- DPRINTK(1, INFO, "%s: link update 0x%08x\n", netxen_nic_driver_name,
- val);
+ DPRINTK(INFO, "link update 0x%08x\n", val);
for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
linkup = val & 1;
if (linkup != (qg_linksup & 1)) {
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 1cb662d5bd76..913e8147114f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1,25 +1,25 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -32,6 +32,7 @@
*/
#include <linux/vmalloc.h>
+#include <linux/highmem.h>
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
@@ -48,14 +49,21 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
-char netxen_nic_driver_name[] = "netxen";
+char netxen_nic_driver_name[] = "netxen-nic";
static char netxen_nic_driver_string[] = "NetXen Network Driver version "
NETXEN_NIC_LINUX_VERSIONID;
+struct netxen_adapter *g_adapter = NULL;
+
#define NETXEN_NETDEV_WEIGHT 120
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
+u8 nx_p2_id = NX_P2_C0;
+
+#define DMA_32BIT_MASK 0x00000000ffffffffULL
+#define DMA_35BIT_MASK 0x00000007ffffffffULL
+
/* Local functions to NetXen NIC driver */
static int __devinit netxen_nic_probe(struct pci_dev *pdev,
const struct pci_device_id *ent);
@@ -64,7 +72,7 @@ static int netxen_nic_open(struct net_device *netdev);
static int netxen_nic_close(struct net_device *netdev);
static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
static void netxen_tx_timeout(struct net_device *netdev);
-static void netxen_tx_timeout_task(struct net_device *netdev);
+static void netxen_tx_timeout_task(struct work_struct *work);
static void netxen_watchdog(unsigned long);
static int netxen_handle_int(struct netxen_adapter *, struct net_device *);
static int netxen_nic_ioctl(struct net_device *netdev,
@@ -87,6 +95,9 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
+struct workqueue_struct *netxen_workq;
+static void netxen_watchdog(unsigned long);
+
/*
* netxen_nic_probe()
*
@@ -105,20 +116,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct net_device *netdev = NULL;
struct netxen_adapter *adapter = NULL;
struct netxen_port *port = NULL;
- u8 *mem_ptr0 = NULL;
- u8 *mem_ptr1 = NULL;
- u8 *mem_ptr2 = NULL;
+ void __iomem *mem_ptr0 = NULL;
+ void __iomem *mem_ptr1 = NULL;
+ void __iomem *mem_ptr2 = NULL;
- unsigned long mem_base, mem_len;
+ u8 *db_ptr = NULL;
+ unsigned long mem_base, mem_len, db_base, db_len;
int pci_using_dac, i, err;
int ring;
struct netxen_recv_context *recv_ctx = NULL;
struct netxen_rcv_desc_ctx *rcv_desc = NULL;
struct netxen_cmd_buffer *cmd_buf_arr = NULL;
u64 mac_addr[FLASH_NUM_PORTS + 1];
- int valid_mac;
+ int valid_mac = 0;
+ static int netxen_cards_found = 0;
printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+ /* In current scheme, we use only PCI function 0 */
+ if (PCI_FUNC(pdev->devfn) != 0) {
+ DPRINTK(ERR, "NetXen function %d will not be enabled.\n",
+ PCI_FUNC(pdev->devfn));
+ return -ENODEV;
+ }
if ((err = pci_enable_device(pdev)))
return err;
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
@@ -130,10 +149,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_disable_pdev;
pci_set_master(pdev);
- if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) &&
- (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0))
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id);
+ if (nx_p2_id == NX_P2_C1 &&
+ (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) &&
+ (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) {
pci_using_dac = 1;
- else {
+ } else {
if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
(err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
goto err_out_free_res;
@@ -153,21 +174,34 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
- DPRINTK(1, ERR,
+ DPRINTK(ERR,
"Cannot remap adapter memory aborting.:"
"0 -> %p, 1 -> %p, 2 -> %p\n",
mem_ptr0, mem_ptr1, mem_ptr2);
err = -EIO;
- if (mem_ptr0)
- iounmap(mem_ptr0);
- if (mem_ptr1)
- iounmap(mem_ptr1);
- if (mem_ptr2)
- iounmap(mem_ptr2);
-
- goto err_out_free_res;
+ goto err_out_iounmap;
+ }
+ db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */
+ db_len = pci_resource_len(pdev, 4);
+
+ if (db_len == 0) {
+ printk(KERN_ERR "%s: doorbell is disabled\n",
+ netxen_nic_driver_name);
+ err = -EIO;
+ goto err_out_iounmap;
+ }
+ DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
+ db_len);
+
+ db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
+ if (db_ptr == 0UL) {
+ printk(KERN_ERR "%s: Failed to allocate doorbell map.",
+ netxen_nic_driver_name);
+ err = -EIO;
+ goto err_out_iounmap;
}
+ DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
/*
* Allocate a adapter structure which will manage all the initialization
@@ -183,17 +217,24 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_nic_driver_name,
(int)sizeof(struct netxen_adapter));
err = -ENOMEM;
- goto err_out_iounmap;
+ goto err_out_dbunmap;
}
+ if (netxen_cards_found == 0) {
+ g_adapter = adapter;
+ }
adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS;
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
+ adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
pci_set_drvdata(pdev, adapter);
cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
if (cmd_buf_arr == NULL) {
+ printk(KERN_ERR
+ "%s: Could not allocate cmd_buf_arr memory:%d\n",
+ netxen_nic_driver_name, (int)TX_RINGSIZE);
err = -ENOMEM;
goto err_out_free_adapter;
}
@@ -220,11 +261,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH;
break;
+ case RCV_RING_LRO:
+ rcv_desc->max_rx_desc_count =
+ adapter->max_lro_rx_desc_count;
+ rcv_desc->flags = RCV_DESC_LRO;
+ rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
+ rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+ break;
+
}
rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
vmalloc(RCV_BUFFSIZE);
if (rcv_desc->rx_buf_arr == NULL) {
+ printk(KERN_ERR "%s: Could not allocate"
+ "rcv_desc->rx_buf_arr memory:%d\n",
+ netxen_nic_driver_name,
+ (int)RCV_BUFFSIZE);
err = -ENOMEM;
goto err_out_free_rx_buffer;
}
@@ -233,30 +286,21 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
- adapter->ops = kzalloc(sizeof(struct netxen_drvops), GFP_KERNEL);
- if (adapter->ops == NULL) {
- printk(KERN_ERR
- "%s: Could not allocate memory for adapter->ops:%d\n",
- netxen_nic_driver_name,
- (int)sizeof(struct netxen_adapter));
- err = -ENOMEM;
- goto err_out_free_rx_buffer;
- }
-
adapter->cmd_buf_arr = cmd_buf_arr;
adapter->ahw.pci_base0 = mem_ptr0;
adapter->ahw.pci_base1 = mem_ptr1;
adapter->ahw.pci_base2 = mem_ptr2;
+ adapter->ahw.db_base = db_ptr;
+ adapter->ahw.db_len = db_len;
spin_lock_init(&adapter->tx_lock);
spin_lock_init(&adapter->lock);
+ netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */
#ifdef CONFIG_IA64
netxen_pinit_from_rom(adapter, 0);
udelay(500);
netxen_load_firmware(adapter);
#endif
- /* initialize the buffers in adapter */
- netxen_initialize_adapter_sw(adapter);
/*
* Set the CRB window to invalid. If any register in window 0 is
* accessed it should set the window to 0 and then reset it to 1.
@@ -274,11 +318,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ahw.xg_linkup = 0;
adapter->watchdog_timer.function = &netxen_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
- INIT_WORK(&adapter->watchdog_task,
- (void (*)(void *))netxen_watchdog_task, adapter);
+ INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
adapter->ahw.pdev = pdev;
adapter->proc_cmd_buf_counter = 0;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id);
+ adapter->ahw.revision_id = nx_p2_id;
if (pci_enable_msi(pdev)) {
adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
@@ -300,6 +343,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
+ /* do this before waking up pegs so that we have valid dummy dma addr */
+ err = netxen_initialize_adapter_offload(adapter);
+ if (err) {
+ goto err_out_free_dev;
+ }
+
/* Unlock the HW, prompting the boot sequence */
writel(1,
NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
@@ -308,6 +357,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
/* initialize the all the ports */
+ adapter->active_ports = 0;
for (i = 0; i < adapter->ahw.max_ports; i++) {
netdev = alloc_etherdev(sizeof(struct netxen_port));
@@ -373,14 +423,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->dev_addr[4],
netdev->dev_addr[5]);
} else {
- if (adapter->ops->macaddr_set)
- adapter->ops->macaddr_set(port,
- netdev->
- dev_addr);
+ if (adapter->macaddr_set)
+ adapter->macaddr_set(port,
+ netdev->dev_addr);
}
}
- INIT_WORK(&adapter->tx_timeout_task,
- (void (*)(void *))netxen_tx_timeout_task, netdev);
+ adapter->netdev = netdev;
+ INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -392,7 +441,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_dev;
}
adapter->port_count++;
- adapter->active_ports = 0;
adapter->port[i] = port;
}
@@ -413,6 +461,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
+ adapter->number = netxen_cards_found;
adapter->driver_mismatch = 0;
return 0;
@@ -427,7 +476,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
free_netdev(port->netdev);
}
}
- kfree(adapter->ops);
+
+ netxen_free_adapter_offload(adapter);
err_out_free_rx_buffer:
for (i = 0; i < MAX_RCV_CTX; ++i) {
@@ -440,19 +490,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
}
-
vfree(cmd_buf_arr);
- kfree(adapter->port);
-
err_out_free_adapter:
pci_set_drvdata(pdev, NULL);
kfree(adapter);
+ err_out_dbunmap:
+ if (db_ptr)
+ iounmap(db_ptr);
+
err_out_iounmap:
- iounmap(mem_ptr0);
- iounmap(mem_ptr1);
- iounmap(mem_ptr2);
+ if (mem_ptr0)
+ iounmap(mem_ptr0);
+ if (mem_ptr1)
+ iounmap(mem_ptr1);
+ if (mem_ptr2)
+ iounmap(mem_ptr2);
err_out_free_res:
pci_release_regions(pdev);
@@ -477,12 +531,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
netxen_nic_stop_all_ports(adapter);
/* leave the hw in the same state as reboot */
- netxen_pinit_from_rom(adapter, 0);
- udelay(500);
netxen_load_firmware(adapter);
-
- if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
- netxen_nic_disable_int(adapter);
+ netxen_free_adapter_offload(adapter);
udelay(500); /* Delay for a while to drain the DMA engines */
for (i = 0; i < adapter->port_count; i++) {
@@ -499,6 +549,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
netxen_free_hw_resources(adapter);
+ iounmap(adapter->ahw.db_base);
iounmap(adapter->ahw.pci_base0);
iounmap(adapter->ahw.pci_base1);
iounmap(adapter->ahw.pci_base2);
@@ -525,7 +576,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
}
vfree(adapter->cmd_buf_arr);
- kfree(adapter->ops);
kfree(adapter);
}
@@ -547,6 +597,8 @@ static int netxen_nic_open(struct net_device *netdev)
return -EIO;
}
netxen_nic_flash_print(adapter);
+ if (adapter->init_niu)
+ adapter->init_niu(adapter);
/* setup all the resources for the Phantom... */
/* this include the descriptors for rcv, tx, and status */
@@ -557,32 +609,31 @@ static int netxen_nic_open(struct net_device *netdev)
err);
return err;
}
- if (adapter->ops->init_port
- && adapter->ops->init_port(adapter, port->portnum) != 0) {
+ if (adapter->init_port
+ && adapter->init_port(adapter, port->portnum) != 0) {
printk(KERN_ERR "%s: Failed to initialize port %d\n",
netxen_nic_driver_name, port->portnum);
netxen_free_hw_resources(adapter);
return -EIO;
}
- if (adapter->ops->init_niu)
- adapter->ops->init_niu(adapter);
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
netxen_post_rx_buffers(adapter, ctx, ring);
}
- adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
- }
- adapter->active_ports++;
- if (adapter->active_ports == 1) {
+ adapter->irq = adapter->ahw.pdev->irq;
err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
adapter);
if (err) {
printk(KERN_ERR "request_irq failed with: %d\n", err);
- adapter->active_ports--;
+ netxen_free_hw_resources(adapter);
return err;
}
- adapter->irq = adapter->ahw.pdev->irq;
+
+ adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+ }
+ adapter->active_ports++;
+ if (adapter->active_ports == 1) {
if (!adapter->driver_mismatch)
mod_timer(&adapter->watchdog_timer, jiffies);
@@ -591,11 +642,14 @@ static int netxen_nic_open(struct net_device *netdev)
/* Done here again so that even if phantom sw overwrote it,
* we set it */
- if (adapter->ops->macaddr_set)
- adapter->ops->macaddr_set(port, netdev->dev_addr);
+ if (adapter->macaddr_set)
+ adapter->macaddr_set(port, netdev->dev_addr);
netxen_nic_set_link_parameters(port);
netxen_nic_set_multi(netdev);
+ if (adapter->set_mtu)
+ adapter->set_mtu(port, netdev->mtu);
+
if (!adapter->driver_mismatch)
netif_start_queue(netdev);
@@ -648,6 +702,7 @@ static int netxen_nic_close(struct net_device *netdev)
}
cmd_buff++;
}
+ FLUSH_SCHEDULED_WORK();
del_timer_sync(&adapter->watchdog_timer);
}
@@ -668,7 +723,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct cmd_desc_type0 *hwdesc;
int k;
struct netxen_cmd_buffer *pbuf = NULL;
- unsigned int tries = 0;
static int dropped_packet = 0;
int frag_count;
u32 local_producer = 0;
@@ -730,7 +784,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (((skb->nh.iph)->ihl * sizeof(u32)) +
((skb->h.th)->doff * sizeof(u32)) +
sizeof(struct ethhdr) >
- (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
+ (sizeof(struct cmd_desc_type0) - 2)) {
no_of_desc++;
}
}
@@ -741,27 +795,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if ((k + no_of_desc) >=
((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
last_cmd_consumer)) {
+ port->stats.nocmddescriptor++;
+ DPRINTK(ERR, "No command descriptors available,"
+ " producer = %d, consumer = %d count=%llu,"
+ " dropping packet\n", producer,
+ adapter->last_cmd_consumer,
+ port->stats.nocmddescriptor);
+
+ netif_stop_queue(netdev);
+ port->flags |= NETXEN_NETDEV_STATUS;
spin_unlock_bh(&adapter->tx_lock);
- if (tries == 0) {
- local_bh_disable();
- netxen_process_cmd_ring((unsigned long)adapter);
- local_bh_enable();
- ++tries;
- goto retry_getting_window;
- } else {
- port->stats.nocmddescriptor++;
- DPRINTK(ERR, "No command descriptors available,"
- " producer = %d, consumer = %d count=%llu,"
- " dropping packet\n", producer,
- adapter->last_cmd_consumer,
- port->stats.nocmddescriptor);
-
- spin_lock_bh(&adapter->tx_lock);
- netif_stop_queue(netdev);
- port->flags |= NETXEN_NETDEV_STATUS;
- spin_unlock_bh(&adapter->tx_lock);
- return NETDEV_TX_BUSY;
- }
+ return NETDEV_TX_BUSY;
}
k = get_index_range(k, max_tx_desc_count, no_of_desc);
adapter->cmd_producer = k;
@@ -783,7 +827,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
pbuf->mss = 0;
hwdesc->mss = 0;
}
- pbuf->no_of_descriptors = no_of_desc;
pbuf->total_length = skb->len;
pbuf->skb = skb;
pbuf->cmd = TX_ETHER_PKT;
@@ -793,11 +836,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len,
PCI_DMA_TODEVICE);
buffrag->length = first_seg_len;
- CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len);
- hwdesc->num_of_buffers = frag_count;
- hwdesc->opcode = TX_ETHER_PKT;
+ netxen_set_cmd_desc_totallength(hwdesc, skb->len);
+ netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
+ netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
- CMD_DESC_PORT_WRT(hwdesc, port->portnum);
+ netxen_set_cmd_desc_port(hwdesc, port->portnum);
hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
@@ -856,12 +899,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* For LSO, we need to copy the MAC/IP/TCP headers into
* the descriptor ring
*/
- if (hw->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) {
+ if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer])
+ == TX_TCP_LSO) {
int hdr_len, first_hdr_len, more_hdr;
hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
- if (hdr_len > (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
- first_hdr_len =
- sizeof(struct cmd_desc_type0) - NET_IP_ALIGN;
+ if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
+ first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
more_hdr = 1;
} else {
first_hdr_len = hdr_len;
@@ -871,7 +914,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
hwdesc = &hw->cmd_desc_head[producer];
/* copy the first 64 bytes */
- memcpy(((void *)hwdesc) + NET_IP_ALIGN,
+ memcpy(((void *)hwdesc) + 2,
(void *)(skb->data), first_hdr_len);
producer = get_next_index(producer, max_tx_desc_count);
@@ -887,7 +930,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
spin_lock_bh(&adapter->tx_lock);
port->stats.txbytes +=
- CMD_DESC_TOTAL_LENGTH(&hw->cmd_desc_head[saved_producer]);
+ netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
/* Code to update the adapter considering how many producer threads
are currently working */
if ((--adapter->num_threads) == 0) {
@@ -897,20 +940,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
wmb();
adapter->total_threads = 0;
- } else {
- u32 crb_producer = 0;
- crb_producer =
- readl(NETXEN_CRB_NORMALIZE
- (adapter, CRB_CMD_PRODUCER_OFFSET));
- if (crb_producer == local_producer) {
- crb_producer = get_index_range(crb_producer,
- max_tx_desc_count,
- no_of_desc);
- writel(crb_producer,
- NETXEN_CRB_NORMALIZE(adapter,
- CRB_CMD_PRODUCER_OFFSET));
- wmb();
- }
}
port->stats.xmitfinished++;
@@ -927,29 +956,36 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static void netxen_watchdog(unsigned long v)
{
struct netxen_adapter *adapter = (struct netxen_adapter *)v;
- schedule_work(&adapter->watchdog_task);
+ if (adapter != g_adapter) {
+ printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n",
+ __FUNCTION__, adapter, g_adapter);
+ return;
+ }
+
+ SCHEDULE_WORK(&adapter->watchdog_task);
}
static void netxen_tx_timeout(struct net_device *netdev)
{
struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
- struct netxen_adapter *adapter = port->adapter;
- schedule_work(&adapter->tx_timeout_task);
+ SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum);
}
-static void netxen_tx_timeout_task(struct net_device *netdev)
+static void netxen_tx_timeout_task(struct work_struct *work)
{
- struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
+ struct netxen_adapter *adapter =
+ container_of(work, struct netxen_adapter, tx_timeout_task);
+ struct net_device *netdev = adapter->netdev;
unsigned long flags;
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, netdev->name);
- spin_lock_irqsave(&port->adapter->lock, flags);
+ spin_lock_irqsave(&adapter->lock, flags);
netxen_nic_close(netdev);
netxen_nic_open(netdev);
- spin_unlock_irqrestore(&port->adapter->lock, flags);
+ spin_unlock_irqrestore(&adapter->lock, flags);
netdev->trans_start = jiffies;
netif_wake_queue(netdev);
}
@@ -966,6 +1002,11 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
int count = 0;
u32 mask;
+ mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+ if ((mask & 0x80) == 0) {
+ /* not our interrupt */
+ return ret;
+ }
netxen_nic_disable_int(adapter);
/* Window = 0 or 1 */
do {
@@ -1025,7 +1066,10 @@ irqreturn_t netxen_intr(int irq, void *data)
netdev = port->netdev;
/* process our status queue (for all 4 ports) */
- netxen_handle_int(adapter, netdev);
+ if (netif_running(netdev)) {
+ netxen_handle_int(adapter, netdev);
+ break;
+ }
}
return IRQ_HANDLED;
@@ -1039,11 +1083,12 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
int done = 1;
int ctx;
int this_work_done;
+ int work_done = 0;
DPRINTK(INFO, "polling for %d descriptors\n", *budget);
port->stats.polled++;
- adapter->work_done = 0;
+ work_done = 0;
for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
/*
* Fairness issue. This will give undue weight to the
@@ -1060,20 +1105,20 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
this_work_done = netxen_process_rcv_ring(adapter, ctx,
work_to_do /
MAX_RCV_CTX);
- adapter->work_done += this_work_done;
+ work_done += this_work_done;
}
- netdev->quota -= adapter->work_done;
- *budget -= adapter->work_done;
+ netdev->quota -= work_done;
+ *budget -= work_done;
- if (adapter->work_done >= work_to_do
- && netxen_nic_rx_has_work(adapter) != 0)
+ if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0)
done = 0;
- netxen_process_cmd_ring((unsigned long)adapter);
+ if (netxen_process_cmd_ring((unsigned long)adapter) == 0)
+ done = 0;
DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
- adapter->work_done, work_to_do);
+ work_done, work_to_do);
if (done) {
netif_rx_complete(netdev);
netxen_nic_enable_int(adapter);
@@ -1116,8 +1161,9 @@ netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
if (ifr->ifr_data) {
sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP,
port->portnum);
- nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name,
- NETXEN_NIC_NAME_LEN);
+ nr_bytes =
+ copy_to_user((char __user *)ifr->ifr_data, dev_name,
+ NETXEN_NIC_NAME_LEN);
if (nr_bytes)
err = -EIO;
@@ -1144,6 +1190,9 @@ static struct pci_driver netxen_driver = {
static int __init netxen_init_module(void)
{
+ if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0)
+ return -ENOMEM;
+
return pci_module_init(&netxen_driver);
}
@@ -1154,7 +1203,7 @@ static void __exit netxen_exit_module(void)
/*
* Wait for some time to allow the dma to drain, if any.
*/
- mdelay(5);
+ destroy_workqueue(netxen_workq);
pci_unregister_driver(&netxen_driver);
}
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 7950a04532e6..4987dc765d99 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2003 - 2006 NetXen, Inc.
* All rights reserved.
- *
+ *
* 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
@@ -16,10 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
- *
+ *
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.
- *
+ *
* Contact Information:
* info@netxen.com
* NetXen,
@@ -40,13 +40,15 @@
static long phy_lock_timeout = 100000000;
-static inline int phy_lock(void)
+static inline int phy_lock(struct netxen_adapter *adapter)
{
int i;
int done = 0, timeout = 0;
while (!done) {
- done = readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
+ done =
+ readl(pci_base_offset
+ (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)));
if (done == 1)
break;
if (timeout >= phy_lock_timeout) {
@@ -61,13 +63,15 @@ static inline int phy_lock(void)
}
}
- writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER);
+ writel(PHY_LOCK_DRIVER,
+ NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID));
return 0;
}
-static inline int phy_unlock(void)
+static inline int phy_unlock(struct netxen_adapter *adapter)
{
- readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
+ readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)));
+
return 0;
}
@@ -95,7 +99,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
__le32 status;
__le32 mac_cfg0;
- if (phy_lock() != 0) {
+ if (phy_lock(adapter) != 0) {
return -1;
}
@@ -162,7 +166,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
NETXEN_NIU_GB_MAC_CONFIG_0(0),
&mac_cfg0, 4))
return -EIO;
- phy_unlock();
+ phy_unlock(adapter);
return result;
}
@@ -399,8 +403,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
{
int result = 0;
__le32 status;
- if (adapter->ops->disable_phy_interrupts)
- adapter->ops->disable_phy_interrupts(adapter, port);
+ if (adapter->disable_phy_interrupts)
+ adapter->disable_phy_interrupts(adapter, port);
mdelay(2);
if (0 ==
@@ -612,7 +616,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
__le32 temp = 0;
struct netxen_adapter *adapter = port->adapter;
int phy = port->portnum;
- unsigned char mac_addr[MAX_ADDR_LEN];
+ unsigned char mac_addr[6];
int i;
for (i = 0; i < 10; i++) {
@@ -631,7 +635,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
netxen_niu_macaddr_get(adapter, phy,
(netxen_ethernet_macaddr_t *) mac_addr);
- if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0))
+ if (memcmp(mac_addr, addr, 6) == 0)
break;
}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 8181d436783f..7879f855af0b 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -33,15 +33,74 @@
/*
* CRB Registers or queue message done only at initialization time.
*/
+#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200)
+#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X))
-/*
- * The following 2 are the base adresses for the CRB registers and their
- * offsets will be added to get addresses for the index addresses.
- */
-#define NIC_CRB_BASE_PORT1 NETXEN_CAM_RAM(0x200)
-#define NIC_CRB_BASE_PORT2 NETXEN_CAM_RAM(0x250)
+#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
+#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
+#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
+#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
+#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */
+#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14)
+#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x18) /* host add:cmd ring */
+#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x1c)
+#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */
+#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24)
+#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28)
+#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c)
+#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) /* phantom init status */
+#define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34)
+#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38)
+#define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c)
+#define CRB_HOST_DUMMY_BUF_ADDR_LO NETXEN_NIC_REG(0x40)
+#define CRB_MMAP_ADDR_0 NETXEN_NIC_REG(0x44)
+#define CRB_MMAP_ADDR_1 NETXEN_NIC_REG(0x48)
+#define CRB_MMAP_ADDR_2 NETXEN_NIC_REG(0x4c)
+#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50)
+#define CRB_MMAP_SIZE_0 NETXEN_NIC_REG(0x54)
+#define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58)
+#define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c)
+#define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60)
+#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) /* interrupt coalescing */
+#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68)
+#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c)
+#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70)
+#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x74)
+#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x78)
+#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x7c)
+#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x80)
+#define CRB_RX_LRO_TIMER NETXEN_NIC_REG(0x84)
+#define CRB_RX_LRO_MID_TIMER NETXEN_NIC_REG(0x88)
+#define CRB_DMA_MAX_RCV_BUFS NETXEN_NIC_REG(0x8c)
+#define CRB_MAX_DMA_ENTRIES NETXEN_NIC_REG(0x90)
+#define CRB_XG_STATE NETXEN_NIC_REG(0x94) /* XG Link status */
+#define CRB_AGENT_GO NETXEN_NIC_REG(0x98) /* NIC pkt gen agent */
+#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0x9c)
+#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0)
+#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4)
+#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8)
+#define CRB_TX_STATE NETXEN_NIC_REG(0xac) /* Debug -performance */
+#define CRB_TX_COUNT NETXEN_NIC_REG(0xb0)
+#define CRB_RX_STATE NETXEN_NIC_REG(0xb4)
+#define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8)
+#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) /* LRO On/OFF */
+#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
+#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */
+#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
+#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
+#define CRB_CTX_RESET NETXEN_NIC_REG(0xd8)
+#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc)
+#define CRB_HOST_STS_CONS NETXEN_NIC_REG(0xe0)
+#define CRB_PEG_CMD_PROD NETXEN_NIC_REG(0xe4)
+#define CRB_PEG_CMD_CONS NETXEN_NIC_REG(0xe8)
+#define CRB_HOST_BUFFER_PROD NETXEN_NIC_REG(0xec)
+#define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0)
+#define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4)
+#define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8)
-#define NETXEN_NIC_REG(X) (NIC_CRB_BASE_PORT1+(X))
+#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac)
+#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0)
+#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4)
/*
* CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
@@ -51,74 +110,20 @@
* on the Phantom.
*/
-#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00)
-#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04)
-
-/* point to the indexes */
-#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08)
-#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c)
-
-#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10)
-#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14)
-
-/* address of command descriptors in the host memory */
-#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x30)
-#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x34)
-
-/* The following 4 CRB registers are for doing performance coal */
-#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x38)
-#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x3c)
-#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x40)
-#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x44)
-
-/* Needed by the host to find out the state of Phantom's initialization */
-#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x4c)
-#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50)
-#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x54)
-
-/* Interrupt coalescing parameters */
-#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x80)
-#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x84)
-#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x88)
-#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x8c)
-#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x90)
-#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x94)
-#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x98)
-#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x9c)
-#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4)
-
-/* Register for communicating XG link status */
-#define CRB_XG_STATE NETXEN_NIC_REG(0xa0)
-
-/* Register for communicating card temperature */
-/* Upper 16 bits are temperature value. Lower 16 bits are the state */
-#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8)
-#define nx_get_temp_val(x) ((x) >> 16)
-#define nx_get_temp_state(x) ((x) & 0xffff)
-#define nx_encode_temp(val, state) (((val) << 16) | (state))
-
-/* Debug registers for controlling NIC pkt gen agent */
-#define CRB_AGENT_GO NETXEN_NIC_REG(0xb0)
-#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0xb4)
-#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xb8)
-#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xbc)
-#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xc0)
-
-/* Debug registers for observing NIC performance */
-#define CRB_TX_STATE NETXEN_NIC_REG(0xd0)
-#define CRB_TX_COUNT NETXEN_NIC_REG(0xd4)
-#define CRB_RX_STATE NETXEN_NIC_REG(0xd8)
+#define nx_get_temp_val(x) ((x) >> 16)
+#define nx_get_temp_state(x) ((x) & 0xffff)
+#define nx_encode_temp(val, state) (((val) << 16) | (state))
/* CRB registers per Rcv Descriptor ring */
struct netxen_rcv_desc_crb {
u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
u32 crb_rcv_consumer_offset;
u32 crb_globalrcv_ring;
+ u32 crb_rcv_ring_size;
};
/*
- * CRB registers used by the receive peg logic. One instance of these
- * needs to be instantiated per instance of the receive peg.
+ * CRB registers used by the receive peg logic.
*/
struct netxen_recv_crb {
@@ -127,6 +132,7 @@ struct netxen_recv_crb {
u32 crb_rcv_status_producer;
u32 crb_rcv_status_consumer;
u32 crb_rcvpeg_state;
+ u32 crb_status_ring_size;
};
#if defined(DEFINE_GLOBAL_RECV_CRB)
@@ -139,30 +145,48 @@ struct netxen_recv_crb recv_crb_registers[] = {
{
{
/* crb_rcv_producer_offset: */
- NETXEN_NIC_REG(0x18),
+ NETXEN_NIC_REG(0x100),
/* crb_rcv_consumer_offset: */
- NETXEN_NIC_REG(0x1c),
+ NETXEN_NIC_REG(0x104),
/* crb_gloablrcv_ring: */
- NETXEN_NIC_REG(0x20),
+ NETXEN_NIC_REG(0x108),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x10c),
+
},
/* Jumbo frames */
{
/* crb_rcv_producer_offset: */
- NETXEN_NIC_REG(0x100),
+ NETXEN_NIC_REG(0x110),
/* crb_rcv_consumer_offset: */
- NETXEN_NIC_REG(0x104),
+ NETXEN_NIC_REG(0x114),
/* crb_gloablrcv_ring: */
- NETXEN_NIC_REG(0x108),
+ NETXEN_NIC_REG(0x118),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x11c),
+ },
+ /* LRO */
+ {
+ /* crb_rcv_producer_offset: */
+ NETXEN_NIC_REG(0x120),
+ /* crb_rcv_consumer_offset: */
+ NETXEN_NIC_REG(0x124),
+ /* crb_gloablrcv_ring: */
+ NETXEN_NIC_REG(0x128),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x12c),
}
},
/* crb_rcvstatus_ring: */
- NETXEN_NIC_REG(0x24),
+ NETXEN_NIC_REG(0x130),
/* crb_rcv_status_producer: */
- NETXEN_NIC_REG(0x28),
+ NETXEN_NIC_REG(0x134),
/* crb_rcv_status_consumer: */
- NETXEN_NIC_REG(0x2c),
+ NETXEN_NIC_REG(0x138),
/* crb_rcvpeg_state: */
- NETXEN_NIC_REG(0x48),
+ NETXEN_NIC_REG(0x13c),
+ /* crb_status_ring_size */
+ NETXEN_NIC_REG(0x140),
},
/*
@@ -173,34 +197,66 @@ struct netxen_recv_crb recv_crb_registers[] = {
{
{
/* crb_rcv_producer_offset: */
- NETXEN_NIC_REG(0x80),
+ NETXEN_NIC_REG(0x144),
/* crb_rcv_consumer_offset: */
- NETXEN_NIC_REG(0x84),
+ NETXEN_NIC_REG(0x148),
/* crb_globalrcv_ring: */
- NETXEN_NIC_REG(0x88),
+ NETXEN_NIC_REG(0x14c),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x150),
+
},
/* Jumbo frames */
{
/* crb_rcv_producer_offset: */
- NETXEN_NIC_REG(0x10C),
+ NETXEN_NIC_REG(0x154),
/* crb_rcv_consumer_offset: */
- NETXEN_NIC_REG(0x110),
+ NETXEN_NIC_REG(0x158),
/* crb_globalrcv_ring: */
- NETXEN_NIC_REG(0x114),
+ NETXEN_NIC_REG(0x15c),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x160),
+ },
+ /* LRO */
+ {
+ /* crb_rcv_producer_offset: */
+ NETXEN_NIC_REG(0x164),
+ /* crb_rcv_consumer_offset: */
+ NETXEN_NIC_REG(0x168),
+ /* crb_globalrcv_ring: */
+ NETXEN_NIC_REG(0x16c),
+ /* crb_rcv_ring_size */
+ NETXEN_NIC_REG(0x170),
}
+
},
/* crb_rcvstatus_ring: */
- NETXEN_NIC_REG(0x8c),
+ NETXEN_NIC_REG(0x174),
/* crb_rcv_status_producer: */
- NETXEN_NIC_REG(0x90),
+ NETXEN_NIC_REG(0x178),
/* crb_rcv_status_consumer: */
- NETXEN_NIC_REG(0x94),
+ NETXEN_NIC_REG(0x17c),
/* crb_rcvpeg_state: */
- NETXEN_NIC_REG(0x98),
+ NETXEN_NIC_REG(0x180),
+ /* crb_status_ring_size */
+ NETXEN_NIC_REG(0x184),
+
},
};
+
+u64 ctx_addr_sig_regs[][3] = {
+ {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
+ {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
+ {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
+ {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
+};
+
#else
extern struct netxen_recv_crb recv_crb_registers[];
+extern u64 ctx_addr_sig_regs[][3];
+#define CRB_CTX_ADDR_REG_LO (ctx_addr_sig_regs[0][0])
+#define CRB_CTX_ADDR_REG_HI (ctx_addr_sig_regs[0][2])
+#define CRB_CTX_SIGNATURE_REG (ctx_addr_sig_regs[0][1])
#endif /* DEFINE_GLOBAL_RECEIVE_CRB */
/*
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 26e42f6e9fb1..196993a29b09 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -1335,7 +1335,7 @@ int __init init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(dev_ni52);
release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 340ad0d5388a..1578f4d98498 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -1259,7 +1259,7 @@ int __init init_module(void)
return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(dev_ni65);
cleanup_card(dev_ni65);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index b0127c71a5b6..568daeb3e9d8 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -414,10 +414,10 @@ struct rx_info {
struct sk_buff *skbs[NR_RX_DESC];
- u32 *next_rx_desc;
+ __le32 *next_rx_desc;
u16 next_rx, next_empty;
- u32 *descs;
+ __le32 *descs;
dma_addr_t phy_descs;
};
@@ -427,6 +427,7 @@ struct ns83820 {
u8 __iomem *base;
struct pci_dev *pci_dev;
+ struct net_device *ndev;
#ifdef NS83820_VLAN_ACCEL_SUPPORT
struct vlan_group *vlgrp;
@@ -459,7 +460,7 @@ struct ns83820 {
struct sk_buff *tx_skbs[NR_TX_DESC];
char pad[16] __attribute__((aligned(16)));
- u32 *tx_descs;
+ __le32 *tx_descs;
dma_addr_t tx_phy_descs;
struct timer_list tx_watchdog;
@@ -533,7 +534,7 @@ static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid
* conditions, still route realtime traffic with as low jitter as
* possible.
*/
-static inline void build_rx_desc(struct ns83820 *dev, u32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts)
+static inline void build_rx_desc(struct ns83820 *dev, __le32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts)
{
desc_addr_set(desc + DESC_LINK, link);
desc_addr_set(desc + DESC_BUFPTR, buf);
@@ -547,7 +548,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
{
unsigned next_empty;
u32 cmdsts;
- u32 *sg;
+ __le32 *sg;
dma_addr_t buf;
next_empty = dev->rx_info.next_empty;
@@ -631,10 +632,10 @@ static void fastcall rx_refill_atomic(struct net_device *ndev)
}
/* REFILL */
-static inline void queue_refill(void *_dev)
+static inline void queue_refill(struct work_struct *work)
{
- struct net_device *ndev = _dev;
- struct ns83820 *dev = PRIV(ndev);
+ struct ns83820 *dev = container_of(work, struct ns83820, tq_refill);
+ struct net_device *ndev = dev->ndev;
rx_refill(ndev, GFP_KERNEL);
if (dev->rx_info.up)
@@ -874,7 +875,8 @@ static void fastcall rx_irq(struct net_device *ndev)
struct rx_info *info = &dev->rx_info;
unsigned next_rx;
int rx_rc, len;
- u32 cmdsts, *desc;
+ u32 cmdsts;
+ __le32 *desc;
unsigned long flags;
int nr = 0;
@@ -1010,7 +1012,8 @@ static inline void kick_tx(struct ns83820 *dev)
static void do_tx_done(struct net_device *ndev)
{
struct ns83820 *dev = PRIV(ndev);
- u32 cmdsts, tx_done_idx, *desc;
+ u32 cmdsts, tx_done_idx;
+ __le32 *desc;
dprintk("do_tx_done(%p)\n", ndev);
tx_done_idx = dev->tx_done_idx;
@@ -1077,7 +1080,7 @@ static void ns83820_cleanup_tx(struct ns83820 *dev)
struct sk_buff *skb = dev->tx_skbs[i];
dev->tx_skbs[i] = NULL;
if (skb) {
- u32 *desc = dev->tx_descs + (i * DESC_SIZE);
+ __le32 *desc = dev->tx_descs + (i * DESC_SIZE);
pci_unmap_single(dev->pci_dev,
desc_addr_get(desc + DESC_BUFPTR),
le32_to_cpu(desc[DESC_CMDSTS]) & CMDSTS_LEN_MASK,
@@ -1107,7 +1110,7 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
skb_frag_t *frag;
int stopped = 0;
int do_intr = 0;
- volatile u32 *first_desc;
+ volatile __le32 *first_desc;
dprintk("ns83820_hard_start_xmit\n");
@@ -1180,7 +1183,7 @@ again:
first_desc = dev->tx_descs + (free_idx * DESC_SIZE);
for (;;) {
- volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
+ volatile __le32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
(unsigned long long)buf);
@@ -1455,7 +1458,8 @@ static int ns83820_stop(struct net_device *ndev)
static void ns83820_tx_timeout(struct net_device *ndev)
{
struct ns83820 *dev = PRIV(ndev);
- u32 tx_done_idx, *desc;
+ u32 tx_done_idx;
+ __le32 *desc;
unsigned long flags;
spin_lock_irqsave(&dev->tx_lock, flags);
@@ -1841,6 +1845,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
ndev = alloc_etherdev(sizeof(struct ns83820));
dev = PRIV(ndev);
+ dev->ndev = ndev;
err = -ENOMEM;
if (!dev)
goto out;
@@ -1853,7 +1858,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
SET_MODULE_OWNER(ndev);
SET_NETDEV_DEV(ndev, &pci_dev->dev);
- INIT_WORK(&dev->tq_refill, queue_refill, ndev);
+ INIT_WORK(&dev->tq_refill, queue_refill);
tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev);
err = pci_enable_device(pci_dev);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 046009928526..794cc61819dd 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -338,7 +338,6 @@ static int tc574_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
tuple_t tuple;
- cisparse_t parse;
unsigned short buf[32];
int last_fn, last_ret, i, j;
kio_addr_t ioaddr;
@@ -350,17 +349,6 @@ static int tc574_config(struct pcmcia_device *link)
DEBUG(0, "3c574_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x20) {
link->io.BasePort1 = j ^ 0x300;
@@ -382,6 +370,10 @@ static int tc574_config(struct pcmcia_device *link)
/* The 3c574 normally uses an EEPROM for configuration info, including
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
+ tuple.Attributes = 0;
+ tuple.TupleData = (cisdata_t *)buf;
+ tuple.TupleDataMax = 64;
+ tuple.TupleOffset = 0;
tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(link, &tuple);
@@ -397,12 +389,9 @@ static int tc574_config(struct pcmcia_device *link)
goto failed;
}
}
- tuple.DesiredTuple = CISTPL_VERS_1;
- if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS &&
- pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS &&
- pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) {
- cardname = parse.version_1.str + parse.version_1.ofs[1];
- } else
+ if (link->prod_id[1])
+ cardname = link->prod_id[1];
+ else
cardname = "3Com 3c574";
{
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 231fa2c9ec6c..1e73ff7d5d8e 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -253,7 +253,6 @@ static int tc589_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
tuple_t tuple;
- cisparse_t parse;
u16 buf[32], *phys_addr;
int last_fn, last_ret, i, j, multi = 0, fifo;
kio_addr_t ioaddr;
@@ -263,26 +262,16 @@ static int tc589_config(struct pcmcia_device *link)
phys_addr = (u16 *)dev->dev_addr;
tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /* Is this a 3c562? */
- tuple.DesiredTuple = CISTPL_MANFID;
tuple.Attributes = TUPLE_RETURN_COMMON;
- if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
- (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) {
- if (le16_to_cpu(buf[0]) != MANFID_3COM)
+
+ /* Is this a 3c562? */
+ if (link->manf_id != MANFID_3COM)
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
"3Com card??\n");
- multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562);
- }
+ multi = (link->card_id == PRODID_3COM_3C562);
/* For the 3c562, the base address must be xx00-xx7f */
link->io.IOAddrLines = 16;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 5ddd5742f779..6139048f8117 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -299,11 +299,7 @@ static int axnet_config(struct pcmcia_device *link)
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
+
/* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63;
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 48434d7924eb..91f65e91cd5f 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -249,12 +249,9 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int com20020_config(struct pcmcia_device *link)
{
struct arcnet_local *lp;
- tuple_t tuple;
- cisparse_t parse;
com20020_dev_t *info;
struct net_device *dev;
int i, last_ret, last_fn;
- u_char buf[64];
int ioaddr;
info = link->priv;
@@ -264,16 +261,6 @@ static int com20020_config(struct pcmcia_device *link)
DEBUG(0, "com20020_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
-
DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
i = !CS_SUCCESS;
if (!link->io.BasePort1)
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 65f6fdf43725..0d7de617e535 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -342,7 +342,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
tuple_t tuple;
cisparse_t parse;
u_short buf[32];
- int i, last_fn, last_ret, ret;
+ int i, last_fn = 0, last_ret = 0, ret;
kio_addr_t ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
@@ -350,21 +350,9 @@ static int fmvj18x_config(struct pcmcia_device *link)
DEBUG(0, "fmvj18x_config(0x%p)\n", link);
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
tuple.TupleData = (u_char *)buf;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
-
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
tuple.DesiredTuple = CISTPL_FUNCE;
tuple.TupleOffset = 0;
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
@@ -374,17 +362,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigIndex = parse.cftable_entry.index;
- tuple.DesiredTuple = CISTPL_MANFID;
- if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS)
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- else
- buf[0] = 0xffff;
- switch (le16_to_cpu(buf[0])) {
+ switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
- if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410
- || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610
- || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) {
+ if (link->card_id == PRODID_TDK_GN3410
+ || link->card_id == PRODID_TDK_NP9610
+ || link->card_id == PRODID_TDK_MN3200) {
/* MultiFunction Card */
link->conf.ConfigBase = 0x800;
link->conf.ConfigIndex = 0x47;
@@ -395,11 +378,11 @@ static int fmvj18x_config(struct pcmcia_device *link)
cardtype = CONTEC;
break;
case MANFID_FUJITSU:
- if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302)
+ if (link->card_id == PRODID_FUJITSU_MBH10302)
/* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),
but these are MBH10304 based card. */
cardtype = MBH10304;
- else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304)
+ else if (link->card_id == PRODID_FUJITSU_MBH10304)
cardtype = MBH10304;
else
cardtype = LA501;
@@ -409,14 +392,9 @@ static int fmvj18x_config(struct pcmcia_device *link)
}
} else {
/* old type card */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS)
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- else
- buf[0] = 0xffff;
- switch (le16_to_cpu(buf[0])) {
+ switch (link->manf_id) {
case MANFID_FUJITSU:
- if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) {
+ if (link->card_id == PRODID_FUJITSU_MBH10304) {
cardtype = XXX10304; /* MBH10304 with buggy CIS */
link->conf.ConfigIndex = 0x20;
} else {
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index bc0ca41a0542..a956a51d284f 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -222,24 +222,12 @@ static int ibmtr_config(struct pcmcia_device *link)
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
struct tok_info *ti = netdev_priv(dev);
- tuple_t tuple;
- cisparse_t parse;
win_req_t req;
memreq_t mem;
int i, last_ret, last_fn;
- u_char buf[64];
DEBUG(0, "ibmtr_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
link->conf.ConfigIndex = 0x61;
/* Determine if this is PRIMARY or ALTERNATE. */
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index e77110e4c288..3b707747a811 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -656,23 +656,12 @@ static int nmclan_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
mace_private *lp = netdev_priv(dev);
tuple_t tuple;
- cisparse_t parse;
u_char buf[64];
int i, last_ret, last_fn;
kio_addr_t ioaddr;
DEBUG(0, "nmclan_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
-
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@@ -686,6 +675,7 @@ static int nmclan_config(struct pcmcia_device *link)
tuple.TupleData = buf;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
+ tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c51cc5d8789a..2b1238e2dbdb 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -519,31 +519,15 @@ static int pcnet_config(struct pcmcia_device *link)
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
- int manfid = 0, prodid = 0, has_shmem = 0;
+ int has_shmem = 0;
u_short buf[64];
hw_info_t *hw_info;
DEBUG(0, "pcnet_config(0x%p)\n", link);
- tuple.Attributes = 0;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- tuple.DesiredTuple = CISTPL_MANFID;
- tuple.Attributes = TUPLE_RETURN_COMMON;
- if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
- (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) {
- manfid = le16_to_cpu(buf[0]);
- prodid = le16_to_cpu(buf[1]);
- }
-
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
@@ -589,8 +573,8 @@ static int pcnet_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
- if ((manfid == MANFID_IBM) &&
- (prodid == PRODID_IBM_HOME_AND_AWAY))
+ if ((link->manf_id == MANFID_IBM) &&
+ (link->card_id == PRODID_IBM_HOME_AND_AWAY))
link->conf.ConfigIndex |= 0x10;
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@@ -624,10 +608,10 @@ static int pcnet_config(struct pcmcia_device *link)
info->flags = hw_info->flags;
/* Check for user overrides */
info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
- if ((manfid == MANFID_SOCKET) &&
- ((prodid == PRODID_SOCKET_LPE) ||
- (prodid == PRODID_SOCKET_LPE_CF) ||
- (prodid == PRODID_SOCKET_EIO)))
+ if ((link->manf_id == MANFID_SOCKET) &&
+ ((link->card_id == PRODID_SOCKET_LPE) ||
+ (link->card_id == PRODID_SOCKET_LPE_CF) ||
+ (link->card_id == PRODID_SOCKET_EIO)))
info->flags &= ~USE_BIG_BUF;
if (!use_big_buf)
info->flags &= ~USE_BIG_BUF;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 20fcc3576202..530df8883fe5 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -560,16 +560,8 @@ static int mhz_setup(struct pcmcia_device *link)
/* Read the station address from the CIS. It is stored as the last
(fourth) string in the Version 1 Version/ID tuple. */
- tuple->DesiredTuple = CISTPL_VERS_1;
- if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
- rc = -1;
- goto free_cfg_mem;
- }
- /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- if (next_tuple(link, tuple, parse) != CS_SUCCESS)
- first_tuple(link, tuple, parse);
- if (parse->version_1.ns > 3) {
- station_addr = parse->version_1.str + parse->version_1.ofs[3];
+ if (link->prod_id[3]) {
+ station_addr = link->prod_id[3];
if (cvt_ascii_address(dev, station_addr) == 0) {
rc = 0;
goto free_cfg_mem;
@@ -744,15 +736,12 @@ static int smc_setup(struct pcmcia_device *link)
}
}
/* Try the third string in the Version 1 Version/ID tuple. */
- tuple->DesiredTuple = CISTPL_VERS_1;
- if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
- rc = -1;
- goto free_cfg_mem;
- }
- station_addr = parse->version_1.str + parse->version_1.ofs[2];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
+ if (link->prod_id[2]) {
+ station_addr = link->prod_id[2];
+ if (cvt_ascii_address(dev, station_addr) == 0) {
+ rc = 0;
+ goto free_cfg_mem;
+ }
}
rc = -1;
@@ -970,10 +959,6 @@ static int smc91c92_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- u_char *buf;
char *name;
int i, j, rev;
kio_addr_t ioaddr;
@@ -981,30 +966,8 @@ static int smc91c92_config(struct pcmcia_device *link)
DEBUG(0, "smc91c92_config(0x%p)\n", link);
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- goto config_failed;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 64;
-
- tuple->DesiredTuple = CISTPL_CONFIG;
- i = first_tuple(link, tuple, parse);
- CS_EXIT_TEST(i, ParseTuple, config_failed);
- link->conf.ConfigBase = parse->config.base;
- link->conf.Present = parse->config.rmask[0];
-
- tuple->DesiredTuple = CISTPL_MANFID;
- tuple->Attributes = TUPLE_RETURN_COMMON;
- if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
- smc->manfid = parse->manfid.manf;
- smc->cardid = parse->manfid.card;
- }
+ smc->manfid = link->manf_id;
+ smc->cardid = link->card_id;
if ((smc->manfid == MANFID_OSITECH) &&
(smc->cardid != PRODID_OSITECH_SEVEN)) {
@@ -1134,14 +1097,12 @@ static int smc91c92_config(struct pcmcia_device *link)
printk(KERN_NOTICE " No MII transceivers found!\n");
}
}
- kfree(cfg_mem);
return 0;
config_undo:
unregister_netdev(dev);
config_failed: /* CS_EXIT_TEST() calls jump to here... */
smc91c92_release(link);
- kfree(cfg_mem);
return -ENODEV;
} /* smc91c92_config */
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f3914f58d67f..8478dca3d8d1 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -332,6 +332,7 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);
*/
typedef struct local_info_t {
+ struct net_device *dev;
struct pcmcia_device *p_dev;
dev_node_t node;
struct net_device_stats stats;
@@ -353,7 +354,7 @@ typedef struct local_info_t {
*/
static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void do_tx_timeout(struct net_device *dev);
-static void xirc2ps_tx_timeout_task(void *data);
+static void xirc2ps_tx_timeout_task(struct work_struct *work);
static struct net_device_stats *do_get_stats(struct net_device *dev);
static void set_addresses(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
@@ -567,6 +568,7 @@ xirc2ps_probe(struct pcmcia_device *link)
if (!dev)
return -ENOMEM;
local = netdev_priv(dev);
+ local->dev = dev;
local->p_dev = link;
link->priv = dev;
@@ -591,7 +593,7 @@ xirc2ps_probe(struct pcmcia_device *link)
#ifdef HAVE_TX_TIMEOUT
dev->tx_timeout = do_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev);
+ INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
#endif
return xirc2ps_config(link);
@@ -707,22 +709,11 @@ set_card_type(struct pcmcia_device *link, const void *s)
* Returns: true if this is a CE2
*/
static int
-has_ce2_string(struct pcmcia_device * link)
+has_ce2_string(struct pcmcia_device * p_dev)
{
- tuple_t tuple;
- cisparse_t parse;
- u_char buf[256];
-
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 254;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
- if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) {
- if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2"))
- return 1;
- }
- return 0;
+ if (p_dev->prod_id[2] && strstr(p_dev->prod_id[2], "CE2"))
+ return 1;
+ return 0;
}
/****************
@@ -792,13 +783,6 @@ xirc2ps_config(struct pcmcia_device * link)
goto failure;
}
- /* get configuration stuff */
- tuple.DesiredTuple = CISTPL_CONFIG;
- if ((err=first_tuple(link, &tuple, &parse)))
- goto cis_error;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* get the ethernet address from the CIS */
tuple.DesiredTuple = CISTPL_FUNCE;
for (err = first_tuple(link, &tuple, &parse); !err;
@@ -1062,8 +1046,6 @@ xirc2ps_config(struct pcmcia_device * link)
xirc2ps_release(link);
return -ENODEV;
- cis_error:
- printk(KNOT_XIRC "unable to parse CIS\n");
failure:
return -ENODEV;
} /* xirc2ps_config */
@@ -1344,9 +1326,11 @@ xirc2ps_interrupt(int irq, void *dev_id)
/*====================================================================*/
static void
-xirc2ps_tx_timeout_task(void *data)
+xirc2ps_tx_timeout_task(struct work_struct *work)
{
- struct net_device *dev = data;
+ local_info_t *local =
+ container_of(work, local_info_t, tx_timeout_task);
+ struct net_device *dev = local->dev;
/* reset the card */
do_reset(dev,1);
dev->trans_start = jiffies;
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index f14e99276dba..096d4a100bf2 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -254,7 +254,7 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
goto device_create_fail;
}
- phydev->irq = -1;
+ phydev->irq = PHY_IGNORE_INTERRUPT;
phydev->dev.bus = &mdio_bus_type;
if(number)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 88237bdb5255..4044bb1ada86 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -397,7 +397,7 @@ out_unlock:
EXPORT_SYMBOL(phy_start_aneg);
-static void phy_change(void *data);
+static void phy_change(struct work_struct *work);
static void phy_timer(unsigned long data);
/* phy_start_machine:
@@ -555,7 +555,7 @@ int phy_start_interrupts(struct phy_device *phydev)
{
int err = 0;
- INIT_WORK(&phydev->phy_queue, phy_change, phydev);
+ INIT_WORK(&phydev->phy_queue, phy_change);
if (request_irq(phydev->irq, phy_interrupt,
IRQF_SHARED,
@@ -598,10 +598,11 @@ EXPORT_SYMBOL(phy_stop_interrupts);
/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void phy_change(void *data)
+static void phy_change(struct work_struct *work)
{
int err;
- struct phy_device *phydev = data;
+ struct phy_device *phydev =
+ container_of(work, struct phy_device, phy_queue);
err = phy_disable_interrupts(phydev);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 71afb274498f..6bb085f54437 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -138,9 +138,9 @@ static const unsigned int net_debug = NET_DEBUG;
#define PLIP_NIBBLE_WAIT 3000
/* Bottom halves */
-static void plip_kick_bh(struct net_device *dev);
-static void plip_bh(struct net_device *dev);
-static void plip_timer_bh(struct net_device *dev);
+static void plip_kick_bh(struct work_struct *work);
+static void plip_bh(struct work_struct *work);
+static void plip_timer_bh(struct work_struct *work);
/* Interrupt handler */
static void plip_interrupt(int irq, void *dev_id);
@@ -207,9 +207,10 @@ struct plip_local {
struct net_local {
struct net_device_stats enet_stats;
+ struct net_device *dev;
struct work_struct immediate;
- struct work_struct deferred;
- struct work_struct timer;
+ struct delayed_work deferred;
+ struct delayed_work timer;
struct plip_local snd_data;
struct plip_local rcv_data;
struct pardevice *pardev;
@@ -306,11 +307,11 @@ plip_init_netdev(struct net_device *dev)
nl->nibble = PLIP_NIBBLE_WAIT;
/* Initialize task queue structures */
- INIT_WORK(&nl->immediate, (void (*)(void *))plip_bh, dev);
- INIT_WORK(&nl->deferred, (void (*)(void *))plip_kick_bh, dev);
+ INIT_WORK(&nl->immediate, plip_bh);
+ INIT_DELAYED_WORK(&nl->deferred, plip_kick_bh);
if (dev->irq == -1)
- INIT_WORK(&nl->timer, (void (*)(void *))plip_timer_bh, dev);
+ INIT_DELAYED_WORK(&nl->timer, plip_timer_bh);
spin_lock_init(&nl->lock);
}
@@ -319,9 +320,10 @@ plip_init_netdev(struct net_device *dev)
This routine is kicked by do_timer().
Request `plip_bh' to be invoked. */
static void
-plip_kick_bh(struct net_device *dev)
+plip_kick_bh(struct work_struct *work)
{
- struct net_local *nl = netdev_priv(dev);
+ struct net_local *nl =
+ container_of(work, struct net_local, deferred.work);
if (nl->is_deferred)
schedule_work(&nl->immediate);
@@ -362,9 +364,9 @@ static const plip_func connection_state_table[] =
/* Bottom half handler of PLIP. */
static void
-plip_bh(struct net_device *dev)
+plip_bh(struct work_struct *work)
{
- struct net_local *nl = netdev_priv(dev);
+ struct net_local *nl = container_of(work, struct net_local, immediate);
struct plip_local *snd = &nl->snd_data;
struct plip_local *rcv = &nl->rcv_data;
plip_func f;
@@ -372,20 +374,21 @@ plip_bh(struct net_device *dev)
nl->is_deferred = 0;
f = connection_state_table[nl->connection];
- if ((r = (*f)(dev, nl, snd, rcv)) != OK
- && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
+ if ((r = (*f)(nl->dev, nl, snd, rcv)) != OK
+ && (r = plip_bh_timeout_error(nl->dev, nl, snd, rcv, r)) != OK) {
nl->is_deferred = 1;
schedule_delayed_work(&nl->deferred, 1);
}
}
static void
-plip_timer_bh(struct net_device *dev)
+plip_timer_bh(struct work_struct *work)
{
- struct net_local *nl = netdev_priv(dev);
+ struct net_local *nl =
+ container_of(work, struct net_local, timer.work);
if (!(atomic_read (&nl->kill_timer))) {
- plip_interrupt (-1, dev);
+ plip_interrupt (-1, nl->dev);
schedule_delayed_work(&nl->timer, 1);
}
@@ -1284,6 +1287,7 @@ static void plip_attach (struct parport *port)
}
nl = netdev_priv(dev);
+ nl->dev = dev;
nl->pardev = parport_register_device(port, name, plip_preempt,
plip_wakeup, plip_interrupt,
0, dev);
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 0adee733b761..315d5c3fc66a 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -393,7 +393,7 @@ static int pppoe_rcv(struct sk_buff *skb,
po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
if (po != NULL)
- return sk_receive_skb(sk_pppox(po), skb);
+ return sk_receive_skb(sk_pppox(po), skb, 0);
drop:
kfree_skb(skb);
out:
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index ec640f6229ae..d79d141a601d 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2008,7 +2008,7 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
"%s: Another function issued a reset to the "
"chip. ISR value = %x.\n", ndev->name, value);
}
- queue_work(qdev->workqueue, &qdev->reset_work);
+ queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0);
spin_unlock(&qdev->adapter_lock);
} else if (value & ISP_IMR_DISABLE_CMPL_INT) {
ql_disable_interrupts(qdev);
@@ -3182,11 +3182,13 @@ static void ql3xxx_tx_timeout(struct net_device *ndev)
/*
* Wake up the worker to process this event.
*/
- queue_work(qdev->workqueue, &qdev->tx_timeout_work);
+ queue_delayed_work(qdev->workqueue, &qdev->tx_timeout_work, 0);
}
-static void ql_reset_work(struct ql3_adapter *qdev)
+static void ql_reset_work(struct work_struct *work)
{
+ struct ql3_adapter *qdev =
+ container_of(work, struct ql3_adapter, reset_work.work);
struct net_device *ndev = qdev->ndev;
u32 value;
struct ql_tx_buf_cb *tx_cb;
@@ -3278,9 +3280,12 @@ static void ql_reset_work(struct ql3_adapter *qdev)
}
}
-static void ql_tx_timeout_work(struct ql3_adapter *qdev)
+static void ql_tx_timeout_work(struct work_struct *work)
{
- ql_cycle_adapter(qdev,QL_DO_RESET);
+ struct ql3_adapter *qdev =
+ container_of(work, struct ql3_adapter, tx_timeout_work.work);
+
+ ql_cycle_adapter(qdev, QL_DO_RESET);
}
static void ql_get_board_info(struct ql3_adapter *qdev)
@@ -3459,9 +3464,8 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
netif_stop_queue(ndev);
qdev->workqueue = create_singlethread_workqueue(ndev->name);
- INIT_WORK(&qdev->reset_work, (void (*)(void *))ql_reset_work, qdev);
- INIT_WORK(&qdev->tx_timeout_work,
- (void (*)(void *))ql_tx_timeout_work, qdev);
+ INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
+ INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
init_timer(&qdev->adapter_timer);
qdev->adapter_timer.function = ql3xxx_timer;
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 65da2c0bfda6..ea94de7fd071 100644
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1186,8 +1186,8 @@ struct ql3_adapter {
u32 numPorts;
struct net_device_stats stats;
struct workqueue_struct *workqueue;
- struct work_struct reset_work;
- struct work_struct tx_timeout_work;
+ struct delayed_work reset_work;
+ struct delayed_work tx_timeout_work;
u32 max_frame_size;
};
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2379d83768d6..f83b41d4cb0e 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -425,6 +425,7 @@ struct ring_info {
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
+ struct net_device *dev;
struct net_device_stats stats; /* statistics of net device */
spinlock_t lock; /* spin lock flag */
u32 msg_enable;
@@ -456,7 +457,7 @@ struct rtl8169_private {
void (*phy_reset_enable)(void __iomem *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
- struct work_struct task;
+ struct delayed_work task;
unsigned wol_enabled : 1;
};
@@ -1508,6 +1509,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev);
+ tp->dev = dev;
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
/* enable device (incl. PCI PM wakeup and hotplug setup) */
@@ -1780,7 +1782,7 @@ static int rtl8169_open(struct net_device *dev)
if (retval < 0)
goto err_free_rx;
- INIT_WORK(&tp->task, NULL, dev);
+ INIT_DELAYED_WORK(&tp->task, NULL);
rtl8169_hw_start(dev);
@@ -2133,11 +2135,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
tp->cur_tx = tp->dirty_tx = 0;
}
-static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *))
+static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
{
struct rtl8169_private *tp = netdev_priv(dev);
- PREPARE_WORK(&tp->task, task, dev);
+ PREPARE_DELAYED_WORK(&tp->task, task);
schedule_delayed_work(&tp->task, 4);
}
@@ -2156,9 +2158,11 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
netif_poll_enable(dev);
}
-static void rtl8169_reinit_task(void *_data)
+static void rtl8169_reinit_task(struct work_struct *work)
{
- struct net_device *dev = _data;
+ struct rtl8169_private *tp =
+ container_of(work, struct rtl8169_private, task.work);
+ struct net_device *dev = tp->dev;
int ret;
if (netif_running(dev)) {
@@ -2181,10 +2185,11 @@ static void rtl8169_reinit_task(void *_data)
}
}
-static void rtl8169_reset_task(void *_data)
+static void rtl8169_reset_task(struct work_struct *work)
{
- struct net_device *dev = _data;
- struct rtl8169_private *tp = netdev_priv(dev);
+ struct rtl8169_private *tp =
+ container_of(work, struct rtl8169_private, task.work);
+ struct net_device *dev = tp->dev;
if (!netif_running(dev))
return;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 33569ec9dbfc..250cdbeefdfd 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5872,9 +5872,9 @@ static void s2io_tasklet(unsigned long dev_addr)
* Description: Sets the link status for the adapter
*/
-static void s2io_set_link(unsigned long data)
+static void s2io_set_link(struct work_struct *work)
{
- nic_t *nic = (nic_t *) data;
+ nic_t *nic = container_of(work, nic_t, set_link_task);
struct net_device *dev = nic->dev;
XENA_dev_config_t __iomem *bar0 = nic->bar0;
register u64 val64;
@@ -6379,10 +6379,10 @@ static int s2io_card_up(nic_t * sp)
* spin lock.
*/
-static void s2io_restart_nic(unsigned long data)
+static void s2io_restart_nic(struct work_struct *work)
{
- struct net_device *dev = (struct net_device *) data;
- nic_t *sp = dev->priv;
+ nic_t *sp = container_of(work, nic_t, rst_timer_task);
+ struct net_device *dev = sp->dev;
s2io_card_down(sp);
if (s2io_card_up(sp)) {
@@ -6992,10 +6992,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->tx_timeout = &s2io_tx_watchdog;
dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
- INIT_WORK(&sp->rst_timer_task,
- (void (*)(void *)) s2io_restart_nic, dev);
- INIT_WORK(&sp->set_link_task,
- (void (*)(void *)) s2io_set_link, sp);
+ INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
+ INIT_WORK(&sp->set_link_task, s2io_set_link);
pci_save_state(sp->pdev);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 12b719f4d00f..3b0bafd273c8 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -1000,7 +1000,7 @@ s2io_msix_fifo_handle(int irq, void *dev_id);
static irqreturn_t s2io_isr(int irq, void *dev_id);
static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
static const struct ethtool_ops netdev_ethtool_ops;
-static void s2io_set_link(unsigned long data);
+static void s2io_set_link(struct work_struct *work);
static int s2io_set_swapper(nic_t * sp);
static void s2io_card_down(nic_t *nic);
static int s2io_card_up(nic_t *nic);
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index d9d0a3a3c558..0d6c95c7aedf 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -750,7 +750,7 @@ int __init init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(dev_seeq);
release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index aaba458584fb..b70ed79d4121 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -280,6 +280,7 @@ enum sis190_feature {
struct sis190_private {
void __iomem *mmio_addr;
struct pci_dev *pci_dev;
+ struct net_device *dev;
struct net_device_stats stats;
spinlock_t lock;
u32 rx_buf_sz;
@@ -897,10 +898,11 @@ static void sis190_hw_start(struct net_device *dev)
netif_start_queue(dev);
}
-static void sis190_phy_task(void * data)
+static void sis190_phy_task(struct work_struct *work)
{
- struct net_device *dev = data;
- struct sis190_private *tp = netdev_priv(dev);
+ struct sis190_private *tp =
+ container_of(work, struct sis190_private, phy_task);
+ struct net_device *dev = tp->dev;
void __iomem *ioaddr = tp->mmio_addr;
int phy_id = tp->mii_if.phy_id;
u16 val;
@@ -1047,7 +1049,7 @@ static int sis190_open(struct net_device *dev)
if (rc < 0)
goto err_free_rx_1;
- INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
+ INIT_WORK(&tp->phy_task, sis190_phy_task);
sis190_request_timer(dev);
@@ -1436,6 +1438,7 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev);
+ tp->dev = dev;
tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT);
rc = pci_enable_device(pdev);
@@ -1798,7 +1801,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
sis190_init_rxfilter(dev);
- INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
+ INIT_WORK(&tp->phy_task, sis190_phy_task);
dev->open = sis190_open;
dev->stop = sis190_close;
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index a5d41ebc9fb4..92d11b961db8 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -114,6 +114,7 @@
#include <linux/dma-mapping.h>
#include <linux/ip.h>
#include <linux/mii.h>
+#include <linux/mm.h>
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
@@ -1562,7 +1563,7 @@ struct sk_buff *pMessage) /* pointer to send-message */
if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
u16 hdrlen = pMessage->h.raw - pMessage->data;
- u16 offset = hdrlen + pMessage->csum;
+ u16 offset = hdrlen + pMessage->csum_offset;
if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
(pAC->GIni.GIChipRev == 0) &&
@@ -1681,7 +1682,7 @@ struct sk_buff *pMessage) /* pointer to send-message */
*/
if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
u16 hdrlen = pMessage->h.raw - pMessage->data;
- u16 offset = hdrlen + pMessage->csum;
+ u16 offset = hdrlen + pMessage->csum_offset;
Control = BMU_STFWD;
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
index ab66d80a4455..3e7aa49afd00 100644
--- a/drivers/net/sk98lin/skgesirq.c
+++ b/drivers/net/sk98lin/skgesirq.c
@@ -1319,7 +1319,7 @@ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
#ifdef xDEBUG
- if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
+ if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
(PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
SK_U32 Stat1, Stat2, Stat3;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 27b537c8d5e3..b60f0451f6cd 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1327,10 +1327,11 @@ static void xm_check_link(struct net_device *dev)
* Since internal PHY is wired to a level triggered pin, can't
* get an interrupt when carrier is detected.
*/
-static void xm_link_timer(void *arg)
+static void xm_link_timer(struct work_struct *work)
{
- struct net_device *dev = arg;
- struct skge_port *skge = netdev_priv(arg);
+ struct skge_port *skge =
+ container_of(work, struct skge_port, link_thread.work);
+ struct net_device *dev = skge->netdev;
struct skge_hw *hw = skge->hw;
int port = skge->port;
@@ -2565,7 +2566,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
td->csum_offs = 0;
td->csum_start = offset;
- td->csum_write = offset + skb->csum;
+ td->csum_write = offset + skb->csum_offset;
} else
control = BMU_CHECK;
@@ -3072,9 +3073,9 @@ static void skge_error_irq(struct skge_hw *hw)
* because accessing phy registers requires spin wait which might
* cause excess interrupt latency.
*/
-static void skge_extirq(void *arg)
+static void skge_extirq(struct work_struct *work)
{
- struct skge_hw *hw = arg;
+ struct skge_hw *hw = container_of(work, struct skge_hw, phy_work);
int port;
mutex_lock(&hw->phy_mutex);
@@ -3456,7 +3457,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
skge->port = port;
/* Only used for Genesis XMAC */
- INIT_WORK(&skge->link_thread, xm_link_timer, dev);
+ INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer);
if (hw->chip_id != CHIP_ID_GENESIS) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
@@ -3543,7 +3544,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
hw->pdev = pdev;
mutex_init(&hw->phy_mutex);
- INIT_WORK(&hw->phy_work, skge_extirq, hw);
+ INIT_WORK(&hw->phy_work, skge_extirq);
spin_lock_init(&hw->hw_lock);
hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 537c0aaa1db8..f6223c533c01 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -389,10 +389,10 @@ enum {
/* Packet Arbiter Registers */
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
enum {
- PA_CLR_TO_TX2 = 1<<13, /* Clear IRQ Packet Timeout TX2 */
- PA_CLR_TO_TX1 = 1<<12, /* Clear IRQ Packet Timeout TX1 */
- PA_CLR_TO_RX2 = 1<<11, /* Clear IRQ Packet Timeout RX2 */
- PA_CLR_TO_RX1 = 1<<10, /* Clear IRQ Packet Timeout RX1 */
+ PA_CLR_TO_TX2 = 1<<13,/* Clear IRQ Packet Timeout TX2 */
+ PA_CLR_TO_TX1 = 1<<12,/* Clear IRQ Packet Timeout TX1 */
+ PA_CLR_TO_RX2 = 1<<11,/* Clear IRQ Packet Timeout RX2 */
+ PA_CLR_TO_RX1 = 1<<10,/* Clear IRQ Packet Timeout RX1 */
PA_ENA_TO_TX2 = 1<<9, /* Enable Timeout Timer TX2 */
PA_DIS_TO_TX2 = 1<<8, /* Disable Timeout Timer TX2 */
PA_ENA_TO_TX1 = 1<<7, /* Enable Timeout Timer TX1 */
@@ -481,14 +481,14 @@ enum {
/* RAM Buffer Register Offsets */
enum {
- RB_START = 0x00,/* 32 bit RAM Buffer Start Address */
+ RB_START= 0x00,/* 32 bit RAM Buffer Start Address */
RB_END = 0x04,/* 32 bit RAM Buffer End Address */
RB_WP = 0x08,/* 32 bit RAM Buffer Write Pointer */
RB_RP = 0x0c,/* 32 bit RAM Buffer Read Pointer */
- RB_RX_UTPP = 0x10,/* 32 bit Rx Upper Threshold, Pause Packet */
- RB_RX_LTPP = 0x14,/* 32 bit Rx Lower Threshold, Pause Packet */
- RB_RX_UTHP = 0x18,/* 32 bit Rx Upper Threshold, High Prio */
- RB_RX_LTHP = 0x1c,/* 32 bit Rx Lower Threshold, High Prio */
+ RB_RX_UTPP= 0x10,/* 32 bit Rx Upper Threshold, Pause Packet */
+ RB_RX_LTPP= 0x14,/* 32 bit Rx Lower Threshold, Pause Packet */
+ RB_RX_UTHP= 0x18,/* 32 bit Rx Upper Threshold, High Prio */
+ RB_RX_LTHP= 0x1c,/* 32 bit Rx Lower Threshold, High Prio */
/* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
RB_PC = 0x20,/* 32 bit RAM Buffer Packet Counter */
RB_LEV = 0x24,/* 32 bit RAM Buffer Level Register */
@@ -532,7 +532,7 @@ enum {
PHY_ADDR_MARV = 0,
};
-#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+#define RB_ADDR(offs, queue) ((u16)B16_RAM_REGS + (u16)(queue) + (offs))
/* Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only) */
enum {
@@ -578,15 +578,15 @@ enum {
MFF_DIS_TIST = 1<<2, /* Disable Time Stamp Gener */
MFF_CLR_INTIST = 1<<1, /* Clear IRQ No Time Stamp */
MFF_CLR_INSTAT = 1<<0, /* Clear IRQ No Status */
-#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
+ MFF_RX_CTRL_DEF = MFF_ENA_TIM_PAT,
};
/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
enum {
- MFF_CLR_PERR = 1<<15, /* Clear Parity Error IRQ */
- /* Bit 14: reserved */
- MFF_ENA_PKT_REC = 1<<13, /* Enable Packet Recovery */
- MFF_DIS_PKT_REC = 1<<12, /* Disable Packet Recovery */
+ MFF_CLR_PERR = 1<<15, /* Clear Parity Error IRQ */
+
+ MFF_ENA_PKT_REC = 1<<13, /* Enable Packet Recovery */
+ MFF_DIS_PKT_REC = 1<<12, /* Disable Packet Recovery */
MFF_ENA_W4E = 1<<7, /* Enable Wait for Empty */
MFF_DIS_W4E = 1<<6, /* Disable Wait for Empty */
@@ -595,9 +595,10 @@ enum {
MFF_DIS_LOOPB = 1<<2, /* Disable Loopback */
MFF_CLR_MAC_RST = 1<<1, /* Clear XMAC Reset */
MFF_SET_MAC_RST = 1<<0, /* Set XMAC Reset */
+
+ MFF_TX_CTRL_DEF = MFF_ENA_PKT_REC | (u16) MFF_ENA_TIM_PAT | MFF_ENA_FLUSH,
};
-#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
@@ -1304,8 +1305,8 @@ enum {
/* special defines for FIBER (88E1011S only) */
enum {
- PHY_M_AN_ASP_X = 1<<8, /* Asymmetric Pause */
- PHY_M_AN_PC_X = 1<<7, /* MAC Pause implemented */
+ PHY_M_AN_ASP_X = 1<<8, /* Asymmetric Pause */
+ PHY_M_AN_PC_X = 1<<7, /* MAC Pause implemented */
PHY_M_AN_1000X_AHD = 1<<6, /* Advertise 10000Base-X Half Duplex */
PHY_M_AN_1000X_AFD = 1<<5, /* Advertise 10000Base-X Full Duplex */
};
@@ -1320,7 +1321,7 @@ enum {
/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum {
- PHY_M_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */
+ PHY_M_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */
PHY_M_1000C_MSE = 1<<12, /* Manual Master/Slave Enable */
PHY_M_1000C_MSC = 1<<11, /* M/S Configuration (1=Master) */
PHY_M_1000C_MPD = 1<<10, /* Multi-Port Device */
@@ -1349,7 +1350,7 @@ enum {
PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */
};
-#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
+#define PHY_M_PC_MDI_XMODE(x) ((((u16)(x)<<5) & PHY_M_PC_MDIX_MSK)
enum {
PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */
@@ -1432,24 +1433,24 @@ enum {
PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */
PHY_M_EC_M_DSC_MSK = 3<<10, /* Bit 11..10: Master Downshift Counter */
/* (88E1011 only) */
- PHY_M_EC_S_DSC_MSK = 3<<8,/* Bit 9.. 8: Slave Downshift Counter */
+ PHY_M_EC_S_DSC_MSK = 3<<8, /* Bit 9.. 8: Slave Downshift Counter */
/* (88E1011 only) */
- PHY_M_EC_M_DSC_MSK2 = 7<<9,/* Bit 11.. 9: Master Downshift Counter */
+ PHY_M_EC_M_DSC_MSK2 = 7<<9, /* Bit 11.. 9: Master Downshift Counter */
/* (88E1111 only) */
- PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */
+ PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */
/* !!! Errata in spec. (1 = disable) */
- PHY_M_EC_RX_TIM_CT = 1<<7, /* RGMII Rx Timing Control*/
- PHY_M_EC_MAC_S_MSK = 7<<4,/* Bit 6.. 4: Def. MAC interface speed */
- PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
- PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */
- PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */
- PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */};
-
-#define PHY_M_EC_M_DSC(x) ((x)<<10) /* 00=1x; 01=2x; 10=3x; 11=4x */
-#define PHY_M_EC_S_DSC(x) ((x)<<8) /* 00=dis; 01=1x; 10=2x; 11=3x */
-#define PHY_M_EC_MAC_S(x) ((x)<<4) /* 01X=0; 110=2.5; 111=25 (MHz) */
-
-#define PHY_M_EC_M_DSC_2(x) ((x)<<9) /* 000=1x; 001=2x; 010=3x; 011=4x */
+ PHY_M_EC_RX_TIM_CT = 1<<7, /* RGMII Rx Timing Control*/
+ PHY_M_EC_MAC_S_MSK = 7<<4, /* Bit 6.. 4: Def. MAC interface speed */
+ PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
+ PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */
+ PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */
+ PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */};
+
+#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10) /* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8) /* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_MAC_S(x) ((u16)(x)<<4) /* 01X=0; 110=2.5; 111=25 (MHz) */
+
+#define PHY_M_EC_M_DSC_2(x) ((u16)(x)<<9) /* 000=1x; 001=2x; 010=3x; 011=4x */
/* 100=5x; 101=6x; 110=7x; 111=8x */
enum {
MAC_TX_CLK_0_MHZ = 2,
@@ -1468,10 +1469,12 @@ enum {
PHY_M_LEDC_LK_C_MSK = 7<<3,/* Bit 5.. 3: Link Control Mask */
/* (88E1111 only) */
};
+#define PHY_M_LED_PULS_DUR(x) (((u16)(x)<<12) & PHY_M_LEDC_PULS_MSK)
+#define PHY_M_LED_BLINK_RT(x) (((u16)(x)<<8) & PHY_M_LEDC_BL_R_MSK)
enum {
- PHY_M_LEDC_LINK_MSK = 3<<3,/* Bit 4.. 3: Link Control Mask */
- /* (88E1011 only) */
+ PHY_M_LEDC_LINK_MSK = 3<<3, /* Bit 4.. 3: Link Control Mask */
+ /* (88E1011 only) */
PHY_M_LEDC_DP_CTRL = 1<<2, /* Duplex Control */
PHY_M_LEDC_DP_C_MSB = 1<<2, /* Duplex Control (MSB, 88E1111 only) */
PHY_M_LEDC_RX_CTRL = 1<<1, /* Rx Activity / Link */
@@ -1479,27 +1482,24 @@ enum {
PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */
};
-#define PHY_M_LED_PULS_DUR(x) (((x)<<12) & PHY_M_LEDC_PULS_MSK)
-
enum {
- PULS_NO_STR = 0,/* no pulse stretching */
- PULS_21MS = 1,/* 21 ms to 42 ms */
- PULS_42MS = 2,/* 42 ms to 84 ms */
- PULS_84MS = 3,/* 84 ms to 170 ms */
- PULS_170MS = 4,/* 170 ms to 340 ms */
- PULS_340MS = 5,/* 340 ms to 670 ms */
- PULS_670MS = 6,/* 670 ms to 1.3 s */
- PULS_1300MS = 7,/* 1.3 s to 2.7 s */
+ PULS_NO_STR = 0, /* no pulse stretching */
+ PULS_21MS = 1, /* 21 ms to 42 ms */
+ PULS_42MS = 2, /* 42 ms to 84 ms */
+ PULS_84MS = 3, /* 84 ms to 170 ms */
+ PULS_170MS = 4, /* 170 ms to 340 ms */
+ PULS_340MS = 5, /* 340 ms to 670 ms */
+ PULS_670MS = 6, /* 670 ms to 1.3 s */
+ PULS_1300MS = 7, /* 1.3 s to 2.7 s */
};
-#define PHY_M_LED_BLINK_RT(x) (((x)<<8) & PHY_M_LEDC_BL_R_MSK)
enum {
- BLINK_42MS = 0,/* 42 ms */
- BLINK_84MS = 1,/* 84 ms */
- BLINK_170MS = 2,/* 170 ms */
- BLINK_340MS = 3,/* 340 ms */
- BLINK_670MS = 4,/* 670 ms */
+ BLINK_42MS = 0, /* 42 ms */
+ BLINK_84MS = 1, /* 84 ms */
+ BLINK_170MS = 2, /* 170 ms */
+ BLINK_340MS = 3, /* 340 ms */
+ BLINK_670MS = 4, /* 670 ms */
};
/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
@@ -1525,7 +1525,7 @@ enum {
PHY_M_EC2_FO_IMPED = 1<<5, /* Fiber Output Impedance */
PHY_M_EC2_FO_M_CLK = 1<<4, /* Fiber Mode Clock Enable */
PHY_M_EC2_FO_BOOST = 1<<3, /* Fiber Output Boost */
- PHY_M_EC2_FO_AM_MSK = 7,/* Bit 2.. 0: Fiber Output Amplitude */
+ PHY_M_EC2_FO_AM_MSK = 7, /* Bit 2.. 0: Fiber Output Amplitude */
};
/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
@@ -1550,7 +1550,7 @@ enum {
PHY_M_CABD_DIS_WAIT = 1<<15, /* Disable Waiting Period (Page 1) */
/* (88E1111 only) */
PHY_M_CABD_STAT_MSK = 3<<13, /* Bit 14..13: Status Mask */
- PHY_M_CABD_AMPL_MSK = 0x1f<<8,/* Bit 12.. 8: Amplitude Mask */
+ PHY_M_CABD_AMPL_MSK = 0x1f<<8, /* Bit 12.. 8: Amplitude Mask */
/* (88E1111 only) */
PHY_M_CABD_DIST_MSK = 0xff, /* Bit 7.. 0: Distance Mask */
};
@@ -1605,9 +1605,9 @@ enum {
/***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/
enum {
- PHY_M_LEDC_LOS_MSK = 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */
+ PHY_M_LEDC_LOS_MSK = 0xf<<12, /* Bit 15..12: LOS LED Ctrl. Mask */
PHY_M_LEDC_INIT_MSK = 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */
- PHY_M_LEDC_STA1_MSK = 0xf<<4,/* Bit 7.. 4: STAT1 LED Ctrl. Mask */
+ PHY_M_LEDC_STA1_MSK = 0xf<<4, /* Bit 7.. 4: STAT1 LED Ctrl. Mask */
PHY_M_LEDC_STA0_MSK = 0xf, /* Bit 3.. 0: STAT0 LED Ctrl. Mask */
};
@@ -1804,8 +1804,8 @@ enum {
/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
enum {
- GM_SMI_CT_PHY_A_MSK = 0x1f<<11,/* Bit 15..11: PHY Device Address */
- GM_SMI_CT_REG_A_MSK = 0x1f<<6,/* Bit 10.. 6: PHY Register Address */
+ GM_SMI_CT_PHY_A_MSK = 0x1f<<11, /* Bit 15..11: PHY Device Address */
+ GM_SMI_CT_REG_A_MSK = 0x1f<<6, /* Bit 10.. 6: PHY Register Address */
GM_SMI_CT_OP_RD = 1<<5, /* Bit 5: OpCode Read (0=Write)*/
GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */
GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */
@@ -1875,9 +1875,9 @@ enum {
/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
enum {
- GMF_WSP_TST_ON = 1<<18,/* Write Shadow Pointer Test On */
- GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */
- GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */
+ GMF_WSP_TST_ON = 1<<18, /* Write Shadow Pointer Test On */
+ GMF_WSP_TST_OFF = 1<<17, /* Write Shadow Pointer Test Off */
+ GMF_WSP_STEP = 1<<16, /* Write Shadow Pointer Step/Increment */
GMF_CLI_TX_FU = 1<<6, /* Clear IRQ Tx FIFO Underrun */
GMF_CLI_TX_FC = 1<<5, /* Clear IRQ Tx Frame Complete */
@@ -2111,18 +2111,18 @@ enum {
/* XM_MMU_CMD 16 bit r/w MMU Command Register */
enum {
- XM_MMU_PHY_RDY = 1<<12,/* Bit 12: PHY Read Ready */
- XM_MMU_PHY_BUSY = 1<<11,/* Bit 11: PHY Busy */
- XM_MMU_IGN_PF = 1<<10,/* Bit 10: Ignore Pause Frame */
- XM_MMU_MAC_LB = 1<<9, /* Bit 9: Enable MAC Loopback */
- XM_MMU_FRC_COL = 1<<7, /* Bit 7: Force Collision */
- XM_MMU_SIM_COL = 1<<6, /* Bit 6: Simulate Collision */
- XM_MMU_NO_PRE = 1<<5, /* Bit 5: No MDIO Preamble */
- XM_MMU_GMII_FD = 1<<4, /* Bit 4: GMII uses Full Duplex */
- XM_MMU_RAT_CTRL = 1<<3, /* Bit 3: Enable Rate Control */
- XM_MMU_GMII_LOOP= 1<<2, /* Bit 2: PHY is in Loopback Mode */
- XM_MMU_ENA_RX = 1<<1, /* Bit 1: Enable Receiver */
- XM_MMU_ENA_TX = 1<<0, /* Bit 0: Enable Transmitter */
+ XM_MMU_PHY_RDY = 1<<12, /* Bit 12: PHY Read Ready */
+ XM_MMU_PHY_BUSY = 1<<11, /* Bit 11: PHY Busy */
+ XM_MMU_IGN_PF = 1<<10, /* Bit 10: Ignore Pause Frame */
+ XM_MMU_MAC_LB = 1<<9, /* Bit 9: Enable MAC Loopback */
+ XM_MMU_FRC_COL = 1<<7, /* Bit 7: Force Collision */
+ XM_MMU_SIM_COL = 1<<6, /* Bit 6: Simulate Collision */
+ XM_MMU_NO_PRE = 1<<5, /* Bit 5: No MDIO Preamble */
+ XM_MMU_GMII_FD = 1<<4, /* Bit 4: GMII uses Full Duplex */
+ XM_MMU_RAT_CTRL = 1<<3, /* Bit 3: Enable Rate Control */
+ XM_MMU_GMII_LOOP= 1<<2, /* Bit 2: PHY is in Loopback Mode */
+ XM_MMU_ENA_RX = 1<<1, /* Bit 1: Enable Receiver */
+ XM_MMU_ENA_TX = 1<<0, /* Bit 0: Enable Transmitter */
};
@@ -2456,7 +2456,7 @@ struct skge_port {
struct net_device_stats net_stats;
- struct work_struct link_thread;
+ struct delayed_work link_thread;
enum pause_control flow_control;
enum pause_status flow_status;
u8 rx_csum;
@@ -2506,7 +2506,7 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
}
/* MAC Related Registers inside the device. */
-#define SK_REG(port,reg) (((port)<<7)+(reg))
+#define SK_REG(port,reg) (((port)<<7)+(u16)(reg))
#define SK_XMAC_REG(port, reg) \
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 0ef1848b9761..fb1d2c30c1bb 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -100,33 +100,32 @@ module_param(idle_timeout, int, 0);
MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
static const struct pci_device_id sky2_id_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
- { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
+ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) }, /* DGE-560SX */
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, /* 88E8022 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, /* 88E8061 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) }, /* 88E8062 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) }, /* 88E8021 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) }, /* 88E8022 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) }, /* 88E8061 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) }, /* 88E8062 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, /* 88E8035 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
{ 0 }
};
@@ -522,7 +521,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
/* turn off the Rx LED (LED_RX) */
- ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+ ledover &= ~PHY_M_LED_MO_RX;
}
if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
@@ -545,7 +544,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
/* turn on 100 Mbps LED (LED_LINK100) */
- ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+ ledover |= PHY_M_LED_MO_100;
}
if (ledover)
@@ -697,10 +696,15 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
}
-/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
+/* Assign Ram Buffer allocation to queue */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
{
- pr_debug(PFX "q %d %#x %#x\n", q, start, end);
+ u32 end;
+
+ /* convert from K bytes to qwords used for hw register */
+ start *= 1024/8;
+ space *= 1024/8;
+ end = start + space - 1;
sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -709,7 +713,6 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
sky2_write32(hw, RB_ADDR(q, RB_RP), start);
if (q == Q_R1 || q == Q_R2) {
- u32 space = end - start + 1;
u32 tp = space - space/4;
/* On receive queue's set the thresholds
@@ -1059,11 +1062,16 @@ static int sky2_rx_start(struct sky2_port *sky2)
sky2->rx_put = sky2->rx_next = 0;
sky2_qset(hw, rxq);
+ /* On PCI express lowering the watermark gives better performance */
+ if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
+ sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX);
+
+ /* These chips have no ram buffer?
+ * MAC Rx RAM Read is controlled by hardware */
if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
- (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) {
- /* MAC Rx RAM Read is controlled by hardware */
+ (hw->chip_rev == CHIP_REV_YU_EC_U_A1
+ || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS);
- }
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
@@ -1139,7 +1147,7 @@ static int sky2_up(struct net_device *dev)
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port;
- u32 ramsize, rxspace, imask;
+ u32 ramsize, imask;
int cap, err = -ENOMEM;
struct net_device *otherdev = hw->dev[sky2->port^1];
@@ -1192,20 +1200,25 @@ static int sky2_up(struct net_device *dev)
sky2_mac_init(hw, port);
- /* Determine available ram buffer space in qwords. */
- ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
+ /* Register is number of 4K blocks on internal RAM buffer. */
+ ramsize = sky2_read8(hw, B2_E_0) * 4;
+ printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize);
- if (ramsize > 6*1024/8)
- rxspace = ramsize - (ramsize + 2) / 3;
- else
- rxspace = ramsize / 2;
+ if (ramsize > 0) {
+ u32 rxspace;
- sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
- sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
+ if (ramsize < 16)
+ rxspace = ramsize / 2;
+ else
+ rxspace = 8 + (2*(ramsize - 16))/3;
+
+ sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+ sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
- /* Make sure SyncQ is disabled */
- sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
- RB_RST_SET);
+ /* Make sure SyncQ is disabled */
+ sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+ RB_RST_SET);
+ }
sky2_qset(hw, txqaddr[port]);
@@ -1350,7 +1363,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
u32 tcpsum;
tcpsum = offset << 16; /* sum start */
- tcpsum |= offset + skb->csum; /* sum write */
+ tcpsum |= offset + skb->csum_offset; /* sum write */
ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
if (skb->nh.iph->protocol == IPPROTO_UDP)
@@ -2917,18 +2930,8 @@ static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
default:
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
- gm_phy_write(hw, port, PHY_MARV_LED_OVER,
- on ? PHY_M_LED_MO_DUP(MO_LED_ON) |
- PHY_M_LED_MO_10(MO_LED_ON) |
- PHY_M_LED_MO_100(MO_LED_ON) |
- PHY_M_LED_MO_1000(MO_LED_ON) |
- PHY_M_LED_MO_RX(MO_LED_ON)
- : PHY_M_LED_MO_DUP(MO_LED_OFF) |
- PHY_M_LED_MO_10(MO_LED_OFF) |
- PHY_M_LED_MO_100(MO_LED_OFF) |
- PHY_M_LED_MO_1000(MO_LED_OFF) |
- PHY_M_LED_MO_RX(MO_LED_OFF));
-
+ gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+ on ? PHY_M_LED_ALL : 0);
}
}
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 7760545edbf2..6ed1d47dbbd3 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -608,7 +608,7 @@ enum {
PHY_ADDR_MARV = 0,
};
-#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+#define RB_ADDR(offs, queue) ((u16) B16_RAM_REGS + (queue) + (offs))
enum {
@@ -680,6 +680,7 @@ enum {
BMU_FIFO_ENA | BMU_OP_ON,
BMU_WM_DEFAULT = 0x600,
+ BMU_WM_PEX = 0x80,
};
/* Tx BMU Control / Status Registers (Yukon-2) */
@@ -1060,7 +1061,7 @@ enum {
PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */
};
-#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
+#define PHY_M_PC_MDI_XMODE(x) (((u16)(x)<<5) & PHY_M_PC_MDIX_MSK)
enum {
PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */
@@ -1156,13 +1157,13 @@ enum {
PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */
PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */};
-#define PHY_M_EC_M_DSC(x) ((x)<<10 & PHY_M_EC_M_DSC_MSK)
+#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK)
/* 00=1x; 01=2x; 10=3x; 11=4x */
-#define PHY_M_EC_S_DSC(x) ((x)<<8 & PHY_M_EC_S_DSC_MSK)
+#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK)
/* 00=dis; 01=1x; 10=2x; 11=3x */
-#define PHY_M_EC_DSC_2(x) ((x)<<9 & PHY_M_EC_M_DSC_MSK2)
+#define PHY_M_EC_DSC_2(x) ((u16)(x)<<9 & PHY_M_EC_M_DSC_MSK2)
/* 000=1x; 001=2x; 010=3x; 011=4x */
-#define PHY_M_EC_MAC_S(x) ((x)<<4 & PHY_M_EC_MAC_S_MSK)
+#define PHY_M_EC_MAC_S(x) ((u16)(x)<<4 & PHY_M_EC_MAC_S_MSK)
/* 01X=0; 110=2.5; 111=25 (MHz) */
/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
@@ -1173,7 +1174,7 @@ enum {
};
/* !!! Errata in spec. (1 = disable) */
-#define PHY_M_PC_DSC(x) (((x)<<12) & PHY_M_PC_DSC_MSK)
+#define PHY_M_PC_DSC(x) (((u16)(x)<<12) & PHY_M_PC_DSC_MSK)
/* 100=5x; 101=6x; 110=7x; 111=8x */
enum {
MAC_TX_CLK_0_MHZ = 2,
@@ -1203,7 +1204,7 @@ enum {
PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */
};
-#define PHY_M_LED_PULS_DUR(x) (((x)<<12) & PHY_M_LEDC_PULS_MSK)
+#define PHY_M_LED_PULS_DUR(x) (((u16)(x)<<12) & PHY_M_LEDC_PULS_MSK)
/***** PHY_MARV_PHY_STAT (page 3)16 bit r/w Polarity Control Reg. *****/
enum {
@@ -1233,7 +1234,7 @@ enum {
PULS_1300MS = 7,/* 1.3 s to 2.7 s */
};
-#define PHY_M_LED_BLINK_RT(x) (((x)<<8) & PHY_M_LEDC_BL_R_MSK)
+#define PHY_M_LED_BLINK_RT(x) (((u16)(x)<<8) & PHY_M_LEDC_BL_R_MSK)
enum {
BLINK_42MS = 0,/* 42 ms */
@@ -1243,21 +1244,18 @@ enum {
BLINK_670MS = 4,/* 670 ms */
};
-/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
-#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */
- /* Bit 13..12: reserved */
-#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */
-#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */
-#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */
-#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */
-#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */
-#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */
-
+/**** PHY_MARV_LED_OVER 16 bit r/w LED control */
enum {
- MO_LED_NORM = 0,
- MO_LED_BLINK = 1,
- MO_LED_OFF = 2,
- MO_LED_ON = 3,
+ PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */
+ PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */
+ PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */
+ PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */
+ PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */
+ PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */
+
+ PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10
+ | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000
+ | PHY_M_LED_MO_RX,
};
/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
@@ -1294,9 +1292,9 @@ enum {
PHY_M_FELP_LED0_MSK = 0xf, /* Bit 3.. 0: LED0 Mask (SPEED) */
};
-#define PHY_M_FELP_LED2_CTRL(x) (((x)<<8) & PHY_M_FELP_LED2_MSK)
-#define PHY_M_FELP_LED1_CTRL(x) (((x)<<4) & PHY_M_FELP_LED1_MSK)
-#define PHY_M_FELP_LED0_CTRL(x) (((x)<<0) & PHY_M_FELP_LED0_MSK)
+#define PHY_M_FELP_LED2_CTRL(x) (((u16)(x)<<8) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x) (((u16)(x)<<4) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x) (((u16)(x)<<0) & PHY_M_FELP_LED0_MSK)
enum {
LED_PAR_CTRL_COLX = 0x00,
@@ -1552,8 +1550,8 @@ enum {
GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */
};
-#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
-#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK)
+#define GM_SMI_CT_PHY_AD(x) (((u16)(x)<<11) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x) (((u16)(x)<<6) & GM_SMI_CT_REG_A_MSK)
/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
enum {
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index 889ef0d7c374..d70bc9795346 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -593,7 +593,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
index e10755ec5def..2c5319c62fa5 100644
--- a/drivers/net/smc-ultra32.c
+++ b/drivers/net/smc-ultra32.c
@@ -437,7 +437,7 @@ int __init init_module(void)
return -ENXIO;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index c0d13d650913..bd6e84506c29 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -1616,7 +1616,7 @@ int __init init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(devSMC9194);
free_irq(devSMC9194->irq, devSMC9194);
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 95b6478f55c6..e62a9586fb95 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -210,6 +210,7 @@ struct smc_local {
/* work queue */
struct work_struct phy_configure;
+ struct net_device *dev;
int work_pending;
spinlock_t lock;
@@ -1114,10 +1115,11 @@ static void smc_phy_check_media(struct net_device *dev, int init)
* of autonegotiation.) If the RPC ANEG bit is cleared, the selection
* is controlled by the RPC SPEED and RPC DPLX bits.
*/
-static void smc_phy_configure(void *data)
+static void smc_phy_configure(struct work_struct *work)
{
- struct net_device *dev = data;
- struct smc_local *lp = netdev_priv(dev);
+ struct smc_local *lp =
+ container_of(work, struct smc_local, phy_configure);
+ struct net_device *dev = lp->dev;
void __iomem *ioaddr = lp->base;
int phyaddr = lp->mii.phy_id;
int my_phy_caps; /* My PHY capabilities */
@@ -1592,7 +1594,7 @@ smc_open(struct net_device *dev)
/* Configure the PHY, initialize the link state */
if (lp->phy_type != 0)
- smc_phy_configure(dev);
+ smc_phy_configure(&lp->phy_configure);
else {
spin_lock_irq(&lp->lock);
smc_10bt_check_media(dev, 1);
@@ -1972,7 +1974,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
#endif
tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
- INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
+ INIT_WORK(&lp->phy_configure, smc_phy_configure);
+ lp->dev = dev;
lp->mii.phy_id_mask = 0x1f;
lp->mii.reg_num_mask = 0x1f;
lp->mii.force_media = 0;
@@ -2322,7 +2325,7 @@ static int smc_drv_resume(struct platform_device *dev)
smc_reset(ndev);
smc_enable(ndev);
if (lp->phy_type != 0)
- smc_phy_configure(ndev);
+ smc_phy_configure(&lp->phy_configure);
netif_device_attach(ndev);
}
}
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index a8640169fc77..9367c574477a 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -238,7 +238,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
-#define SMC_inb(a, r) inb((u32)a) + (r))
+#define SMC_inb(a, r) inb(((u32)a) + (r))
#define SMC_inw(a, r) inw(((u32)a) + (r))
#define SMC_outb(v, a, r) outb(v, ((u32)a) + (r))
#define SMC_outw(v, a, r) outw(v, ((u32)a) + (r))
@@ -434,6 +434,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define SMC_IRQ_FLAGS (0)
+#elif defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT 1
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 1
+#define SMC_NOWAIT 1
+
+#define SMC_inb(a, r) readb((a) + (r))
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_inl(a, r) readl((a) + (r))
+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_outl(v, a, r) writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS (0)
+
#else
#define SMC_CAN_USE_8BIT 1
@@ -1216,7 +1234,7 @@ static const char * chip_ids[ 16 ] = {
if (SMC_CAN_USE_32BIT) { \
void *__ptr = (p); \
int __len = (l); \
- void *__ioaddr = ioaddr; \
+ void __iomem *__ioaddr = ioaddr; \
if (__len >= 2 && (unsigned long)__ptr & 2) { \
__len -= 2; \
SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \
@@ -1240,7 +1258,7 @@ static const char * chip_ids[ 16 ] = {
if (SMC_CAN_USE_32BIT) { \
void *__ptr = (p); \
int __len = (l); \
- void *__ioaddr = ioaddr; \
+ void __iomem *__ioaddr = ioaddr; \
if ((unsigned long)__ptr & 2) { \
/* \
* We want 32bit alignment here. \
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index cef7e6671c49..ebb6aa39f9c7 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -88,12 +88,11 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
static inline u32
spider_net_read_reg(struct spider_net_card *card, u32 reg)
{
- u32 value;
-
- value = readl(card->regs + reg);
- value = le32_to_cpu(value);
-
- return value;
+ /* We use the powerpc specific variants instead of readl_be() because
+ * we know spidernet is not a real PCI device and we can thus avoid the
+ * performance hit caused by the PCI workarounds.
+ */
+ return in_be32(card->regs + reg);
}
/**
@@ -105,8 +104,11 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg)
static inline void
spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
{
- value = cpu_to_le32(value);
- writel(value, card->regs + reg);
+ /* We use the powerpc specific variants instead of writel_be() because
+ * we know spidernet is not a real PCI device and we can thus avoid the
+ * performance hit caused by the PCI workarounds.
+ */
+ out_be32(card->regs + reg, value);
}
/** spider_net_write_phy - write to phy register
@@ -1937,10 +1939,11 @@ spider_net_stop(struct net_device *netdev)
* called as task when tx hangs, resets interface (if interface is up)
*/
static void
-spider_net_tx_timeout_task(void *data)
+spider_net_tx_timeout_task(struct work_struct *work)
{
- struct net_device *netdev = data;
- struct spider_net_card *card = netdev_priv(netdev);
+ struct spider_net_card *card =
+ container_of(work, struct spider_net_card, tx_timeout_task);
+ struct net_device *netdev = card->netdev;
if (!(netdev->flags & IFF_UP))
goto out;
@@ -2114,7 +2117,7 @@ spider_net_alloc_card(void)
card = netdev_priv(netdev);
card->netdev = netdev;
card->msg_enable = SPIDER_NET_DEFAULT_MSG;
- INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev);
+ INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task);
init_waitqueue_head(&card->waitq);
atomic_set(&card->tx_timeout_task_counter, 0);
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 7a0aee6c869d..bf873ea25797 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -41,6 +41,7 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
+#include <linux/mm.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index b865db363ba0..c62e85d89f41 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -38,6 +38,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne
#include <linux/skbuff.h>
#include <linux/bitops.h>
+#include <asm/cacheflush.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -944,7 +945,7 @@ static void set_multicast_list( struct net_device *dev )
static struct net_device *sun3lance_dev;
-int init_module(void)
+int __init init_module(void)
{
sun3lance_dev = sun3lance_probe(-1);
if (IS_ERR(sun3lance_dev))
@@ -952,7 +953,7 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
unregister_netdev(sun3lance_dev);
#ifdef CONFIG_SUN3
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 253e96e7ad20..785e4a535f9e 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -56,6 +56,7 @@
#include <linux/if_vlan.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/mm.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1030,7 +1031,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
u64 csum_start_off, csum_stuff_off;
csum_start_off = (u64) (skb->h.raw - skb->data);
- csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data);
+ csum_stuff_off = csum_start_off + skb->csum_offset;
ctrl = (TXDCTRL_CENAB |
(csum_start_off << 15) |
@@ -2281,9 +2282,9 @@ static void gem_do_stop(struct net_device *dev, int wol)
}
}
-static void gem_reset_task(void *data)
+static void gem_reset_task(struct work_struct *work)
{
- struct gem *gp = (struct gem *) data;
+ struct gem *gp = container_of(work, struct gem, reset_task);
mutex_lock(&gp->pm_mutex);
@@ -3043,7 +3044,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->link_timer.function = gem_link_timer;
gp->link_timer.data = (unsigned long) gp;
- INIT_WORK(&gp->reset_task, gem_reset_task, gp);
+ INIT_WORK(&gp->reset_task, gem_reset_task);
gp->lstate = link_down;
gp->timer_ticks = 0;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 9d7cd130c19d..ef671739cfea 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -32,6 +32,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/mm.h>
#include <linux/bitops.h>
#include <asm/system.h>
@@ -2272,7 +2273,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 csum_start_off, csum_stuff_off;
csum_start_off = (u32) (skb->h.raw - skb->data);
- csum_stuff_off = (u32) ((skb->h.raw + skb->csum) - skb->data);
+ csum_stuff_off = csum_start_off + skb->csum_offset;
tx_flags = (TXFLAG_OWN | TXFLAG_CSENABLE |
((csum_start_off << 14) & TXFLAG_CSBUFBEGIN) |
@@ -3012,6 +3013,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
#endif
err = -ENODEV;
+
+ if (pci_enable_device(pdev))
+ goto err_out;
+ pci_set_master(pdev);
+
if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
qp = quattro_pci_find(pdev);
if (qp == NULL)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index c20bb998e0e5..d9123c9adc1e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3654,9 +3654,9 @@ static void tg3_poll_controller(struct net_device *dev)
}
#endif
-static void tg3_reset_task(void *_data)
+static void tg3_reset_task(struct work_struct *work)
{
- struct tg3 *tp = _data;
+ struct tg3 *tp = container_of(work, struct tg3, reset_task);
unsigned int restart_timer;
tg3_full_lock(tp, 0);
@@ -11734,7 +11734,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
#endif
spin_lock_init(&tp->lock);
spin_lock_init(&tp->indirect_lock);
- INIT_WORK(&tp->reset_task, tg3_reset_task, tp);
+ INIT_WORK(&tp->reset_task, tg3_reset_task);
tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len);
if (tp->regs == 0UL) {
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index e14f5a00f65a..f85f00251123 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -296,6 +296,7 @@ static void TLan_SetMulticastList( struct net_device *);
static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
static void TLan_tx_timeout( struct net_device *dev);
+static void TLan_tx_timeout_work(struct work_struct *work);
static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 TLan_HandleInvalid( struct net_device *, u16 );
@@ -562,6 +563,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
priv = netdev_priv(dev);
priv->pciDev = pdev;
+ priv->dev = dev;
/* Is this a PCI device? */
if (pdev) {
@@ -634,7 +636,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
/* This will be used when we get an adapter error from
* within our irq handler */
- INIT_WORK(&priv->tlan_tqueue, (void *)(void*)TLan_tx_timeout, dev);
+ INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work);
spin_lock_init(&priv->lock);
@@ -1040,6 +1042,25 @@ static void TLan_tx_timeout(struct net_device *dev)
}
+ /***************************************************************
+ * TLan_tx_timeout_work
+ *
+ * Returns: nothing
+ *
+ * Params:
+ * work work item of device which timed out
+ *
+ **************************************************************/
+
+static void TLan_tx_timeout_work(struct work_struct *work)
+{
+ TLanPrivateInfo *priv =
+ container_of(work, TLanPrivateInfo, tlan_tqueue);
+
+ TLan_tx_timeout(priv->dev);
+}
+
+
/***************************************************************
* TLan_StartTx
diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h
index a44e2f2ef62a..41ce0b665937 100644
--- a/drivers/net/tlan.h
+++ b/drivers/net/tlan.h
@@ -170,6 +170,7 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE];
typedef struct tlan_private_tag {
struct net_device *nextDevice;
struct pci_dev *pciDev;
+ struct net_device *dev;
void *dmaStorage;
dma_addr_t dmaStorageDMA;
unsigned int dmaSize;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index bfe59865b1dd..0d97e10ccac5 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -1826,7 +1826,7 @@ static void tr_rx(struct net_device *dev)
skb->protocol = tr_type_trans(skb, dev);
if (IPv4_p) {
skb->csum = chksum;
- skb->ip_summed = 1;
+ skb->ip_summed = CHECKSUM_COMPLETE;
}
netif_rx(skb);
dev->last_rx = jiffies;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 46dabdb12071..cec282a6f62d 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -5706,7 +5706,7 @@ int __init init_module(void)
return found ? 0 : -ENODEV;
}
-void cleanup_module(void)
+void __exit cleanup_module(void)
{
int i;
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index fa3a2bb105ad..942b839ccc5b 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -26,10 +26,11 @@ static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
of available transceivers. */
-void t21142_media_task(void *data)
+void t21142_media_task(struct work_struct *work)
{
- struct net_device *dev = data;
- struct tulip_private *tp = netdev_priv(dev);
+ struct tulip_private *tp =
+ container_of(work, struct tulip_private, media_work);
+ struct net_device *dev = tp->dev;
void __iomem *ioaddr = tp->base_addr;
int csr12 = ioread32(ioaddr + CSR12);
int next_tick = 60*HZ;
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 3f4b6408b755..4b3cd3d8b62a 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -473,9 +473,9 @@
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <asm/uaccess.h>
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC_PMAC */
#include "de4x5.h"
@@ -4151,7 +4151,7 @@ get_hw_addr(struct net_device *dev)
/* If possible, try to fix a broken card - SMC only so far */
srom_repair(dev, broken);
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#ifdef CONFIG_PPC_PMAC
/*
** If the address starts with 00 a0, we have to bit-reverse
** each byte of the address.
@@ -4168,7 +4168,7 @@ get_hw_addr(struct net_device *dev)
dev->dev_addr[i] = ((x & 0x55) << 1) + ((x & 0xaa) >> 1);
}
}
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC_PMAC */
/* Test for a bad enet address */
status = test_bad_enet(dev, status);
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index 066e5d6bcbd8..df326fe1cc8f 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -18,10 +18,11 @@
#include "tulip.h"
-void tulip_media_task(void *data)
+void tulip_media_task(struct work_struct *work)
{
- struct net_device *dev = data;
- struct tulip_private *tp = netdev_priv(dev);
+ struct tulip_private *tp =
+ container_of(work, struct tulip_private, media_work);
+ struct net_device *dev = tp->dev;
void __iomem *ioaddr = tp->base_addr;
u32 csr12 = ioread32(ioaddr + CSR12);
int next_tick = 2*HZ;
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index ad107f45c7b1..25f25da76917 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -44,7 +44,7 @@ struct tulip_chip_table {
int valid_intrs; /* CSR7 interrupt enable settings */
int flags;
void (*media_timer) (unsigned long);
- void (*media_task) (void *);
+ work_func_t media_task;
};
@@ -392,6 +392,7 @@ struct tulip_private {
int csr12_shadow;
int pad0; /* Used for 8-byte alignment */
struct work_struct media_work;
+ struct net_device *dev;
};
@@ -406,7 +407,7 @@ struct eeprom_fixup {
/* 21142.c */
extern u16 t21142_csr14[];
-void t21142_media_task(void *data);
+void t21142_media_task(struct work_struct *work);
void t21142_start_nway(struct net_device *dev);
void t21142_lnk_change(struct net_device *dev, int csr5);
@@ -444,7 +445,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5);
void pnic_timer(unsigned long data);
/* timer.c */
-void tulip_media_task(void *data);
+void tulip_media_task(struct work_struct *work);
void mxic_timer(unsigned long data);
void comet_timer(unsigned long data);
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 0aee618f883c..5a35354aa523 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1367,6 +1367,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
* it is zeroed and aligned in alloc_etherdev
*/
tp = netdev_priv(dev);
+ tp->dev = dev;
tp->rx_ring = pci_alloc_consistent(pdev,
sizeof(struct tulip_rx_desc) * RX_RING_SIZE +
@@ -1389,7 +1390,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
tp->timer.data = (unsigned long)dev;
tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
- INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev);
+ INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task);
dev->base_addr = (unsigned long)ioaddr;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 3bf9e630404f..9781b16bb8b6 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -117,6 +117,7 @@ static const int multicast_filter_limit = 32;
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
@@ -127,7 +128,6 @@ static const int multicast_filter_limit = 32;
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/in6.h>
-#include <asm/checksum.h>
#include <linux/version.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 931cbdf6d791..b2a23aed4428 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -125,8 +125,8 @@ static int cpc_tty_write_room(struct tty_struct *tty);
static int cpc_tty_chars_in_buffer(struct tty_struct *tty);
static void cpc_tty_flush_buffer(struct tty_struct *tty);
static void cpc_tty_hangup(struct tty_struct *tty);
-static void cpc_tty_rx_work(void *data);
-static void cpc_tty_tx_work(void *data);
+static void cpc_tty_rx_work(struct work_struct *work);
+static void cpc_tty_tx_work(struct work_struct *work);
static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
@@ -261,8 +261,8 @@ void cpc_tty_init(pc300dev_t *pc300dev)
cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
cpc_tty->pc300dev = pc300dev;
- INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work, (void *)cpc_tty);
- INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work, (void *)port);
+ INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work);
+ INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work);
cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL;
@@ -659,21 +659,23 @@ static void cpc_tty_hangup(struct tty_struct *tty)
* o call the line disc. read
* o free memory
*/
-static void cpc_tty_rx_work(void * data)
+static void cpc_tty_rx_work(struct work_struct *work)
{
+ st_cpc_tty_area *cpc_tty;
unsigned long port;
int i, j;
- st_cpc_tty_area *cpc_tty;
volatile st_cpc_rx_buf *buf;
char flags=0,flg_rx=1;
struct tty_ldisc *ld;
if (cpc_tty_cnt == 0) return;
-
for (i=0; (i < 4) && flg_rx ; i++) {
flg_rx = 0;
- port = (unsigned long)data;
+
+ cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work);
+ port = cpc_tty - cpc_tty_area;
+
for (j=0; j < CPC_TTY_NPORTS; j++) {
cpc_tty = &cpc_tty_area[port];
@@ -882,9 +884,10 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
* o if need call line discipline wakeup
* o call wake_up_interruptible
*/
-static void cpc_tty_tx_work(void *data)
+static void cpc_tty_tx_work(struct work_struct *work)
{
- st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data;
+ st_cpc_tty_area *cpc_tty =
+ container_of(work, st_cpc_tty_area, tty_tx_work);
struct tty_struct *tty;
CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index 41f1d6778849..7f38012b9c92 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -538,7 +538,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void
+void __exit
cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index ac9437d497f0..f12355398fe7 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -219,21 +219,6 @@ static int airo_config(struct pcmcia_device *link)
dev = link->priv;
DEBUG(0, "airo_config(0x%p)\n", link);
-
- /*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
/*
In this loop, we scan the CIS for configuration table entries,
@@ -247,6 +232,10 @@ static int airo_config(struct pcmcia_device *link)
these things without consulting the CIS, and most client drivers
will only use the CIS to fill in implementation-defined details.
*/
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 5c410989c4d7..12617cd0b78e 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -244,17 +244,6 @@ static int atmel_config(struct pcmcia_device *link)
tuple.TupleOffset = 0;
/*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
In this loop, we scan the CIS for configuration table entries,
each of which describes a valid card configuration, including
voltage, IO window, memory window, and interrupt settings.
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 94dfb92fab5c..8286678513b9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -819,7 +819,7 @@ struct bcm43xx_private {
struct tasklet_struct isr_tasklet;
/* Periodic tasks */
- struct work_struct periodic_work;
+ struct delayed_work periodic_work;
unsigned int periodic_state;
struct work_struct restart_work;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 5b3c27359a18..2ec2e5afce67 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3215,9 +3215,10 @@ static void do_periodic_work(struct bcm43xx_private *bcm)
schedule_delayed_work(&bcm->periodic_work, HZ * 15);
}
-static void bcm43xx_periodic_work_handler(void *d)
+static void bcm43xx_periodic_work_handler(struct work_struct *work)
{
- struct bcm43xx_private *bcm = d;
+ struct bcm43xx_private *bcm =
+ container_of(work, struct bcm43xx_private, periodic_work.work);
struct net_device *net_dev = bcm->net_dev;
unsigned long flags;
u32 savedirqs = 0;
@@ -3279,11 +3280,11 @@ void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
{
- struct work_struct *work = &(bcm->periodic_work);
+ struct delayed_work *work = &bcm->periodic_work;
assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
- INIT_WORK(work, bcm43xx_periodic_work_handler, bcm);
- schedule_work(work);
+ INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
+ schedule_delayed_work(work, 0);
}
static void bcm43xx_security_init(struct bcm43xx_private *bcm)
@@ -3635,7 +3636,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
bcm43xx_periodic_tasks_setup(bcm);
/*FIXME: This should be handled by softmac instead. */
- schedule_work(&bcm->softmac->associnfo.work);
+ schedule_delayed_work(&bcm->softmac->associnfo.work, 0);
out:
mutex_unlock(&(bcm)->mutex);
@@ -4182,9 +4183,10 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
/* Hard-reset the chip. Do not call this directly.
* Use bcm43xx_controller_restart()
*/
-static void bcm43xx_chip_reset(void *_bcm)
+static void bcm43xx_chip_reset(struct work_struct *work)
{
- struct bcm43xx_private *bcm = _bcm;
+ struct bcm43xx_private *bcm =
+ container_of(work, struct bcm43xx_private, restart_work);
struct bcm43xx_phyinfo *phy;
int err = -ENODEV;
@@ -4211,7 +4213,7 @@ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
return;
printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
- INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
+ INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset);
schedule_work(&bcm->restart_work);
}
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index e663518bd570..e89c890d16fd 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -35,7 +35,7 @@ int hostap_80211_get_hdrlen(u16 fc);
struct net_device_stats *hostap_get_stats(struct net_device *dev);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int main_dev);
-void hostap_set_multicast_list_queue(void *data);
+void hostap_set_multicast_list_queue(struct work_struct *work);
int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked);
int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked);
void hostap_cleanup(local_info_t *local);
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index ba13125024cb..974a8e5bec8b 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -49,10 +49,10 @@ MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs "
static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta);
static void hostap_event_expired_sta(struct net_device *dev,
struct sta_info *sta);
-static void handle_add_proc_queue(void *data);
+static void handle_add_proc_queue(struct work_struct *work);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
-static void handle_wds_oper_queue(void *data);
+static void handle_wds_oper_queue(struct work_struct *work);
static void prism2_send_mgmt(struct net_device *dev,
u16 type_subtype, char *body,
int body_len, u8 *addr, u16 tx_cb_idx);
@@ -807,7 +807,7 @@ void hostap_init_data(local_info_t *local)
INIT_LIST_HEAD(&ap->sta_list);
/* Initialize task queue structure for AP management */
- INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap);
+ INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue);
ap->tx_callback_idx =
hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
@@ -815,7 +815,7 @@ void hostap_init_data(local_info_t *local)
printk(KERN_WARNING "%s: failed to register TX callback for "
"AP\n", local->dev->name);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
- INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local);
+ INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue);
ap->tx_callback_auth =
hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
@@ -1062,9 +1062,10 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off,
}
-static void handle_add_proc_queue(void *data)
+static void handle_add_proc_queue(struct work_struct *work)
{
- struct ap_data *ap = (struct ap_data *) data;
+ struct ap_data *ap = container_of(work, struct ap_data,
+ add_sta_proc_queue);
struct sta_info *sta;
char name[20];
struct add_sta_proc_data *entry, *prev;
@@ -1099,15 +1100,13 @@ static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
{
struct sta_info *sta;
- sta = (struct sta_info *)
- kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
+ sta = kzalloc(sizeof(struct sta_info), GFP_ATOMIC);
if (sta == NULL) {
PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
return NULL;
}
/* initialize STA info data */
- memset(sta, 0, sizeof(struct sta_info));
sta->local = ap->local;
skb_queue_head_init(&sta->tx_buf);
memcpy(sta->addr, addr, ETH_ALEN);
@@ -1952,9 +1951,11 @@ static void handle_pspoll(local_info_t *local,
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
-static void handle_wds_oper_queue(void *data)
+static void handle_wds_oper_queue(struct work_struct *work)
{
- local_info_t *local = data;
+ struct ap_data *ap = container_of(work, struct ap_data,
+ wds_oper_queue);
+ local_info_t *local = ap->local;
struct wds_oper_data *entry, *prev;
spin_lock_bh(&local->lock);
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index f63909e4bc32..8d8f4b9b8b07 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -293,15 +293,12 @@ static int sandisk_enable_wireless(struct net_device *dev)
goto done;
}
- tuple.DesiredTuple = CISTPL_MANFID;
tuple.Attributes = TUPLE_RETURN_COMMON;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
- pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
- pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
- parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
+
+ if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
/* No SanDisk manfid found */
ret = -ENODEV;
goto done;
@@ -566,23 +563,16 @@ static int prism2_config(struct pcmcia_device *link)
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
- hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
+ hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (parse == NULL || hw_priv == NULL) {
ret = -ENOMEM;
goto failed;
}
- memset(hw_priv, 0, sizeof(*hw_priv));
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse));
- link->conf.ConfigBase = parse->config.base;
- link->conf.Present = parse->config.rmask[0];
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c
index ab26b52b3e76..24fc387bba67 100644
--- a/drivers/net/wireless/hostap/hostap_download.c
+++ b/drivers/net/wireless/hostap/hostap_download.c
@@ -685,14 +685,12 @@ static int prism2_download(local_info_t *local,
goto out;
}
- dl = kmalloc(sizeof(*dl) + param->num_areas *
+ dl = kzalloc(sizeof(*dl) + param->num_areas *
sizeof(struct prism2_download_data_area), GFP_KERNEL);
if (dl == NULL) {
ret = -ENOMEM;
goto out;
}
- memset(dl, 0, sizeof(*dl) + param->num_areas *
- sizeof(struct prism2_download_data_area));
dl->dl_cmd = param->dl_cmd;
dl->start_addr = param->start_addr;
dl->num_areas = param->num_areas;
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index ed00ebb6e7f4..a394a23b9a20 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -347,14 +347,12 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
if (signal_pending(current))
return -EINTR;
- entry = (struct hostap_cmd_queue *)
- kmalloc(sizeof(*entry), GFP_ATOMIC);
+ entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
if (entry == NULL) {
printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
dev->name);
return -ENOMEM;
}
- memset(entry, 0, sizeof(*entry));
atomic_set(&entry->usecnt, 1);
entry->type = CMD_SLEEP;
entry->cmd = cmd;
@@ -517,14 +515,12 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
return -1;
}
- entry = (struct hostap_cmd_queue *)
- kmalloc(sizeof(*entry), GFP_ATOMIC);
+ entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
if (entry == NULL) {
printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
"failed\n", dev->name);
return -ENOMEM;
}
- memset(entry, 0, sizeof(*entry));
atomic_set(&entry->usecnt, 1);
entry->type = CMD_CALLBACK;
entry->cmd = cmd;
@@ -1645,9 +1641,9 @@ static void prism2_schedule_reset(local_info_t *local)
/* Called only as scheduled task after noticing card timeout in interrupt
* context */
-static void handle_reset_queue(void *data)
+static void handle_reset_queue(struct work_struct *work)
{
- local_info_t *local = (local_info_t *) data;
+ local_info_t *local = container_of(work, local_info_t, reset_queue);
printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name);
prism2_hw_reset(local->dev);
@@ -2896,9 +2892,10 @@ static void hostap_passive_scan(unsigned long data)
/* Called only as a scheduled task when communications quality values should
* be updated. */
-static void handle_comms_qual_update(void *data)
+static void handle_comms_qual_update(struct work_struct *work)
{
- local_info_t *local = data;
+ local_info_t *local =
+ container_of(work, local_info_t, comms_qual_update);
prism2_update_comms_qual(local->dev);
}
@@ -3015,14 +3012,12 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
iface = netdev_priv(dev);
local = iface->local;
- new_entry = (struct set_tim_data *)
- kmalloc(sizeof(*new_entry), GFP_ATOMIC);
+ new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC);
if (new_entry == NULL) {
printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
local->dev->name);
return -ENOMEM;
}
- memset(new_entry, 0, sizeof(*new_entry));
new_entry->aid = aid;
new_entry->set = set;
@@ -3050,9 +3045,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
}
-static void handle_set_tim_queue(void *data)
+static void handle_set_tim_queue(struct work_struct *work)
{
- local_info_t *local = (local_info_t *) data;
+ local_info_t *local = container_of(work, local_info_t, set_tim_queue);
struct set_tim_data *entry;
u16 val;
@@ -3209,15 +3204,15 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
local->scan_channel_mask = 0xffff;
/* Initialize task queue structures */
- INIT_WORK(&local->reset_queue, handle_reset_queue, local);
+ INIT_WORK(&local->reset_queue, handle_reset_queue);
INIT_WORK(&local->set_multicast_list_queue,
- hostap_set_multicast_list_queue, local->dev);
+ hostap_set_multicast_list_queue);
- INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local);
+ INIT_WORK(&local->set_tim_queue, handle_set_tim_queue);
INIT_LIST_HEAD(&local->set_tim_list);
spin_lock_init(&local->set_tim_lock);
- INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local);
+ INIT_WORK(&local->comms_qual_update, handle_comms_qual_update);
/* Initialize tasklets for handling hardware IRQ related operations
* outside hw IRQ handler */
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 50f72d831cf4..b6a02a02da74 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -327,11 +327,10 @@ static void prism2_info_hostscanresults(local_info_t *local,
ptr = (u8 *) pos;
new_count = left / result_size;
- results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
+ results = kcalloc(new_count, sizeof(struct hfa384x_hostscan_result),
GFP_ATOMIC);
if (results == NULL)
return;
- memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result));
for (i = 0; i < new_count; i++) {
memcpy(&results[i], ptr, copy_len);
@@ -474,9 +473,9 @@ static void handle_info_queue_scanresults(local_info_t *local)
/* Called only as scheduled task after receiving info frames (used to avoid
* pending too much time in HW IRQ handler). */
-static void handle_info_queue(void *data)
+static void handle_info_queue(struct work_struct *work)
{
- local_info_t *local = (local_info_t *) data;
+ local_info_t *local = container_of(work, local_info_t, info_queue);
if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS,
&local->pending_info))
@@ -493,7 +492,7 @@ void hostap_info_init(local_info_t *local)
{
skb_queue_head_init(&local->info_list);
#ifndef PRISM2_NO_STATION_MODES
- INIT_WORK(&local->info_queue, handle_info_queue, local);
+ INIT_WORK(&local->info_queue, handle_info_queue);
#endif /* PRISM2_NO_STATION_MODES */
}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index d061fb3443ff..3b7b8063ff1c 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -181,12 +181,10 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
struct ieee80211_crypt_data *new_crypt;
/* take WEP into use */
- new_crypt = (struct ieee80211_crypt_data *)
- kmalloc(sizeof(struct ieee80211_crypt_data),
+ new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL);
if (new_crypt == NULL)
return -ENOMEM;
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
if (!new_crypt->ops) {
request_module("ieee80211_crypt_wep");
@@ -3320,14 +3318,12 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
prism2_crypt_delayed_deinit(local, crypt);
- new_crypt = (struct ieee80211_crypt_data *)
- kmalloc(sizeof(struct ieee80211_crypt_data),
+ new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL);
if (new_crypt == NULL) {
ret = -ENOMEM;
goto done;
}
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
new_crypt->priv = new_crypt->ops->init(i);
if (new_crypt->priv == NULL) {
@@ -3538,14 +3534,12 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
prism2_crypt_delayed_deinit(local, crypt);
- new_crypt = (struct ieee80211_crypt_data *)
- kmalloc(sizeof(struct ieee80211_crypt_data),
+ new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL);
if (new_crypt == NULL) {
ret = -ENOMEM;
goto done;
}
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
if (new_crypt->priv == NULL) {
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 53374fcba77e..0796be9d9e77 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -767,14 +767,14 @@ static int prism2_set_mac_address(struct net_device *dev, void *p)
/* TODO: to be further implemented as soon as Prism2 fully supports
* GroupAddresses and correct documentation is available */
-void hostap_set_multicast_list_queue(void *data)
+void hostap_set_multicast_list_queue(struct work_struct *work)
{
- struct net_device *dev = (struct net_device *) data;
+ local_info_t *local =
+ container_of(work, local_info_t, set_multicast_list_queue);
+ struct net_device *dev = local->dev;
struct hostap_interface *iface;
- local_info_t *local;
iface = netdev_priv(dev);
- local = iface->local;
if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
local->is_promisc)) {
printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index d1de9766c831..c4f6020baa9e 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -300,10 +300,9 @@ static int prism2_pci_probe(struct pci_dev *pdev,
struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv;
- hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
+ hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (hw_priv == NULL)
return -ENOMEM;
- memset(hw_priv, 0, sizeof(*hw_priv));
if (pci_enable_device(pdev))
goto err_out_free;
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index bc81b13a5a2a..e235e0647897 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -447,10 +447,9 @@ static int prism2_plx_probe(struct pci_dev *pdev,
int tmd7160;
struct hostap_plx_priv *hw_priv;
- hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
+ hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (hw_priv == NULL)
return -ENOMEM;
- memset(hw_priv, 0, sizeof(*hw_priv));
if (pci_enable_device(pdev))
goto err_out_free;
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 79607b8b877c..dd9ba4aad7bb 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -316,7 +316,7 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
struct ipw2100_fw *fw);
static int ipw2100_ucode_download(struct ipw2100_priv *priv,
struct ipw2100_fw *fw);
-static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
+static void ipw2100_wx_event_work(struct work_struct *work);
static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
static struct iw_handler_def ipw2100_wx_handler_def;
@@ -679,7 +679,8 @@ static void schedule_reset(struct ipw2100_priv *priv)
queue_delayed_work(priv->workqueue, &priv->reset_work,
priv->reset_backoff * HZ);
else
- queue_work(priv->workqueue, &priv->reset_work);
+ queue_delayed_work(priv->workqueue, &priv->reset_work,
+ 0);
if (priv->reset_backoff < MAX_RESET_BACKOFF)
priv->reset_backoff++;
@@ -1873,8 +1874,10 @@ static void ipw2100_down(struct ipw2100_priv *priv)
netif_stop_queue(priv->net_dev);
}
-static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
+static void ipw2100_reset_adapter(struct work_struct *work)
{
+ struct ipw2100_priv *priv =
+ container_of(work, struct ipw2100_priv, reset_work.work);
unsigned long flags;
union iwreq_data wrqu = {
.ap_addr = {
@@ -2071,9 +2074,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
return;
if (priv->status & STATUS_SECURITY_UPDATED)
- queue_work(priv->workqueue, &priv->security_work);
+ queue_delayed_work(priv->workqueue, &priv->security_work, 0);
- queue_work(priv->workqueue, &priv->wx_event_work);
+ queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0);
}
static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
@@ -5524,8 +5527,11 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
return err;
}
-static void ipw2100_security_work(struct ipw2100_priv *priv)
+static void ipw2100_security_work(struct work_struct *work)
{
+ struct ipw2100_priv *priv =
+ container_of(work, struct ipw2100_priv, security_work.work);
+
/* If we happen to have reconnected before we get a chance to
* process this, then update the security settings--which causes
* a disassociation to occur */
@@ -5748,7 +5754,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
priv->reset_backoff = 0;
mutex_unlock(&priv->action_mutex);
- ipw2100_reset_adapter(priv);
+ ipw2100_reset_adapter(&priv->reset_work.work);
return 0;
done:
@@ -5910,9 +5916,10 @@ static const struct ethtool_ops ipw2100_ethtool_ops = {
.get_drvinfo = ipw_ethtool_get_drvinfo,
};
-static void ipw2100_hang_check(void *adapter)
+static void ipw2100_hang_check(struct work_struct *work)
{
- struct ipw2100_priv *priv = adapter;
+ struct ipw2100_priv *priv =
+ container_of(work, struct ipw2100_priv, hang_check.work);
unsigned long flags;
u32 rtc = 0xa5a5a5a5;
u32 len = sizeof(rtc);
@@ -5952,9 +5959,10 @@ static void ipw2100_hang_check(void *adapter)
spin_unlock_irqrestore(&priv->low_lock, flags);
}
-static void ipw2100_rf_kill(void *adapter)
+static void ipw2100_rf_kill(struct work_struct *work)
{
- struct ipw2100_priv *priv = adapter;
+ struct ipw2100_priv *priv =
+ container_of(work, struct ipw2100_priv, rf_kill.work);
unsigned long flags;
spin_lock_irqsave(&priv->low_lock, flags);
@@ -6103,14 +6111,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
priv->workqueue = create_workqueue(DRV_NAME);
- INIT_WORK(&priv->reset_work,
- (void (*)(void *))ipw2100_reset_adapter, priv);
- INIT_WORK(&priv->security_work,
- (void (*)(void *))ipw2100_security_work, priv);
- INIT_WORK(&priv->wx_event_work,
- (void (*)(void *))ipw2100_wx_event_work, priv);
- INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv);
- INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv);
+ INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter);
+ INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work);
+ INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
+ INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
+ INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
ipw2100_irq_tasklet, (unsigned long)priv);
@@ -6215,7 +6220,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
/* Allocate and initialize the Tx/Rx queues and lists */
if (ipw2100_queues_allocate(priv)) {
printk(KERN_WARNING DRV_NAME
- "Error calilng ipw2100_queues_allocate.\n");
+ "Error calling ipw2100_queues_allocate.\n");
err = -ENOMEM;
goto fail;
}
@@ -8281,8 +8286,10 @@ static struct iw_handler_def ipw2100_wx_handler_def = {
.get_wireless_stats = ipw2100_wx_wireless_stats,
};
-static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
+static void ipw2100_wx_event_work(struct work_struct *work)
{
+ struct ipw2100_priv *priv =
+ container_of(work, struct ipw2100_priv, wx_event_work.work);
union iwreq_data wrqu;
int len = ETH_ALEN;
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 55b7227198df..de7d384d38af 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -583,11 +583,11 @@ struct ipw2100_priv {
struct tasklet_struct irq_tasklet;
struct workqueue_struct *workqueue;
- struct work_struct reset_work;
- struct work_struct security_work;
- struct work_struct wx_event_work;
- struct work_struct hang_check;
- struct work_struct rf_kill;
+ struct delayed_work reset_work;
+ struct delayed_work security_work;
+ struct delayed_work wx_event_work;
+ struct delayed_work hang_check;
+ struct delayed_work rf_kill;
u32 interrupts;
int tx_interrupts;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index c692d01a76ca..22cb3fb7502e 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -70,7 +70,7 @@
#define VQ
#endif
-#define IPW2200_VERSION "1.1.4" VK VD VM VP VR VQ
+#define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
#define DRV_VERSION IPW2200_VERSION
@@ -187,9 +187,9 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
static void ipw_rx_queue_replenish(void *);
static int ipw_up(struct ipw_priv *);
-static void ipw_bg_up(void *);
+static void ipw_bg_up(struct work_struct *work);
static void ipw_down(struct ipw_priv *);
-static void ipw_bg_down(void *);
+static void ipw_bg_down(struct work_struct *work);
static int ipw_config(struct ipw_priv *);
static int init_supported_rates(struct ipw_priv *priv,
struct ipw_supported_rates *prates);
@@ -862,11 +862,12 @@ static void ipw_led_link_on(struct ipw_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void ipw_bg_led_link_on(void *data)
+static void ipw_bg_led_link_on(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, led_link_on.work);
mutex_lock(&priv->mutex);
- ipw_led_link_on(data);
+ ipw_led_link_on(priv);
mutex_unlock(&priv->mutex);
}
@@ -906,11 +907,12 @@ static void ipw_led_link_off(struct ipw_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void ipw_bg_led_link_off(void *data)
+static void ipw_bg_led_link_off(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, led_link_off.work);
mutex_lock(&priv->mutex);
- ipw_led_link_off(data);
+ ipw_led_link_off(priv);
mutex_unlock(&priv->mutex);
}
@@ -985,11 +987,12 @@ static void ipw_led_activity_off(struct ipw_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void ipw_bg_led_activity_off(void *data)
+static void ipw_bg_led_activity_off(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, led_act_off.work);
mutex_lock(&priv->mutex);
- ipw_led_activity_off(data);
+ ipw_led_activity_off(priv);
mutex_unlock(&priv->mutex);
}
@@ -2228,11 +2231,12 @@ static void ipw_adapter_restart(void *adapter)
}
}
-static void ipw_bg_adapter_restart(void *data)
+static void ipw_bg_adapter_restart(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, adapter_restart);
mutex_lock(&priv->mutex);
- ipw_adapter_restart(data);
+ ipw_adapter_restart(priv);
mutex_unlock(&priv->mutex);
}
@@ -2249,11 +2253,12 @@ static void ipw_scan_check(void *data)
}
}
-static void ipw_bg_scan_check(void *data)
+static void ipw_bg_scan_check(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, scan_check.work);
mutex_lock(&priv->mutex);
- ipw_scan_check(data);
+ ipw_scan_check(priv);
mutex_unlock(&priv->mutex);
}
@@ -3831,17 +3836,19 @@ static int ipw_disassociate(void *data)
return 1;
}
-static void ipw_bg_disassociate(void *data)
+static void ipw_bg_disassociate(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, disassociate);
mutex_lock(&priv->mutex);
- ipw_disassociate(data);
+ ipw_disassociate(priv);
mutex_unlock(&priv->mutex);
}
-static void ipw_system_config(void *data)
+static void ipw_system_config(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, system_config);
#ifdef CONFIG_IPW2200_PROMISCUOUS
if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
@@ -4208,11 +4215,12 @@ static void ipw_gather_stats(struct ipw_priv *priv)
IPW_STATS_INTERVAL);
}
-static void ipw_bg_gather_stats(void *data)
+static void ipw_bg_gather_stats(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, gather_stats.work);
mutex_lock(&priv->mutex);
- ipw_gather_stats(data);
+ ipw_gather_stats(priv);
mutex_unlock(&priv->mutex);
}
@@ -4268,8 +4276,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
if (!(priv->status & STATUS_ROAMING)) {
priv->status |= STATUS_ROAMING;
if (!(priv->status & STATUS_SCANNING))
- queue_work(priv->workqueue,
- &priv->request_scan);
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, 0);
}
return;
}
@@ -4607,8 +4615,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
priv->status |= STATUS_SCAN_FORCED;
- queue_work(priv->workqueue,
- &priv->request_scan);
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, 0);
break;
}
priv->status &= ~STATUS_SCAN_FORCED;
@@ -4631,8 +4639,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
/* Don't schedule if we aborted the scan */
priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING)
- queue_work(priv->workqueue,
- &priv->request_scan);
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, 0);
else if (priv->config & CFG_BACKGROUND_SCAN
&& priv->status & STATUS_ASSOCIATED)
queue_delayed_work(priv->workqueue,
@@ -5055,11 +5063,12 @@ static void ipw_rx_queue_replenish(void *data)
ipw_rx_queue_restock(priv);
}
-static void ipw_bg_rx_queue_replenish(void *data)
+static void ipw_bg_rx_queue_replenish(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, rx_replenish);
mutex_lock(&priv->mutex);
- ipw_rx_queue_replenish(data);
+ ipw_rx_queue_replenish(priv);
mutex_unlock(&priv->mutex);
}
@@ -5489,9 +5498,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
return 1;
}
-static void ipw_merge_adhoc_network(void *data)
+static void ipw_merge_adhoc_network(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, merge_networks);
struct ieee80211_network *network = NULL;
struct ipw_network_match match = {
.network = priv->assoc_network
@@ -5948,11 +5958,12 @@ static void ipw_adhoc_check(void *data)
priv->assoc_request.beacon_interval);
}
-static void ipw_bg_adhoc_check(void *data)
+static void ipw_bg_adhoc_check(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, adhoc_check.work);
mutex_lock(&priv->mutex);
- ipw_adhoc_check(data);
+ ipw_adhoc_check(priv);
mutex_unlock(&priv->mutex);
}
@@ -6299,19 +6310,26 @@ done:
return err;
}
-static int ipw_request_passive_scan(struct ipw_priv *priv) {
- return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE);
+static void ipw_request_passive_scan(struct work_struct *work)
+{
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, request_passive_scan);
+ ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE);
}
-static int ipw_request_scan(struct ipw_priv *priv) {
- return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE);
+static void ipw_request_scan(struct work_struct *work)
+{
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, request_scan.work);
+ ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE);
}
-static void ipw_bg_abort_scan(void *data)
+static void ipw_bg_abort_scan(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, abort_scan);
mutex_lock(&priv->mutex);
- ipw_abort_scan(data);
+ ipw_abort_scan(priv);
mutex_unlock(&priv->mutex);
}
@@ -7084,9 +7102,10 @@ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
/*
* background support to run QoS activate functionality
*/
-static void ipw_bg_qos_activate(void *data)
+static void ipw_bg_qos_activate(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, qos_activate);
if (priv == NULL)
return;
@@ -7394,11 +7413,12 @@ static void ipw_roam(void *data)
priv->status &= ~STATUS_ROAMING;
}
-static void ipw_bg_roam(void *data)
+static void ipw_bg_roam(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, roam);
mutex_lock(&priv->mutex);
- ipw_roam(data);
+ ipw_roam(priv);
mutex_unlock(&priv->mutex);
}
@@ -7479,8 +7499,8 @@ static int ipw_associate(void *data)
&priv->request_scan,
SCAN_INTERVAL);
else
- queue_work(priv->workqueue,
- &priv->request_scan);
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, 0);
}
return 0;
@@ -7491,11 +7511,12 @@ static int ipw_associate(void *data)
return 1;
}
-static void ipw_bg_associate(void *data)
+static void ipw_bg_associate(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, associate);
mutex_lock(&priv->mutex);
- ipw_associate(data);
+ ipw_associate(priv);
mutex_unlock(&priv->mutex);
}
@@ -7656,7 +7677,8 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
/* Big bitfield of all the fields we provide in radiotap */
ipw_rt->rt_hdr.it_present =
- ((1 << IEEE80211_RADIOTAP_FLAGS) |
+ ((1 << IEEE80211_RADIOTAP_TSFT) |
+ (1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_RATE) |
(1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
@@ -7665,10 +7687,14 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
/* Zero the flags, we'll add to them as we go */
ipw_rt->rt_flags = 0;
- ipw_rt->rt_tsf = 0ULL;
+ ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
+ frame->parent_tsf[2] << 16 |
+ frame->parent_tsf[1] << 8 |
+ frame->parent_tsf[0]);
/* Convert signal to DBM */
ipw_rt->rt_dbmsignal = antsignal;
+ ipw_rt->rt_dbmnoise = frame->noise;
/* Convert the channel data and set the flags */
ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
@@ -7868,7 +7894,8 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
/* Big bitfield of all the fields we provide in radiotap */
ipw_rt->rt_hdr.it_present =
- ((1 << IEEE80211_RADIOTAP_FLAGS) |
+ ((1 << IEEE80211_RADIOTAP_TSFT) |
+ (1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_RATE) |
(1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
@@ -7877,7 +7904,10 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
/* Zero the flags, we'll add to them as we go */
ipw_rt->rt_flags = 0;
- ipw_rt->rt_tsf = 0ULL;
+ ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
+ frame->parent_tsf[2] << 16 |
+ frame->parent_tsf[1] << 8 |
+ frame->parent_tsf[0]);
/* Convert to DBM */
ipw_rt->rt_dbmsignal = signal;
@@ -8276,7 +8306,7 @@ static void ipw_rx(struct ipw_priv *priv)
("Notification: subtype=%02X flags=%02X size=%d\n",
pkt->u.notification.subtype,
pkt->u.notification.flags,
- pkt->u.notification.size);
+ le16_to_cpu(pkt->u.notification.size));
ipw_rx_notification(priv, &pkt->u.notification);
break;
}
@@ -9410,7 +9440,7 @@ static int ipw_wx_set_scan(struct net_device *dev,
IPW_DEBUG_WX("Start scan\n");
- queue_work(priv->workqueue, &priv->request_scan);
+ queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
return 0;
}
@@ -10547,11 +10577,12 @@ static void ipw_rf_kill(void *adapter)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void ipw_bg_rf_kill(void *data)
+static void ipw_bg_rf_kill(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, rf_kill.work);
mutex_lock(&priv->mutex);
- ipw_rf_kill(data);
+ ipw_rf_kill(priv);
mutex_unlock(&priv->mutex);
}
@@ -10582,11 +10613,12 @@ static void ipw_link_up(struct ipw_priv *priv)
queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
}
-static void ipw_bg_link_up(void *data)
+static void ipw_bg_link_up(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, link_up);
mutex_lock(&priv->mutex);
- ipw_link_up(data);
+ ipw_link_up(priv);
mutex_unlock(&priv->mutex);
}
@@ -10606,15 +10638,16 @@ static void ipw_link_down(struct ipw_priv *priv)
if (!(priv->status & STATUS_EXIT_PENDING)) {
/* Queue up another scan... */
- queue_work(priv->workqueue, &priv->request_scan);
+ queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
}
}
-static void ipw_bg_link_down(void *data)
+static void ipw_bg_link_down(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, link_down);
mutex_lock(&priv->mutex);
- ipw_link_down(data);
+ ipw_link_down(priv);
mutex_unlock(&priv->mutex);
}
@@ -10626,38 +10659,30 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv)
init_waitqueue_head(&priv->wait_command_queue);
init_waitqueue_head(&priv->wait_state);
- INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
- INIT_WORK(&priv->associate, ipw_bg_associate, priv);
- INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
- INIT_WORK(&priv->system_config, ipw_system_config, priv);
- INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
- INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
- INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
- INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
- INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
- INIT_WORK(&priv->request_scan,
- (void (*)(void *))ipw_request_scan, priv);
- INIT_WORK(&priv->request_passive_scan,
- (void (*)(void *))ipw_request_passive_scan, priv);
- INIT_WORK(&priv->gather_stats,
- (void (*)(void *))ipw_bg_gather_stats, priv);
- INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
- INIT_WORK(&priv->roam, ipw_bg_roam, priv);
- INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
- INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
- INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
- INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
- priv);
- INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
- priv);
- INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
- priv);
- INIT_WORK(&priv->merge_networks,
- (void (*)(void *))ipw_merge_adhoc_network, priv);
+ INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check);
+ INIT_WORK(&priv->associate, ipw_bg_associate);
+ INIT_WORK(&priv->disassociate, ipw_bg_disassociate);
+ INIT_WORK(&priv->system_config, ipw_system_config);
+ INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish);
+ INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart);
+ INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill);
+ INIT_WORK(&priv->up, ipw_bg_up);
+ INIT_WORK(&priv->down, ipw_bg_down);
+ INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan);
+ INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan);
+ INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats);
+ INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan);
+ INIT_WORK(&priv->roam, ipw_bg_roam);
+ INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check);
+ INIT_WORK(&priv->link_up, ipw_bg_link_up);
+ INIT_WORK(&priv->link_down, ipw_bg_link_down);
+ INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on);
+ INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off);
+ INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off);
+ INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network);
#ifdef CONFIG_IPW2200_QOS
- INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
- priv);
+ INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
#endif /* CONFIG_IPW2200_QOS */
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
@@ -11129,14 +11154,13 @@ static int ipw_up(struct ipw_priv *priv)
return -EIO;
if (cmdlog && !priv->cmdlog) {
- priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
+ priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog),
GFP_KERNEL);
if (priv->cmdlog == NULL) {
IPW_ERROR("Error allocating %d command log entries.\n",
cmdlog);
return -ENOMEM;
} else {
- memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
priv->cmdlog_len = cmdlog;
}
}
@@ -11190,7 +11214,8 @@ static int ipw_up(struct ipw_priv *priv)
/* If configure to try and auto-associate, kick
* off a scan. */
- queue_work(priv->workqueue, &priv->request_scan);
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, 0);
return 0;
}
@@ -11211,11 +11236,12 @@ static int ipw_up(struct ipw_priv *priv)
return -EIO;
}
-static void ipw_bg_up(void *data)
+static void ipw_bg_up(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, up);
mutex_lock(&priv->mutex);
- ipw_up(data);
+ ipw_up(priv);
mutex_unlock(&priv->mutex);
}
@@ -11282,11 +11308,12 @@ static void ipw_down(struct ipw_priv *priv)
ipw_led_radio_off(priv);
}
-static void ipw_bg_down(void *data)
+static void ipw_bg_down(struct work_struct *work)
{
- struct ipw_priv *priv = data;
+ struct ipw_priv *priv =
+ container_of(work, struct ipw_priv, down);
mutex_lock(&priv->mutex);
- ipw_down(data);
+ ipw_down(priv);
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index dad5eedefbf1..626a240a87d8 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1290,21 +1290,21 @@ struct ipw_priv {
struct workqueue_struct *workqueue;
- struct work_struct adhoc_check;
+ struct delayed_work adhoc_check;
struct work_struct associate;
struct work_struct disassociate;
struct work_struct system_config;
struct work_struct rx_replenish;
- struct work_struct request_scan;
+ struct delayed_work request_scan;
struct work_struct request_passive_scan;
struct work_struct adapter_restart;
- struct work_struct rf_kill;
+ struct delayed_work rf_kill;
struct work_struct up;
struct work_struct down;
- struct work_struct gather_stats;
+ struct delayed_work gather_stats;
struct work_struct abort_scan;
struct work_struct roam;
- struct work_struct scan_check;
+ struct delayed_work scan_check;
struct work_struct link_up;
struct work_struct link_down;
@@ -1319,9 +1319,9 @@ struct ipw_priv {
u32 led_ofdm_on;
u32 led_ofdm_off;
- struct work_struct led_link_on;
- struct work_struct led_link_off;
- struct work_struct led_act_off;
+ struct delayed_work led_link_on;
+ struct delayed_work led_link_off;
+ struct delayed_work led_act_off;
struct work_struct merge_networks;
struct ipw_cmd_log *cmdlog;
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 6714e0dfa8d6..644b4741ef74 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -735,10 +735,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int netwave_pcmcia_config(struct pcmcia_device *link) {
struct net_device *dev = link->priv;
netwave_private *priv = netdev_priv(dev);
- tuple_t tuple;
- cisparse_t parse;
int i, j, last_ret, last_fn;
- u_char buf[64];
win_req_t req;
memreq_t mem;
u_char __iomem *ramBase = NULL;
@@ -746,21 +743,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
/*
- This reads the card's CONFIG tuple to find its configuration
- registers.
- */
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
- /*
* Try allocating IO ports. This tries a few fixed addresses.
* If you want, you can also read the card's config table to
* pick addresses -- see the serial driver for an example.
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 336cabac13b3..936c888e03e1 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -980,9 +980,11 @@ static void print_linkstatus(struct net_device *dev, u16 status)
}
/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct net_device *dev)
+static void orinoco_join_ap(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, join_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
int err;
unsigned long flags;
@@ -1055,9 +1057,11 @@ static void orinoco_join_ap(struct net_device *dev)
}
/* Send new BSSID to userspace */
-static void orinoco_send_wevents(struct net_device *dev)
+static void orinoco_send_wevents(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, wevent_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
union iwreq_data wrqu;
int err;
@@ -1864,9 +1868,11 @@ __orinoco_set_multicast_list(struct net_device *dev)
/* This must be called from user context, without locks held - use
* schedule_work() */
-static void orinoco_reset(struct net_device *dev)
+static void orinoco_reset(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, reset_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
int err;
unsigned long flags;
@@ -2434,9 +2440,9 @@ struct net_device *alloc_orinocodev(int sizeof_card,
priv->hw_unavailable = 1; /* orinoco_init() must clear this
* before anything else touches the
* hardware */
- INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
- INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
- INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
+ INIT_WORK(&priv->reset_work, orinoco_reset);
+ INIT_WORK(&priv->join_work, orinoco_join_ap);
+ INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
@@ -3608,7 +3614,7 @@ static int orinoco_ioctl_reset(struct net_device *dev,
printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
/* Firmware reset */
- orinoco_reset(dev);
+ orinoco_reset(&priv->reset_work);
} else {
printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
@@ -4154,7 +4160,7 @@ static int orinoco_ioctl_commit(struct net_device *dev,
return 0;
if (priv->broken_disableport) {
- orinoco_reset(dev);
+ orinoco_reset(&priv->reset_work);
return 0;
}
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index bc14689cbf24..d08ae8d2726c 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -178,21 +178,6 @@ orinoco_cs_config(struct pcmcia_device *link)
cisparse_t parse;
void __iomem *mem;
- /*
- * This reads the card's CONFIG tuple to find its
- * configuration registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
@@ -211,6 +196,10 @@ orinoco_cs_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45de3ca..96606ed10076 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -157,8 +157,9 @@ prism54_mib_init(islpci_private *priv)
* schedule_work(), thus we can as well use sleeping semaphore
* locking */
void
-prism54_update_stats(islpci_private *priv)
+prism54_update_stats(struct work_struct *work)
{
+ islpci_private *priv = container_of(work, islpci_private, stats_work);
char *data;
int j;
struct obj_bss bss, *bss2;
@@ -2140,11 +2141,9 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
- if (bss != NULL) {
+ bss = kzalloc(sizeof (*bss), GFP_ATOMIC);
+ if (bss != NULL)
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
- }
}
if (bss != NULL) {
memcpy(bss->bssid, bssid, ETH_ALEN);
@@ -2493,9 +2492,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
* interrupt context, no locks held.
*/
void
-prism54_process_trap(void *data)
+prism54_process_trap(struct work_struct *work)
{
- struct islpci_mgmtframe *frame = data;
+ struct islpci_mgmtframe *frame =
+ container_of(work, struct islpci_mgmtframe, ws);
struct net_device *ndev = frame->ndev;
enum oid_num_t n = mgt_oidtonum(frame->header->oid);
@@ -2684,11 +2684,10 @@ prism2_ioctl_set_generic_element(struct net_device *ndev,
return -EINVAL;
alen = sizeof(*attach) + len;
- attach = kmalloc(alen, GFP_KERNEL);
+ attach = kzalloc(alen, GFP_KERNEL);
if (attach == NULL)
return -ENOMEM;
- memset(attach, 0, alen);
#define WLAN_FC_TYPE_MGMT 0
#define WLAN_FC_STYPE_ASSOC_REQ 0
#define WLAN_FC_STYPE_REASSOC_REQ 2
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d30c52e..bcfbfb9281d2 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -31,12 +31,12 @@
void prism54_mib_init(islpci_private *);
struct iw_statistics *prism54_get_wireless_stats(struct net_device *);
-void prism54_update_stats(islpci_private *);
+void prism54_update_stats(struct work_struct *);
void prism54_acl_init(struct islpci_acl *);
void prism54_acl_clean(struct islpci_acl *);
-void prism54_process_trap(void *);
+void prism54_process_trap(struct work_struct *);
void prism54_wpa_bss_ie_init(islpci_private *priv);
void prism54_wpa_bss_ie_clean(islpci_private *priv);
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603ca436c..f057fd9fcd79 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -860,11 +860,10 @@ islpci_setup(struct pci_dev *pdev)
priv->state_off = 1;
/* initialize workqueue's */
- INIT_WORK(&priv->stats_work,
- (void (*)(void *)) prism54_update_stats, priv);
+ INIT_WORK(&priv->stats_work, prism54_update_stats);
priv->stats_timestamp = 0;
- INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
+ INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake);
priv->reset_task_pending = 0;
/* allocate various memory areas */
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d83813dc8..b1122912ee2d 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -480,9 +480,9 @@ islpci_eth_receive(islpci_private *priv)
}
void
-islpci_do_reset_and_wake(void *data)
+islpci_do_reset_and_wake(struct work_struct *work)
{
- islpci_private *priv = data;
+ islpci_private *priv = container_of(work, islpci_private, reset_task);
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
index 26789454067c..5bf820defbd0 100644
--- a/drivers/net/wireless/prism54/islpci_eth.h
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -67,6 +67,6 @@ void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
int islpci_eth_transmit(struct sk_buff *, struct net_device *);
int islpci_eth_receive(islpci_private *);
void islpci_eth_tx_timeout(struct net_device *);
-void islpci_do_reset_and_wake(void *data);
+void islpci_do_reset_and_wake(struct work_struct *);
#endif /* _ISL_GEN_H */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875054c9..2246f7930b4e 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -386,7 +386,7 @@ islpci_mgt_receive(struct net_device *ndev)
/* Create work to handle trap out of interrupt
* context. */
- INIT_WORK(&frame->ws, prism54_process_trap, frame);
+ INIT_WORK(&frame->ws, prism54_process_trap);
schedule_work(&frame->ws);
} else {
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6a3024..e6cf9df2c206 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -235,12 +235,10 @@ mgt_init(islpci_private *priv)
{
int i;
- priv->mib = kmalloc(OID_NUM_LAST * sizeof (void *), GFP_KERNEL);
+ priv->mib = kcalloc(OID_NUM_LAST, sizeof (void *), GFP_KERNEL);
if (!priv->mib)
return -ENOMEM;
- memset(priv->mib, 0, OID_NUM_LAST * sizeof (void *));
-
/* Alloc the cache */
for (i = 0; i < OID_NUM_LAST; i++) {
if (isl_oid[i].flags & OID_FLAG_CACHED) {
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 7fbfc9e41d07..88e10c9bc4ac 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -408,11 +408,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
static int ray_config(struct pcmcia_device *link)
{
- tuple_t tuple;
- cisparse_t parse;
int last_fn = 0, last_ret = 0;
int i;
- u_char buf[MAX_TUPLE_SIZE];
win_req_t req;
memreq_t mem;
struct net_device *dev = (struct net_device *)link->priv;
@@ -420,29 +417,12 @@ static int ray_config(struct pcmcia_device *link)
DEBUG(1, "ray_config(0x%p)\n", link);
- /* This reads the card's CONFIG tuple to find its configuration regs */
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleData = buf;
- tuple.TupleDataMax = MAX_TUPLE_SIZE;
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Determine card type and firmware version */
- buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleData = buf;
- tuple.TupleDataMax = MAX_TUPLE_SIZE;
- tuple.TupleOffset = 2;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-
- for (i=0; i<tuple.TupleDataLen - 4; i++)
- if (buf[i] == 0) buf[i] = ' ';
- printk(KERN_INFO "ray_cs Detected: %s\n",buf);
+ printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
+ link->prod_id[0] ? link->prod_id[0] : " ",
+ link->prod_id[1] ? link->prod_id[1] : " ",
+ link->prod_id[2] ? link->prod_id[2] : " ",
+ link->prod_id[3] ? link->prod_id[3] : " ");
/* Now allocate an interrupt line. Note that this does not
actually assign a handler to the interrupt.
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index bcc7038130f6..cf2d1486b01d 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -647,21 +647,6 @@ spectrum_cs_config(struct pcmcia_device *link)
cisparse_t parse;
void __iomem *mem;
- /*
- * This reads the card's CONFIG tuple to find its
- * configuration registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
@@ -681,6 +666,10 @@ spectrum_cs_config(struct pcmcia_device *link)
* implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index aafb301041b1..233d906c08f0 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3939,11 +3939,8 @@ wv_hw_reset(struct net_device * dev)
static inline int
wv_pcmcia_config(struct pcmcia_device * link)
{
- tuple_t tuple;
- cisparse_t parse;
struct net_device * dev = (struct net_device *) link->priv;
int i;
- u_char buf[64];
win_req_t req;
memreq_t mem;
net_local * lp = netdev_priv(dev);
@@ -3953,36 +3950,6 @@ wv_pcmcia_config(struct pcmcia_device * link)
printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
#endif
- /*
- * This reads the card's CONFIG tuple to find its configuration
- * registers.
- */
- do
- {
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- i = pcmcia_get_first_tuple(link, &tuple);
- if(i != CS_SUCCESS)
- break;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- i = pcmcia_get_tuple_data(link, &tuple);
- if(i != CS_SUCCESS)
- break;
- i = pcmcia_parse_tuple(link, &tuple, &parse);
- if(i != CS_SUCCESS)
- break;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
- }
- while(0);
- if(i != CS_SUCCESS)
- {
- cs_error(link, ParseTuple, i);
- return FALSE;
- }
-
do
{
i = pcmcia_request_io(link, &link->io);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 5b98a7876982..583e0d655a98 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1966,25 +1966,10 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
*/
static int wl3501_config(struct pcmcia_device *link)
{
- tuple_t tuple;
- cisparse_t parse;
struct net_device *dev = link->priv;
int i = 0, j, last_fn, last_ret;
- unsigned char bf[64];
struct wl3501_card *this;
- /* This reads the card's CONFIG tuple to find its config registers. */
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleData = bf;
- tuple.TupleDataMax = sizeof(bf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Try allocating IO ports. This tries a few fixed addresses. If you
* want, you can also read the card's config table to pick addresses --
* see the serial driver for an example. */
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 8be99ebbe1cd..77e11ddad836 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1673,3 +1673,16 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
return 0;
}
+
+int zd_chip_set_multicast_hash(struct zd_chip *chip,
+ struct zd_mc_hash *hash)
+{
+ struct zd_ioreq32 ioreqs[] = {
+ { CR_GROUP_HASH_P1, hash->low },
+ { CR_GROUP_HASH_P2, hash->high },
+ };
+
+ dev_dbg_f(zd_chip_dev(chip), "hash l 0x%08x h 0x%08x\n",
+ ioreqs[0].value, ioreqs[1].value);
+ return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index ca892b9a6448..a4e3cee9b59d 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -390,10 +390,19 @@
#define CR_BSSID_P1 CTL_REG(0x0618)
#define CR_BSSID_P2 CTL_REG(0x061C)
#define CR_BCN_PLCP_CFG CTL_REG(0x0620)
+
+/* Group hash table for filtering incoming packets.
+ *
+ * The group hash table is 64 bit large and split over two parts. The first
+ * part is the lower part. The upper 6 bits of the last byte of the target
+ * address are used as index. Packets are received if the hash table bit is
+ * set. This is used for multicast handling, but for broadcasts (address
+ * ff:ff:ff:ff:ff:ff) the highest bit in the second table must also be set.
+ */
#define CR_GROUP_HASH_P1 CTL_REG(0x0624)
#define CR_GROUP_HASH_P2 CTL_REG(0x0628)
-#define CR_RX_TIMEOUT CTL_REG(0x062C)
+#define CR_RX_TIMEOUT CTL_REG(0x062C)
/* Basic rates supported by the BSS. When producing ACK or CTS messages, the
* device will use a rate in this table that is less than or equal to the rate
* of the incoming frame which prompted the response */
@@ -864,4 +873,36 @@ u8 zd_rx_strength_percent(u8 rssi);
u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
+struct zd_mc_hash {
+ u32 low;
+ u32 high;
+};
+
+static inline void zd_mc_clear(struct zd_mc_hash *hash)
+{
+ hash->low = 0;
+ /* The interfaces must always received broadcasts.
+ * The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63.
+ */
+ hash->high = 0x80000000;
+}
+
+static inline void zd_mc_add_all(struct zd_mc_hash *hash)
+{
+ hash->low = hash->high = 0xffffffff;
+}
+
+static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
+{
+ unsigned int i = addr[5] >> 2;
+ if (i < 32) {
+ hash->low |= 1 << i;
+ } else {
+ hash->high |= 1 << (i-32);
+ }
+}
+
+int zd_chip_set_multicast_hash(struct zd_chip *chip,
+ struct zd_mc_hash *hash);
+
#endif /* _ZD_CHIP_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 2696f95b9278..61c7916b7656 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -32,13 +32,15 @@
static void ieee_init(struct ieee80211_device *ieee);
static void softmac_init(struct ieee80211softmac_device *sm);
-static void set_rts_cts_work(void *d);
-static void set_basic_rates_work(void *d);
+static void set_rts_cts_work(struct work_struct *work);
+static void set_basic_rates_work(struct work_struct *work);
static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac);
+static void set_multicast_hash_handler(void *mac_ptr);
+
int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev,
struct usb_interface *intf)
@@ -48,13 +50,15 @@ int zd_mac_init(struct zd_mac *mac,
memset(mac, 0, sizeof(*mac));
spin_lock_init(&mac->lock);
mac->netdev = netdev;
- INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac);
- INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac);
+ INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
+ INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work);
ieee_init(ieee);
softmac_init(ieee80211_priv(netdev));
zd_chip_init(&mac->chip, netdev, intf);
housekeeping_init(mac);
+ INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler,
+ mac);
return 0;
}
@@ -136,6 +140,7 @@ out:
void zd_mac_clear(struct zd_mac *mac)
{
+ flush_workqueue(zd_workqueue);
zd_chip_clear(&mac->chip);
ZD_ASSERT(!spin_is_locked(&mac->lock));
ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
@@ -256,6 +261,42 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p)
return 0;
}
+static void set_multicast_hash_handler(void *mac_ptr)
+{
+ struct zd_mac *mac = mac_ptr;
+ struct zd_mc_hash hash;
+
+ spin_lock_irq(&mac->lock);
+ hash = mac->multicast_hash;
+ spin_unlock_irq(&mac->lock);
+
+ zd_chip_set_multicast_hash(&mac->chip, &hash);
+}
+
+void zd_mac_set_multicast_list(struct net_device *dev)
+{
+ struct zd_mc_hash hash;
+ struct zd_mac *mac = zd_netdev_mac(dev);
+ struct dev_mc_list *mc;
+ unsigned long flags;
+
+ if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) {
+ zd_mc_add_all(&hash);
+ } else {
+ zd_mc_clear(&hash);
+ for (mc = dev->mc_list; mc; mc = mc->next) {
+ dev_dbg_f(zd_mac_dev(mac), "mc addr " MAC_FMT "\n",
+ MAC_ARG(mc->dmi_addr));
+ zd_mc_add_addr(&hash, mc->dmi_addr);
+ }
+ }
+
+ spin_lock_irqsave(&mac->lock, flags);
+ mac->multicast_hash = hash;
+ spin_unlock_irqrestore(&mac->lock, flags);
+ queue_work(zd_workqueue, &mac->set_multicast_hash_work);
+}
+
int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
{
int r;
@@ -366,9 +407,10 @@ static void try_enable_tx(struct zd_mac *mac)
spin_unlock_irqrestore(&mac->lock, flags);
}
-static void set_rts_cts_work(void *d)
+static void set_rts_cts_work(struct work_struct *work)
{
- struct zd_mac *mac = d;
+ struct zd_mac *mac =
+ container_of(work, struct zd_mac, set_rts_cts_work.work);
unsigned long flags;
u8 rts_rate;
unsigned int short_preamble;
@@ -387,9 +429,10 @@ static void set_rts_cts_work(void *d)
try_enable_tx(mac);
}
-static void set_basic_rates_work(void *d)
+static void set_basic_rates_work(struct work_struct *work)
{
- struct zd_mac *mac = d;
+ struct zd_mac *mac =
+ container_of(work, struct zd_mac, set_basic_rates_work.work);
unsigned long flags;
u16 basic_rates;
@@ -467,12 +510,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes)
if (need_set_rts_cts && !mac->updating_rts_rate) {
mac->updating_rts_rate = 1;
netif_stop_queue(mac->netdev);
- queue_work(zd_workqueue, &mac->set_rts_cts_work);
+ queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0);
}
if (need_set_rates && !mac->updating_basic_rates) {
mac->updating_basic_rates = 1;
netif_stop_queue(mac->netdev);
- queue_work(zd_workqueue, &mac->set_basic_rates_work);
+ queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work,
+ 0);
}
spin_unlock_irqrestore(&mac->lock, flags);
}
@@ -615,6 +659,9 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 20;
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
ZD_ASSERT(!irqs_disabled());
spin_lock_irq(&mac->lock);
regdomain = mac->regdomain;
@@ -927,7 +974,8 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee,
}
return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
- is_multicast_ether_addr(hdr->addr1) ||
+ (is_multicast_ether_addr(hdr->addr1) &&
+ memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
(netdev->flags & IFF_PROMISC);
}
@@ -1059,10 +1107,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
memcpy(skb_put(skb, length), buffer, length);
r = ieee80211_rx(ieee, skb, &stats);
- if (!r) {
- ZD_ASSERT(in_irq());
- dev_kfree_skb_irq(skb);
- }
+ if (!r)
+ dev_kfree_skb_any(skb);
return 0;
}
@@ -1182,9 +1228,10 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
#define LINK_LED_WORK_DELAY HZ
-static void link_led_handler(void *p)
+static void link_led_handler(struct work_struct *work)
{
- struct zd_mac *mac = p;
+ struct zd_mac *mac =
+ container_of(work, struct zd_mac, housekeeping.link_led_work.work);
struct zd_chip *chip = &mac->chip;
struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev);
int is_associated;
@@ -1205,7 +1252,7 @@ static void link_led_handler(void *p)
static void housekeeping_init(struct zd_mac *mac)
{
- INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac);
+ INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler);
}
static void housekeeping_enable(struct zd_mac *mac)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 5dcfb251f02e..f0cf05dc7d3e 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -119,7 +119,7 @@ struct rx_status {
#define ZD_RX_ERROR 0x80
struct housekeeping {
- struct work_struct link_led_work;
+ struct delayed_work link_led_work;
};
#define ZD_MAC_STATS_BUFFER_SIZE 16
@@ -133,8 +133,10 @@ struct zd_mac {
struct iw_statistics iw_stats;
struct housekeeping housekeeping;
- struct work_struct set_rts_cts_work;
- struct work_struct set_basic_rates_work;
+ struct work_struct set_multicast_hash_work;
+ struct zd_mc_hash multicast_hash;
+ struct delayed_work set_rts_cts_work;
+ struct delayed_work set_basic_rates_work;
unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
@@ -189,6 +191,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type);
int zd_mac_open(struct net_device *netdev);
int zd_mac_stop(struct net_device *netdev);
int zd_mac_set_mac_address(struct net_device *dev, void *p);
+void zd_mac_set_multicast_list(struct net_device *netdev);
int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length);
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
index 60f1b0f6d45b..8bda48de31ef 100644
--- a/drivers/net/wireless/zd1211rw/zd_netdev.c
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -242,7 +242,7 @@ struct net_device *zd_netdev_alloc(struct usb_interface *intf)
netdev->open = zd_mac_open;
netdev->stop = zd_mac_stop;
/* netdev->get_stats = */
- /* netdev->set_multicast_list = */
+ netdev->set_multicast_list = zd_mac_set_multicast_list;
netdev->set_mac_address = zd_mac_set_mac_address;
netdev->wireless_handlers = &iw_handler_def;
/* netdev->ethtool_ops = */
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index fc4bc9b94c74..a83c3db7d18f 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -29,7 +29,7 @@
struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned;
-static void wq_sync_buffer(void *);
+static void wq_sync_buffer(struct work_struct *work);
#define DEFAULT_TIMER_EXPIRE (HZ / 10)
static int work_enabled;
@@ -65,7 +65,7 @@ int alloc_cpu_buffers(void)
b->sample_received = 0;
b->sample_lost_overflow = 0;
b->cpu = i;
- INIT_WORK(&b->work, wq_sync_buffer, b);
+ INIT_DELAYED_WORK(&b->work, wq_sync_buffer);
}
return 0;
@@ -282,9 +282,10 @@ void oprofile_add_trace(unsigned long pc)
* By using schedule_delayed_work_on and then schedule_delayed_work
* we guarantee this will stay on the correct cpu
*/
-static void wq_sync_buffer(void * data)
+static void wq_sync_buffer(struct work_struct *work)
{
- struct oprofile_cpu_buffer * b = data;
+ struct oprofile_cpu_buffer * b =
+ container_of(work, struct oprofile_cpu_buffer, work.work);
if (b->cpu != smp_processor_id()) {
printk("WQ on CPU%d, prefer CPU%d\n",
smp_processor_id(), b->cpu);
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
index 09abb80e0570..49900d9e3235 100644
--- a/drivers/oprofile/cpu_buffer.h
+++ b/drivers/oprofile/cpu_buffer.h
@@ -43,7 +43,7 @@ struct oprofile_cpu_buffer {
unsigned long sample_lost_overflow;
unsigned long backtrace_aborted;
int cpu;
- struct work_struct work;
+ struct delayed_work work;
} ____cacheline_aligned;
extern struct oprofile_cpu_buffer cpu_buffer[];
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index b953d5907c05..e60b4bf6bae8 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -166,14 +166,6 @@ static int parport_config(struct pcmcia_device *link)
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
@@ -263,6 +255,7 @@ void parport_cs_release(struct pcmcia_device *link)
static struct pcmcia_device_id parport_ids[] = {
PCMCIA_DEVICE_FUNC_ID(3),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003),
PCMCIA_DEVICE_NULL
};
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 73a58c73d526..fc405f0165d9 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -1,5 +1,6 @@
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/wait.h>
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index ea2087c34149..50757695844f 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -70,7 +70,7 @@ struct slot {
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
char name[SLOT_NAME_SIZE];
- struct work_struct work; /* work for button event */
+ struct delayed_work work; /* work for button event */
struct mutex lock;
};
@@ -187,7 +187,7 @@ extern int shpchp_configure_device(struct slot *p_slot);
extern int shpchp_unconfigure_device(struct slot *p_slot);
extern void shpchp_remove_ctrl_files(struct controller *ctrl);
extern void cleanup_slots(struct controller *ctrl);
-extern void queue_pushbutton_work(void *data);
+extern void queue_pushbutton_work(struct work_struct *work);
#ifdef CONFIG_ACPI
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 235c18a22393..4eac85b3d90e 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -159,7 +159,7 @@ static int init_slots(struct controller *ctrl)
goto error_info;
slot->number = sun;
- INIT_WORK(&slot->work, queue_pushbutton_work, slot);
+ INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
/* register this slot with the hotplug pci core */
hotplug_slot->private = slot;
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index c39901dbff20..158ac7836096 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -36,7 +36,7 @@
#include "../pci.h"
#include "shpchp.h"
-static void interrupt_event_handler(void *data);
+static void interrupt_event_handler(struct work_struct *work);
static int shpchp_enable_slot(struct slot *p_slot);
static int shpchp_disable_slot(struct slot *p_slot);
@@ -50,7 +50,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
info->event_type = event_type;
info->p_slot = p_slot;
- INIT_WORK(&info->work, interrupt_event_handler, info);
+ INIT_WORK(&info->work, interrupt_event_handler);
schedule_work(&info->work);
@@ -408,9 +408,10 @@ struct pushbutton_work_info {
* Handles all pending events and exits.
*
*/
-static void shpchp_pushbutton_thread(void *data)
+static void shpchp_pushbutton_thread(struct work_struct *work)
{
- struct pushbutton_work_info *info = data;
+ struct pushbutton_work_info *info =
+ container_of(work, struct pushbutton_work_info, work);
struct slot *p_slot = info->p_slot;
mutex_lock(&p_slot->lock);
@@ -436,9 +437,9 @@ static void shpchp_pushbutton_thread(void *data)
kfree(info);
}
-void queue_pushbutton_work(void *data)
+void queue_pushbutton_work(struct work_struct *work)
{
- struct slot *p_slot = data;
+ struct slot *p_slot = container_of(work, struct slot, work.work);
struct pushbutton_work_info *info;
info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -447,7 +448,7 @@ void queue_pushbutton_work(void *data)
return;
}
info->p_slot = p_slot;
- INIT_WORK(&info->work, shpchp_pushbutton_thread, info);
+ INIT_WORK(&info->work, shpchp_pushbutton_thread);
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
@@ -541,9 +542,9 @@ static void handle_button_press_event(struct slot *p_slot)
}
}
-static void interrupt_event_handler(void *data)
+static void interrupt_event_handler(struct work_struct *work)
{
- struct event_info *info = data;
+ struct event_info *info = container_of(work, struct event_info, work);
struct slot *p_slot = info->p_slot;
mutex_lock(&p_slot->lock);
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 04c43ef529ac..55866b6b26fa 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -160,7 +160,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
rpc->e_lock = SPIN_LOCK_UNLOCKED;
rpc->rpd = dev;
- INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev);
+ INIT_WORK(&rpc->dpc_handler, aer_isr);
rpc->prod_idx = rpc->cons_idx = 0;
mutex_init(&rpc->rpc_mutex);
init_waitqueue_head(&rpc->wait_release);
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index daf0cad88fc8..3c0a58f64dd8 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -118,7 +118,7 @@ extern struct bus_type pcie_port_bus_type;
extern void aer_enable_rootport(struct aer_rpc *rpc);
extern void aer_delete_rootport(struct aer_rpc *rpc);
extern int aer_init(struct pcie_device *dev);
-extern void aer_isr(void *context);
+extern void aer_isr(struct work_struct *work);
extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
extern int aer_osc_setup(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 1c7e660d6535..08e13033ced8 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -690,14 +690,14 @@ static void aer_isr_one_error(struct pcie_device *p_device,
/**
* aer_isr - consume errors detected by root port
- * @context: pointer to a private data of pcie device
+ * @work: definition of this work item
*
* Invoked, as DPC, when root port records new detected error
**/
-void aer_isr(void *context)
+void aer_isr(struct work_struct *work)
{
- struct pcie_device *p_device = (struct pcie_device *) context;
- struct aer_rpc *rpc = get_service_data(p_device);
+ struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
+ struct pcie_device *p_device = rpc->rpd;
struct aer_err_source *e_src;
mutex_lock(&rpc->rpc_mutex);
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 3bcb7dc32995..b6746301d9a9 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -32,10 +32,11 @@
* A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW;
* some other bit in {A24,A22..A11} is nREG to flag memory access
* (vs attributes). So more than 2KB/region would just be waste.
+ * Note: These are offsets from the physical base address.
*/
-#define CF_ATTR_PHYS (AT91_CF_BASE)
-#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23))
-#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800)
+#define CF_ATTR_PHYS (0)
+#define CF_IO_PHYS (1 << 23)
+#define CF_MEM_PHYS (0x017ff800)
/*--------------------------------------------------------------------------*/
@@ -48,6 +49,8 @@ struct at91_cf_socket {
struct platform_device *pdev;
struct at91_cf_data *board;
+
+ unsigned long phys_baseaddr;
};
#define SZ_2K (2 * SZ_1K)
@@ -154,9 +157,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
/*
* Use 16 bit accesses unless/until we need 8-bit i/o space.
- * Always set CSR4 ... PCMCIA won't always unmap things.
*/
- csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW;
+ csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW;
/*
* NOTE: this CF controller ignores IOIS16, so we can't really do
@@ -168,14 +170,14 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
* some cards only like that way to get at the odd byte, despite
* CF 3.0 spec table 35 also giving the D8-D15 option.
*/
- if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) {
+ if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) {
csr |= AT91_SMC_DBW_8;
pr_debug("%s: 8bit i/o bus\n", driver_name);
} else {
csr |= AT91_SMC_DBW_16;
pr_debug("%s: 16bit i/o bus\n", driver_name);
}
- at91_sys_write(AT91_SMC_CSR(4), csr);
+ at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr);
io->start = cf->socket.io_offset;
io->stop = io->start + SZ_2K - 1;
@@ -194,11 +196,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
cf = container_of(s, struct at91_cf_socket, socket);
- map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
+ map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT);
if (map->flags & MAP_ATTRIB)
- map->static_start = CF_ATTR_PHYS;
+ map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS;
else
- map->static_start = CF_MEM_PHYS;
+ map->static_start = cf->phys_baseaddr + CF_MEM_PHYS;
return 0;
}
@@ -219,7 +221,6 @@ static int __init at91_cf_probe(struct platform_device *pdev)
struct at91_cf_socket *cf;
struct at91_cf_data *board = pdev->dev.platform_data;
struct resource *io;
- unsigned int csa;
int status;
if (!board || !board->det_pin || !board->rst_pin)
@@ -235,33 +236,11 @@ static int __init at91_cf_probe(struct platform_device *pdev)
cf->board = board;
cf->pdev = pdev;
+ cf->phys_baseaddr = io->start;
platform_set_drvdata(pdev, cf);
- /* CF takes over CS4, CS5, CS6 */
- csa = at91_sys_read(AT91_EBI_CSA);
- at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
-
- /* nWAIT is _not_ a default setting */
- (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */
-
- /*
- * Static memory controller timing adjustments.
- * REVISIT: these timings are in terms of MCK cycles, so
- * when MCK changes (cpufreq etc) so must these values...
- */
- at91_sys_write(AT91_SMC_CSR(4),
- AT91_SMC_ACSS_STD
- | AT91_SMC_DBW_16
- | AT91_SMC_BAT
- | AT91_SMC_WSEN
- | AT91_SMC_NWS_(32) /* wait states */
- | AT91_SMC_RWSETUP_(6) /* setup time */
- | AT91_SMC_RWHOLD_(4) /* hold time */
- );
-
/* must be a GPIO; ergo must trigger on both edges */
- status = request_irq(board->det_pin, at91_cf_irq,
- IRQF_SAMPLE_RANDOM, driver_name, cf);
+ status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
if (status < 0)
goto fail0;
device_init_wakeup(&pdev->dev, 1);
@@ -282,14 +261,18 @@ static int __init at91_cf_probe(struct platform_device *pdev)
cf->socket.pci_irq = NR_IRQS + 1;
/* pcmcia layer only remaps "real" memory not iospace */
- cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K);
- if (!cf->socket.io_offset)
+ cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
+ if (!cf->socket.io_offset) {
+ status = -ENXIO;
goto fail1;
+ }
- /* reserve CS4, CS5, and CS6 regions; but use just CS4 */
+ /* reserve chip-select regions */
if (!request_mem_region(io->start, io->end + 1 - io->start,
- driver_name))
+ driver_name)) {
+ status = -ENXIO;
goto fail1;
+ }
pr_info("%s: irqs det #%d, io #%d\n", driver_name,
board->det_pin, board->irq_pin);
@@ -319,9 +302,7 @@ fail1:
fail0a:
device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf);
- device_init_wakeup(&pdev->dev, 0);
fail0:
- at91_sys_write(AT91_EBI_CSA, csa);
kfree(cf);
return status;
}
@@ -331,19 +312,15 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
struct at91_cf_socket *cf = platform_get_drvdata(pdev);
struct at91_cf_data *board = cf->board;
struct resource *io = cf->socket.io[0].res;
- unsigned int csa;
pcmcia_unregister_socket(&cf->socket);
if (board->irq_pin)
free_irq(board->irq_pin, cf);
- free_irq(board->det_pin, cf);
device_init_wakeup(&pdev->dev, 0);
+ free_irq(board->det_pin, cf);
iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(io->start, io->end + 1 - io->start);
- csa = at91_sys_read(AT91_EBI_CSA);
- at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A);
-
kfree(cf);
return 0;
}
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index d6164cd583fd..f573ea04db6f 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -135,7 +135,7 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_s
struct pcmcia_callback{
struct module *owner;
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
- void (*requery) (struct pcmcia_socket *s);
+ void (*requery) (struct pcmcia_socket *s, int new_cis);
int (*suspend) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 21d83a895b21..7355eb455a88 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -231,65 +231,6 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
}
-#ifdef CONFIG_PCMCIA_LOAD_CIS
-
-/**
- * pcmcia_load_firmware - load CIS from userspace if device-provided is broken
- * @dev - the pcmcia device which needs a CIS override
- * @filename - requested filename in /lib/firmware/
- *
- * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if
- * the one provided by the card is broken. The firmware files reside in
- * /lib/firmware/ in userspace.
- */
-static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
-{
- struct pcmcia_socket *s = dev->socket;
- const struct firmware *fw;
- char path[20];
- int ret=-ENOMEM;
- cisdump_t *cis;
-
- if (!filename)
- return -EINVAL;
-
- ds_dbg(1, "trying to load firmware %s\n", filename);
-
- if (strlen(filename) > 14)
- return -EINVAL;
-
- snprintf(path, 20, "%s", filename);
-
- if (request_firmware(&fw, path, &dev->dev) == 0) {
- if (fw->size >= CISTPL_MAX_CIS_SIZE)
- goto release;
-
- cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
- if (!cis)
- goto release;
-
- cis->Length = fw->size + 1;
- memcpy(cis->Data, fw->data, fw->size);
-
- if (!pcmcia_replace_cis(s, cis))
- ret = 0;
- }
- release:
- release_firmware(fw);
-
- return (ret);
-}
-
-#else /* !CONFIG_PCMCIA_LOAD_CIS */
-
-static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
-{
- return -ENODEV;
-}
-
-#endif
-
-
/*======================================================================*/
@@ -309,6 +250,8 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
driver->drv.bus = &pcmcia_bus_type;
driver->drv.owner = driver->owner;
+ ds_dbg(3, "registering driver %s\n", driver->drv.name);
+
return driver_register(&driver->drv);
}
EXPORT_SYMBOL(pcmcia_register_driver);
@@ -318,6 +261,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
*/
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{
+ ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
driver_unregister(&driver->drv);
}
EXPORT_SYMBOL(pcmcia_unregister_driver);
@@ -343,23 +287,27 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
static void pcmcia_release_function(struct kref *ref)
{
struct config_t *c = container_of(ref, struct config_t, ref);
+ ds_dbg(1, "releasing config_t\n");
kfree(c);
}
static void pcmcia_release_dev(struct device *dev)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
- ds_dbg(1, "releasing dev %p\n", p_dev);
+ ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id);
pcmcia_put_socket(p_dev->socket);
kfree(p_dev->devname);
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
kfree(p_dev);
}
-static void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
+static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
{
if (!s->pcmcia_state.device_add_pending) {
+ ds_dbg(1, "scheduling to add %s secondary"
+ " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
s->pcmcia_state.device_add_pending = 1;
+ s->pcmcia_state.mfc_pfc = mfc;
schedule_work(&s->device_add);
}
return;
@@ -371,6 +319,7 @@ static int pcmcia_device_probe(struct device * dev)
struct pcmcia_driver *p_drv;
struct pcmcia_device_id *did;
struct pcmcia_socket *s;
+ cistpl_config_t cis_config;
int ret = 0;
dev = get_device(dev);
@@ -381,15 +330,33 @@ static int pcmcia_device_probe(struct device * dev)
p_drv = to_pcmcia_drv(dev->driver);
s = p_dev->socket;
+ ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
+ p_drv->drv.name);
+
if ((!p_drv->probe) || (!p_dev->function_config) ||
(!try_module_get(p_drv->owner))) {
ret = -EINVAL;
goto put_dev;
}
+ /* set up some more device information */
+ ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG,
+ &cis_config);
+ if (!ret) {
+ p_dev->conf.ConfigBase = cis_config.base;
+ p_dev->conf.Present = cis_config.rmask[0];
+ } else {
+ printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n");
+ p_dev->conf.ConfigBase = 0;
+ p_dev->conf.Present = 0;
+ }
+
ret = p_drv->probe(p_dev);
- if (ret)
+ if (ret) {
+ ds_dbg(1, "binding %s to %s failed with %d\n",
+ p_dev->dev.bus_id, p_drv->drv.name, ret);
goto put_module;
+ }
/* handle pseudo multifunction devices:
* there are at most two pseudo multifunction devices.
@@ -400,7 +367,7 @@ static int pcmcia_device_probe(struct device * dev)
did = p_dev->dev.driver_data;
if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
(p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
- pcmcia_add_pseudo_device(p_dev->socket);
+ pcmcia_add_device_later(p_dev->socket, 0);
put_module:
if (ret)
@@ -421,8 +388,8 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
struct pcmcia_device *tmp;
unsigned long flags;
- ds_dbg(2, "unbind_request(%d)\n", s->sock);
-
+ ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock,
+ leftover ? leftover->devname : "");
if (!leftover)
s->device_count = 0;
@@ -439,6 +406,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id);
device_unregister(&p_dev->dev);
}
@@ -455,6 +423,8 @@ static int pcmcia_device_remove(struct device * dev)
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);
+ ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id);
+
/* If we're removing the primary module driving a
* pseudo multi-function card, we need to unbind
* all devices
@@ -587,8 +557,10 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
mutex_lock(&device_add_lock);
- /* max of 2 devices per card */
- if (s->device_count == 2)
+ ds_dbg(3, "adding device to %d, function %d\n", s->sock, function);
+
+ /* max of 4 devices per card */
+ if (s->device_count == 4)
goto err_put;
p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
@@ -598,8 +570,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
p_dev->socket = s;
p_dev->device_no = (s->device_count++);
p_dev->func = function;
- if (s->functions <= function)
- s->functions = function + 1;
p_dev->dev.bus = &pcmcia_bus_type;
p_dev->dev.parent = s->dev.dev;
@@ -610,8 +580,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
if (!p_dev->devname)
goto err_free;
sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
+ ds_dbg(3, "devname is %s\n", p_dev->devname);
- /* compat */
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
/*
@@ -631,6 +601,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
if (!p_dev->function_config) {
+ ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id);
p_dev->function_config = kzalloc(sizeof(struct config_t),
GFP_KERNEL);
if (!p_dev->function_config)
@@ -674,11 +645,16 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
unsigned int no_funcs, i;
int ret = 0;
- if (!(s->resource_setup_done))
+ if (!(s->resource_setup_done)) {
+ ds_dbg(3, "no resources available, delaying card_add\n");
return -EAGAIN; /* try again, but later... */
+ }
- if (pcmcia_validate_mem(s))
+ if (pcmcia_validate_mem(s)) {
+ ds_dbg(3, "validating mem resources failed, "
+ "delaying card_add\n");
return -EAGAIN; /* try again, but later... */
+ }
ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
if (ret || !cisinfo.Chains) {
@@ -690,6 +666,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
no_funcs = mfc.nfn;
else
no_funcs = 1;
+ s->functions = no_funcs;
for (i=0; i < no_funcs; i++)
pcmcia_device_add(s, i);
@@ -698,38 +675,50 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
}
-static void pcmcia_delayed_add_pseudo_device(void *data)
+static void pcmcia_delayed_add_device(struct work_struct *work)
{
- struct pcmcia_socket *s = data;
- pcmcia_device_add(s, 0);
+ struct pcmcia_socket *s =
+ container_of(work, struct pcmcia_socket, device_add);
+ ds_dbg(1, "adding additional device to %d\n", s->sock);
+ pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
s->pcmcia_state.device_add_pending = 0;
+ s->pcmcia_state.mfc_pfc = 0;
}
static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
- if (!p_dev->dev.driver)
+ if (!p_dev->dev.driver) {
+ ds_dbg(1, "update device information for %s\n",
+ p_dev->dev.bus_id);
pcmcia_device_query(p_dev);
+ }
return 0;
}
-static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
+static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
{
- int no_devices=0;
+ int no_devices = 0;
int ret = 0;
unsigned long flags;
/* must be called with skt_mutex held */
+ ds_dbg(0, "re-scanning socket %d\n", skt->sock);
+
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
if (list_empty(&skt->devices_list))
- no_devices=1;
+ no_devices = 1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ /* If this is because of a CIS override, start over */
+ if (new_cis && !no_devices)
+ pcmcia_card_remove(skt, NULL);
+
/* if no devices were added for this socket yet because of
* missing resource information or other trouble, we need to
* do this now. */
- if (no_devices) {
+ if (no_devices || new_cis) {
ret = pcmcia_card_add(skt);
if (ret)
return;
@@ -747,6 +736,97 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
}
+#ifdef CONFIG_PCMCIA_LOAD_CIS
+
+/**
+ * pcmcia_load_firmware - load CIS from userspace if device-provided is broken
+ * @dev - the pcmcia device which needs a CIS override
+ * @filename - requested filename in /lib/firmware/
+ *
+ * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if
+ * the one provided by the card is broken. The firmware files reside in
+ * /lib/firmware/ in userspace.
+ */
+static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
+{
+ struct pcmcia_socket *s = dev->socket;
+ const struct firmware *fw;
+ char path[20];
+ int ret = -ENOMEM;
+ int no_funcs;
+ int old_funcs;
+ cisdump_t *cis;
+ cistpl_longlink_mfc_t mfc;
+
+ if (!filename)
+ return -EINVAL;
+
+ ds_dbg(1, "trying to load CIS file %s\n", filename);
+
+ if (strlen(filename) > 14) {
+ printk(KERN_WARNING "pcmcia: CIS filename is too long\n");
+ return -EINVAL;
+ }
+
+ snprintf(path, 20, "%s", filename);
+
+ if (request_firmware(&fw, path, &dev->dev) == 0) {
+ if (fw->size >= CISTPL_MAX_CIS_SIZE) {
+ ret = -EINVAL;
+ printk(KERN_ERR "pcmcia: CIS override is too big\n");
+ goto release;
+ }
+
+ cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
+ if (!cis) {
+ ret = -ENOMEM;
+ goto release;
+ }
+
+ cis->Length = fw->size + 1;
+ memcpy(cis->Data, fw->data, fw->size);
+
+ if (!pcmcia_replace_cis(s, cis))
+ ret = 0;
+ else {
+ printk(KERN_ERR "pcmcia: CIS override failed\n");
+ goto release;
+ }
+
+
+ /* update information */
+ pcmcia_device_query(dev);
+
+ /* does this cis override add or remove functions? */
+ old_funcs = s->functions;
+
+ if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
+ no_funcs = mfc.nfn;
+ else
+ no_funcs = 1;
+ s->functions = no_funcs;
+
+ if (old_funcs > no_funcs)
+ pcmcia_card_remove(s, dev);
+ else if (no_funcs > old_funcs)
+ pcmcia_add_device_later(s, 1);
+ }
+ release:
+ release_firmware(fw);
+
+ return (ret);
+}
+
+#else /* !CONFIG_PCMCIA_LOAD_CIS */
+
+static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
+{
+ return -ENODEV;
+}
+
+#endif
+
+
static inline int pcmcia_devmatch(struct pcmcia_device *dev,
struct pcmcia_device_id *did)
{
@@ -813,11 +893,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
* after it has re-checked that there is no possible module
* with a prod_id/manf_id/card_id match.
*/
+ ds_dbg(0, "skipping FUNC_ID match for %s until userspace "
+ "interaction\n", dev->dev.bus_id);
if (!dev->allow_func_id_match)
return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
+ ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id);
if (!dev->socket->fake_cis)
pcmcia_load_firmware(dev, did->cisfile);
@@ -847,13 +930,21 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
- if (p_dev->cardmgr == p_drv)
+ if (p_dev->cardmgr == p_drv) {
+ ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id,
+ drv->name);
return 1;
+ }
#endif
while (did && did->match_flags) {
- if (pcmcia_devmatch(p_dev, did))
+ ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
+ drv->name);
+ if (pcmcia_devmatch(p_dev, did)) {
+ ds_dbg(0, "matched %s to %s\n", dev->bus_id,
+ drv->name);
return 1;
+ }
did++;
}
@@ -1044,6 +1135,8 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
struct pcmcia_driver *p_drv = NULL;
int ret = 0;
+ ds_dbg(2, "suspending %s\n", dev->bus_id);
+
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1052,12 +1145,18 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_drv->suspend) {
ret = p_drv->suspend(p_dev);
- if (ret)
+ if (ret) {
+ printk(KERN_ERR "pcmcia: device %s (driver %s) did "
+ "not want to go to sleep (%d)\n",
+ p_dev->devname, p_drv->drv.name, ret);
goto out;
+ }
}
- if (p_dev->device_no == p_dev->func)
+ if (p_dev->device_no == p_dev->func) {
+ ds_dbg(2, "releasing configuration for %s\n", dev->bus_id);
pcmcia_release_configuration(p_dev);
+ }
out:
if (!ret)
@@ -1072,6 +1171,8 @@ static int pcmcia_dev_resume(struct device * dev)
struct pcmcia_driver *p_drv = NULL;
int ret = 0;
+ ds_dbg(2, "resuming %s\n", dev->bus_id);
+
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1079,6 +1180,7 @@ static int pcmcia_dev_resume(struct device * dev)
goto out;
if (p_dev->device_no == p_dev->func) {
+ ds_dbg(2, "requesting configuration for %s\n", dev->bus_id);
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
if (ret)
goto out;
@@ -1120,12 +1222,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
{
+ ds_dbg(2, "resuming socket %d\n", skt->sock);
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
return 0;
}
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
{
+ ds_dbg(2, "suspending socket %d\n", skt->sock);
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
pcmcia_bus_suspend_callback)) {
pcmcia_bus_resume(skt);
@@ -1246,7 +1350,7 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
init_waitqueue_head(&socket->queue);
#endif
INIT_LIST_HEAD(&socket->devices_list);
- INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket);
+ INIT_WORK(&socket->device_add, pcmcia_delayed_add_device);
memset(&socket->pcmcia_state, 0, sizeof(u8));
socket->device_count = 0;
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 36fdaa58458c..3c22ac4625c2 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -398,7 +398,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
static void pcc_interrupt_wrapper(u_long data)
{
debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
- pcc_interrupt(0, NULL, NULL);
+ pcc_interrupt(0, NULL);
init_timer(&poll_timer);
poll_timer.expires = jiffies + poll_interval;
add_timer(&poll_timer);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 310ede575caa..d077870c6731 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -594,7 +594,12 @@ static int ds_ioctl(struct inode * inode, struct file * file,
err = ret = 0;
- if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
+ if (cmd & IOC_IN) {
+ if (__copy_from_user((char *)buf, uarg, size)) {
+ err = -EFAULT;
+ goto free_out;
+ }
+ }
switch (cmd) {
case DS_ADJUST_RESOURCE_INFO:
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index a70f97fdbbdd..360c24896548 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -581,10 +581,10 @@ static irqreturn_t pd6729_test(int irq, void *dev)
return IRQ_HANDLED;
}
-static int pd6729_check_irq(int irq, int flags)
+static int pd6729_check_irq(int irq)
{
- if (request_irq(irq, pd6729_test, flags, "x", pd6729_test) != 0)
- return -1;
+ if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test)
+ != 0) return -1;
free_irq(irq, pd6729_test);
return 0;
}
@@ -610,7 +610,7 @@ static u_int __devinit pd6729_isa_scan(void)
/* just find interrupts that aren't in use */
for (i = 0; i < 16; i++)
- if ((mask0 & (1 << i)) && (pd6729_check_irq(i, 0) == 0))
+ if ((mask0 & (1 << i)) && (pd6729_check_irq(i) == 0))
mask |= (1 << i);
printk(KERN_INFO "pd6729: ISA irqs = ");
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 933cd864a5c9..b005602d6b53 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -188,7 +188,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
(s->state & SOCKET_PRESENT) &&
!(s->state & SOCKET_CARDBUS)) {
if (try_module_get(s->callback->owner)) {
- s->callback->requery(s);
+ s->callback->requery(s, 0);
module_put(s->callback->owner);
}
}
@@ -325,7 +325,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
if ((s->callback) && (s->state & SOCKET_PRESENT) &&
!(s->state & SOCKET_CARDBUS)) {
if (try_module_get(s->callback->owner)) {
- s->callback->requery(s);
+ s->callback->requery(s, 1);
module_put(s->callback->owner);
}
}
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
new file mode 100644
index 000000000000..b52d547b7a78
--- /dev/null
+++ b/drivers/ps3/Makefile
@@ -0,0 +1 @@
+obj-y += system-bus.o
diff --git a/drivers/ps3/system-bus.c b/drivers/ps3/system-bus.c
new file mode 100644
index 000000000000..d79f949bcb2a
--- /dev/null
+++ b/drivers/ps3/system-bus.c
@@ -0,0 +1,362 @@
+/*
+ * PS3 system bus driver.
+ *
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ * Copyright 2006 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+
+#include <asm/udbg.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+#include <asm/firmware.h>
+
+#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
+static void _dump_mmio_region(const struct ps3_mmio_region* r,
+ const char* func, int line)
+{
+ pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id,
+ r->did.dev_id);
+ pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
+ pr_debug("%s:%d: len %lxh\n", func, line, r->len);
+ pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
+}
+
+int ps3_mmio_region_create(struct ps3_mmio_region *r)
+{
+ int result;
+
+ result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id,
+ r->bus_addr, r->len, r->page_size, &r->lpar_addr);
+
+ if (result) {
+ pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+ r->lpar_addr = r->len = r->bus_addr = 0;
+ }
+
+ dump_mmio_region(r);
+ return result;
+}
+
+int ps3_free_mmio_region(struct ps3_mmio_region *r)
+{
+ int result;
+
+ result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
+ r->bus_addr);
+
+ if (result)
+ pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+
+ r->lpar_addr = r->len = r->bus_addr = 0;
+ return result;
+}
+
+static int ps3_system_bus_match(struct device *_dev,
+ struct device_driver *_drv)
+{
+ int result;
+ struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv);
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+
+ result = dev->match_id == drv->match_id;
+
+ pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__,
+ dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name,
+ (result ? "match" : "miss"));
+ return result;
+}
+
+static int ps3_system_bus_probe(struct device *_dev)
+{
+ int result;
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ struct ps3_system_bus_driver *drv =
+ to_ps3_system_bus_driver(_dev->driver);
+
+ result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
+
+ if (result) {
+ pr_debug("%s:%d: lv1_open_device failed (%d)\n",
+ __func__, __LINE__, result);
+ result = -EACCES;
+ goto clean_none;
+ }
+
+ if (dev->d_region->did.bus_id) {
+ result = ps3_dma_region_create(dev->d_region);
+
+ if (result) {
+ pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
+ __func__, __LINE__, result);
+ BUG_ON("check region type");
+ result = -EINVAL;
+ goto clean_device;
+ }
+ }
+
+ BUG_ON(!drv);
+
+ if (drv->probe)
+ result = drv->probe(dev);
+ else
+ pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
+ dev->core.bus_id);
+
+ if (result) {
+ pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
+ goto clean_dma;
+ }
+
+ return result;
+
+clean_dma:
+ ps3_dma_region_free(dev->d_region);
+clean_device:
+ lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+clean_none:
+ return result;
+}
+
+static int ps3_system_bus_remove(struct device *_dev)
+{
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ struct ps3_system_bus_driver *drv =
+ to_ps3_system_bus_driver(_dev->driver);
+
+ if (drv->remove)
+ drv->remove(dev);
+ else
+ pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
+ dev->core.bus_id);
+
+ ps3_dma_region_free(dev->d_region);
+ ps3_free_mmio_region(dev->m_region);
+ lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+
+ return 0;
+}
+
+struct bus_type ps3_system_bus_type = {
+ .name = "ps3_system_bus",
+ .match = ps3_system_bus_match,
+ .probe = ps3_system_bus_probe,
+ .remove = ps3_system_bus_remove,
+};
+
+int __init ps3_system_bus_init(void)
+{
+ int result;
+
+ if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+ return 0;
+
+ result = bus_register(&ps3_system_bus_type);
+ BUG_ON(result);
+ return result;
+}
+
+core_initcall(ps3_system_bus_init);
+
+/* Allocates a contiguous real buffer and creates mappings over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (mapping) of the first page.
+ */
+
+static void * ps3_alloc_coherent(struct device *_dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ int result;
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ unsigned long virt_addr;
+
+ BUG_ON(!dev->d_region->bus_addr);
+
+ flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
+ flag |= __GFP_ZERO;
+
+ virt_addr = __get_free_pages(flag, get_order(size));
+
+ if (!virt_addr) {
+ pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
+ goto clean_none;
+ }
+
+ result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle);
+
+ if (result) {
+ pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
+ __func__, __LINE__, result);
+ BUG_ON("check region type");
+ goto clean_alloc;
+ }
+
+ return (void*)virt_addr;
+
+clean_alloc:
+ free_pages(virt_addr, get_order(size));
+clean_none:
+ dma_handle = NULL;
+ return NULL;
+}
+
+static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+
+ ps3_dma_unmap(dev->d_region, dma_handle, size);
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+
+/* Creates TCEs for a user provided buffer. The user buffer must be
+ * contiguous real kernel storage (not vmalloc). The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer. The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+
+static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ int result;
+ unsigned long bus_addr;
+
+ result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
+ &bus_addr);
+
+ if (result) {
+ pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
+ __func__, __LINE__, result);
+ }
+
+ return bus_addr;
+}
+
+static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ int result;
+
+ result = ps3_dma_unmap(dev->d_region, dma_addr, size);
+
+ if (result) {
+ pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
+ __func__, __LINE__, result);
+ }
+}
+
+static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+#if defined(CONFIG_PS3_DYNAMIC_DMA)
+ BUG_ON("do");
+#endif
+ return 0;
+}
+
+static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+#if defined(CONFIG_PS3_DYNAMIC_DMA)
+ BUG_ON("do");
+#endif
+}
+
+static int ps3_dma_supported(struct device *_dev, u64 mask)
+{
+ return 1;
+}
+
+static struct dma_mapping_ops ps3_dma_ops = {
+ .alloc_coherent = ps3_alloc_coherent,
+ .free_coherent = ps3_free_coherent,
+ .map_single = ps3_map_single,
+ .unmap_single = ps3_unmap_single,
+ .map_sg = ps3_map_sg,
+ .unmap_sg = ps3_unmap_sg,
+ .dma_supported = ps3_dma_supported
+};
+
+/**
+ * ps3_system_bus_release_device - remove a device from the system bus
+ */
+
+static void ps3_system_bus_release_device(struct device *_dev)
+{
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ kfree(dev);
+}
+
+/**
+ * ps3_system_bus_device_register - add a device to the system bus
+ *
+ * ps3_system_bus_device_register() expects the dev object to be allocated
+ * dynamically by the caller. The system bus takes ownership of the dev
+ * object and frees the object in ps3_system_bus_release_device().
+ */
+
+int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
+{
+ int result;
+ static unsigned int dev_count = 1;
+
+ dev->core.parent = NULL;
+ dev->core.bus = &ps3_system_bus_type;
+ dev->core.release = ps3_system_bus_release_device;
+
+ dev->core.archdata.of_node = NULL;
+ dev->core.archdata.dma_ops = &ps3_dma_ops;
+ dev->core.archdata.numa_node = 0;
+
+ snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
+ dev_count++);
+
+ pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
+
+ result = device_register(&dev->core);
+ return result;
+}
+
+EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
+
+int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
+{
+ int result;
+
+ drv->core.bus = &ps3_system_bus_type;
+
+ result = driver_register(&drv->core);
+ return result;
+}
+
+EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
+
+void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
+{
+ driver_unregister(&drv->core);
+}
+
+EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 814b9e1873f5..828b329e08e0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -53,9 +53,10 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
* Routine to poll RTC seconds field for change as often as possible,
* after first RTC_UIE use timer to reduce polling
*/
-static void rtc_uie_task(void *data)
+static void rtc_uie_task(struct work_struct *work)
{
- struct rtc_device *rtc = data;
+ struct rtc_device *rtc =
+ container_of(work, struct rtc_device, uie_task);
struct rtc_time tm;
int num = 0;
int err;
@@ -411,7 +412,7 @@ static int rtc_dev_add_device(struct class_device *class_dev,
spin_lock_init(&rtc->irq_lock);
init_waitqueue_head(&rtc->irq_queue);
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
- INIT_WORK(&rtc->uie_task, rtc_uie_task, rtc);
+ INIT_WORK(&rtc->uie_task, rtc_uie_task);
setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
#endif
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 79ffef6bfaf8..2af2d9b53d18 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -54,7 +54,7 @@ static void dasd_flush_request_queue(struct dasd_device *);
static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
static int dasd_flush_ccw_queue(struct dasd_device *, int);
static void dasd_tasklet(struct dasd_device *);
-static void do_kick_device(void *data);
+static void do_kick_device(struct work_struct *);
/*
* SECTION: Operations on the device structure.
@@ -100,7 +100,7 @@ dasd_alloc_device(void)
(unsigned long) device);
INIT_LIST_HEAD(&device->ccw_queue);
init_timer(&device->timer);
- INIT_WORK(&device->kick_work, do_kick_device, device);
+ INIT_WORK(&device->kick_work, do_kick_device);
device->state = DASD_STATE_NEW;
device->target = DASD_STATE_NEW;
@@ -407,11 +407,9 @@ dasd_change_state(struct dasd_device *device)
* event daemon.
*/
static void
-do_kick_device(void *data)
+do_kick_device(struct work_struct *work)
{
- struct dasd_device *device;
-
- device = (struct dasd_device *) data;
+ struct dasd_device *device = container_of(work, struct dasd_device, kick_work);
dasd_change_state(device);
dasd_schedule_bh(device);
dasd_put_device(device);
@@ -1264,15 +1262,21 @@ __dasd_check_expire(struct dasd_device * device)
if (list_empty(&device->ccw_queue))
return;
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
- if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) {
- if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) {
+ if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) &&
+ (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
+ if (device->discipline->term_IO(cqr) != 0) {
+ /* Hmpf, try again in 5 sec */
+ dasd_set_timer(device, 5*HZ);
+ DEV_MESSAGE(KERN_ERR, device,
+ "internal error - timeout (%is) expired "
+ "for cqr %p, termination failed, "
+ "retrying in 5s",
+ (cqr->expires/HZ), cqr);
+ } else {
DEV_MESSAGE(KERN_ERR, device,
"internal error - timeout (%is) expired "
"for cqr %p (%i retries left)",
(cqr->expires/HZ), cqr, cqr->retries);
- if (device->discipline->term_IO(cqr) != 0)
- /* Hmpf, try again in 1/10 sec */
- dasd_set_timer(device, 10);
}
}
}
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 91cf971f0652..17fdd8c9f740 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -684,21 +684,26 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dasd_devmap *devmap;
- int ro_flag;
+ int val;
+ char *endp;
devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
if (IS_ERR(devmap))
return PTR_ERR(devmap);
- ro_flag = buf[0] == '1';
+
+ val = simple_strtoul(buf, &endp, 0);
+ if (((endp + 1) < (buf + count)) || (val > 1))
+ return -EINVAL;
+
spin_lock(&dasd_devmap_lock);
- if (ro_flag)
+ if (val)
devmap->features |= DASD_FEATURE_READONLY;
else
devmap->features &= ~DASD_FEATURE_READONLY;
if (devmap->device)
devmap->device->features = devmap->features;
if (devmap->device && devmap->device->gdp)
- set_disk_ro(devmap->device->gdp, ro_flag);
+ set_disk_ro(devmap->device->gdp, val);
spin_unlock(&dasd_devmap_lock);
return count;
}
@@ -729,17 +734,22 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
{
struct dasd_devmap *devmap;
ssize_t rc;
- int use_diag;
+ int val;
+ char *endp;
devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
if (IS_ERR(devmap))
return PTR_ERR(devmap);
- use_diag = buf[0] == '1';
+
+ val = simple_strtoul(buf, &endp, 0);
+ if (((endp + 1) < (buf + count)) || (val > 1))
+ return -EINVAL;
+
spin_lock(&dasd_devmap_lock);
/* Changing diag discipline flag is only allowed in offline state. */
rc = count;
if (!devmap->device) {
- if (use_diag)
+ if (val)
devmap->features |= DASD_FEATURE_USEDIAG;
else
devmap->features &= ~DASD_FEATURE_USEDIAG;
@@ -854,14 +864,20 @@ dasd_eer_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dasd_devmap *devmap;
- int rc;
+ int val, rc;
+ char *endp;
devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
if (IS_ERR(devmap))
return PTR_ERR(devmap);
if (!devmap->device)
- return count;
- if (buf[0] == '1') {
+ return -ENODEV;
+
+ val = simple_strtoul(buf, &endp, 0);
+ if (((endp + 1) < (buf + count)) || (val > 1))
+ return -EINVAL;
+
+ if (val) {
rc = dasd_eer_enable(devmap->device);
if (rc)
return rc;
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index d7de175d53f0..c9321b920e90 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -299,14 +299,14 @@ raw3215_timeout(unsigned long __data)
struct raw3215_info *raw = (struct raw3215_info *) __data;
unsigned long flags;
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if (raw->flags & RAW3215_TIMER_RUNS) {
del_timer(&raw->timer);
raw->flags &= ~RAW3215_TIMER_RUNS;
raw3215_mk_write_req(raw);
raw3215_start_io(raw);
}
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
/*
@@ -355,10 +355,10 @@ raw3215_tasklet(void *data)
unsigned long flags;
raw = (struct raw3215_info *) data;
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_mk_write_req(raw);
raw3215_try_io(raw);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
/* Check for pending message from raw3215_irq */
if (raw->message != NULL) {
printk(raw->message, raw->msg_dstat, raw->msg_cstat);
@@ -512,9 +512,9 @@ raw3215_make_room(struct raw3215_info *raw, unsigned int length)
if (RAW3215_BUFFER_SIZE - raw->count >= length)
break;
/* there might be another cpu waiting for the lock */
- spin_unlock(raw->lock);
+ spin_unlock(get_ccwdev_lock(raw->cdev));
udelay(100);
- spin_lock(raw->lock);
+ spin_lock(get_ccwdev_lock(raw->cdev));
}
}
@@ -528,7 +528,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
int c, count;
while (length > 0) {
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
count = (length > RAW3215_BUFFER_SIZE) ?
RAW3215_BUFFER_SIZE : length;
length -= count;
@@ -555,7 +555,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
/* start or queue request */
raw3215_try_io(raw);
}
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
}
@@ -568,7 +568,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
unsigned long flags;
unsigned int length, i;
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if (ch == '\t') {
length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
raw->line_pos += length;
@@ -592,7 +592,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
/* start or queue request */
raw3215_try_io(raw);
}
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
/*
@@ -604,13 +604,13 @@ raw3215_flush_buffer(struct raw3215_info *raw)
{
unsigned long flags;
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if (raw->count > 0) {
raw->flags |= RAW3215_FLUSHING;
raw3215_try_io(raw);
raw->flags &= ~RAW3215_FLUSHING;
}
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
/*
@@ -625,9 +625,9 @@ raw3215_startup(struct raw3215_info *raw)
return 0;
raw->line_pos = 0;
raw->flags |= RAW3215_ACTIVE;
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_try_io(raw);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
return 0;
}
@@ -644,21 +644,21 @@ raw3215_shutdown(struct raw3215_info *raw)
if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
return;
/* Wait for outstanding requests, then free irq */
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if ((raw->flags & RAW3215_WORKING) ||
raw->queued_write != NULL ||
raw->queued_read != NULL) {
raw->flags |= RAW3215_CLOSING;
add_wait_queue(&raw->empty_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
schedule();
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
remove_wait_queue(&raw->empty_wait, &wait);
set_current_state(TASK_RUNNING);
raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
}
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
static int
@@ -686,7 +686,6 @@ raw3215_probe (struct ccw_device *cdev)
}
raw->cdev = cdev;
- raw->lock = get_ccwdev_lock(cdev);
raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
memset(raw, 0, sizeof(struct raw3215_info));
raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
@@ -809,9 +808,9 @@ con3215_unblank(void)
unsigned long flags;
raw = raw3215[0]; /* console 3215 is the first one */
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
static int __init
@@ -873,7 +872,6 @@ con3215_init(void)
raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
raw->cdev = cdev;
- raw->lock = get_ccwdev_lock(cdev);
cdev->dev.driver_data = raw;
cdev->handler = raw3215_irq;
@@ -1066,10 +1064,10 @@ tty3215_unthrottle(struct tty_struct * tty)
raw = (struct raw3215_info *) tty->driver_data;
if (raw->flags & RAW3215_THROTTLED) {
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw->flags &= ~RAW3215_THROTTLED;
raw3215_try_io(raw);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
}
@@ -1096,10 +1094,10 @@ tty3215_start(struct tty_struct *tty)
raw = (struct raw3215_info *) tty->driver_data;
if (raw->flags & RAW3215_STOPPED) {
- spin_lock_irqsave(raw->lock, flags);
+ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw->flags &= ~RAW3215_STOPPED;
raw3215_try_io(raw);
- spin_unlock_irqrestore(raw->lock, flags);
+ spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
}
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 32004aae95c1..ffa9282ce97a 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -19,52 +19,17 @@
#include "sclp.h"
-
-#ifdef CONFIG_SMP
-/* Signal completion of shutdown process. All CPUs except the first to enter
- * this function: go to stopped state. First CPU: wait until all other
- * CPUs are in stopped or check stop state. Afterwards, load special PSW
- * to indicate completion. */
-static void
-do_load_quiesce_psw(void * __unused)
-{
- static atomic_t cpuid = ATOMIC_INIT(-1);
- psw_t quiesce_psw;
- int cpu;
-
- if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
- signal_processor(smp_processor_id(), sigp_stop);
- /* Wait for all other cpus to enter stopped state */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
- while(!smp_cpu_not_running(cpu))
- cpu_relax();
- }
- /* Quiesce the last cpu with the special psw */
- quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
- quiesce_psw.addr = 0xfff;
- __load_psw(quiesce_psw);
-}
-
-/* Shutdown handler. Perform shutdown function on all CPUs. */
-static void
-do_machine_quiesce(void)
-{
- on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
-}
-#else
/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
static void
do_machine_quiesce(void)
{
psw_t quiesce_psw;
+ smp_send_stop();
quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
quiesce_psw.addr = 0xfff;
__load_psw(quiesce_psw);
}
-#endif
/* Handler for quiesce event. Start shutdown procedure. */
static void
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 2d78f0f4a40f..dbfb77b03928 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -251,6 +251,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
cc = cio_clear(sch);
if (cc == -ENODEV)
goto out_unreg;
+ /* Request retry of internal operation. */
+ device_set_intretry(sch);
/* Call handler. */
if (sch->driver && sch->driver->termination)
sch->driver->termination(&sch->dev);
@@ -711,9 +713,6 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
{
int cc;
- if (!device_is_online(sch))
- /* cio could be doing I/O. */
- return 0;
cc = stsch(sch->schid, &sch->schib);
if (cc)
return 0;
@@ -722,6 +721,26 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
return 0;
}
+static void terminate_internal_io(struct subchannel *sch)
+{
+ if (cio_clear(sch)) {
+ /* Recheck device in case clear failed. */
+ sch->lpm = 0;
+ if (device_trigger_verify(sch) != 0) {
+ if(css_enqueue_subchannel_slow(sch->schid)) {
+ css_clear_subchannel_slow_list();
+ need_rescan = 1;
+ }
+ }
+ return;
+ }
+ /* Request retry of internal operation. */
+ device_set_intretry(sch);
+ /* Call handler. */
+ if (sch->driver && sch->driver->termination)
+ sch->driver->termination(&sch->dev);
+}
+
static inline void
__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
{
@@ -744,20 +763,26 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
device_trigger_reprobe(sch);
else if (sch->driver && sch->driver->verify)
sch->driver->verify(&sch->dev);
- } else {
- sch->opm &= ~(0x80 >> chp);
- sch->lpm &= ~(0x80 >> chp);
- if (check_for_io_on_path(sch, chp))
+ break;
+ }
+ sch->opm &= ~(0x80 >> chp);
+ sch->lpm &= ~(0x80 >> chp);
+ if (check_for_io_on_path(sch, chp)) {
+ if (device_is_online(sch))
/* Path verification is done after killing. */
device_kill_io(sch);
- else if (!sch->lpm) {
+ else
+ /* Kill and retry internal I/O. */
+ terminate_internal_io(sch);
+ } else if (!sch->lpm) {
+ if (device_trigger_verify(sch) != 0) {
if (css_enqueue_subchannel_slow(sch->schid)) {
css_clear_subchannel_slow_list();
need_rescan = 1;
}
- } else if (sch->driver && sch->driver->verify)
- sch->driver->verify(&sch->dev);
- }
+ }
+ } else if (sch->driver && sch->driver->verify)
+ sch->driver->verify(&sch->dev);
break;
}
spin_unlock_irqrestore(&sch->lock, flags);
@@ -1465,41 +1490,6 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no)
return desc;
}
-static int reset_channel_path(struct channel_path *chp)
-{
- int cc;
-
- cc = rchp(chp->id);
- switch (cc) {
- case 0:
- return 0;
- case 2:
- return -EBUSY;
- default:
- return -ENODEV;
- }
-}
-
-static void reset_channel_paths_css(struct channel_subsystem *css)
-{
- int i;
-
- for (i = 0; i <= __MAX_CHPID; i++) {
- if (css->chps[i])
- reset_channel_path(css->chps[i]);
- }
-}
-
-void cio_reset_channel_paths(void)
-{
- int i;
-
- for (i = 0; i <= __MAX_CSSID; i++) {
- if (css[i] && css[i]->valid)
- reset_channel_paths_css(css[i]);
- }
-}
-
static int __init
chsc_alloc_sei_area(void)
{
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 8936e460a807..20aee2783847 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -21,6 +21,7 @@
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/setup.h>
+#include <asm/reset.h>
#include "airq.h"
#include "cio.h"
#include "css.h"
@@ -28,6 +29,7 @@
#include "ioasm.h"
#include "blacklist.h"
#include "cio_debug.h"
+#include "../s390mach.h"
debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id;
@@ -841,26 +843,12 @@ __clear_subchannel_easy(struct subchannel_id schid)
return -EBUSY;
}
-struct sch_match_id {
- struct subchannel_id schid;
- struct ccw_dev_id devid;
- int rc;
-};
-
-static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
- void *data)
+static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
{
struct schib schib;
- struct sch_match_id *match_id = data;
if (stsch_err(schid, &schib))
return -ENXIO;
- if (match_id && schib.pmcw.dnv &&
- (schib.pmcw.dev == match_id->devid.devno) &&
- (schid.ssid == match_id->devid.ssid)) {
- match_id->schid = schid;
- match_id->rc = 0;
- }
if (!schib.pmcw.ena)
return 0;
switch(__disable_subchannel_easy(schid, &schib)) {
@@ -876,27 +864,111 @@ static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
return 0;
}
-static int clear_all_subchannels_and_match(struct ccw_dev_id *devid,
- struct subchannel_id *schid)
+static atomic_t chpid_reset_count;
+
+static void s390_reset_chpids_mcck_handler(void)
+{
+ struct crw crw;
+ struct mci *mci;
+
+ /* Check for pending channel report word. */
+ mci = (struct mci *)&S390_lowcore.mcck_interruption_code;
+ if (!mci->cp)
+ return;
+ /* Process channel report words. */
+ while (stcrw(&crw) == 0) {
+ /* Check for responses to RCHP. */
+ if (crw.slct && crw.rsc == CRW_RSC_CPATH)
+ atomic_dec(&chpid_reset_count);
+ }
+}
+
+#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
+static void css_reset(void)
+{
+ int i, ret;
+ unsigned long long timeout;
+
+ /* Reset subchannels. */
+ for_each_subchannel(__shutdown_subchannel_easy, NULL);
+ /* Reset channel paths. */
+ s390_reset_mcck_handler = s390_reset_chpids_mcck_handler;
+ /* Enable channel report machine checks. */
+ __ctl_set_bit(14, 28);
+ /* Temporarily reenable machine checks. */
+ local_mcck_enable();
+ for (i = 0; i <= __MAX_CHPID; i++) {
+ ret = rchp(i);
+ if ((ret == 0) || (ret == 2))
+ /*
+ * rchp either succeeded, or another rchp is already
+ * in progress. In either case, we'll get a crw.
+ */
+ atomic_inc(&chpid_reset_count);
+ }
+ /* Wait for machine check for all channel paths. */
+ timeout = get_clock() + (RCHP_TIMEOUT << 12);
+ while (atomic_read(&chpid_reset_count) != 0) {
+ if (get_clock() > timeout)
+ break;
+ cpu_relax();
+ }
+ /* Disable machine checks again. */
+ local_mcck_disable();
+ /* Disable channel report machine checks. */
+ __ctl_clear_bit(14, 28);
+ s390_reset_mcck_handler = NULL;
+}
+
+static struct reset_call css_reset_call = {
+ .fn = css_reset,
+};
+
+static int __init init_css_reset_call(void)
+{
+ atomic_set(&chpid_reset_count, 0);
+ register_reset_call(&css_reset_call);
+ return 0;
+}
+
+arch_initcall(init_css_reset_call);
+
+struct sch_match_id {
+ struct subchannel_id schid;
+ struct ccw_dev_id devid;
+ int rc;
+};
+
+static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
+{
+ struct schib schib;
+ struct sch_match_id *match_id = data;
+
+ if (stsch_err(schid, &schib))
+ return -ENXIO;
+ if (schib.pmcw.dnv &&
+ (schib.pmcw.dev == match_id->devid.devno) &&
+ (schid.ssid == match_id->devid.ssid)) {
+ match_id->schid = schid;
+ match_id->rc = 0;
+ return 1;
+ }
+ return 0;
+}
+
+static int reipl_find_schid(struct ccw_dev_id *devid,
+ struct subchannel_id *schid)
{
struct sch_match_id match_id;
match_id.devid = *devid;
match_id.rc = -ENODEV;
- local_irq_disable();
- for_each_subchannel(__shutdown_subchannel_easy_and_match, &match_id);
+ for_each_subchannel(__reipl_subchannel_match, &match_id);
if (match_id.rc == 0)
*schid = match_id.schid;
return match_id.rc;
}
-
-void clear_all_subchannels(void)
-{
- local_irq_disable();
- for_each_subchannel(__shutdown_subchannel_easy_and_match, NULL);
-}
-
extern void do_reipl_asm(__u32 schid);
/* Make sure all subchannels are quiet before we re-ipl an lpar. */
@@ -904,9 +976,9 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
{
struct subchannel_id schid;
- if (clear_all_subchannels_and_match(devid, &schid))
+ s390_reset_system();
+ if (reipl_find_schid(devid, &schid) != 0)
panic("IPL Device not found\n");
- cio_reset_channel_paths();
do_reipl_asm(*((__u32*)&schid));
}
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index ad7f7e1c0163..26cf2f5ae2e7 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -334,7 +334,7 @@ static LIST_HEAD(slow_subchannels_head);
static DEFINE_SPINLOCK(slow_subchannel_lock);
static void
-css_trigger_slow_path(void)
+css_trigger_slow_path(struct work_struct *unused)
{
CIO_TRACE_EVENT(4, "slowpath");
@@ -359,8 +359,7 @@ css_trigger_slow_path(void)
spin_unlock_irq(&slow_subchannel_lock);
}
-typedef void (*workfunc)(void *);
-DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
+DECLARE_WORK(slow_path_work, css_trigger_slow_path);
struct workqueue_struct *slow_path_wq;
/* Reprobe subchannel if unregistered. */
@@ -397,7 +396,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data)
}
/* Work function used to reprobe all unregistered subchannels. */
-static void reprobe_all(void *data)
+static void reprobe_all(struct work_struct *unused)
{
int ret;
@@ -413,7 +412,7 @@ static void reprobe_all(void *data)
need_reprobe);
}
-DECLARE_WORK(css_reprobe_work, reprobe_all, NULL);
+DECLARE_WORK(css_reprobe_work, reprobe_all);
/* Schedule reprobing of all unregistered subchannels. */
void css_schedule_reprobe(void)
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 4c2ff8336288..9ff064e71767 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -94,6 +94,7 @@ struct ccw_device_private {
unsigned int donotify:1; /* call notify function */
unsigned int recog_done:1; /* dev. recog. complete */
unsigned int fake_irb:1; /* deliver faked irb */
+ unsigned int intretry:1; /* retry internal operation */
} __attribute__((packed)) flags;
unsigned long intparm; /* user interruption parameter */
struct qdio_irq *qdio_data;
@@ -171,6 +172,8 @@ void device_trigger_reprobe(struct subchannel *);
/* Helper functions for vary on/off. */
int device_is_online(struct subchannel *);
void device_kill_io(struct subchannel *);
+void device_set_intretry(struct subchannel *sch);
+int device_trigger_verify(struct subchannel *sch);
/* Machine check helper function. */
void device_kill_pending_timer(struct subchannel *);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 39c98f940507..d3d3716ff84b 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -687,8 +687,20 @@ io_subchannel_register(void *data)
cdev = data;
sch = to_subchannel(cdev->dev.parent);
+ /*
+ * io_subchannel_register() will also be called after device
+ * recognition has been done for a boxed device (which will already
+ * be registered). We need to reprobe since we may now have sense id
+ * information.
+ */
if (klist_node_attached(&cdev->dev.knode_parent)) {
- bus_rescan_devices(&ccw_bus_type);
+ if (!cdev->drv) {
+ ret = device_reprobe(&cdev->dev);
+ if (ret)
+ /* We can't do much here. */
+ dev_info(&cdev->dev, "device_reprobe() returned"
+ " %d\n", ret);
+ }
goto out;
}
/* make it known to the system */
@@ -948,6 +960,9 @@ io_subchannel_ioterm(struct device *dev)
cdev = dev->driver_data;
if (!cdev)
return;
+ /* Internal I/O will be retried by the interrupt handler. */
+ if (cdev->private->flags.intretry)
+ return;
cdev->private->state = DEV_STATE_CLEAR_VERIFY;
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index de3d0857db9f..09c7672eb3f3 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -59,6 +59,27 @@ device_set_disconnected(struct subchannel *sch)
cdev->private->state = DEV_STATE_DISCONNECTED;
}
+void device_set_intretry(struct subchannel *sch)
+{
+ struct ccw_device *cdev;
+
+ cdev = sch->dev.driver_data;
+ if (!cdev)
+ return;
+ cdev->private->flags.intretry = 1;
+}
+
+int device_trigger_verify(struct subchannel *sch)
+{
+ struct ccw_device *cdev;
+
+ cdev = sch->dev.driver_data;
+ if (!cdev || !cdev->online)
+ return -EINVAL;
+ dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+ return 0;
+}
+
/*
* Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
*/
@@ -893,6 +914,12 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
* had killed the original request.
*/
if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
+ /* Retry Basic Sense if requested. */
+ if (cdev->private->flags.intretry) {
+ cdev->private->flags.intretry = 0;
+ ccw_device_do_sense(cdev, irb);
+ return;
+ }
cdev->private->flags.dosense = 0;
memset(&cdev->private->irb, 0, sizeof(struct irb));
ccw_device_accumulate_irb(cdev, irb);
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index a74785b9e4eb..f17275917fe5 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -191,6 +191,8 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
if ((sch->opm & cdev->private->imask) != 0 &&
cdev->private->iretry > 0) {
cdev->private->iretry--;
+ /* Reset internal retry indication. */
+ cdev->private->flags.intretry = 0;
ret = cio_start (sch, cdev->private->iccws,
cdev->private->imask);
/* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -237,8 +239,14 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
return 0; /* Success */
}
/* Check the error cases. */
- if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+ if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+ /* Retry Sense ID if requested. */
+ if (cdev->private->flags.intretry) {
+ cdev->private->flags.intretry = 0;
+ return -EAGAIN;
+ }
return -ETIME;
+ }
if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) {
/*
* if the device doesn't support the SenseID
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 2975ce888c19..cb1879a96818 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -71,6 +71,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
if (cdev->private->iretry > 0) {
cdev->private->iretry--;
+ /* Reset internal retry indication. */
+ cdev->private->flags.intretry = 0;
ret = cio_start (sch, cdev->private->iccws,
cdev->private->imask);
/* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -122,8 +124,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent);
irb = &cdev->private->irb;
- if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+ if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+ /* Retry Sense PGID if requested. */
+ if (cdev->private->flags.intretry) {
+ cdev->private->flags.intretry = 0;
+ return -EAGAIN;
+ }
return -ETIME;
+ }
if (irb->esw.esw0.erw.cons &&
(irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
/*
@@ -253,6 +261,8 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
ret = -EACCES;
if (cdev->private->iretry > 0) {
cdev->private->iretry--;
+ /* Reset internal retry indication. */
+ cdev->private->flags.intretry = 0;
ret = cio_start (sch, cdev->private->iccws,
cdev->private->imask);
/* We expect an interrupt in case of success or busy
@@ -293,6 +303,8 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
ret = -EACCES;
if (cdev->private->iretry > 0) {
cdev->private->iretry--;
+ /* Reset internal retry indication. */
+ cdev->private->flags.intretry = 0;
ret = cio_start (sch, cdev->private->iccws,
cdev->private->imask);
/* We expect an interrupt in case of success or busy
@@ -321,8 +333,14 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent);
irb = &cdev->private->irb;
- if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+ if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+ /* Retry Set PGID if requested. */
+ if (cdev->private->flags.intretry) {
+ cdev->private->flags.intretry = 0;
+ return -EAGAIN;
+ }
return -ETIME;
+ }
if (irb->esw.esw0.erw.cons) {
if (irb->ecw[0] & SNS0_CMD_REJECT)
return -EOPNOTSUPP;
@@ -360,8 +378,14 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent);
irb = &cdev->private->irb;
- if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+ if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+ /* Retry NOP if requested. */
+ if (cdev->private->flags.intretry) {
+ cdev->private->flags.intretry = 0;
+ return -EAGAIN;
+ }
return -ETIME;
+ }
if (irb->scsw.cc == 3) {
CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
" lpm %02X, became 'not operational'\n",
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 3f7cbce4cd87..bdcf930f7beb 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -319,6 +319,9 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
sch->sense_ccw.count = SENSE_MAX_COUNT;
sch->sense_ccw.flags = CCW_FLAG_SLI;
+ /* Reset internal retry indication. */
+ cdev->private->flags.intretry = 0;
+
return cio_start (sch, &sch->sense_ccw, 0xff);
}
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 476aa1da5cbc..8d5fa1b4d11f 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -481,7 +481,7 @@ qdio_stop_polling(struct qdio_q *q)
unsigned char state = 0;
struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
- if (!atomic_swap(&q->polling,0))
+ if (!atomic_xchg(&q->polling,0))
return 1;
QDIO_DBF_TEXT4(0,trace,"stoppoll");
@@ -1964,8 +1964,8 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
QDIO_PRINT_WARN("sense data available on qdio channel.\n");
- HEXDUMP16(WARN,"irb: ",irb);
- HEXDUMP16(WARN,"sense data: ",irb->ecw);
+ QDIO_HEXDUMP16(WARN,"irb: ",irb);
+ QDIO_HEXDUMP16(WARN,"sense data: ",irb->ecw);
}
}
@@ -3425,7 +3425,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
(callflags&QDIO_FLAG_UNDER_INTERRUPT))
- atomic_swap(&q->polling,0);
+ atomic_xchg(&q->polling,0);
if (used_elements)
return;
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 49bb9e371c32..42927c1b7451 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -236,7 +236,7 @@ enum qdio_irq_states {
#define QDIO_PRINT_EMERG(x...) do { } while (0)
#endif
-#define HEXDUMP16(importance,header,ptr) \
+#define QDIO_HEXDUMP16(importance,header,ptr) \
QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \
"%02x %02x %02x %02x %02x %02x %02x %02x " \
"%02x %02x %02x %02x\n",*(((char*)ptr)), \
@@ -429,8 +429,6 @@ struct qdio_perf_stats {
};
#endif /* QDIO_PERFORMANCE_STATS */
-#define atomic_swap(a,b) xchg((int*)a.counter,b)
-
/* unlikely as the later the better */
#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)
#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 79d89c368919..e4dc947e74e9 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -37,7 +37,7 @@
#include "ap_bus.h"
/* Some prototypes. */
-static void ap_scan_bus(void *);
+static void ap_scan_bus(struct work_struct *);
static void ap_poll_all(unsigned long);
static void ap_poll_timeout(unsigned long);
static int ap_poll_thread_start(void);
@@ -71,7 +71,7 @@ static struct device *ap_root_device = NULL;
static struct workqueue_struct *ap_work_queue;
static struct timer_list ap_config_timer;
static int ap_config_time = AP_CONFIG_TIME;
-static DECLARE_WORK(ap_config_work, ap_scan_bus, NULL);
+static DECLARE_WORK(ap_config_work, ap_scan_bus);
/**
* Tasklet & timer for AP request polling.
@@ -431,7 +431,15 @@ static int ap_uevent (struct device *dev, char **envp, int num_envp,
ap_dev->device_type);
if (buffer_size - length <= 0)
return -ENOMEM;
- envp[1] = 0;
+ buffer += length;
+ buffer_size -= length;
+ /* Add MODALIAS= */
+ envp[1] = buffer;
+ length = scnprintf(buffer, buffer_size, "MODALIAS=ap:t%02X",
+ ap_dev->device_type);
+ if (buffer_size - length <= 0)
+ return -ENOMEM;
+ envp[2] = NULL;
return 0;
}
@@ -724,7 +732,7 @@ static void ap_device_release(struct device *dev)
kfree(ap_dev);
}
-static void ap_scan_bus(void *data)
+static void ap_scan_bus(struct work_struct *unused)
{
struct ap_device *ap_dev;
struct device *dev;
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 16ac68c27a27..e5665b6743a1 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -54,6 +54,8 @@
#error Cannot compile lcs.c without some net devices switched on.
#endif
+#define PRINTK_HEADER " lcs: "
+
/**
* initialization string for output
*/
@@ -65,7 +67,7 @@ static char debug_buffer[255];
* Some prototypes.
*/
static void lcs_tasklet(unsigned long);
-static void lcs_start_kernel_thread(struct lcs_card *card);
+static void lcs_start_kernel_thread(struct work_struct *);
static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
static int lcs_recovery(void *ptr);
@@ -120,7 +122,7 @@ lcs_alloc_channel(struct lcs_channel *channel)
kzalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL);
if (channel->iob[cnt].data == NULL)
break;
- channel->iob[cnt].state = BUF_STATE_EMPTY;
+ channel->iob[cnt].state = LCS_BUF_STATE_EMPTY;
}
if (cnt < LCS_NUM_BUFFS) {
/* Not all io buffers could be allocated. */
@@ -236,7 +238,7 @@ lcs_setup_read_ccws(struct lcs_card *card)
((struct lcs_header *)
card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET;
card->read.iob[cnt].callback = lcs_get_frames_cb;
- card->read.iob[cnt].state = BUF_STATE_READY;
+ card->read.iob[cnt].state = LCS_BUF_STATE_READY;
card->read.iob[cnt].count = LCS_IOBUFFERSIZE;
}
card->read.ccws[0].flags &= ~CCW_FLAG_PCI;
@@ -247,7 +249,7 @@ lcs_setup_read_ccws(struct lcs_card *card)
card->read.ccws[LCS_NUM_BUFFS].cda =
(__u32) __pa(card->read.ccws);
/* Setg initial state of the read channel. */
- card->read.state = CH_STATE_INIT;
+ card->read.state = LCS_CH_STATE_INIT;
card->read.io_idx = 0;
card->read.buf_idx = 0;
@@ -294,7 +296,7 @@ lcs_setup_write_ccws(struct lcs_card *card)
card->write.ccws[LCS_NUM_BUFFS].cda =
(__u32) __pa(card->write.ccws);
/* Set initial state of the write channel. */
- card->read.state = CH_STATE_INIT;
+ card->read.state = LCS_CH_STATE_INIT;
card->write.io_idx = 0;
card->write.buf_idx = 0;
@@ -496,7 +498,7 @@ lcs_start_channel(struct lcs_channel *channel)
channel->ccws + channel->io_idx, 0, 0,
DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND);
if (rc == 0)
- channel->state = CH_STATE_RUNNING;
+ channel->state = LCS_CH_STATE_RUNNING;
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) {
LCS_DBF_TEXT_(4,trace,"essh%s", channel->ccwdev->dev.bus_id);
@@ -520,8 +522,8 @@ lcs_clear_channel(struct lcs_channel *channel)
LCS_DBF_TEXT_(4,trace,"ecsc%s", channel->ccwdev->dev.bus_id);
return rc;
}
- wait_event(channel->wait_q, (channel->state == CH_STATE_CLEARED));
- channel->state = CH_STATE_STOPPED;
+ wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_CLEARED));
+ channel->state = LCS_CH_STATE_STOPPED;
return rc;
}
@@ -535,11 +537,11 @@ lcs_stop_channel(struct lcs_channel *channel)
unsigned long flags;
int rc;
- if (channel->state == CH_STATE_STOPPED)
+ if (channel->state == LCS_CH_STATE_STOPPED)
return 0;
LCS_DBF_TEXT(4,trace,"haltsch");
LCS_DBF_TEXT_(4,trace,"%s", channel->ccwdev->dev.bus_id);
- channel->state = CH_STATE_INIT;
+ channel->state = LCS_CH_STATE_INIT;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_halt(channel->ccwdev, (addr_t) channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
@@ -548,7 +550,7 @@ lcs_stop_channel(struct lcs_channel *channel)
return rc;
}
/* Asynchronous halt initialted. Wait for its completion. */
- wait_event(channel->wait_q, (channel->state == CH_STATE_HALTED));
+ wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_HALTED));
lcs_clear_channel(channel);
return 0;
}
@@ -596,8 +598,8 @@ __lcs_get_buffer(struct lcs_channel *channel)
LCS_DBF_TEXT(5, trace, "_getbuff");
index = channel->io_idx;
do {
- if (channel->iob[index].state == BUF_STATE_EMPTY) {
- channel->iob[index].state = BUF_STATE_LOCKED;
+ if (channel->iob[index].state == LCS_BUF_STATE_EMPTY) {
+ channel->iob[index].state = LCS_BUF_STATE_LOCKED;
return channel->iob + index;
}
index = (index + 1) & (LCS_NUM_BUFFS - 1);
@@ -626,7 +628,7 @@ __lcs_resume_channel(struct lcs_channel *channel)
{
int rc;
- if (channel->state != CH_STATE_SUSPENDED)
+ if (channel->state != LCS_CH_STATE_SUSPENDED)
return 0;
if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND)
return 0;
@@ -636,7 +638,7 @@ __lcs_resume_channel(struct lcs_channel *channel)
LCS_DBF_TEXT_(4, trace, "ersc%s", channel->ccwdev->dev.bus_id);
PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc);
} else
- channel->state = CH_STATE_RUNNING;
+ channel->state = LCS_CH_STATE_RUNNING;
return rc;
}
@@ -670,10 +672,10 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, rc;
LCS_DBF_TEXT(5, trace, "rdybuff");
- BUG_ON(buffer->state != BUF_STATE_LOCKED &&
- buffer->state != BUF_STATE_PROCESSED);
+ BUG_ON(buffer->state != LCS_BUF_STATE_LOCKED &&
+ buffer->state != LCS_BUF_STATE_PROCESSED);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
- buffer->state = BUF_STATE_READY;
+ buffer->state = LCS_BUF_STATE_READY;
index = buffer - channel->iob;
/* Set length. */
channel->ccws[index].count = buffer->count;
@@ -695,8 +697,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, prev, next;
LCS_DBF_TEXT(5, trace, "prcsbuff");
- BUG_ON(buffer->state != BUF_STATE_READY);
- buffer->state = BUF_STATE_PROCESSED;
+ BUG_ON(buffer->state != LCS_BUF_STATE_READY);
+ buffer->state = LCS_BUF_STATE_PROCESSED;
index = buffer - channel->iob;
prev = (index - 1) & (LCS_NUM_BUFFS - 1);
next = (index + 1) & (LCS_NUM_BUFFS - 1);
@@ -704,7 +706,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
channel->ccws[index].flags |= CCW_FLAG_SUSPEND;
channel->ccws[index].flags &= ~CCW_FLAG_PCI;
/* Check the suspend bit of the previous buffer. */
- if (channel->iob[prev].state == BUF_STATE_READY) {
+ if (channel->iob[prev].state == LCS_BUF_STATE_READY) {
/*
* Previous buffer is in state ready. It might have
* happened in lcs_ready_buffer that the suspend bit
@@ -727,10 +729,10 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
unsigned long flags;
LCS_DBF_TEXT(5, trace, "relbuff");
- BUG_ON(buffer->state != BUF_STATE_LOCKED &&
- buffer->state != BUF_STATE_PROCESSED);
+ BUG_ON(buffer->state != LCS_BUF_STATE_LOCKED &&
+ buffer->state != LCS_BUF_STATE_PROCESSED);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
- buffer->state = BUF_STATE_EMPTY;
+ buffer->state = LCS_BUF_STATE_EMPTY;
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
}
@@ -1147,7 +1149,7 @@ list_modified:
* get mac address for the relevant Multicast address
*/
static void
-lcs_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
+lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev)
{
LCS_DBF_TEXT(4,trace, "getmac");
if (dev->type == ARPHRD_IEEE802_TR)
@@ -1264,7 +1266,7 @@ lcs_register_mc_addresses(void *data)
netif_carrier_off(card->dev);
netif_tx_disable(card->dev);
wait_event(card->write.wait_q,
- (card->write.state != CH_STATE_RUNNING));
+ (card->write.state != LCS_CH_STATE_RUNNING));
lcs_fix_multicast_list(card);
if (card->state == DEV_STATE_UP) {
netif_carrier_on(card->dev);
@@ -1404,7 +1406,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
}
}
/* How far in the ccw chain have we processed? */
- if ((channel->state != CH_STATE_INIT) &&
+ if ((channel->state != LCS_CH_STATE_INIT) &&
(irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa)
- channel->ccws;
@@ -1424,20 +1426,20 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
(irb->scsw.dstat & DEV_STAT_CHN_END) ||
(irb->scsw.dstat & DEV_STAT_UNIT_CHECK))
/* Mark channel as stopped. */
- channel->state = CH_STATE_STOPPED;
+ channel->state = LCS_CH_STATE_STOPPED;
else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
/* CCW execution stopped on a suspend bit. */
- channel->state = CH_STATE_SUSPENDED;
+ channel->state = LCS_CH_STATE_SUSPENDED;
if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
if (irb->scsw.cc != 0) {
ccw_device_halt(channel->ccwdev, (addr_t) channel);
return;
}
/* The channel has been stopped by halt_IO. */
- channel->state = CH_STATE_HALTED;
+ channel->state = LCS_CH_STATE_HALTED;
}
if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
- channel->state = CH_STATE_CLEARED;
+ channel->state = LCS_CH_STATE_CLEARED;
}
/* Do the rest in the tasklet. */
tasklet_schedule(&channel->irq_tasklet);
@@ -1461,7 +1463,7 @@ lcs_tasklet(unsigned long data)
/* Check for processed buffers. */
iob = channel->iob;
buf_idx = channel->buf_idx;
- while (iob[buf_idx].state == BUF_STATE_PROCESSED) {
+ while (iob[buf_idx].state == LCS_BUF_STATE_PROCESSED) {
/* Do the callback thing. */
if (iob[buf_idx].callback != NULL)
iob[buf_idx].callback(channel, iob + buf_idx);
@@ -1469,12 +1471,12 @@ lcs_tasklet(unsigned long data)
}
channel->buf_idx = buf_idx;
- if (channel->state == CH_STATE_STOPPED)
+ if (channel->state == LCS_CH_STATE_STOPPED)
// FIXME: what if rc != 0 ??
rc = lcs_start_channel(channel);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
- if (channel->state == CH_STATE_SUSPENDED &&
- channel->iob[channel->io_idx].state == BUF_STATE_READY) {
+ if (channel->state == LCS_CH_STATE_SUSPENDED &&
+ channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
// FIXME: what if rc != 0 ??
rc = __lcs_resume_channel(channel);
}
@@ -1689,8 +1691,8 @@ lcs_detect(struct lcs_card *card)
card->state = DEV_STATE_UP;
} else {
card->state = DEV_STATE_DOWN;
- card->write.state = CH_STATE_INIT;
- card->read.state = CH_STATE_INIT;
+ card->write.state = LCS_CH_STATE_INIT;
+ card->read.state = LCS_CH_STATE_INIT;
}
return rc;
}
@@ -1705,8 +1707,8 @@ lcs_stopcard(struct lcs_card *card)
LCS_DBF_TEXT(3, setup, "stopcard");
- if (card->read.state != CH_STATE_STOPPED &&
- card->write.state != CH_STATE_STOPPED &&
+ if (card->read.state != LCS_CH_STATE_STOPPED &&
+ card->write.state != LCS_CH_STATE_STOPPED &&
card->state == DEV_STATE_UP) {
lcs_clear_multicast_list(card);
rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP);
@@ -1722,8 +1724,9 @@ lcs_stopcard(struct lcs_card *card)
* Kernel Thread helper functions for LGW initiated commands
*/
static void
-lcs_start_kernel_thread(struct lcs_card *card)
+lcs_start_kernel_thread(struct work_struct *work)
{
+ struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter);
LCS_DBF_TEXT(5, trace, "krnthrd");
if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
@@ -1871,7 +1874,7 @@ lcs_stop_device(struct net_device *dev)
netif_tx_disable(dev);
dev->flags &= ~IFF_UP;
wait_event(card->write.wait_q,
- (card->write.state != CH_STATE_RUNNING));
+ (card->write.state != LCS_CH_STATE_RUNNING));
rc = lcs_stopcard(card);
if (rc)
PRINT_ERR("Try it again!\n ");
@@ -2051,8 +2054,7 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
ccwgdev->cdev[0]->handler = lcs_irq;
ccwgdev->cdev[1]->handler = lcs_irq;
card->gdev = ccwgdev;
- INIT_WORK(&card->kernel_thread_starter,
- (void *) lcs_start_kernel_thread, card);
+ INIT_WORK(&card->kernel_thread_starter, lcs_start_kernel_thread);
card->thread_start_mask = 0;
card->thread_allowed_mask = 0;
card->thread_running_mask = 0;
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 93143932983b..0e1e4a0a88f0 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -23,11 +23,6 @@ do { \
} while (0)
/**
- * some more definitions for debug or output stuff
- */
-#define PRINTK_HEADER " lcs: "
-
-/**
* sysfs related stuff
*/
#define CARD_FROM_DEV(cdev) \
@@ -127,22 +122,22 @@ do { \
* LCS Buffer states
*/
enum lcs_buffer_states {
- BUF_STATE_EMPTY, /* buffer is empty */
- BUF_STATE_LOCKED, /* buffer is locked, don't touch */
- BUF_STATE_READY, /* buffer is ready for read/write */
- BUF_STATE_PROCESSED,
+ LCS_BUF_STATE_EMPTY, /* buffer is empty */
+ LCS_BUF_STATE_LOCKED, /* buffer is locked, don't touch */
+ LCS_BUF_STATE_READY, /* buffer is ready for read/write */
+ LCS_BUF_STATE_PROCESSED,
};
/**
* LCS Channel State Machine declarations
*/
enum lcs_channel_states {
- CH_STATE_INIT,
- CH_STATE_HALTED,
- CH_STATE_STOPPED,
- CH_STATE_RUNNING,
- CH_STATE_SUSPENDED,
- CH_STATE_CLEARED,
+ LCS_CH_STATE_INIT,
+ LCS_CH_STATE_HALTED,
+ LCS_CH_STATE_STOPPED,
+ LCS_CH_STATE_RUNNING,
+ LCS_CH_STATE_SUSPENDED,
+ LCS_CH_STATE_CLEARED,
};
/**
@@ -169,7 +164,7 @@ struct lcs_header {
} __attribute__ ((packed));
struct lcs_ip_mac_pair {
- __u32 ip_addr;
+ __be32 ip_addr;
__u8 mac_addr[LCS_MAC_LENGTH];
__u8 reserved[2];
} __attribute__ ((packed));
@@ -287,7 +282,7 @@ struct lcs_card {
enum lcs_dev_states state;
struct net_device *dev;
struct net_device_stats stats;
- unsigned short (*lan_type_trans)(struct sk_buff *skb,
+ __be16 (*lan_type_trans)(struct sk_buff *skb,
struct net_device *dev);
struct ccwgroup_device *gdev;
struct lcs_channel read;
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 821383d8cbe7..53c358c7d368 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -151,8 +151,6 @@ qeth_hex_dump(unsigned char *buf, size_t len)
#define SENSE_RESETTING_EVENT_BYTE 1
#define SENSE_RESETTING_EVENT_FLAG 0x80
-#define atomic_swap(a,b) xchg((int *)a.counter, b)
-
/*
* Common IO related definitions
*/
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index a363721cf28d..6bb558a9a032 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -258,7 +258,7 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
static inline void
qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
- u32 *hcsum)
+ __wsum *hcsum)
{
struct skb_frag_struct *frag;
int left_in_frag;
@@ -305,7 +305,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
static inline void
qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
struct qeth_eddp_data *eddp, int data_len,
- u32 hcsum)
+ __wsum hcsum)
{
u8 *page;
int page_remainder;
@@ -349,10 +349,10 @@ qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
}
-static inline u32
+static inline __wsum
qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
{
- u32 phcsum; /* pseudo header checksum */
+ __wsum phcsum; /* pseudo header checksum */
QETH_DBF_TEXT(trace, 5, "eddpckt4");
eddp->th.tcp.h.check = 0;
@@ -363,11 +363,11 @@ qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
}
-static inline u32
+static inline __wsum
qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
{
- u32 proto;
- u32 phcsum; /* pseudo header checksum */
+ __be32 proto;
+ __wsum phcsum; /* pseudo header checksum */
QETH_DBF_TEXT(trace, 5, "eddpckt6");
eddp->th.tcp.h.check = 0;
@@ -405,7 +405,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
{
struct tcphdr *tcph;
int data_len;
- u32 hcsum;
+ __wsum hcsum;
QETH_DBF_TEXT(trace, 5, "eddpftcp");
eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
@@ -433,22 +433,22 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
eddp->qh.hdr.l3.length = data_len + eddp->nhl +
eddp->thl;
/* prepare ip hdr */
- if (eddp->skb->protocol == ETH_P_IP){
- eddp->nh.ip4.h.tot_len = data_len + eddp->nhl +
- eddp->thl;
+ if (eddp->skb->protocol == htons(ETH_P_IP)){
+ eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
+ eddp->thl);
eddp->nh.ip4.h.check = 0;
eddp->nh.ip4.h.check =
ip_fast_csum((u8 *)&eddp->nh.ip4.h,
eddp->nh.ip4.h.ihl);
} else
- eddp->nh.ip6.h.payload_len = data_len + eddp->thl;
+ eddp->nh.ip6.h.payload_len = htons(data_len + eddp->thl);
/* prepare tcp hdr */
if (data_len == (eddp->skb->len - eddp->skb_offset)){
/* last segment -> set FIN and PSH flags */
eddp->th.tcp.h.fin = tcph->fin;
eddp->th.tcp.h.psh = tcph->psh;
}
- if (eddp->skb->protocol == ETH_P_IP)
+ if (eddp->skb->protocol == htons(ETH_P_IP))
hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
else
hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
@@ -458,9 +458,9 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
if (eddp->skb_offset >= eddp->skb->len)
break;
/* prepare headers for next round */
- if (eddp->skb->protocol == ETH_P_IP)
- eddp->nh.ip4.h.id++;
- eddp->th.tcp.h.seq += data_len;
+ if (eddp->skb->protocol == htons(ETH_P_IP))
+ eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
+ eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) + data_len);
}
}
@@ -472,7 +472,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
QETH_DBF_TEXT(trace, 5, "eddpficx");
/* create our segmentation headers and copy original headers */
- if (skb->protocol == ETH_P_IP)
+ if (skb->protocol == htons(ETH_P_IP))
eddp = qeth_eddp_create_eddp_data(qhdr, (u8 *)skb->nh.iph,
skb->nh.iph->ihl*4,
(u8 *)skb->h.th, skb->h.th->doff*4);
@@ -490,7 +490,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
#ifdef CONFIG_QETH_VLAN
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
- eddp->vlan[0] = __constant_htons(skb->protocol);
+ eddp->vlan[0] = skb->protocol;
eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
}
#endif /* CONFIG_QETH_VLAN */
@@ -588,11 +588,11 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
struct qeth_eddp_context *ctx = NULL;
QETH_DBF_TEXT(trace, 5, "creddpct");
- if (skb->protocol == ETH_P_IP)
+ if (skb->protocol == htons(ETH_P_IP))
ctx = qeth_eddp_create_context_generic(card, skb,
sizeof(struct qeth_hdr) + skb->nh.iph->ihl*4 +
skb->h.th->doff*4);
- else if (skb->protocol == ETH_P_IPV6)
+ else if (skb->protocol == htons(ETH_P_IPV6))
ctx = qeth_eddp_create_context_generic(card, skb,
sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
skb->h.th->doff*4);
diff --git a/drivers/s390/net/qeth_eddp.h b/drivers/s390/net/qeth_eddp.h
index cae9ba265056..103768d3bab2 100644
--- a/drivers/s390/net/qeth_eddp.h
+++ b/drivers/s390/net/qeth_eddp.h
@@ -54,7 +54,7 @@ qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
struct qeth_eddp_data {
struct qeth_hdr qh;
struct ethhdr mac;
- u16 vlan[2];
+ __be16 vlan[2];
union {
struct {
struct iphdr h;
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 8364d5475ac7..2bde4f1fb9c2 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1039,8 +1039,9 @@ qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
}
static void
-qeth_start_kernel_thread(struct qeth_card *card)
+qeth_start_kernel_thread(struct work_struct *work)
{
+ struct qeth_card *card = container_of(work, struct qeth_card, kernel_thread_starter);
QETH_DBF_TEXT(trace , 2, "strthrd");
if (card->read.state != CH_STATE_UP &&
@@ -1103,8 +1104,7 @@ qeth_setup_card(struct qeth_card *card)
card->thread_start_mask = 0;
card->thread_allowed_mask = 0;
card->thread_running_mask = 0;
- INIT_WORK(&card->kernel_thread_starter,
- (void *)qeth_start_kernel_thread,card);
+ INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
INIT_LIST_HEAD(&card->ip_list);
card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
if (!card->ip_tbd_list) {
@@ -2982,7 +2982,7 @@ qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
*/
if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
!atomic_read(&queue->set_pci_flags_count)){
- if (atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
+ if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
QETH_OUT_Q_UNLOCKED) {
/*
* If we get in here, there was no action in
@@ -3245,7 +3245,7 @@ qeth_free_qdio_buffers(struct qeth_card *card)
int i, j;
QETH_DBF_TEXT(trace, 2, "freeqdbf");
- if (atomic_swap(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
+ if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
QETH_QDIO_UNINITIALIZED)
return;
kfree(card->qdio.in_q);
@@ -4366,7 +4366,7 @@ out:
if (flush_count)
qeth_flush_buffers(queue, 0, start_index, flush_count);
else if (!atomic_read(&queue->set_pci_flags_count))
- atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
+ atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
/*
* queue->state will go from LOCKED -> UNLOCKED or from
* LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 562432d017b0..335a25540c08 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -622,8 +622,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
/* restore the old result if the request sense was
* successful */
- if(result == 0)
+ if (result == 0)
result = cmnd[7];
+ /* restore the original length */
+ SCp->cmd_len = cmnd[8];
} else
NCR_700_unmap(hostdata, SCp, slot);
@@ -1007,6 +1009,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
* of the command */
cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
cmnd[7] = hostdata->status[0];
+ cmnd[8] = SCp->cmd_len;
+ SCp->cmd_len = 6; /* command length for
+ * REQUEST_SENSE */
slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE);
slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index cdd033724786..3075204915c8 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2186,21 +2186,21 @@ static int __init BusLogic_init(void)
if (BusLogic_ProbeOptions.NoProbe)
return -ENODEV;
- BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *)
- kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC);
+ BusLogic_ProbeInfoList =
+ kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
if (BusLogic_ProbeInfoList == NULL) {
BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
return -ENOMEM;
}
- memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo));
- PrototypeHostAdapter = (struct BusLogic_HostAdapter *)
- kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC);
+
+ PrototypeHostAdapter =
+ kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
if (PrototypeHostAdapter == NULL) {
kfree(BusLogic_ProbeInfoList);
BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
return -ENOMEM;
}
- memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
+
#ifdef MODULE
if (BusLogic != NULL)
BusLogic_Setup(BusLogic);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 9540eb8efdcb..69569096dae5 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -29,6 +29,13 @@ config SCSI
However, do not compile this as a module if your root file system
(the one containing the directory /) is located on a SCSI device.
+config SCSI_TGT
+ tristate "SCSI target support"
+ depends on SCSI && EXPERIMENTAL
+ ---help---
+ If you want to use SCSI target mode drivers enable this option.
+ If you choose M, the module will be called scsi_tgt.
+
config SCSI_NETLINK
bool
default n
@@ -216,6 +223,23 @@ config SCSI_LOGGING
there should be no noticeable performance impact as long as you have
logging turned off.
+config SCSI_SCAN_ASYNC
+ bool "Asynchronous SCSI scanning"
+ depends on SCSI
+ help
+ The SCSI subsystem can probe for devices while the rest of the
+ system continues booting, and even probe devices on different
+ busses in parallel, leading to a significant speed-up.
+ If you have built SCSI as modules, enabling this option can
+ be a problem as the devices may not have been found by the
+ time your system expects them to have been. You can load the
+ scsi_wait_scan module to ensure that all scans have completed.
+ If you build your SCSI drivers into the kernel, then everything
+ will work fine if you say Y here.
+
+ You can override this choice by specifying scsi_mod.scan="sync"
+ or "async" on the kernel's command line.
+
menu "SCSI Transports"
depends on SCSI
@@ -797,6 +821,20 @@ config SCSI_IBMVSCSI
To compile this driver as a module, choose M here: the
module will be called ibmvscsic.
+config SCSI_IBMVSCSIS
+ tristate "IBM Virtual SCSI Server support"
+ depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP
+ help
+ This is the SRP target driver for IBM pSeries virtual environments.
+
+ The userspace component needed to initialize the driver and
+ documentation can be found:
+
+ http://stgt.berlios.de/
+
+ To compile this driver as a module, choose M here: the
+ module will be called ibmvstgt.
+
config SCSI_INITIO
tristate "Initio 9100U(W) support"
depends on PCI && SCSI
@@ -944,8 +982,13 @@ config SCSI_STEX
tristate "Promise SuperTrak EX Series support"
depends on PCI && SCSI
---help---
- This driver supports Promise SuperTrak EX8350/8300/16350/16300
- Storage controllers.
+ This driver supports Promise SuperTrak EX series storage controllers.
+
+ Promise provides Linux RAID configuration utility for these
+ controllers. Please visit <http://www.promise.com> to download.
+
+ To compile this driver as a module, choose M here: the
+ module will be called stex.
config SCSI_SYM53C8XX_2
tristate "SYM53C8XX Version 2 SCSI support"
@@ -1026,6 +1069,7 @@ config SCSI_IPR
config SCSI_IPR_TRACE
bool "enable driver internal trace"
depends on SCSI_IPR
+ default y
help
If you say Y here, the driver will trace all commands issued
to the adapter. Performance impact is minimal. Trace can be
@@ -1034,6 +1078,7 @@ config SCSI_IPR_TRACE
config SCSI_IPR_DUMP
bool "enable adapter dump support"
depends on SCSI_IPR
+ default y
help
If you say Y here, the driver will support adapter crash dump.
If you enable this support, the iprdump daemon can be used
@@ -1734,6 +1779,16 @@ config ZFCP
called zfcp. If you want to compile it as a module, say M here
and read <file:Documentation/modules.txt>.
+config SCSI_SRP
+ tristate "SCSI RDMA Protocol helper library"
+ depends on SCSI && PCI
+ select SCSI_TGT
+ help
+ If you wish to use SRP target drivers, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called libsrp.
+
endmenu
source "drivers/scsi/pcmcia/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index bcca39c3bcbf..bd7c9888f7f4 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -21,6 +21,7 @@ CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
subdir-$(CONFIG_PCMCIA) += pcmcia
obj-$(CONFIG_SCSI) += scsi_mod.o
+obj-$(CONFIG_SCSI_TGT) += scsi_tgt.o
obj-$(CONFIG_RAID_ATTRS) += raid_class.o
@@ -125,7 +126,9 @@ obj-$(CONFIG_SCSI_FCAL) += fcal.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o
+obj-$(CONFIG_SCSI_SRP) += libsrp.o
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
+obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o
@@ -141,6 +144,8 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o
# This goes last, so that "real" scsi devices probe earlier
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
+obj-$(CONFIG_SCSI) += scsi_wait_scan.o
+
scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \
scsicam.o scsi_error.o scsi_lib.o \
scsi_scan.o scsi_sysfs.o \
@@ -149,6 +154,8 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
+scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
+
sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index a6aa91072880..bb3cb3360541 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -849,7 +849,7 @@ static int __devinit NCR5380_init(struct Scsi_Host *instance, int flags)
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
- INIT_WORK(&hostdata->coroutine, NCR5380_main, hostdata);
+ INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
#ifdef NCR5380_STATS
for (i = 0; i < 8; ++i) {
@@ -1016,7 +1016,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
/* Run the coroutine if it isn't already running. */
/* Kick off command processing */
- schedule_work(&hostdata->coroutine);
+ schedule_delayed_work(&hostdata->coroutine, 0);
return 0;
}
@@ -1033,9 +1033,10 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
* host lock and called routines may take the isa dma lock.
*/
-static void NCR5380_main(void *p)
+static void NCR5380_main(struct work_struct *work)
{
- struct NCR5380_hostdata *hostdata = p;
+ struct NCR5380_hostdata *hostdata =
+ container_of(work, struct NCR5380_hostdata, coroutine.work);
struct Scsi_Host *instance = hostdata->host;
Scsi_Cmnd *tmp, *prev;
int done;
@@ -1221,7 +1222,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
} /* if BASR_IRQ */
spin_unlock_irqrestore(instance->host_lock, flags);
if(!done)
- schedule_work(&hostdata->coroutine);
+ schedule_delayed_work(&hostdata->coroutine, 0);
} while (!done);
return IRQ_HANDLED;
}
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 1bc73de496b0..713a108c02ef 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -271,7 +271,7 @@ struct NCR5380_hostdata {
unsigned long time_expires; /* in jiffies, set prior to sleeping */
int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting;
- struct work_struct coroutine; /* our co-routine */
+ struct delayed_work coroutine; /* our co-routine */
#ifdef NCR5380_STATS
unsigned timebase; /* Base for time calcs */
long time_read[8]; /* time to do reads */
@@ -298,7 +298,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
static irqreturn_t NCR5380_intr(int irq, void *dev_id);
#endif
-static void NCR5380_main(void *ptr);
+static void NCR5380_main(struct work_struct *work);
static void NCR5380_print_options(struct Scsi_Host *instance);
#ifdef NDEBUG
static void NCR5380_print_phase(struct Scsi_Host *instance);
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index d4613815f685..8578555d58fd 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -220,9 +220,11 @@ static void *addresses[] = {
static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 };
#define PORT_COUNT ARRAY_SIZE(ports)
+#ifndef MODULE
/* possible interrupt channels */
static unsigned short intrs[] = { 10, 11, 12, 15 };
#define INTR_COUNT ARRAY_SIZE(intrs)
+#endif /* !MODULE */
/* signatures for NCR 53c406a based controllers */
#if USE_BIOS
@@ -605,6 +607,7 @@ static int NCR53c406a_release(struct Scsi_Host *shost)
return 0;
}
+#ifndef MODULE
/* called from init/main.c */
static int __init NCR53c406a_setup(char *str)
{
@@ -661,6 +664,8 @@ static int __init NCR53c406a_setup(char *str)
__setup("ncr53c406a=", NCR53c406a_setup);
+#endif /* !MODULE */
+
static const char *NCR53c406a_info(struct Scsi_Host *SChost)
{
DEB(printk("NCR53c406a_info called\n"));
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index eb3ed91bac79..4f8b4c53d435 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -11,8 +11,8 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2409
-# define AAC_DRIVER_BRANCH "-mh2"
+# define AAC_DRIVER_BUILD 2423
+# define AAC_DRIVER_BRANCH "-mh3"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 19e42ac07cb2..4893a6d06a33 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -518,6 +518,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
*/
unsigned long count = 36000000L; /* 3 minutes */
while (down_trylock(&fibptr->event_wait)) {
+ int blink;
if (--count == 0) {
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
@@ -530,6 +531,14 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
return -ETIMEDOUT;
}
+ if ((blink = aac_adapter_check_health(dev)) > 0) {
+ if (wait == -1) {
+ printk(KERN_ERR "aacraid: aac_fib_send: adapter blinkLED 0x%x.\n"
+ "Usually a result of a serious unrecoverable hardware problem\n",
+ blink);
+ }
+ return -EFAULT;
+ }
udelay(5);
}
} else if (down_interruptible(&fibptr->event_wait)) {
@@ -1093,6 +1102,20 @@ static int _aac_reset_adapter(struct aac_dev *aac)
goto out;
}
+ /*
+ * Loop through the fibs, close the synchronous FIBS
+ */
+ for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
+ struct fib *fib = &aac->fibs[index];
+ if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
+ (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) {
+ unsigned long flagv;
+ spin_lock_irqsave(&fib->event_lock, flagv);
+ up(&fib->event_wait);
+ spin_unlock_irqrestore(&fib->event_lock, flagv);
+ schedule();
+ }
+ }
index = aac->cardtype;
/*
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 306f46b85a55..0cec742d12e9 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1443,7 +1443,7 @@ static struct work_struct aha152x_tq;
* Run service completions on the card with interrupts enabled.
*
*/
-static void run(void)
+static void run(struct work_struct *work)
{
struct aha152x_hostdata *hd;
@@ -1499,7 +1499,7 @@ static irqreturn_t intr(int irqno, void *dev_id)
HOSTDATA(shpnt)->service=1;
/* Poke the BH handler */
- INIT_WORK(&aha152x_tq, (void *) run, NULL);
+ INIT_WORK(&aha152x_tq, run);
schedule_work(&aha152x_tq);
}
DO_UNLOCK(flags);
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index c3c38a7e8d32..d7af9c63a04d 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -586,7 +586,7 @@ static struct scsi_host_template aha1740_template = {
static int aha1740_probe (struct device *dev)
{
- int slotbase;
+ int slotbase, rc;
unsigned int irq_level, irq_type, translation;
struct Scsi_Host *shpnt;
struct aha1740_hostdata *host;
@@ -641,10 +641,16 @@ static int aha1740_probe (struct device *dev)
}
eisa_set_drvdata (edev, shpnt);
- scsi_add_host (shpnt, dev); /* XXX handle failure */
+
+ rc = scsi_add_host (shpnt, dev);
+ if (rc)
+ goto err_irq;
+
scsi_scan_host (shpnt);
return 0;
+ err_irq:
+ free_irq(irq_level, shpnt);
err_unmap:
dma_unmap_single (&edev->dev, host->ecb_dma_addr,
sizeof (host->ecb), DMA_BIDIRECTIONAL);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 2001fe890e71..1a3ab6aa856b 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -62,6 +62,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = {
/* aic7901 based controllers */
ID(ID_AHA_29320A),
ID(ID_AHA_29320ALP),
+ ID(ID_AHA_29320LPE),
/* aic7902 based controllers */
ID(ID_AHA_29320),
ID(ID_AHA_29320B),
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index c07735819cd1..2cf7bb3123f0 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -109,7 +109,13 @@ static struct ahd_pci_identity ahd_pci_ident_table [] =
{
ID_AHA_29320ALP,
ID_ALL_MASK,
- "Adaptec 29320ALP Ultra320 SCSI adapter",
+ "Adaptec 29320ALP PCIx Ultra320 SCSI adapter",
+ ahd_aic7901_setup
+ },
+ {
+ ID_AHA_29320LPE,
+ ID_ALL_MASK,
+ "Adaptec 29320LPE PCIe Ultra320 SCSI adapter",
ahd_aic7901_setup
},
/* aic7901A based controllers */
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.h b/drivers/scsi/aic7xxx/aic79xx_pci.h
index da45153668c7..16b7c70a673c 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.h
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.h
@@ -51,6 +51,7 @@
#define ID_AIC7901 0x800F9005FFFF9005ull
#define ID_AHA_29320A 0x8000900500609005ull
#define ID_AHA_29320ALP 0x8017900500449005ull
+#define ID_AHA_29320LPE 0x8017900500459005ull
#define ID_AIC7901A 0x801E9005FFFF9005ull
#define ID_AHA_29320LP 0x8014900500449005ull
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 57c5ba4043f2..42302ef05ee5 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -724,6 +724,15 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha)
list_for_each_safe(pos, n, &pending) {
struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list);
+ /*
+ * Delete unexpired ascb timers. This may happen if we issue
+ * a CONTROL PHY scb to an adapter and rmmod before the scb
+ * times out. Apparently we don't wait for the CONTROL PHY
+ * to complete, so it doesn't matter if we kill the timer.
+ */
+ del_timer_sync(&ascb->timer);
+ WARN_ON(ascb->scb->header.opcode != CONTROL_PHY);
+
list_del_init(pos);
ASD_DPRINTK("freeing from pending\n");
asd_ascb_free(ascb);
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index b15caf1c8fa2..75ed6b0569d1 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -25,6 +25,7 @@
*/
#include <linux/pci.h>
+#include <scsi/scsi_host.h>
#include "aic94xx.h"
#include "aic94xx_reg.h"
@@ -412,6 +413,40 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
}
}
+/* hard reset a phy later */
+static void do_phy_reset_later(struct work_struct *work)
+{
+ struct sas_phy *sas_phy =
+ container_of(work, struct sas_phy, reset_work);
+ int error;
+
+ ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__,
+ sas_phy->identify.phy_identifier);
+ /* Reset device port */
+ error = sas_phy_reset(sas_phy, 1);
+ if (error)
+ ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n",
+ __FUNCTION__, sas_phy->identify.phy_identifier, error);
+}
+
+static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost)
+{
+ INIT_WORK(&sas_phy->reset_work, do_phy_reset_later);
+ queue_work(shost->work_q, &sas_phy->reset_work);
+}
+
+/* start up the ABORT TASK tmf... */
+static void task_kill_later(struct asd_ascb *ascb)
+{
+ struct asd_ha_struct *asd_ha = ascb->ha;
+ struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
+ struct Scsi_Host *shost = sas_ha->core.shost;
+ struct sas_task *task = ascb->uldd_task;
+
+ INIT_WORK(&task->abort_work, sas_task_abort);
+ queue_work(shost->work_q, &task->abort_work);
+}
+
static void escb_tasklet_complete(struct asd_ascb *ascb,
struct done_list_struct *dl)
{
@@ -439,6 +474,74 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
ascb->scb->header.opcode);
}
+ /* Catch these before we mask off the sb_opcode bits */
+ switch (sb_opcode) {
+ case REQ_TASK_ABORT: {
+ struct asd_ascb *a, *b;
+ u16 tc_abort;
+
+ tc_abort = *((u16*)(&dl->status_block[1]));
+ tc_abort = le16_to_cpu(tc_abort);
+
+ ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
+ __FUNCTION__, dl->status_block[3]);
+
+ /* Find the pending task and abort it. */
+ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list)
+ if (a->tc_index == tc_abort) {
+ task_kill_later(a);
+ break;
+ }
+ goto out;
+ }
+ case REQ_DEVICE_RESET: {
+ struct Scsi_Host *shost = sas_ha->core.shost;
+ struct sas_phy *dev_phy;
+ struct asd_ascb *a;
+ u16 conn_handle;
+
+ conn_handle = *((u16*)(&dl->status_block[1]));
+ conn_handle = le16_to_cpu(conn_handle);
+
+ ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__,
+ dl->status_block[3]);
+
+ /* Kill all pending tasks and reset the device */
+ dev_phy = NULL;
+ list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
+ struct sas_task *task;
+ struct domain_device *dev;
+ u16 x;
+
+ task = a->uldd_task;
+ if (!task)
+ continue;
+ dev = task->dev;
+
+ x = (unsigned long)dev->lldd_dev;
+ if (x == conn_handle) {
+ dev_phy = dev->port->phy;
+ task_kill_later(a);
+ }
+ }
+
+ /* Reset device port */
+ if (!dev_phy) {
+ ASD_DPRINTK("%s: No pending commands; can't reset.\n",
+ __FUNCTION__);
+ goto out;
+ }
+ phy_reset_later(dev_phy, shost);
+ goto out;
+ }
+ case SIGNAL_NCQ_ERROR:
+ ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__);
+ goto out;
+ case CLEAR_NCQ_ERROR:
+ ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__);
+ goto out;
+ }
+
sb_opcode &= ~DL_PHY_MASK;
switch (sb_opcode) {
@@ -469,22 +572,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
asd_deform_port(asd_ha, phy);
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
break;
- case REQ_TASK_ABORT:
- ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__,
- phy_id);
- break;
- case REQ_DEVICE_RESET:
- ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__,
- phy_id);
- break;
- case SIGNAL_NCQ_ERROR:
- ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__,
- phy_id);
- break;
- case CLEAR_NCQ_ERROR:
- ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__,
- phy_id);
- break;
default:
ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__,
phy_id, sb_opcode);
@@ -504,7 +591,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
break;
}
-
+out:
asd_invalidate_edb(ascb, edb);
}
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index ef8285c326e4..668569e8856b 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -294,6 +294,7 @@ static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
static int user_fifo_count = 0;
static int user_fifo_size = 0;
+#ifndef MODULE
static int __init fd_mcs_setup(char *str)
{
static int done_setup = 0;
@@ -311,6 +312,7 @@ static int __init fd_mcs_setup(char *str)
}
__setup("fd_mcs=", fd_mcs_setup);
+#endif /* !MODULE */
static void print_banner(struct Scsi_Host *shpnt)
{
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 68ef1636678d..38c3a291efac 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -263,6 +263,10 @@ static void scsi_host_dev_release(struct device *dev)
kthread_stop(shost->ehandler);
if (shost->work_q)
destroy_workqueue(shost->work_q);
+ if (shost->uspace_req_q) {
+ kfree(shost->uspace_req_q->queuedata);
+ scsi_free_queue(shost->uspace_req_q);
+ }
scsi_destroy_command_freelist(shost);
if (shost->bqt)
@@ -301,8 +305,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
if (!shost)
return NULL;
- spin_lock_init(&shost->default_lock);
- scsi_assign_lock(shost, &shost->default_lock);
+ shost->host_lock = &shost->default_lock;
+ spin_lock_init(shost->host_lock);
shost->shost_state = SHOST_CREATED;
INIT_LIST_HEAD(&shost->__devices);
INIT_LIST_HEAD(&shost->__targets);
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index 4e247b6b8700..6ac0633d5452 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -3,3 +3,5 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
ibmvscsic-y += ibmvscsi.o
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
+
+obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
new file mode 100644
index 000000000000..e28260f05d6b
--- /dev/null
+++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
@@ -0,0 +1,960 @@
+/*
+ * IBM eServer i/pSeries Virtual SCSI Target Driver
+ * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
+ * Santiago Leon (santil@us.ibm.com) IBM Corp.
+ * Linda Xie (lxie@us.ibm.com) IBM Corp.
+ *
+ * Copyright (C) 2005-2006 FUJITA Tomonori <tomof@acm.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
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tgt.h>
+#include <scsi/libsrp.h>
+#include <asm/hvcall.h>
+#include <asm/iommu.h>
+#include <asm/prom.h>
+#include <asm/vio.h>
+
+#include "ibmvscsi.h"
+
+#define INITIAL_SRP_LIMIT 16
+#define DEFAULT_MAX_SECTORS 512
+
+#define TGT_NAME "ibmvstgt"
+
+/*
+ * Hypervisor calls.
+ */
+#define h_copy_rdma(l, sa, sb, da, db) \
+ plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
+#define h_send_crq(ua, l, h) \
+ plpar_hcall_norets(H_SEND_CRQ, ua, l, h)
+#define h_reg_crq(ua, tok, sz)\
+ plpar_hcall_norets(H_REG_CRQ, ua, tok, sz);
+#define h_free_crq(ua) \
+ plpar_hcall_norets(H_FREE_CRQ, ua);
+
+/* tmp - will replace with SCSI logging stuff */
+#define eprintk(fmt, args...) \
+do { \
+ printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \
+} while (0)
+/* #define dprintk eprintk */
+#define dprintk(fmt, args...)
+
+struct vio_port {
+ struct vio_dev *dma_dev;
+
+ struct crq_queue crq_queue;
+ struct work_struct crq_work;
+
+ unsigned long liobn;
+ unsigned long riobn;
+ struct srp_target *target;
+};
+
+static struct workqueue_struct *vtgtd;
+
+/*
+ * These are fixed for the system and come from the Open Firmware device tree.
+ * We just store them here to save getting them every time.
+ */
+static char system_id[64] = "";
+static char partition_name[97] = "UNKNOWN";
+static unsigned int partition_number = -1;
+
+static struct vio_port *target_to_port(struct srp_target *target)
+{
+ return (struct vio_port *) target->ldata;
+}
+
+static inline union viosrp_iu *vio_iu(struct iu_entry *iue)
+{
+ return (union viosrp_iu *) (iue->sbuf->buf);
+}
+
+static int send_iu(struct iu_entry *iue, uint64_t length, uint8_t format)
+{
+ struct srp_target *target = iue->target;
+ struct vio_port *vport = target_to_port(target);
+ long rc, rc1;
+ union {
+ struct viosrp_crq cooked;
+ uint64_t raw[2];
+ } crq;
+
+ /* First copy the SRP */
+ rc = h_copy_rdma(length, vport->liobn, iue->sbuf->dma,
+ vport->riobn, iue->remote_token);
+
+ if (rc)
+ eprintk("Error %ld transferring data\n", rc);
+
+ crq.cooked.valid = 0x80;
+ crq.cooked.format = format;
+ crq.cooked.reserved = 0x00;
+ crq.cooked.timeout = 0x00;
+ crq.cooked.IU_length = length;
+ crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag;
+
+ if (rc == 0)
+ crq.cooked.status = 0x99; /* Just needs to be non-zero */
+ else
+ crq.cooked.status = 0x00;
+
+ rc1 = h_send_crq(vport->dma_dev->unit_address, crq.raw[0], crq.raw[1]);
+
+ if (rc1) {
+ eprintk("%ld sending response\n", rc1);
+ return rc1;
+ }
+
+ return rc;
+}
+
+#define SRP_RSP_SENSE_DATA_LEN 18
+
+static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc,
+ unsigned char status, unsigned char asc)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ uint64_t tag = iu->srp.rsp.tag;
+
+ /* If the linked bit is on and status is good */
+ if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE))
+ status = 0x10;
+
+ memset(iu, 0, sizeof(struct srp_rsp));
+ iu->srp.rsp.opcode = SRP_RSP;
+ iu->srp.rsp.req_lim_delta = 1;
+ iu->srp.rsp.tag = tag;
+
+ if (test_bit(V_DIOVER, &iue->flags))
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER;
+
+ iu->srp.rsp.data_in_res_cnt = 0;
+ iu->srp.rsp.data_out_res_cnt = 0;
+
+ iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID;
+
+ iu->srp.rsp.resp_data_len = 0;
+ iu->srp.rsp.status = status;
+ if (status) {
+ uint8_t *sense = iu->srp.rsp.data;
+
+ if (sc) {
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+ iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE;
+ memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE);
+ } else {
+ iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION;
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+ iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN;
+
+ /* Valid bit and 'current errors' */
+ sense[0] = (0x1 << 7 | 0x70);
+ /* Sense key */
+ sense[2] = status;
+ /* Additional sense length */
+ sense[7] = 0xa; /* 10 bytes */
+ /* Additional sense code */
+ sense[12] = asc;
+ }
+ }
+
+ send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN,
+ VIOSRP_SRP_FORMAT);
+
+ return 0;
+}
+
+static void handle_cmd_queue(struct srp_target *target)
+{
+ struct Scsi_Host *shost = target->shost;
+ struct iu_entry *iue;
+ struct srp_cmd *cmd;
+ unsigned long flags;
+ int err;
+
+retry:
+ spin_lock_irqsave(&target->lock, flags);
+
+ list_for_each_entry(iue, &target->cmd_queue, ilist) {
+ if (!test_and_set_bit(V_FLYING, &iue->flags)) {
+ spin_unlock_irqrestore(&target->lock, flags);
+ cmd = iue->sbuf->buf;
+ err = srp_cmd_queue(shost, cmd, iue, 0);
+ if (err) {
+ eprintk("cannot queue cmd %p %d\n", cmd, err);
+ srp_iu_put(iue);
+ }
+ goto retry;
+ }
+ }
+
+ spin_unlock_irqrestore(&target->lock, flags);
+}
+
+static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg,
+ struct srp_direct_buf *md, int nmd,
+ enum dma_data_direction dir, unsigned int rest)
+{
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ struct srp_target *target = iue->target;
+ struct vio_port *vport = target_to_port(target);
+ dma_addr_t token;
+ long err;
+ unsigned int done = 0;
+ int i, sidx, soff;
+
+ sidx = soff = 0;
+ token = sg_dma_address(sg + sidx);
+
+ for (i = 0; i < nmd && rest; i++) {
+ unsigned int mdone, mlen;
+
+ mlen = min(rest, md[i].len);
+ for (mdone = 0; mlen;) {
+ int slen = min(sg_dma_len(sg + sidx) - soff, mlen);
+
+ if (dir == DMA_TO_DEVICE)
+ err = h_copy_rdma(slen,
+ vport->riobn,
+ md[i].va + mdone,
+ vport->liobn,
+ token + soff);
+ else
+ err = h_copy_rdma(slen,
+ vport->liobn,
+ token + soff,
+ vport->riobn,
+ md[i].va + mdone);
+
+ if (err != H_SUCCESS) {
+ eprintk("rdma error %d %d\n", dir, slen);
+ goto out;
+ }
+
+ mlen -= slen;
+ mdone += slen;
+ soff += slen;
+ done += slen;
+
+ if (soff == sg_dma_len(sg + sidx)) {
+ sidx++;
+ soff = 0;
+ token = sg_dma_address(sg + sidx);
+
+ if (sidx > nsg) {
+ eprintk("out of sg %p %d %d\n",
+ iue, sidx, nsg);
+ goto out;
+ }
+ }
+ };
+
+ rest -= mlen;
+ }
+out:
+
+ return 0;
+}
+
+static int ibmvstgt_transfer_data(struct scsi_cmnd *sc,
+ void (*done)(struct scsi_cmnd *))
+{
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ int err;
+
+ err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1);
+
+ done(sc);
+
+ return err;
+}
+
+static int ibmvstgt_cmd_done(struct scsi_cmnd *sc,
+ void (*done)(struct scsi_cmnd *))
+{
+ unsigned long flags;
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ struct srp_target *target = iue->target;
+
+ dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]);
+
+ spin_lock_irqsave(&target->lock, flags);
+ list_del(&iue->ilist);
+ spin_unlock_irqrestore(&target->lock, flags);
+
+ if (sc->result != SAM_STAT_GOOD) {
+ eprintk("operation failed %p %d %x\n",
+ iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]);
+ send_rsp(iue, sc, HARDWARE_ERROR, 0x00);
+ } else
+ send_rsp(iue, sc, NO_SENSE, 0x00);
+
+ done(sc);
+ srp_iu_put(iue);
+ return 0;
+}
+
+int send_adapter_info(struct iu_entry *iue,
+ dma_addr_t remote_buffer, uint16_t length)
+{
+ struct srp_target *target = iue->target;
+ struct vio_port *vport = target_to_port(target);
+ struct Scsi_Host *shost = target->shost;
+ dma_addr_t data_token;
+ struct mad_adapter_info_data *info;
+ int err;
+
+ info = dma_alloc_coherent(target->dev, sizeof(*info), &data_token,
+ GFP_KERNEL);
+ if (!info) {
+ eprintk("bad dma_alloc_coherent %p\n", target);
+ return 1;
+ }
+
+ /* Get remote info */
+ err = h_copy_rdma(sizeof(*info), vport->riobn, remote_buffer,
+ vport->liobn, data_token);
+ if (err == H_SUCCESS) {
+ dprintk("Client connect: %s (%d)\n",
+ info->partition_name, info->partition_number);
+ }
+
+ memset(info, 0, sizeof(*info));
+
+ strcpy(info->srp_version, "16.a");
+ strncpy(info->partition_name, partition_name,
+ sizeof(info->partition_name));
+ info->partition_number = partition_number;
+ info->mad_version = 1;
+ info->os_type = 2;
+ info->port_max_txu[0] = shost->hostt->max_sectors << 9;
+
+ /* Send our info to remote */
+ err = h_copy_rdma(sizeof(*info), vport->liobn, data_token,
+ vport->riobn, remote_buffer);
+
+ dma_free_coherent(target->dev, sizeof(*info), info, data_token);
+
+ if (err != H_SUCCESS) {
+ eprintk("Error sending adapter info %d\n", err);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void process_login(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ struct srp_login_rsp *rsp = &iu->srp.login_rsp;
+ uint64_t tag = iu->srp.rsp.tag;
+
+ /* TODO handle case that requested size is wrong and
+ * buffer format is wrong
+ */
+ memset(iu, 0, sizeof(struct srp_login_rsp));
+ rsp->opcode = SRP_LOGIN_RSP;
+ rsp->req_lim_delta = INITIAL_SRP_LIMIT;
+ rsp->tag = tag;
+ rsp->max_it_iu_len = sizeof(union srp_iu);
+ rsp->max_ti_iu_len = sizeof(union srp_iu);
+ /* direct and indirect */
+ rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
+
+ send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT);
+}
+
+static inline void queue_cmd(struct iu_entry *iue)
+{
+ struct srp_target *target = iue->target;
+ unsigned long flags;
+
+ spin_lock_irqsave(&target->lock, flags);
+ list_add_tail(&iue->ilist, &target->cmd_queue);
+ spin_unlock_irqrestore(&target->lock, flags);
+}
+
+static int process_tsk_mgmt(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ int fn;
+
+ dprintk("%p %u\n", iue, iu->srp.tsk_mgmt.tsk_mgmt_func);
+
+ switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
+ case SRP_TSK_ABORT_TASK:
+ fn = ABORT_TASK;
+ break;
+ case SRP_TSK_ABORT_TASK_SET:
+ fn = ABORT_TASK_SET;
+ break;
+ case SRP_TSK_CLEAR_TASK_SET:
+ fn = CLEAR_TASK_SET;
+ break;
+ case SRP_TSK_LUN_RESET:
+ fn = LOGICAL_UNIT_RESET;
+ break;
+ case SRP_TSK_CLEAR_ACA:
+ fn = CLEAR_ACA;
+ break;
+ default:
+ fn = 0;
+ }
+ if (fn)
+ scsi_tgt_tsk_mgmt_request(iue->target->shost, fn,
+ iu->srp.tsk_mgmt.task_tag,
+ (struct scsi_lun *) &iu->srp.tsk_mgmt.lun,
+ iue);
+ else
+ send_rsp(iue, NULL, ILLEGAL_REQUEST, 0x20);
+
+ return !fn;
+}
+
+static int process_mad_iu(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ struct viosrp_adapter_info *info;
+ struct viosrp_host_config *conf;
+
+ switch (iu->mad.empty_iu.common.type) {
+ case VIOSRP_EMPTY_IU_TYPE:
+ eprintk("%s\n", "Unsupported EMPTY MAD IU");
+ break;
+ case VIOSRP_ERROR_LOG_TYPE:
+ eprintk("%s\n", "Unsupported ERROR LOG MAD IU");
+ iu->mad.error_log.common.status = 1;
+ send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT);
+ break;
+ case VIOSRP_ADAPTER_INFO_TYPE:
+ info = &iu->mad.adapter_info;
+ info->common.status = send_adapter_info(iue, info->buffer,
+ info->common.length);
+ send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT);
+ break;
+ case VIOSRP_HOST_CONFIG_TYPE:
+ conf = &iu->mad.host_config;
+ conf->common.status = 1;
+ send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT);
+ break;
+ default:
+ eprintk("Unknown type %u\n", iu->srp.rsp.opcode);
+ }
+
+ return 1;
+}
+
+static int process_srp_iu(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ int done = 1;
+ u8 opcode = iu->srp.rsp.opcode;
+
+ switch (opcode) {
+ case SRP_LOGIN_REQ:
+ process_login(iue);
+ break;
+ case SRP_TSK_MGMT:
+ done = process_tsk_mgmt(iue);
+ break;
+ case SRP_CMD:
+ queue_cmd(iue);
+ done = 0;
+ break;
+ case SRP_LOGIN_RSP:
+ case SRP_I_LOGOUT:
+ case SRP_T_LOGOUT:
+ case SRP_RSP:
+ case SRP_CRED_REQ:
+ case SRP_CRED_RSP:
+ case SRP_AER_REQ:
+ case SRP_AER_RSP:
+ eprintk("Unsupported type %u\n", opcode);
+ break;
+ default:
+ eprintk("Unknown type %u\n", opcode);
+ }
+
+ return done;
+}
+
+static void process_iu(struct viosrp_crq *crq, struct srp_target *target)
+{
+ struct vio_port *vport = target_to_port(target);
+ struct iu_entry *iue;
+ long err, done;
+
+ iue = srp_iu_get(target);
+ if (!iue) {
+ eprintk("Error getting IU from pool, %p\n", target);
+ return;
+ }
+
+ iue->remote_token = crq->IU_data_ptr;
+
+ err = h_copy_rdma(crq->IU_length, vport->riobn,
+ iue->remote_token, vport->liobn, iue->sbuf->dma);
+
+ if (err != H_SUCCESS) {
+ eprintk("%ld transferring data error %p\n", err, iue);
+ done = 1;
+ goto out;
+ }
+
+ if (crq->format == VIOSRP_MAD_FORMAT)
+ done = process_mad_iu(iue);
+ else
+ done = process_srp_iu(iue);
+out:
+ if (done)
+ srp_iu_put(iue);
+}
+
+static irqreturn_t ibmvstgt_interrupt(int irq, void *data)
+{
+ struct srp_target *target = (struct srp_target *) data;
+ struct vio_port *vport = target_to_port(target);
+
+ vio_disable_interrupts(vport->dma_dev);
+ queue_work(vtgtd, &vport->crq_work);
+
+ return IRQ_HANDLED;
+}
+
+static int crq_queue_create(struct crq_queue *queue, struct srp_target *target)
+{
+ int err;
+ struct vio_port *vport = target_to_port(target);
+
+ queue->msgs = (struct viosrp_crq *) get_zeroed_page(GFP_KERNEL);
+ if (!queue->msgs)
+ goto malloc_failed;
+ queue->size = PAGE_SIZE / sizeof(*queue->msgs);
+
+ queue->msg_token = dma_map_single(target->dev, queue->msgs,
+ queue->size * sizeof(*queue->msgs),
+ DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(queue->msg_token))
+ goto map_failed;
+
+ err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token,
+ PAGE_SIZE);
+
+ /* If the adapter was left active for some reason (like kexec)
+ * try freeing and re-registering
+ */
+ if (err == H_RESOURCE) {
+ do {
+ err = h_free_crq(vport->dma_dev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+ err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token,
+ PAGE_SIZE);
+ }
+
+ if (err != H_SUCCESS && err != 2) {
+ eprintk("Error 0x%x opening virtual adapter\n", err);
+ goto reg_crq_failed;
+ }
+
+ err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt,
+ SA_INTERRUPT, "ibmvstgt", target);
+ if (err)
+ goto req_irq_failed;
+
+ vio_enable_interrupts(vport->dma_dev);
+
+ h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0);
+
+ queue->cur = 0;
+ spin_lock_init(&queue->lock);
+
+ return 0;
+
+req_irq_failed:
+ do {
+ err = h_free_crq(vport->dma_dev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+reg_crq_failed:
+ dma_unmap_single(target->dev, queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+map_failed:
+ free_page((unsigned long) queue->msgs);
+
+malloc_failed:
+ return -ENOMEM;
+}
+
+static void crq_queue_destroy(struct srp_target *target)
+{
+ struct vio_port *vport = target_to_port(target);
+ struct crq_queue *queue = &vport->crq_queue;
+ int err;
+
+ free_irq(vport->dma_dev->irq, target);
+ do {
+ err = h_free_crq(vport->dma_dev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+ dma_unmap_single(target->dev, queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+
+ free_page((unsigned long) queue->msgs);
+}
+
+static void process_crq(struct viosrp_crq *crq, struct srp_target *target)
+{
+ struct vio_port *vport = target_to_port(target);
+ dprintk("%x %x\n", crq->valid, crq->format);
+
+ switch (crq->valid) {
+ case 0xC0:
+ /* initialization */
+ switch (crq->format) {
+ case 0x01:
+ h_send_crq(vport->dma_dev->unit_address,
+ 0xC002000000000000, 0);
+ break;
+ case 0x02:
+ break;
+ default:
+ eprintk("Unknown format %u\n", crq->format);
+ }
+ break;
+ case 0xFF:
+ /* transport event */
+ break;
+ case 0x80:
+ /* real payload */
+ switch (crq->format) {
+ case VIOSRP_SRP_FORMAT:
+ case VIOSRP_MAD_FORMAT:
+ process_iu(crq, target);
+ break;
+ case VIOSRP_OS400_FORMAT:
+ case VIOSRP_AIX_FORMAT:
+ case VIOSRP_LINUX_FORMAT:
+ case VIOSRP_INLINE_FORMAT:
+ eprintk("Unsupported format %u\n", crq->format);
+ break;
+ default:
+ eprintk("Unknown format %u\n", crq->format);
+ }
+ break;
+ default:
+ eprintk("unknown message type 0x%02x!?\n", crq->valid);
+ }
+}
+
+static inline struct viosrp_crq *next_crq(struct crq_queue *queue)
+{
+ struct viosrp_crq *crq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+ crq = &queue->msgs[queue->cur];
+ if (crq->valid & 0x80) {
+ if (++queue->cur == queue->size)
+ queue->cur = 0;
+ } else
+ crq = NULL;
+ spin_unlock_irqrestore(&queue->lock, flags);
+
+ return crq;
+}
+
+static void handle_crq(struct work_struct *work)
+{
+ struct vio_port *vport = container_of(work, struct vio_port, crq_work);
+ struct srp_target *target = vport->target;
+ struct viosrp_crq *crq;
+ int done = 0;
+
+ while (!done) {
+ while ((crq = next_crq(&vport->crq_queue)) != NULL) {
+ process_crq(crq, target);
+ crq->valid = 0x00;
+ }
+
+ vio_enable_interrupts(vport->dma_dev);
+
+ crq = next_crq(&vport->crq_queue);
+ if (crq) {
+ vio_disable_interrupts(vport->dma_dev);
+ process_crq(crq, target);
+ crq->valid = 0x00;
+ } else
+ done = 1;
+ }
+
+ handle_cmd_queue(target);
+}
+
+
+static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc)
+{
+ unsigned long flags;
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ struct srp_target *target = iue->target;
+
+ dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]);
+
+ spin_lock_irqsave(&target->lock, flags);
+ list_del(&iue->ilist);
+ spin_unlock_irqrestore(&target->lock, flags);
+
+ srp_iu_put(iue);
+
+ return 0;
+}
+
+static int ibmvstgt_tsk_mgmt_response(u64 mid, int result)
+{
+ struct iu_entry *iue = (struct iu_entry *) ((void *) mid);
+ union viosrp_iu *iu = vio_iu(iue);
+ unsigned char status, asc;
+
+ eprintk("%p %d\n", iue, result);
+ status = NO_SENSE;
+ asc = 0;
+
+ switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
+ case SRP_TSK_ABORT_TASK:
+ asc = 0x14;
+ if (result)
+ status = ABORTED_COMMAND;
+ break;
+ default:
+ break;
+ }
+
+ send_rsp(iue, NULL, status, asc);
+ srp_iu_put(iue);
+
+ return 0;
+}
+
+static ssize_t system_id_show(struct class_device *cdev, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", system_id);
+}
+
+static ssize_t partition_number_show(struct class_device *cdev, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%x\n", partition_number);
+}
+
+static ssize_t unit_address_show(struct class_device *cdev, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct srp_target *target = host_to_srp_target(shost);
+ struct vio_port *vport = target_to_port(target);
+ return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address);
+}
+
+static CLASS_DEVICE_ATTR(system_id, S_IRUGO, system_id_show, NULL);
+static CLASS_DEVICE_ATTR(partition_number, S_IRUGO, partition_number_show, NULL);
+static CLASS_DEVICE_ATTR(unit_address, S_IRUGO, unit_address_show, NULL);
+
+static struct class_device_attribute *ibmvstgt_attrs[] = {
+ &class_device_attr_system_id,
+ &class_device_attr_partition_number,
+ &class_device_attr_unit_address,
+ NULL,
+};
+
+static struct scsi_host_template ibmvstgt_sht = {
+ .name = TGT_NAME,
+ .module = THIS_MODULE,
+ .can_queue = INITIAL_SRP_LIMIT,
+ .sg_tablesize = SG_ALL,
+ .use_clustering = DISABLE_CLUSTERING,
+ .max_sectors = DEFAULT_MAX_SECTORS,
+ .transfer_response = ibmvstgt_cmd_done,
+ .transfer_data = ibmvstgt_transfer_data,
+ .eh_abort_handler = ibmvstgt_eh_abort_handler,
+ .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response,
+ .shost_attrs = ibmvstgt_attrs,
+ .proc_name = TGT_NAME,
+};
+
+static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
+{
+ struct Scsi_Host *shost;
+ struct srp_target *target;
+ struct vio_port *vport;
+ unsigned int *dma, dma_size;
+ int err = -ENOMEM;
+
+ vport = kzalloc(sizeof(struct vio_port), GFP_KERNEL);
+ if (!vport)
+ return err;
+ shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target));
+ if (!shost)
+ goto free_vport;
+ err = scsi_tgt_alloc_queue(shost);
+ if (err)
+ goto put_host;
+
+ target = host_to_srp_target(shost);
+ target->shost = shost;
+ vport->dma_dev = dev;
+ target->ldata = vport;
+ vport->target = target;
+ err = srp_target_alloc(target, &dev->dev, INITIAL_SRP_LIMIT,
+ SRP_MAX_IU_LEN);
+ if (err)
+ goto put_host;
+
+ dma = (unsigned int *) vio_get_attribute(dev, "ibm,my-dma-window",
+ &dma_size);
+ if (!dma || dma_size != 40) {
+ eprintk("Couldn't get window property %d\n", dma_size);
+ err = -EIO;
+ goto free_srp_target;
+ }
+ vport->liobn = dma[0];
+ vport->riobn = dma[5];
+
+ INIT_WORK(&vport->crq_work, handle_crq);
+
+ err = crq_queue_create(&vport->crq_queue, target);
+ if (err)
+ goto free_srp_target;
+
+ err = scsi_add_host(shost, target->dev);
+ if (err)
+ goto destroy_queue;
+ return 0;
+
+destroy_queue:
+ crq_queue_destroy(target);
+free_srp_target:
+ srp_target_free(target);
+put_host:
+ scsi_host_put(shost);
+free_vport:
+ kfree(vport);
+ return err;
+}
+
+static int ibmvstgt_remove(struct vio_dev *dev)
+{
+ struct srp_target *target = (struct srp_target *) dev->dev.driver_data;
+ struct Scsi_Host *shost = target->shost;
+ struct vio_port *vport = target->ldata;
+
+ crq_queue_destroy(target);
+ scsi_remove_host(shost);
+ scsi_tgt_free_queue(shost);
+ srp_target_free(target);
+ kfree(vport);
+ scsi_host_put(shost);
+ return 0;
+}
+
+static struct vio_device_id ibmvstgt_device_table[] __devinitdata = {
+ {"v-scsi-host", "IBM,v-scsi-host"},
+ {"",""}
+};
+
+MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table);
+
+static struct vio_driver ibmvstgt_driver = {
+ .id_table = ibmvstgt_device_table,
+ .probe = ibmvstgt_probe,
+ .remove = ibmvstgt_remove,
+ .driver = {
+ .name = "ibmvscsis",
+ .owner = THIS_MODULE,
+ }
+};
+
+static int get_system_info(void)
+{
+ struct device_node *rootdn;
+ const char *id, *model, *name;
+ unsigned int *num;
+
+ rootdn = find_path_device("/");
+ if (!rootdn)
+ return -ENOENT;
+
+ model = get_property(rootdn, "model", NULL);
+ id = get_property(rootdn, "system-id", NULL);
+ if (model && id)
+ snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
+
+ name = get_property(rootdn, "ibm,partition-name", NULL);
+ if (name)
+ strncpy(partition_name, name, sizeof(partition_name));
+
+ num = (unsigned int *) get_property(rootdn, "ibm,partition-no", NULL);
+ if (num)
+ partition_number = *num;
+
+ return 0;
+}
+
+static int ibmvstgt_init(void)
+{
+ int err = -ENOMEM;
+
+ printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n");
+
+ vtgtd = create_workqueue("ibmvtgtd");
+ if (!vtgtd)
+ return err;
+
+ err = get_system_info();
+ if (err)
+ goto destroy_wq;
+
+ err = vio_register_driver(&ibmvstgt_driver);
+ if (err)
+ goto destroy_wq;
+
+ return 0;
+
+destroy_wq:
+ destroy_workqueue(vtgtd);
+ return err;
+}
+
+static void ibmvstgt_exit(void)
+{
+ printk("Unregister IBM virtual SCSI driver\n");
+
+ destroy_workqueue(vtgtd);
+ vio_unregister_driver(&ibmvstgt_driver);
+}
+
+MODULE_DESCRIPTION("IBM Virtual SCSI Target");
+MODULE_AUTHOR("Santiago Leon");
+MODULE_LICENSE("GPL");
+
+module_init(ibmvstgt_init);
+module_exit(ibmvstgt_exit);
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index e31f6122106f..0464c182c577 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -36,7 +36,7 @@ typedef struct {
int base_hi; /* Hi Base address for ECP-ISA chipset */
int mode; /* Transfer mode */
struct scsi_cmnd *cur_cmd; /* Current queued command */
- struct work_struct imm_tq; /* Polling interrupt stuff */
+ struct delayed_work imm_tq; /* Polling interrupt stuff */
unsigned long jstart; /* Jiffies at start */
unsigned failed:1; /* Failure flag */
unsigned dp:1; /* Data phase present */
@@ -733,9 +733,9 @@ static int imm_completion(struct scsi_cmnd *cmd)
* the scheduler's task queue to generate a stream of call-backs and
* complete the request when the drive is ready.
*/
-static void imm_interrupt(void *data)
+static void imm_interrupt(struct work_struct *work)
{
- imm_struct *dev = (imm_struct *) data;
+ imm_struct *dev = container_of(work, imm_struct, imm_tq.work);
struct scsi_cmnd *cmd = dev->cur_cmd;
struct Scsi_Host *host = cmd->device->host;
unsigned long flags;
@@ -745,7 +745,6 @@ static void imm_interrupt(void *data)
return;
}
if (imm_engine(dev, cmd)) {
- INIT_WORK(&dev->imm_tq, imm_interrupt, (void *) dev);
schedule_delayed_work(&dev->imm_tq, 1);
return;
}
@@ -953,8 +952,7 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
cmd->result = DID_ERROR << 16; /* default return code */
cmd->SCp.phase = 0; /* bus free */
- INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
- schedule_work(&dev->imm_tq);
+ schedule_delayed_work(&dev->imm_tq, 0);
imm_pb_claim(dev);
@@ -1225,7 +1223,7 @@ static int __imm_attach(struct parport *pb)
else
ports = 8;
- INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
+ INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt);
err = -ENOMEM;
host = scsi_host_alloc(&imm_template, sizeof(imm_struct *));
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index afed293dd7b9..f160357e37a6 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -170,7 +170,7 @@ static int setup_debug = 0;
static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
/* PCI Devices supported by this driver */
-static struct pci_device_id i91u_pci_devices[] __devinitdata = {
+static struct pci_device_id i91u_pci_devices[] = {
{ PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 2dde821025f3..ccd4dafce8e2 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -79,7 +79,6 @@
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_transport.h>
#include "ipr.h"
/*
@@ -98,7 +97,7 @@ static DEFINE_SPINLOCK(ipr_driver_lock);
/* This table describes the differences between DMA controller chips */
static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
- { /* Gemstone, Citrine, and Obsidian */
+ { /* Gemstone, Citrine, Obsidian, and Obsidian-E */
.mailbox = 0x0042C,
.cache_line_size = 0x20,
{
@@ -135,6 +134,7 @@ static const struct ipr_chip_t ipr_chip[] = {
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] }
};
@@ -1249,19 +1249,23 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
/**
* ipr_log_hex_data - Log additional hex IOA error data.
+ * @ioa_cfg: ioa config struct
* @data: IOA error data
* @len: data length
*
* Return value:
* none
**/
-static void ipr_log_hex_data(u32 *data, int len)
+static void ipr_log_hex_data(struct ipr_ioa_cfg *ioa_cfg, u32 *data, int len)
{
int i;
if (len == 0)
return;
+ if (ioa_cfg->log_level <= IPR_DEFAULT_LOG_LEVEL)
+ len = min_t(int, len, IPR_DEFAULT_MAX_ERROR_DUMP);
+
for (i = 0; i < len / 4; i += 4) {
ipr_err("%08X: %08X %08X %08X %08X\n", i*4,
be32_to_cpu(data[i]),
@@ -1290,7 +1294,7 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
ipr_err("%s\n", error->failure_reason);
ipr_err("Remote Adapter VPD:\n");
ipr_log_ext_vpd(&error->vpd);
- ipr_log_hex_data(error->data,
+ ipr_log_hex_data(ioa_cfg, error->data,
be32_to_cpu(hostrcb->hcam.length) -
(offsetof(struct ipr_hostrcb_error, u) +
offsetof(struct ipr_hostrcb_type_17_error, data)));
@@ -1315,12 +1319,225 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
ipr_err("%s\n", error->failure_reason);
ipr_err("Remote Adapter VPD:\n");
ipr_log_vpd(&error->vpd);
- ipr_log_hex_data(error->data,
+ ipr_log_hex_data(ioa_cfg, error->data,
be32_to_cpu(hostrcb->hcam.length) -
(offsetof(struct ipr_hostrcb_error, u) +
offsetof(struct ipr_hostrcb_type_07_error, data)));
}
+static const struct {
+ u8 active;
+ char *desc;
+} path_active_desc[] = {
+ { IPR_PATH_NO_INFO, "Path" },
+ { IPR_PATH_ACTIVE, "Active path" },
+ { IPR_PATH_NOT_ACTIVE, "Inactive path" }
+};
+
+static const struct {
+ u8 state;
+ char *desc;
+} path_state_desc[] = {
+ { IPR_PATH_STATE_NO_INFO, "has no path state information available" },
+ { IPR_PATH_HEALTHY, "is healthy" },
+ { IPR_PATH_DEGRADED, "is degraded" },
+ { IPR_PATH_FAILED, "is failed" }
+};
+
+/**
+ * ipr_log_fabric_path - Log a fabric path error
+ * @hostrcb: hostrcb struct
+ * @fabric: fabric descriptor
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
+ struct ipr_hostrcb_fabric_desc *fabric)
+{
+ int i, j;
+ u8 path_state = fabric->path_state;
+ u8 active = path_state & IPR_PATH_ACTIVE_MASK;
+ u8 state = path_state & IPR_PATH_STATE_MASK;
+
+ for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
+ if (path_active_desc[i].active != active)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
+ if (path_state_desc[j].state != state)
+ continue;
+
+ if (fabric->cascaded_expander == 0xff && fabric->phy == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d\n",
+ path_active_desc[i].desc, path_state_desc[j].desc,
+ fabric->ioa_port);
+ } else if (fabric->cascaded_expander == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Phy=%d\n",
+ path_active_desc[i].desc, path_state_desc[j].desc,
+ fabric->ioa_port, fabric->phy);
+ } else if (fabric->phy == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d\n",
+ path_active_desc[i].desc, path_state_desc[j].desc,
+ fabric->ioa_port, fabric->cascaded_expander);
+ } else {
+ ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d, Phy=%d\n",
+ path_active_desc[i].desc, path_state_desc[j].desc,
+ fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
+ }
+ return;
+ }
+ }
+
+ ipr_err("Path state=%02X IOA Port=%d Cascade=%d Phy=%d\n", path_state,
+ fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
+}
+
+static const struct {
+ u8 type;
+ char *desc;
+} path_type_desc[] = {
+ { IPR_PATH_CFG_IOA_PORT, "IOA port" },
+ { IPR_PATH_CFG_EXP_PORT, "Expander port" },
+ { IPR_PATH_CFG_DEVICE_PORT, "Device port" },
+ { IPR_PATH_CFG_DEVICE_LUN, "Device LUN" }
+};
+
+static const struct {
+ u8 status;
+ char *desc;
+} path_status_desc[] = {
+ { IPR_PATH_CFG_NO_PROB, "Functional" },
+ { IPR_PATH_CFG_DEGRADED, "Degraded" },
+ { IPR_PATH_CFG_FAILED, "Failed" },
+ { IPR_PATH_CFG_SUSPECT, "Suspect" },
+ { IPR_PATH_NOT_DETECTED, "Missing" },
+ { IPR_PATH_INCORRECT_CONN, "Incorrectly connected" }
+};
+
+static const char *link_rate[] = {
+ "unknown",
+ "disabled",
+ "phy reset problem",
+ "spinup hold",
+ "port selector",
+ "unknown",
+ "unknown",
+ "unknown",
+ "1.5Gbps",
+ "3.0Gbps",
+ "unknown",
+ "unknown",
+ "unknown",
+ "unknown",
+ "unknown",
+ "unknown"
+};
+
+/**
+ * ipr_log_path_elem - Log a fabric path element.
+ * @hostrcb: hostrcb struct
+ * @cfg: fabric path element struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
+ struct ipr_hostrcb_config_element *cfg)
+{
+ int i, j;
+ u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
+ u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
+
+ if (type == IPR_PATH_CFG_NOT_EXIST)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
+ if (path_type_desc[i].type != type)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
+ if (path_status_desc[j].status != status)
+ continue;
+
+ if (type == IPR_PATH_CFG_IOA_PORT) {
+ ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, WWN=%08X%08X\n",
+ path_status_desc[j].desc, path_type_desc[i].desc,
+ cfg->phy, link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ } else {
+ if (cfg->cascaded_expander == 0xff && cfg->phy == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: Link rate=%s, WWN=%08X%08X\n",
+ path_status_desc[j].desc, path_type_desc[i].desc,
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ } else if (cfg->cascaded_expander == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, "
+ "WWN=%08X%08X\n", path_status_desc[j].desc,
+ path_type_desc[i].desc, cfg->phy,
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ } else if (cfg->phy == 0xff) {
+ ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Link rate=%s, "
+ "WWN=%08X%08X\n", path_status_desc[j].desc,
+ path_type_desc[i].desc, cfg->cascaded_expander,
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ } else {
+ ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Phy=%d, Link rate=%s "
+ "WWN=%08X%08X\n", path_status_desc[j].desc,
+ path_type_desc[i].desc, cfg->cascaded_expander, cfg->phy,
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ }
+ }
+ return;
+ }
+ }
+
+ ipr_hcam_err(hostrcb, "Path element=%02X: Cascade=%d Phy=%d Link rate=%s "
+ "WWN=%08X%08X\n", cfg->type_status, cfg->cascaded_expander, cfg->phy,
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+}
+
+/**
+ * ipr_log_fabric_error - Log a fabric error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ struct ipr_hostrcb_type_20_error *error;
+ struct ipr_hostrcb_fabric_desc *fabric;
+ struct ipr_hostrcb_config_element *cfg;
+ int i, add_len;
+
+ error = &hostrcb->hcam.u.error.u.type_20_error;
+ error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+ ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
+
+ add_len = be32_to_cpu(hostrcb->hcam.length) -
+ (offsetof(struct ipr_hostrcb_error, u) +
+ offsetof(struct ipr_hostrcb_type_20_error, desc));
+
+ for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
+ ipr_log_fabric_path(hostrcb, fabric);
+ for_each_fabric_cfg(fabric, cfg)
+ ipr_log_path_elem(hostrcb, cfg);
+
+ add_len -= be16_to_cpu(fabric->length);
+ fabric = (struct ipr_hostrcb_fabric_desc *)
+ ((unsigned long)fabric + be16_to_cpu(fabric->length));
+ }
+
+ ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
+}
+
/**
* ipr_log_generic_error - Log an adapter error.
* @ioa_cfg: ioa config struct
@@ -1332,7 +1549,7 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg,
struct ipr_hostrcb *hostrcb)
{
- ipr_log_hex_data(hostrcb->hcam.u.raw.data,
+ ipr_log_hex_data(ioa_cfg, hostrcb->hcam.u.raw.data,
be32_to_cpu(hostrcb->hcam.length));
}
@@ -1394,13 +1611,7 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
if (!ipr_error_table[error_index].log_hcam)
return;
- if (ipr_is_device(&hostrcb->hcam.u.error.failing_dev_res_addr)) {
- ipr_ra_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr,
- "%s\n", ipr_error_table[error_index].error);
- } else {
- dev_err(&ioa_cfg->pdev->dev, "%s\n",
- ipr_error_table[error_index].error);
- }
+ ipr_hcam_err(hostrcb, "%s\n", ipr_error_table[error_index].error);
/* Set indication we have logged an error */
ioa_cfg->errors_logged++;
@@ -1437,6 +1648,9 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
case IPR_HOST_RCB_OVERLAY_ID_17:
ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb);
break;
+ case IPR_HOST_RCB_OVERLAY_ID_20:
+ ipr_log_fabric_error(ioa_cfg, hostrcb);
+ break;
case IPR_HOST_RCB_OVERLAY_ID_1:
case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
default:
@@ -2093,7 +2307,7 @@ static void ipr_release_dump(struct kref *kref)
/**
* ipr_worker_thread - Worker thread
- * @data: ioa config struct
+ * @work: ioa config struct
*
* Called at task level from a work thread. This function takes care
* of adding and removing device from the mid-layer as configuration
@@ -2102,13 +2316,14 @@ static void ipr_release_dump(struct kref *kref)
* Return value:
* nothing
**/
-static void ipr_worker_thread(void *data)
+static void ipr_worker_thread(struct work_struct *work)
{
unsigned long lock_flags;
struct ipr_resource_entry *res;
struct scsi_device *sdev;
struct ipr_dump *dump;
- struct ipr_ioa_cfg *ioa_cfg = data;
+ struct ipr_ioa_cfg *ioa_cfg =
+ container_of(work, struct ipr_ioa_cfg, work_q);
u8 bus, target, lun;
int did_work;
@@ -2969,7 +3184,6 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg)
struct ipr_dump *dump;
unsigned long lock_flags = 0;
- ENTER;
dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL);
if (!dump) {
@@ -2996,7 +3210,6 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg)
}
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- LEAVE;
return 0;
}
@@ -3573,6 +3786,12 @@ static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)
ENTER;
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ while(ioa_cfg->in_reset_reload) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ }
+
res = sata_port->res;
if (res) {
rc = ipr_device_reset(ioa_cfg, res);
@@ -3636,6 +3855,10 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
if (ipr_cmd->scsi_cmd)
ipr_cmd->done = ipr_scsi_eh_done;
+ if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) {
+ ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;
+ ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;
+ }
}
}
@@ -3770,7 +3993,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
*/
if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead)
return FAILED;
- if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res)))
+ if (!res || !ipr_is_gscsi(res))
return FAILED;
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
@@ -4615,7 +4838,7 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
* Return value:
* 0 on success / other on failure
**/
-int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
{
struct ipr_resource_entry *res;
@@ -4648,40 +4871,6 @@ static const char * ipr_ioa_info(struct Scsi_Host *host)
return buffer;
}
-/**
- * ipr_scsi_timed_out - Handle scsi command timeout
- * @scsi_cmd: scsi command struct
- *
- * Return value:
- * EH_NOT_HANDLED
- **/
-enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd)
-{
- struct ipr_ioa_cfg *ioa_cfg;
- struct ipr_cmnd *ipr_cmd;
- unsigned long flags;
-
- ENTER;
- spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
- ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
-
- list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
- if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) {
- ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;
- ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;
- break;
- }
- }
-
- spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
- LEAVE;
- return EH_NOT_HANDLED;
-}
-
-static struct scsi_transport_template ipr_transport_template = {
- .eh_timed_out = ipr_scsi_timed_out
-};
-
static struct scsi_host_template driver_template = {
.module = THIS_MODULE,
.name = "IPR",
@@ -4776,6 +4965,12 @@ static void ipr_ata_post_internal(struct ata_queued_cmd *qc)
unsigned long flags;
spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+ while(ioa_cfg->in_reset_reload) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+ spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+ }
+
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
if (ipr_cmd->qc == qc) {
ipr_device_reset(ioa_cfg, sata_port->res);
@@ -6832,6 +7027,7 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->hostrcb[i]->hostrcb_dma =
ioa_cfg->hostrcb_dma[i] + offsetof(struct ipr_hostrcb, hcam);
+ ioa_cfg->hostrcb[i]->ioa_cfg = ioa_cfg;
list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q);
}
@@ -6926,7 +7122,7 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
INIT_LIST_HEAD(&ioa_cfg->hostrcb_pending_q);
INIT_LIST_HEAD(&ioa_cfg->free_res_q);
INIT_LIST_HEAD(&ioa_cfg->used_res_q);
- INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread, ioa_cfg);
+ INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
init_waitqueue_head(&ioa_cfg->reset_wait_q);
ioa_cfg->sdt_state = INACTIVE;
if (ipr_enable_cache)
@@ -7017,7 +7213,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;
memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg));
- host->transportt = &ipr_transport_template;
ata_host_init(&ioa_cfg->ata_host, &pdev->dev,
sata_port_info.flags, &ipr_sata_ops);
@@ -7351,12 +7546,24 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
@@ -7366,6 +7573,9 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
+ { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F,
+ 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
{ }
};
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 6d035283af08..9f62a1d4d511 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -37,8 +37,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.2.0"
-#define IPR_DRIVER_DATE "(September 25, 2006)"
+#define IPR_DRIVER_VERSION "2.3.0"
+#define IPR_DRIVER_DATE "(November 8, 2006)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -54,6 +54,8 @@
*/
#define IPR_NUM_BASE_CMD_BLKS 100
+#define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339
+
#define IPR_SUBS_DEV_ID_2780 0x0264
#define IPR_SUBS_DEV_ID_5702 0x0266
#define IPR_SUBS_DEV_ID_5703 0x0278
@@ -66,7 +68,11 @@
#define IPR_SUBS_DEV_ID_571F 0x02D5
#define IPR_SUBS_DEV_ID_572A 0x02C1
#define IPR_SUBS_DEV_ID_572B 0x02C2
+#define IPR_SUBS_DEV_ID_572F 0x02C3
#define IPR_SUBS_DEV_ID_575B 0x030D
+#define IPR_SUBS_DEV_ID_575C 0x0338
+#define IPR_SUBS_DEV_ID_57B7 0x0360
+#define IPR_SUBS_DEV_ID_57B8 0x02C2
#define IPR_NAME "ipr"
@@ -98,6 +104,7 @@
#define IPR_IOASC_IOA_WAS_RESET 0x10000001
#define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002
+#define IPR_DEFAULT_MAX_ERROR_DUMP 984
#define IPR_NUM_LOG_HCAMS 2
#define IPR_NUM_CFG_CHG_HCAMS 2
#define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
@@ -731,6 +738,64 @@ struct ipr_hostrcb_type_17_error {
u32 data[476];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb_config_element {
+ u8 type_status;
+#define IPR_PATH_CFG_TYPE_MASK 0xF0
+#define IPR_PATH_CFG_NOT_EXIST 0x00
+#define IPR_PATH_CFG_IOA_PORT 0x10
+#define IPR_PATH_CFG_EXP_PORT 0x20
+#define IPR_PATH_CFG_DEVICE_PORT 0x30
+#define IPR_PATH_CFG_DEVICE_LUN 0x40
+
+#define IPR_PATH_CFG_STATUS_MASK 0x0F
+#define IPR_PATH_CFG_NO_PROB 0x00
+#define IPR_PATH_CFG_DEGRADED 0x01
+#define IPR_PATH_CFG_FAILED 0x02
+#define IPR_PATH_CFG_SUSPECT 0x03
+#define IPR_PATH_NOT_DETECTED 0x04
+#define IPR_PATH_INCORRECT_CONN 0x05
+
+ u8 cascaded_expander;
+ u8 phy;
+ u8 link_rate;
+#define IPR_PHY_LINK_RATE_MASK 0x0F
+
+ __be32 wwid[2];
+}__attribute__((packed, aligned (4)));
+
+struct ipr_hostrcb_fabric_desc {
+ __be16 length;
+ u8 ioa_port;
+ u8 cascaded_expander;
+ u8 phy;
+ u8 path_state;
+#define IPR_PATH_ACTIVE_MASK 0xC0
+#define IPR_PATH_NO_INFO 0x00
+#define IPR_PATH_ACTIVE 0x40
+#define IPR_PATH_NOT_ACTIVE 0x80
+
+#define IPR_PATH_STATE_MASK 0x0F
+#define IPR_PATH_STATE_NO_INFO 0x00
+#define IPR_PATH_HEALTHY 0x01
+#define IPR_PATH_DEGRADED 0x02
+#define IPR_PATH_FAILED 0x03
+
+ __be16 num_entries;
+ struct ipr_hostrcb_config_element elem[1];
+}__attribute__((packed, aligned (4)));
+
+#define for_each_fabric_cfg(fabric, cfg) \
+ for (cfg = (fabric)->elem; \
+ cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \
+ cfg++)
+
+struct ipr_hostrcb_type_20_error {
+ u8 failure_reason[64];
+ u8 reserved[3];
+ u8 num_entries;
+ struct ipr_hostrcb_fabric_desc desc[1];
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_error {
__be32 failing_dev_ioasc;
struct ipr_res_addr failing_dev_res_addr;
@@ -747,6 +812,7 @@ struct ipr_hostrcb_error {
struct ipr_hostrcb_type_13_error type_13_error;
struct ipr_hostrcb_type_14_error type_14_error;
struct ipr_hostrcb_type_17_error type_17_error;
+ struct ipr_hostrcb_type_20_error type_20_error;
} u;
}__attribute__((packed, aligned (4)));
@@ -786,6 +852,7 @@ struct ipr_hcam {
#define IPR_HOST_RCB_OVERLAY_ID_14 0x14
#define IPR_HOST_RCB_OVERLAY_ID_16 0x16
#define IPR_HOST_RCB_OVERLAY_ID_17 0x17
+#define IPR_HOST_RCB_OVERLAY_ID_20 0x20
#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF
u8 reserved1[3];
@@ -805,6 +872,7 @@ struct ipr_hostrcb {
struct ipr_hcam hcam;
dma_addr_t hostrcb_dma;
struct list_head queue;
+ struct ipr_ioa_cfg *ioa_cfg;
};
/* IPR smart dump table structures */
@@ -1283,6 +1351,17 @@ struct ipr_ucode_image_header {
} \
}
+#define ipr_hcam_err(hostrcb, fmt, ...) \
+{ \
+ if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \
+ ipr_ra_err((hostrcb)->ioa_cfg, \
+ (hostrcb)->hcam.u.error.failing_dev_res_addr, \
+ fmt, ##__VA_ARGS__); \
+ } else { \
+ dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \
+ } \
+}
+
#define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
__FILE__, __FUNCTION__, __LINE__)
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index f06a06ae6092..8b704f73055a 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -5001,7 +5001,7 @@ ips_init_copperhead(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (j >= 45)
@@ -5027,7 +5027,7 @@ ips_init_copperhead(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (j >= 240)
@@ -5045,7 +5045,7 @@ ips_init_copperhead(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (i >= 240)
@@ -5095,7 +5095,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (j >= 45)
@@ -5121,7 +5121,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (j >= 240)
@@ -5139,7 +5139,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (i >= 240)
@@ -5191,7 +5191,7 @@ ips_init_morpheus(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (i >= 45) {
@@ -5217,7 +5217,7 @@ ips_init_morpheus(ips_ha_t * ha)
if (Post != 0x4F00)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (i >= 120) {
@@ -5247,7 +5247,7 @@ ips_init_morpheus(ips_ha_t * ha)
break;
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
}
if (i >= 240) {
@@ -5307,12 +5307,12 @@ ips_reset_copperhead(ips_ha_t * ha)
outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
outb(0, ha->io_addr + IPS_REG_SCPR);
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
if ((*ha->func.init) (ha))
break;
@@ -5352,12 +5352,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha)
writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
writeb(0, ha->mem_ptr + IPS_REG_SCPR);
/* Delay for 1 Second */
- msleep(IPS_ONE_SEC);
+ MDELAY(IPS_ONE_SEC);
if ((*ha->func.init) (ha))
break;
@@ -5398,7 +5398,7 @@ ips_reset_morpheus(ips_ha_t * ha)
writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
/* Delay for 5 Seconds */
- msleep(5 * IPS_ONE_SEC);
+ MDELAY(5 * IPS_ONE_SEC);
/* Do a PCI config read to wait for adapter */
pci_read_config_byte(ha->pcidev, 4, &junk);
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 34680f3dd452..b726dcc424b1 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -51,6 +51,7 @@
#define _IPS_H_
#include <linux/version.h>
+#include <linux/nmi.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -116,9 +117,11 @@
dev_printk(level , &((pcidev)->dev) , format , ## arg)
#endif
- #ifndef MDELAY
- #define MDELAY mdelay
- #endif
+ #define MDELAY(n) \
+ do { \
+ mdelay(n); \
+ touch_nmi_watchdog(); \
+ } while (0)
#ifndef min
#define min(x,y) ((x) < (y) ? x : y)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5d8862189485..e11b23c641e2 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -719,9 +719,10 @@ again:
return rc;
}
-static void iscsi_xmitworker(void *data)
+static void iscsi_xmitworker(struct work_struct *work)
{
- struct iscsi_conn *conn = data;
+ struct iscsi_conn *conn =
+ container_of(work, struct iscsi_conn, xmitwork);
int rc;
/*
* serialize Xmit worker on a per-connection basis.
@@ -1512,7 +1513,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
goto mgmtqueue_alloc_fail;
- INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
+ INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
/* allocate login_mtask used for the login/text sequences */
spin_lock_bh(&session->lock);
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index d977bd492d8d..fb7df7b75811 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -647,10 +647,12 @@ void sas_unregister_domain_devices(struct asd_sas_port *port)
* Discover process only interrogates devices in order to discover the
* domain.
*/
-static void sas_discover_domain(void *data)
+static void sas_discover_domain(struct work_struct *work)
{
int error = 0;
- struct asd_sas_port *port = data;
+ struct sas_discovery_event *ev =
+ container_of(work, struct sas_discovery_event, work);
+ struct asd_sas_port *port = ev->port;
sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock,
&port->disc.pending);
@@ -692,10 +694,12 @@ static void sas_discover_domain(void *data)
current->pid, error);
}
-static void sas_revalidate_domain(void *data)
+static void sas_revalidate_domain(struct work_struct *work)
{
int res = 0;
- struct asd_sas_port *port = data;
+ struct sas_discovery_event *ev =
+ container_of(work, struct sas_discovery_event, work);
+ struct asd_sas_port *port = ev->port;
sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock,
&port->disc.pending);
@@ -722,7 +726,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
BUG_ON(ev >= DISC_NUM_EVENTS);
sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
- &disc->disc_work[ev], port->ha->core.shost);
+ &disc->disc_work[ev].work, port->ha->core.shost);
return 0;
}
@@ -737,13 +741,15 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
{
int i;
- static void (*sas_event_fns[DISC_NUM_EVENTS])(void *) = {
+ static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
[DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
[DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
};
spin_lock_init(&disc->disc_event_lock);
disc->pending = 0;
- for (i = 0; i < DISC_NUM_EVENTS; i++)
- INIT_WORK(&disc->disc_work[i], sas_event_fns[i], port);
+ for (i = 0; i < DISC_NUM_EVENTS; i++) {
+ INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
+ disc->disc_work[i].port = port;
+ }
}
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
index 19110ed1c89c..d83392ee6823 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
BUG_ON(event >= HA_NUM_EVENTS);
sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
- &sas_ha->ha_events[event], sas_ha->core.shost);
+ &sas_ha->ha_events[event].work, sas_ha->core.shost);
}
static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
@@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
BUG_ON(event >= PORT_NUM_EVENTS);
sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
- &phy->port_events[event], ha->core.shost);
+ &phy->port_events[event].work, ha->core.shost);
}
static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
@@ -51,12 +51,12 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
BUG_ON(event >= PHY_NUM_EVENTS);
sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
- &phy->phy_events[event], ha->core.shost);
+ &phy->phy_events[event].work, ha->core.shost);
}
int sas_init_events(struct sas_ha_struct *sas_ha)
{
- static void (*sas_ha_event_fns[HA_NUM_EVENTS])(void *) = {
+ static const work_func_t sas_ha_event_fns[HA_NUM_EVENTS] = {
[HAE_RESET] = sas_hae_reset,
};
@@ -64,8 +64,10 @@ int sas_init_events(struct sas_ha_struct *sas_ha)
spin_lock_init(&sas_ha->event_lock);
- for (i = 0; i < HA_NUM_EVENTS; i++)
- INIT_WORK(&sas_ha->ha_events[i], sas_ha_event_fns[i], sas_ha);
+ for (i = 0; i < HA_NUM_EVENTS; i++) {
+ INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);
+ sas_ha->ha_events[i].ha = sas_ha;
+ }
sas_ha->notify_ha_event = notify_ha_event;
sas_ha->notify_port_event = notify_port_event;
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index e34a93435497..d31e6fa466f7 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -597,10 +597,15 @@ static struct domain_device *sas_ex_discover_end_dev(
child->iproto = phy->attached_iproto;
memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
- phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
- BUG_ON(!phy->port);
- /* FIXME: better error handling*/
- BUG_ON(sas_port_add(phy->port) != 0);
+ if (!phy->port) {
+ phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
+ if (unlikely(!phy->port))
+ goto out_err;
+ if (unlikely(sas_port_add(phy->port) != 0)) {
+ sas_port_free(phy->port);
+ goto out_err;
+ }
+ }
sas_ex_get_linkrate(parent, child, phy);
if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
@@ -615,8 +620,7 @@ static struct domain_device *sas_ex_discover_end_dev(
SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
"0x%x\n", SAS_ADDR(parent->sas_addr),
phy_id, res);
- kfree(child);
- return NULL;
+ goto out_free;
}
memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
sizeof(struct dev_to_host_fis));
@@ -627,14 +631,14 @@ static struct domain_device *sas_ex_discover_end_dev(
"%016llx:0x%x returned 0x%x\n",
SAS_ADDR(child->sas_addr),
SAS_ADDR(parent->sas_addr), phy_id, res);
- kfree(child);
- return NULL;
+ goto out_free;
}
} else if (phy->attached_tproto & SAS_PROTO_SSP) {
child->dev_type = SAS_END_DEV;
rphy = sas_end_device_alloc(phy->port);
/* FIXME: error handling */
- BUG_ON(!rphy);
+ if (unlikely(!rphy))
+ goto out_free;
child->tproto = phy->attached_tproto;
sas_init_dev(child);
@@ -651,9 +655,7 @@ static struct domain_device *sas_ex_discover_end_dev(
"at %016llx:0x%x returned 0x%x\n",
SAS_ADDR(child->sas_addr),
SAS_ADDR(parent->sas_addr), phy_id, res);
- /* FIXME: this kfrees list elements without removing them */
- //kfree(child);
- return NULL;
+ goto out_list_del;
}
} else {
SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
@@ -663,6 +665,16 @@ static struct domain_device *sas_ex_discover_end_dev(
list_add_tail(&child->siblings, &parent_ex->children);
return child;
+
+ out_list_del:
+ list_del(&child->dev_list_node);
+ sas_rphy_free(rphy);
+ out_free:
+ sas_port_delete(phy->port);
+ out_err:
+ phy->port = NULL;
+ kfree(child);
+ return NULL;
}
static struct domain_device *sas_ex_discover_expander(
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index c836a237fb79..d65bc4e0f214 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -65,9 +65,11 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
/* ---------- HA events ---------- */
-void sas_hae_reset(void *data)
+void sas_hae_reset(struct work_struct *work)
{
- struct sas_ha_struct *ha = data;
+ struct sas_ha_event *ev =
+ container_of(work, struct sas_ha_event, work);
+ struct sas_ha_struct *ha = ev->ha;
sas_begin_event(HAE_RESET, &ha->event_lock,
&ha->pending);
@@ -112,6 +114,8 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
}
}
+ INIT_LIST_HEAD(&sas_ha->eh_done_q);
+
return 0;
Undo_ports:
@@ -142,7 +146,7 @@ static int sas_get_linkerrors(struct sas_phy *phy)
return sas_smp_get_phy_events(phy);
}
-static int sas_phy_reset(struct sas_phy *phy, int hard_reset)
+int sas_phy_reset(struct sas_phy *phy, int hard_reset)
{
int ret;
enum phy_func reset_type;
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index bffcee474921..137d7e496b6d 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -60,11 +60,11 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
void sas_deform_port(struct asd_sas_phy *phy);
-void sas_porte_bytes_dmaed(void *);
-void sas_porte_broadcast_rcvd(void *);
-void sas_porte_link_reset_err(void *);
-void sas_porte_timer_event(void *);
-void sas_porte_hard_reset(void *);
+void sas_porte_bytes_dmaed(struct work_struct *work);
+void sas_porte_broadcast_rcvd(struct work_struct *work);
+void sas_porte_link_reset_err(struct work_struct *work);
+void sas_porte_timer_event(struct work_struct *work);
+void sas_porte_hard_reset(struct work_struct *work);
int sas_notify_lldd_dev_found(struct domain_device *);
void sas_notify_lldd_dev_gone(struct domain_device *);
@@ -75,7 +75,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy);
struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
-void sas_hae_reset(void *);
+void sas_hae_reset(struct work_struct *work);
static inline void sas_queue_event(int event, spinlock_t *lock,
unsigned long *pending,
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index 9340cdbae4a3..b459c4b635b1 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -30,9 +30,11 @@
/* ---------- Phy events ---------- */
-static void sas_phye_loss_of_signal(void *data)
+static void sas_phye_loss_of_signal(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
&phy->phy_events_pending);
@@ -40,18 +42,22 @@ static void sas_phye_loss_of_signal(void *data)
sas_deform_port(phy);
}
-static void sas_phye_oob_done(void *data)
+static void sas_phye_oob_done(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
&phy->phy_events_pending);
phy->error = 0;
}
-static void sas_phye_oob_error(void *data)
+static void sas_phye_oob_error(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
struct sas_ha_struct *sas_ha = phy->ha;
struct asd_sas_port *port = phy->port;
struct sas_internal *i =
@@ -80,9 +86,11 @@ static void sas_phye_oob_error(void *data)
}
}
-static void sas_phye_spinup_hold(void *data)
+static void sas_phye_spinup_hold(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
struct sas_ha_struct *sas_ha = phy->ha;
struct sas_internal *i =
to_sas_internal(sas_ha->core.shost->transportt);
@@ -100,14 +108,14 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
{
int i;
- static void (*sas_phy_event_fns[PHY_NUM_EVENTS])(void *) = {
+ static const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = {
[PHYE_LOSS_OF_SIGNAL] = sas_phye_loss_of_signal,
[PHYE_OOB_DONE] = sas_phye_oob_done,
[PHYE_OOB_ERROR] = sas_phye_oob_error,
[PHYE_SPINUP_HOLD] = sas_phye_spinup_hold,
};
- static void (*sas_port_event_fns[PORT_NUM_EVENTS])(void *) = {
+ static const work_func_t sas_port_event_fns[PORT_NUM_EVENTS] = {
[PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed,
[PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd,
[PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err,
@@ -122,13 +130,18 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
phy->error = 0;
INIT_LIST_HEAD(&phy->port_phy_el);
- for (k = 0; k < PORT_NUM_EVENTS; k++)
- INIT_WORK(&phy->port_events[k], sas_port_event_fns[k],
- phy);
+ for (k = 0; k < PORT_NUM_EVENTS; k++) {
+ INIT_WORK(&phy->port_events[k].work,
+ sas_port_event_fns[k]);
+ phy->port_events[k].phy = phy;
+ }
+
+ for (k = 0; k < PHY_NUM_EVENTS; k++) {
+ INIT_WORK(&phy->phy_events[k].work,
+ sas_phy_event_fns[k]);
+ phy->phy_events[k].phy = phy;
+ }
- for (k = 0; k < PHY_NUM_EVENTS; k++)
- INIT_WORK(&phy->phy_events[k], sas_phy_event_fns[k],
- phy);
phy->port = NULL;
phy->ha = sas_ha;
spin_lock_init(&phy->frame_rcvd_lock);
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 253cdcf306a2..971c37ceecb4 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -181,9 +181,11 @@ void sas_deform_port(struct asd_sas_phy *phy)
/* ---------- SAS port events ---------- */
-void sas_porte_bytes_dmaed(void *data)
+void sas_porte_bytes_dmaed(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock,
&phy->port_events_pending);
@@ -191,11 +193,13 @@ void sas_porte_bytes_dmaed(void *data)
sas_form_port(phy);
}
-void sas_porte_broadcast_rcvd(void *data)
+void sas_porte_broadcast_rcvd(struct work_struct *work)
{
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
unsigned long flags;
u32 prim;
- struct asd_sas_phy *phy = data;
sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock,
&phy->port_events_pending);
@@ -208,9 +212,11 @@ void sas_porte_broadcast_rcvd(void *data)
sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN);
}
-void sas_porte_link_reset_err(void *data)
+void sas_porte_link_reset_err(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
&phy->port_events_pending);
@@ -218,9 +224,11 @@ void sas_porte_link_reset_err(void *data)
sas_deform_port(phy);
}
-void sas_porte_timer_event(void *data)
+void sas_porte_timer_event(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
&phy->port_events_pending);
@@ -228,9 +236,11 @@ void sas_porte_timer_event(void *data)
sas_deform_port(phy);
}
-void sas_porte_hard_reset(void *data)
+void sas_porte_hard_reset(struct work_struct *work)
{
- struct asd_sas_phy *phy = data;
+ struct asd_sas_event *ev =
+ container_of(work, struct asd_sas_event, work);
+ struct asd_sas_phy *phy = ev->phy;
sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
&phy->port_events_pending);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index e46e79355b77..22672d54aa27 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -29,9 +29,11 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_sas.h>
#include "../scsi_sas_internal.h"
+#include "../scsi_transport_api.h"
#include <linux/err.h>
#include <linux/blkdev.h>
@@ -46,6 +48,7 @@ static void sas_scsi_task_done(struct sas_task *task)
{
struct task_status_struct *ts = &task->task_status;
struct scsi_cmnd *sc = task->uldd_task;
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host);
unsigned ts_flags = task->task_state_flags;
int hs = 0, stat = 0;
@@ -116,7 +119,7 @@ static void sas_scsi_task_done(struct sas_task *task)
sas_free_task(task);
/* This is very ugly but this is how SCSI Core works. */
if (ts_flags & SAS_TASK_STATE_ABORTED)
- scsi_finish_command(sc);
+ scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q);
else
sc->scsi_done(sc);
}
@@ -307,6 +310,15 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) {
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ SAS_DPRINTK("%s: task 0x%p already aborted\n",
+ __FUNCTION__, task);
+ return TASK_IS_ABORTED;
+ }
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
for (i = 0; i < 5; i++) {
SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
res = si->dft->lldd_abort_task(task);
@@ -409,13 +421,16 @@ Again:
SAS_DPRINTK("going over list...\n");
list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
struct sas_task *task = TO_SAS_TASK(cmd);
+ list_del_init(&cmd->eh_entry);
+ if (!task) {
+ SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__);
+ continue;
+ }
SAS_DPRINTK("trying to find task 0x%p\n", task);
- list_del_init(&cmd->eh_entry);
res = sas_scsi_find_task(task);
cmd->eh_eflags = 0;
- shost->host_failed--;
switch (res) {
case TASK_IS_DONE:
@@ -491,6 +506,7 @@ Again:
}
}
out:
+ scsi_eh_flush_done_q(&ha->eh_done_q);
SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
return;
clear_q:
@@ -508,12 +524,18 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
unsigned long flags;
if (!task) {
- SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
+ SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n",
cmd, task);
return EH_HANDLED;
}
spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) {
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: "
+ "EH_NOT_HANDLED\n", cmd, task);
+ return EH_NOT_HANDLED;
+ }
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
@@ -777,6 +799,66 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}
+static int do_sas_task_abort(struct sas_task *task)
+{
+ struct scsi_cmnd *sc = task->uldd_task;
+ struct sas_internal *si =
+ to_sas_internal(task->dev->port->ha->core.shost->transportt);
+ unsigned long flags;
+ int res;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__,
+ task);
+ return 0;
+ }
+
+ task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED;
+ if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
+ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ if (!si->dft->lldd_abort_task)
+ return -ENODEV;
+
+ res = si->dft->lldd_abort_task(task);
+ if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
+ (res == TMF_RESP_FUNC_COMPLETE))
+ {
+ /* SMP commands don't have scsi_cmds(?) */
+ if (!sc) {
+ task->task_done(task);
+ return 0;
+ }
+ scsi_req_abort_cmd(sc);
+ scsi_schedule_eh(sc->device->host);
+ return 0;
+ }
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED;
+ if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
+ task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ return -EAGAIN;
+}
+
+void sas_task_abort(struct work_struct *work)
+{
+ struct sas_task *task =
+ container_of(work, struct sas_task, abort_work);
+ int i;
+
+ for (i = 0; i < 5; i++)
+ if (!do_sas_task_abort(task))
+ return;
+
+ SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__);
+}
+
EXPORT_SYMBOL_GPL(sas_queuecommand);
EXPORT_SYMBOL_GPL(sas_target_alloc);
EXPORT_SYMBOL_GPL(sas_slave_configure);
@@ -784,3 +866,5 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy);
EXPORT_SYMBOL_GPL(sas_change_queue_depth);
EXPORT_SYMBOL_GPL(sas_change_queue_type);
EXPORT_SYMBOL_GPL(sas_bios_param);
+EXPORT_SYMBOL_GPL(sas_task_abort);
+EXPORT_SYMBOL_GPL(sas_phy_reset);
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
new file mode 100644
index 000000000000..89403b00e042
--- /dev/null
+++ b/drivers/scsi/libsrp.c
@@ -0,0 +1,441 @@
+/*
+ * SCSI RDAM Protocol lib functions
+ *
+ * Copyright (C) 2006 FUJITA Tomonori <tomof@acm.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/err.h>
+#include <linux/kfifo.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_tgt.h>
+#include <scsi/srp.h>
+#include <scsi/libsrp.h>
+
+enum srp_task_attributes {
+ SRP_SIMPLE_TASK = 0,
+ SRP_HEAD_TASK = 1,
+ SRP_ORDERED_TASK = 2,
+ SRP_ACA_TASK = 4
+};
+
+/* tmp - will replace with SCSI logging stuff */
+#define eprintk(fmt, args...) \
+do { \
+ printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \
+} while (0)
+/* #define dprintk eprintk */
+#define dprintk(fmt, args...)
+
+static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
+ struct srp_buf **ring)
+{
+ int i;
+ struct iu_entry *iue;
+
+ q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL);
+ if (!q->pool)
+ return -ENOMEM;
+ q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL);
+ if (!q->items)
+ goto free_pool;
+
+ spin_lock_init(&q->lock);
+ q->queue = kfifo_init((void *) q->pool, max * sizeof(void *),
+ GFP_KERNEL, &q->lock);
+ if (IS_ERR(q->queue))
+ goto free_item;
+
+ for (i = 0, iue = q->items; i < max; i++) {
+ __kfifo_put(q->queue, (void *) &iue, sizeof(void *));
+ iue->sbuf = ring[i];
+ iue++;
+ }
+ return 0;
+
+free_item:
+ kfree(q->items);
+free_pool:
+ kfree(q->pool);
+ return -ENOMEM;
+}
+
+static void srp_iu_pool_free(struct srp_queue *q)
+{
+ kfree(q->items);
+ kfree(q->pool);
+}
+
+static struct srp_buf **srp_ring_alloc(struct device *dev,
+ size_t max, size_t size)
+{
+ int i;
+ struct srp_buf **ring;
+
+ ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL);
+ if (!ring)
+ return NULL;
+
+ for (i = 0; i < max; i++) {
+ ring[i] = kzalloc(sizeof(struct srp_buf), GFP_KERNEL);
+ if (!ring[i])
+ goto out;
+ ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma,
+ GFP_KERNEL);
+ if (!ring[i]->buf)
+ goto out;
+ }
+ return ring;
+
+out:
+ for (i = 0; i < max && ring[i]; i++) {
+ if (ring[i]->buf)
+ dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
+ kfree(ring[i]);
+ }
+ kfree(ring);
+
+ return NULL;
+}
+
+static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
+ size_t size)
+{
+ int i;
+
+ for (i = 0; i < max; i++) {
+ dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
+ kfree(ring[i]);
+ }
+}
+
+int srp_target_alloc(struct srp_target *target, struct device *dev,
+ size_t nr, size_t iu_size)
+{
+ int err;
+
+ spin_lock_init(&target->lock);
+ INIT_LIST_HEAD(&target->cmd_queue);
+
+ target->dev = dev;
+ target->dev->driver_data = target;
+
+ target->srp_iu_size = iu_size;
+ target->rx_ring_size = nr;
+ target->rx_ring = srp_ring_alloc(target->dev, nr, iu_size);
+ if (!target->rx_ring)
+ return -ENOMEM;
+ err = srp_iu_pool_alloc(&target->iu_queue, nr, target->rx_ring);
+ if (err)
+ goto free_ring;
+
+ return 0;
+
+free_ring:
+ srp_ring_free(target->dev, target->rx_ring, nr, iu_size);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(srp_target_alloc);
+
+void srp_target_free(struct srp_target *target)
+{
+ srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size,
+ target->srp_iu_size);
+ srp_iu_pool_free(&target->iu_queue);
+}
+EXPORT_SYMBOL_GPL(srp_target_free);
+
+struct iu_entry *srp_iu_get(struct srp_target *target)
+{
+ struct iu_entry *iue = NULL;
+
+ kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *));
+ if (!iue)
+ return iue;
+ iue->target = target;
+ INIT_LIST_HEAD(&iue->ilist);
+ iue->flags = 0;
+ return iue;
+}
+EXPORT_SYMBOL_GPL(srp_iu_get);
+
+void srp_iu_put(struct iu_entry *iue)
+{
+ kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+}
+EXPORT_SYMBOL_GPL(srp_iu_put);
+
+static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
+ enum dma_data_direction dir, srp_rdma_t rdma_io,
+ int dma_map, int ext_desc)
+{
+ struct iu_entry *iue = NULL;
+ struct scatterlist *sg = NULL;
+ int err, nsg = 0, len;
+
+ if (dma_map) {
+ iue = (struct iu_entry *) sc->SCp.ptr;
+ sg = sc->request_buffer;
+
+ dprintk("%p %u %u %d\n", iue, sc->request_bufflen,
+ md->len, sc->use_sg);
+
+ nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg,
+ DMA_BIDIRECTIONAL);
+ if (!nsg) {
+ printk("fail to map %p %d\n", iue, sc->use_sg);
+ return 0;
+ }
+ len = min(sc->request_bufflen, md->len);
+ } else
+ len = md->len;
+
+ err = rdma_io(sc, sg, nsg, md, 1, dir, len);
+
+ if (dma_map)
+ dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+
+ return err;
+}
+
+static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
+ struct srp_indirect_buf *id,
+ enum dma_data_direction dir, srp_rdma_t rdma_io,
+ int dma_map, int ext_desc)
+{
+ struct iu_entry *iue = NULL;
+ struct srp_direct_buf *md = NULL;
+ struct scatterlist dummy, *sg = NULL;
+ dma_addr_t token = 0;
+ long err;
+ unsigned int done = 0;
+ int nmd, nsg = 0, len;
+
+ if (dma_map || ext_desc) {
+ iue = (struct iu_entry *) sc->SCp.ptr;
+ sg = sc->request_buffer;
+
+ dprintk("%p %u %u %d %d\n",
+ iue, sc->request_bufflen, id->len,
+ cmd->data_in_desc_cnt, cmd->data_out_desc_cnt);
+ }
+
+ nmd = id->table_desc.len / sizeof(struct srp_direct_buf);
+
+ if ((dir == DMA_FROM_DEVICE && nmd == cmd->data_in_desc_cnt) ||
+ (dir == DMA_TO_DEVICE && nmd == cmd->data_out_desc_cnt)) {
+ md = &id->desc_list[0];
+ goto rdma;
+ }
+
+ if (ext_desc && dma_map) {
+ md = dma_alloc_coherent(iue->target->dev, id->table_desc.len,
+ &token, GFP_KERNEL);
+ if (!md) {
+ eprintk("Can't get dma memory %u\n", id->table_desc.len);
+ return -ENOMEM;
+ }
+
+ sg_init_one(&dummy, md, id->table_desc.len);
+ sg_dma_address(&dummy) = token;
+ err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
+ id->table_desc.len);
+ if (err < 0) {
+ eprintk("Error copying indirect table %ld\n", err);
+ goto free_mem;
+ }
+ } else {
+ eprintk("This command uses external indirect buffer\n");
+ return -EINVAL;
+ }
+
+rdma:
+ if (dma_map) {
+ nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL);
+ if (!nsg) {
+ eprintk("fail to map %p %d\n", iue, sc->use_sg);
+ goto free_mem;
+ }
+ len = min(sc->request_bufflen, id->len);
+ } else
+ len = id->len;
+
+ err = rdma_io(sc, sg, nsg, md, nmd, dir, len);
+
+ if (dma_map)
+ dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+
+free_mem:
+ if (token && dma_map)
+ dma_free_coherent(iue->target->dev, id->table_desc.len, md, token);
+
+ return done;
+}
+
+static int data_out_desc_size(struct srp_cmd *cmd)
+{
+ int size = 0;
+ u8 fmt = cmd->buf_fmt >> 4;
+
+ switch (fmt) {
+ case SRP_NO_DATA_DESC:
+ break;
+ case SRP_DATA_DESC_DIRECT:
+ size = sizeof(struct srp_direct_buf);
+ break;
+ case SRP_DATA_DESC_INDIRECT:
+ size = sizeof(struct srp_indirect_buf) +
+ sizeof(struct srp_direct_buf) * cmd->data_out_desc_cnt;
+ break;
+ default:
+ eprintk("client error. Invalid data_out_format %x\n", fmt);
+ break;
+ }
+ return size;
+}
+
+/*
+ * TODO: this can be called multiple times for a single command if it
+ * has very long data.
+ */
+int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
+ srp_rdma_t rdma_io, int dma_map, int ext_desc)
+{
+ struct srp_direct_buf *md;
+ struct srp_indirect_buf *id;
+ enum dma_data_direction dir;
+ int offset, err = 0;
+ u8 format;
+
+ offset = cmd->add_cdb_len * 4;
+
+ dir = srp_cmd_direction(cmd);
+ if (dir == DMA_FROM_DEVICE)
+ offset += data_out_desc_size(cmd);
+
+ if (dir == DMA_TO_DEVICE)
+ format = cmd->buf_fmt >> 4;
+ else
+ format = cmd->buf_fmt & ((1U << 4) - 1);
+
+ switch (format) {
+ case SRP_NO_DATA_DESC:
+ break;
+ case SRP_DATA_DESC_DIRECT:
+ md = (struct srp_direct_buf *)
+ (cmd->add_data + offset);
+ err = srp_direct_data(sc, md, dir, rdma_io, dma_map, ext_desc);
+ break;
+ case SRP_DATA_DESC_INDIRECT:
+ id = (struct srp_indirect_buf *)
+ (cmd->add_data + offset);
+ err = srp_indirect_data(sc, cmd, id, dir, rdma_io, dma_map,
+ ext_desc);
+ break;
+ default:
+ eprintk("Unknown format %d %x\n", dir, format);
+ break;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(srp_transfer_data);
+
+static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
+{
+ struct srp_direct_buf *md;
+ struct srp_indirect_buf *id;
+ int len = 0, offset = cmd->add_cdb_len * 4;
+ u8 fmt;
+
+ if (dir == DMA_TO_DEVICE)
+ fmt = cmd->buf_fmt >> 4;
+ else {
+ fmt = cmd->buf_fmt & ((1U << 4) - 1);
+ offset += data_out_desc_size(cmd);
+ }
+
+ switch (fmt) {
+ case SRP_NO_DATA_DESC:
+ break;
+ case SRP_DATA_DESC_DIRECT:
+ md = (struct srp_direct_buf *) (cmd->add_data + offset);
+ len = md->len;
+ break;
+ case SRP_DATA_DESC_INDIRECT:
+ id = (struct srp_indirect_buf *) (cmd->add_data + offset);
+ len = id->len;
+ break;
+ default:
+ eprintk("invalid data format %x\n", fmt);
+ break;
+ }
+ return len;
+}
+
+int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
+ u64 addr)
+{
+ enum dma_data_direction dir;
+ struct scsi_cmnd *sc;
+ int tag, len, err;
+
+ switch (cmd->task_attr) {
+ case SRP_SIMPLE_TASK:
+ tag = MSG_SIMPLE_TAG;
+ break;
+ case SRP_ORDERED_TASK:
+ tag = MSG_ORDERED_TAG;
+ break;
+ case SRP_HEAD_TASK:
+ tag = MSG_HEAD_TAG;
+ break;
+ default:
+ eprintk("Task attribute %d not supported\n", cmd->task_attr);
+ tag = MSG_ORDERED_TAG;
+ }
+
+ dir = srp_cmd_direction(cmd);
+ len = vscsis_data_length(cmd, dir);
+
+ dprintk("%p %x %lx %d %d %d %llx\n", info, cmd->cdb[0],
+ cmd->lun, dir, len, tag, (unsigned long long) cmd->tag);
+
+ sc = scsi_host_get_command(shost, dir, GFP_KERNEL);
+ if (!sc)
+ return -ENOMEM;
+
+ sc->SCp.ptr = info;
+ memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
+ sc->request_bufflen = len;
+ sc->request_buffer = (void *) (unsigned long) addr;
+ sc->tag = tag;
+ err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag);
+ if (err)
+ scsi_host_put_command(shost, sc);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(srp_cmd_queue);
+
+MODULE_DESCRIPTION("SCSI RDAM Protocol lib functions");
+MODULE_AUTHOR("FUJITA Tomonori");
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3f7f5f8abd75..a7de0bca5bdd 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -296,13 +296,17 @@ struct lpfc_hba {
uint32_t cfg_cr_delay;
uint32_t cfg_cr_count;
uint32_t cfg_multi_ring_support;
+ uint32_t cfg_multi_ring_rctl;
+ uint32_t cfg_multi_ring_type;
uint32_t cfg_fdmi_on;
uint32_t cfg_discovery_threads;
uint32_t cfg_max_luns;
uint32_t cfg_poll;
uint32_t cfg_poll_tmo;
+ uint32_t cfg_use_msi;
uint32_t cfg_sg_seg_cnt;
uint32_t cfg_sg_dma_buf_size;
+ uint64_t cfg_soft_wwnn;
uint64_t cfg_soft_wwpn;
uint32_t dev_loss_tmo_changed;
@@ -355,7 +359,7 @@ struct lpfc_hba {
#define VPD_PORT 0x8 /* valid vpd port data */
#define VPD_MASK 0xf /* mask for any vpd data */
- uint8_t soft_wwpn_enable;
+ uint8_t soft_wwn_enable;
struct timer_list fcp_poll_timer;
struct timer_list els_tmofunc;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 2a4e02e7a392..f247e786af99 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -552,10 +552,10 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
-static char *lpfc_soft_wwpn_key = "C99G71SL8032A";
+static char *lpfc_soft_wwn_key = "C99G71SL8032A";
static ssize_t
-lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf,
+lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf,
size_t count)
{
struct Scsi_Host *host = class_to_shost(cdev);
@@ -579,15 +579,15 @@ lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf,
if (buf[cnt-1] == '\n')
cnt--;
- if ((cnt != strlen(lpfc_soft_wwpn_key)) ||
- (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0))
+ if ((cnt != strlen(lpfc_soft_wwn_key)) ||
+ (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
return -EINVAL;
- phba->soft_wwpn_enable = 1;
+ phba->soft_wwn_enable = 1;
return count;
}
-static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL,
- lpfc_soft_wwpn_enable_store);
+static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL,
+ lpfc_soft_wwn_enable_store);
static ssize_t
lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
@@ -613,12 +613,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
if (buf[cnt-1] == '\n')
cnt--;
- if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) ||
+ if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) ||
((cnt == 17) && (*buf++ != 'x')) ||
((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
return -EINVAL;
- phba->soft_wwpn_enable = 0;
+ phba->soft_wwn_enable = 0;
memset(wwpn, 0, sizeof(wwpn));
@@ -639,6 +639,8 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
}
phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
fc_host_port_name(host) = phba->cfg_soft_wwpn;
+ if (phba->cfg_soft_wwnn)
+ fc_host_node_name(host) = phba->cfg_soft_wwnn;
dev_printk(KERN_NOTICE, &phba->pcidev->dev,
"lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
@@ -664,6 +666,66 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);
+static ssize_t
+lpfc_soft_wwnn_show(struct class_device *cdev, char *buf)
+{
+ struct Scsi_Host *host = class_to_shost(cdev);
+ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+ return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+ (unsigned long long)phba->cfg_soft_wwnn);
+}
+
+
+static ssize_t
+lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count)
+{
+ struct Scsi_Host *host = class_to_shost(cdev);
+ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+ unsigned int i, j, cnt=count;
+ u8 wwnn[8];
+
+ /* count may include a LF at end of string */
+ if (buf[cnt-1] == '\n')
+ cnt--;
+
+ if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) ||
+ ((cnt == 17) && (*buf++ != 'x')) ||
+ ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
+ return -EINVAL;
+
+ /*
+ * Allow wwnn to be set many times, as long as the enable is set.
+ * However, once the wwpn is set, everything locks.
+ */
+
+ memset(wwnn, 0, sizeof(wwnn));
+
+ /* Validate and store the new name */
+ for (i=0, j=0; i < 16; i++) {
+ if ((*buf >= 'a') && (*buf <= 'f'))
+ j = ((j << 4) | ((*buf++ -'a') + 10));
+ else if ((*buf >= 'A') && (*buf <= 'F'))
+ j = ((j << 4) | ((*buf++ -'A') + 10));
+ else if ((*buf >= '0') && (*buf <= '9'))
+ j = ((j << 4) | (*buf++ -'0'));
+ else
+ return -EINVAL;
+ if (i % 2) {
+ wwnn[i/2] = j & 0xff;
+ j = 0;
+ }
+ }
+ phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
+
+ dev_printk(KERN_NOTICE, &phba->pcidev->dev,
+ "lpfc%d: soft_wwnn set. Value will take effect upon "
+ "setting of the soft_wwpn\n", phba->brd_no);
+
+ return count;
+}
+static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\
+ lpfc_soft_wwnn_show, lpfc_soft_wwnn_store);
+
static int lpfc_poll = 0;
module_param(lpfc_poll, int, 0);
@@ -802,12 +864,11 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
# LOG_MBOX 0x4 Mailbox events
# LOG_INIT 0x8 Initialization events
# LOG_LINK_EVENT 0x10 Link events
-# LOG_IP 0x20 IP traffic history
# LOG_FCP 0x40 FCP traffic history
# LOG_NODE 0x80 Node table events
# LOG_MISC 0x400 Miscellaneous events
# LOG_SLI 0x800 SLI events
-# LOG_CHK_COND 0x1000 FCP Check condition flag
+# LOG_FCP_ERROR 0x1000 Only log FCP errors
# LOG_LIBDFC 0x2000 LIBDFC events
# LOG_ALL_MSG 0xffff LOG all messages
*/
@@ -916,6 +977,22 @@ LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
"SLI rings to spread IOCB entries across");
/*
+# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
+# identifies what rctl value to configure the additional ring for.
+# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
+*/
+LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1,
+ 255, "Identifies RCTL for additional ring configuration");
+
+/*
+# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
+# identifies what type value to configure the additional ring for.
+# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
+*/
+LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1,
+ 255, "Identifies TYPE for additional ring configuration");
+
+/*
# lpfc_fdmi_on: controls FDMI support.
# 0 = no FDMI support
# 1 = support FDMI without attribute of hostname
@@ -946,6 +1023,15 @@ LPFC_ATTR_R(max_luns, 255, 0, 65535,
LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
"Milliseconds driver will wait between polling FCP ring");
+/*
+# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
+# support this feature
+# 0 = MSI disabled (default)
+# 1 = MSI enabled
+# Value range is [0,1]. Default value is 0.
+*/
+LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible");
+
struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_info,
@@ -974,6 +1060,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_lpfc_cr_delay,
&class_device_attr_lpfc_cr_count,
&class_device_attr_lpfc_multi_ring_support,
+ &class_device_attr_lpfc_multi_ring_rctl,
+ &class_device_attr_lpfc_multi_ring_type,
&class_device_attr_lpfc_fdmi_on,
&class_device_attr_lpfc_max_luns,
&class_device_attr_nport_evt_cnt,
@@ -982,8 +1070,10 @@ struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_issue_reset,
&class_device_attr_lpfc_poll,
&class_device_attr_lpfc_poll_tmo,
+ &class_device_attr_lpfc_use_msi,
+ &class_device_attr_lpfc_soft_wwnn,
&class_device_attr_lpfc_soft_wwpn,
- &class_device_attr_lpfc_soft_wwpn_enable,
+ &class_device_attr_lpfc_soft_wwn_enable,
NULL,
};
@@ -1771,6 +1861,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_cr_delay_init(phba, lpfc_cr_delay);
lpfc_cr_count_init(phba, lpfc_cr_count);
lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
+ lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
+ lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
lpfc_fcp_class_init(phba, lpfc_fcp_class);
lpfc_use_adisc_init(phba, lpfc_use_adisc);
@@ -1782,9 +1874,11 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
lpfc_max_luns_init(phba, lpfc_max_luns);
lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
+ lpfc_use_msi_init(phba, lpfc_use_msi);
lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
phba->cfg_poll = lpfc_poll;
+ phba->cfg_soft_wwnn = 0L;
phba->cfg_soft_wwpn = 0L;
/*
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 3add7c237859..a51a41b7f15d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -558,6 +558,14 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
return;
}
+static void
+lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+ struct lpfc_iocbq * rspiocb)
+{
+ lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+ return;
+}
+
void
lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp)
{
@@ -629,6 +637,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
bpl->tus.f.bdeSize = RNN_REQUEST_SZ;
else if (cmdcode == SLI_CTNS_RSNN_NN)
bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
+ else if (cmdcode == SLI_CTNS_RFF_ID)
+ bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
else
bpl->tus.f.bdeSize = 0;
bpl->tus.w = le32_to_cpu(bpl->tus.w);
@@ -660,6 +670,17 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
cmpl = lpfc_cmpl_ct_cmd_rft_id;
break;
+ case SLI_CTNS_RFF_ID:
+ CtReq->CommandResponse.bits.CmdRsp =
+ be16_to_cpu(SLI_CTNS_RFF_ID);
+ CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID);
+ CtReq->un.rff.feature_res = 0;
+ CtReq->un.rff.feature_tgt = 0;
+ CtReq->un.rff.type_code = FC_FCP_DATA;
+ CtReq->un.rff.feature_init = 1;
+ cmpl = lpfc_cmpl_ct_cmd_rff_id;
+ break;
+
case SLI_CTNS_RNN_ID:
CtReq->CommandResponse.bits.CmdRsp =
be16_to_cpu(SLI_CTNS_RNN_ID);
@@ -934,7 +955,8 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
sprintf(ae->un.OsNameVersion, "%s %s %s",
- init_utsname()->sysname, init_utsname()->release,
+ init_utsname()->sysname,
+ init_utsname()->release,
init_utsname()->version);
len = strlen(ae->un.OsNameVersion);
len += (len & 3) ? (4 - (len & 3)) : 4;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 71864cdc6c71..a5f33a0dd4e7 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -243,6 +243,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
struct serv_parm *sp, IOCB_t *irsp)
{
LPFC_MBOXQ_t *mbox;
+ struct lpfc_dmabuf *mp;
int rc;
spin_lock_irq(phba->host->host_lock);
@@ -307,10 +308,14 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
if (rc == MBX_NOT_FINISHED)
- goto fail_free_mbox;
+ goto fail_issue_reg_login;
return 0;
+ fail_issue_reg_login:
+ mp = (struct lpfc_dmabuf *) mbox->context1;
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
fail_free_mbox:
mempool_free(mbox, phba->mbox_mem_pool);
fail:
@@ -657,6 +662,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
uint8_t name[sizeof (struct lpfc_name)];
uint32_t rc;
+ /* Fabric nodes can have the same WWPN so we don't bother searching
+ * by WWPN. Just return the ndlp that was given to us.
+ */
+ if (ndlp->nlp_type & NLP_FABRIC)
+ return ndlp;
+
lp = (uint32_t *) prsp->virt;
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
memset(name, 0, sizeof (struct lpfc_name));
@@ -1122,7 +1133,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
mempool_free(mbox,
phba->mbox_mem_pool);
lpfc_disc_flush_list(phba);
- psli->ring[(psli->ip_ring)].
+ psli->ring[(psli->extra_ring)].
flag &=
~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].
@@ -1851,6 +1862,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
IOCB_t *irsp;
struct lpfc_nodelist *ndlp;
LPFC_MBOXQ_t *mbox = NULL;
+ struct lpfc_dmabuf *mp;
irsp = &rspiocb->iocb;
@@ -1862,6 +1874,11 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
/* Check to see if link went down during discovery */
if ((lpfc_els_chk_latt(phba)) || !ndlp) {
if (mbox) {
+ mp = (struct lpfc_dmabuf *) mbox->context1;
+ if (mp) {
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ }
mempool_free( mbox, phba->mbox_mem_pool);
}
goto out;
@@ -1893,9 +1910,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
}
/* NOTE: we should have messages for unsuccessful
reglogin */
- mempool_free( mbox, phba->mbox_mem_pool);
} else {
- mempool_free( mbox, phba->mbox_mem_pool);
/* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */
if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
@@ -1907,6 +1922,12 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
}
}
}
+ mp = (struct lpfc_dmabuf *) mbox->context1;
+ if (mp) {
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ }
+ mempool_free(mbox, phba->mbox_mem_pool);
}
out:
if (ndlp) {
@@ -2644,6 +2665,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_prev_state = ndlp->nlp_state;
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
+ lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
lpfc_issue_els_plogi(phba, NameServer_DID, 0);
/* Wait for NameServer login cmpl before we can
continue */
@@ -3039,7 +3061,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
/* FARP-REQ received from DID <did> */
lpfc_printf_log(phba,
KERN_INFO,
- LOG_IP,
+ LOG_ELS,
"%d:0601 FARP-REQ received from DID x%x\n",
phba->brd_no, did);
@@ -3101,7 +3123,7 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba,
/* FARP-RSP received from DID <did> */
lpfc_printf_log(phba,
KERN_INFO,
- LOG_IP,
+ LOG_ELS,
"%d:0600 FARP-RSP received from DID x%x\n",
phba->brd_no, did);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 19c79a0549a7..c39564e85e94 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -525,7 +525,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
psli = &phba->sli;
mb = &pmb->mb;
/* Since we don't do discovery right now, turn these off here */
- psli->ring[psli->ip_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
+ psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
@@ -641,7 +641,7 @@ out:
if (rc == MBX_NOT_FINISHED) {
mempool_free(pmb, phba->mbox_mem_pool);
lpfc_disc_flush_list(phba);
- psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
+ psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
phba->hba_state = LPFC_HBA_READY;
@@ -672,6 +672,8 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,
sizeof (struct serv_parm));
+ if (phba->cfg_soft_wwnn)
+ u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
if (phba->cfg_soft_wwpn)
u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
memcpy((uint8_t *) & phba->fc_nodename,
@@ -696,7 +698,7 @@ out:
== MBX_NOT_FINISHED) {
mempool_free( pmb, phba->mbox_mem_pool);
lpfc_disc_flush_list(phba);
- psli->ring[(psli->ip_ring)].flag &=
+ psli->ring[(psli->extra_ring)].flag &=
~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].flag &=
~LPFC_STOP_IOCB_EVENT;
@@ -715,6 +717,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
{
int i;
LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;
+ struct lpfc_dmabuf *mp;
+ int rc;
+
sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -793,16 +798,27 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
if (sparam_mbox) {
lpfc_read_sparam(phba, sparam_mbox);
sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
- lpfc_sli_issue_mbox(phba, sparam_mbox,
+ rc = lpfc_sli_issue_mbox(phba, sparam_mbox,
(MBX_NOWAIT | MBX_STOP_IOCB));
+ if (rc == MBX_NOT_FINISHED) {
+ mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ mempool_free(sparam_mbox, phba->mbox_mem_pool);
+ if (cfglink_mbox)
+ mempool_free(cfglink_mbox, phba->mbox_mem_pool);
+ return;
+ }
}
if (cfglink_mbox) {
phba->hba_state = LPFC_LOCAL_CFG_LINK;
lpfc_config_link(phba, cfglink_mbox);
cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
- lpfc_sli_issue_mbox(phba, cfglink_mbox,
+ rc = lpfc_sli_issue_mbox(phba, cfglink_mbox,
(MBX_NOWAIT | MBX_STOP_IOCB));
+ if (rc == MBX_NOT_FINISHED)
+ mempool_free(cfglink_mbox, phba->mbox_mem_pool);
}
}
@@ -1067,6 +1083,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID);
lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN);
lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID);
+ lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID);
}
phba->fc_ns_retry = 0;
@@ -1423,7 +1440,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
if (iocb->context1 == (uint8_t *) ndlp)
return 1;
}
- } else if (pring->ringno == psli->ip_ring) {
+ } else if (pring->ringno == psli->extra_ring) {
} else if (pring->ringno == psli->fcp_ring) {
/* Skip match check if waiting to relogin to FCP target */
@@ -1680,112 +1697,38 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
struct lpfc_nodelist *
lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
{
- struct lpfc_nodelist *ndlp, *next_ndlp;
+ struct lpfc_nodelist *ndlp;
+ struct list_head *lists[]={&phba->fc_nlpunmap_list,
+ &phba->fc_nlpmap_list,
+ &phba->fc_plogi_list,
+ &phba->fc_adisc_list,
+ &phba->fc_reglogin_list,
+ &phba->fc_prli_list,
+ &phba->fc_npr_list,
+ &phba->fc_unused_list};
+ uint32_t search[]={NLP_SEARCH_UNMAPPED,
+ NLP_SEARCH_MAPPED,
+ NLP_SEARCH_PLOGI,
+ NLP_SEARCH_ADISC,
+ NLP_SEARCH_REGLOGIN,
+ NLP_SEARCH_PRLI,
+ NLP_SEARCH_NPR,
+ NLP_SEARCH_UNUSED};
+ int i;
uint32_t data1;
spin_lock_irq(phba->host->host_lock);
- if (order & NLP_SEARCH_UNMAPPED) {
- list_for_each_entry_safe(ndlp, next_ndlp,
- &phba->fc_nlpunmap_list, nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* FIND node DID unmapped */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0929 FIND node DID unmapped"
- " Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_MAPPED) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* FIND node DID mapped */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0930 FIND node DID mapped "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_PLOGI) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to PLOGI */
- /* FIND node DID plogi */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0908 FIND node DID plogi "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_ADISC) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to ADISC */
- /* FIND node DID adisc */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0931 FIND node DID adisc "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_REGLOGIN) {
- list_for_each_entry_safe(ndlp, next_ndlp,
- &phba->fc_reglogin_list, nlp_listp) {
+ for (i = 0; i < ARRAY_SIZE(lists); i++ ) {
+ if (!(order & search[i]))
+ continue;
+ list_for_each_entry(ndlp, lists[i], nlp_listp) {
if (lpfc_matchdid(phba, ndlp, did)) {
-
data1 = (((uint32_t) ndlp->nlp_state << 24) |
((uint32_t) ndlp->nlp_xri << 16) |
((uint32_t) ndlp->nlp_type << 8) |
((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to REGLOGIN */
- /* FIND node DID reglogin */
lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0901 FIND node DID reglogin"
+ "%d:0929 FIND node DID "
" Data: x%p x%x x%x x%x\n",
phba->brd_no,
ndlp, ndlp->nlp_DID,
@@ -1795,86 +1738,12 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
}
}
}
-
- if (order & NLP_SEARCH_PRLI) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to PRLI */
- /* FIND node DID prli */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0902 FIND node DID prli "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_NPR) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to NPR */
- /* FIND node DID npr */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0903 FIND node DID npr "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
- if (order & NLP_SEARCH_UNUSED) {
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
- nlp_listp) {
- if (lpfc_matchdid(phba, ndlp, did)) {
-
- data1 = (((uint32_t) ndlp->nlp_state << 24) |
- ((uint32_t) ndlp->nlp_xri << 16) |
- ((uint32_t) ndlp->nlp_type << 8) |
- ((uint32_t) ndlp->nlp_rpi & 0xff));
- /* LOG change to UNUSED */
- /* FIND node DID unused */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d:0905 FIND node DID unused "
- "Data: x%p x%x x%x x%x\n",
- phba->brd_no,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
- spin_unlock_irq(phba->host->host_lock);
- return ndlp;
- }
- }
- }
-
spin_unlock_irq(phba->host->host_lock);
/* FIND node did <did> NOT FOUND */
- lpfc_printf_log(phba,
- KERN_INFO,
- LOG_NODE,
+ lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
"%d:0932 FIND node did x%x NOT FOUND Data: x%x\n",
phba->brd_no, did, order);
-
- /* no match found */
return NULL;
}
@@ -2036,7 +1905,7 @@ lpfc_disc_start(struct lpfc_hba * phba)
if (rc == MBX_NOT_FINISHED) {
mempool_free( mbox, phba->mbox_mem_pool);
lpfc_disc_flush_list(phba);
- psli->ring[(psli->ip_ring)].flag &=
+ psli->ring[(psli->extra_ring)].flag &=
~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].flag &=
~LPFC_STOP_IOCB_EVENT;
@@ -2415,7 +2284,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
if (clrlaerr) {
lpfc_disc_flush_list(phba);
- psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
+ psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
phba->hba_state = LPFC_HBA_READY;
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index eedf98801366..f79cb6136906 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -42,14 +42,14 @@
#define FCELSSIZE 1024 /* maximum ELS transfer size */
#define LPFC_FCP_RING 0 /* ring 0 for FCP initiator commands */
-#define LPFC_IP_RING 1 /* ring 1 for IP commands */
+#define LPFC_EXTRA_RING 1 /* ring 1 for other protocols */
#define LPFC_ELS_RING 2 /* ring 2 for ELS commands */
#define LPFC_FCP_NEXT_RING 3
#define SLI2_IOCB_CMD_R0_ENTRIES 172 /* SLI-2 FCP command ring entries */
#define SLI2_IOCB_RSP_R0_ENTRIES 134 /* SLI-2 FCP response ring entries */
-#define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 IP command ring entries */
-#define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 IP response ring entries */
+#define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 extra command ring entries */
+#define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 extra response ring entries */
#define SLI2_IOCB_CMD_R1XTRA_ENTRIES 36 /* SLI-2 extra FCP cmd ring entries */
#define SLI2_IOCB_RSP_R1XTRA_ENTRIES 52 /* SLI-2 extra FCP rsp ring entries */
#define SLI2_IOCB_CMD_R2_ENTRIES 20 /* SLI-2 ELS command ring entries */
@@ -121,6 +121,20 @@ struct lpfc_sli_ct_request {
uint32_t rsvd[7];
} rft;
+ struct rff {
+ uint32_t PortId;
+ uint8_t reserved[2];
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint8_t feature_res:6;
+ uint8_t feature_init:1;
+ uint8_t feature_tgt:1;
+#else /* __LITTLE_ENDIAN_BITFIELD */
+ uint8_t feature_tgt:1;
+ uint8_t feature_init:1;
+ uint8_t feature_res:6;
+#endif
+ uint8_t type_code; /* type=8 for FCP */
+ } rff;
struct rnn {
uint32_t PortId; /* For RNN_ID requests */
uint8_t wwnn[8];
@@ -136,6 +150,7 @@ struct lpfc_sli_ct_request {
#define SLI_CT_REVISION 1
#define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260)
#define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228)
+#define RFF_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 235)
#define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252)
#define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request))
@@ -225,6 +240,7 @@ struct lpfc_sli_ct_request {
#define SLI_CTNS_RNN_ID 0x0213
#define SLI_CTNS_RCS_ID 0x0214
#define SLI_CTNS_RFT_ID 0x0217
+#define SLI_CTNS_RFF_ID 0x021F
#define SLI_CTNS_RSPN_ID 0x0218
#define SLI_CTNS_RPT_ID 0x021A
#define SLI_CTNS_RIP_NN 0x0235
@@ -1089,12 +1105,6 @@ typedef struct {
#define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11
#define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12
-#define PCI_SUBSYSTEM_ID_LP11000S 0xfc11
-#define PCI_SUBSYSTEM_ID_LP11002S 0xfc12
-#define PCI_SUBSYSTEM_ID_LPE11000S 0xfc21
-#define PCI_SUBSYSTEM_ID_LPE11002S 0xfc22
-#define PCI_SUBSYSTEM_ID_LPE11010S 0xfc2A
-
#define JEDEC_ID_ADDRESS 0x0080001c
#define FIREFLY_JEDEC_ID 0x1ACC
#define SUPERFLY_JEDEC_ID 0x0020
@@ -1284,6 +1294,10 @@ typedef struct { /* FireFly BIU registers */
#define CMD_FCP_IREAD_CX 0x1B
#define CMD_FCP_ICMND_CR 0x1C
#define CMD_FCP_ICMND_CX 0x1D
+#define CMD_FCP_TSEND_CX 0x1F
+#define CMD_FCP_TRECEIVE_CX 0x21
+#define CMD_FCP_TRSP_CX 0x23
+#define CMD_FCP_AUTO_TRSP_CX 0x29
#define CMD_ADAPTER_MSG 0x20
#define CMD_ADAPTER_DUMP 0x22
@@ -1310,6 +1324,9 @@ typedef struct { /* FireFly BIU registers */
#define CMD_FCP_IREAD64_CX 0x9B
#define CMD_FCP_ICMND64_CR 0x9C
#define CMD_FCP_ICMND64_CX 0x9D
+#define CMD_FCP_TSEND64_CX 0x9F
+#define CMD_FCP_TRECEIVE64_CX 0xA1
+#define CMD_FCP_TRSP64_CX 0xA3
#define CMD_GEN_REQUEST64_CR 0xC2
#define CMD_GEN_REQUEST64_CX 0xC3
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index a5723ad0a099..afca45cdbcef 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -268,6 +268,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
kfree(mp);
pmb->context1 = NULL;
+ if (phba->cfg_soft_wwnn)
+ u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
if (phba->cfg_soft_wwpn)
u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName,
@@ -349,8 +351,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
phba->hba_state = LPFC_LINK_DOWN;
/* Only process IOCBs on ring 0 till hba_state is READY */
- if (psli->ring[psli->ip_ring].cmdringaddr)
- psli->ring[psli->ip_ring].flag |= LPFC_STOP_IOCB_EVENT;
+ if (psli->ring[psli->extra_ring].cmdringaddr)
+ psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT;
if (psli->ring[psli->fcp_ring].cmdringaddr)
psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT;
if (psli->ring[psli->next_ring].cmdringaddr)
@@ -517,7 +519,8 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
struct lpfc_sli_ring *pring;
uint32_t event_data;
- if (phba->work_hs & HS_FFER6) {
+ if (phba->work_hs & HS_FFER6 ||
+ phba->work_hs & HS_FFER5) {
/* Re-establishing Link */
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
"%d:1301 Re-establishing Link "
@@ -611,7 +614,7 @@ lpfc_handle_latt(struct lpfc_hba * phba)
pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
if (rc == MBX_NOT_FINISHED)
- goto lpfc_handle_latt_free_mp;
+ goto lpfc_handle_latt_free_mbuf;
/* Clear Link Attention in HA REG */
spin_lock_irq(phba->host->host_lock);
@@ -621,6 +624,8 @@ lpfc_handle_latt(struct lpfc_hba * phba)
return;
+lpfc_handle_latt_free_mbuf:
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
lpfc_handle_latt_free_mp:
kfree(mp);
lpfc_handle_latt_free_pmb:
@@ -802,19 +807,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
{
lpfc_vpd_t *vp;
uint16_t dev_id = phba->pcidev->device;
- uint16_t dev_subid = phba->pcidev->subsystem_device;
- uint8_t hdrtype;
int max_speed;
- char * ports;
struct {
char * name;
int max_speed;
- char * ports;
char * bus;
- } m = {"<Unknown>", 0, "", ""};
+ } m = {"<Unknown>", 0, ""};
- pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
- ports = (hdrtype == 0x80) ? "2-port " : "";
if (mdp && mdp[0] != '\0'
&& descp && descp[0] != '\0')
return;
@@ -834,130 +833,93 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
switch (dev_id) {
case PCI_DEVICE_ID_FIREFLY:
- m = (typeof(m)){"LP6000", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP6000", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_SUPERFLY:
if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
- m = (typeof(m)){"LP7000", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP7000", max_speed, "PCI"};
else
- m = (typeof(m)){"LP7000E", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP7000E", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_DRAGONFLY:
- m = (typeof(m)){"LP8000", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP8000", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_CENTAUR:
if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
- m = (typeof(m)){"LP9002", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP9002", max_speed, "PCI"};
else
- m = (typeof(m)){"LP9000", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP9000", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_RFLY:
- m = (typeof(m)){"LP952", max_speed, "", "PCI"};
+ m = (typeof(m)){"LP952", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_PEGASUS:
- m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"};
+ m = (typeof(m)){"LP9802", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_THOR:
- if (hdrtype == 0x80)
- m = (typeof(m)){"LP10000DC",
- max_speed, ports, "PCI-X"};
- else
- m = (typeof(m)){"LP10000",
- max_speed, ports, "PCI-X"};
+ m = (typeof(m)){"LP10000", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_VIPER:
- m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"};
+ m = (typeof(m)){"LPX1000", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_PFLY:
- m = (typeof(m)){"LP982", max_speed, "", "PCI-X"};
+ m = (typeof(m)){"LP982", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_TFLY:
- if (hdrtype == 0x80)
- m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"};
- else
- m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"};
+ m = (typeof(m)){"LP1050", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_HELIOS:
- if (hdrtype == 0x80)
- m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"};
- else
- m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"};
+ m = (typeof(m)){"LP11000", max_speed, "PCI-X2"};
break;
case PCI_DEVICE_ID_HELIOS_SCSP:
- m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"};
+ m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"};
break;
case PCI_DEVICE_ID_HELIOS_DCSP:
- m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"};
+ m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"};
break;
case PCI_DEVICE_ID_NEPTUNE:
- if (hdrtype == 0x80)
- m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"};
- else
- m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe1000", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_NEPTUNE_SCSP:
- m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_NEPTUNE_DCSP:
- m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_BMID:
- m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"};
+ m = (typeof(m)){"LP1150", max_speed, "PCI-X2"};
break;
case PCI_DEVICE_ID_BSMB:
- m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"};
+ m = (typeof(m)){"LP111", max_speed, "PCI-X2"};
break;
case PCI_DEVICE_ID_ZEPHYR:
- if (hdrtype == 0x80)
- m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"};
- else
- m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_ZEPHYR_SCSP:
- m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_ZEPHYR_DCSP:
- m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe11002-SP", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_ZMID:
- m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe1150", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_ZSMB:
- m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"};
+ m = (typeof(m)){"LPe111", max_speed, "PCIe"};
break;
case PCI_DEVICE_ID_LP101:
- m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"};
+ m = (typeof(m)){"LP101", max_speed, "PCI-X"};
break;
case PCI_DEVICE_ID_LP10000S:
- m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"};
+ m = (typeof(m)){"LP10000-S", max_speed, "PCI"};
break;
case PCI_DEVICE_ID_LP11000S:
+ m = (typeof(m)){"LP11000-S", max_speed,
+ "PCI-X2"};
+ break;
case PCI_DEVICE_ID_LPE11000S:
- switch (dev_subid) {
- case PCI_SUBSYSTEM_ID_LP11000S:
- m = (typeof(m)){"LP11000-S", max_speed,
- ports, "PCI-X2"};
- break;
- case PCI_SUBSYSTEM_ID_LP11002S:
- m = (typeof(m)){"LP11002-S", max_speed,
- ports, "PCI-X2"};
- break;
- case PCI_SUBSYSTEM_ID_LPE11000S:
- m = (typeof(m)){"LPe11000-S", max_speed,
- ports, "PCIe"};
- break;
- case PCI_SUBSYSTEM_ID_LPE11002S:
- m = (typeof(m)){"LPe11002-S", max_speed,
- ports, "PCIe"};
- break;
- case PCI_SUBSYSTEM_ID_LPE11010S:
- m = (typeof(m)){"LPe11010-S", max_speed,
- "10-port ", "PCIe"};
- break;
- default:
- m = (typeof(m)){ NULL };
- break;
- }
+ m = (typeof(m)){"LPe11000-S", max_speed,
+ "PCIe"};
break;
default:
m = (typeof(m)){ NULL };
@@ -968,8 +930,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
snprintf(mdp, 79,"%s", m.name);
if (descp && descp[0] == '\0')
snprintf(descp, 255,
- "Emulex %s %dGb %s%s Fibre Channel Adapter",
- m.name, m.max_speed, m.ports, m.bus);
+ "Emulex %s %dGb %s Fibre Channel Adapter",
+ m.name, m.max_speed, m.bus);
}
/**************************************************/
@@ -1651,6 +1613,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
if (error)
goto out_remove_host;
+ if (phba->cfg_use_msi) {
+ error = pci_enable_msi(phba->pcidev);
+ if (error)
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0452 "
+ "Enable MSI failed, continuing with "
+ "IRQ\n", phba->brd_no);
+ }
+
error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED,
LPFC_DRIVER_NAME, phba);
if (error) {
@@ -1730,6 +1700,7 @@ out_free_irq:
lpfc_stop_timer(phba);
phba->work_hba_events = 0;
free_irq(phba->pcidev->irq, phba);
+ pci_disable_msi(phba->pcidev);
out_free_sysfs_attr:
lpfc_free_sysfs_attr(phba);
out_remove_host:
@@ -1796,6 +1767,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
/* Release the irq reservation */
free_irq(phba->pcidev->irq, phba);
+ pci_disable_msi(phba->pcidev);
lpfc_cleanup(phba, 0);
lpfc_stop_timer(phba);
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index 62c8ca862e9e..438cbcd9eb13 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -28,7 +28,7 @@
#define LOG_NODE 0x80 /* Node table events */
#define LOG_MISC 0x400 /* Miscellaneous events */
#define LOG_SLI 0x800 /* SLI events */
-#define LOG_CHK_COND 0x1000 /* FCP Check condition flag */
+#define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */
#define LOG_LIBDFC 0x2000 /* Libdfc events */
#define LOG_ALL_MSG 0xffff /* LOG all messages */
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d5f415007db2..0c7e731dc45a 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -739,7 +739,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
uint32_t evt)
{
struct lpfc_iocbq *cmdiocb, *rspiocb;
- struct lpfc_dmabuf *pcmd, *prsp;
+ struct lpfc_dmabuf *pcmd, *prsp, *mp;
uint32_t *lp;
IOCB_t *irsp;
struct serv_parm *sp;
@@ -829,6 +829,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
NLP_REGLOGIN_LIST);
return ndlp->nlp_state;
}
+ mp = (struct lpfc_dmabuf *)mbox->context1;
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
mempool_free(mbox, phba->mbox_mem_pool);
} else {
mempool_free(mbox, phba->mbox_mem_pool);
@@ -1620,8 +1623,8 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
* or discovery in progress for this node. Starting discovery
* here will affect the counting of discovery threads.
*/
- if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) &&
- (ndlp->nlp_flag & NLP_NPR_2B_DISC)){
+ if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
+ !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){
if (ndlp->nlp_flag & NLP_NPR_ADISC) {
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 97ae98dc95d0..c3e68e0d8f74 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -297,8 +297,10 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm;
uint32_t resp_info = fcprsp->rspStatus2;
uint32_t scsi_status = fcprsp->rspStatus3;
+ uint32_t *lp;
uint32_t host_status = DID_OK;
uint32_t rsplen = 0;
+ uint32_t logit = LOG_FCP | LOG_FCP_ERROR;
/*
* If this is a task management command, there is no
@@ -310,10 +312,25 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
goto out;
}
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d:0730 FCP command failed: RSP "
- "Data: x%x x%x x%x x%x x%x x%x\n",
- phba->brd_no, resp_info, scsi_status,
+ if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
+ uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
+ if (snslen > SCSI_SENSE_BUFFERSIZE)
+ snslen = SCSI_SENSE_BUFFERSIZE;
+
+ if (resp_info & RSP_LEN_VALID)
+ rsplen = be32_to_cpu(fcprsp->rspRspLen);
+ memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen);
+ }
+ lp = (uint32_t *)cmnd->sense_buffer;
+
+ if (!scsi_status && (resp_info & RESID_UNDER))
+ logit = LOG_FCP;
+
+ lpfc_printf_log(phba, KERN_WARNING, logit,
+ "%d:0730 FCP command x%x failed: x%x SNS x%x x%x "
+ "Data: x%x x%x x%x x%x x%x\n",
+ phba->brd_no, cmnd->cmnd[0], scsi_status,
+ be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info,
be32_to_cpu(fcprsp->rspResId),
be32_to_cpu(fcprsp->rspSnsLen),
be32_to_cpu(fcprsp->rspRspLen),
@@ -328,14 +345,6 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
}
}
- if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
- uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
- if (snslen > SCSI_SENSE_BUFFERSIZE)
- snslen = SCSI_SENSE_BUFFERSIZE;
-
- memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen);
- }
-
cmnd->resid = 0;
if (resp_info & RESID_UNDER) {
cmnd->resid = be32_to_cpu(fcprsp->rspResId);
@@ -378,7 +387,7 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
*/
} else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm &&
(cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
"%d:0734 FCP Read Check Error Data: "
"x%x x%x x%x x%x\n", phba->brd_no,
be32_to_cpu(fcpcmd->fcpDl),
@@ -670,6 +679,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
struct lpfc_iocbq *iocbqrsp;
int ret;
+ if (!rdata->pnode)
+ return FAILED;
+
lpfc_cmd->rdata = rdata;
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
FCP_TARGET_RESET);
@@ -976,20 +988,34 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
lpfc_block_error_handler(cmnd);
spin_lock_irq(shost->host_lock);
+ loopcnt = 0;
/*
* If target is not in a MAPPED state, delay the reset until
* target is rediscovered or devloss timeout expires.
*/
while ( 1 ) {
if (!pnode)
- break;
+ return FAILED;
if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
spin_unlock_irq(phba->host->host_lock);
schedule_timeout_uninterruptible(msecs_to_jiffies(500));
spin_lock_irq(phba->host->host_lock);
+ loopcnt++;
+ rdata = cmnd->device->hostdata;
+ if (!rdata ||
+ (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+ "%d:0721 LUN Reset rport failure:"
+ " cnt x%x rdata x%p\n",
+ phba->brd_no, loopcnt, rdata);
+ goto out;
+ }
+ pnode = rdata->pnode;
+ if (!pnode)
+ return FAILED;
}
- if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE))
+ if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
break;
}
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 582f5ea4e84e..a4128e19338a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -117,6 +117,10 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd)
case CMD_FCP_IREAD_CX:
case CMD_FCP_ICMND_CR:
case CMD_FCP_ICMND_CX:
+ case CMD_FCP_TSEND_CX:
+ case CMD_FCP_TRSP_CX:
+ case CMD_FCP_TRECEIVE_CX:
+ case CMD_FCP_AUTO_TRSP_CX:
case CMD_ADAPTER_MSG:
case CMD_ADAPTER_DUMP:
case CMD_XMIT_SEQUENCE64_CR:
@@ -131,6 +135,9 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd)
case CMD_FCP_IREAD64_CX:
case CMD_FCP_ICMND64_CR:
case CMD_FCP_ICMND64_CX:
+ case CMD_FCP_TSEND64_CX:
+ case CMD_FCP_TRSP64_CX:
+ case CMD_FCP_TRECEIVE64_CX:
case CMD_GEN_REQUEST64_CR:
case CMD_GEN_REQUEST64_CX:
case CMD_XMIT_ELS_RSP64_CX:
@@ -1098,6 +1105,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
lpfc_sli_pcimem_bcopy((uint32_t *) entry,
(uint32_t *) &rspiocbq.iocb,
sizeof (IOCB_t));
+ INIT_LIST_HEAD(&(rspiocbq.list));
irsp = &rspiocbq.iocb;
type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
@@ -1149,6 +1157,11 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
}
}
break;
+ case LPFC_UNSOL_IOCB:
+ spin_unlock_irqrestore(phba->host->host_lock, iflag);
+ lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq);
+ spin_lock_irqsave(phba->host->host_lock, iflag);
+ break;
default:
if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
char adaptermsg[LPFC_MAX_ADPTMSG];
@@ -2472,13 +2485,17 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
psli = &phba->sli;
/* Adjust cmd/rsp ring iocb entries more evenly */
+
+ /* Take some away from the FCP ring */
pring = &psli->ring[psli->fcp_ring];
pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
- pring = &psli->ring[1];
+ /* and give them to the extra ring */
+ pring = &psli->ring[psli->extra_ring];
+
pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
@@ -2488,8 +2505,8 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
pring->iotag_max = 4096;
pring->num_mask = 1;
pring->prt[0].profile = 0; /* Mask 0 */
- pring->prt[0].rctl = FC_UNSOL_DATA;
- pring->prt[0].type = 5;
+ pring->prt[0].rctl = phba->cfg_multi_ring_rctl;
+ pring->prt[0].type = phba->cfg_multi_ring_type;
pring->prt[0].lpfc_sli_rcv_unsol_event = NULL;
return 0;
}
@@ -2505,7 +2522,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
psli->sli_flag = 0;
psli->fcp_ring = LPFC_FCP_RING;
psli->next_ring = LPFC_FCP_NEXT_RING;
- psli->ip_ring = LPFC_IP_RING;
+ psli->extra_ring = LPFC_EXTRA_RING;
psli->iocbq_lookup = NULL;
psli->iocbq_lookup_len = 0;
@@ -2528,7 +2545,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
pring->fast_iotag = pring->iotag_max;
pring->num_mask = 0;
break;
- case LPFC_IP_RING: /* ring 1 - IP */
+ case LPFC_EXTRA_RING: /* ring 1 - EXTRA */
/* numCiocb and numRiocb are used in config_port */
pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES;
pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES;
@@ -3238,6 +3255,21 @@ lpfc_intr_handler(int irq, void *dev_id)
lpfc_sli_handle_fast_ring_event(phba,
&phba->sli.ring[LPFC_FCP_RING],
status);
+
+ if (phba->cfg_multi_ring_support == 2) {
+ /*
+ * Process all events on extra ring. Take the optimized path
+ * for extra ring IO. Any other IO is slow path and is handled
+ * by the worker thread.
+ */
+ status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
+ status >>= (4*LPFC_EXTRA_RING);
+ if (status & HA_RXATT) {
+ lpfc_sli_handle_fast_ring_event(phba,
+ &phba->sli.ring[LPFC_EXTRA_RING],
+ status);
+ }
+ }
return IRQ_HANDLED;
} /* lpfc_intr_handler */
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index e26de6809358..a43549959dc7 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -198,7 +198,7 @@ struct lpfc_sli {
int fcp_ring; /* ring used for FCP initiator commands */
int next_ring;
- int ip_ring; /* ring used for IP network drv cmds */
+ int extra_ring; /* extra ring used for other protocols */
struct lpfc_sli_stat slistat; /* SLI statistical info */
struct list_head mboxq;
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index ac417908b407..a61ef3d1e7f1 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.1.10"
+#define LPFC_DRIVER_VERSION "8.1.11"
#define LPFC_DRIVER_NAME "lpfc"
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 86099fde1b2a..77d9d3804ccf 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -73,10 +73,10 @@ static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT;
module_param(max_mbox_busy_wait, ushort, 0);
MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)");
-#define RDINDOOR(adapter) readl((adapter)->base + 0x20)
-#define RDOUTDOOR(adapter) readl((adapter)->base + 0x2C)
-#define WRINDOOR(adapter,value) writel(value, (adapter)->base + 0x20)
-#define WROUTDOOR(adapter,value) writel(value, (adapter)->base + 0x2C)
+#define RDINDOOR(adapter) readl((adapter)->mmio_base + 0x20)
+#define RDOUTDOOR(adapter) readl((adapter)->mmio_base + 0x2C)
+#define WRINDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x20)
+#define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C)
/*
* Global variables
@@ -1386,7 +1386,8 @@ megaraid_isr_memmapped(int irq, void *devp)
handled = 1;
- while( RDINDOOR(adapter) & 0x02 ) cpu_relax();
+ while( RDINDOOR(adapter) & 0x02 )
+ cpu_relax();
mega_cmd_done(adapter, completed, nstatus, status);
@@ -4668,6 +4669,8 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
host->host_no, mega_baseport, irq);
adapter->base = mega_baseport;
+ if (flag & BOARD_MEMMAP)
+ adapter->mmio_base = (void __iomem *) mega_baseport;
INIT_LIST_HEAD(&adapter->free_list);
INIT_LIST_HEAD(&adapter->pending_list);
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 66529f11d23c..c6e74643abe2 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -801,7 +801,8 @@ typedef struct {
clustering is available */
u32 flag;
- unsigned long base;
+ unsigned long base;
+ void __iomem *mmio_base;
/* mbox64 with mbox not aligned on 16-byte boundry */
mbox64_t *una_mbox64;
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7e4262f2af96..046223b4ae57 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -517,7 +517,7 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
* Returns the number of frames required for numnber of sge's (sge_count)
*/
-u32 megasas_get_frame_count(u8 sge_count)
+static u32 megasas_get_frame_count(u8 sge_count)
{
int num_cnt;
int sge_bytes;
@@ -1733,7 +1733,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
*
* Tasklet to complete cmds
*/
-void megasas_complete_cmd_dpc(unsigned long instance_addr)
+static void megasas_complete_cmd_dpc(unsigned long instance_addr)
{
u32 producer;
u32 consumer;
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index adb8eb4f5fd1..bbf521cbc55d 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -589,10 +589,12 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
static struct ncr_driver_setup
driver_setup = SCSI_NCR_DRIVER_SETUP;
+#ifndef MODULE
#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
static struct ncr_driver_setup
driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP;
#endif
+#endif /* !MODULE */
#define initverbose (driver_setup.verbose)
#define bootverbose (np->verbose)
@@ -641,6 +643,13 @@ static struct ncr_driver_setup
#define OPT_IARB 26
#endif
+#ifdef MODULE
+#define ARG_SEP ' '
+#else
+#define ARG_SEP ','
+#endif
+
+#ifndef MODULE
static char setup_token[] __initdata =
"tags:" "mpar:"
"spar:" "disc:"
@@ -660,12 +669,6 @@ static char setup_token[] __initdata =
#endif
; /* DONNOT REMOVE THIS ';' */
-#ifdef MODULE
-#define ARG_SEP ' '
-#else
-#define ARG_SEP ','
-#endif
-
static int __init get_setup_token(char *p)
{
char *cur = setup_token;
@@ -682,7 +685,6 @@ static int __init get_setup_token(char *p)
return 0;
}
-
static int __init sym53c8xx__setup(char *str)
{
#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
@@ -804,6 +806,7 @@ static int __init sym53c8xx__setup(char *str)
#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
return 1;
}
+#endif /* !MODULE */
/*===================================================================
**
@@ -8321,12 +8324,12 @@ char *ncr53c8xx; /* command line passed by insmod */
module_param(ncr53c8xx, charp, 0);
#endif
+#ifndef MODULE
static int __init ncr53c8xx_setup(char *str)
{
return sym53c8xx__setup(str);
}
-#ifndef MODULE
__setup("ncr53c8xx=", ncr53c8xx_setup);
#endif
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index dd67a68c5c23..c116a6ae3c54 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -72,12 +72,12 @@ static void dma_advance_sg(Scsi_Cmnd *);
static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x);
#ifdef USE_BOTTOM_HALF
-static void dma_commit(void *opaque);
+static void dma_commit(struct work_struct *unused);
long oktag_to_io(long *paddr, long *addr, long len);
long oktag_from_io(long *addr, long *paddr, long len);
-static DECLARE_WORK(tq_fake_dma, dma_commit, NULL);
+static DECLARE_WORK(tq_fake_dma, dma_commit);
#define DMA_MAXTRANSFER 0x8000
@@ -266,7 +266,7 @@ oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x)
*/
-static void dma_commit(void *opaque)
+static void dma_commit(struct work_struct *unused)
{
long wait,len2,pos;
struct NCR_ESP *esp;
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index ee449b29fc82..aad362ba02e0 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -154,16 +154,11 @@ static int aha152x_config_cs(struct pcmcia_device *link)
DEBUG(0, "aha152x_config(0x%p)\n", link);
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.TupleData = tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
-
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 85f7ffac19a0..a1c5f265069f 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -136,14 +136,9 @@ static int fdomain_config(struct pcmcia_device *link)
DEBUG(0, "fdomain_config(0x%p)\n", link);
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.TupleData = tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index f2d79c3f0b8e..d72df5dae4ee 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1685,16 +1685,10 @@ static int nsp_cs_config(struct pcmcia_device *link)
nsp_dbg(NSP_DEBUG_INIT, "in");
- tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = tuple_data;
tuple.TupleDataMax = sizeof(tuple_data);
tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 86c2ac6ae623..9d431fe7f47f 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -208,18 +208,11 @@ static int qlogic_config(struct pcmcia_device * link)
DEBUG(0, "qlogic_config(0x%p)\n", link);
+ info->manf_id = link->manf_id;
+
tuple.TupleData = (cisdata_t *) tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
-
- tuple.DesiredTuple = CISTPL_MANFID;
- if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS))
- info->manf_id = le16_to_cpu(tuple.TupleData[0]);
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 72fe5d055de1..fb7acea60286 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -722,19 +722,11 @@ SYM53C500_config(struct pcmcia_device *link)
DEBUG(0, "SYM53C500_config(0x%p)\n", link);
+ info->manf_id = link->manf_id;
+
tuple.TupleData = (cisdata_t *)tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
-
- tuple.DesiredTuple = CISTPL_MANFID;
- if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
- (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS))
- info->manf_id = le16_to_cpu(tuple.TupleData[0]);
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 89a2a9f11e41..584ba4d6e038 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -31,7 +31,7 @@ typedef struct {
int base; /* Actual port address */
int mode; /* Transfer mode */
struct scsi_cmnd *cur_cmd; /* Current queued command */
- struct work_struct ppa_tq; /* Polling interrupt stuff */
+ struct delayed_work ppa_tq; /* Polling interrupt stuff */
unsigned long jstart; /* Jiffies at start */
unsigned long recon_tmo; /* How many usecs to wait for reconnection (6th bit) */
unsigned int failed:1; /* Failure flag */
@@ -627,9 +627,9 @@ static int ppa_completion(struct scsi_cmnd *cmd)
* the scheduler's task queue to generate a stream of call-backs and
* complete the request when the drive is ready.
*/
-static void ppa_interrupt(void *data)
+static void ppa_interrupt(struct work_struct *work)
{
- ppa_struct *dev = (ppa_struct *) data;
+ ppa_struct *dev = container_of(work, ppa_struct, ppa_tq.work);
struct scsi_cmnd *cmd = dev->cur_cmd;
if (!cmd) {
@@ -637,7 +637,6 @@ static void ppa_interrupt(void *data)
return;
}
if (ppa_engine(dev, cmd)) {
- dev->ppa_tq.data = (void *) dev;
schedule_delayed_work(&dev->ppa_tq, 1);
return;
}
@@ -822,8 +821,7 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
cmd->result = DID_ERROR << 16; /* default return code */
cmd->SCp.phase = 0; /* bus free */
- dev->ppa_tq.data = dev;
- schedule_work(&dev->ppa_tq);
+ schedule_delayed_work(&dev->ppa_tq, 0);
ppa_pb_claim(dev);
@@ -1086,7 +1084,7 @@ static int __ppa_attach(struct parport *pb)
else
ports = 8;
- INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev);
+ INIT_DELAYED_WORK(&dev->ppa_tq, ppa_interrupt);
err = -ENOMEM;
host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *));
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 285c8e8ff1a0..7b18a6c7b7eb 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -390,7 +390,7 @@ static struct sysfs_entry {
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
{ "vpd", &sysfs_vpd_attr, 1 },
{ "sfp", &sysfs_sfp_attr, 1 },
- { 0 },
+ { NULL },
};
void
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 08cb5e3fb553..a823f0bc519d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -59,9 +59,6 @@ int
qla2x00_initialize_adapter(scsi_qla_host_t *ha)
{
int rval;
- uint8_t restart_risc = 0;
- uint8_t retry;
- uint32_t wait_time;
/* Clear adapter flags. */
ha->flags.online = 0;
@@ -104,87 +101,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
- retry = 10;
- /*
- * Try to configure the loop.
- */
- do {
- restart_risc = 0;
-
- /* If firmware needs to be loaded */
- if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
- if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) {
- rval = qla2x00_setup_chip(ha);
- }
- }
-
- if (rval == QLA_SUCCESS &&
- (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) {
-check_fw_ready_again:
- /*
- * Wait for a successful LIP up to a maximum
- * of (in seconds): RISC login timeout value,
- * RISC retry count value, and port down retry
- * value OR a minimum of 4 seconds OR If no
- * cable, only 5 seconds.
- */
- rval = qla2x00_fw_ready(ha);
- if (rval == QLA_SUCCESS) {
- clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
-
- /* Issue a marker after FW becomes ready. */
- qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
-
- /*
- * Wait at most MAX_TARGET RSCNs for a stable
- * link.
- */
- wait_time = 256;
- do {
- clear_bit(LOOP_RESYNC_NEEDED,
- &ha->dpc_flags);
- rval = qla2x00_configure_loop(ha);
-
- if (test_and_clear_bit(ISP_ABORT_NEEDED,
- &ha->dpc_flags)) {
- restart_risc = 1;
- break;
- }
-
- /*
- * If loop state change while we were
- * discoverying devices then wait for
- * LIP to complete
- */
-
- if (atomic_read(&ha->loop_state) !=
- LOOP_READY && retry--) {
- goto check_fw_ready_again;
- }
- wait_time--;
- } while (!atomic_read(&ha->loop_down_timer) &&
- retry &&
- wait_time &&
- (test_bit(LOOP_RESYNC_NEEDED,
- &ha->dpc_flags)));
-
- if (wait_time == 0)
- rval = QLA_FUNCTION_FAILED;
- } else if (ha->device_flags & DFLG_NO_CABLE)
- /* If no cable, then all is good. */
- rval = QLA_SUCCESS;
- }
- } while (restart_risc && retry--);
-
- if (rval == QLA_SUCCESS) {
- clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
- qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
- ha->marker_needed = 0;
-
- ha->flags.online = 1;
- } else {
- DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__));
+ if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
+ rval = ha->isp_ops.chip_diag(ha);
+ if (rval)
+ return (rval);
+ rval = qla2x00_setup_chip(ha);
+ if (rval)
+ return (rval);
}
+ rval = qla2x00_init_rings(ha);
return (rval);
}
@@ -2208,8 +2133,7 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
atomic_set(&fcport->state, FCS_ONLINE);
- if (ha->flags.init_done)
- qla2x00_reg_remote_port(ha, fcport);
+ qla2x00_reg_remote_port(ha, fcport);
}
void
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 208607be78c7..cbe0cad83b68 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -95,6 +95,8 @@ MODULE_PARM_DESC(ql2xqfullrampup,
*/
static int qla2xxx_slave_configure(struct scsi_device * device);
static int qla2xxx_slave_alloc(struct scsi_device *);
+static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
+static void qla2xxx_scan_start(struct Scsi_Host *);
static void qla2xxx_slave_destroy(struct scsi_device *);
static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
void (*fn)(struct scsi_cmnd *));
@@ -124,6 +126,8 @@ static struct scsi_host_template qla2x00_driver_template = {
.slave_alloc = qla2xxx_slave_alloc,
.slave_destroy = qla2xxx_slave_destroy,
+ .scan_finished = qla2xxx_scan_finished,
+ .scan_start = qla2xxx_scan_start,
.change_queue_depth = qla2x00_change_queue_depth,
.change_queue_type = qla2x00_change_queue_type,
.this_id = -1,
@@ -287,7 +291,7 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
return str;
}
-char *
+static char *
qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str)
{
char un_str[10];
@@ -325,7 +329,7 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str)
return (str);
}
-char *
+static char *
qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
{
sprintf(str, "%d.%02d.%02d ", ha->fw_major_version,
@@ -634,7 +638,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
* Note:
* Only return FAILED if command not returned by firmware.
**************************************************************************/
-int
+static int
qla2xxx_eh_abort(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
@@ -771,7 +775,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
* SUCCESS/FAILURE (defined as macro in scsi.h).
*
**************************************************************************/
-int
+static int
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
@@ -902,7 +906,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
* SUCCESS/FAILURE (defined as macro in scsi.h).
*
**************************************************************************/
-int
+static int
qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
@@ -963,7 +967,7 @@ eh_bus_reset_done:
*
* Note:
**************************************************************************/
-int
+static int
qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
@@ -1366,6 +1370,29 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
+static void
+qla2xxx_scan_start(struct Scsi_Host *shost)
+{
+ scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata;
+
+ set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
+ set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
+ set_bit(RSCN_UPDATE, &ha->dpc_flags);
+}
+
+static int
+qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+ scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata;
+
+ if (!ha->host)
+ return 1;
+ if (time > ha->loop_reset_delay * HZ)
+ return 1;
+
+ return atomic_read(&ha->loop_state) == LOOP_READY;
+}
+
/*
* PCI driver interface
*/
@@ -1377,10 +1404,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct Scsi_Host *host;
scsi_qla_host_t *ha;
unsigned long flags = 0;
- unsigned long wait_switch = 0;
char pci_info[20];
char fw_str[30];
- fc_port_t *fcport;
struct scsi_host_template *sht;
if (pci_enable_device(pdev))
@@ -1631,30 +1656,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->isp_ops.enable_intrs(ha);
- /* v2.19.5b6 */
- /*
- * Wait around max loop_reset_delay secs for the devices to come
- * on-line. We don't want Linux scanning before we are ready.
- *
- */
- for (wait_switch = jiffies + (ha->loop_reset_delay * HZ);
- time_before(jiffies,wait_switch) &&
- !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES))
- && (ha->device_flags & SWITCH_FOUND) ;) {
-
- qla2x00_check_fabric_devices(ha);
-
- msleep(10);
- }
-
pci_set_drvdata(pdev, ha);
+
ha->flags.init_done = 1;
+ ha->flags.online = 1;
+
num_hosts++;
ret = scsi_add_host(host, &pdev->dev);
if (ret)
goto probe_failed;
+ scsi_scan_host(host);
+
qla2x00_alloc_sysfs_attr(ha);
qla2x00_init_host_attr(ha);
@@ -1669,10 +1683,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
ha->isp_ops.fw_version_str(ha, fw_str));
- /* Go with fc_rport registration. */
- list_for_each_entry(fcport, &ha->fcports, list)
- qla2x00_reg_remote_port(ha, fcport);
-
return 0;
probe_failed:
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index c71dbd5bd543..15390ad87456 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -449,7 +449,7 @@ nvram_data_to_access_addr(uint32_t naddr)
return FARX_ACCESS_NVRAM_DATA | naddr;
}
-uint32_t
+static uint32_t
qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr)
{
int rval;
@@ -490,7 +490,7 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
return dwptr;
}
-int
+static int
qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data)
{
int rval;
@@ -512,7 +512,7 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data)
return rval;
}
-void
+static void
qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
uint8_t *flash_id)
{
@@ -537,7 +537,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
}
}
-int
+static int
qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
uint32_t dwords)
{
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
index 752031fadfef..7b4e077a39c1 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.c
+++ b/drivers/scsi/qla4xxx/ql4_dbg.c
@@ -71,7 +71,7 @@ void __dump_registers(struct scsi_qla_host *ha)
readw(&ha->reg->u1.isp4010.nvram));
}
- else if (is_qla4022(ha)) {
+ else if (is_qla4022(ha) | is_qla4032(ha)) {
printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n",
(uint8_t) offsetof(struct isp_reg,
u1.isp4022.intr_mask),
@@ -119,7 +119,7 @@ void __dump_registers(struct scsi_qla_host *ha)
readw(&ha->reg->u2.isp4010.port_err_status));
}
- else if (is_qla4022(ha)) {
+ else if (is_qla4022(ha) | is_qla4032(ha)) {
printk(KERN_INFO "Page 0 Registers:\n");
printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n",
(uint8_t) offsetof(struct isp_reg,
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index a7f6c7b1c590..4249e52a5592 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -40,7 +40,11 @@
#ifndef PCI_DEVICE_ID_QLOGIC_ISP4022
#define PCI_DEVICE_ID_QLOGIC_ISP4022 0x4022
-#endif /* */
+#endif
+
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP4032
+#define PCI_DEVICE_ID_QLOGIC_ISP4032 0x4032
+#endif
#define QLA_SUCCESS 0
#define QLA_ERROR 1
@@ -277,7 +281,6 @@ struct scsi_qla_host {
#define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */
#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */
#define AF_LINK_UP 8 /* 0x00000100 */
-#define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */
#define AF_IRQ_ATTACHED 10 /* 0x00000400 */
#define AF_ISNS_CMD_IN_PROCESS 12 /* 0x00001000 */
#define AF_ISNS_CMD_DONE 13 /* 0x00002000 */
@@ -317,16 +320,17 @@ struct scsi_qla_host {
/* NVRAM registers */
struct eeprom_data *nvram;
spinlock_t hardware_lock ____cacheline_aligned;
- spinlock_t list_lock;
uint32_t eeprom_cmd_data;
/* Counters for general statistics */
+ uint64_t isr_count;
uint64_t adapter_error_count;
uint64_t device_error_count;
uint64_t total_io_count;
uint64_t total_mbytes_xferred;
uint64_t link_failure_count;
uint64_t invalid_crc_count;
+ uint32_t bytes_xfered;
uint32_t spurious_int_count;
uint32_t aborted_io_count;
uint32_t io_timeout_count;
@@ -438,6 +442,11 @@ static inline int is_qla4022(struct scsi_qla_host *ha)
return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022;
}
+static inline int is_qla4032(struct scsi_qla_host *ha)
+{
+ return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032;
+}
+
static inline int adapter_up(struct scsi_qla_host *ha)
{
return (test_bit(AF_ONLINE, &ha->flags) != 0) &&
@@ -451,58 +460,58 @@ static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost)
static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u1.isp4022.semaphore :
- &ha->reg->u1.isp4010.nvram);
+ return (is_qla4010(ha) ?
+ &ha->reg->u1.isp4010.nvram :
+ &ha->reg->u1.isp4022.semaphore);
}
static inline void __iomem* isp_nvram(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u1.isp4022.nvram :
- &ha->reg->u1.isp4010.nvram);
+ return (is_qla4010(ha) ?
+ &ha->reg->u1.isp4010.nvram :
+ &ha->reg->u1.isp4022.nvram);
}
static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u2.isp4022.p0.ext_hw_conf :
- &ha->reg->u2.isp4010.ext_hw_conf);
+ return (is_qla4010(ha) ?
+ &ha->reg->u2.isp4010.ext_hw_conf :
+ &ha->reg->u2.isp4022.p0.ext_hw_conf);
}
static inline void __iomem* isp_port_status(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u2.isp4022.p0.port_status :
- &ha->reg->u2.isp4010.port_status);
+ return (is_qla4010(ha) ?
+ &ha->reg->u2.isp4010.port_status :
+ &ha->reg->u2.isp4022.p0.port_status);
}
static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u2.isp4022.p0.port_ctrl :
- &ha->reg->u2.isp4010.port_ctrl);
+ return (is_qla4010(ha) ?
+ &ha->reg->u2.isp4010.port_ctrl :
+ &ha->reg->u2.isp4022.p0.port_ctrl);
}
static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u2.isp4022.p0.port_err_status :
- &ha->reg->u2.isp4010.port_err_status);
+ return (is_qla4010(ha) ?
+ &ha->reg->u2.isp4010.port_err_status :
+ &ha->reg->u2.isp4022.p0.port_err_status);
}
static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- &ha->reg->u2.isp4022.p0.gp_out :
- &ha->reg->u2.isp4010.gp_out);
+ return (is_qla4010(ha) ?
+ &ha->reg->u2.isp4010.gp_out :
+ &ha->reg->u2.isp4022.p0.gp_out);
}
static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha)
{
- return (is_qla4022(ha) ?
- offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 :
- offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2);
+ return (is_qla4010(ha) ?
+ offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2 :
+ offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2);
}
int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
@@ -511,59 +520,59 @@ int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
static inline int ql4xxx_lock_flash(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
+ if (is_qla4010(a))
+ return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
+ QL4010_FLASH_SEM_BITS);
+ else
return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK,
(QL4022_RESOURCE_BITS_BASE_CODE |
(a->mac_index)) << 13);
- else
- return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
- QL4010_FLASH_SEM_BITS);
}
static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
- ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
- else
+ if (is_qla4010(a))
ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK);
+ else
+ ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
}
static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
+ if (is_qla4010(a))
+ return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
+ QL4010_NVRAM_SEM_BITS);
+ else
return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK,
(QL4022_RESOURCE_BITS_BASE_CODE |
(a->mac_index)) << 10);
- else
- return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
- QL4010_NVRAM_SEM_BITS);
}
static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
- ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
- else
+ if (is_qla4010(a))
ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK);
+ else
+ ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
}
static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
+ if (is_qla4010(a))
+ return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
+ QL4010_DRVR_SEM_BITS);
+ else
return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK,
(QL4022_RESOURCE_BITS_BASE_CODE |
(a->mac_index)) << 1);
- else
- return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
- QL4010_DRVR_SEM_BITS);
}
static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
{
- if (is_qla4022(a))
- ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
- else
+ if (is_qla4010(a))
ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK);
+ else
+ ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
}
/*---------------------------------------------------------------------------*/
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 427489de64bc..4eea8c571916 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -296,7 +296,6 @@ static inline uint32_t clr_rmask(uint32_t val)
/* ISP Semaphore definitions */
/* ISP General Purpose Output definitions */
-#define GPOR_TOPCAT_RESET 0x00000004
/* shadow registers (DMA'd from HA to system memory. read only) */
struct shadow_regs {
@@ -339,10 +338,13 @@ union external_hw_config_reg {
/* Mailbox command definitions */
#define MBOX_CMD_ABOUT_FW 0x0009
#define MBOX_CMD_LUN_RESET 0x0016
+#define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E
#define MBOX_CMD_GET_FW_STATUS 0x001F
#define MBOX_CMD_SET_ISNS_SERVICE 0x0021
#define ISNS_DISABLE 0
#define ISNS_ENABLE 1
+#define MBOX_CMD_COPY_FLASH 0x0024
+#define MBOX_CMD_WRITE_FLASH 0x0025
#define MBOX_CMD_READ_FLASH 0x0026
#define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031
#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056
@@ -360,10 +362,13 @@ union external_hw_config_reg {
#define DDB_DS_SESSION_FAILED 0x06
#define DDB_DS_LOGIN_IN_PROCESS 0x07
#define MBOX_CMD_GET_FW_STATE 0x0069
+#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A
+#define MBOX_CMD_RESTORE_FACTORY_DEFAULTS 0x0087
/* Mailbox 1 */
#define FW_STATE_READY 0x0000
#define FW_STATE_CONFIG_WAIT 0x0001
+#define FW_STATE_WAIT_LOGIN 0x0002
#define FW_STATE_ERROR 0x0004
#define FW_STATE_DHCP_IN_PROGRESS 0x0008
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 1b221ff0f6f7..2122967bbf0b 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -8,6 +8,7 @@
#ifndef __QLA4x_GBL_H
#define __QLA4x_GBL_H
+int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a);
int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port);
int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb);
int qla4xxx_initialize_adapter(struct scsi_qla_host * ha,
@@ -75,4 +76,4 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
extern int ql4xextended_error_logging;
extern int ql4xdiscoverywait;
extern int ql4xdontresethba;
-#endif /* _QLA4x_GBL_H */
+#endif /* _QLA4x_GBL_H */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index bb3a1c11f44c..cc210f297a78 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -259,10 +259,16 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
"seconds expired= %d\n", ha->host_no, __func__,
ha->firmware_state, ha->addl_fw_state,
timeout_count));
+ if (is_qla4032(ha) &&
+ !(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) &&
+ (timeout_count < ADAPTER_INIT_TOV - 5)) {
+ break;
+ }
+
msleep(1000);
} /* end of for */
- if (timeout_count <= 0)
+ if (timeout_count == 0)
DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n",
ha->host_no, __func__));
@@ -806,32 +812,6 @@ int qla4xxx_relogin_device(struct scsi_qla_host *ha,
return QLA_SUCCESS;
}
-/**
- * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip
- * @ha: Pointer to host adapter structure.
- *
- **/
-static int qla4010_get_topcat_presence(struct scsi_qla_host *ha)
-{
- unsigned long flags;
- uint16_t topcat;
-
- if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS)
- return QLA_ERROR;
- spin_lock_irqsave(&ha->hardware_lock, flags);
- topcat = rd_nvram_word(ha, offsetof(struct eeprom_data,
- isp4010.topcat));
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
- if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT)
- set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
- else
- clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
- ql4xxx_unlock_nvram(ha);
- return QLA_SUCCESS;
-}
-
-
static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
{
unsigned long flags;
@@ -866,7 +846,7 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
/* set defaults */
if (is_qla4010(ha))
extHwConfig.Asuint32_t = 0x1912;
- else if (is_qla4022(ha))
+ else if (is_qla4022(ha) | is_qla4032(ha))
extHwConfig.Asuint32_t = 0x0023;
}
DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n",
@@ -927,7 +907,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
spin_lock_irqsave(&ha->hardware_lock, flags);
writel(jiffies, &ha->reg->mailbox[7]);
- if (is_qla4022(ha))
+ if (is_qla4022(ha) | is_qla4032(ha))
writel(set_rmask(NVR_WRITE_ENABLE),
&ha->reg->u1.isp4022.nvram);
@@ -978,7 +958,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
return status;
}
-static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
+int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
{
#define QL4_LOCK_DRVR_WAIT 300
#define QL4_LOCK_DRVR_SLEEP 100
@@ -1018,12 +998,7 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
int soft_reset = 1;
int config_chip = 0;
- if (is_qla4010(ha)){
- if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS)
- return QLA_ERROR;
- }
-
- if (is_qla4022(ha))
+ if (is_qla4022(ha) | is_qla4032(ha))
ql4xxx_set_mac_number(ha);
if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)
diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h
index 0d61797af7da..6375eb017dd3 100644
--- a/drivers/scsi/qla4xxx/ql4_inline.h
+++ b/drivers/scsi/qla4xxx/ql4_inline.h
@@ -38,7 +38,7 @@ qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index)
static inline void
__qla4xxx_enable_intrs(struct scsi_qla_host *ha)
{
- if (is_qla4022(ha)) {
+ if (is_qla4022(ha) | is_qla4032(ha)) {
writel(set_rmask(IMR_SCSI_INTR_ENABLE),
&ha->reg->u1.isp4022.intr_mask);
readl(&ha->reg->u1.isp4022.intr_mask);
@@ -52,7 +52,7 @@ __qla4xxx_enable_intrs(struct scsi_qla_host *ha)
static inline void
__qla4xxx_disable_intrs(struct scsi_qla_host *ha)
{
- if (is_qla4022(ha)) {
+ if (is_qla4022(ha) | is_qla4032(ha)) {
writel(clr_rmask(IMR_SCSI_INTR_ENABLE),
&ha->reg->u1.isp4022.intr_mask);
readl(&ha->reg->u1.isp4022.intr_mask);
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index c0a254b89a30..d41ce380eedc 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -294,6 +294,12 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
cmd_entry->control_flags = CF_WRITE;
else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
cmd_entry->control_flags = CF_READ;
+
+ ha->bytes_xfered += cmd->request_bufflen;
+ if (ha->bytes_xfered & ~0xFFFFF){
+ ha->total_mbytes_xferred += ha->bytes_xfered >> 20;
+ ha->bytes_xfered &= 0xFFFFF;
+ }
}
/* Set tagged queueing control flags */
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 1e283321a59d..ef975e0dc87f 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -627,6 +627,7 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
spin_lock_irqsave(&ha->hardware_lock, flags);
+ ha->isr_count++;
/*
* Repeatedly service interrupts up to a maximum of
* MAX_REQS_SERVICED_PER_INTR
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c
index e3957ca5b645..58afd135aa1d 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.c
+++ b/drivers/scsi/qla4xxx/ql4_nvram.c
@@ -7,15 +7,22 @@
#include "ql4_def.h"
+static inline void eeprom_cmd(uint32_t cmd, struct scsi_qla_host *ha)
+{
+ writel(cmd, isp_nvram(ha));
+ readl(isp_nvram(ha));
+ udelay(1);
+}
+
static inline int eeprom_size(struct scsi_qla_host *ha)
{
- return is_qla4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16;
+ return is_qla4010(ha) ? FM93C66A_SIZE_16 : FM93C86A_SIZE_16;
}
static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha)
{
- return is_qla4022(ha) ? FM93C86A_NO_ADDR_BITS_16 :
- FM93C56A_NO_ADDR_BITS_16;
+ return is_qla4010(ha) ? FM93C56A_NO_ADDR_BITS_16 :
+ FM93C86A_NO_ADDR_BITS_16 ;
}
static inline int eeprom_no_data_bits(struct scsi_qla_host *ha)
@@ -28,8 +35,7 @@ static int fm93c56a_select(struct scsi_qla_host * ha)
DEBUG5(printk(KERN_ERR "fm93c56a_select:\n"));
ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000;
- writel(ha->eeprom_cmd_data, isp_nvram(ha));
- readl(isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data, ha);
return 1;
}
@@ -41,12 +47,13 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr)
int previousBit;
/* Clock in a zero, then do the start bit. */
- writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, isp_nvram(ha));
- writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
- AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
- writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
- AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
- readl(isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, ha);
+
+ eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+ AUBURN_EEPROM_CLK_RISE, ha);
+ eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+ AUBURN_EEPROM_CLK_FALL, ha);
+
mask = 1 << (FM93C56A_CMD_BITS - 1);
/* Force the previous data bit to be different. */
@@ -60,14 +67,14 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr)
* If the bit changed, then change the DO state to
* match.
*/
- writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha);
previousBit = dataBit;
}
- writel(ha->eeprom_cmd_data | dataBit |
- AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
- writel(ha->eeprom_cmd_data | dataBit |
- AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
- readl(isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit |
+ AUBURN_EEPROM_CLK_RISE, ha);
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit |
+ AUBURN_EEPROM_CLK_FALL, ha);
+
cmd = cmd << 1;
}
mask = 1 << (eeprom_no_addr_bits(ha) - 1);
@@ -82,14 +89,15 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr)
* If the bit changed, then change the DO state to
* match.
*/
- writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha);
+
previousBit = dataBit;
}
- writel(ha->eeprom_cmd_data | dataBit |
- AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
- writel(ha->eeprom_cmd_data | dataBit |
- AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
- readl(isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit |
+ AUBURN_EEPROM_CLK_RISE, ha);
+ eeprom_cmd(ha->eeprom_cmd_data | dataBit |
+ AUBURN_EEPROM_CLK_FALL, ha);
+
addr = addr << 1;
}
return 1;
@@ -98,8 +106,7 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr)
static int fm93c56a_deselect(struct scsi_qla_host * ha)
{
ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000;
- writel(ha->eeprom_cmd_data, isp_nvram(ha));
- readl(isp_nvram(ha));
+ eeprom_cmd(ha->eeprom_cmd_data, ha);
return 1;
}
@@ -112,12 +119,13 @@ static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value)
/* Read the data bits
* The first bit is a dummy. Clock right over it. */
for (i = 0; i < eeprom_no_data_bits(ha); i++) {
- writel(ha->eeprom_cmd_data |
- AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
- writel(ha->eeprom_cmd_data |
- AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
- dataBit =
- (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0;
+ eeprom_cmd(ha->eeprom_cmd_data |
+ AUBURN_EEPROM_CLK_RISE, ha);
+ eeprom_cmd(ha->eeprom_cmd_data |
+ AUBURN_EEPROM_CLK_FALL, ha);
+
+ dataBit = (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0;
+
data = (data << 1) | dataBit;
}
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h
index 08e2aed8c6cc..b47b4fc59d83 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.h
+++ b/drivers/scsi/qla4xxx/ql4_nvram.h
@@ -134,9 +134,7 @@ struct eeprom_data {
u16 phyConfig; /* x36 */
#define PHY_CONFIG_PHY_ADDR_MASK 0x1f
#define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20
- u16 topcat; /* x38 */
-#define TOPCAT_PRESENT 0x0100
-#define TOPCAT_MASK 0xFF00
+ u16 reserved_56; /* x38 */
#define EEPROM_UNUSED_1_SIZE 2
u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 5b8db6109536..969c9e431028 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -708,10 +708,10 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
}
/**
- * qla4010_soft_reset - performs soft reset.
+ * qla4xxx_soft_reset - performs soft reset.
* @ha: Pointer to host adapter structure.
**/
-static int qla4010_soft_reset(struct scsi_qla_host *ha)
+int qla4xxx_soft_reset(struct scsi_qla_host *ha)
{
uint32_t max_wait_time;
unsigned long flags = 0;
@@ -817,29 +817,6 @@ static int qla4010_soft_reset(struct scsi_qla_host *ha)
}
/**
- * qla4xxx_topcat_reset - performs hard reset of TopCat Chip.
- * @ha: Pointer to host adapter structure.
- **/
-static int qla4xxx_topcat_reset(struct scsi_qla_host *ha)
-{
- unsigned long flags;
-
- ql4xxx_lock_nvram(ha);
- spin_lock_irqsave(&ha->hardware_lock, flags);
- writel(set_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha));
- readl(isp_gp_out(ha));
- mdelay(1);
-
- writel(clr_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha));
- readl(isp_gp_out(ha));
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- mdelay(2523);
-
- ql4xxx_unlock_nvram(ha);
- return QLA_SUCCESS;
-}
-
-/**
* qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S.
* @ha: Pointer to host adapter structure.
*
@@ -867,26 +844,6 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha)
}
/**
- * qla4xxx_hard_reset - performs HBA Hard Reset
- * @ha: Pointer to host adapter structure.
- **/
-static int qla4xxx_hard_reset(struct scsi_qla_host *ha)
-{
- /* The QLA4010 really doesn't have an equivalent to a hard reset */
- qla4xxx_flush_active_srbs(ha);
- if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) {
- int status = QLA_ERROR;
-
- if ((qla4010_soft_reset(ha) == QLA_SUCCESS) &&
- (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) &&
- (qla4010_soft_reset(ha) == QLA_SUCCESS))
- status = QLA_SUCCESS;
- return status;
- } else
- return qla4010_soft_reset(ha);
-}
-
-/**
* qla4xxx_recover_adapter - recovers adapter after a fatal error
* @ha: Pointer to host adapter structure.
* @renew_ddb_list: Indicates what to do with the adapter's ddb list
@@ -919,18 +876,11 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha,
if (status == QLA_SUCCESS) {
DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n",
ha->host_no, __func__));
- status = qla4xxx_soft_reset(ha);
- }
- /* FIXMEkaren: Do we want to keep interrupts enabled and process
- AENs after soft reset */
-
- /* If firmware (SOFT) reset failed, or if all outstanding
- * commands have not returned, then do a HARD reset.
- */
- if (status == QLA_ERROR) {
- DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n",
- ha->host_no, __func__));
- status = qla4xxx_hard_reset(ha);
+ qla4xxx_flush_active_srbs(ha);
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
+ status = qla4xxx_soft_reset(ha);
+ else
+ status = QLA_ERROR;
}
/* Flush any pending ddb changed AENs */
@@ -1011,18 +961,15 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha,
* the mid-level tries to sleep when it reaches the driver threshold
* "host->can_queue". This can cause a panic if we were in our interrupt code.
**/
-static void qla4xxx_do_dpc(void *data)
+static void qla4xxx_do_dpc(struct work_struct *work)
{
- struct scsi_qla_host *ha = (struct scsi_qla_host *) data;
+ struct scsi_qla_host *ha =
+ container_of(work, struct scsi_qla_host, dpc_work);
struct ddb_entry *ddb_entry, *dtemp;
- DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n",
- ha->host_no, __func__));
-
- DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n",
- ha->host_no, __func__, ha->flags));
- DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n",
- ha->host_no, __func__, ha->dpc_flags));
+ DEBUG2(printk("scsi%ld: %s: DPC handler waking up."
+ "flags = 0x%08lx, dpc_flags = 0x%08lx\n",
+ ha->host_no, __func__, ha->flags, ha->dpc_flags));
/* Initialization not yet finished. Don't do anything yet. */
if (!test_bit(AF_INIT_DONE, &ha->flags))
@@ -1032,16 +979,8 @@ static void qla4xxx_do_dpc(void *data)
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) {
- if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags))
- /*
- * dg 09/23 Never initialize ddb list
- * once we up and running
- * qla4xxx_recover_adapter(ha,
- * REBUILD_DDB_LIST);
- */
- qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
-
- if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
+ if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
+ test_bit(DPC_RESET_HA, &ha->dpc_flags))
qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
@@ -1122,7 +1061,8 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
destroy_workqueue(ha->dpc_thread);
/* Issue Soft Reset to put firmware in unknown state */
- qla4xxx_soft_reset(ha);
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
+ qla4xxx_soft_reset(ha);
/* Remove timer thread, if present */
if (ha->timer_active)
@@ -1261,7 +1201,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
init_waitqueue_head(&ha->mailbox_wait_queue);
spin_lock_init(&ha->hardware_lock);
- spin_lock_init(&ha->list_lock);
/* Allocate dma buffers */
if (qla4xxx_mem_alloc(ha)) {
@@ -1315,7 +1254,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
ret = -ENODEV;
goto probe_failed;
}
- INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc, ha);
+ INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc);
ret = request_irq(pdev->irq, qla4xxx_intr_handler,
SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha);
@@ -1468,27 +1407,6 @@ struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t in
}
/**
- * qla4xxx_soft_reset - performs a SOFT RESET of hba.
- * @ha: Pointer to host adapter structure.
- **/
-int qla4xxx_soft_reset(struct scsi_qla_host *ha)
-{
-
- DEBUG2(printk(KERN_WARNING "scsi%ld: %s: chip reset!\n", ha->host_no,
- __func__));
- if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) {
- int status = QLA_ERROR;
-
- if ((qla4010_soft_reset(ha) == QLA_SUCCESS) &&
- (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) &&
- (qla4010_soft_reset(ha) == QLA_SUCCESS) )
- status = QLA_SUCCESS;
- return status;
- } else
- return qla4010_soft_reset(ha);
-}
-
-/**
* qla4xxx_eh_wait_on_command - waits for command to be returned by firmware
* @ha: actual ha whose done queue will contain the comd returned by firmware.
* @cmd: Scsi Command to wait on.
@@ -1686,6 +1604,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = {
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
+ {
+ .vendor = PCI_VENDOR_ID_QLOGIC,
+ .device = PCI_DEVICE_ID_QLOGIC_ISP4032,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index b3fe7e68988e..454e19c8ad68 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,9 +5,4 @@
* See LICENSE.qla4xxx for copyright and licensing details.
*/
-#define QLA4XXX_DRIVER_VERSION "5.00.05b9-k"
-
-#define QL4_DRIVER_MAJOR_VER 5
-#define QL4_DRIVER_MINOR_VER 0
-#define QL4_DRIVER_PATCH_VER 5
-#define QL4_DRIVER_BETA_VER 9
+#define QLA4XXX_DRIVER_VERSION "5.00.07-k"
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index c59f31533ab4..fafc00deaade 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -156,8 +156,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
static DEFINE_MUTEX(host_cmd_pool_mutex);
-static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
- gfp_t gfp_mask)
+struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -178,6 +177,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
return cmd;
}
+EXPORT_SYMBOL_GPL(__scsi_get_command);
/*
* Function: scsi_get_command()
@@ -214,9 +214,29 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
put_device(&dev->sdev_gendev);
return cmd;
-}
+}
EXPORT_SYMBOL(scsi_get_command);
+void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd,
+ struct device *dev)
+{
+ unsigned long flags;
+
+ /* changing locks here, don't need to restore the irq state */
+ spin_lock_irqsave(&shost->free_list_lock, flags);
+ if (unlikely(list_empty(&shost->free_list))) {
+ list_add(&cmd->list, &shost->free_list);
+ cmd = NULL;
+ }
+ spin_unlock_irqrestore(&shost->free_list_lock, flags);
+
+ if (likely(cmd != NULL))
+ kmem_cache_free(shost->cmd_pool->slab, cmd);
+
+ put_device(dev);
+}
+EXPORT_SYMBOL(__scsi_put_command);
+
/*
* Function: scsi_put_command()
*
@@ -231,26 +251,15 @@ EXPORT_SYMBOL(scsi_get_command);
void scsi_put_command(struct scsi_cmnd *cmd)
{
struct scsi_device *sdev = cmd->device;
- struct Scsi_Host *shost = sdev->host;
unsigned long flags;
-
+
/* serious error if the command hasn't come from a device list */
spin_lock_irqsave(&cmd->device->list_lock, flags);
BUG_ON(list_empty(&cmd->list));
list_del_init(&cmd->list);
- spin_unlock(&cmd->device->list_lock);
- /* changing locks here, don't need to restore the irq state */
- spin_lock(&shost->free_list_lock);
- if (unlikely(list_empty(&shost->free_list))) {
- list_add(&cmd->list, &shost->free_list);
- cmd = NULL;
- }
- spin_unlock_irqrestore(&shost->free_list_lock, flags);
-
- if (likely(cmd != NULL))
- kmem_cache_free(shost->cmd_pool->slab, cmd);
+ spin_unlock_irqrestore(&cmd->device->list_lock, flags);
- put_device(&sdev->sdev_gendev);
+ __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev);
}
EXPORT_SYMBOL(scsi_put_command);
@@ -871,9 +880,9 @@ EXPORT_SYMBOL(scsi_device_get);
*/
void scsi_device_put(struct scsi_device *sdev)
{
+#ifdef CONFIG_MODULE_UNLOAD
struct module *module = sdev->host->hostt->module;
-#ifdef CONFIG_MODULE_UNLOAD
/* The module refcount will be zero if scsi_device_get()
* was called from a module removal routine */
if (module && module_refcount(module) != 0)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index aff1b0cfd4b2..2ecb6ff42444 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -453,9 +453,18 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
}
/**
- * scsi_send_eh_cmnd - send a cmd to a device as part of error recovery.
- * @scmd: SCSI Cmd to send.
- * @timeout: Timeout for cmd.
+ * scsi_send_eh_cmnd - submit a scsi command as part of error recory
+ * @scmd: SCSI command structure to hijack
+ * @cmnd: CDB to send
+ * @cmnd_size: size in bytes of @cmnd
+ * @timeout: timeout for this request
+ * @copy_sense: request sense data if set to 1
+ *
+ * This function is used to send a scsi command down to a target device
+ * as part of the error recovery process. If @copy_sense is 0 the command
+ * sent must be one that does not transfer any data. If @copy_sense is 1
+ * the command must be REQUEST_SENSE and this functions copies out the
+ * sense buffer it got into @scmd->sense_buffer.
*
* Return value:
* SUCCESS or FAILED or NEEDS_RETRY
@@ -469,6 +478,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
DECLARE_COMPLETION_ONSTACK(done);
unsigned long timeleft;
unsigned long flags;
+ struct scatterlist sgl;
unsigned char old_cmnd[MAX_COMMAND_SIZE];
enum dma_data_direction old_data_direction;
unsigned short old_use_sg;
@@ -500,19 +510,24 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
if (shost->hostt->unchecked_isa_dma)
gfp_mask |= __GFP_DMA;
- scmd->sc_data_direction = DMA_FROM_DEVICE;
- scmd->request_bufflen = 252;
- scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
- if (!scmd->request_buffer)
+ sgl.page = alloc_page(gfp_mask);
+ if (!sgl.page)
return FAILED;
+ sgl.offset = 0;
+ sgl.length = 252;
+
+ scmd->sc_data_direction = DMA_FROM_DEVICE;
+ scmd->request_bufflen = sgl.length;
+ scmd->request_buffer = &sgl;
+ scmd->use_sg = 1;
} else {
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->sc_data_direction = DMA_NONE;
+ scmd->use_sg = 0;
}
scmd->underflow = 0;
- scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
if (sdev->scsi_level <= SCSI_2)
@@ -583,7 +598,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
memcpy(scmd->sense_buffer, scmd->request_buffer,
sizeof(scmd->sense_buffer));
}
- kfree(scmd->request_buffer);
+ __free_page(sgl.page);
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3ac4890ce086..fb616c69151f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -704,7 +704,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
return NULL;
}
-static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
struct scsi_host_sg_pool *sgp;
struct scatterlist *sgl;
@@ -745,7 +745,9 @@ static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_m
return sgl;
}
-static void scsi_free_sgtable(struct scatterlist *sgl, int index)
+EXPORT_SYMBOL(scsi_alloc_sgtable);
+
+void scsi_free_sgtable(struct scatterlist *sgl, int index)
{
struct scsi_host_sg_pool *sgp;
@@ -755,6 +757,8 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free(sgl, sgp->pool);
}
+EXPORT_SYMBOL(scsi_free_sgtable);
+
/*
* Function: scsi_release_buffers()
*
@@ -996,25 +1000,14 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
int count;
/*
- * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
- */
- if (blk_pc_request(req) && !req->bio) {
- cmd->request_bufflen = req->data_len;
- cmd->request_buffer = req->data;
- req->buffer = req->data;
- cmd->use_sg = 0;
- return 0;
- }
-
- /*
- * we used to not use scatter-gather for single segment request,
+ * 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)
*/
cmd->use_sg = req->nr_phys_segments;
/*
- * if sg table allocation fails, requeue request later.
+ * If sg table allocation fails, requeue request later.
*/
sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
if (unlikely(!sgpnt)) {
@@ -1022,24 +1015,21 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
return BLKPREP_DEFER;
}
+ req->buffer = NULL;
cmd->request_buffer = (char *) sgpnt;
- cmd->request_bufflen = req->nr_sectors << 9;
if (blk_pc_request(req))
cmd->request_bufflen = req->data_len;
- req->buffer = NULL;
+ else
+ cmd->request_bufflen = req->nr_sectors << 9;
/*
* Next, walk the list, and fill in the addresses and sizes of
* each segment.
*/
count = blk_rq_map_sg(req->q, req, cmd->request_buffer);
-
- /*
- * mapped well, send it off
- */
if (likely(count <= cmd->use_sg)) {
cmd->use_sg = count;
- return 0;
+ return BLKPREP_OK;
}
printk(KERN_ERR "Incorrect number of segments after building list\n");
@@ -1069,6 +1059,27 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
return -EOPNOTSUPP;
}
+static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
+ struct request *req)
+{
+ struct scsi_cmnd *cmd;
+
+ if (!req->special) {
+ cmd = scsi_get_command(sdev, GFP_ATOMIC);
+ if (unlikely(!cmd))
+ return NULL;
+ req->special = cmd;
+ } else {
+ cmd = req->special;
+ }
+
+ /* pull a tag out of the request if we have one */
+ cmd->tag = req->tag;
+ cmd->request = req;
+
+ return cmd;
+}
+
static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
{
BUG_ON(!blk_pc_request(cmd->request));
@@ -1081,9 +1092,37 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
scsi_io_completion(cmd, cmd->request_bufflen);
}
-static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
+static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
{
- struct request *req = cmd->request;
+ struct scsi_cmnd *cmd;
+
+ cmd = scsi_get_cmd_from_req(sdev, req);
+ if (unlikely(!cmd))
+ return BLKPREP_DEFER;
+
+ /*
+ * BLOCK_PC requests may transfer data, in which case they must
+ * a bio attached to them. Or they might contain a SCSI command
+ * that does not transfer data, in which case they may optionally
+ * submit a request without an attached bio.
+ */
+ if (req->bio) {
+ int ret;
+
+ BUG_ON(!req->nr_phys_segments);
+
+ ret = scsi_init_io(cmd);
+ if (unlikely(ret))
+ return ret;
+ } else {
+ BUG_ON(req->data_len);
+ BUG_ON(req->data);
+
+ cmd->request_bufflen = 0;
+ cmd->request_buffer = NULL;
+ cmd->use_sg = 0;
+ req->buffer = NULL;
+ }
BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
@@ -1099,154 +1138,138 @@ static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
cmd->allowed = req->retries;
cmd->timeout_per_command = req->timeout;
cmd->done = scsi_blk_pc_done;
+ return BLKPREP_OK;
}
-static int scsi_prep_fn(struct request_queue *q, struct request *req)
+/*
+ * Setup a REQ_TYPE_FS command. These are simple read/write request
+ * from filesystems that still need to be translated to SCSI CDBs from
+ * the ULD.
+ */
+static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
{
- struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd;
- int specials_only = 0;
+ struct scsi_driver *drv;
+ int ret;
/*
- * Just check to see if the device is online. If it isn't, we
- * refuse to process any commands. The device must be brought
- * online before trying any recovery commands
+ * Filesystem requests must transfer data.
*/
- if (unlikely(!scsi_device_online(sdev))) {
- sdev_printk(KERN_ERR, sdev,
- "rejecting I/O to offline device\n");
- goto kill;
- }
- if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {
- /* OK, we're not in a running state don't prep
- * user commands */
- if (sdev->sdev_state == SDEV_DEL) {
- /* Device is fully deleted, no commands
- * at all allowed down */
- sdev_printk(KERN_ERR, sdev,
- "rejecting I/O to dead device\n");
- goto kill;
- }
- /* OK, we only allow special commands (i.e. not
- * user initiated ones */
- specials_only = sdev->sdev_state;
+ BUG_ON(!req->nr_phys_segments);
+
+ cmd = scsi_get_cmd_from_req(sdev, req);
+ if (unlikely(!cmd))
+ return BLKPREP_DEFER;
+
+ ret = scsi_init_io(cmd);
+ if (unlikely(ret))
+ return ret;
+
+ /*
+ * Initialize the actual SCSI command for this request.
+ */
+ drv = *(struct scsi_driver **)req->rq_disk->private_data;
+ if (unlikely(!drv->init_command(cmd))) {
+ scsi_release_buffers(cmd);
+ scsi_put_command(cmd);
+ return BLKPREP_KILL;
}
+ return BLKPREP_OK;
+}
+
+static int scsi_prep_fn(struct request_queue *q, struct request *req)
+{
+ struct scsi_device *sdev = q->queuedata;
+ int ret = BLKPREP_OK;
+
/*
- * Find the actual device driver associated with this command.
- * The SPECIAL requests are things like character device or
- * ioctls, which did not originate from ll_rw_blk. Note that
- * the special field is also used to indicate the cmd for
- * the remainder of a partially fulfilled request that can
- * come up when there is a medium error. We have to treat
- * these two cases differently. We differentiate by looking
- * at request->cmd, as this tells us the real story.
+ * If the device is not in running state we will reject some
+ * or all commands.
*/
- if (blk_special_request(req) && req->special)
- cmd = req->special;
- else if (blk_pc_request(req) || blk_fs_request(req)) {
- if (unlikely(specials_only) && !(req->cmd_flags & REQ_PREEMPT)){
- if (specials_only == SDEV_QUIESCE ||
- specials_only == SDEV_BLOCK)
- goto defer;
-
+ if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {
+ switch (sdev->sdev_state) {
+ case SDEV_OFFLINE:
+ /*
+ * If the device is offline we refuse to process any
+ * commands. The device must be brought online
+ * before trying any recovery commands.
+ */
sdev_printk(KERN_ERR, sdev,
- "rejecting I/O to device being removed\n");
- goto kill;
+ "rejecting I/O to offline device\n");
+ ret = BLKPREP_KILL;
+ break;
+ case SDEV_DEL:
+ /*
+ * If the device is fully deleted, we refuse to
+ * process any commands as well.
+ */
+ sdev_printk(KERN_ERR, sdev,
+ "rejecting I/O to dead device\n");
+ ret = BLKPREP_KILL;
+ break;
+ case SDEV_QUIESCE:
+ case SDEV_BLOCK:
+ /*
+ * If the devices is blocked we defer normal commands.
+ */
+ if (!(req->cmd_flags & REQ_PREEMPT))
+ ret = BLKPREP_DEFER;
+ break;
+ default:
+ /*
+ * For any other not fully online state we only allow
+ * special commands. In particular any user initiated
+ * command is not allowed.
+ */
+ if (!(req->cmd_flags & REQ_PREEMPT))
+ ret = BLKPREP_KILL;
+ break;
}
-
- /*
- * Now try and find a command block that we can use.
- */
- if (!req->special) {
- cmd = scsi_get_command(sdev, GFP_ATOMIC);
- if (unlikely(!cmd))
- goto defer;
- } else
- cmd = req->special;
-
- /* pull a tag out of the request if we have one */
- cmd->tag = req->tag;
- } else {
- blk_dump_rq_flags(req, "SCSI bad req");
- goto kill;
+
+ if (ret != BLKPREP_OK)
+ goto out;
}
-
- /* note the overloading of req->special. When the tag
- * is active it always means cmd. If the tag goes
- * back for re-queueing, it may be reset */
- req->special = cmd;
- cmd->request = req;
-
- /*
- * FIXME: drop the lock here because the functions below
- * expect to be called without the queue lock held. Also,
- * previously, we dequeued the request before dropping the
- * lock. We hope REQ_STARTED prevents anything untoward from
- * happening now.
- */
- if (blk_fs_request(req) || blk_pc_request(req)) {
- int ret;
+ switch (req->cmd_type) {
+ case REQ_TYPE_BLOCK_PC:
+ ret = scsi_setup_blk_pc_cmnd(sdev, req);
+ break;
+ case REQ_TYPE_FS:
+ ret = scsi_setup_fs_cmnd(sdev, req);
+ break;
+ default:
/*
- * This will do a couple of things:
- * 1) Fill in the actual SCSI command.
- * 2) Fill in any other upper-level specific fields
- * (timeout).
+ * All other command types are not supported.
*
- * If this returns 0, it means that the request failed
- * (reading past end of disk, reading offline device,
- * etc). This won't actually talk to the device, but
- * some kinds of consistency checking may cause the
- * request to be rejected immediately.
+ * Note that these days the SCSI subsystem does not use
+ * REQ_TYPE_SPECIAL requests anymore. These are only used
+ * (directly or via blk_insert_request) by non-SCSI drivers.
*/
+ blk_dump_rq_flags(req, "SCSI bad req");
+ ret = BLKPREP_KILL;
+ break;
+ }
- /*
- * This sets up the scatter-gather table (allocating if
- * required).
- */
- ret = scsi_init_io(cmd);
- switch(ret) {
- /* For BLKPREP_KILL/DEFER the cmd was released */
- case BLKPREP_KILL:
- goto kill;
- case BLKPREP_DEFER:
- goto defer;
- }
-
+ out:
+ switch (ret) {
+ case BLKPREP_KILL:
+ req->errors = DID_NO_CONNECT << 16;
+ break;
+ case BLKPREP_DEFER:
/*
- * Initialize the actual SCSI command for this request.
+ * If we defer, the elv_next_request() returns NULL, but the
+ * queue must be restarted, so we plug here if no returning
+ * command will automatically do that.
*/
- if (blk_pc_request(req)) {
- scsi_setup_blk_pc_cmnd(cmd);
- } else if (req->rq_disk) {
- struct scsi_driver *drv;
-
- drv = *(struct scsi_driver **)req->rq_disk->private_data;
- if (unlikely(!drv->init_command(cmd))) {
- scsi_release_buffers(cmd);
- scsi_put_command(cmd);
- goto kill;
- }
- }
+ if (sdev->device_busy == 0)
+ blk_plug_device(q);
+ break;
+ default:
+ req->cmd_flags |= REQ_DONTPREP;
}
- /*
- * The request is now prepped, no need to come back here
- */
- req->cmd_flags |= REQ_DONTPREP;
- return BLKPREP_OK;
-
- defer:
- /* If we defer, the elv_next_request() returns NULL, but the
- * queue must be restarted, so we plug here if no returning
- * command will automatically do that. */
- if (sdev->device_busy == 0)
- blk_plug_device(q);
- return BLKPREP_DEFER;
- kill:
- req->errors = DID_NO_CONNECT << 16;
- return BLKPREP_KILL;
+ return ret;
}
/*
@@ -1548,29 +1571,40 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(scsi_calculate_bounce_limit);
-struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
+struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
+ request_fn_proc *request_fn)
{
- struct Scsi_Host *shost = sdev->host;
struct request_queue *q;
- q = blk_init_queue(scsi_request_fn, NULL);
+ q = blk_init_queue(request_fn, NULL);
if (!q)
return NULL;
- blk_queue_prep_rq(q, scsi_prep_fn);
-
blk_queue_max_hw_segments(q, shost->sg_tablesize);
blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS);
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
blk_queue_segment_boundary(q, shost->dma_boundary);
- blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
- blk_queue_softirq_done(q, scsi_softirq_done);
if (!shost->use_clustering)
clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
return q;
}
+EXPORT_SYMBOL(__scsi_alloc_queue);
+
+struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
+{
+ struct request_queue *q;
+
+ q = __scsi_alloc_queue(sdev->host, scsi_request_fn);
+ if (!q)
+ return NULL;
+
+ blk_queue_prep_rq(q, scsi_prep_fn);
+ blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
+ blk_queue_softirq_done(q, scsi_softirq_done);
+ return q;
+}
void scsi_free_queue(struct request_queue *q)
{
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 5d023d44e5e7..f458c2f686d2 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -39,6 +39,9 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
{ };
#endif
+/* scsi_scan.c */
+int scsi_complete_async_scans(void);
+
/* scsi_devinfo.c */
extern int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor,
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 94a274645f6f..14e635aa44ce 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -29,7 +29,9 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/blkdev.h>
-#include <asm/semaphore.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -87,6 +89,17 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(max_luns,
"last scsi LUN (should be between 1 and 2^32-1)");
+#ifdef CONFIG_SCSI_SCAN_ASYNC
+#define SCSI_SCAN_TYPE_DEFAULT "async"
+#else
+#define SCSI_SCAN_TYPE_DEFAULT "sync"
+#endif
+
+static char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
+
+module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
+MODULE_PARM_DESC(scan, "sync, async or none");
+
/*
* max_scsi_report_luns: the maximum number of LUNS that will be
* returned from the REPORT LUNS command. 8 times this value must
@@ -108,6 +121,68 @@ MODULE_PARM_DESC(inq_timeout,
"Timeout (in seconds) waiting for devices to answer INQUIRY."
" Default is 5. Some non-compliant devices need more.");
+static DEFINE_SPINLOCK(async_scan_lock);
+static LIST_HEAD(scanning_hosts);
+
+struct async_scan_data {
+ struct list_head list;
+ struct Scsi_Host *shost;
+ struct completion prev_finished;
+};
+
+/**
+ * scsi_complete_async_scans - Wait for asynchronous scans to complete
+ *
+ * Asynchronous scans add themselves to the scanning_hosts list. Once
+ * that list is empty, we know that the scans are complete. Rather than
+ * waking up periodically to check the state of the list, we pretend to be
+ * a scanning task by adding ourselves at the end of the list and going to
+ * sleep. When the task before us wakes us up, we take ourselves off the
+ * list and return.
+ */
+int scsi_complete_async_scans(void)
+{
+ struct async_scan_data *data;
+
+ do {
+ if (list_empty(&scanning_hosts))
+ return 0;
+ /* If we can't get memory immediately, that's OK. Just
+ * sleep a little. Even if we never get memory, the async
+ * scans will finish eventually.
+ */
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ msleep(1);
+ } while (!data);
+
+ data->shost = NULL;
+ init_completion(&data->prev_finished);
+
+ spin_lock(&async_scan_lock);
+ /* Check that there's still somebody else on the list */
+ if (list_empty(&scanning_hosts))
+ goto done;
+ list_add_tail(&data->list, &scanning_hosts);
+ spin_unlock(&async_scan_lock);
+
+ printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n");
+ wait_for_completion(&data->prev_finished);
+
+ spin_lock(&async_scan_lock);
+ list_del(&data->list);
+ done:
+ spin_unlock(&async_scan_lock);
+
+ kfree(data);
+ return 0;
+}
+
+#ifdef MODULE
+/* Only exported for the benefit of scsi_wait_scan */
+EXPORT_SYMBOL_GPL(scsi_complete_async_scans);
+#endif
+
/**
* scsi_unlock_floptical - unlock device via a special MODE SENSE command
* @sdev: scsi device to send command to
@@ -362,9 +437,10 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
goto retry;
}
-static void scsi_target_reap_usercontext(void *data)
+static void scsi_target_reap_usercontext(struct work_struct *work)
{
- struct scsi_target *starget = data;
+ struct scsi_target *starget =
+ container_of(work, struct scsi_target, ew.work);
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
@@ -400,7 +476,7 @@ void scsi_target_reap(struct scsi_target *starget)
starget->state = STARGET_DEL;
spin_unlock_irqrestore(shost->host_lock, flags);
execute_in_process_context(scsi_target_reap_usercontext,
- starget, &starget->ew);
+ &starget->ew);
return;
}
@@ -619,7 +695,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
* SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
**/
static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
- int *bflags)
+ int *bflags, int async)
{
/*
* XXX do not save the inquiry, since it can change underneath us,
@@ -805,7 +881,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
* register it and tell the rest of the kernel
* about it.
*/
- if (scsi_sysfs_add_sdev(sdev) != 0)
+ if (!async && scsi_sysfs_add_sdev(sdev) != 0)
return SCSI_SCAN_NO_RESPONSE;
return SCSI_SCAN_LUN_PRESENT;
@@ -974,7 +1050,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
goto out_free_result;
}
- res = scsi_add_lun(sdev, result, &bflags);
+ res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
if (res == SCSI_SCAN_LUN_PRESENT) {
if (bflags & BLIST_KEY) {
sdev->lockable = 0;
@@ -1474,6 +1550,12 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
{
struct Scsi_Host *shost = dev_to_shost(parent);
+ if (strncmp(scsi_scan_type, "none", 4) == 0)
+ return;
+
+ if (!shost->async_scan)
+ scsi_complete_async_scans();
+
mutex_lock(&shost->scan_mutex);
if (scsi_host_scan_allowed(shost))
__scsi_scan_target(parent, channel, id, lun, rescan);
@@ -1519,6 +1601,9 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
"%s: <%u:%u:%u>\n",
__FUNCTION__, channel, id, lun));
+ if (!shost->async_scan)
+ scsi_complete_async_scans();
+
if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
@@ -1539,14 +1624,143 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
return 0;
}
+static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
+{
+ struct scsi_device *sdev;
+ shost_for_each_device(sdev, shost) {
+ if (scsi_sysfs_add_sdev(sdev) != 0)
+ scsi_destroy_sdev(sdev);
+ }
+}
+
+/**
+ * scsi_prep_async_scan - prepare for an async scan
+ * @shost: the host which will be scanned
+ * Returns: a cookie to be passed to scsi_finish_async_scan()
+ *
+ * Tells the midlayer this host is going to do an asynchronous scan.
+ * It reserves the host's position in the scanning list and ensures
+ * that other asynchronous scans started after this one won't affect the
+ * ordering of the discovered devices.
+ */
+static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
+{
+ struct async_scan_data *data;
+
+ if (strncmp(scsi_scan_type, "sync", 4) == 0)
+ return NULL;
+
+ if (shost->async_scan) {
+ printk("%s called twice for host %d", __FUNCTION__,
+ shost->host_no);
+ dump_stack();
+ return NULL;
+ }
+
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ goto err;
+ data->shost = scsi_host_get(shost);
+ if (!data->shost)
+ goto err;
+ init_completion(&data->prev_finished);
+
+ spin_lock(&async_scan_lock);
+ shost->async_scan = 1;
+ if (list_empty(&scanning_hosts))
+ complete(&data->prev_finished);
+ list_add_tail(&data->list, &scanning_hosts);
+ spin_unlock(&async_scan_lock);
+
+ return data;
+
+ err:
+ kfree(data);
+ return NULL;
+}
+
+/**
+ * scsi_finish_async_scan - asynchronous scan has finished
+ * @data: cookie returned from earlier call to scsi_prep_async_scan()
+ *
+ * All the devices currently attached to this host have been found.
+ * This function announces all the devices it has found to the rest
+ * of the system.
+ */
+static void scsi_finish_async_scan(struct async_scan_data *data)
+{
+ struct Scsi_Host *shost;
+
+ if (!data)
+ return;
+
+ shost = data->shost;
+ if (!shost->async_scan) {
+ printk("%s called twice for host %d", __FUNCTION__,
+ shost->host_no);
+ dump_stack();
+ return;
+ }
+
+ wait_for_completion(&data->prev_finished);
+
+ scsi_sysfs_add_devices(shost);
+
+ spin_lock(&async_scan_lock);
+ shost->async_scan = 0;
+ list_del(&data->list);
+ if (!list_empty(&scanning_hosts)) {
+ struct async_scan_data *next = list_entry(scanning_hosts.next,
+ struct async_scan_data, list);
+ complete(&next->prev_finished);
+ }
+ spin_unlock(&async_scan_lock);
+
+ scsi_host_put(shost);
+ kfree(data);
+}
+
+static void do_scsi_scan_host(struct Scsi_Host *shost)
+{
+ if (shost->hostt->scan_finished) {
+ unsigned long start = jiffies;
+ if (shost->hostt->scan_start)
+ shost->hostt->scan_start(shost);
+
+ while (!shost->hostt->scan_finished(shost, jiffies - start))
+ msleep(10);
+ } else {
+ scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
+ SCAN_WILD_CARD, 0);
+ }
+}
+
+static int do_scan_async(void *_data)
+{
+ struct async_scan_data *data = _data;
+ do_scsi_scan_host(data->shost);
+ scsi_finish_async_scan(data);
+ return 0;
+}
+
/**
* scsi_scan_host - scan the given adapter
* @shost: adapter to scan
**/
void scsi_scan_host(struct Scsi_Host *shost)
{
- scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
- SCAN_WILD_CARD, 0);
+ struct async_scan_data *data;
+
+ if (strncmp(scsi_scan_type, "none", 4) == 0)
+ return;
+
+ data = scsi_prep_async_scan(shost);
+ if (!data) {
+ do_scsi_scan_host(shost);
+ return;
+ }
+
+ kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
}
EXPORT_SYMBOL(scsi_scan_host);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e1a91665d1c2..259c90cfa367 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -218,16 +218,16 @@ static void scsi_device_cls_release(struct class_device *class_dev)
put_device(&sdev->sdev_gendev);
}
-static void scsi_device_dev_release_usercontext(void *data)
+static void scsi_device_dev_release_usercontext(struct work_struct *work)
{
- struct device *dev = data;
struct scsi_device *sdev;
struct device *parent;
struct scsi_target *starget;
unsigned long flags;
- parent = dev->parent;
- sdev = to_scsi_device(dev);
+ sdev = container_of(work, struct scsi_device, ew.work);
+
+ parent = sdev->sdev_gendev.parent;
starget = to_scsi_target(parent);
spin_lock_irqsave(sdev->host->host_lock, flags);
@@ -258,7 +258,7 @@ static void scsi_device_dev_release_usercontext(void *data)
static void scsi_device_dev_release(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
- execute_in_process_context(scsi_device_dev_release_usercontext, dev,
+ execute_in_process_context(scsi_device_dev_release_usercontext,
&sdp->ew);
}
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
new file mode 100644
index 000000000000..37bbfbdb870f
--- /dev/null
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -0,0 +1,352 @@
+/*
+ * SCSI target kernel/user interface functions
+ *
+ * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/miscdevice.h>
+#include <linux/file.h>
+#include <net/tcp.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tgt.h>
+#include <scsi/scsi_tgt_if.h>
+
+#include <asm/cacheflush.h>
+
+#include "scsi_tgt_priv.h"
+
+struct tgt_ring {
+ u32 tr_idx;
+ unsigned long tr_pages[TGT_RING_PAGES];
+ spinlock_t tr_lock;
+};
+
+/* tx_ring : kernel->user, rx_ring : user->kernel */
+static struct tgt_ring tx_ring, rx_ring;
+static DECLARE_WAIT_QUEUE_HEAD(tgt_poll_wait);
+
+static inline void tgt_ring_idx_inc(struct tgt_ring *ring)
+{
+ if (ring->tr_idx == TGT_MAX_EVENTS - 1)
+ ring->tr_idx = 0;
+ else
+ ring->tr_idx++;
+}
+
+static struct tgt_event *tgt_head_event(struct tgt_ring *ring, u32 idx)
+{
+ u32 pidx, off;
+
+ pidx = idx / TGT_EVENT_PER_PAGE;
+ off = idx % TGT_EVENT_PER_PAGE;
+
+ return (struct tgt_event *)
+ (ring->tr_pages[pidx] + sizeof(struct tgt_event) * off);
+}
+
+static int tgt_uspace_send_event(u32 type, struct tgt_event *p)
+{
+ struct tgt_event *ev;
+ struct tgt_ring *ring = &tx_ring;
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&ring->tr_lock, flags);
+
+ ev = tgt_head_event(ring, ring->tr_idx);
+ if (!ev->hdr.status)
+ tgt_ring_idx_inc(ring);
+ else
+ err = -BUSY;
+
+ spin_unlock_irqrestore(&ring->tr_lock, flags);
+
+ if (err)
+ return err;
+
+ memcpy(ev, p, sizeof(*ev));
+ ev->hdr.type = type;
+ mb();
+ ev->hdr.status = 1;
+
+ flush_dcache_page(virt_to_page(ev));
+
+ wake_up_interruptible(&tgt_poll_wait);
+
+ return 0;
+}
+
+int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag)
+{
+ struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
+ struct tgt_event ev;
+ int err;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.p.cmd_req.host_no = shost->host_no;
+ ev.p.cmd_req.data_len = cmd->request_bufflen;
+ memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb));
+ memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun));
+ ev.p.cmd_req.attribute = cmd->tag;
+ ev.p.cmd_req.tag = tag;
+
+ dprintk("%p %d %u %x %llx\n", cmd, shost->host_no,
+ ev.p.cmd_req.data_len, cmd->tag,
+ (unsigned long long) ev.p.cmd_req.tag);
+
+ err = tgt_uspace_send_event(TGT_KEVENT_CMD_REQ, &ev);
+ if (err)
+ eprintk("tx buf is full, could not send\n");
+
+ return err;
+}
+
+int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag)
+{
+ struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
+ struct tgt_event ev;
+ int err;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.p.cmd_done.host_no = shost->host_no;
+ ev.p.cmd_done.tag = tag;
+ ev.p.cmd_done.result = cmd->result;
+
+ dprintk("%p %d %llu %u %x\n", cmd, shost->host_no,
+ (unsigned long long) ev.p.cmd_req.tag,
+ ev.p.cmd_req.data_len, cmd->tag);
+
+ err = tgt_uspace_send_event(TGT_KEVENT_CMD_DONE, &ev);
+ if (err)
+ eprintk("tx buf is full, could not send\n");
+
+ return err;
+}
+
+int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag,
+ struct scsi_lun *scsilun, void *data)
+{
+ struct tgt_event ev;
+ int err;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.p.tsk_mgmt_req.host_no = host_no;
+ ev.p.tsk_mgmt_req.function = function;
+ ev.p.tsk_mgmt_req.tag = tag;
+ memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun));
+ ev.p.tsk_mgmt_req.mid = (u64) (unsigned long) data;
+
+ dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag,
+ (unsigned long long) ev.p.tsk_mgmt_req.mid);
+
+ err = tgt_uspace_send_event(TGT_KEVENT_TSK_MGMT_REQ, &ev);
+ if (err)
+ eprintk("tx buf is full, could not send\n");
+
+ return err;
+}
+
+static int event_recv_msg(struct tgt_event *ev)
+{
+ int err = 0;
+
+ switch (ev->hdr.type) {
+ case TGT_UEVENT_CMD_RSP:
+ err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no,
+ ev->p.cmd_rsp.tag,
+ ev->p.cmd_rsp.result,
+ ev->p.cmd_rsp.len,
+ ev->p.cmd_rsp.uaddr,
+ ev->p.cmd_rsp.rw);
+ break;
+ case TGT_UEVENT_TSK_MGMT_RSP:
+ err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no,
+ ev->p.tsk_mgmt_rsp.mid,
+ ev->p.tsk_mgmt_rsp.result);
+ break;
+ default:
+ eprintk("unknown type %d\n", ev->hdr.type);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static ssize_t tgt_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ struct tgt_event *ev;
+ struct tgt_ring *ring = &rx_ring;
+
+ while (1) {
+ ev = tgt_head_event(ring, ring->tr_idx);
+ /* do we need this? */
+ flush_dcache_page(virt_to_page(ev));
+
+ if (!ev->hdr.status)
+ break;
+
+ tgt_ring_idx_inc(ring);
+ event_recv_msg(ev);
+ ev->hdr.status = 0;
+ };
+
+ return count;
+}
+
+static unsigned int tgt_poll(struct file * file, struct poll_table_struct *wait)
+{
+ struct tgt_event *ev;
+ struct tgt_ring *ring = &tx_ring;
+ unsigned long flags;
+ unsigned int mask = 0;
+ u32 idx;
+
+ poll_wait(file, &tgt_poll_wait, wait);
+
+ spin_lock_irqsave(&ring->tr_lock, flags);
+
+ idx = ring->tr_idx ? ring->tr_idx - 1 : TGT_MAX_EVENTS - 1;
+ ev = tgt_head_event(ring, idx);
+ if (ev->hdr.status)
+ mask |= POLLIN | POLLRDNORM;
+
+ spin_unlock_irqrestore(&ring->tr_lock, flags);
+
+ return mask;
+}
+
+static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr,
+ struct tgt_ring *ring)
+{
+ int i, err;
+
+ for (i = 0; i < TGT_RING_PAGES; i++) {
+ struct page *page = virt_to_page(ring->tr_pages[i]);
+ err = vm_insert_page(vma, addr, page);
+ if (err)
+ return err;
+ addr += PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+static int tgt_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long addr;
+ int err;
+
+ if (vma->vm_pgoff)
+ return -EINVAL;
+
+ if (vma->vm_end - vma->vm_start != TGT_RING_SIZE * 2) {
+ eprintk("mmap size must be %lu, not %lu \n",
+ TGT_RING_SIZE * 2, vma->vm_end - vma->vm_start);
+ return -EINVAL;
+ }
+
+ addr = vma->vm_start;
+ err = uspace_ring_map(vma, addr, &tx_ring);
+ if (err)
+ return err;
+ err = uspace_ring_map(vma, addr + TGT_RING_SIZE, &rx_ring);
+
+ return err;
+}
+
+static int tgt_open(struct inode *inode, struct file *file)
+{
+ tx_ring.tr_idx = rx_ring.tr_idx = 0;
+
+ return 0;
+}
+
+static struct file_operations tgt_fops = {
+ .owner = THIS_MODULE,
+ .open = tgt_open,
+ .poll = tgt_poll,
+ .write = tgt_write,
+ .mmap = tgt_mmap,
+};
+
+static struct miscdevice tgt_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "tgt",
+ .fops = &tgt_fops,
+};
+
+static void tgt_ring_exit(struct tgt_ring *ring)
+{
+ int i;
+
+ for (i = 0; i < TGT_RING_PAGES; i++)
+ free_page(ring->tr_pages[i]);
+}
+
+static int tgt_ring_init(struct tgt_ring *ring)
+{
+ int i;
+
+ spin_lock_init(&ring->tr_lock);
+
+ for (i = 0; i < TGT_RING_PAGES; i++) {
+ ring->tr_pages[i] = get_zeroed_page(GFP_KERNEL);
+ if (!ring->tr_pages[i]) {
+ eprintk("out of memory\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+void scsi_tgt_if_exit(void)
+{
+ tgt_ring_exit(&tx_ring);
+ tgt_ring_exit(&rx_ring);
+ misc_deregister(&tgt_miscdev);
+}
+
+int scsi_tgt_if_init(void)
+{
+ int err;
+
+ err = tgt_ring_init(&tx_ring);
+ if (err)
+ return err;
+
+ err = tgt_ring_init(&rx_ring);
+ if (err)
+ goto free_tx_ring;
+
+ err = misc_register(&tgt_miscdev);
+ if (err)
+ goto free_rx_ring;
+
+ return 0;
+free_rx_ring:
+ tgt_ring_exit(&rx_ring);
+free_tx_ring:
+ tgt_ring_exit(&tx_ring);
+
+ return err;
+}
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
new file mode 100644
index 000000000000..386dbae17b44
--- /dev/null
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -0,0 +1,745 @@
+/*
+ * SCSI target lib functions
+ *
+ * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
+ * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/blkdev.h>
+#include <linux/hash.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tgt.h>
+#include <../drivers/md/dm-bio-list.h>
+
+#include "scsi_tgt_priv.h"
+
+static struct workqueue_struct *scsi_tgtd;
+static kmem_cache_t *scsi_tgt_cmd_cache;
+
+/*
+ * TODO: this struct will be killed when the block layer supports large bios
+ * and James's work struct code is in
+ */
+struct scsi_tgt_cmd {
+ /* TODO replace work with James b's code */
+ struct work_struct work;
+ /* TODO replace the lists with a large bio */
+ struct bio_list xfer_done_list;
+ struct bio_list xfer_list;
+
+ struct list_head hash_list;
+ struct request *rq;
+ u64 tag;
+
+ void *buffer;
+ unsigned bufflen;
+};
+
+#define TGT_HASH_ORDER 4
+#define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER)
+
+struct scsi_tgt_queuedata {
+ struct Scsi_Host *shost;
+ struct list_head cmd_hash[1 << TGT_HASH_ORDER];
+ spinlock_t cmd_hash_lock;
+};
+
+/*
+ * Function: scsi_host_get_command()
+ *
+ * Purpose: Allocate and setup a scsi command block and blk request
+ *
+ * Arguments: shost - scsi host
+ * data_dir - dma data dir
+ * gfp_mask- allocator flags
+ *
+ * Returns: The allocated scsi command structure.
+ *
+ * This should be called by target LLDs to get a command.
+ */
+struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
+ enum dma_data_direction data_dir,
+ gfp_t gfp_mask)
+{
+ int write = (data_dir == DMA_TO_DEVICE);
+ struct request *rq;
+ struct scsi_cmnd *cmd;
+ struct scsi_tgt_cmd *tcmd;
+
+ /* Bail if we can't get a reference to the device */
+ if (!get_device(&shost->shost_gendev))
+ return NULL;
+
+ tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC);
+ if (!tcmd)
+ goto put_dev;
+
+ rq = blk_get_request(shost->uspace_req_q, write, gfp_mask);
+ if (!rq)
+ goto free_tcmd;
+
+ cmd = __scsi_get_command(shost, gfp_mask);
+ if (!cmd)
+ goto release_rq;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->sc_data_direction = data_dir;
+ cmd->jiffies_at_alloc = jiffies;
+ cmd->request = rq;
+
+ rq->special = cmd;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
+ rq->end_io_data = tcmd;
+
+ bio_list_init(&tcmd->xfer_list);
+ bio_list_init(&tcmd->xfer_done_list);
+ tcmd->rq = rq;
+
+ return cmd;
+
+release_rq:
+ blk_put_request(rq);
+free_tcmd:
+ kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
+put_dev:
+ put_device(&shost->shost_gendev);
+ return NULL;
+
+}
+EXPORT_SYMBOL_GPL(scsi_host_get_command);
+
+/*
+ * Function: scsi_host_put_command()
+ *
+ * Purpose: Free a scsi command block
+ *
+ * Arguments: shost - scsi host
+ * cmd - command block to free
+ *
+ * Returns: Nothing.
+ *
+ * Notes: The command must not belong to any lists.
+ */
+void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+{
+ struct request_queue *q = shost->uspace_req_q;
+ struct request *rq = cmd->request;
+ struct scsi_tgt_cmd *tcmd = rq->end_io_data;
+ unsigned long flags;
+
+ kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ __blk_put_request(q, rq);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ __scsi_put_command(shost, cmd, &shost->shost_gendev);
+}
+EXPORT_SYMBOL_GPL(scsi_host_put_command);
+
+static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd)
+{
+ struct bio *bio;
+
+ /* must call bio_endio in case bio was bounced */
+ while ((bio = bio_list_pop(&tcmd->xfer_done_list))) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ }
+
+ while ((bio = bio_list_pop(&tcmd->xfer_list))) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ }
+}
+
+static void cmd_hashlist_del(struct scsi_cmnd *cmd)
+{
+ struct request_queue *q = cmd->request->q;
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
+ unsigned long flags;
+ struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ list_del(&tcmd->hash_list);
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+}
+
+static void scsi_tgt_cmd_destroy(struct work_struct *work)
+{
+ struct scsi_tgt_cmd *tcmd =
+ container_of(work, struct scsi_tgt_cmd, work);
+ struct scsi_cmnd *cmd = tcmd->rq->special;
+
+ dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction,
+ rq_data_dir(cmd->request));
+ /*
+ * We fix rq->cmd_flags here since when we told bio_map_user
+ * to write vm for WRITE commands, blk_rq_bio_prep set
+ * rq_data_dir the flags to READ.
+ */
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ cmd->request->cmd_flags |= REQ_RW;
+ else
+ cmd->request->cmd_flags &= ~REQ_RW;
+
+ scsi_unmap_user_pages(tcmd);
+ scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd);
+}
+
+static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd,
+ u64 tag)
+{
+ struct scsi_tgt_queuedata *qdata = rq->q->queuedata;
+ unsigned long flags;
+ struct list_head *head;
+
+ tcmd->tag = tag;
+ INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy);
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ head = &qdata->cmd_hash[cmd_hashfn(tag)];
+ list_add(&tcmd->hash_list, head);
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+}
+
+/*
+ * scsi_tgt_alloc_queue - setup queue used for message passing
+ * shost: scsi host
+ *
+ * This should be called by the LLD after host allocation.
+ * And will be released when the host is released.
+ */
+int scsi_tgt_alloc_queue(struct Scsi_Host *shost)
+{
+ struct scsi_tgt_queuedata *queuedata;
+ struct request_queue *q;
+ int err, i;
+
+ /*
+ * Do we need to send a netlink event or should uspace
+ * just respond to the hotplug event?
+ */
+ q = __scsi_alloc_queue(shost, NULL);
+ if (!q)
+ return -ENOMEM;
+
+ queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL);
+ if (!queuedata) {
+ err = -ENOMEM;
+ goto cleanup_queue;
+ }
+ queuedata->shost = shost;
+ q->queuedata = queuedata;
+
+ /*
+ * this is a silly hack. We should probably just queue as many
+ * command as is recvd to userspace. uspace can then make
+ * sure we do not overload the HBA
+ */
+ q->nr_requests = shost->hostt->can_queue;
+ /*
+ * We currently only support software LLDs so this does
+ * not matter for now. Do we need this for the cards we support?
+ * If so we should make it a host template value.
+ */
+ blk_queue_dma_alignment(q, 0);
+ shost->uspace_req_q = q;
+
+ for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++)
+ INIT_LIST_HEAD(&queuedata->cmd_hash[i]);
+ spin_lock_init(&queuedata->cmd_hash_lock);
+
+ return 0;
+
+cleanup_queue:
+ blk_cleanup_queue(q);
+ return err;
+}
+EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue);
+
+void scsi_tgt_free_queue(struct Scsi_Host *shost)
+{
+ int i;
+ unsigned long flags;
+ struct request_queue *q = shost->uspace_req_q;
+ struct scsi_cmnd *cmd;
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
+ struct scsi_tgt_cmd *tcmd, *n;
+ LIST_HEAD(cmds);
+
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+
+ for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) {
+ list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i],
+ hash_list) {
+ list_del(&tcmd->hash_list);
+ list_add(&tcmd->hash_list, &cmds);
+ }
+ }
+
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+
+ while (!list_empty(&cmds)) {
+ tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list);
+ list_del(&tcmd->hash_list);
+ cmd = tcmd->rq->special;
+
+ shost->hostt->eh_abort_handler(cmd);
+ scsi_tgt_cmd_destroy(&tcmd->work);
+ }
+}
+EXPORT_SYMBOL_GPL(scsi_tgt_free_queue);
+
+struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd)
+{
+ struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata;
+ return queue->shost;
+}
+EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host);
+
+/*
+ * scsi_tgt_queue_command - queue command for userspace processing
+ * @cmd: scsi command
+ * @scsilun: scsi lun
+ * @tag: unique value to identify this command for tmf
+ */
+int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun,
+ u64 tag)
+{
+ struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+ int err;
+
+ init_scsi_tgt_cmd(cmd->request, tcmd, tag);
+ err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag);
+ if (err)
+ cmd_hashlist_del(cmd);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(scsi_tgt_queue_command);
+
+/*
+ * This is run from a interrpt handler normally and the unmap
+ * needs process context so we must queue
+ */
+static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
+{
+ struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+
+ dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request));
+
+ scsi_tgt_uspace_send_status(cmd, tcmd->tag);
+ queue_work(scsi_tgtd, &tcmd->work);
+}
+
+static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd)
+{
+ struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
+ int err;
+
+ dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request));
+
+ err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done);
+ switch (err) {
+ case SCSI_MLQUEUE_HOST_BUSY:
+ case SCSI_MLQUEUE_DEVICE_BUSY:
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd)
+{
+ struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+ int err;
+
+ err = __scsi_tgt_transfer_response(cmd);
+ if (!err)
+ return;
+
+ cmd->result = DID_BUS_BUSY << 16;
+ err = scsi_tgt_uspace_send_status(cmd, tcmd->tag);
+ if (err <= 0)
+ /* the eh will have to pick this up */
+ printk(KERN_ERR "Could not send cmd %p status\n", cmd);
+}
+
+static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+ struct request *rq = cmd->request;
+ struct scsi_tgt_cmd *tcmd = rq->end_io_data;
+ int count;
+
+ cmd->use_sg = rq->nr_phys_segments;
+ cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask);
+ if (!cmd->request_buffer)
+ return -ENOMEM;
+
+ cmd->request_bufflen = rq->data_len;
+
+ dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg,
+ rq_data_dir(rq));
+ count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer);
+ if (likely(count <= cmd->use_sg)) {
+ cmd->use_sg = count;
+ return 0;
+ }
+
+ eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg);
+ scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+ return -EINVAL;
+}
+
+/* TODO: test this crap and replace bio_map_user with new interface maybe */
+static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
+ int rw)
+{
+ struct request_queue *q = cmd->request->q;
+ struct request *rq = cmd->request;
+ void *uaddr = tcmd->buffer;
+ unsigned int len = tcmd->bufflen;
+ struct bio *bio;
+ int err;
+
+ while (len > 0) {
+ dprintk("%lx %u\n", (unsigned long) uaddr, len);
+ bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw);
+ if (IS_ERR(bio)) {
+ err = PTR_ERR(bio);
+ dprintk("fail to map %lx %u %d %x\n",
+ (unsigned long) uaddr, len, err, cmd->cmnd[0]);
+ goto unmap_bios;
+ }
+
+ uaddr += bio->bi_size;
+ len -= bio->bi_size;
+
+ /*
+ * The first bio is added and merged. We could probably
+ * try to add others using scsi_merge_bio() but for now
+ * we keep it simple. The first bio should be pretty large
+ * (either hitting the 1 MB bio pages limit or a queue limit)
+ * already but for really large IO we may want to try and
+ * merge these.
+ */
+ if (!rq->bio) {
+ blk_rq_bio_prep(q, rq, bio);
+ rq->data_len = bio->bi_size;
+ } else
+ /* put list of bios to transfer in next go around */
+ bio_list_add(&tcmd->xfer_list, bio);
+ }
+
+ cmd->offset = 0;
+ err = scsi_tgt_init_cmd(cmd, GFP_KERNEL);
+ if (err)
+ goto unmap_bios;
+
+ return 0;
+
+unmap_bios:
+ if (rq->bio) {
+ bio_unmap_user(rq->bio);
+ while ((bio = bio_list_pop(&tcmd->xfer_list)))
+ bio_unmap_user(bio);
+ }
+
+ return err;
+}
+
+static int scsi_tgt_transfer_data(struct scsi_cmnd *);
+
+static void scsi_tgt_data_transfer_done(struct scsi_cmnd *cmd)
+{
+ struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+ struct bio *bio;
+ int err;
+
+ /* should we free resources here on error ? */
+ if (cmd->result) {
+send_uspace_err:
+ err = scsi_tgt_uspace_send_status(cmd, tcmd->tag);
+ if (err <= 0)
+ /* the tgt uspace eh will have to pick this up */
+ printk(KERN_ERR "Could not send cmd %p status\n", cmd);
+ return;
+ }
+
+ dprintk("cmd %p request_bufflen %u bufflen %u\n",
+ cmd, cmd->request_bufflen, tcmd->bufflen);
+
+ scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+ bio_list_add(&tcmd->xfer_done_list, cmd->request->bio);
+
+ tcmd->buffer += cmd->request_bufflen;
+ cmd->offset += cmd->request_bufflen;
+
+ if (!tcmd->xfer_list.head) {
+ scsi_tgt_transfer_response(cmd);
+ return;
+ }
+
+ dprintk("cmd2 %p request_bufflen %u bufflen %u\n",
+ cmd, cmd->request_bufflen, tcmd->bufflen);
+
+ bio = bio_list_pop(&tcmd->xfer_list);
+ BUG_ON(!bio);
+
+ blk_rq_bio_prep(cmd->request->q, cmd->request, bio);
+ cmd->request->data_len = bio->bi_size;
+ err = scsi_tgt_init_cmd(cmd, GFP_ATOMIC);
+ if (err) {
+ cmd->result = DID_ERROR << 16;
+ goto send_uspace_err;
+ }
+
+ if (scsi_tgt_transfer_data(cmd)) {
+ cmd->result = DID_NO_CONNECT << 16;
+ goto send_uspace_err;
+ }
+}
+
+static int scsi_tgt_transfer_data(struct scsi_cmnd *cmd)
+{
+ int err;
+ struct Scsi_Host *host = scsi_tgt_cmd_to_host(cmd);
+
+ err = host->hostt->transfer_data(cmd, scsi_tgt_data_transfer_done);
+ switch (err) {
+ case SCSI_MLQUEUE_HOST_BUSY:
+ case SCSI_MLQUEUE_DEVICE_BUSY:
+ return -EAGAIN;
+ default:
+ return 0;
+ }
+}
+
+static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr,
+ unsigned len)
+{
+ char __user *p = (char __user *) uaddr;
+
+ if (copy_from_user(cmd->sense_buffer, p,
+ min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) {
+ printk(KERN_ERR "Could not copy the sense buffer\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+{
+ struct scsi_tgt_cmd *tcmd;
+ int err;
+
+ err = shost->hostt->eh_abort_handler(cmd);
+ if (err)
+ eprintk("fail to abort %p\n", cmd);
+
+ tcmd = cmd->request->end_io_data;
+ scsi_tgt_cmd_destroy(&tcmd->work);
+ return err;
+}
+
+static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag)
+{
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
+ struct request *rq = NULL;
+ struct list_head *head;
+ struct scsi_tgt_cmd *tcmd;
+ unsigned long flags;
+
+ head = &qdata->cmd_hash[cmd_hashfn(tag)];
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ list_for_each_entry(tcmd, head, hash_list) {
+ if (tcmd->tag == tag) {
+ rq = tcmd->rq;
+ list_del(&tcmd->hash_list);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+
+ return rq;
+}
+
+int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len,
+ unsigned long uaddr, u8 rw)
+{
+ struct Scsi_Host *shost;
+ struct scsi_cmnd *cmd;
+ struct request *rq;
+ struct scsi_tgt_cmd *tcmd;
+ int err = 0;
+
+ dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag,
+ result, len, uaddr, rw);
+
+ /* TODO: replace with a O(1) alg */
+ shost = scsi_host_lookup(host_no);
+ if (IS_ERR(shost)) {
+ printk(KERN_ERR "Could not find host no %d\n", host_no);
+ return -EINVAL;
+ }
+
+ if (!shost->uspace_req_q) {
+ printk(KERN_ERR "Not target scsi host %d\n", host_no);
+ goto done;
+ }
+
+ rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag);
+ if (!rq) {
+ printk(KERN_ERR "Could not find tag %llu\n",
+ (unsigned long long) tag);
+ err = -EINVAL;
+ goto done;
+ }
+ cmd = rq->special;
+
+ dprintk("cmd %p result %d len %d bufflen %u %lu %x\n", cmd,
+ result, len, cmd->request_bufflen, rq_data_dir(rq), cmd->cmnd[0]);
+
+ if (result == TASK_ABORTED) {
+ scsi_tgt_abort_cmd(shost, cmd);
+ goto done;
+ }
+ /*
+ * store the userspace values here, the working values are
+ * in the request_* values
+ */
+ tcmd = cmd->request->end_io_data;
+ tcmd->buffer = (void *)uaddr;
+ tcmd->bufflen = len;
+ cmd->result = result;
+
+ if (!tcmd->bufflen || cmd->request_buffer) {
+ err = __scsi_tgt_transfer_response(cmd);
+ goto done;
+ }
+
+ /*
+ * TODO: Do we need to handle case where request does not
+ * align with LLD.
+ */
+ err = scsi_map_user_pages(rq->end_io_data, cmd, rw);
+ if (err) {
+ eprintk("%p %d\n", cmd, err);
+ err = -EAGAIN;
+ goto done;
+ }
+
+ /* userspace failure */
+ if (cmd->result) {
+ if (status_byte(cmd->result) == CHECK_CONDITION)
+ scsi_tgt_copy_sense(cmd, uaddr, len);
+ err = __scsi_tgt_transfer_response(cmd);
+ goto done;
+ }
+ /* ask the target LLD to transfer the data to the buffer */
+ err = scsi_tgt_transfer_data(cmd);
+
+done:
+ scsi_host_put(shost);
+ return err;
+}
+
+int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag,
+ struct scsi_lun *scsilun, void *data)
+{
+ int err;
+
+ /* TODO: need to retry if this fails. */
+ err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function,
+ tag, scsilun, data);
+ if (err < 0)
+ eprintk("The task management request lost!\n");
+ return err;
+}
+EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request);
+
+int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result)
+{
+ struct Scsi_Host *shost;
+ int err = -EINVAL;
+
+ dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid);
+
+ shost = scsi_host_lookup(host_no);
+ if (IS_ERR(shost)) {
+ printk(KERN_ERR "Could not find host no %d\n", host_no);
+ return err;
+ }
+
+ if (!shost->uspace_req_q) {
+ printk(KERN_ERR "Not target scsi host %d\n", host_no);
+ goto done;
+ }
+
+ err = shost->hostt->tsk_mgmt_response(mid, result);
+done:
+ scsi_host_put(shost);
+ return err;
+}
+
+static int __init scsi_tgt_init(void)
+{
+ int err;
+
+ scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd",
+ sizeof(struct scsi_tgt_cmd),
+ 0, 0, NULL, NULL);
+ if (!scsi_tgt_cmd_cache)
+ return -ENOMEM;
+
+ scsi_tgtd = create_workqueue("scsi_tgtd");
+ if (!scsi_tgtd) {
+ err = -ENOMEM;
+ goto free_kmemcache;
+ }
+
+ err = scsi_tgt_if_init();
+ if (err)
+ goto destroy_wq;
+
+ return 0;
+
+destroy_wq:
+ destroy_workqueue(scsi_tgtd);
+free_kmemcache:
+ kmem_cache_destroy(scsi_tgt_cmd_cache);
+ return err;
+}
+
+static void __exit scsi_tgt_exit(void)
+{
+ destroy_workqueue(scsi_tgtd);
+ scsi_tgt_if_exit();
+ kmem_cache_destroy(scsi_tgt_cmd_cache);
+}
+
+module_init(scsi_tgt_init);
+module_exit(scsi_tgt_exit);
+
+MODULE_DESCRIPTION("SCSI target core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h
new file mode 100644
index 000000000000..84488c51ff62
--- /dev/null
+++ b/drivers/scsi/scsi_tgt_priv.h
@@ -0,0 +1,25 @@
+struct scsi_cmnd;
+struct scsi_lun;
+struct Scsi_Host;
+struct task_struct;
+
+/* tmp - will replace with SCSI logging stuff */
+#define eprintk(fmt, args...) \
+do { \
+ printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \
+} while (0)
+
+#define dprintk(fmt, args...)
+/* #define dprintk eprintk */
+
+extern void scsi_tgt_if_exit(void);
+extern int scsi_tgt_if_init(void);
+
+extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun,
+ u64 tag);
+extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag);
+extern int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len,
+ unsigned long uaddr, u8 rw);
+extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag,
+ struct scsi_lun *scsilun, void *data);
+extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 38c215a78f69..3571ce8934e7 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -241,9 +241,9 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
#define FC_MGMTSRVR_PORTID 0x00000a
-static void fc_timeout_deleted_rport(void *data);
-static void fc_timeout_fail_rport_io(void *data);
-static void fc_scsi_scan_rport(void *data);
+static void fc_timeout_deleted_rport(struct work_struct *work);
+static void fc_timeout_fail_rport_io(struct work_struct *work);
+static void fc_scsi_scan_rport(struct work_struct *work);
/*
* Attribute counts pre object type...
@@ -1613,7 +1613,7 @@ fc_flush_work(struct Scsi_Host *shost)
* 1 on success / 0 already queued / < 0 for error
**/
static int
-fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work,
+fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
unsigned long delay)
{
if (unlikely(!fc_host_devloss_work_q(shost))) {
@@ -1625,9 +1625,6 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work,
return -EINVAL;
}
- if (delay == 0)
- return queue_work(fc_host_devloss_work_q(shost), work);
-
return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
}
@@ -1712,12 +1709,13 @@ EXPORT_SYMBOL(fc_remove_host);
* fc_starget_delete - called to delete the scsi decendents of an rport
* (target and all sdevs)
*
- * @data: remote port to be operated on.
+ * @work: remote port to be operated on.
**/
static void
-fc_starget_delete(void *data)
+fc_starget_delete(struct work_struct *work)
{
- struct fc_rport *rport = (struct fc_rport *)data;
+ struct fc_rport *rport =
+ container_of(work, struct fc_rport, stgt_delete_work);
struct Scsi_Host *shost = rport_to_shost(rport);
unsigned long flags;
struct fc_internal *i = to_fc_internal(shost->transportt);
@@ -1751,12 +1749,13 @@ fc_starget_delete(void *data)
/**
* fc_rport_final_delete - finish rport termination and delete it.
*
- * @data: remote port to be deleted.
+ * @work: remote port to be deleted.
**/
static void
-fc_rport_final_delete(void *data)
+fc_rport_final_delete(struct work_struct *work)
{
- struct fc_rport *rport = (struct fc_rport *)data;
+ struct fc_rport *rport =
+ container_of(work, struct fc_rport, rport_delete_work);
struct device *dev = &rport->dev;
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);
@@ -1770,7 +1769,7 @@ fc_rport_final_delete(void *data)
/* Delete SCSI target and sdevs */
if (rport->scsi_target_id != -1)
- fc_starget_delete(data);
+ fc_starget_delete(&rport->stgt_delete_work);
else if (i->f->dev_loss_tmo_callbk)
i->f->dev_loss_tmo_callbk(rport);
else if (i->f->terminate_rport_io)
@@ -1829,11 +1828,11 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
rport->channel = channel;
rport->fast_io_fail_tmo = -1;
- INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
- INIT_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io, rport);
- INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
- INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport);
- INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport);
+ INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport);
+ INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io);
+ INIT_WORK(&rport->scan_work, fc_scsi_scan_rport);
+ INIT_WORK(&rport->stgt_delete_work, fc_starget_delete);
+ INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete);
spin_lock_irqsave(shost->host_lock, flags);
@@ -1963,7 +1962,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
}
if (match) {
- struct work_struct *work =
+ struct delayed_work *work =
&rport->dev_loss_work;
memcpy(&rport->node_name, &ids->node_name,
@@ -2267,12 +2266,13 @@ EXPORT_SYMBOL(fc_remote_port_rolechg);
* was a SCSI target (thus was blocked), and failed
* to return in the alloted time.
*
- * @data: rport target that failed to reappear in the alloted time.
+ * @work: rport target that failed to reappear in the alloted time.
**/
static void
-fc_timeout_deleted_rport(void *data)
+fc_timeout_deleted_rport(struct work_struct *work)
{
- struct fc_rport *rport = (struct fc_rport *)data;
+ struct fc_rport *rport =
+ container_of(work, struct fc_rport, dev_loss_work.work);
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
unsigned long flags;
@@ -2366,15 +2366,16 @@ fc_timeout_deleted_rport(void *data)
* fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a
* disconnected SCSI target.
*
- * @data: rport to terminate io on.
+ * @work: rport to terminate io on.
*
* Notes: Only requests the failure of the io, not that all are flushed
* prior to returning.
**/
static void
-fc_timeout_fail_rport_io(void *data)
+fc_timeout_fail_rport_io(struct work_struct *work)
{
- struct fc_rport *rport = (struct fc_rport *)data;
+ struct fc_rport *rport =
+ container_of(work, struct fc_rport, fail_io_work.work);
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);
@@ -2387,12 +2388,13 @@ fc_timeout_fail_rport_io(void *data)
/**
* fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
*
- * @data: remote port to be scanned.
+ * @work: remote port to be scanned.
**/
static void
-fc_scsi_scan_rport(void *data)
+fc_scsi_scan_rport(struct work_struct *work)
{
- struct fc_rport *rport = (struct fc_rport *)data;
+ struct fc_rport *rport =
+ container_of(work, struct fc_rport, scan_work);
struct Scsi_Host *shost = rport_to_shost(rport);
unsigned long flags;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 9b25124a989e..9c22f1342715 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -234,9 +234,11 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
return 0;
}
-static void session_recovery_timedout(void *data)
+static void session_recovery_timedout(struct work_struct *work)
{
- struct iscsi_cls_session *session = data;
+ struct iscsi_cls_session *session =
+ container_of(work, struct iscsi_cls_session,
+ recovery_work.work);
dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
"out after %d secs\n", session->recovery_tmo);
@@ -276,7 +278,7 @@ iscsi_alloc_session(struct Scsi_Host *shost,
session->transport = transport;
session->recovery_tmo = 120;
- INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
+ INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
INIT_LIST_HEAD(&session->host_list);
INIT_LIST_HEAD(&session->sess_list);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index b5b0c2cba96b..5c0b75bbfa10 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/jiffies.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/string.h>
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 9f070f0d0f2b..3fded4831460 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -964,9 +964,10 @@ struct work_queue_wrapper {
};
static void
-spi_dv_device_work_wrapper(void *data)
+spi_dv_device_work_wrapper(struct work_struct *work)
{
- struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+ struct work_queue_wrapper *wqw =
+ container_of(work, struct work_queue_wrapper, work);
struct scsi_device *sdev = wqw->sdev;
kfree(wqw);
@@ -1006,7 +1007,7 @@ spi_schedule_dv_device(struct scsi_device *sdev)
return;
}
- INIT_WORK(&wqw->work, spi_dv_device_work_wrapper, wqw);
+ INIT_WORK(&wqw->work, spi_dv_device_work_wrapper);
wqw->sdev = sdev;
schedule_work(&wqw->work);
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c
new file mode 100644
index 000000000000..8a636103083d
--- /dev/null
+++ b/drivers/scsi/scsi_wait_scan.c
@@ -0,0 +1,31 @@
+/*
+ * scsi_wait_scan.c
+ *
+ * Copyright (C) 2006 James Bottomley <James.Bottomley@SteelEye.com>
+ *
+ * This is a simple module to wait until all the async scans are
+ * complete. The idea is to use it in initrd/initramfs scripts. You
+ * modprobe it after all the modprobes of the root SCSI drivers and it
+ * will wait until they have all finished scanning their busses before
+ * allowing the boot to proceed
+ */
+
+#include <linux/module.h>
+#include "scsi_priv.h"
+
+static int __init wait_scan_init(void)
+{
+ scsi_complete_async_scans();
+ return 0;
+}
+
+static void __exit wait_scan_exit(void)
+{
+}
+
+MODULE_DESCRIPTION("SCSI wait for scans");
+MODULE_AUTHOR("James Bottomley");
+MODULE_LICENSE("GPL");
+
+late_initcall(wait_scan_init);
+module_exit(wait_scan_exit);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 84ff203ffedd..f6a452846fab 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1051,6 +1051,14 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
&sshdr, SD_TIMEOUT,
SD_MAX_RETRIES);
+ /*
+ * If the drive has indicated to us that it
+ * doesn't have any media in it, don't bother
+ * with any more polling.
+ */
+ if (media_not_present(sdkp, &sshdr))
+ return;
+
if (the_result)
sense_valid = scsi_sense_valid(&sshdr);
retries++;
@@ -1059,14 +1067,6 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
((driver_byte(the_result) & DRIVER_SENSE) &&
sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
- /*
- * If the drive has indicated to us that it doesn't have
- * any media in it, don't bother with any of the rest of
- * this crap.
- */
- if (media_not_present(sdkp, &sshdr))
- return;
-
if ((driver_byte(the_result) & DRIVER_SENSE) == 0) {
/* no sense, TUR either succeeded or failed
* with a status error */
@@ -1467,7 +1467,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
if (scsi_status_is_good(res)) {
- int ct = 0;
int offset = data.header_length + data.block_descriptor_length;
if (offset >= SD_BUF_SIZE - 2) {
@@ -1496,11 +1495,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
sdkp->DPOFUA = 0;
}
- ct = sdkp->RCD + 2*sdkp->WCE;
-
- printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n",
- diskname, sd_cache_types[ct],
- sdkp->DPOFUA ? " w/ FUA" : "");
+ printk(KERN_NOTICE "SCSI device %s: "
+ "write cache: %s, read cache: %s, %s\n",
+ diskname,
+ sdkp->WCE ? "enabled" : "disabled",
+ sdkp->RCD ? "disabled" : "enabled",
+ sdkp->DPOFUA ? "supports DPO and FUA"
+ : "doesn't support DPO or FUA");
return;
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index e1a52c525ed4..587274dd7059 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -9,7 +9,7 @@
Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
Michael Schaefer, J"org Weule, and Eric Youngdale.
- Copyright 1992 - 2005 Kai Makisara
+ Copyright 1992 - 2006 Kai Makisara
email Kai.Makisara@kolumbus.fi
Some small formal changes - aeb, 950809
@@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static const char *verstr = "20050830";
+static const char *verstr = "20061107";
#include <linux/module.h>
@@ -999,7 +999,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
STp->min_block = ((STp->buffer)->b_data[4] << 8) |
(STp->buffer)->b_data[5];
if ( DEB( debugging || ) !STp->inited)
- printk(KERN_WARNING
+ printk(KERN_INFO
"%s: Block limits %d - %d bytes.\n", name,
STp->min_block, STp->max_block);
} else {
@@ -1224,7 +1224,7 @@ static int st_flush(struct file *filp, fl_owner_t id)
}
DEBC( if (STp->nbr_requests)
- printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
+ printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
if (STps->rw == ST_WRITING && !STp->pos_unknown) {
@@ -4056,11 +4056,11 @@ static int st_probe(struct device *dev)
goto out_free_tape;
}
- sdev_printk(KERN_WARNING, SDp,
+ sdev_printk(KERN_NOTICE, SDp,
"Attached scsi tape %s\n", tape_name(tpnt));
- printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
- tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
- queue_dma_alignment(SDp->request_queue) + 1);
+ sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
+ tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
+ queue_dma_alignment(SDp->request_queue) + 1);
return 0;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 185c270bb043..ba6bcdaf2a6a 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -11,8 +11,6 @@
* Written By:
* Ed Lin <promise_linux@promise.com>
*
- * Version: 3.0.0.1
- *
*/
#include <linux/init.h>
@@ -37,9 +35,9 @@
#include <scsi/scsi_tcq.h>
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "3.0.0.1"
+#define ST_DRIVER_VERSION "3.1.0.1"
#define ST_VER_MAJOR 3
-#define ST_VER_MINOR 0
+#define ST_VER_MINOR 1
#define ST_OEM 0
#define ST_BUILD_VER 1
@@ -76,8 +74,10 @@ enum {
MU_STATE_STARTED = 4,
MU_STATE_RESETTING = 5,
- MU_MAX_DELAY_TIME = 240000,
+ MU_MAX_DELAY = 120,
MU_HANDSHAKE_SIGNATURE = 0x55aaaa55,
+ MU_HANDSHAKE_SIGNATURE_HALF = 0x5a5a0000,
+ MU_HARD_RESET_WAIT = 30000,
HMU_PARTNER_TYPE = 2,
/* firmware returned values */
@@ -120,7 +120,8 @@ enum {
st_shasta = 0,
st_vsc = 1,
- st_yosemite = 2,
+ st_vsc1 = 2,
+ st_yosemite = 3,
PASSTHRU_REQ_TYPE = 0x00000001,
PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
@@ -150,6 +151,8 @@ enum {
MGT_CMD_SIGNATURE = 0xba,
INQUIRY_EVPD = 0x01,
+
+ ST_ADDITIONAL_MEM = 0x200000,
};
/* SCSI inquiry data */
@@ -211,7 +214,9 @@ struct handshake_frame {
__le32 partner_ver_minor;
__le32 partner_ver_oem;
__le32 partner_ver_build;
- u32 reserved1[4];
+ __le32 extra_offset; /* NEW */
+ __le32 extra_size; /* NEW */
+ u32 reserved1[2];
};
struct req_msg {
@@ -302,6 +307,7 @@ struct st_hba {
void __iomem *mmio_base; /* iomapped PCI memory space */
void *dma_mem;
dma_addr_t dma_handle;
+ size_t dma_size;
struct Scsi_Host *host;
struct pci_dev *pdev;
@@ -507,6 +513,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
size_t count = sizeof(struct st_frame);
p = hba->copy_buffer;
+ stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD);
memset(p->base, 0, sizeof(u32)*6);
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
p->rom_addr = 0;
@@ -901,27 +908,34 @@ static int stex_handshake(struct st_hba *hba)
void __iomem *base = hba->mmio_base;
struct handshake_frame *h;
dma_addr_t status_phys;
- int i;
+ u32 data;
+ unsigned long before;
if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) {
writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL);
readl(base + IDBL);
- for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE
- && i < MU_MAX_DELAY_TIME; i++) {
+ before = jiffies;
+ while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) {
+ if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): no handshake signature\n",
+ pci_name(hba->pdev));
+ return -1;
+ }
rmb();
msleep(1);
}
-
- if (i == MU_MAX_DELAY_TIME) {
- printk(KERN_ERR DRV_NAME
- "(%s): no handshake signature\n",
- pci_name(hba->pdev));
- return -1;
- }
}
udelay(10);
+ data = readl(base + OMR1);
+ if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) {
+ data &= 0x0000ffff;
+ if (hba->host->can_queue > data)
+ hba->host->can_queue = data;
+ }
+
h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE);
h->rb_phy = cpu_to_le32(hba->dma_handle);
h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16);
@@ -931,6 +945,11 @@ static int stex_handshake(struct st_hba *hba)
h->status_cnt = cpu_to_le16(MU_STATUS_COUNT);
stex_gettime(&h->hosttime);
h->partner_type = HMU_PARTNER_TYPE;
+ if (hba->dma_size > STEX_BUFFER_SIZE) {
+ h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE);
+ h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM);
+ } else
+ h->extra_offset = h->extra_size = 0;
status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE;
writel(status_phys, base + IMR0);
@@ -944,19 +963,18 @@ static int stex_handshake(struct st_hba *hba)
readl(base + IDBL); /* flush */
udelay(10);
- for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE
- && i < MU_MAX_DELAY_TIME; i++) {
+ before = jiffies;
+ while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) {
+ if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): no signature after handshake frame\n",
+ pci_name(hba->pdev));
+ return -1;
+ }
rmb();
msleep(1);
}
- if (i == MU_MAX_DELAY_TIME) {
- printk(KERN_ERR DRV_NAME
- "(%s): no signature after handshake frame\n",
- pci_name(hba->pdev));
- return -1;
- }
-
writel(0, base + IMR0);
readl(base + IMR0);
writel(0, base + OMR0);
@@ -1038,9 +1056,9 @@ static void stex_hard_reset(struct st_hba *hba)
pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
- for (i = 0; i < MU_MAX_DELAY_TIME; i++) {
+ for (i = 0; i < MU_HARD_RESET_WAIT; i++) {
pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd);
- if (pci_cmd & PCI_COMMAND_MASTER)
+ if (pci_cmd != 0xffff && (pci_cmd & PCI_COMMAND_MASTER))
break;
msleep(1);
}
@@ -1100,18 +1118,18 @@ static int stex_reset(struct scsi_cmnd *cmd)
static int stex_biosparam(struct scsi_device *sdev,
struct block_device *bdev, sector_t capacity, int geom[])
{
- int heads = 255, sectors = 63, cylinders;
+ int heads = 255, sectors = 63;
if (capacity < 0x200000) {
heads = 64;
sectors = 32;
}
- cylinders = sector_div(capacity, heads * sectors);
+ sector_div(capacity, heads * sectors);
geom[0] = heads;
geom[1] = sectors;
- geom[2] = cylinders;
+ geom[2] = capacity;
return 0;
}
@@ -1193,8 +1211,13 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_iounmap;
}
+ hba->cardtype = (unsigned int) id->driver_data;
+ if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1)
+ hba->cardtype = st_vsc1;
+ hba->dma_size = (hba->cardtype == st_vsc1) ?
+ (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE);
hba->dma_mem = dma_alloc_coherent(&pdev->dev,
- STEX_BUFFER_SIZE, &hba->dma_handle, GFP_KERNEL);
+ hba->dma_size, &hba->dma_handle, GFP_KERNEL);
if (!hba->dma_mem) {
err = -ENOMEM;
printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
@@ -1207,8 +1230,6 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
hba->mu_status = MU_STATE_STARTING;
- hba->cardtype = (unsigned int) id->driver_data;
-
/* firmware uses id/lun pair for a logical drive, but lun would be
always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
channel to map lun here */
@@ -1233,7 +1254,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto out_free_irq;
- err = scsi_init_shared_tag_map(host, ST_CAN_QUEUE);
+ err = scsi_init_shared_tag_map(host, host->can_queue);
if (err) {
printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n",
pci_name(pdev));
@@ -1256,7 +1277,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
out_free_irq:
free_irq(pdev->irq, hba);
out_pci_free:
- dma_free_coherent(&pdev->dev, STEX_BUFFER_SIZE,
+ dma_free_coherent(&pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
out_iounmap:
iounmap(hba->mmio_base);
@@ -1317,7 +1338,7 @@ static void stex_hba_free(struct st_hba *hba)
pci_release_regions(hba->pdev);
- dma_free_coherent(&hba->pdev->dev, STEX_BUFFER_SIZE,
+ dma_free_coherent(&hba->pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
}
@@ -1346,15 +1367,32 @@ static void stex_shutdown(struct pci_dev *pdev)
}
static struct pci_device_id stex_pci_tbl[] = {
- { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0xf350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
- { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
- { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
+ /* st_shasta */
+ { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
+ { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX12350 */
+ { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX4350 */
+ { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX24350 */
+
+ /* st_vsc */
+ { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
+
+ /* st_yosemite */
+ { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0,
+ st_yosemite }, /* SuperTrak EX4650 */
+ { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0,
+ st_yosemite }, /* SuperTrak EX4650o */
+ { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0,
+ st_yosemite }, /* SuperTrak EX8650EL */
+ { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0,
+ st_yosemite }, /* SuperTrak EX8650 */
+ { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0,
+ st_yosemite }, /* SuperTrak EX8654 */
+ { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_yosemite }, /* generic st_yosemite */
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h
index 646e840266e2..76a069b7ac0b 100644
--- a/drivers/scsi/t128.h
+++ b/drivers/scsi/t128.h
@@ -8,20 +8,20 @@
* drew@colorado.edu
* +1 (303) 440-4894
*
- * DISTRIBUTION RELEASE 3.
+ * DISTRIBUTION RELEASE 3.
*
- * For more information, please consult
+ * For more information, please consult
*
* Trantor Systems, Ltd.
* T128/T128F/T228 SCSI Host Adapter
* Hardware Specifications
- *
- * Trantor Systems, Ltd.
+ *
+ * Trantor Systems, Ltd.
* 5415 Randall Place
* Fremont, CA 94538
* 1+ (415) 770-1400, FAX 1+ (415) 770-9910
- *
- * and
+ *
+ * and
*
* NCR 5380 Family
* SCSI Protocol Controller
@@ -48,15 +48,15 @@
#define TDEBUG_TRANSFER 0x2
/*
- * The trantor boards are memory mapped. They use an NCR5380 or
+ * The trantor boards are memory mapped. They use an NCR5380 or
* equivalent (my sample board had part second sourced from ZILOG).
- * NCR's recommended "Pseudo-DMA" architecture is used, where
+ * NCR's recommended "Pseudo-DMA" architecture is used, where
* a PAL drives the DMA signals on the 5380 allowing fast, blind
- * transfers with proper handshaking.
+ * transfers with proper handshaking.
*/
/*
- * Note : a boot switch is provided for the purpose of informing the
+ * Note : a boot switch is provided for the purpose of informing the
* firmware to boot or not boot from attached SCSI devices. So, I imagine
* there are fewer people who've yanked the ROM like they do on the Seagate
* to make bootup faster, and I'll probably use this for autodetection.
@@ -92,19 +92,20 @@
#define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */
#ifndef ASM
-static int t128_abort(Scsi_Cmnd *);
+static int t128_abort(struct scsi_cmnd *);
static int t128_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int t128_detect(struct scsi_host_template *);
-static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int t128_bus_reset(Scsi_Cmnd *);
+static int t128_queue_command(struct scsi_cmnd *,
+ void (*done)(struct scsi_cmnd *));
+static int t128_bus_reset(struct scsi_cmnd *);
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
+#define CAN_QUEUE 32
#endif
#ifndef HOSTS_C
@@ -120,7 +121,7 @@ static int t128_bus_reset(Scsi_Cmnd *);
#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
-#if !(TDEBUG & TDEBUG_TRANSFER)
+#if !(TDEBUG & TDEBUG_TRANSFER)
#define NCR5380_read(reg) readb(T128_address(reg))
#define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
#else
@@ -129,7 +130,7 @@ static int t128_bus_reset(Scsi_Cmnd *);
, instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
#define NCR5380_write(reg, value) { \
- printk("scsi%d : write %02x to register %d at address %08x\n", \
+ printk("scsi%d : write %02x to register %d at address %08x\n", \
instance->hostno, (value), (reg), T128_address(reg)); \
writeb((value), (T128_address(reg))); \
}
@@ -142,10 +143,10 @@ static int t128_bus_reset(Scsi_Cmnd *);
#define NCR5380_bus_reset t128_bus_reset
#define NCR5380_proc_info t128_proc_info
-/* 15 14 12 10 7 5 3
+/* 15 14 12 10 7 5 3
1101 0100 1010 1000 */
-
-#define T128_IRQS 0xc4a8
+
+#define T128_IRQS 0xc4a8
#endif /* else def HOSTS_C */
#endif /* ndef ASM */
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index b691d3e14754..787a8f134677 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -282,7 +282,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
}
/* Setup any dynamic params in the uart desc */
-int cpm_uart_init_portdesc(void)
+int __init cpm_uart_init_portdesc(void)
{
#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
u32 addr;
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index aee1b31f1a1c..3db206d29b33 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -60,7 +60,8 @@ struct timer_list mcfrs_timer_struct;
#if defined(CONFIG_HW_FEITH)
#define CONSOLE_BAUD_RATE 38400
#define DEFAULT_CBAUD B38400
-#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || defined(CONFIG_M5329EVB)
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \
+ defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO)
#define CONSOLE_BAUD_RATE 115200
#define DEFAULT_CBAUD B115200
#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
@@ -109,12 +110,30 @@ static struct mcf_serial mcfrs_table[] = {
.irq = IRQBASE,
.flags = ASYNC_BOOT_AUTOCONF,
},
+#ifdef MCFUART_BASE2
{ /* ttyS1 */
.magic = 0,
.addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2),
.irq = IRQBASE+1,
.flags = ASYNC_BOOT_AUTOCONF,
},
+#endif
+#ifdef MCFUART_BASE3
+ { /* ttyS2 */
+ .magic = 0,
+ .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3),
+ .irq = IRQBASE+2,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ },
+#endif
+#ifdef MCFUART_BASE4
+ { /* ttyS3 */
+ .magic = 0,
+ .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4),
+ .irq = IRQBASE+3,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ },
+#endif
};
@@ -1516,6 +1535,22 @@ static void mcfrs_irqinit(struct mcf_serial *info)
imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
MCFINTC_IMRL);
*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#if defined(CONFIG_M527x)
+ {
+ /*
+ * External Pin Mask Setting & Enable External Pin for Interface
+ * mrcbis@aliceposta.it
+ */
+ unsigned short *serpin_enable_mask;
+ serpin_enable_mask = (MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ if (info->line == 0)
+ *serpin_enable_mask |= UART0_ENABLE_MASK;
+ else if (info->line == 1)
+ *serpin_enable_mask |= UART1_ENABLE_MASK;
+ else if (info->line == 2)
+ *serpin_enable_mask |= UART2_ENABLE_MASK;
+ }
+#endif
#elif defined(CONFIG_M520x)
volatile unsigned char *icrp, *uartp;
volatile unsigned long *imrp;
@@ -1713,7 +1748,7 @@ mcfrs_init(void)
/* Initialize the tty_driver structure */
mcfrs_serial_driver->owner = THIS_MODULE;
mcfrs_serial_driver->name = "ttyS";
- mcfrs_serial_driver->driver_name = "serial";
+ mcfrs_serial_driver->driver_name = "mcfserial";
mcfrs_serial_driver->major = TTY_MAJOR;
mcfrs_serial_driver->minor_start = 64;
mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -1797,10 +1832,23 @@ void mcfrs_init_console(void)
uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
+#ifdef CONFIG_M5272
+{
+ /*
+ * For the MCF5272, also compute the baudrate fraction.
+ */
+ int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud);
+ fraction *= 16;
+ fraction /= (32 * mcfrs_console_baud);
+ uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */
+ clk = (MCF_BUSCLK / mcfrs_console_baud) / 32;
+}
+#else
clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */
+#endif
+
uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */
uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */
-
uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 4f80c5b4a753..6dd579ed9777 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -1,6 +1,4 @@
/*
- * drivers/serial/mpc52xx_uart.c
- *
* Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs.
*
* FIXME According to the usermanual the status bits in the status register
@@ -14,18 +12,20 @@
*
*
* Maintainer : Sylvain Munaut <tnt@246tNt.com>
- *
+ *
* Some of the code has been inspired/copied from the 2.4 code written
* by Dale Farnsworth <dfarnsworth@mvista.com>.
- *
- * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2006 Secret Lab Technologies Ltd.
+ * Grant Likely <grant.likely@secretlab.ca>
+ * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003 MontaVista, Software, Inc.
- *
+ *
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
-
+
/* Platform device Usage :
*
* Since PSCs can have multiple function, the correct driver for each one
@@ -44,7 +44,24 @@
* will be mapped to.
*/
-#include <linux/platform_device.h>
+/* OF Platform device Usage :
+ *
+ * This driver is only used for PSCs configured in uart mode. The device
+ * tree will have a node for each PSC in uart mode w/ device_type = "serial"
+ * and "mpc52xx-psc-uart" in the compatible string
+ *
+ * By default, PSC devices are enumerated in the order they are found. However
+ * a particular PSC number can be forces by adding 'device_no = <port#>'
+ * to the device node.
+ *
+ * The driver init all necessary registers to place the PSC in uart mode without
+ * DCD. However, the pin multiplexing aren't changed and should be set either
+ * by the bootloader or in the platform init code.
+ */
+
+#undef DEBUG
+
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h>
@@ -54,6 +71,12 @@
#include <asm/delay.h>
#include <asm/io.h>
+#if defined(CONFIG_PPC_MERGE)
+#include <asm/of_platform.h>
+#else
+#include <linux/platform_device.h>
+#endif
+
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
@@ -80,6 +103,12 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM];
* it's cleared, then a memset(...,0,...) should be added to
* the console_init
*/
+#if defined(CONFIG_PPC_MERGE)
+/* lookup table for matching device nodes to index numbers */
+static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
+
+static void mpc52xx_uart_of_enumerate(void);
+#endif
#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
@@ -96,32 +125,40 @@ static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id);
#define uart_console(port) (0)
#endif
+#if defined(CONFIG_PPC_MERGE)
+static struct of_device_id mpc52xx_uart_of_match[] = {
+ { .type = "serial", .compatible = "mpc52xx-psc-uart", },
+ { .type = "serial", .compatible = "mpc5200-psc", }, /* Efika only! */
+ {},
+};
+#endif
+
/* ======================================================================== */
/* UART operations */
/* ======================================================================== */
-static unsigned int
+static unsigned int
mpc52xx_uart_tx_empty(struct uart_port *port)
{
int status = in_be16(&PSC(port)->mpc52xx_psc_status);
return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
}
-static void
+static void
mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
/* Not implemented */
}
-static unsigned int
+static unsigned int
mpc52xx_uart_get_mctrl(struct uart_port *port)
{
/* Not implemented */
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
}
-static void
+static void
mpc52xx_uart_stop_tx(struct uart_port *port)
{
/* port->lock taken by caller */
@@ -129,7 +166,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port)
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
}
-static void
+static void
mpc52xx_uart_start_tx(struct uart_port *port)
{
/* port->lock taken by caller */
@@ -137,12 +174,12 @@ mpc52xx_uart_start_tx(struct uart_port *port)
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
}
-static void
+static void
mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
{
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
-
+
port->x_char = ch;
if (ch) {
/* Make sure tx interrupts are on */
@@ -150,7 +187,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
}
-
+
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -178,7 +215,7 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK);
else
out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK);
-
+
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -197,11 +234,11 @@ mpc52xx_uart_startup(struct uart_port *port)
/* Reset/activate the port, clear and enable interrupts */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
out_8(&psc->command,MPC52xx_PSC_RST_TX);
-
+
out_be32(&psc->sicr,0); /* UART mode DCD ignored */
out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */
-
+
out_8(&psc->rfcntl, 0x00);
out_be16(&psc->rfalarm, 0x1ff);
out_8(&psc->tfcntl, 0x07);
@@ -209,10 +246,10 @@ mpc52xx_uart_startup(struct uart_port *port)
port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
-
+
out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
-
+
return 0;
}
@@ -220,19 +257,19 @@ static void
mpc52xx_uart_shutdown(struct uart_port *port)
{
struct mpc52xx_psc __iomem *psc = PSC(port);
-
+
/* Shut down the port, interrupt and all */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
out_8(&psc->command,MPC52xx_PSC_RST_TX);
-
- port->read_status_mask = 0;
+
+ port->read_status_mask = 0;
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
/* Release interrupt */
free_irq(port->irq, port);
}
-static void
+static void
mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
struct termios *old)
{
@@ -241,10 +278,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
unsigned char mr1, mr2;
unsigned short ctr;
unsigned int j, baud, quot;
-
+
/* Prepare what we're gonna write */
mr1 = 0;
-
+
switch (new->c_cflag & CSIZE) {
case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS;
break;
@@ -261,8 +298,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN;
} else
mr1 |= MPC52xx_PSC_MODE_PARNONE;
-
-
+
+
mr2 = 0;
if (new->c_cflag & CSTOPB)
@@ -276,7 +313,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
ctr = quot & 0xffff;
-
+
/* Get the lock */
spin_lock_irqsave(&port->lock, flags);
@@ -290,14 +327,14 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
* boot for the console, all stuff is not yet ready to receive at that
* time and that just makes the kernel oops */
/* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
- while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
+ while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
--j)
udelay(1);
if (!j)
printk( KERN_ERR "mpc52xx_uart.c: "
"Unable to flush RX & TX fifos in-time in set_termios."
- "Some chars may have been lost.\n" );
+ "Some chars may have been lost.\n" );
/* Reset the TX & RX */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
@@ -309,7 +346,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
out_8(&psc->mode,mr2);
out_8(&psc->ctur,ctr >> 8);
out_8(&psc->ctlr,ctr & 0xff);
-
+
/* Reenable TX & RX */
out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
@@ -332,7 +369,7 @@ mpc52xx_uart_release_port(struct uart_port *port)
port->membase = NULL;
}
- release_mem_region(port->mapbase, MPC52xx_PSC_SIZE);
+ release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
}
static int
@@ -341,12 +378,13 @@ mpc52xx_uart_request_port(struct uart_port *port)
int err;
if (port->flags & UPF_IOREMAP) /* Need to remap ? */
- port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
+ port->membase = ioremap(port->mapbase,
+ sizeof(struct mpc52xx_psc));
if (!port->membase)
return -EINVAL;
- err = request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
+ err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc),
"mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
if (err && (port->flags & UPF_IOREMAP)) {
@@ -373,7 +411,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
if ( (ser->irq != port->irq) ||
(ser->io_type != SERIAL_IO_MEM) ||
- (ser->baud_base != port->uartclk) ||
+ (ser->baud_base != port->uartclk) ||
(ser->iomem_base != (void*)port->mapbase) ||
(ser->hub6 != 0 ) )
return -EINVAL;
@@ -404,11 +442,11 @@ static struct uart_ops mpc52xx_uart_ops = {
.verify_port = mpc52xx_uart_verify_port
};
-
+
/* ======================================================================== */
/* Interrupt handling */
/* ======================================================================== */
-
+
static inline int
mpc52xx_uart_int_rx_chars(struct uart_port *port)
{
@@ -435,11 +473,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
flag = TTY_NORMAL;
port->icount.rx++;
-
+
if ( status & (MPC52xx_PSC_SR_PE |
MPC52xx_PSC_SR_FE |
MPC52xx_PSC_SR_RB) ) {
-
+
if (status & MPC52xx_PSC_SR_RB) {
flag = TTY_BREAK;
uart_handle_break(port);
@@ -464,7 +502,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
}
tty_flip_buffer_push(tty);
-
+
return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY;
}
@@ -509,25 +547,25 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
return 1;
}
-static irqreturn_t
+static irqreturn_t
mpc52xx_uart_int(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
unsigned long pass = ISR_PASS_LIMIT;
unsigned int keepgoing;
unsigned short status;
-
+
spin_lock(&port->lock);
-
+
/* While we have stuff to do, we continue */
do {
/* If we don't find anything to do, we stop */
- keepgoing = 0;
-
+ keepgoing = 0;
+
/* Read status */
status = in_be16(&PSC(port)->mpc52xx_psc_isr);
status &= port->read_status_mask;
-
+
/* Do we need to receive chars ? */
/* For this RX interrupts must be on and some chars waiting */
if ( status & MPC52xx_PSC_IMR_RXRDY )
@@ -537,15 +575,15 @@ mpc52xx_uart_int(int irq, void *dev_id)
/* For this, TX must be ready and TX interrupt enabled */
if ( status & MPC52xx_PSC_IMR_TXRDY )
keepgoing |= mpc52xx_uart_int_tx_chars(port);
-
+
/* Limit number of iteration */
if ( !(--pass) )
keepgoing = 0;
} while (keepgoing);
-
+
spin_unlock(&port->lock);
-
+
return IRQ_HANDLED;
}
@@ -563,13 +601,18 @@ mpc52xx_console_get_options(struct uart_port *port,
struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned char mr1;
+ pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
+
/* Read the mode registers */
out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
mr1 = in_8(&psc->mode);
-
+
/* CT{U,L}R are write-only ! */
- *baud = __res.bi_baudrate ?
- __res.bi_baudrate : CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
+ *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
+#if !defined(CONFIG_PPC_MERGE)
+ if (__res.bi_baudrate)
+ *baud = __res.bi_baudrate;
+#endif
/* Parse them */
switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
@@ -579,26 +622,26 @@ mpc52xx_console_get_options(struct uart_port *port,
case MPC52xx_PSC_MODE_8_BITS:
default: *bits = 8;
}
-
+
if (mr1 & MPC52xx_PSC_MODE_PARNONE)
*parity = 'n';
else
*parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e';
}
-static void
+static void
mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
{
struct uart_port *port = &mpc52xx_uart_ports[co->index];
struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned int i, j;
-
+
/* Disable interrupts */
out_be16(&psc->mpc52xx_psc_imr, 0);
/* Wait the TX buffer to be empty */
- j = 5000000; /* Maximum wait */
- while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
+ j = 5000000; /* Maximum wait */
+ while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
--j)
udelay(1);
@@ -607,13 +650,13 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
/* Line return handling */
if (*s == '\n')
out_8(&psc->mpc52xx_psc_buffer_8, '\r');
-
+
/* Send the char */
out_8(&psc->mpc52xx_psc_buffer_8, *s);
/* Wait the TX buffer to be empty */
- j = 20000; /* Maximum wait */
- while (!(in_be16(&psc->mpc52xx_psc_status) &
+ j = 20000; /* Maximum wait */
+ while (!(in_be16(&psc->mpc52xx_psc_status) &
MPC52xx_PSC_SR_TXEMP) && --j)
udelay(1);
}
@@ -622,6 +665,7 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
}
+#if !defined(CONFIG_PPC_MERGE)
static int __init
mpc52xx_console_setup(struct console *co, char *options)
{
@@ -634,7 +678,7 @@ mpc52xx_console_setup(struct console *co, char *options)
if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM)
return -EINVAL;
-
+
/* Basic port init. Needed since we use some uart_??? func before
* real init for early access */
spin_lock_init(&port->lock);
@@ -656,6 +700,78 @@ mpc52xx_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
+#else
+
+static int __init
+mpc52xx_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port = &mpc52xx_uart_ports[co->index];
+ struct device_node *np = mpc52xx_uart_nodes[co->index];
+ unsigned int ipb_freq;
+ struct resource res;
+ int ret;
+
+ int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n",
+ co, co->index, options);
+
+ if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) {
+ pr_debug("PSC%x out of range\n", co->index);
+ return -EINVAL;
+ }
+
+ if (!np) {
+ pr_debug("PSC%x not found in device tree\n", co->index);
+ return -EINVAL;
+ }
+
+ pr_debug("Console on ttyPSC%x is %s\n",
+ co->index, mpc52xx_uart_nodes[co->index]->full_name);
+
+ /* Fetch register locations */
+ if ((ret = of_address_to_resource(np, 0, &res)) != 0) {
+ pr_debug("Could not get resources for PSC%x\n", co->index);
+ return ret;
+ }
+
+ /* Search for bus-frequency property in this node or a parent */
+ if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) {
+ pr_debug("Could not find IPB bus frequency!\n");
+ return -EINVAL;
+ }
+
+ /* Basic port init. Needed since we use some uart_??? func before
+ * real init for early access */
+ spin_lock_init(&port->lock);
+ port->uartclk = ipb_freq / 2;
+ port->ops = &mpc52xx_uart_ops;
+ port->mapbase = res.start;
+ port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
+ port->irq = irq_of_parse_and_map(np, 0);
+
+ if (port->membase == NULL)
+ return -EINVAL;
+
+ pr_debug("mpc52xx-psc uart at %lx, mapped to %p, irq=%x, freq=%i\n",
+ port->mapbase, port->membase, port->irq, port->uartclk);
+
+ /* Setup the port parameters accoding to options */
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else
+ mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
+
+ pr_debug("Setting console parameters: %i %i%c1 flow=%c\n",
+ baud, bits, parity, flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+#endif /* defined(CONFIG_PPC_MERGE) */
+
static struct uart_driver mpc52xx_uart_driver;
@@ -669,10 +785,11 @@ static struct console mpc52xx_console = {
.data = &mpc52xx_uart_driver,
};
-
-static int __init
+
+static int __init
mpc52xx_console_init(void)
{
+ mpc52xx_uart_of_enumerate();
register_console(&mpc52xx_console);
return 0;
}
@@ -700,6 +817,7 @@ static struct uart_driver mpc52xx_uart_driver = {
};
+#if !defined(CONFIG_PPC_MERGE)
/* ======================================================================== */
/* Platform Driver */
/* ======================================================================== */
@@ -723,8 +841,6 @@ mpc52xx_uart_probe(struct platform_device *dev)
/* Init the port structure */
port = &mpc52xx_uart_ports[idx];
- memset(port, 0x00, sizeof(struct uart_port));
-
spin_lock_init(&port->lock);
port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
port->fifosize = 512;
@@ -733,6 +849,7 @@ mpc52xx_uart_probe(struct platform_device *dev)
( uart_console(port) ? 0 : UPF_IOREMAP );
port->line = idx;
port->ops = &mpc52xx_uart_ops;
+ port->dev = &dev->dev;
/* Search for IRQ and mapbase */
for (i=0 ; i<dev->num_resources ; i++, res++) {
@@ -771,7 +888,7 @@ mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
{
struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
- if (sport)
+ if (port)
uart_suspend_port(&mpc52xx_uart_driver, port);
return 0;
@@ -789,6 +906,7 @@ mpc52xx_uart_resume(struct platform_device *dev)
}
#endif
+
static struct platform_driver mpc52xx_uart_platform_driver = {
.probe = mpc52xx_uart_probe,
.remove = mpc52xx_uart_remove,
@@ -800,6 +918,184 @@ static struct platform_driver mpc52xx_uart_platform_driver = {
.name = "mpc52xx-psc",
},
};
+#endif /* !defined(CONFIG_PPC_MERGE) */
+
+
+#if defined(CONFIG_PPC_MERGE)
+/* ======================================================================== */
+/* OF Platform Driver */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+ int idx = -1;
+ unsigned int ipb_freq;
+ struct uart_port *port = NULL;
+ struct resource res;
+ int ret;
+
+ dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match);
+
+ /* Check validity & presence */
+ for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++)
+ if (mpc52xx_uart_nodes[idx] == op->node)
+ break;
+ if (idx >= MPC52xx_PSC_MAXNUM)
+ return -EINVAL;
+ pr_debug("Found %s assigned to ttyPSC%x\n",
+ mpc52xx_uart_nodes[idx]->full_name, idx);
+
+ /* Search for bus-frequency property in this node or a parent */
+ if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) {
+ dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
+ return -EINVAL;
+ }
+
+ /* Init the port structure */
+ port = &mpc52xx_uart_ports[idx];
+
+ spin_lock_init(&port->lock);
+ port->uartclk = ipb_freq / 2;
+ port->fifosize = 512;
+ port->iotype = UPIO_MEM;
+ port->flags = UPF_BOOT_AUTOCONF |
+ ( uart_console(port) ? 0 : UPF_IOREMAP );
+ port->line = idx;
+ port->ops = &mpc52xx_uart_ops;
+ port->dev = &op->dev;
+
+ /* Search for IRQ and mapbase */
+ if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)
+ return ret;
+
+ port->mapbase = res.start;
+ port->irq = irq_of_parse_and_map(op->node, 0);
+
+ dev_dbg(&op->dev, "mpc52xx-psc uart at %lx, irq=%x, freq=%i\n",
+ port->mapbase, port->irq, port->uartclk);
+
+ if ((port->irq==NO_IRQ) || !port->mapbase) {
+ printk(KERN_ERR "Could not allocate resources for PSC\n");
+ return -EINVAL;
+ }
+
+ /* Add the port to the uart sub-system */
+ ret = uart_add_one_port(&mpc52xx_uart_driver, port);
+ if (!ret)
+ dev_set_drvdata(&op->dev, (void*)port);
+
+ return ret;
+}
+
+static int
+mpc52xx_uart_of_remove(struct of_device *op)
+{
+ struct uart_port *port = dev_get_drvdata(&op->dev);
+ dev_set_drvdata(&op->dev, NULL);
+
+ if (port)
+ uart_remove_one_port(&mpc52xx_uart_driver, port);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state)
+{
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
+
+ if (port)
+ uart_suspend_port(&mpc52xx_uart_driver, port);
+
+ return 0;
+}
+
+static int
+mpc52xx_uart_of_resume(struct of_device *op)
+{
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
+
+ if (port)
+ uart_resume_port(&mpc52xx_uart_driver, port);
+
+ return 0;
+}
+#endif
+
+static void
+mpc52xx_uart_of_assign(struct device_node *np, int idx)
+{
+ int free_idx = -1;
+ int i;
+
+ /* Find the first free node */
+ for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
+ if (mpc52xx_uart_nodes[i] == NULL) {
+ free_idx = i;
+ break;
+ }
+ }
+
+ if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM))
+ idx = free_idx;
+
+ if (idx < 0)
+ return; /* No free slot; abort */
+
+ /* If the slot is already occupied, then swap slots */
+ if (mpc52xx_uart_nodes[idx] && (free_idx != -1))
+ mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];
+ mpc52xx_uart_nodes[i] = np;
+}
+
+static void
+mpc52xx_uart_of_enumerate(void)
+{
+ static int enum_done = 0;
+ struct device_node *np;
+ const unsigned int *devno;
+ int i;
+
+ if (enum_done)
+ return;
+
+ for_each_node_by_type(np, "serial") {
+ if (!of_match_node(mpc52xx_uart_of_match, np))
+ continue;
+
+ /* Is a particular device number requested? */
+ devno = get_property(np, "device_no", NULL);
+ mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);
+ }
+
+ enum_done = 1;
+
+ for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
+ if (mpc52xx_uart_nodes[i])
+ pr_debug("%s assigned to ttyPSC%x\n",
+ mpc52xx_uart_nodes[i]->full_name, i);
+ }
+}
+
+MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);
+
+static struct of_platform_driver mpc52xx_uart_of_driver = {
+ .owner = THIS_MODULE,
+ .name = "mpc52xx-psc-uart",
+ .match_table = mpc52xx_uart_of_match,
+ .probe = mpc52xx_uart_of_probe,
+ .remove = mpc52xx_uart_of_remove,
+#ifdef CONFIG_PM
+ .suspend = mpc52xx_uart_of_suspend,
+ .resume = mpc52xx_uart_of_resume,
+#endif
+ .driver = {
+ .name = "mpc52xx-psc-uart",
+ },
+};
+#endif /* defined(CONFIG_PPC_MERGE) */
/* ======================================================================== */
@@ -811,22 +1107,45 @@ mpc52xx_uart_init(void)
{
int ret;
- printk(KERN_INFO "Serial: MPC52xx PSC driver\n");
+ printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n");
- ret = uart_register_driver(&mpc52xx_uart_driver);
- if (ret == 0) {
- ret = platform_driver_register(&mpc52xx_uart_platform_driver);
- if (ret)
- uart_unregister_driver(&mpc52xx_uart_driver);
+ if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {
+ printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",
+ __FILE__, ret);
+ return ret;
}
- return ret;
+#if defined(CONFIG_PPC_MERGE)
+ mpc52xx_uart_of_enumerate();
+
+ ret = of_register_platform_driver(&mpc52xx_uart_of_driver);
+ if (ret) {
+ printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n",
+ __FILE__, ret);
+ uart_unregister_driver(&mpc52xx_uart_driver);
+ return ret;
+ }
+#else
+ ret = platform_driver_register(&mpc52xx_uart_platform_driver);
+ if (ret) {
+ printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
+ __FILE__, ret);
+ uart_unregister_driver(&mpc52xx_uart_driver);
+ return ret;
+ }
+#endif
+
+ return 0;
}
static void __exit
mpc52xx_uart_exit(void)
{
+#if defined(CONFIG_PPC_MERGE)
+ of_unregister_platform_driver(&mpc52xx_uart_of_driver);
+#else
platform_driver_unregister(&mpc52xx_uart_platform_driver);
+#endif
uart_unregister_driver(&mpc52xx_uart_driver);
}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 00f9ffd69489..431433f4dd6d 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -723,7 +723,7 @@ static int serial_config(struct pcmcia_device * link)
u_char *buf;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
- int i, last_ret, last_fn;
+ int i;
DEBUG(0, "serial_config(0x%p)\n", link);
@@ -740,15 +740,6 @@ static int serial_config(struct pcmcia_device * link)
tuple->TupleOffset = 0;
tuple->TupleDataMax = 255;
tuple->Attributes = 0;
- /* Get configuration register information */
- tuple->DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(link, tuple, parse);
- if (last_ret != CS_SUCCESS) {
- last_fn = ParseTuple;
- goto cs_failed;
- }
- link->conf.ConfigBase = parse->config.base;
- link->conf.Present = parse->config.rmask[0];
/* Is this a compliant multifunction card? */
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
@@ -757,27 +748,25 @@ static int serial_config(struct pcmcia_device * link)
/* Is this a multiport card? */
tuple->DesiredTuple = CISTPL_MANFID;
- if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
- info->manfid = parse->manfid.manf;
- info->prodid = parse->manfid.card;
-
- for (i = 0; i < ARRAY_SIZE(quirks); i++)
- if ((quirks[i].manfid == ~0 ||
- quirks[i].manfid == info->manfid) &&
- (quirks[i].prodid == ~0 ||
- quirks[i].prodid == info->prodid)) {
- info->quirk = &quirks[i];
- break;
- }
- }
+ info->manfid = link->manf_id;
+ info->prodid = link->card_id;
+
+ for (i = 0; i < ARRAY_SIZE(quirks); i++)
+ if ((quirks[i].manfid == ~0 ||
+ quirks[i].manfid == info->manfid) &&
+ (quirks[i].prodid == ~0 ||
+ quirks[i].prodid == info->prodid)) {
+ info->quirk = &quirks[i];
+ break;
+ }
/* Another check for dual-serial cards: look for either serial or
multifunction cards that ask for appropriate IO port ranges */
tuple->DesiredTuple = CISTPL_FUNCID;
if ((info->multi == 0) &&
- ((first_tuple(link, tuple, parse) != CS_SUCCESS) ||
- (parse->funcid.func == CISTPL_FUNCID_MULTI) ||
- (parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
+ (link->has_func_id) &&
+ ((link->func_id == CISTPL_FUNCID_MULTI) ||
+ (link->func_id == CISTPL_FUNCID_SERIAL))) {
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
@@ -814,8 +803,6 @@ static int serial_config(struct pcmcia_device * link)
kfree(cfg_mem);
return 0;
- cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
serial_remove(link);
kfree(cfg_mem);
@@ -925,6 +912,30 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3),
+ PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676),
+ PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767),
+ PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
+ PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
+ PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
+ PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+ PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+ PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+ PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
/* too generic */
/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index cfcc3caf49d8..3b5f19ec2126 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -775,7 +775,7 @@ static int sci_notifier(struct notifier_block *self,
*
* Clean this up later..
*/
- clk = clk_get("module_clk");
+ clk = clk_get(NULL, "module_clk");
port->uartclk = clk_get_rate(clk) * 16;
clk_put(clk);
}
@@ -960,7 +960,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios,
default:
{
#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
- struct clk *clk = clk_get("module_clk");
+ struct clk *clk = clk_get(NULL, "module_clk");
t = SCBRR_VALUE(baud, clk_get_rate(clk));
clk_put(clk);
#else
@@ -1128,7 +1128,7 @@ static void __init sci_init_ports(void)
* XXX: We should use a proper SCI/SCIF clock
*/
{
- struct clk *clk = clk_get("module_clk");
+ struct clk *clk = clk_get(NULL, "module_clk");
sci_ports[i].port.uartclk = clk_get_rate(clk) * 16;
clk_put(clk);
}
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 7ee992146ae9..e4557cc4f74b 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -133,6 +133,20 @@
# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
+# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
+# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */
+# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */
+# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
+# define SCSPTR1 0xf8410020 /* 16 bit SCIF */
+# define SCSPTR2 0xf8420020 /* 16 bit SCIF */
+# define SCIF_ORER 0x0001 /* overrun error bit */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
#else
# error CPU subtype not defined
#endif
@@ -365,6 +379,7 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
@@ -544,6 +559,28 @@ static inline int sci_rxd_in(struct uart_port *port)
if (port->mapbase == 0xffe10000)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->mapbase == 0xfffe8000)
+ return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xfffe8800)
+ return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xfffe9000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xfffe9800)
+ return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
+}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->mapbase == 0xf8400000)
+ return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xf8410000)
+ return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xf8420000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+}
#endif
/*
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 72025df5561d..494d9b856488 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -148,7 +148,7 @@ struct chip_data {
void (*cs_control)(u32 command);
};
-static void pump_messages(void *data);
+static void pump_messages(struct work_struct *work);
static int flush(struct driver_data *drv_data)
{
@@ -884,9 +884,10 @@ static void pump_transfers(unsigned long data)
}
}
-static void pump_messages(void *data)
+static void pump_messages(struct work_struct *work)
{
- struct driver_data *drv_data = data;
+ struct driver_data *drv_data =
+ container_of(work, struct driver_data, pump_messages);
unsigned long flags;
/* Lock queue and check for queue work */
@@ -1098,7 +1099,7 @@ static int init_queue(struct driver_data *drv_data)
tasklet_init(&drv_data->pump_transfers,
pump_transfers, (unsigned long)drv_data);
- INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data);
+ INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
drv_data->master->cdev.dev->bus_id);
if (drv_data->workqueue == NULL)
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index a23862ef72b2..08c1c57c6128 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -265,9 +265,10 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
* Drivers can provide word-at-a-time i/o primitives, or provide
* transfer-at-a-time ones to leverage dma or fifo hardware.
*/
-static void bitbang_work(void *_bitbang)
+static void bitbang_work(struct work_struct *work)
{
- struct spi_bitbang *bitbang = _bitbang;
+ struct spi_bitbang *bitbang =
+ container_of(work, struct spi_bitbang, work);
unsigned long flags;
spin_lock_irqsave(&bitbang->lock, flags);
@@ -456,7 +457,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
if (!bitbang->master || !bitbang->chipselect)
return -EINVAL;
- INIT_WORK(&bitbang->work, bitbang_work, bitbang);
+ INIT_WORK(&bitbang->work, bitbang_work);
spin_lock_init(&bitbang->lock);
INIT_LIST_HEAD(&bitbang->queue);
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 39d9b20f2038..c2f601f8e4f2 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/parport.h>
+#include <linux/sched.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/flash.h>
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index dda0ca45d904..164a5dcf1f1e 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -69,25 +69,21 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
{
- tuple_t tuple;
- u_short buf[128];
char *str;
- int last_ret, last_fn, i, place;
+ int i, place;
DEBUG(0, "ixj_get_serial(0x%p)\n", link);
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 80;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- str = (char *) buf;
- printk("PCMCIA Version %d.%d\n", str[0], str[1]);
- str += 2;
+
+ str = link->prod_id[0];
+ if (!str)
+ goto cs_failed;
printk("%s", str);
- str = str + strlen(str) + 1;
+ str = link->prod_id[1];
+ if (!str)
+ goto cs_failed;
printk(" %s", str);
- str = str + strlen(str) + 1;
+ str = link->prod_id[2];
+ if (!str)
+ goto cs_failed;
place = 1;
for (i = strlen(str) - 1; i >= 0; i--) {
switch (str[i]) {
@@ -122,7 +118,9 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
}
place = place * 0x10;
}
- str = str + strlen(str) + 1;
+ str = link->prod_id[3];
+ if (!str)
+ goto cs_failed;
printk(" version %s\n", str);
cs_failed:
return;
@@ -146,13 +144,6 @@ static int ixj_config(struct pcmcia_device * link)
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index e6565633ba0f..3dfa3e40e148 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -158,7 +158,7 @@ struct cxacru_data {
const struct cxacru_modem_type *modem_type;
int line_status;
- struct work_struct poll_work;
+ struct delayed_work poll_work;
/* contol handles */
struct mutex cm_serialize;
@@ -347,7 +347,7 @@ static int cxacru_card_status(struct cxacru_data *instance)
return 0;
}
-static void cxacru_poll_status(struct cxacru_data *instance);
+static void cxacru_poll_status(struct work_struct *work);
static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
struct atm_dev *atm_dev)
@@ -376,12 +376,14 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
}
/* Start status polling */
- cxacru_poll_status(instance);
+ cxacru_poll_status(&instance->poll_work.work);
return 0;
}
-static void cxacru_poll_status(struct cxacru_data *instance)
+static void cxacru_poll_status(struct work_struct *work)
{
+ struct cxacru_data *instance =
+ container_of(work, struct cxacru_data, poll_work.work);
u32 buf[CXINF_MAX] = {};
struct usbatm_data *usbatm = instance->usbatm;
struct atm_dev *atm_dev = usbatm->atm_dev;
@@ -720,7 +722,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
mutex_init(&instance->cm_serialize);
- INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance);
+ INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status);
usbatm_instance->driver_data = instance;
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index a823486495c3..8ed6c75adf0f 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -142,7 +142,7 @@ struct speedtch_instance_data {
struct speedtch_params params; /* set in probe, constant afterwards */
- struct work_struct status_checker;
+ struct delayed_work status_checker;
unsigned char last_status;
@@ -498,8 +498,11 @@ static int speedtch_start_synchro(struct speedtch_instance_data *instance)
return ret;
}
-static void speedtch_check_status(struct speedtch_instance_data *instance)
+static void speedtch_check_status(struct work_struct *work)
{
+ struct speedtch_instance_data *instance =
+ container_of(work, struct speedtch_instance_data,
+ status_checker.work);
struct usbatm_data *usbatm = instance->usbatm;
struct atm_dev *atm_dev = usbatm->atm_dev;
unsigned char *buf = instance->scratch_buffer;
@@ -576,7 +579,7 @@ static void speedtch_status_poll(unsigned long data)
{
struct speedtch_instance_data *instance = (void *)data;
- schedule_work(&instance->status_checker);
+ schedule_delayed_work(&instance->status_checker, 0);
/* The following check is racy, but the race is harmless */
if (instance->poll_delay < MAX_POLL_DELAY)
@@ -596,7 +599,7 @@ static void speedtch_resubmit_int(unsigned long data)
if (int_urb) {
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
if (!ret)
- schedule_work(&instance->status_checker);
+ schedule_delayed_work(&instance->status_checker, 0);
else {
atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
@@ -640,7 +643,7 @@ static void speedtch_handle_int(struct urb *int_urb)
if ((int_urb = instance->int_urb)) {
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
- schedule_work(&instance->status_checker);
+ schedule_delayed_work(&instance->status_checker, 0);
if (ret < 0) {
atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
goto fail;
@@ -855,7 +858,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
- INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
+ INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status);
instance->status_checker.timer.function = speedtch_status_poll;
instance->status_checker.timer.data = (unsigned long)instance;
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index c137c041f7a4..f2d196fa1e8b 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -655,9 +655,9 @@ static int request_dsp(struct uea_softc *sc)
/*
* The uea_load_page() function must be called within a process context
*/
-static void uea_load_page(void *xsc)
+static void uea_load_page(struct work_struct *work)
{
- struct uea_softc *sc = xsc;
+ struct uea_softc *sc = container_of(work, struct uea_softc, task);
u16 pageno = sc->pageno;
u16 ovl = sc->ovl;
struct block_info bi;
@@ -1348,7 +1348,7 @@ static int uea_boot(struct uea_softc *sc)
uea_enters(INS_TO_USBDEV(sc));
- INIT_WORK(&sc->task, uea_load_page, sc);
+ INIT_WORK(&sc->task, uea_load_page);
init_waitqueue_head(&sc->sync_q);
init_waitqueue_head(&sc->cmv_ack_wait);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ec3438dc8ee5..7f1fa956dcdb 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -421,9 +421,9 @@ static void acm_write_bulk(struct urb *urb)
schedule_work(&acm->work);
}
-static void acm_softint(void *private)
+static void acm_softint(struct work_struct *work)
{
- struct acm *acm = private;
+ struct acm *acm = container_of(work, struct acm, work);
dbg("Entering acm_softint.");
if (!ACM_READY(acm))
@@ -927,7 +927,7 @@ skip_normal_probe:
acm->rx_buflimit = num_rx_buf;
acm->urb_task.func = acm_rx_tasklet;
acm->urb_task.data = (unsigned long) acm;
- INIT_WORK(&acm->work, acm_softint, acm);
+ INIT_WORK(&acm->work, acm_softint);
spin_lock_init(&acm->throttle_lock);
spin_lock_init(&acm->write_lock);
spin_lock_init(&acm->read_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0ce393eb3c4b..9be41ed1f9a6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -68,7 +68,7 @@ struct usb_hub {
unsigned has_indicators:1;
u8 indicator[USB_MAXCHILDREN];
- struct work_struct leds;
+ struct delayed_work leds;
};
@@ -218,9 +218,10 @@ static void set_port_led(
#define LED_CYCLE_PERIOD ((2*HZ)/3)
-static void led_work (void *__hub)
+static void led_work (struct work_struct *work)
{
- struct usb_hub *hub = __hub;
+ struct usb_hub *hub =
+ container_of(work, struct usb_hub, leds.work);
struct usb_device *hdev = hub->hdev;
unsigned i;
unsigned changed = 0;
@@ -405,9 +406,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
* talking to TTs must queue control transfers (not just bulk and iso), so
* both can talk to the same hub concurrently.
*/
-static void hub_tt_kevent (void *arg)
+static void hub_tt_kevent (struct work_struct *work)
{
- struct usb_hub *hub = arg;
+ struct usb_hub *hub =
+ container_of(work, struct usb_hub, tt.kevent);
unsigned long flags;
spin_lock_irqsave (&hub->tt.lock, flags);
@@ -694,7 +696,7 @@ static int hub_configure(struct usb_hub *hub,
spin_lock_init (&hub->tt.lock);
INIT_LIST_HEAD (&hub->tt.clear_list);
- INIT_WORK (&hub->tt.kevent, hub_tt_kevent, hub);
+ INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
switch (hdev->descriptor.bDeviceProtocol) {
case 0:
break;
@@ -938,7 +940,7 @@ descriptor_error:
INIT_LIST_HEAD(&hub->event_list);
hub->intfdev = &intf->dev;
hub->hdev = hdev;
- INIT_WORK(&hub->leds, led_work, hub);
+ INIT_DELAYED_WORK(&hub->leds, led_work);
usb_set_intfdata (intf, hub);
intf->needs_remote_wakeup = 1;
@@ -2381,7 +2383,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
/* hub LEDs are probably harder to miss than syslog */
if (hub->has_indicators) {
hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
- schedule_work (&hub->leds);
+ schedule_delayed_work (&hub->leds, 0);
}
}
kfree(qual);
@@ -2555,7 +2557,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (hub->has_indicators) {
hub->indicator[port1-1] =
INDICATOR_AMBER_BLINK;
- schedule_work (&hub->leds);
+ schedule_delayed_work (&hub->leds, 0);
}
status = -ENOTCONN; /* Don't retry */
goto loop_disable;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 29b0fa9ff9d0..7390b67c609d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1501,9 +1501,10 @@ struct set_config_request {
};
/* Worker routine for usb_driver_set_configuration() */
-static void driver_set_config_work(void *_req)
+static void driver_set_config_work(struct work_struct *work)
{
- struct set_config_request *req = _req;
+ struct set_config_request *req =
+ container_of(work, struct set_config_request, work);
usb_lock_device(req->udev);
usb_set_configuration(req->udev, req->config);
@@ -1541,7 +1542,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config)
return -ENOMEM;
req->udev = udev;
req->config = config;
- INIT_WORK(&req->work, driver_set_config_work, req);
+ INIT_WORK(&req->work, driver_set_config_work);
usb_get_dev(udev);
if (!schedule_work(&req->work)) {
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 81cb52564e68..02426d0b9a34 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -203,9 +203,10 @@ static void ksuspend_usb_cleanup(void)
#ifdef CONFIG_USB_SUSPEND
/* usb_autosuspend_work - callback routine to autosuspend a USB device */
-static void usb_autosuspend_work(void *_udev)
+static void usb_autosuspend_work(struct work_struct *work)
{
- struct usb_device *udev = _udev;
+ struct usb_device *udev =
+ container_of(work, struct usb_device, autosuspend.work);
usb_pm_lock(udev);
udev->auto_pm = 1;
@@ -215,7 +216,7 @@ static void usb_autosuspend_work(void *_udev)
#else
-static void usb_autosuspend_work(void *_udev)
+static void usb_autosuspend_work(struct work_struct *work)
{}
#endif /* CONFIG_USB_SUSPEND */
@@ -304,7 +305,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
#ifdef CONFIG_PM
mutex_init(&dev->pm_mutex);
- INIT_WORK(&dev->autosuspend, usb_autosuspend_work, dev);
+ INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
#endif
return dev;
}
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3bd1dfe565c1..d15bf22b9a03 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1833,9 +1833,9 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
spin_unlock_irqrestore(&dev->req_lock, flags);
}
-static void eth_work (void *_dev)
+static void eth_work (struct work_struct *work)
{
- struct eth_dev *dev = _dev;
+ struct eth_dev *dev = container_of(work, struct eth_dev, work);
if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) {
if (netif_running (dev->net))
@@ -2398,7 +2398,7 @@ autoconf_fail:
dev = netdev_priv(net);
spin_lock_init (&dev->lock);
spin_lock_init (&dev->req_lock);
- INIT_WORK (&dev->work, eth_work, dev);
+ INIT_WORK (&dev->work, eth_work);
INIT_LIST_HEAD (&dev->tx_reqs);
INIT_LIST_HEAD (&dev->rx_reqs);
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 54f554e0f0ad..ac9f11d19817 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -169,21 +169,14 @@ static int sl811_cs_config(struct pcmcia_device *link)
DBG(0, "sl811_cs_config(0x%p)\n", link);
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index ef54e310bfc4..a9d7119e3176 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -163,7 +163,7 @@ struct u132_endp {
u16 queue_next;
struct urb *urb_list[ENDP_QUEUE_SIZE];
struct list_head urb_more;
- struct work_struct scheduler;
+ struct delayed_work scheduler;
};
struct u132_ring {
unsigned in_use:1;
@@ -171,7 +171,7 @@ struct u132_ring {
u8 number;
struct u132 *u132;
struct u132_endp *curr_endp;
- struct work_struct scheduler;
+ struct delayed_work scheduler;
};
#define OHCI_QUIRK_AMD756 0x01
#define OHCI_QUIRK_SUPERIO 0x02
@@ -198,7 +198,7 @@ struct u132 {
u32 hc_roothub_portstatus[MAX_ROOT_PORTS];
int flags;
unsigned long next_statechange;
- struct work_struct monitor;
+ struct delayed_work monitor;
int num_endpoints;
struct u132_addr addr[MAX_U132_ADDRS];
struct u132_udev udev[MAX_U132_UDEVS];
@@ -310,7 +310,7 @@ static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring,
if (delta > 0) {
if (queue_delayed_work(workqueue, &ring->scheduler, delta))
return;
- } else if (queue_work(workqueue, &ring->scheduler))
+ } else if (queue_delayed_work(workqueue, &ring->scheduler, 0))
return;
kref_put(&u132->kref, u132_hcd_delete);
return;
@@ -389,12 +389,8 @@ static inline void u132_endp_init_kref(struct u132 *u132,
static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp,
unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(workqueue, &endp->scheduler, delta))
- kref_get(&endp->kref);
- } else if (queue_work(workqueue, &endp->scheduler))
- kref_get(&endp->kref);
- return;
+ if (queue_delayed_work(workqueue, &endp->scheduler, delta))
+ kref_get(&endp->kref);
}
static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp)
@@ -410,24 +406,14 @@ static inline void u132_monitor_put_kref(struct u132 *u132)
static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(workqueue, &u132->monitor, delta)) {
- kref_get(&u132->kref);
- }
- } else if (queue_work(workqueue, &u132->monitor))
- kref_get(&u132->kref);
- return;
+ if (queue_delayed_work(workqueue, &u132->monitor, delta))
+ kref_get(&u132->kref);
}
static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(workqueue, &u132->monitor, delta))
- return;
- } else if (queue_work(workqueue, &u132->monitor))
- return;
- kref_put(&u132->kref, u132_hcd_delete);
- return;
+ if (!queue_delayed_work(workqueue, &u132->monitor, delta))
+ kref_put(&u132->kref, u132_hcd_delete);
}
static void u132_monitor_cancel_work(struct u132 *u132)
@@ -489,9 +475,9 @@ static int read_roothub_info(struct u132 *u132)
return 0;
}
-static void u132_hcd_monitor_work(void *data)
+static void u132_hcd_monitor_work(struct work_struct *work)
{
- struct u132 *u132 = data;
+ struct u132 *u132 = container_of(work, struct u132, monitor.work);
if (u132->going > 1) {
dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
, u132->going);
@@ -1315,15 +1301,14 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf,
}
}
-static void u132_hcd_ring_work_scheduler(void *data);
-static void u132_hcd_endp_work_scheduler(void *data);
/*
* this work function is only executed from the work queue
*
*/
-static void u132_hcd_ring_work_scheduler(void *data)
+static void u132_hcd_ring_work_scheduler(struct work_struct *work)
{
- struct u132_ring *ring = data;
+ struct u132_ring *ring =
+ container_of(work, struct u132_ring, scheduler.work);
struct u132 *u132 = ring->u132;
down(&u132->scheduler_lock);
if (ring->in_use) {
@@ -1382,10 +1367,11 @@ static void u132_hcd_ring_work_scheduler(void *data)
}
}
-static void u132_hcd_endp_work_scheduler(void *data)
+static void u132_hcd_endp_work_scheduler(struct work_struct *work)
{
struct u132_ring *ring;
- struct u132_endp *endp = data;
+ struct u132_endp *endp =
+ container_of(work, struct u132_endp, scheduler.work);
struct u132 *u132 = endp->u132;
down(&u132->scheduler_lock);
ring = endp->ring;
@@ -1943,7 +1929,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132,
if (!endp) {
return -ENOMEM;
}
- INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
+ INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
spin_lock_init(&endp->queue_lock.slock);
INIT_LIST_HEAD(&endp->urb_more);
ring = endp->ring = &u132->ring[0];
@@ -2032,7 +2018,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132,
if (!endp) {
return -ENOMEM;
}
- INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
+ INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
spin_lock_init(&endp->queue_lock.slock);
INIT_LIST_HEAD(&endp->urb_more);
endp->dequeueing = 0;
@@ -2117,7 +2103,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132,
if (!endp) {
return -ENOMEM;
}
- INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp);
+ INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler);
spin_lock_init(&endp->queue_lock.slock);
INIT_LIST_HEAD(&endp->urb_more);
ring = endp->ring = &u132->ring[0];
@@ -3096,10 +3082,10 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
ring->number = rings + 1;
ring->length = 0;
ring->curr_endp = NULL;
- INIT_WORK(&ring->scheduler, u132_hcd_ring_work_scheduler,
- (void *)ring);
+ INIT_DELAYED_WORK(&ring->scheduler,
+ u132_hcd_ring_work_scheduler);
} down(&u132->sw_lock);
- INIT_WORK(&u132->monitor, u132_hcd_monitor_work, (void *)u132);
+ INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work);
while (ports-- > 0) {
struct u132_port *port = &u132->port[ports];
port->u132 = u132;
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index a49644b7c58e..4295bab4f1e2 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -969,9 +969,10 @@ static void hid_retry_timeout(unsigned long _hid)
}
/* Workqueue routine to reset the device or clear a halt */
-static void hid_reset(void *_hid)
+static void hid_reset(struct work_struct *work)
{
- struct hid_device *hid = (struct hid_device *) _hid;
+ struct hid_device *hid =
+ container_of(work, struct hid_device, reset_work);
int rc_lock, rc = 0;
if (test_bit(HID_CLEAR_HALT, &hid->iofl)) {
@@ -2043,7 +2044,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
init_waitqueue_head(&hid->wait);
- INIT_WORK(&hid->reset_work, hid_reset, hid);
+ INIT_WORK(&hid->reset_work, hid_reset);
setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
spin_lock_init(&hid->inlock);
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index ba30ca6a14aa..02cbb7fff24f 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -76,7 +76,7 @@ struct appledisplay {
char *urbdata; /* interrupt URB data buffer */
char *msgdata; /* control message data buffer */
- struct work_struct work;
+ struct delayed_work work;
int button_pressed;
spinlock_t lock;
};
@@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb)
case ACD_BTN_BRIGHT_UP:
case ACD_BTN_BRIGHT_DOWN:
pdata->button_pressed = 1;
- queue_work(wq, &pdata->work);
+ queue_delayed_work(wq, &pdata->work, 0);
break;
case ACD_BTN_NONE:
default:
@@ -184,9 +184,10 @@ static struct backlight_properties appledisplay_bl_data = {
.max_brightness = 0xFF
};
-static void appledisplay_work(void *private)
+static void appledisplay_work(struct work_struct *work)
{
- struct appledisplay *pdata = private;
+ struct appledisplay *pdata =
+ container_of(work, struct appledisplay, work.work);
int retval;
up(&pdata->bd->sem);
@@ -238,7 +239,7 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata->udev = udev;
spin_lock_init(&pdata->lock);
- INIT_WORK(&pdata->work, appledisplay_work, pdata);
+ INIT_DELAYED_WORK(&pdata->work, appledisplay_work);
/* Allocate buffer for control messages */
pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index cb0ba3107d7f..18b1925032a8 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -156,9 +156,9 @@ struct usb_ftdi {
struct usb_device *udev;
struct usb_interface *interface;
struct usb_class_driver *class;
- struct work_struct status_work;
- struct work_struct command_work;
- struct work_struct respond_work;
+ struct delayed_work status_work;
+ struct delayed_work command_work;
+ struct delayed_work respond_work;
struct u132_platform_data platform_data;
struct resource resources[0];
struct platform_device platform_dev;
@@ -210,23 +210,14 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi)
static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
- return;
- } else if (queue_work(status_queue, &ftdi->status_work))
- return;
- kref_put(&ftdi->kref, ftdi_elan_delete);
- return;
+ if (!queue_delayed_work(status_queue, &ftdi->status_work, delta))
+ kref_put(&ftdi->kref, ftdi_elan_delete);
}
static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
- kref_get(&ftdi->kref);
- } else if (queue_work(status_queue, &ftdi->status_work))
- kref_get(&ftdi->kref);
- return;
+ if (queue_delayed_work(status_queue, &ftdi->status_work, delta))
+ kref_get(&ftdi->kref);
}
static void ftdi_status_cancel_work(struct usb_ftdi *ftdi)
@@ -237,25 +228,14 @@ static void ftdi_status_cancel_work(struct usb_ftdi *ftdi)
static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(command_queue, &ftdi->command_work,
- delta))
- return;
- } else if (queue_work(command_queue, &ftdi->command_work))
- return;
- kref_put(&ftdi->kref, ftdi_elan_delete);
- return;
+ if (!queue_delayed_work(command_queue, &ftdi->command_work, delta))
+ kref_put(&ftdi->kref, ftdi_elan_delete);
}
static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(command_queue, &ftdi->command_work,
- delta))
- kref_get(&ftdi->kref);
- } else if (queue_work(command_queue, &ftdi->command_work))
- kref_get(&ftdi->kref);
- return;
+ if (queue_delayed_work(command_queue, &ftdi->command_work, delta))
+ kref_get(&ftdi->kref);
}
static void ftdi_command_cancel_work(struct usb_ftdi *ftdi)
@@ -267,25 +247,14 @@ static void ftdi_command_cancel_work(struct usb_ftdi *ftdi)
static void ftdi_response_requeue_work(struct usb_ftdi *ftdi,
unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(respond_queue, &ftdi->respond_work,
- delta))
- return;
- } else if (queue_work(respond_queue, &ftdi->respond_work))
- return;
- kref_put(&ftdi->kref, ftdi_elan_delete);
- return;
+ if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta))
+ kref_put(&ftdi->kref, ftdi_elan_delete);
}
static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta)
{
- if (delta > 0) {
- if (queue_delayed_work(respond_queue, &ftdi->respond_work,
- delta))
- kref_get(&ftdi->kref);
- } else if (queue_work(respond_queue, &ftdi->respond_work))
- kref_get(&ftdi->kref);
- return;
+ if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta))
+ kref_get(&ftdi->kref);
}
static void ftdi_response_cancel_work(struct usb_ftdi *ftdi)
@@ -475,9 +444,11 @@ static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
return;
}
-static void ftdi_elan_command_work(void *data)
+static void ftdi_elan_command_work(struct work_struct *work)
{
- struct usb_ftdi *ftdi = data;
+ struct usb_ftdi *ftdi =
+ container_of(work, struct usb_ftdi, command_work.work);
+
if (ftdi->disconnected > 0) {
ftdi_elan_put_kref(ftdi);
return;
@@ -500,9 +471,10 @@ static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi)
return;
}
-static void ftdi_elan_respond_work(void *data)
+static void ftdi_elan_respond_work(struct work_struct *work)
{
- struct usb_ftdi *ftdi = data;
+ struct usb_ftdi *ftdi =
+ container_of(work, struct usb_ftdi, respond_work.work);
if (ftdi->disconnected > 0) {
ftdi_elan_put_kref(ftdi);
return;
@@ -534,9 +506,10 @@ static void ftdi_elan_respond_work(void *data)
* after the FTDI has been synchronized
*
*/
-static void ftdi_elan_status_work(void *data)
+static void ftdi_elan_status_work(struct work_struct *work)
{
- struct usb_ftdi *ftdi = data;
+ struct usb_ftdi *ftdi =
+ container_of(work, struct usb_ftdi, status_work.work);
int work_delay_in_msec = 0;
if (ftdi->disconnected > 0) {
ftdi_elan_put_kref(ftdi);
@@ -2677,12 +2650,9 @@ static int ftdi_elan_probe(struct usb_interface *interface,
ftdi->class = NULL;
dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a"
"ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber);
- INIT_WORK(&ftdi->status_work, ftdi_elan_status_work,
- (void *)ftdi);
- INIT_WORK(&ftdi->command_work, ftdi_elan_command_work,
- (void *)ftdi);
- INIT_WORK(&ftdi->respond_work, ftdi_elan_respond_work,
- (void *)ftdi);
+ INIT_DELAYED_WORK(&ftdi->status_work, ftdi_elan_status_work);
+ INIT_DELAYED_WORK(&ftdi->command_work, ftdi_elan_command_work);
+ INIT_DELAYED_WORK(&ftdi->respond_work, ftdi_elan_respond_work);
ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000));
return 0;
} else {
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 9110793f81d3..9659c79e187e 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -81,8 +81,8 @@ struct interfacekit {
unsigned char *data;
dma_addr_t data_dma;
- struct work_struct do_notify;
- struct work_struct do_resubmit;
+ struct delayed_work do_notify;
+ struct delayed_work do_resubmit;
unsigned long input_events;
unsigned long sensor_events;
};
@@ -374,7 +374,7 @@ static void interfacekit_irq(struct urb *urb)
}
if (kit->input_events || kit->sensor_events)
- schedule_work(&kit->do_notify);
+ schedule_delayed_work(&kit->do_notify, 0);
resubmit:
status = usb_submit_urb(urb, SLAB_ATOMIC);
@@ -384,9 +384,10 @@ resubmit:
kit->udev->devpath, status);
}
-static void do_notify(void *data)
+static void do_notify(struct work_struct *work)
{
- struct interfacekit *kit = data;
+ struct interfacekit *kit =
+ container_of(work, struct interfacekit, do_notify.work);
int i;
char sysfs_file[8];
@@ -405,9 +406,11 @@ static void do_notify(void *data)
}
}
-static void do_resubmit(void *data)
+static void do_resubmit(struct work_struct *work)
{
- set_outputs(data);
+ struct interfacekit *kit =
+ container_of(work, struct interfacekit, do_resubmit.work);
+ set_outputs(kit);
}
#define show_set_output(value) \
@@ -575,8 +578,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
kit->udev = usb_get_dev(dev);
kit->intf = intf;
- INIT_WORK(&kit->do_notify, do_notify, kit);
- INIT_WORK(&kit->do_resubmit, do_resubmit, kit);
+ INIT_DELAYED_WORK(&kit->do_notify, do_notify);
+ INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit);
usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
interfacekit_irq, kit, endpoint->bInterval);
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index c3469b0a67c2..2bb4fa572bb7 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -41,7 +41,7 @@ struct motorcontrol {
unsigned char *data;
dma_addr_t data_dma;
- struct work_struct do_notify;
+ struct delayed_work do_notify;
unsigned long input_events;
unsigned long speed_events;
unsigned long exceed_events;
@@ -148,7 +148,7 @@ static void motorcontrol_irq(struct urb *urb)
set_bit(1, &mc->exceed_events);
if (mc->input_events || mc->exceed_events || mc->speed_events)
- schedule_work(&mc->do_notify);
+ schedule_delayed_work(&mc->do_notify, 0);
resubmit:
status = usb_submit_urb(urb, SLAB_ATOMIC);
@@ -159,9 +159,10 @@ resubmit:
mc->udev->devpath, status);
}
-static void do_notify(void *data)
+static void do_notify(struct work_struct *work)
{
- struct motorcontrol *mc = data;
+ struct motorcontrol *mc =
+ container_of(work, struct motorcontrol, do_notify.work);
int i;
char sysfs_file[8];
@@ -348,7 +349,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
mc->udev = usb_get_dev(dev);
mc->intf = intf;
mc->acceleration[0] = mc->acceleration[1] = 10;
- INIT_WORK(&mc->do_notify, do_notify, mc);
+ INIT_DELAYED_WORK(&mc->do_notify, do_notify);
usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data,
maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
motorcontrol_irq, mc, endpoint->bInterval);
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 7c906a43e497..fa78326d0bf0 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -222,7 +222,7 @@ struct kaweth_device
int suspend_lowmem_ctrl;
int linkstate;
int opened;
- struct work_struct lowmem_work;
+ struct delayed_work lowmem_work;
struct usb_device *dev;
struct net_device *net;
@@ -530,9 +530,10 @@ resubmit:
kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);
}
-static void kaweth_resubmit_tl(void *d)
+static void kaweth_resubmit_tl(struct work_struct *work)
{
- struct kaweth_device *kaweth = (struct kaweth_device *)d;
+ struct kaweth_device *kaweth =
+ container_of(work, struct kaweth_device, lowmem_work.work);
if (IS_BLOCKED(kaweth->status))
return;
@@ -1126,7 +1127,7 @@ err_fw:
/* kaweth is zeroed as part of alloc_netdev */
- INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth);
+ INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
SET_MODULE_OWNER(netdev);
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 69eb0db399df..b5690b3834e3 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -1281,9 +1281,9 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
static struct workqueue_struct *pegasus_workqueue = NULL;
#define CARRIER_CHECK_DELAY (2 * HZ)
-static void check_carrier(void *data)
+static void check_carrier(struct work_struct *work)
{
- pegasus_t *pegasus = data;
+ pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work);
set_carrier(pegasus->net);
if (!(pegasus->flags & PEGASUS_UNPLUG)) {
queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
@@ -1319,7 +1319,7 @@ static int pegasus_probe(struct usb_interface *intf,
tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus);
- INIT_WORK(&pegasus->carrier_check, check_carrier, pegasus);
+ INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier);
pegasus->intf = intf;
pegasus->usb = dev;
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
index 006438069b66..98f6898cae1f 100644
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -95,7 +95,7 @@ typedef struct pegasus {
int dev_index;
int intr_interval;
struct tasklet_struct rx_tl;
- struct work_struct carrier_check;
+ struct delayed_work carrier_check;
struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
struct sk_buff *rx_pool[RX_SKBS];
struct sk_buff *rx_skb;
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 7672e11c94c4..327f97555679 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -782,9 +782,10 @@ static struct ethtool_ops usbnet_ethtool_ops = {
* especially now that control transfers can be queued.
*/
static void
-kevent (void *data)
+kevent (struct work_struct *work)
{
- struct usbnet *dev = data;
+ struct usbnet *dev =
+ container_of(work, struct usbnet, kevent);
int status;
/* usb_clear_halt() needs a thread context */
@@ -1146,7 +1147,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
skb_queue_head_init (&dev->done);
dev->bh.func = usbnet_bh;
dev->bh.data = (unsigned long) dev;
- INIT_WORK (&dev->kevent, kevent, dev);
+ INIT_WORK (&dev->kevent, kevent);
dev->delay.function = usbnet_bh;
dev->delay.data = (unsigned long) dev;
init_timer (&dev->delay);
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index b1b5707bc99a..86bcf63b6ba5 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -92,6 +92,7 @@ struct aircable_private {
struct circ_buf *rx_buf; /* read buffer */
int rx_flags; /* for throttilng */
struct work_struct rx_work; /* work cue for the receiving line */
+ struct usb_serial_port *port; /* USB port with which associated */
};
/* Private methods */
@@ -251,10 +252,11 @@ static void aircable_send(struct usb_serial_port *port)
schedule_work(&port->work);
}
-static void aircable_read(void *params)
+static void aircable_read(struct work_struct *work)
{
- struct usb_serial_port *port = params;
- struct aircable_private *priv = usb_get_serial_port_data(port);
+ struct aircable_private *priv =
+ container_of(work, struct aircable_private, rx_work);
+ struct usb_serial_port *port = priv->port;
struct tty_struct *tty;
unsigned char *data;
int count;
@@ -349,7 +351,8 @@ static int aircable_attach (struct usb_serial *serial)
}
priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
- INIT_WORK(&priv->rx_work, aircable_read, port);
+ priv->port = port;
+ INIT_WORK(&priv->rx_work, aircable_read);
usb_set_serial_port_data(serial->port[0], priv);
@@ -516,7 +519,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
package_length - shift);
}
}
- aircable_read(port);
+ aircable_read(&priv->rx_work);
}
/* Schedule the next read _if_ we are still open */
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 5e3ac281a2f8..83d0e21145b0 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -430,13 +430,14 @@ struct digi_port {
int dp_in_close; /* close in progress */
wait_queue_head_t dp_close_wait; /* wait queue for close */
struct work_struct dp_wakeup_work;
+ struct usb_serial_port *dp_port;
};
/* Local Function Declarations */
static void digi_wakeup_write( struct usb_serial_port *port );
-static void digi_wakeup_write_lock(void *);
+static void digi_wakeup_write_lock(struct work_struct *work);
static int digi_write_oob_command( struct usb_serial_port *port,
unsigned char *buf, int count, int interruptible );
static int digi_write_inb_command( struct usb_serial_port *port,
@@ -598,11 +599,12 @@ static inline long cond_wait_interruptible_timeout_irqrestore(
* on writes.
*/
-static void digi_wakeup_write_lock(void *arg)
+static void digi_wakeup_write_lock(struct work_struct *work)
{
- struct usb_serial_port *port = arg;
+ struct digi_port *priv =
+ container_of(work, struct digi_port, dp_wakeup_work);
+ struct usb_serial_port *port = priv->dp_port;
unsigned long flags;
- struct digi_port *priv = usb_get_serial_port_data(port);
spin_lock_irqsave( &priv->dp_port_lock, flags );
@@ -1702,8 +1704,8 @@ dbg( "digi_startup: TOP" );
init_waitqueue_head( &priv->dp_flush_wait );
priv->dp_in_close = 0;
init_waitqueue_head( &priv->dp_close_wait );
- INIT_WORK(&priv->dp_wakeup_work,
- digi_wakeup_write_lock, serial->port[i]);
+ INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
+ priv->dp_port = serial->port[i];
/* initialize write wait queue for this port */
init_waitqueue_head( &serial->port[i]->write_wait );
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 89ce2775be15..72e4d48f51e9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -559,7 +559,8 @@ struct ftdi_private {
char prev_status, diff_status; /* Used for TIOCMIWAIT */
__u8 rx_flags; /* receive state flags (throttling) */
spinlock_t rx_lock; /* spinlock for receive state */
- struct work_struct rx_work;
+ struct delayed_work rx_work;
+ struct usb_serial_port *port;
int rx_processed;
unsigned long rx_bytes;
@@ -593,7 +594,7 @@ static int ftdi_write_room (struct usb_serial_port *port);
static int ftdi_chars_in_buffer (struct usb_serial_port *port);
static void ftdi_write_bulk_callback (struct urb *urb);
static void ftdi_read_bulk_callback (struct urb *urb);
-static void ftdi_process_read (void *param);
+static void ftdi_process_read (struct work_struct *work);
static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old);
static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file);
static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
@@ -1201,7 +1202,8 @@ static int ftdi_sio_attach (struct usb_serial *serial)
port->read_urb->transfer_buffer_length = BUFSZ;
}
- INIT_WORK(&priv->rx_work, ftdi_process_read, port);
+ INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read);
+ priv->port = port;
/* Free port's existing write urb and transfer buffer. */
if (port->write_urb) {
@@ -1640,17 +1642,18 @@ static void ftdi_read_bulk_callback (struct urb *urb)
priv->rx_bytes += countread;
spin_unlock_irqrestore(&priv->rx_lock, flags);
- ftdi_process_read(port);
+ ftdi_process_read(&priv->rx_work.work);
} /* ftdi_read_bulk_callback */
-static void ftdi_process_read (void *param)
+static void ftdi_process_read (struct work_struct *work)
{ /* ftdi_process_read */
- struct usb_serial_port *port = (struct usb_serial_port*)param;
+ struct ftdi_private *priv =
+ container_of(work, struct ftdi_private, rx_work.work);
+ struct usb_serial_port *port = priv->port;
struct urb *urb;
struct tty_struct *tty;
- struct ftdi_private *priv;
char error_flag;
unsigned char *data;
@@ -2179,7 +2182,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port)
spin_unlock_irqrestore(&priv->rx_lock, flags);
if (actually_throttled)
- schedule_work(&priv->rx_work);
+ schedule_delayed_work(&priv->rx_work, 0);
}
static int __init ftdi_init (void)
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 909005107ea2..e09a0bfe6231 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -120,6 +120,8 @@ struct keyspan_pda_private {
int tx_throttled;
struct work_struct wakeup_work;
struct work_struct unthrottle_work;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
};
@@ -175,9 +177,11 @@ static struct usb_device_id id_table_fake_xircom [] = {
};
#endif
-static void keyspan_pda_wakeup_write( struct usb_serial_port *port )
+static void keyspan_pda_wakeup_write(struct work_struct *work)
{
-
+ struct keyspan_pda_private *priv =
+ container_of(work, struct keyspan_pda_private, wakeup_work);
+ struct usb_serial_port *port = priv->port;
struct tty_struct *tty = port->tty;
/* wake up port processes */
@@ -187,8 +191,11 @@ static void keyspan_pda_wakeup_write( struct usb_serial_port *port )
tty_wakeup(tty);
}
-static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
+static void keyspan_pda_request_unthrottle(struct work_struct *work)
{
+ struct keyspan_pda_private *priv =
+ container_of(work, struct keyspan_pda_private, unthrottle_work);
+ struct usb_serial *serial = priv->serial;
int result;
dbg(" request_unthrottle");
@@ -765,11 +772,10 @@ static int keyspan_pda_startup (struct usb_serial *serial)
return (1); /* error */
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
- INIT_WORK(&priv->wakeup_work, (void *)keyspan_pda_wakeup_write,
- (void *)(serial->port[0]));
- INIT_WORK(&priv->unthrottle_work,
- (void *)keyspan_pda_request_unthrottle,
- (void *)(serial));
+ INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
+ INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
+ priv->serial = serial;
+ priv->port = serial->port[0];
return (0);
}
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index c1257d5292f5..3d5072f14b8d 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -533,9 +533,10 @@ void usb_serial_port_softint(struct usb_serial_port *port)
schedule_work(&port->work);
}
-static void usb_serial_port_work(void *private)
+static void usb_serial_port_work(struct work_struct *work)
{
- struct usb_serial_port *port = private;
+ struct usb_serial_port *port =
+ container_of(work, struct usb_serial_port, work);
struct tty_struct *tty;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -799,7 +800,7 @@ int usb_serial_probe(struct usb_interface *interface,
port->serial = serial;
spin_lock_init(&port->lock);
mutex_init(&port->mutex);
- INIT_WORK(&port->work, usb_serial_port_work, port);
+ INIT_WORK(&port->work, usb_serial_port_work);
serial->port[i] = port;
}
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 4d1cd7aeccd3..154c7d290597 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -227,6 +227,7 @@ struct whiteheat_private {
struct list_head rx_urbs_submitted;
struct list_head rx_urb_q;
struct work_struct rx_work;
+ struct usb_serial_port *port;
struct list_head tx_urbs_free;
struct list_head tx_urbs_submitted;
};
@@ -241,7 +242,7 @@ static void command_port_read_callback(struct urb *urb);
static int start_port_read(struct usb_serial_port *port);
static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
static struct list_head *list_first(struct list_head *head);
-static void rx_data_softint(void *private);
+static void rx_data_softint(struct work_struct *work);
static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
static int firm_open(struct usb_serial_port *port);
@@ -424,7 +425,8 @@ static int whiteheat_attach (struct usb_serial *serial)
spin_lock_init(&info->lock);
info->flags = 0;
info->mcr = 0;
- INIT_WORK(&info->rx_work, rx_data_softint, port);
+ INIT_WORK(&info->rx_work, rx_data_softint);
+ info->port = port;
INIT_LIST_HEAD(&info->rx_urbs_free);
INIT_LIST_HEAD(&info->rx_urbs_submitted);
@@ -949,7 +951,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
spin_unlock_irqrestore(&info->lock, flags);
if (actually_throttled)
- rx_data_softint(port);
+ rx_data_softint(&info->rx_work);
return;
}
@@ -1400,10 +1402,11 @@ static struct list_head *list_first(struct list_head *head)
}
-static void rx_data_softint(void *private)
+static void rx_data_softint(struct work_struct *work)
{
- struct usb_serial_port *port = (struct usb_serial_port *)private;
- struct whiteheat_private *info = usb_get_serial_port_data(port);
+ struct whiteheat_private *info =
+ container_of(work, struct whiteheat_private, rx_work);
+ struct usb_serial_port *port = info->port;
struct tty_struct *tty = port->tty;
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 302174b8e477..31f476a64790 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -383,9 +383,9 @@ static void fbcon_update_softback(struct vc_data *vc)
softback_top = 0;
}
-static void fb_flashcursor(void *private)
+static void fb_flashcursor(struct work_struct *work)
{
- struct fb_info *info = private;
+ struct fb_info *info = container_of(work, struct fb_info, queue);
struct fbcon_ops *ops = info->fbcon_par;
struct display *p;
struct vc_data *vc = NULL;
@@ -442,7 +442,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info)
if ((!info->queue.func || info->queue.func == fb_flashcursor) &&
!(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {
if (!info->queue.func)
- INIT_WORK(&info->queue, fb_flashcursor, info);
+ INIT_WORK(&info->queue, fb_flashcursor);
init_timer(&ops->cursor_timer);
ops->cursor_timer.function = cursor_timer_handler;
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index fdb33cd21a27..cb26c6df0583 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -34,6 +34,7 @@
#include <asm/prom.h>
#include <asm/pgtable.h>
#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include "macmodes.h"
#include "platinumfb.h"
@@ -682,14 +683,14 @@ static int __init platinumfb_init(void)
return -ENODEV;
platinumfb_setup(option);
#endif
- of_register_driver(&platinum_driver);
+ of_register_platform_driver(&platinum_driver);
return 0;
}
static void __exit platinumfb_exit(void)
{
- of_unregister_driver(&platinum_driver);
+ of_unregister_platform_driver(&platinum_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 8a8ae55a7403..38eb0b69c2d7 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -964,9 +964,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
* Our LCD controller task (which is called when we blank or unblank)
* via keventd.
*/
-static void pxafb_task(void *dummy)
+static void pxafb_task(struct work_struct *work)
{
- struct pxafb_info *fbi = dummy;
+ struct pxafb_info *fbi =
+ container_of(work, struct pxafb_info, task);
u_int state = xchg(&fbi->task_state, -1);
set_ctrlr_state(fbi, state);
@@ -1159,7 +1160,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
}
init_waitqueue_head(&fbi->ctrlr_wait);
- INIT_WORK(&fbi->task, pxafb_task, fbi);
+ INIT_WORK(&fbi->task, pxafb_task);
init_MUTEX(&fbi->ctrlr_sem);
return fbi;
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 5372cfcbd054..b022fffd8c51 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/sched.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/delay.h>
OpenPOWER on IntegriCloud